From 5a483e4d35557e2c0803bc8a8b091beaffdc8d26 Mon Sep 17 00:00:00 2001 From: Waldemar Kornewald Date: Fri, 6 Feb 2004 18:12:24 +0000 Subject: [PATCH] Fixed a couple of possible dead-locks. Fixed some minor bugs. PPPoE: added experimental support for AccessConcentrator and ServiceName settings. Changed libppp to import strlcat.c from libroot instead of duplicating code. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6511 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../network/interfaces/ppp/PPPManager.cpp | 38 +++++--- src/add-ons/kernel/network/ppp/ipcp/Jamfile | 2 +- .../kernel/network/ppp/ipcp/Protocol.h | 4 +- src/add-ons/kernel/network/ppp/modem/Jamfile | 1 - src/add-ons/kernel/network/ppp/pap/Jamfile | 1 - .../kernel/network/ppp/pap/Protocol.cpp | 4 +- .../network/ppp/pppoe/DiscoveryPacket.cpp | 4 +- .../network/ppp/pppoe/DiscoveryPacket.h | 2 +- src/add-ons/kernel/network/ppp/pppoe/Jamfile | 1 - src/add-ons/kernel/network/ppp/pppoe/PPPoE.h | 5 +- .../kernel/network/ppp/pppoe/PPPoEDevice.cpp | 52 ++++++----- .../kernel/network/ppp/pppoe/PPPoEDevice.h | 2 +- src/add-ons/kernel/network/ppp/pppoe/TODO | 1 + .../kernel/network/ppp/pppoe/pppoe.cpp | 12 ++- .../ppp/shared/libkernelppp/KPPPInterface.cpp | 12 +-- .../ppp/shared/libkernelppp/KPPPLayer.cpp | 1 + .../ppp/shared/libkernelppp/KPPPProfile.cpp | 16 ++-- .../shared/libkernelppp/KPPPReportManager.cpp | 93 +++++++++++-------- .../shared/libkernelppp/KPPPStateMachine.cpp | 20 +++- .../_KPPPAuthenticationHandler.cpp | 4 +- .../shared/libkernelppp/_KPPPMRUHandler.cpp | 4 +- .../shared/libkernelppp/headers/PPPControl.h | 3 +- .../libkernelppp/headers/PPPReportDefs.h | 12 ++- .../kernel/network/ppp/shared/libppp/Jamfile | 3 +- .../shared/libppp/PPPInterfaceListener.cpp | 47 +++++++--- .../ppp/shared/libppp/_libppputils.cpp | 31 ------- .../libppp/headers/PPPInterfaceListener.h | 2 +- 27 files changed, 212 insertions(+), 165 deletions(-) diff --git a/src/add-ons/kernel/network/interfaces/ppp/PPPManager.cpp b/src/add-ons/kernel/network/interfaces/ppp/PPPManager.cpp index 225048479d..d2115b12f0 100644 --- a/src/add-ons/kernel/network/interfaces/ppp/PPPManager.cpp +++ b/src/add-ons/kernel/network/interfaces/ppp/PPPManager.cpp @@ -308,11 +308,18 @@ PPPManager::DeleteInterface(ppp_interface_id ID) if(!entry) return false; - ++entry->accessing; + if(entry->deleting) + return true; + // this check prevents a dead-lock - locker.UnlockNow(); - entry->interface->Down(); entry->deleting = true; + ++entry->accessing; + locker.UnlockNow(); + + // bring interface down if needed + if(entry->interface->State() != PPP_INITIAL_STATE + || entry->interface->Phase() != PPP_DOWN_PHASE) + entry->interface->Down(); --entry->accessing; @@ -415,6 +422,9 @@ PPPManager::Control(uint32 op, void *data, size_t length) // this method is intended for use by userland applications switch(op) { +// case PPPC_CONTROL_MODULE: { +// } break; + case PPPC_CREATE_INTERFACE: { if(length < sizeof(ppp_interface_description_info) || !data) return B_ERROR; @@ -462,6 +472,7 @@ PPPManager::Control(uint32 op, void *data, size_t length) return B_BAD_INDEX; ++entry->accessing; + locker.UnlockNow(); return bring_interface_up(entry); } break; @@ -477,6 +488,7 @@ PPPManager::Control(uint32 op, void *data, size_t length) return B_BAD_INDEX; ++entry->accessing; + locker.UnlockNow(); return bring_interface_down(entry); } break; @@ -485,14 +497,9 @@ PPPManager::Control(uint32 op, void *data, size_t length) if(length < sizeof(ppp_control_info) || !data) return B_ERROR; - LockerHelper locker(fLock); - ppp_control_info *control = (ppp_control_info*) data; - ppp_interface_entry *entry = EntryFor(control->index); - if(!entry || entry->deleting) - return B_BAD_INDEX; - return entry->interface->Control(control->op, control->data, + return ControlInterface(control->index, control->op, control->data, control->length); } break; @@ -525,6 +532,8 @@ PPPManager::Control(uint32 op, void *data, size_t length) if(!info->u.settings) return B_ERROR; + LockerHelper locker(fLock); + ppp_interface_entry *entry = EntryFor(info->u.settings); if(entry) info->interface = entry->interface->ID(); @@ -568,11 +577,16 @@ PPPManager::ControlInterface(ppp_interface_id ID, uint32 op, void *data, size_t LockerHelper locker(fLock); + status_t result = B_BAD_INDEX; ppp_interface_entry *entry = EntryFor(ID); - if(entry && !entry->deleting) - return entry->interface->Control(op, data, length); + if(entry && !entry->deleting) { + ++entry->accessing; + locker.UnlockNow(); + result = entry->interface->Control(op, data, length); + --entry->accessing; + } - return B_BAD_INDEX; + return result; } diff --git a/src/add-ons/kernel/network/ppp/ipcp/Jamfile b/src/add-ons/kernel/network/ppp/ipcp/Jamfile index 4c9f420084..d60168c18c 100644 --- a/src/add-ons/kernel/network/ppp/ipcp/Jamfile +++ b/src/add-ons/kernel/network/ppp/ipcp/Jamfile @@ -5,7 +5,7 @@ UsePrivateHeaders net ; UsePrivateHeaders [ FDirName kernel ] ; UsePrivateHeaders [ FDirName kernel util ] ; UseHeaders [ FDirName $(OBOS_TOP) src add-ons kernel network ppp shared libkernelppp headers ] ; -UseHeaders [ FDirName $(OBOS_TOP) src add-ons kernel network ppp shared libkernelppp ] ; + R5KernelAddon ipcp : kernel obos_network ppp : # imported from libnet diff --git a/src/add-ons/kernel/network/ppp/ipcp/Protocol.h b/src/add-ons/kernel/network/ppp/ipcp/Protocol.h index 801013f2cd..7c7e2f4806 100644 --- a/src/add-ons/kernel/network/ppp/ipcp/Protocol.h +++ b/src/add-ons/kernel/network/ppp/ipcp/Protocol.h @@ -23,8 +23,8 @@ typedef struct ip_item { uint8 type; uint8 length; - in_addr_t address _PACKED; -} ip_item; + in_addr_t address; +} _PACKED ip_item; enum ipcp_configure_item_codes { diff --git a/src/add-ons/kernel/network/ppp/modem/Jamfile b/src/add-ons/kernel/network/ppp/modem/Jamfile index df13edabbe..ecc4c3ff32 100644 --- a/src/add-ons/kernel/network/ppp/modem/Jamfile +++ b/src/add-ons/kernel/network/ppp/modem/Jamfile @@ -5,7 +5,6 @@ UsePrivateHeaders net ; UsePrivateHeaders [ FDirName kernel ] ; UsePrivateHeaders [ FDirName kernel util ] ; UseHeaders [ FDirName $(OBOS_TOP) src add-ons kernel network ppp shared libkernelppp headers ] ; -UseHeaders [ FDirName $(OBOS_TOP) src add-ons kernel network ppp shared libkernelppp ] ; R5KernelAddon modem : kernel obos_network ppp : diff --git a/src/add-ons/kernel/network/ppp/pap/Jamfile b/src/add-ons/kernel/network/ppp/pap/Jamfile index 0062b759c9..0209cdbb2e 100644 --- a/src/add-ons/kernel/network/ppp/pap/Jamfile +++ b/src/add-ons/kernel/network/ppp/pap/Jamfile @@ -5,7 +5,6 @@ UsePrivateHeaders net ; UsePrivateHeaders [ FDirName kernel ] ; UsePrivateHeaders [ FDirName kernel util ] ; UseHeaders [ FDirName $(OBOS_TOP) src add-ons kernel network ppp shared libkernelppp headers ] ; -UseHeaders [ FDirName $(OBOS_TOP) src add-ons kernel network ppp shared libkernelppp ] ; R5KernelAddon pap : kernel obos_network ppp : diff --git a/src/add-ons/kernel/network/ppp/pap/Protocol.cpp b/src/add-ons/kernel/network/ppp/pap/Protocol.cpp index 397f5c43ec..55ba991118 100644 --- a/src/add-ons/kernel/network/ppp/pap/Protocol.cpp +++ b/src/add-ons/kernel/network/ppp/pap/Protocol.cpp @@ -28,8 +28,8 @@ typedef struct authentication_item { uint8 type; uint8 length; - uint16 protocolNumber _PACKED; -} authentication_item; + uint16 protocolNumber; +} _PACKED authentication_item; PAPHandler::PAPHandler(PAP& owner, KPPPInterface& interface) diff --git a/src/add-ons/kernel/network/ppp/pppoe/DiscoveryPacket.cpp b/src/add-ons/kernel/network/ppp/pppoe/DiscoveryPacket.cpp index 02752d1352..a15cb04c74 100644 --- a/src/add-ons/kernel/network/ppp/pppoe/DiscoveryPacket.cpp +++ b/src/add-ons/kernel/network/ppp/pppoe/DiscoveryPacket.cpp @@ -42,7 +42,7 @@ DiscoveryPacket::DiscoveryPacket(struct mbuf *packet, uint32 start = 0) tag = (pppoe_tag*) (header->data + position); position += ntohs(tag->length) + 4; - AddTag(ntohs(tag->type), ntohs(tag->length), tag->data); + AddTag(ntohs(tag->type), tag->data, ntohs(tag->length)); } fInitStatus = B_OK; @@ -57,7 +57,7 @@ DiscoveryPacket::~DiscoveryPacket() bool -DiscoveryPacket::AddTag(uint16 type, uint16 length, void *data, int32 index = -1) +DiscoveryPacket::AddTag(uint16 type, const void *data, uint16 length, int32 index = -1) { pppoe_tag *add = (pppoe_tag*) malloc(length + 4); add->type = type; diff --git a/src/add-ons/kernel/network/ppp/pppoe/DiscoveryPacket.h b/src/add-ons/kernel/network/ppp/pppoe/DiscoveryPacket.h index c037175d1c..07427a15d2 100644 --- a/src/add-ons/kernel/network/ppp/pppoe/DiscoveryPacket.h +++ b/src/add-ons/kernel/network/ppp/pppoe/DiscoveryPacket.h @@ -61,7 +61,7 @@ class DiscoveryPacket { uint16 SessionID() const { return fSessionID; } - bool AddTag(uint16 type, uint16 length, void *data, int32 index = -1); + bool AddTag(uint16 type, const void *data, uint16 length, int32 index = -1); bool RemoveTag(pppoe_tag *tag); int32 CountTags() const { return fTags.CountItems(); } diff --git a/src/add-ons/kernel/network/ppp/pppoe/Jamfile b/src/add-ons/kernel/network/ppp/pppoe/Jamfile index 080421ffe2..934cd6d86b 100644 --- a/src/add-ons/kernel/network/ppp/pppoe/Jamfile +++ b/src/add-ons/kernel/network/ppp/pppoe/Jamfile @@ -5,7 +5,6 @@ UsePrivateHeaders net ; UsePrivateHeaders [ FDirName kernel ] ; UsePrivateHeaders [ FDirName kernel util ] ; UseHeaders [ FDirName $(OBOS_TOP) src add-ons kernel network ppp shared libkernelppp headers ] ; -UseHeaders [ FDirName $(OBOS_TOP) src add-ons kernel network ppp shared libkernelppp ] ; R5KernelAddon pppoe : kernel obos_network ppp : diff --git a/src/add-ons/kernel/network/ppp/pppoe/PPPoE.h b/src/add-ons/kernel/network/ppp/pppoe/PPPoE.h index a71ccb42c8..0817a223b1 100644 --- a/src/add-ons/kernel/network/ppp/pppoe/PPPoE.h +++ b/src/add-ons/kernel/network/ppp/pppoe/PPPoE.h @@ -20,11 +20,14 @@ class PPPoEDevice; #define PPPoE_TIMEOUT 3000000 // 3 seconds #define PPPoE_MAX_ATTEMPTS 2 + // maximum number of PPPoE's dial-retries #define PPPoE_VERSION 0x1 #define PPPoE_TYPE 0x1 #define PPPoE_INTERFACE_KEY "interface" +#define PPPoE_AC_NAME_KEY "ACName" +#define PPPoE_SERVICE_NAME_KEY "ServiceName" extern struct core_module_info *core; @@ -36,7 +39,7 @@ typedef struct pppoe_header { uint16 sessionID; uint16 length; uint8 data[0]; -} pppoe_header _PACKED; +} _PACKED pppoe_header; typedef struct complete_pppoe_header { struct ether_header ethernetHeader; diff --git a/src/add-ons/kernel/network/ppp/pppoe/PPPoEDevice.cpp b/src/add-ons/kernel/network/ppp/pppoe/PPPoEDevice.cpp index c09909c6e6..db1d13f246 100644 --- a/src/add-ons/kernel/network/ppp/pppoe/PPPoEDevice.cpp +++ b/src/add-ons/kernel/network/ppp/pppoe/PPPoEDevice.cpp @@ -49,8 +49,6 @@ PPPoEDevice::PPPoEDevice(KPPPInterface& interface, driver_parameter *settings) fEthernetIfnet(NULL), fSessionID(0), fHostUniq(NewHostUniq()), - fACName(NULL), - fServiceName(NULL), fAttempts(0), fNextTimeout(0), fState(INITIAL) @@ -72,17 +70,14 @@ PPPoEDevice::PPPoEDevice(KPPPInterface& interface, driver_parameter *settings) const char *interfaceName = get_parameter_value(PPPoE_INTERFACE_KEY, settings); if(!interfaceName) return; -#if DEBUG - dprintf("PPPoEDevice::ctor: interfaceName: %s\n", interfaceName); -#endif + + fACName = get_parameter_value(PPPoE_AC_NAME_KEY, settings); + fServiceName = get_parameter_value(PPPoE_SERVICE_NAME_KEY, settings); ifnet *current = get_interfaces(); for(; current; current = current->if_next) { if(current->if_type == IFT_ETHER && current->if_name && !strcmp(current->if_name, interfaceName)) { -#if DEBUG - dprintf("PPPoEDevice::ctor: found ethernet interface\n"); -#endif fEthernetIfnet = current; break; } @@ -104,9 +99,6 @@ PPPoEDevice::~PPPoEDevice() #endif remove_device(this); - - free(fACName); - free(fServiceName); } @@ -147,12 +139,12 @@ PPPoEDevice::Up() // create PADI DiscoveryPacket discovery(PADI); - if(fServiceName) - discovery.AddTag(SERVICE_NAME, strlen(fServiceName), fServiceName); + if(ServiceName()) + discovery.AddTag(SERVICE_NAME, ServiceName(), strlen(ServiceName())); else - discovery.AddTag(SERVICE_NAME, 0, NULL); - discovery.AddTag(HOST_UNIQ, sizeof(fHostUniq), &fHostUniq); - discovery.AddTag(END_OF_LIST, 0, NULL); + discovery.AddTag(SERVICE_NAME, NULL, 0); + discovery.AddTag(HOST_UNIQ, &fHostUniq, sizeof(fHostUniq)); + discovery.AddTag(END_OF_LIST, NULL, 0); // set up PPP header struct mbuf *packet = discovery.ToMbuf(MTU()); @@ -220,7 +212,7 @@ PPPoEDevice::Down() // create PADT DiscoveryPacket discovery(PADT, SessionID()); - discovery.AddTag(END_OF_LIST, 0, NULL); + discovery.AddTag(END_OF_LIST, NULL, 0); struct mbuf *packet = discovery.ToMbuf(MTU()); if(!packet) { @@ -388,23 +380,35 @@ PPPoEDevice::Receive(struct mbuf *packet, uint16 protocolNumber = 0) return B_OK; } - bool hasServiceName = false; + bool hasServiceName = false, hasACName = false; pppoe_tag *tag; DiscoveryPacket reply(PADR); for(int32 index = 0; index < discovery.CountTags(); index++) { tag = discovery.TagAt(index); switch(tag->type) { case SERVICE_NAME: - if(!hasServiceName && (!fServiceName - || !memcmp(tag->data, fServiceName, tag->length))) { + if(!hasServiceName && (!ServiceName() + || (strlen(ServiceName()) == tag->length) + && !memcmp(tag->data, ServiceName(), + tag->length))) { hasServiceName = true; - reply.AddTag(tag->type, tag->length, tag->data); + reply.AddTag(tag->type, tag->data, tag->length); + } + break; + + case AC_NAME: + if(!hasACName && (!ACName() + || (strlen(ACName()) == tag->length) + && !memcmp(tag->data, ACName(), + tag->length))) { + hasACName = true; + reply.AddTag(tag->type, tag->data, tag->length); } break; case AC_COOKIE: case RELAY_SESSION_ID: - reply.AddTag(tag->type, tag->length, tag->data); + reply.AddTag(tag->type, tag->data, tag->length); break; case SERVICE_NAME_ERROR: @@ -424,8 +428,8 @@ PPPoEDevice::Receive(struct mbuf *packet, uint16 protocolNumber = 0) return B_ERROR; } - reply.AddTag(HOST_UNIQ, sizeof(fHostUniq), &fHostUniq); - reply.AddTag(END_OF_LIST, 0, NULL); + reply.AddTag(HOST_UNIQ, &fHostUniq, sizeof(fHostUniq)); + reply.AddTag(END_OF_LIST, NULL, 0); struct mbuf *replyPacket = reply.ToMbuf(MTU()); if(!replyPacket) { m_freem(packet); diff --git a/src/add-ons/kernel/network/ppp/pppoe/PPPoEDevice.h b/src/add-ons/kernel/network/ppp/pppoe/PPPoEDevice.h index 2282a7f645..f7d1c78a68 100644 --- a/src/add-ons/kernel/network/ppp/pppoe/PPPoEDevice.h +++ b/src/add-ons/kernel/network/ppp/pppoe/PPPoEDevice.h @@ -63,7 +63,7 @@ class PPPoEDevice : public KPPPDevice { uint8 fPeer[6]; uint16 fSessionID; uint32 fHostUniq; - char *fACName, *fServiceName; + const char *fACName, *fServiceName; uint32 fAttempts; bigtime_t fNextTimeout; diff --git a/src/add-ons/kernel/network/ppp/pppoe/TODO b/src/add-ons/kernel/network/ppp/pppoe/TODO index 13f9f21d2d..78891b1e18 100644 --- a/src/add-ons/kernel/network/ppp/pppoe/TODO +++ b/src/add-ons/kernel/network/ppp/pppoe/TODO @@ -1 +1,2 @@ - add support for server mode +- add service-query support (for userland preflet) diff --git a/src/add-ons/kernel/network/ppp/pppoe/pppoe.cpp b/src/add-ons/kernel/network/ppp/pppoe/pppoe.cpp index 2d951994cd..0039a325bd 100644 --- a/src/add-ons/kernel/network/ppp/pppoe/pppoe.cpp +++ b/src/add-ons/kernel/network/ppp/pppoe/pppoe.cpp @@ -141,13 +141,21 @@ add_to(KPPPInterface& mainInterface, KPPPInterface *subInterface, } +static +status_t +control(uint32 op, void *data, size_t length) +{ + return B_ERROR; +} + + static ppp_module_info pppoe_module = { { PPPoE_MODULE_NAME, 0, std_ops }, - NULL, + control, add_to }; @@ -167,6 +175,8 @@ std_ops(int32 op, ...) return B_ERROR; } + set_max_linkhdr(PPPoE_HEADER_SIZE + ETHER_HDR_LEN); + sDevices = new TemplateList; sEthernet->set_pppoe_receiver(pppoe_input); diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPInterface.cpp b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPInterface.cpp index 73d09a532b..00109468e6 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPInterface.cpp +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPInterface.cpp @@ -62,7 +62,6 @@ KPPPInterface::KPPPInterface(const char *name, ppp_interface_entry *entry, const driver_settings *profile, KPPPInterface *parent = NULL) : KPPPLayer(name, PPP_INTERFACE_LEVEL, 2), fID(ID), - fSettings(dup_driver_settings(settings)), fIfnet(NULL), fUpThread(-1), fOpenEventThread(-1), @@ -94,6 +93,7 @@ KPPPInterface::KPPPInterface(const char *name, ppp_interface_entry *entry, { entry->interface = this; + fSettings = dup_driver_settings(settings); fProfile.LoadSettings(profile, fSettings); // add internal modules @@ -659,18 +659,12 @@ KPPPProtocol* KPPPInterface::ProtocolFor(uint16 protocolNumber, KPPPProtocol *start = NULL) const { #if DEBUG - dprintf("KPPPInterface: ProtocolFor(%X), p&=%X\n", protocolNumber, - protocolNumber & 0x7FFF); + dprintf("KPPPInterface: ProtocolFor(%X)\n", protocolNumber); #endif KPPPProtocol *current = start ? start : FirstProtocol(); for(; current; current = current->NextProtocol()) { -#if DEBUG - dprintf("KPPPInterface: ProtocolFor(): c=%X, c&=%X\n", current->ProtocolNumber(), - current->ProtocolNumber() & 0x7FFF); -#endif - if(current->ProtocolNumber() == protocolNumber || (current->Flags() & PPP_INCLUDES_NCP && (current->ProtocolNumber() & 0x7FFF) @@ -1022,6 +1016,8 @@ KPPPInterface::Down() if(InitCheck() != B_OK) return false; + else if(State() == PPP_INITIAL_STATE && Phase() == PPP_DOWN_PHASE) + return true; send_data_with_timeout(fRedialThread, 0, NULL, 0, 200); // the redial thread should be notified that the user wants to disconnect diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPLayer.cpp b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPLayer.cpp index 0f3cd212a4..fa1d6b729e 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPLayer.cpp +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPLayer.cpp @@ -20,6 +20,7 @@ KPPPLayer::KPPPLayer(const char *name, ppp_level level, uint32 overhead) : fInitStatus(B_OK), fOverhead(overhead), fLevel(level), + fName(NULL), fNext(NULL) { SetName(name); diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPProfile.cpp b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPProfile.cpp index cd3d0b6581..d1971967c6 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPProfile.cpp +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPProfile.cpp @@ -83,13 +83,13 @@ KPPPProfile::LoadSettings(const driver_settings *profile, if(name) { sprintf(path, "pppidf/profile/%s", name); void *handle = load_driver_settings(path); - fSettings = dup_driver_settings(get_driver_settings(handle)); - - if(handle) + if(handle) { + fSettings = dup_driver_settings(get_driver_settings(handle)); unload_driver_settings(handle); - - if(fSettings) - return; + + if(fSettings) + return; + } } // ----------------------------- @@ -99,7 +99,7 @@ KPPPProfile::LoadSettings(const driver_settings *profile, } -/*! \brief Finds a parameter with name \a type that has a value of \a name. +/*! \brief Finds a parameter for a module of type \a type and name \a name. This method is intended for modules. @@ -123,7 +123,7 @@ KPPPProfile::SettingsFor(const char *type, const char *name) const if(name) { for(int32 valueIndex = 0; valueIndex < parameter->value_count; valueIndex++) - if(!strcasecmp(parameter->values[index], name)) + if(!strcasecmp(parameter->values[valueIndex], name)) return parameter; } else return parameter; diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPReportManager.cpp b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPReportManager.cpp index 5a007b86cf..13c28502fb 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPReportManager.cpp +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPReportManager.cpp @@ -28,6 +28,9 @@ void KPPPReportManager::EnableReports(ppp_report_type type, thread_id thread, int32 flags = PPP_NO_FLAGS) { + if(thread < 0 || type == PPP_ALL_REPORTS) + return; + LockerHelper locker(fLock); ppp_report_request *request = new ppp_report_request; @@ -42,6 +45,9 @@ KPPPReportManager::EnableReports(ppp_report_type type, thread_id thread, void KPPPReportManager::DisableReports(ppp_report_type type, thread_id thread) { + if(thread < 0) + return; + LockerHelper locker(fLock); ppp_report_request *request; @@ -52,7 +58,7 @@ KPPPReportManager::DisableReports(ppp_report_type type, thread_id thread) if(request->thread != thread) continue; - if(request->type == type || request->type == PPP_ALL_REPORTS) + if(request->type == type || type == PPP_ALL_REPORTS) fReportRequests.RemoveItem(request); } } @@ -61,6 +67,9 @@ KPPPReportManager::DisableReports(ppp_report_type type, thread_id thread) bool KPPPReportManager::DoesReport(ppp_report_type type, thread_id thread) { + if(thread < 0) + return false; + LockerHelper locker(fLock); ppp_report_request *request; @@ -118,53 +127,61 @@ KPPPReportManager::Report(ppp_report_type type, int32 code, void *data, int32 le sizeof(report), PPP_REPORT_TIMEOUT); #if DEBUG - if(result == B_TIMED_OUT) - dprintf("KPPPReportManager::Report(): timed out sending\n"); + if(result == B_TIMED_OUT) + dprintf("KPPPReportManager::Report(): timed out sending\n"); #endif + thread_info info; + if(result == B_BAD_THREAD_ID || result == B_NO_MEMORY) { fReportRequests.RemoveItem(request); --index; continue; - } else if(result == B_OK) { - if(request->flags & PPP_WAIT_FOR_REPLY) { - thread_info info; - - if(request->flags & PPP_NO_REPLY_TIMEOUT) { - sender = -1; - result = B_ERROR; - // always check if the thread still exists - while(sender != request->thread - && get_thread_info(request->thread, &info) - != B_BAD_THREAD_ID) { - result = receive_data_with_timeout(&sender, &code, NULL, 0, - PPP_REPORT_TIMEOUT); - - if(request->flags & PPP_ALLOW_ANY_REPLY_THREAD) - sender = request->thread; - } - } else { - sender = -1; - result = B_OK; - while(sender != request->thread && result == B_OK) { - result = receive_data_with_timeout(&sender, &code, NULL, 0, - PPP_REPORT_TIMEOUT); - - if(request->flags & PPP_ALLOW_ANY_REPLY_THREAD) - sender = request->thread; - } + } else if(result == B_OK && request->flags & PPP_WAIT_FOR_REPLY) { + if(request->flags & PPP_NO_REPLY_TIMEOUT) { + sender = -1; + result = B_ERROR; + // always check if the thread still exists + while(sender != request->thread + && get_thread_info(request->thread, &info) == B_OK) { + result = receive_data_with_timeout(&sender, &code, NULL, 0, + PPP_REPORT_TIMEOUT); + + if(request->flags & PPP_ALLOW_ANY_REPLY_THREAD + && result == B_OK) + sender = request->thread; + } + } else { + sender = -1; + result = B_OK; + while(sender != request->thread && result == B_OK + && get_thread_info(request->thread, &info) == B_OK) { + result = receive_data_with_timeout(&sender, &code, NULL, 0, + PPP_REPORT_TIMEOUT); + + if(request->flags & PPP_ALLOW_ANY_REPLY_THREAD) + sender = request->thread; } - - if(result == B_OK && code != B_OK) - acceptable = false; -#if DEBUG - if(result == B_TIMED_OUT) - dprintf("KPPPReportManager::Report(): reply timed out\n"); -#endif } + + if(sender != request->thread) { +#if DEBUG + dprintf("KPPPReportManager::Report(): sender != requested\n"); +#endif + continue; + } + + if(result == B_OK && code != B_OK) + acceptable = false; +#if DEBUG + if(result == B_TIMED_OUT) + dprintf("KPPPReportManager::Report(): reply timed out\n"); +#endif } - if(request->flags & PPP_REMOVE_AFTER_REPORT) { + // remove thread if it is not existant or if remove-flag is set + if(request->flags & PPP_REMOVE_AFTER_REPORT + || get_thread_info(request->thread, &info) != B_OK) { fReportRequests.RemoveItem(request); --index; } diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPStateMachine.cpp b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPStateMachine.cpp index 6f31c8daf1..c751c16fc5 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPStateMachine.cpp +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPStateMachine.cpp @@ -216,6 +216,10 @@ KPPPStateMachine::LocalAuthenticationRequested() LockerHelper locker(fLock); + Interface().Report(PPP_CONNECTION_REPORT, + PPP_REPORT_LOCAL_AUTHENTICATION_REQUESTED, &fInterface.fID, + sizeof(ppp_interface_id)); + fLocalAuthenticationStatus = PPP_AUTHENTICATING; free(fLocalAuthenticationName); fLocalAuthenticationName = NULL; @@ -274,6 +278,10 @@ KPPPStateMachine::PeerAuthenticationRequested() LockerHelper locker(fLock); + Interface().Report(PPP_CONNECTION_REPORT, + PPP_REPORT_PEER_AUTHENTICATION_REQUESTED, &fInterface.fID, + sizeof(ppp_interface_id)); + fPeerAuthenticationStatus = PPP_AUTHENTICATING; free(fPeerAuthenticationName); fPeerAuthenticationName = NULL; @@ -615,7 +623,7 @@ KPPPStateMachine::DownEvent() if(Interface().Device() && Interface().Device()->IsUp()) return; - // it is not our device that went up... + // it is not our device that went down... Interface().CalculateBaudRate(); @@ -1459,11 +1467,15 @@ KPPPStateMachine::TimerEvent() dprintf("KPPPSM: TimerEvent()\n"); #endif - LockerHelper locker(fLock); - if(fNextTimeout == 0 || fNextTimeout > system_time()) + // We might cause a dead-lock. Thus, abort if we cannot get the lock. + if(fLock.LockWithTimeout(100000) != B_OK) return; + if(fNextTimeout == 0 || fNextTimeout > system_time()) { + fLock.Unlock(); + return; + } fNextTimeout = 0; - locker.UnlockNow(); + fLock.Unlock(); switch(State()) { case PPP_CLOSING_STATE: diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/_KPPPAuthenticationHandler.cpp b/src/add-ons/kernel/network/ppp/shared/libkernelppp/_KPPPAuthenticationHandler.cpp index fa41210cb2..30fbe2e7b2 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/_KPPPAuthenticationHandler.cpp +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/_KPPPAuthenticationHandler.cpp @@ -19,8 +19,8 @@ typedef struct authentication_item { uint8 type; uint8 length; - uint16 protocolNumber _PACKED; -} authentication_item; + uint16 protocolNumber; +} _PACKED authentication_item; _KPPPAuthenticationHandler::_KPPPAuthenticationHandler(KPPPInterface& interface) diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/_KPPPMRUHandler.cpp b/src/add-ons/kernel/network/ppp/shared/libkernelppp/_KPPPMRUHandler.cpp index b1cb2064d8..24c60c29e9 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/_KPPPMRUHandler.cpp +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/_KPPPMRUHandler.cpp @@ -18,8 +18,8 @@ typedef struct mru_item { uint8 type; uint8 length; - uint16 MRU _PACKED; -} mru_item; + uint16 MRU; +} _PACKED mru_item; status_t ParseRequestedItem(mru_item *item, KPPPInterface& interface); diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/PPPControl.h b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/PPPControl.h index fac67344d5..45d7153599 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/PPPControl.h +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/PPPControl.h @@ -33,7 +33,8 @@ enum ppp_control_ops { // ----------------------------------------------------- // PPPManager (the PPP interface module) - PPPC_CREATE_INTERFACE = PPP_OPS_START, + PPPC_CONTROL_MODULE = PPP_OPS_START, + PPPC_CREATE_INTERFACE, PPPC_CREATE_INTERFACE_WITH_NAME, PPPC_DELETE_INTERFACE, PPPC_BRING_INTERFACE_UP, diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/PPPReportDefs.h b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/PPPReportDefs.h index ca4bd02e69..e45b89b78a 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/PPPReportDefs.h +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/PPPReportDefs.h @@ -54,11 +54,13 @@ enum ppp_connection_report_codes { PPP_REPORT_DOWN_SUCCESSFUL = 2, PPP_REPORT_UP_ABORTED = 3, PPP_REPORT_DEVICE_UP_FAILED = 4, - PPP_REPORT_LOCAL_AUTHENTICATION_SUCCESSFUL = 5, - PPP_REPORT_PEER_AUTHENTICATION_SUCCESSFUL = 6, - PPP_REPORT_LOCAL_AUTHENTICATION_FAILED = 7, - PPP_REPORT_PEER_AUTHENTICATION_FAILED = 8, - PPP_REPORT_CONNECTION_LOST = 9 + PPP_REPORT_LOCAL_AUTHENTICATION_REQUESTED = 5, + PPP_REPORT_PEER_AUTHENTICATION_REQUESTED = 6, + PPP_REPORT_LOCAL_AUTHENTICATION_SUCCESSFUL = 7, + PPP_REPORT_PEER_AUTHENTICATION_SUCCESSFUL = 8, + PPP_REPORT_LOCAL_AUTHENTICATION_FAILED = 9, + PPP_REPORT_PEER_AUTHENTICATION_FAILED = 10, + PPP_REPORT_CONNECTION_LOST = 11 }; diff --git a/src/add-ons/kernel/network/ppp/shared/libppp/Jamfile b/src/add-ons/kernel/network/ppp/shared/libppp/Jamfile index ce1ed26b53..9bae7f5855 100644 --- a/src/add-ons/kernel/network/ppp/shared/libppp/Jamfile +++ b/src/add-ons/kernel/network/ppp/shared/libppp/Jamfile @@ -3,10 +3,10 @@ SubDir OBOS_TOP src add-ons kernel network ppp shared libppp ; UsePrivateHeaders net ; UseHeaders [ FDirName $(OBOS_TOP) src add-ons kernel network ppp shared libppp headers ] ; UseHeaders [ FDirName $(OBOS_TOP) src add-ons kernel network ppp shared libkernelppp headers ] ; -UseHeaders [ FDirName $(OBOS_TOP) src add-ons kernel network ppp shared libkernelppp ] ; StaticLibrary ppp : + strlcat.c driver_settings.c settings_tools.cpp @@ -16,5 +16,6 @@ StaticLibrary ppp : PPPManager.cpp ; +SEARCH on [ FGristFiles strlcat.c ] = [ FDirName $(OBOS_TOP) src kernel libroot posix string ] ; SEARCH on [ FGristFiles driver_settings.c ] = [ FDirName $(OBOS_TOP) src kernel libroot os ] ; SEARCH on [ FGristFiles settings_tools.cpp ] = [ FDirName $(OBOS_TOP) src add-ons kernel network ppp shared libkernelppp ] ; diff --git a/src/add-ons/kernel/network/ppp/shared/libppp/PPPInterfaceListener.cpp b/src/add-ons/kernel/network/ppp/shared/libppp/PPPInterfaceListener.cpp index 14d4098896..148c26d186 100644 --- a/src/add-ons/kernel/network/ppp/shared/libppp/PPPInterfaceListener.cpp +++ b/src/add-ons/kernel/network/ppp/shared/libppp/PPPInterfaceListener.cpp @@ -14,7 +14,8 @@ #include -#define REPORT_FLAGS PPP_WAIT_FOR_REPLY | PPP_NO_REPLY_TIMEOUT +#define REPORT_FLAGS PPP_WAIT_FOR_REPLY | PPP_NO_REPLY_TIMEOUT \ + | PPP_ALLOW_ANY_REPLY_THREAD #define QUIT_REPORT_THREAD 'QUIT' @@ -69,7 +70,11 @@ PPPInterfaceListenerThread::Run() message.AddInt32("interface", static_cast(*interfaceID)); } - messenger.SendMessage(&message); + // We might cause a dead-lock. Thus, abort if we cannot get the lock. + BHandler *noHandler = NULL; + // needed to tell compiler which version of SendMessage we want + if(messenger.SendMessage(&message, noHandler, 100000) != B_OK) + send_data(sender, B_OK, NULL, 0); } } @@ -141,17 +146,23 @@ PPPInterfaceListener::SetTarget(BHandler *target) } -void +bool PPPInterfaceListener::WatchInterface(ppp_interface_id ID) { StopWatchingInterfaces(); // enable reports PPPInterface interface(ID); - interface.EnableReports(PPP_CONNECTION_REPORT, fReportThread, REPORT_FLAGS); + if(interface.InitCheck() != B_OK) + return false; + + if(!interface.EnableReports(PPP_CONNECTION_REPORT, fReportThread, REPORT_FLAGS)) + return false; fDoesWatch = true; fWatchingInterface = ID; + + return true; } @@ -184,20 +195,28 @@ PPPInterfaceListener::WatchAllInterfaces() void PPPInterfaceListener::StopWatchingInterfaces() { - // disable reports - int32 count; - PPPInterface interface; - ppp_interface_id *interfaceList; - - interfaceList = Manager().Interfaces(&count); - if(!interfaceList) + if(!fDoesWatch) return; - for(int32 index = 0; index < count; index++) { - interface.SetTo(interfaceList[index]); + if(fWatchingInterface == PPP_UNDEFINED_INTERFACE_ID) { + // disable all reports + int32 count; + PPPInterface interface; + ppp_interface_id *interfaceList; + + interfaceList = Manager().Interfaces(&count); + if(!interfaceList) + return; + + for(int32 index = 0; index < count; index++) { + interface.SetTo(interfaceList[index]); + interface.DisableReports(PPP_ALL_REPORTS, fReportThread); + } + delete interfaceList; + } else { + PPPInterface interface(fWatchingInterface); interface.DisableReports(PPP_ALL_REPORTS, fReportThread); } - delete interfaceList; fDoesWatch = false; fWatchingInterface = PPP_UNDEFINED_INTERFACE_ID; diff --git a/src/add-ons/kernel/network/ppp/shared/libppp/_libppputils.cpp b/src/add-ons/kernel/network/ppp/shared/libppp/_libppputils.cpp index ce267ac47f..8baa5febb6 100644 --- a/src/add-ons/kernel/network/ppp/shared/libppp/_libppputils.cpp +++ b/src/add-ons/kernel/network/ppp/shared/libppp/_libppputils.cpp @@ -9,37 +9,6 @@ #include -// R5 only: strlcat is needed by driver_settings API -/** Concatenates the source string to the destination, writes - * as much as "maxLength" bytes to the dest string. - * Always null terminates the string as long as maxLength is - * larger than the dest string. - * Returns the length of the string that it tried to create - * to be able to easily detect string truncation. - */ -size_t -strlcat(char *dest, const char *source, size_t maxLength) -{ - size_t destLength = strnlen(dest, maxLength); - - // This returns the wrong size, but it's all we can do - if (maxLength == destLength) - return destLength + strlen(source); - - dest += destLength; - maxLength -= destLength; - - size_t i = 0; - for (; i < maxLength - 1 && source[i]; i++) { - dest[i] = source[i]; - } - - dest[i] = '\0'; - - return destLength + i + strlen(source + i); -} - - char* get_stack_driver_path() { diff --git a/src/add-ons/kernel/network/ppp/shared/libppp/headers/PPPInterfaceListener.h b/src/add-ons/kernel/network/ppp/shared/libppp/headers/PPPInterfaceListener.h index b5b51f0bd3..f78dbe6c7c 100644 --- a/src/add-ons/kernel/network/ppp/shared/libppp/headers/PPPInterfaceListener.h +++ b/src/add-ons/kernel/network/ppp/shared/libppp/headers/PPPInterfaceListener.h @@ -40,7 +40,7 @@ class PPPInterfaceListener { const PPPManager& Manager() const { return fManager; } - void WatchInterface(ppp_interface_id ID); + bool WatchInterface(ppp_interface_id ID); void WatchAllInterfaces(); void StopWatchingInterfaces();