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
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 :
|
||||
|
||||
@@ -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 :
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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(); }
|
||||
|
||||
@@ -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 :
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
- add support for server mode
|
||||
- add service-query support (for userland preflet)
|
||||
|
||||
@@ -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<PPPoEDevice*>;
|
||||
|
||||
sEthernet->set_pppoe_receiver(pppoe_input);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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 ] ;
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
#include <LockerHelper.h>
|
||||
|
||||
|
||||
#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<int32>(*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;
|
||||
|
||||
@@ -9,37 +9,6 @@
|
||||
#include <cstring>
|
||||
|
||||
|
||||
// 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()
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user