Bug fixes.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5148 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Waldemar Kornewald 2003-10-24 20:08:56 +00:00
parent 7f29148da0
commit b0bff411f1
9 changed files with 179 additions and 43 deletions

View File

@ -17,8 +17,8 @@
#ifdef _KERNEL_MODE
#define spawn_thread spawn_kernel_thread
#define printf dprintf
#define spawn_thread spawn_kernel_thread
#define printf dprintf
#endif
@ -107,6 +107,10 @@ PPPManager::PPPManager()
: fReportManager(fReportLock),
fNextID(1)
{
#if DEBUG
printf("PPPManager: Constructor\n");
#endif
fDeleterThread = spawn_thread(deleter_thread, "PPPManager: deleter_thread",
B_NORMAL_PRIORITY, this);
resume_thread(fDeleterThread);
@ -116,6 +120,10 @@ PPPManager::PPPManager()
PPPManager::~PPPManager()
{
#if DEBUG
printf("PPPManager: Destructor\n");
#endif
int32 tmp;
send_data(fDeleterThread, 0, NULL, 0);
// notify deleter_thread that we are being destroyed
@ -136,6 +144,10 @@ PPPManager::~PPPManager()
int32
PPPManager::Stop(ifnet *ifp)
{
#if DEBUG
printf("PPPManager: Stop(%s)\n", ifp ? ifp->if_name : "Unknown");
#endif
LockerHelper locker(fLock);
interface_entry *entry = EntryFor(ifp);
@ -152,6 +164,10 @@ int32
PPPManager::Output(ifnet *ifp, struct mbuf *buf, struct sockaddr *dst,
struct rtentry *rt0)
{
#if DEBUG
printf("PPPManager: Output(%s)\n", ifp ? ifp->if_name : "Unknown");
#endif
if(dst->sa_family == AF_UNSPEC)
return B_ERROR;
@ -193,6 +209,10 @@ PPPManager::Output(ifnet *ifp, struct mbuf *buf, struct sockaddr *dst,
int32
PPPManager::Control(ifnet *ifp, ulong cmd, caddr_t data)
{
#if DEBUG
printf("PPPManager: Control(%s)\n", ifp ? ifp->if_name : "Unknown");
#endif
LockerHelper locker(fLock);
interface_entry *entry = EntryFor(ifp);
if(!entry || entry->deleting)
@ -226,6 +246,10 @@ interface_id
PPPManager::CreateInterface(const driver_settings *settings,
interface_id parentID = PPP_UNDEFINED_INTERFACE_ID)
{
#if DEBUG
printf("PPPManager: CreateInterface()\n");
#endif
LockerHelper locker(fLock);
interface_entry *parentEntry = EntryFor(parentID);
@ -263,6 +287,10 @@ PPPManager::CreateInterface(const driver_settings *settings,
void
PPPManager::DeleteInterface(interface_id ID)
{
#if DEBUG
printf("PPPManager: DeleteInterface(%ld)\n", ID);
#endif
// This only marks the interface for deletion.
// Our deleter_thread does the real work.
LockerHelper locker(fLock);
@ -276,6 +304,10 @@ PPPManager::DeleteInterface(interface_id ID)
void
PPPManager::RemoveInterface(interface_id ID)
{
#if DEBUG
printf("PPPManager: RemoveInterface(%ld)\n", ID);
#endif
LockerHelper locker(fLock);
int32 index;
@ -293,6 +325,10 @@ PPPManager::RemoveInterface(interface_id ID)
ifnet*
PPPManager::RegisterInterface(interface_id ID)
{
#if DEBUG
printf("PPPManager: RegisterInterface(%ld)\n", ID);
#endif
LockerHelper locker(fLock);
interface_entry *entry = EntryFor(ID);
@ -316,6 +352,11 @@ PPPManager::RegisterInterface(interface_id ID)
ifp->output = ppp_ifnet_output;
ifp->ioctl = ppp_ifnet_ioctl;
#if DEBUG
printf("PPPManager::DeleteInterface(): Created new ifnet: %s%d\n",
ifp->name, ifp->if_unit);
#endif
if_attach(ifp);
return ifp;
}
@ -324,6 +365,10 @@ PPPManager::RegisterInterface(interface_id ID)
bool
PPPManager::UnregisterInterface(interface_id ID)
{
#if DEBUG
printf("PPPManager: UnregisterInterface(%ld)\n", ID);
#endif
LockerHelper locker(fLock);
interface_entry *entry = EntryFor(ID);
@ -342,6 +387,10 @@ PPPManager::UnregisterInterface(interface_id ID)
status_t
PPPManager::Control(uint32 op, void *data, size_t length)
{
#if DEBUG
printf("PPPManager: Control(%ld)\n", op);
#endif
// this method is intended for use by userland applications
switch(op) {
@ -454,6 +503,10 @@ PPPManager::Control(uint32 op, void *data, size_t length)
status_t
PPPManager::ControlInterface(interface_id ID, uint32 op, void *data, size_t length)
{
#if DEBUG
printf("PPPManager: ControlInterface(%ld)\n", ID);
#endif
LockerHelper locker(fLock);
interface_entry *entry = EntryFor(ID);
@ -468,6 +521,10 @@ int32
PPPManager::GetInterfaces(interface_id *interfaces, int32 count,
ppp_interface_filter filter = PPP_REGISTERED_INTERFACES)
{
#if DEBUG
printf("PPPManager: GetInterfaces()\n");
#endif
LockerHelper locker(fLock);
int32 item = 0;
@ -507,6 +564,10 @@ PPPManager::GetInterfaces(interface_id *interfaces, int32 count,
int32
PPPManager::CountInterfaces(ppp_interface_filter filter = PPP_REGISTERED_INTERFACES)
{
#if DEBUG
printf("PPPManager: CountInterfaces()\n");
#endif
LockerHelper locker(fLock);
if(filter == PPP_ALL_INTERFACES)
@ -544,6 +605,10 @@ PPPManager::CountInterfaces(ppp_interface_filter filter = PPP_REGISTERED_INTERFA
interface_entry*
PPPManager::EntryFor(interface_id ID, int32 *saveIndex = NULL) const
{
#if DEBUG
printf("PPPManager: EntryFor(%ld)\n", ID);
#endif
if(ID == PPP_UNDEFINED_INTERFACE_ID)
return NULL;
@ -567,6 +632,10 @@ PPPManager::EntryFor(ifnet *ifp, int32 *saveIndex = NULL) const
if(!ifp)
return NULL;
#if DEBUG
printf("PPPManager: EntryFor(%s%d)\n", ifp->name, ifp->if_unit);
#endif
interface_entry *entry;
for(int32 index = 0; index < fEntries.CountItems(); index++) {
entry = fEntries.ItemAt(index);

View File

@ -36,10 +36,6 @@ PPPoEDevice::PPPoEDevice(PPPInterface& interface, driver_parameter *settings)
printf("PPPoEDevice: Constructor\n");
if(!settings || !settings->parameters)
printf("PPPoEDevice::ctor: No settings!\n");
else if(settings->parameter_count > 0 && settings->parameters[0].value_count > 0)
printf("PPPoEDevice::ctor: Value0: %s\n", settings->parameters[0].values[0]);
else
printf("PPPoEDevice::ctor: No values!\n");
#endif
memset(fPeer, 0xFF, sizeof(fPeer));
@ -56,7 +52,8 @@ PPPoEDevice::PPPoEDevice(PPPInterface& interface, driver_parameter *settings)
ifnet *current = get_interfaces();
for(; current; current = current->if_next) {
if(current->if_name && !strcmp(current->if_name, interfaceName)) {
if(current->if_type == IFT_ETHER && current->if_name
&& !strcmp(current->if_name, interfaceName)) {
#if DEBUG
printf("PPPoEDevice::ctor: found ethernet interface\n");
#endif

View File

@ -96,10 +96,16 @@ add_to(PPPInterface& mainInterface, PPPInterface *subInterface,
PPPoEDevice *device;
bool success;
if(subInterface) {
#if DEBUG
printf("PPPoE: add_to(): Adding to subInterface\n");
#endif
device = new PPPoEDevice(*subInterface, settings);
success = subInterface->SetDevice(device);
} else
device = new PPPoEDevice(mainInterface, settings); {
} else {
#if DEBUG
printf("PPPoE: add_to(): Adding to mainInterface\n");
#endif
device = new PPPoEDevice(mainInterface, settings);
success = mainInterface.SetDevice(device);
}

View File

@ -58,6 +58,8 @@ status_t redial_thread(void *data);
// other functions
status_t interface_deleter_thread(void *data);
status_t call_open_event_thread(void *data);
status_t call_close_event_thread(void *data);
PPPInterface::PPPInterface(uint32 ID, const driver_settings *settings,
@ -67,6 +69,8 @@ PPPInterface::PPPInterface(uint32 ID, const driver_settings *settings,
fSettings(dup_driver_settings(settings)),
fIfnet(NULL),
fUpThread(-1),
fOpenEventThread(-1),
fCloseEventThread(-1),
fRedialThread(-1),
fDialRetry(0),
fDialRetriesLimit(0),
@ -182,12 +186,12 @@ PPPInterface::PPPInterface(uint32 ID, const driver_settings *settings,
PPPInterface::~PPPInterface()
{
++fDeleteCounter;
#if DEBUG
printf("PPPInterface: Destructor\n");
#endif
++fDeleteCounter;
// make sure we are not accessible by any thread before we continue
UnregisterInterface();
@ -211,6 +215,8 @@ PPPInterface::~PPPInterface()
send_data_with_timeout(fRedialThread, 0, NULL, 0, 200);
// tell thread that we are being destroyed (200ms timeout)
wait_for_thread(fRedialThread, &tmp);
wait_for_thread(fOpenEventThread, &tmp);
wait_for_thread(fCloseEventThread, &tmp);
while(CountChildren())
delete ChildAt(0);
@ -459,7 +465,7 @@ bool
PPPInterface::SetDevice(PPPDevice *device)
{
#if DEBUG
printf("PPPInterface: SetDevice()\n");
printf("PPPInterface: SetDevice(%p)\n", device);
#endif
if(device && &device->Interface() != this)
@ -715,7 +721,7 @@ PPPInterface::SetAutoRedial(bool autoRedial = true)
printf("PPPInterface: SetAutoRedial(%s)\n", autoRedial ? "true" : "false");
#endif
if(Mode() == PPP_CLIENT_MODE)
if(Mode() != PPP_CLIENT_MODE)
return;
LockerHelper locker(fLock);
@ -732,7 +738,6 @@ PPPInterface::SetDialOnDemand(bool dialOnDemand = true)
#if DEBUG
printf("PPPInterface: SetDialOnDemand(%s)\n", dialOnDemand ? "true" : "false");
printf("PPPInterface::SetDialOnDemand(): %s\n", fDialOnDemand ? "true" : "false");
#endif
// Only clients support DialOnDemand.
@ -749,10 +754,6 @@ PPPInterface::SetDialOnDemand(bool dialOnDemand = true)
fDialOnDemand = dialOnDemand;
#if DEBUG
printf("PPPInterface::SetDialOnDemand() done: %s\n", fDialOnDemand?"true":"false");
#endif
// Do not allow changes when we are disconnected (only main interfaces).
// This would make no sense because
// - enabling: this cannot happen because hidden interfaces are deleted if they
@ -810,22 +811,31 @@ PPPInterface::Up()
// One thread has to do the real task while all other threads are observers.
// Lock needs timeout because destructor could have locked the interface.
while(!fLock.LockWithTimeout(100000) != B_NO_ERROR)
while(fLock.LockWithTimeout(100000) != B_NO_ERROR)
if(fDeleteCounter > 0)
return false;
if(fUpThread == -1)
fUpThread = me;
ReportManager().EnableReports(PPP_CONNECTION_REPORT, me, PPP_WAIT_FOR_REPLY);
fLock.Unlock();
// fUpThread tells the state machine to go up
if(me == fUpThread || me == fRedialThread)
StateMachine().OpenEvent();
// fUpThread/fRedialThread tells the state machine to go up (using a new thread
// because we might not receive report messages otherwise)
if(me == fUpThread || me == fRedialThread) {
if(fOpenEventThread != -1) {
int32 tmp;
wait_for_thread(fOpenEventThread, &tmp);
}
fOpenEventThread = spawn_thread(call_open_event_thread,
"PPPInterface: call_open_event_thread", B_NORMAL_PRIORITY, this);
resume_thread(fOpenEventThread);
}
fLock.Unlock();
if(me == fRedialThread && me != fUpThread)
return true;
// the redial thread is doing a DialRetry in this case
// the redial thread is doing a DialRetry in this case (fUpThread
// is waiting for new reports)
while(true) {
if(IsUp()) {
@ -1004,12 +1014,18 @@ PPPInterface::Down()
return true;
ReportManager().EnableReports(PPP_CONNECTION_REPORT, find_thread(NULL));
locker.UnlockNow();
thread_id sender;
ppp_report_packet report;
StateMachine().CloseEvent();
if(fCloseEventThread != -1) {
int32 tmp;
wait_for_thread(fCloseEventThread, &tmp);
}
fCloseEventThread = spawn_thread(call_close_event_thread,
"PPPInterface: call_close_event_thread", B_NORMAL_PRIORITY, this);
resume_thread(fCloseEventThread);
locker.UnlockNow();
while(true) {
if(receive_data(&sender, &report, sizeof(report)) != PPP_REPORT_CODE)
@ -1351,10 +1367,6 @@ PPPInterface::RegisterInterface()
LockerHelper locker(fLock);
if(InitCheck() != B_OK)
return false;
// we cannot register if something is wrong
// only MainInterfaces get an ifnet
if(IsMultilink() && Parent() && Parent()->RegisterInterface())
return true;
@ -1583,14 +1595,56 @@ redial_thread(void *data)
// which is only defined here (the real class is defined in the ppp interface module).
class PPPManager {
public:
PPPManager(PPPInterface *interface)
{ if(interface) delete interface; }
PPPManager() {}
void Delete(PPPInterface *interface)
{ delete interface; }
void CallOpenEvent(PPPInterface *interface)
{
while(interface->fLock.LockWithTimeout(100000) != B_NO_ERROR)
if(interface->fDeleteCounter > 0)
return;
interface->CallOpenEvent();
interface->fOpenEventThread = -1;
interface->fLock.Unlock();
}
void CallCloseEvent(PPPInterface *interface)
{
while(interface->fLock.LockWithTimeout(100000) != B_NO_ERROR)
if(interface->fDeleteCounter > 0)
return;
interface->CallCloseEvent();
interface->fCloseEventThread = -1;
interface->fLock.Unlock();
}
};
status_t
interface_deleter_thread(void *data)
{
PPPManager((PPPInterface*) data);
PPPManager manager;
manager.Delete((PPPInterface*) data);
return B_OK;
}
status_t
call_open_event_thread(void *data)
{
PPPManager manager;
manager.CallOpenEvent((PPPInterface*) data);
return B_OK;
}
status_t
call_close_event_thread(void *data)
{
PPPManager manager;
manager.CallCloseEvent((PPPInterface*) data);
return B_OK;
}

View File

@ -425,7 +425,7 @@ PPPStateMachine::UpFailedEvent()
Interface().Parent()->StateMachine().UpFailedEvent(Interface());
NewPhase(PPP_DOWN_PHASE);
// tell DownEvent() that we do not need to redial
// tell DownEvent() that it should not create a connection-lost-report
DownEvent();
break;

View File

@ -187,6 +187,12 @@ class PPPInterface : public PPPLayer {
void CalculateInterfaceMTU();
void CalculateBaudRate();
// these two methods are used by the open/close_event_threads
void CallOpenEvent()
{ StateMachine().OpenEvent(); }
void CallCloseEvent()
{ StateMachine().CloseEvent(); }
void Redial(uint32 delay);
// multilink methods
@ -199,7 +205,7 @@ class PPPInterface : public PPPLayer {
driver_settings *fSettings;
struct ifnet *fIfnet;
thread_id fUpThread;
thread_id fUpThread, fOpenEventThread, fCloseEventThread;
thread_id fRedialThread;
uint32 fDialRetry, fDialRetriesLimit;

View File

@ -52,7 +52,11 @@ PPPInterface::SetTo(interface_id ID)
fID = ID;
return Control(PPPC_GET_INTERFACE_INFO, &fInfo, sizeof(fInfo));
status_t error = Control(PPPC_GET_INTERFACE_INFO, &fInfo, sizeof(fInfo));
if(error != B_OK)
fID = PPP_UNDEFINED_INTERFACE_ID;
return error;
}
@ -80,7 +84,7 @@ PPPInterface::Control(uint32 op, void *data, size_t length) const
bool
PPPInterface::GetInterfaceInfo(ppp_interface_info *info) const
PPPInterface::GetInterfaceInfo(ppp_interface_info_t *info) const
{
if(InitCheck() != B_OK || !info)
return false;

View File

@ -133,12 +133,12 @@ PPPManager::InterfaceWithSettings(const driver_settings *settings) const
interface_id id = PPP_UNDEFINED_INTERFACE_ID;
PPPInterface interface;
ppp_interface_info info;
ppp_interface_info_t info;
for(int32 index = 0; index < count; index++) {
interface.SetTo(interfaces[index]);
if(interface.InitCheck() == B_OK && interface.GetInterfaceInfo(&info)
&& equal_driver_settings(settings, info.settings)) {
&& equal_driver_settings(settings, info.info.settings)) {
id = interface.ID();
break;
}
@ -161,12 +161,12 @@ PPPManager::InterfaceWithUnit(int32 if_unit)
interface_id id = PPP_UNDEFINED_INTERFACE_ID;
PPPInterface interface;
ppp_interface_info info;
ppp_interface_info_t info;
for(int32 index = 0; index < count; index++) {
interface.SetTo(interfaces[index]);
if(interface.InitCheck() == B_OK && interface.GetInterfaceInfo(&info)
&& info.if_unit == if_unit) {
&& info.info.if_unit == if_unit) {
id = interface.ID();
break;
}

View File

@ -25,7 +25,7 @@ class PPPInterface {
status_t Control(uint32 op, void *data, size_t length) const;
bool GetInterfaceInfo(ppp_interface_info *info) const;
bool GetInterfaceInfo(ppp_interface_info_t *info) const;
bool Up() const;
bool Down() const;
@ -43,7 +43,7 @@ class PPPInterface {
interface_id fID;
int fFD;
ppp_interface_info fInfo;
ppp_interface_info_t fInfo;
};