From 5c7a44d43649fc821f947909e679503ec5a4dcb8 Mon Sep 17 00:00:00 2001 From: Waldemar Kornewald Date: Sun, 24 Aug 2003 19:43:20 +0000 Subject: [PATCH] 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 --- src/tests/kits/net/ppp/headers/KPPPDevice.h | 3 +- .../kits/net/ppp/headers/KPPPInterface.h | 17 ++- .../kits/net/ppp/headers/KPPPStateMachine.h | 3 +- .../kits/net/ppp/src/KPPPConfigurePacket.cpp | 1 + src/tests/kits/net/ppp/src/KPPPDevice.cpp | 1 + .../kits/net/ppp/src/KPPPEncapsulator.cpp | 1 + src/tests/kits/net/ppp/src/KPPPInterface.cpp | 115 +++++++++++++++--- .../kits/net/ppp/src/KPPPOptionHandler.cpp | 1 + src/tests/kits/net/ppp/src/KPPPProtocol.cpp | 1 + .../kits/net/ppp/src/KPPPStateMachine.cpp | 37 ++++-- 10 files changed, 145 insertions(+), 35 deletions(-) create mode 100644 src/tests/kits/net/ppp/src/KPPPConfigurePacket.cpp create mode 100644 src/tests/kits/net/ppp/src/KPPPDevice.cpp create mode 100644 src/tests/kits/net/ppp/src/KPPPEncapsulator.cpp create mode 100644 src/tests/kits/net/ppp/src/KPPPOptionHandler.cpp create mode 100644 src/tests/kits/net/ppp/src/KPPPProtocol.cpp diff --git a/src/tests/kits/net/ppp/headers/KPPPDevice.h b/src/tests/kits/net/ppp/headers/KPPPDevice.h index 1f1d80990c..80ca16dd17 100644 --- a/src/tests/kits/net/ppp/headers/KPPPDevice.h +++ b/src/tests/kits/net/ppp/headers/KPPPDevice.h @@ -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; diff --git a/src/tests/kits/net/ppp/headers/KPPPInterface.h b/src/tests/kits/net/ppp/headers/KPPPInterface.h index c643421907..5c7d6b069c 100644 --- a/src/tests/kits/net/ppp/headers/KPPPInterface.h +++ b/src/tests/kits/net/ppp/headers/KPPPInterface.h @@ -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; diff --git a/src/tests/kits/net/ppp/headers/KPPPStateMachine.h b/src/tests/kits/net/ppp/headers/KPPPStateMachine.h index 374df75f1d..6f6c442a03 100644 --- a/src/tests/kits/net/ppp/headers/KPPPStateMachine.h +++ b/src/tests/kits/net/ppp/headers/KPPPStateMachine.h @@ -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; }; diff --git a/src/tests/kits/net/ppp/src/KPPPConfigurePacket.cpp b/src/tests/kits/net/ppp/src/KPPPConfigurePacket.cpp new file mode 100644 index 0000000000..eede15ed97 --- /dev/null +++ b/src/tests/kits/net/ppp/src/KPPPConfigurePacket.cpp @@ -0,0 +1 @@ +#include "KPPPConfigurePacket.h" diff --git a/src/tests/kits/net/ppp/src/KPPPDevice.cpp b/src/tests/kits/net/ppp/src/KPPPDevice.cpp new file mode 100644 index 0000000000..a73fcd2d8b --- /dev/null +++ b/src/tests/kits/net/ppp/src/KPPPDevice.cpp @@ -0,0 +1 @@ +#include "KPPPDevice.h" diff --git a/src/tests/kits/net/ppp/src/KPPPEncapsulator.cpp b/src/tests/kits/net/ppp/src/KPPPEncapsulator.cpp new file mode 100644 index 0000000000..fb1edc5811 --- /dev/null +++ b/src/tests/kits/net/ppp/src/KPPPEncapsulator.cpp @@ -0,0 +1 @@ +#include "KPPPEncapsulator.h" diff --git a/src/tests/kits/net/ppp/src/KPPPInterface.cpp b/src/tests/kits/net/ppp/src/KPPPInterface.cpp index 7a5a08beca..50262eeb19 100644 --- a/src/tests/kits/net/ppp/src/KPPPInterface.cpp +++ b/src/tests/kits/net/ppp/src/KPPPInterface.cpp @@ -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; +} diff --git a/src/tests/kits/net/ppp/src/KPPPOptionHandler.cpp b/src/tests/kits/net/ppp/src/KPPPOptionHandler.cpp new file mode 100644 index 0000000000..08598992bd --- /dev/null +++ b/src/tests/kits/net/ppp/src/KPPPOptionHandler.cpp @@ -0,0 +1 @@ +#include "KPPPOptionHandler.h" diff --git a/src/tests/kits/net/ppp/src/KPPPProtocol.cpp b/src/tests/kits/net/ppp/src/KPPPProtocol.cpp new file mode 100644 index 0000000000..ac9a677cfc --- /dev/null +++ b/src/tests/kits/net/ppp/src/KPPPProtocol.cpp @@ -0,0 +1 @@ +#include "KPPPProtocol.h" diff --git a/src/tests/kits/net/ppp/src/KPPPStateMachine.cpp b/src/tests/kits/net/ppp/src/KPPPStateMachine.cpp index 03a867d1d8..620164afec 100644 --- a/src/tests/kits/net/ppp/src/KPPPStateMachine.cpp +++ b/src/tests/kits/net/ppp/src/KPPPStateMachine.cpp @@ -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(); }