Added empty .cpp files for the remaining classes.

Finished Down().
Added input queue to PPPInterface.
Added initial timeout handling.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4370 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Waldemar Kornewald 2003-08-24 19:43:20 +00:00
parent 770108b448
commit 5c7a44d436
10 changed files with 145 additions and 35 deletions

View File

@ -6,7 +6,8 @@
class PPPDevice {
public:
PPPDevice(const char *fName, uint32 overhead, PPPInterface *interface, driver_parameter *settings);
PPPDevice(const char *fName, uint32 overhead, PPPInterface *interface,
driver_parameter *settings);
virtual ~PPPDevice();
virtual status_t InitCheck() const = 0;

View File

@ -42,9 +42,12 @@ class PPPInterface {
PPPLCP& LCP() const
{ return fLCP; }
ifnet *Ifnet() const
struct ifnet *Ifnet() const
{ return fIfnet; }
struct ifq *InQueue() const
{ return fInQueue; }
void SetLinkMTU(uint32 linkMTU);
uint32 LinkMTU() const
{ return fLinkMTU; }
@ -103,6 +106,8 @@ class PPPInterface {
bool Down();
bool IsUp() const;
PPPReportManager& ReportManager() const
{ return fReportManager; }
bool Report(PPP_REPORT_TYPE type, int32 code, void *data, int32 length)
{ fReportManager.Report(type, code, data, length); }
// returns false if reply was bad (or an error occured)
@ -119,6 +124,9 @@ class PPPInterface {
// This is called by the receive-thread.
// Only call this if it does not block Send() or
// SendToDevice()!
void Pulse();
// this manages all timeouts, etc.
private:
bool RegisterInterface();
@ -139,9 +147,12 @@ class PPPInterface {
PPPStateMachine fStateMachine;
PPPLCP fLCP;
PPPReportManager fReportManager;
ifnet *fIfnet;
struct ifnet *fIfnet;
thread_id fUpThread, fRedialThread;
thread_id fUpThread, fInQueueThread;
struct ifq *fInQueue;
thread_id fRedialThread;
uint32 fDialRetry, fDialRetriesLimit;
ppp_manager_info *fManager;

View File

@ -143,8 +143,7 @@ class PPPStateMachine {
int32 fRequestCounter, fTerminateCounter, fNakCounter;
uint8 fRequestID, fTerminateID;
// the ID we used for the last configure/terminate request
bigtime_t fTimeout;
// last time we sent a packet
bigtime_t fNextTimeout;
};

View File

@ -0,0 +1 @@
#include "KPPPConfigurePacket.h"

View File

@ -0,0 +1 @@
#include "KPPPDevice.h"

View File

@ -0,0 +1 @@
#include "KPPPEncapsulator.h"

View File

@ -32,15 +32,22 @@ typedef struct redial_info {
status_t redial_func(void *data);
// other functions
status_t in_queue_thread(void *data);
PPPInterface::PPPInterface(driver_settings *settings, PPPInterface *parent = NULL)
: fSettings(dup_driver_settings(settings)),
fStateMachine(*this), fLCP(*this), fReportManager(StateMachine().Locker()),
fStateMachine(*this), fLCP(*this), ReportManager()(StateMachine().Locker()),
fIfnet(NULL), fUpThread(-1), fRedialThread(-1), fDialRetry(0),
fDialRetriesLimit(0), fLinkMTU(1500), fAccessing(0), fChildrenCount(0),
fDevice(NULL), fFirstEncapsulator(NULL), fLock(StateMachine().Locker())
{
fInQueue = start_ifq();
fInQueueThread = spawn_kernel_thread(in_queue_thread, "PPPInterface: Input",
B_NORMAL_PRIORITY, this);
resume_thread(fInQueueThread);
if(get_module(PPP_MANAGER_MODULE_NAME, (module_info**) &fManager) != B_OK)
fManager = NULL;
@ -87,9 +94,16 @@ PPPInterface::PPPInterface(driver_settings *settings, PPPInterface *parent = NUL
PPPInterface::~PPPInterface()
{
fLock.Lock();
// make sure no thread wants to call Unlock() on fLock after it is deleted
Report(PPP_DESTRUCTION_REPORT, 0, NULL, 0);
// tell all listeners that we are being destroyed
int32 tmp;
stop_ifq(InQueue());
wait_for_thread(fInQueueThread, &tmp);
// TODO:
// kill (or wait for) fRedialThread
// remove our iface, so that nobody will access it:
@ -185,6 +199,9 @@ PPPInterface::SetDevice(PPPDevice *device)
fDevice = device;
fLinkMTU = fDevice->MTU();
if(Ifnet())
Ifnet()->if_baudrate = max(fDevice->InputTransferRate(),
fDevice->OutputTransferRate());
CalculateMRU();
}
@ -440,7 +457,7 @@ PPPInterface::Up()
if(fUpThread == -1)
fUpThread = me;
fReportManager.EnableReports(PPP_CONNECTION_REPORT, me, PPP_WAIT_FOR_REPLY);
ReportManager().EnableReports(PPP_CONNECTION_REPORT, me, PPP_WAIT_FOR_REPLY);
fLock.Unlock();
// fUpThread tells the state machine to go up
@ -449,7 +466,7 @@ PPPInterface::Up()
while(true) {
if(IsUp()) {
fReportManager.DisableReports(PPP_CONNECTION_REPORT, me);
ReportManager().DisableReports(PPP_CONNECTION_REPORT, me);
if(me == fUpThread) {
fLock.Lock();
@ -471,7 +488,7 @@ PPPInterface::Up()
}
PPP_REPLY(sender, B_OK);
fReportManager.DisableReports(PPP_CONNECTION_REPORT, me);
ReportManager().DisableReports(PPP_CONNECTION_REPORT, me);
return true;
}
@ -483,7 +500,7 @@ PPPInterface::Up()
}
PPP_REPLY(sender, B_OK);
fReportManager.DisableReports(PPP_CONNECTION_REPORT, me);
ReportManager().DisableReports(PPP_CONNECTION_REPORT, me);
return false;
} else if(report.type != PPP_CONNECTION_REPORT) {
PPP_REPLY(sender, B_OK);
@ -500,7 +517,7 @@ PPPInterface::Up()
}
PPP_REPLY(sender, B_OK);
fReportManager.DisableReports(PPP_CONNECTION_REPORT, me);
ReportManager().DisableReports(PPP_CONNECTION_REPORT, me);
return true;
} else if(report.code == PPP_REPORT_DOWN_SUCCESSFUL
|| report.code == PPP_REPORT_UP_ABORTED
@ -514,7 +531,7 @@ PPPInterface::Up()
}
PPP_REPLY(sender, B_OK);
fReportManager.DisableReports(PPP_CONNECTION_REPORT, me);
ReportManager().DisableReports(PPP_CONNECTION_REPORT, me);
return false;
}
@ -523,7 +540,7 @@ PPPInterface::Up()
if(report.code == PPP_REPORT_DEVICE_UP_FAILED) {
if(fDialRetry >= fDialRetriesLimit || fUpThread == -1) {
PPP_REPLY(sender, B_OK);
fReportManager.DisableReports(PPP_CONNECTION_REPORT, me);
ReportManager().DisableReports(PPP_CONNECTION_REPORT, me);
return false;
} else {
PPP_REPLY(sender, B_OK);
@ -535,7 +552,7 @@ PPPInterface::Up()
continue;
} else {
PPP_REPLY(sender, B_OK);
fReportManager.DisableReports(PPP_CONNECTION_REPORT, me);
ReportManager().DisableReports(PPP_CONNECTION_REPORT, me);
return false;
}
}
@ -551,7 +568,7 @@ PPPInterface::Up()
fManager->delete_interface(this);
PPP_REPLY(sender, B_OK);
fReportManager.DisableReports(PPP_CONNECTION_REPORT, me);
ReportManager().DisableReports(PPP_CONNECTION_REPORT, me);
return false;
} else {
++fDialRetry;
@ -571,7 +588,7 @@ PPPInterface::Up()
fDialRetry = 0;
fUpThread = -1;
PPP_REPLY(sender, B_OK);
fReportManager.DisableReports(PPP_CONNECTION_REPORT, me);
ReportManager().DisableReports(PPP_CONNECTION_REPORT, me);
if(!DoesDialOnDemand()
&& report.code != PPP_REPORT_DOWN_SUCCESSFUL)
@ -590,23 +607,39 @@ PPPInterface::Up()
bool
PPPInterface::Down()
{
// ToDo:
// instead of waiting for state change we should wait until
// all retries are done
if(!InitCheck())
return false;
// TODO:
// Add one-time connection report request.
// this locked section guarantees that there are no state changes before we
// enable the connection reports
LockerHelper locker(fLock);
if(State() == PPP_INITIAL_STATE && Phase() == PPP_DOWN_PHASE)
return true;
ReportManager().EnableReports(PPP_CONNECTION_REPORT, find_thread(NULL));
locker.UnlockNow();
thread_id sender;
ppp_report_packet report;
StateMachine().CloseEvent();
while(true) {
if(receive_data(&sender, &report, sizeof(report)) != PPP_REPORT_CODE)
continue;
if(report.code == PPP_REPORT_DOWN_SUCCESSFUL
|| report.code == PPP_REPORT_UP_ABORTED
|| (State() == PPP_INITIAL_STATE && Phase() == PPP_DOWN_PHASE)) {
ReportManager().DisableReports(PPP_CONNECTION_REPORT, find_thread(NULL));
break;
}
}
// All attempts to connect have failed.
if(!DoesDialOnDemand())
fManager->delete_interface(this);
return false;
return true;
}
@ -936,6 +969,16 @@ PPPInterface::ReceiveFromDevice(mbuf *packet)
}
void
PPPInterface::Pulse()
{
// TODO:
// check our idle time
StateMachine().TimerEvent();
}
bool
PPPInterface::RegisterInterface()
{
@ -959,6 +1002,10 @@ PPPInterface::RegisterInterface()
if(!fIfnet)
return false;
if(Device())
fIfnet->if_baudrate = max(Device()->InputTransferRate(),
Device()->OutputTransferRate());
return true;
}
@ -1021,8 +1068,10 @@ PPPInterface::Redial()
info.interface = this;
info.thread = &fRedialThread;
fRedialThread = spawn_thread(redial_func, "PPPInterface: redial_thread",
fRedialThread = spawn_kernel_thread(redial_func, "PPPInterface: redial_thread",
B_NORMAL_PRIORITY, info);
resume_thread(fRedialThread);
}
@ -1036,3 +1085,29 @@ redial_func(void *data)
delete info;
}
status_t
in_queue_thread(void *data)
{
PPPInterface *interface = (PPPInterface*) data;
struct ifq *queue = interface->InQueue();
mbuf *packet;
status_t error;
while(true) {
error = acquire_sem_etc(queue->pop, 1, B_CAN_INTERRUPT | B_DO_NOT_RESCHEDULE, 0);
if(error == B_INTERRUPTED)
continue;
else if(error != B_NO_ERROR)
break;
IFQ_DEQUEUE(queue, packet);
if(packet)
interface->ReceiveFromDevice(packet);
}
return B_ERROR;
}

View File

@ -0,0 +1 @@
#include "KPPPOptionHandler.h"

View File

@ -0,0 +1 @@
#include "KPPPProtocol.h"

View File

@ -1,6 +1,8 @@
#include "KPPPStateMachine.h"
#define PPP_STATE_MACHINE_TIMEOUT 3000000
// TODO:
// do not forget to reset authentication status when:
// - connection is lost
@ -16,7 +18,7 @@ PPPStateMachine::PPPStateMachine(PPPInterface& interface)
fAuthenticationName(NULL), fPeerAuthenticationName(NULL),
fAuthenticatorIndex(-1), fPeerAuthenticatorIndex(-1),
fMaxTerminate(2), fMaxConfigure(10), fMaxNak(5),
fRequestID(0), fTerminateID(0), fTimeout(0)
fRequestID(0), fTerminateID(0), fNextTimeout(0)
{
}
@ -40,6 +42,9 @@ PPPStateMachine::NextID()
void
PPPStateMachine::NewState(PPP_STATE next)
{
if(next < PPP_CLOSING_STATE || next == PPP_OPENED_STATE)
fNextTimeout = 0;
if(State() == PPP_OPENED_STATE && next != State())
ResetOptionHandlers();
@ -360,6 +365,11 @@ PPPStateMachine::UpEvent()
return;
// it is not our device that went up...
if(Interface()->Ifnet())
Interface()->Ifnet()->if_baudrate = max(
Interface()->Device()->InputTransferRate(),
Interface()->Device()->OutputTransferRate());
switch(State()) {
case PPP_INITIAL_STATE:
if(Mode() != PPP_SERVER_MODE
@ -411,6 +421,15 @@ PPPStateMachine::DownEvent()
{
LockerHelper locker(fLock);
if(!Interface()->Device() || Interface()->Device->IsUp())
return;
// it is not our device that went up...
if(Interface()->Ifnet())
Interface()->Ifnet()->if_baudrate = max(
Interface()->Device()->InputTransferRate(),
Interface()->Device()->OutputTransferRate());
switch(State()) {
case PPP_CLOSED_STATE:
case PPP_CLOSING_STATE:
@ -1048,8 +1067,6 @@ PPPStateMachine::RXJBadEvent(mbuf *packet)
void
PPPStateMachine::RXREvent(mbuf *packet)
{
LockerHelper locker(fLock);
lcp_packet *echo = mtod(mbuf, lcp_packet*);
switch(State()) {
@ -1071,6 +1088,10 @@ void
PPPStateMachine::TimerEvent()
{
LockerHelper locker(fLock);
if(fNextTimeout == 0 || fNextTimeout > system_time())
return;
fNextTimeout = 0;
locker.UnlockNow();
switch(State()) {
case PPP_CLOSING_STATE:
@ -1264,8 +1285,8 @@ PPPStateMachine::InitializeRestartCount()
fTerminateCounter = fMaxTerminate;
fNakCounter = fMaxNak;
// TODO:
// start timer
LockerHelper locker(fLock);
fNextTimeout = system_time() + PPP_STATE_MACHINE_TIMEOUT;
}
@ -1276,8 +1297,8 @@ PPPStateMachine::ZeroRestartCount()
fTerminateCounter = 0;
fNakCounter = 0;
// TODO:
// start timer
LockerHelper locker(fLock);
fNextTimeout = system_time() + PPP_STATE_MACHINE_TIMEOUT;
}
@ -1299,8 +1320,6 @@ PPPStateMachine::SendConfigureRequest()
}
LCP().Send(request.ToMbuf());
fTimeout = system_time();
}