Worked on events and actions.
StateMachine now waits until all protocols/encapsulators have finished going up before entering next phase. Added StateMachine methods to support main interfaces (multilink). git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4055 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -66,6 +66,9 @@ class PPPEncapsulator {
|
|||||||
// call the interface's SendToDevice function
|
// call the interface's SendToDevice function
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void UpStarted();
|
||||||
|
void DownStarted();
|
||||||
|
|
||||||
void UpFailedEvent();
|
void UpFailedEvent();
|
||||||
void UpEvent();
|
void UpEvent();
|
||||||
void DownEvent();
|
void DownEvent();
|
||||||
|
|||||||
@@ -135,6 +135,8 @@ class PPPInterface {
|
|||||||
PPPLCP fLCP;
|
PPPLCP fLCP;
|
||||||
ifnet *fIfnet;
|
ifnet *fIfnet;
|
||||||
|
|
||||||
|
ppp_manager_info *fManager;
|
||||||
|
|
||||||
uint32 fLinkMTU, fMRU, fHeaderLength;
|
uint32 fLinkMTU, fMRU, fHeaderLength;
|
||||||
|
|
||||||
PPPInterface *fParent;
|
PPPInterface *fParent;
|
||||||
|
|||||||
@@ -51,6 +51,9 @@ class PPPProtocol {
|
|||||||
virtual status_t Receive(mbuf *packet) = 0;
|
virtual status_t Receive(mbuf *packet) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void UpStarted();
|
||||||
|
void DownStarted();
|
||||||
|
|
||||||
void UpFailedEvent();
|
void UpFailedEvent();
|
||||||
void UpEvent();
|
void UpEvent();
|
||||||
void DownEvent();
|
void DownEvent();
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ class PPPStateMachine {
|
|||||||
|
|
||||||
// private StateMachine methods
|
// private StateMachine methods
|
||||||
void NewState(PPP_STATE next);
|
void NewState(PPP_STATE next);
|
||||||
|
void NewPhase(PPP_PHASE next);
|
||||||
|
|
||||||
// private events
|
// private events
|
||||||
void OpenEvent();
|
void OpenEvent();
|
||||||
@@ -92,7 +93,7 @@ class PPPStateMachine {
|
|||||||
void RCNEvent(mbuf *packet);
|
void RCNEvent(mbuf *packet);
|
||||||
void RTREvent(mbuf *packet);
|
void RTREvent(mbuf *packet);
|
||||||
void RTAEvent(mbuf *packet);
|
void RTAEvent(mbuf *packet);
|
||||||
void RUCEvent(mbuf *packet, uint16 protocol);
|
void RUCEvent(mbuf *packet, uint16 protocol, uint8 type);
|
||||||
void RXJGoodEvent(mbuf *packet);
|
void RXJGoodEvent(mbuf *packet);
|
||||||
void RXJBadEvent(mbuf *packet);
|
void RXJBadEvent(mbuf *packet);
|
||||||
void RXREvent(mbuf *packet);
|
void RXREvent(mbuf *packet);
|
||||||
@@ -115,8 +116,11 @@ class PPPStateMachine {
|
|||||||
void SendConfigureNak(mbuf *packet);
|
void SendConfigureNak(mbuf *packet);
|
||||||
void SendTerminateRequest();
|
void SendTerminateRequest();
|
||||||
void SendTerminateAck(mbuf *request);
|
void SendTerminateAck(mbuf *request);
|
||||||
void SendCodeReject(mbuf *packet, uint16 protocol);
|
void SendCodeReject(mbuf *packet, uint16 protocol, uint8 type);
|
||||||
void SendEchoReply(mbuf *request);
|
void SendEchoReply(mbuf *request);
|
||||||
|
|
||||||
|
void BringHandlersUp();
|
||||||
|
uint32 BringPhaseUp();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PPPInterface *fInterface;
|
PPPInterface *fInterface;
|
||||||
|
|||||||
@@ -29,6 +29,9 @@ PPPInterface::PPPInterface(driver_settings *settings, PPPInterface *parent = NUL
|
|||||||
fAccessing(0), fChildrenCount(0), fDevice(NULL), fFirstEncapsulator(NULL),
|
fAccessing(0), fChildrenCount(0), fDevice(NULL), fFirstEncapsulator(NULL),
|
||||||
fGeneralLock(StateMachine().Locker())
|
fGeneralLock(StateMachine().Locker())
|
||||||
{
|
{
|
||||||
|
if(get_module(PPP_MANAGER_MODULE_NAME, (module_info**) &fManager) != B_OK)
|
||||||
|
fManager = NULL;
|
||||||
|
|
||||||
// are we a multilink subinterface?
|
// are we a multilink subinterface?
|
||||||
if(parent && parent->IsMultilink()) {
|
if(parent && parent->IsMultilink()) {
|
||||||
fParent = parent;
|
fParent = parent;
|
||||||
@@ -72,6 +75,8 @@ PPPInterface::PPPInterface(driver_settings *settings, PPPInterface *parent = NUL
|
|||||||
|
|
||||||
PPPInterface::~PPPInterface()
|
PPPInterface::~PPPInterface()
|
||||||
{
|
{
|
||||||
|
put_module((module_info**) &fManager);
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// remove our iface, so that nobody will access it:
|
// remove our iface, so that nobody will access it:
|
||||||
// go down if up
|
// go down if up
|
||||||
@@ -89,7 +94,7 @@ PPPInterface::~PPPInterface()
|
|||||||
status_t
|
status_t
|
||||||
PPPInterface::InitCheck() const
|
PPPInterface::InitCheck() const
|
||||||
{
|
{
|
||||||
if(!fSettings)
|
if(!fSettings || !fManager)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
// sub-interfaces should have a device
|
// sub-interfaces should have a device
|
||||||
@@ -118,14 +123,10 @@ PPPInterface::RegisterInterface()
|
|||||||
if(IsMultilink() && Parent() && Parent()->RegisterInterface())
|
if(IsMultilink() && Parent() && Parent()->RegisterInterface())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
ppp_manager_info *manager;
|
if(!fManager)
|
||||||
if(get_module(PPP_MANAGER_MODULE_NAME, (module_info**) &manager) != B_OK)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
fIfnet = manager->add_interface(this);
|
fIfnet = fManager->add_interface(this);
|
||||||
|
|
||||||
put_module((module_info**) &manager);
|
|
||||||
|
|
||||||
|
|
||||||
if(!fIfnet)
|
if(!fIfnet)
|
||||||
return false;
|
return false;
|
||||||
@@ -145,15 +146,12 @@ PPPInterface::UnregisterInterface()
|
|||||||
if(IsMultilink() && Parent())
|
if(IsMultilink() && Parent())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
ppp_manager_info *manager;
|
if(!fManager)
|
||||||
if(get_module(PPP_MANAGER_MODULE_NAME, (module_info**) &manager) != B_OK)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
manager->remove_interface(this);
|
fManager->remove_interface(this);
|
||||||
fIfnet = NULL;
|
fIfnet = NULL;
|
||||||
|
|
||||||
put_module((module_info**) &manager);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -406,6 +404,10 @@ PPPInterface::RemoveChild(PPPInterface *child)
|
|||||||
|
|
||||||
child->SetParent(NULL);
|
child->SetParent(NULL);
|
||||||
|
|
||||||
|
// parents cannot exist without their children
|
||||||
|
if(CountChildren() == 0 && fManager)
|
||||||
|
fManager->delete_interface(this);
|
||||||
|
|
||||||
CalculateMRU();
|
CalculateMRU();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -623,13 +625,13 @@ PPPInterface::Send(mbuf *packet, uint16 protocol)
|
|||||||
|
|
||||||
// we must pass the basic tests!
|
// we must pass the basic tests!
|
||||||
if(InitCheck() != B_OK) {
|
if(InitCheck() != B_OK) {
|
||||||
m_free(packet);
|
m_freem(packet);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// test whether are going down
|
// test whether are going down
|
||||||
if(Phase() == PPP_TERMINATION_PHASE) {
|
if(Phase() == PPP_TERMINATION_PHASE) {
|
||||||
m_free(packet);
|
m_freem(packet);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -646,7 +648,7 @@ PPPInterface::Send(mbuf *packet, uint16 protocol)
|
|||||||
|
|
||||||
// never send normal protocols when we are down
|
// never send normal protocols when we are down
|
||||||
if(!IsUp()) {
|
if(!IsUp()) {
|
||||||
m_free(packet);
|
m_freem(packet);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -722,7 +724,7 @@ PPPInterface::Receive(mbuf *packet, uint16 protocol)
|
|||||||
return Parent->Receive(packet, protocol);
|
return Parent->Receive(packet, protocol);
|
||||||
|
|
||||||
if(result == PPP_UNHANDLED)
|
if(result == PPP_UNHANDLED)
|
||||||
m_free(packet);
|
m_freem(packet);
|
||||||
return PPP_DISCARDED;
|
return PPP_DISCARDED;
|
||||||
else {
|
else {
|
||||||
StateMachine()->RUCEvent(packet, protocol);
|
StateMachine()->RUCEvent(packet, protocol);
|
||||||
@@ -743,13 +745,13 @@ PPPInterface::SendToDevice(mbuf *packet, uint16 protocol)
|
|||||||
// do we have a device (as main interface)?
|
// do we have a device (as main interface)?
|
||||||
// did we load all modules?
|
// did we load all modules?
|
||||||
if(InitCheck() != B_OK) {
|
if(InitCheck() != B_OK) {
|
||||||
m_free(packet);
|
m_freem(packet);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// test whether are going down
|
// test whether are going down
|
||||||
if(Phase() == PPP_TERMINATION_PHASE) {
|
if(Phase() == PPP_TERMINATION_PHASE) {
|
||||||
m_free(packet);
|
m_freem(packet);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -769,12 +771,12 @@ PPPInterface::SendToDevice(mbuf *packet, uint16 protocol)
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
m_free(packet);
|
m_freem(packet);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// encode in ppp frame
|
// encode in ppp frame
|
||||||
M_PREPEND(packet, sizeof(uint16));
|
packet = M_PREPEND(packet, sizeof(uint16));
|
||||||
|
|
||||||
if(packet == NULL)
|
if(packet == NULL)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
@@ -789,14 +791,14 @@ PPPInterface::SendToDevice(mbuf *packet, uint16 protocol)
|
|||||||
// check if packet is too big for device
|
// check if packet is too big for device
|
||||||
if((packet->m_flags & M_PKTHDR && packet->m_pkt_hdr.len > LinkMTU())
|
if((packet->m_flags & M_PKTHDR && packet->m_pkt_hdr.len > LinkMTU())
|
||||||
|| packet->m_len > LinkMTU()) {
|
|| packet->m_len > LinkMTU()) {
|
||||||
m_free(packet);
|
m_freem(packet);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Device()->Send(packet);
|
return Device()->Send(packet);
|
||||||
} else {
|
} else {
|
||||||
// the multilink encapsulator should have sent it to some child interface
|
// the multilink encapsulator should have sent it to some child interface
|
||||||
m_free(packet);
|
m_freem(packet);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -811,7 +813,7 @@ PPPInterface::ReceiveFromDevice(mbuf *packet)
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
if(!InitCheck()) {
|
if(!InitCheck()) {
|
||||||
m_free(packet);
|
m_freem(packet);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -827,7 +829,7 @@ PPPInterface::ReceiveFromDevice(mbuf *packet)
|
|||||||
// the packet
|
// the packet
|
||||||
|
|
||||||
if(!packet->m_pkthdr.rcvif) {
|
if(!packet->m_pkthdr.rcvif) {
|
||||||
m_free(packet);
|
m_freem(packet);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -852,15 +854,11 @@ PPPInterface::CalculateMRU()
|
|||||||
|
|
||||||
fMRU -= fHeaderLength;
|
fMRU -= fHeaderLength;
|
||||||
|
|
||||||
if(Parent())
|
|
||||||
Parent()->CalculateMRU();
|
|
||||||
|
|
||||||
for(int32 i = 0; i < fChildren.CountItems(); i++)
|
|
||||||
fMRU += fChildren.ItemAt(i)->MRU();
|
|
||||||
// add our subinterfaces' MRU (so we have the MRRU)
|
|
||||||
|
|
||||||
if(Ifnet()) {
|
if(Ifnet()) {
|
||||||
Ifnet()->if_mtu = fMRU;
|
Ifnet()->if_mtu = fMRU;
|
||||||
Ifnet()->if_hdrlen = fHeaderLength;
|
Ifnet()->if_hdrlen = fHeaderLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(Parent())
|
||||||
|
Parent()->CalculateMRU();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
#include "KPPPStateMachine.h"
|
#include "KPPPStateMachine.h"
|
||||||
|
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
// do not forget to reset authentication status when needed
|
||||||
|
|
||||||
PPPStateMachine::PPPStateMachine(PPPInterface& interface)
|
PPPStateMachine::PPPStateMachine(PPPInterface& interface)
|
||||||
: fInterface(&interface), fPhase(PPP_DOWN_PHASE),
|
: fInterface(&interface), fPhase(PPP_DOWN_PHASE),
|
||||||
fState(PPP_INITIAL_STATE), fID(system_time() & 0xFF),
|
fState(PPP_INITIAL_STATE), fID(system_time() & 0xFF),
|
||||||
fAuthenticationStatus(PPP_NOT_AUTHENTICATED),
|
fAuthenticationStatus(PPP_NOT_AUTHENTICATED),
|
||||||
fPeerAuthenticationStatus(PPP_NOT_AUTHENTICATED),
|
fPeerAuthenticationStatus(PPP_NOT_AUTHENTICATED),
|
||||||
|
fAuthenticationName(NULL), fPeerAuthenticationName(NULL),
|
||||||
fAuthenticatorIndex(-1), fPeerAuthenticatorIndex(-1),
|
fAuthenticatorIndex(-1), fPeerAuthenticatorIndex(-1),
|
||||||
fMaxTerminate(2), fMaxConfigure(10), fMaxNak(5),
|
fMaxTerminate(2), fMaxConfigure(10), fMaxNak(5),
|
||||||
fRequestID(0), fTerminateID(0), fTimeout(0)
|
fRequestID(0), fTerminateID(0), fTimeout(0)
|
||||||
@@ -15,6 +19,8 @@ PPPStateMachine::PPPStateMachine(PPPInterface& interface)
|
|||||||
|
|
||||||
PPPStateMachine::~PPPStateMachine()
|
PPPStateMachine::~PPPStateMachine()
|
||||||
{
|
{
|
||||||
|
free(fAuthenticationName);
|
||||||
|
free(fPeerAuthenticationName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -30,6 +36,7 @@ PPPStateMachine::NextID()
|
|||||||
void
|
void
|
||||||
PPPStateMachine::NewState(PPP_STATE next)
|
PPPStateMachine::NewState(PPP_STATE next)
|
||||||
{
|
{
|
||||||
|
// TODO:
|
||||||
// if(State() == PPP_OPENED_STATE)
|
// if(State() == PPP_OPENED_STATE)
|
||||||
// ResetOptionHandlers();
|
// ResetOptionHandlers();
|
||||||
|
|
||||||
@@ -37,90 +44,163 @@ PPPStateMachine::NewState(PPP_STATE next)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PPPStateMachine::NewPhase(PPP_PHASE next)
|
||||||
|
{
|
||||||
|
// Report a down event to parent if we are not usable anymore.
|
||||||
|
// The report threads get their notification later.
|
||||||
|
if(Phase() == PPP_ESTABLISHED_PHASE && Interface()->Parent())
|
||||||
|
Interface()->Parent()->StateMachine().DownEvent(Interface());
|
||||||
|
|
||||||
|
// there is nothing after established phase and nothing before down phase
|
||||||
|
if(next > PPP_ESTABLISHED_PHASE)
|
||||||
|
fPhase = PPP_ESTABLISHED_PHASE;
|
||||||
|
else if(next < PPP_DOWN_PHASE)
|
||||||
|
fPhase = PPP_DOWN_PHASE;
|
||||||
|
else
|
||||||
|
fPhase = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// authentication events
|
// authentication events
|
||||||
void
|
void
|
||||||
PPPStateMachine::AuthenticationRequested()
|
PPPStateMachine::AuthenticationRequested()
|
||||||
{
|
{
|
||||||
// IMPLEMENT ME!
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
|
fAuthenticationStatus = PPP_AUTHENTICATING;
|
||||||
|
free(fAuthenticationName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PPPStateMachine::AuthenticationAccepted(const char *name)
|
PPPStateMachine::AuthenticationAccepted(const char *name)
|
||||||
{
|
{
|
||||||
// IMPLEMENT ME!
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
|
fAuthenticationStatus = PPP_AUTHENTICATION_SUCCESSFUL;
|
||||||
|
free(fAuthenticationName);
|
||||||
|
fAuthenticationName = strdup(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PPPStateMachine::AuthenticationDenied(const char *name)
|
PPPStateMachine::AuthenticationDenied(const char *name)
|
||||||
{
|
{
|
||||||
// IMPLEMENT ME!
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
|
fAuthenticationStatus = PPP_AUTHENTICATION_FAILED;
|
||||||
|
free(fAuthenticationName);
|
||||||
|
fAuthenticationName = strdup(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const char*
|
const char*
|
||||||
PPPStateMachine::AuthenticationName() const
|
PPPStateMachine::AuthenticationName() const
|
||||||
{
|
{
|
||||||
// IMPLEMENT ME!
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
|
return fAuthenticationName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PPPStateMachine::PeerAuthenticationRequested()
|
PPPStateMachine::PeerAuthenticationRequested()
|
||||||
{
|
{
|
||||||
// IMPLEMENT ME!
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
|
fPeerAuthenticationStatus = PPP_AUTHENTICATING;
|
||||||
|
free(fPeerAuthenticationName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PPPStateMachine::PeerAuthenticationAccepted(const char *name)
|
PPPStateMachine::PeerAuthenticationAccepted(const char *name)
|
||||||
{
|
{
|
||||||
// IMPLEMENT ME!
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
|
fPeerAuthenticationStatus = PPP_AUTHENTICATION_SUCCESSFUL;
|
||||||
|
free(fPeerAuthenticationName);
|
||||||
|
fPeerAuthenticationName = strdup(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PPPStateMachine::PeerAuthenticationDenied(const char *name)
|
PPPStateMachine::PeerAuthenticationDenied(const char *name)
|
||||||
{
|
{
|
||||||
// IMPLEMENT ME!
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
|
fPeerAuthenticationStatus = PPP_AUTHENTICATION_FAILED;
|
||||||
|
free(fPeerAuthenticationName);
|
||||||
|
fPeerAuthenticationName = strdup(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const char*
|
const char*
|
||||||
PPPStateMachine::PeerAuthenticationName() const
|
PPPStateMachine::PeerAuthenticationName() const
|
||||||
{
|
{
|
||||||
// IMPLEMENT ME!
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
|
return fPeerAuthenticationName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PPPStateMachine::UpFailedEvent(PPPInterface *interface)
|
PPPStateMachine::UpFailedEvent(PPPInterface *interface)
|
||||||
{
|
{
|
||||||
|
// TODO:
|
||||||
|
// log that an interface did not go up
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PPPStateMachine::UpEvent(PPPInterface *interface)
|
PPPStateMachine::UpEvent(PPPInterface *interface)
|
||||||
{
|
{
|
||||||
|
if(Phase() < PPP_ESTABLISHMENT_PHASE) {
|
||||||
|
Interface()->UnregisterInterface();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Interface()->IsMultilink() && !Interface()->Parent())
|
||||||
|
Interface()->RegisterInterface();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PPPStateMachine::DownEvent(PPPInterface *interface)
|
PPPStateMachine::DownEvent(PPPInterface *interface)
|
||||||
{
|
{
|
||||||
|
// when all children are down we should not be registered
|
||||||
|
if(Interface()->IsMultilink() && !Interface()->Parent()) {
|
||||||
|
uint32 count = 0;
|
||||||
|
PPPInterface *child;
|
||||||
|
for(int32 i = 0; i < Interface()->CountChildren(); i++) {
|
||||||
|
child = Interface()->ChildAt(i);
|
||||||
|
|
||||||
|
if(child && child->IsUp())
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(count == 0)
|
||||||
|
Interface()->UnregisterInterface();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PPPStateMachine::UpFailedEvent(PPPProtocol *protocol)
|
PPPStateMachine::UpFailedEvent(PPPProtocol *protocol)
|
||||||
{
|
{
|
||||||
|
// All protocols must go up.
|
||||||
|
CloseEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PPPStateMachine::UpEvent(PPPProtocol *protocol)
|
PPPStateMachine::UpEvent(PPPProtocol *protocol)
|
||||||
{
|
{
|
||||||
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
|
if(Phase() >= PPP_ESTABLISHMENT_PHASE)
|
||||||
|
BringHandlersUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -133,12 +213,18 @@ PPPStateMachine::DownEvent(PPPProtocol *protocol)
|
|||||||
void
|
void
|
||||||
PPPStateMachine::UpFailedEvent(PPPEncapsulator *encapsulator)
|
PPPStateMachine::UpFailedEvent(PPPEncapsulator *encapsulator)
|
||||||
{
|
{
|
||||||
|
// All encapsulators must go up.
|
||||||
|
CloseEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PPPStateMachine::UpEvent(PPPEncapsulator *encapsulator)
|
PPPStateMachine::UpEvent(PPPEncapsulator *encapsulator)
|
||||||
{
|
{
|
||||||
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
|
if(Phase() >= PPP_ESTABLISHMENT_PHASE)
|
||||||
|
BringHandlersUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -160,7 +246,7 @@ PPPStateMachine::TLSNotify()
|
|||||||
|
|
||||||
if(State() == PPP_STARTING_STATE) {
|
if(State() == PPP_STARTING_STATE) {
|
||||||
if(Phase() == PPP_DOWN_PHASE)
|
if(Phase() == PPP_DOWN_PHASE)
|
||||||
fPhase = PPP_ESTABLISHMENT_PHASE;
|
NewPhase(PPP_ESTABLISHMENT_PHASE);
|
||||||
// this says that the device is going up
|
// this says that the device is going up
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -185,7 +271,7 @@ PPPStateMachine::TLFNotify()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// from now on no packets may be sent to the device
|
// from now on no packets may be sent to the device
|
||||||
fPhase = PPP_DOWN_PHASE;
|
NewPhase(PPP_DOWN_PHASE);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -211,6 +297,8 @@ PPPStateMachine::UpFailedEvent()
|
|||||||
// TODO:
|
// TODO:
|
||||||
// report that up failed
|
// report that up failed
|
||||||
// Report(PPP_CONNECTION_REPORT, PPP_UP_FAILED, NULL, 0);
|
// Report(PPP_CONNECTION_REPORT, PPP_UP_FAILED, NULL, 0);
|
||||||
|
if(Interface()->Parent())
|
||||||
|
Interface()->Parent()->StateMachine().UpFailedEvent(Interface());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -285,14 +373,14 @@ PPPStateMachine::DownEvent()
|
|||||||
case PPP_CLOSED_STATE:
|
case PPP_CLOSED_STATE:
|
||||||
case PPP_CLOSING_STATE:
|
case PPP_CLOSING_STATE:
|
||||||
NewState(PPP_INITIAL_STATE);
|
NewState(PPP_INITIAL_STATE);
|
||||||
fPhase = PPP_DOWN_PHASE;
|
NewPhase(PPP_DOWN_PHASE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PPP_STOPPED_STATE:
|
case PPP_STOPPED_STATE:
|
||||||
// The RFC says we should reconnect, but our implementation
|
// The RFC says we should reconnect, but our implementation
|
||||||
// will only do this if auto-redial is enabled (only clients).
|
// will only do this if auto-redial is enabled (only clients).
|
||||||
NewStatus(PPP_STARTING_STATE);
|
NewStatus(PPP_STARTING_STATE);
|
||||||
fPhase = PPP_DOWN_PHASE;
|
NewPhase(PPP_DOWN_PHASE);
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// report that we lost the connection
|
// report that we lost the connection
|
||||||
@@ -304,7 +392,7 @@ PPPStateMachine::DownEvent()
|
|||||||
|
|
||||||
case PPP_STOPPING_STATE:
|
case PPP_STOPPING_STATE:
|
||||||
NewStatus(PPP_STARTING_STATE);
|
NewStatus(PPP_STARTING_STATE);
|
||||||
fPhase = PPP_DOWN_PHASE;
|
NewPhase(PPP_DOWN_PHASE);
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// report that we lost the connection
|
// report that we lost the connection
|
||||||
@@ -315,7 +403,7 @@ PPPStateMachine::DownEvent()
|
|||||||
case PPP_ACK_RCVD_STATE:
|
case PPP_ACK_RCVD_STATE:
|
||||||
case PPP_ACK_SENT_STATE:
|
case PPP_ACK_SENT_STATE:
|
||||||
NewStatus(PPP_STARTING_STATE);
|
NewStatus(PPP_STARTING_STATE);
|
||||||
fPhase = PPP_DOWN_PHASE;
|
NewPhase(PPP_DOWN_PHASE);
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// report that we lost the connection
|
// report that we lost the connection
|
||||||
@@ -325,7 +413,7 @@ PPPStateMachine::DownEvent()
|
|||||||
case PPP_OPENED_STATE:
|
case PPP_OPENED_STATE:
|
||||||
// tld/1
|
// tld/1
|
||||||
NewStatus(PPP_STARTING_STATE);
|
NewStatus(PPP_STARTING_STATE);
|
||||||
fPhase = PPP_DOWN_PHASE;
|
NewPhase(PPP_DOWN_PHASE);
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// report that we lost the connection
|
// report that we lost the connection
|
||||||
@@ -339,8 +427,14 @@ PPPStateMachine::DownEvent()
|
|||||||
// maybe we need to redial
|
// maybe we need to redial
|
||||||
if(State() == PPP_STARTING_STATE) {
|
if(State() == PPP_STARTING_STATE) {
|
||||||
if(Interface()->DoesAutoRedial()) {
|
if(Interface()->DoesAutoRedial()) {
|
||||||
|
NewState(PPP_INITIAL_STATE);
|
||||||
// TODO:
|
// TODO:
|
||||||
// redial using a new thread (maybe interface manager will help us)
|
// redial using a new thread (maybe interface manager will help us)
|
||||||
|
} else {
|
||||||
|
if(Interface()->Parent())
|
||||||
|
Interface()->Parent()->StateMachine().UpFailedEvent(Interface());
|
||||||
|
// TODO:
|
||||||
|
// we must delete our interface
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -366,7 +460,7 @@ PPPStateMachine::OpenEvent()
|
|||||||
}
|
}
|
||||||
|
|
||||||
NewState(PPP_REQ_SENT_STATE);
|
NewState(PPP_REQ_SENT_STATE);
|
||||||
fPhase = PPP_ESTABLISHMENT_PHASE;
|
NewPhase(PPP_ESTABLISHMENT_PHASE);
|
||||||
InitializeRestartCount();
|
InitializeRestartCount();
|
||||||
locker.UnlockNow();
|
locker.UnlockNow();
|
||||||
SendConfigureRequest();
|
SendConfigureRequest();
|
||||||
@@ -391,7 +485,7 @@ PPPStateMachine::CloseEvent()
|
|||||||
case PPP_ACK_RCVD_STATE:
|
case PPP_ACK_RCVD_STATE:
|
||||||
case PPP_ACK_SENT_STATE:
|
case PPP_ACK_SENT_STATE:
|
||||||
NewState(PPP_CLOSING_STATE);
|
NewState(PPP_CLOSING_STATE);
|
||||||
fPhase = PPP_TERMINATION_PHASE;
|
NewPhase(PPP_TERMINATION_PHASE);
|
||||||
InitializeRestartCount();
|
InitializeRestartCount();
|
||||||
locker.UnlockNow();
|
locker.UnlockNow();
|
||||||
SendTerminateRequest();
|
SendTerminateRequest();
|
||||||
@@ -405,7 +499,7 @@ PPPStateMachine::CloseEvent()
|
|||||||
// are in PPP_INITIAL_STATE now
|
// are in PPP_INITIAL_STATE now
|
||||||
if(Phase() == PPP_ESTABLISHMENT_PHASE) {
|
if(Phase() == PPP_ESTABLISHMENT_PHASE) {
|
||||||
// the device is already up
|
// the device is already up
|
||||||
fPhase = PPP_DOWN_PHASE;
|
NewPhase(PPP_DOWN_PHASE);
|
||||||
// this says the following DownEvent() was not caused by
|
// this says the following DownEvent() was not caused by
|
||||||
// a connection fault
|
// a connection fault
|
||||||
locker.UnlockNow();
|
locker.UnlockNow();
|
||||||
@@ -461,7 +555,7 @@ PPPStateMachine::TOBadEvent()
|
|||||||
switch(State()) {
|
switch(State()) {
|
||||||
case PPP_CLOSING_STATE:
|
case PPP_CLOSING_STATE:
|
||||||
NewState(PPP_CLOSED_STATE);
|
NewState(PPP_CLOSED_STATE);
|
||||||
fPhase = PPP_TERMINATION_PHASE;
|
NewPhase(PPP_TERMINATION_PHASE);
|
||||||
locker.UnlockNow();
|
locker.UnlockNow();
|
||||||
ThisLayerFinished();
|
ThisLayerFinished();
|
||||||
break;
|
break;
|
||||||
@@ -471,7 +565,7 @@ PPPStateMachine::TOBadEvent()
|
|||||||
case PPP_ACK_RCVD_STATE:
|
case PPP_ACK_RCVD_STATE:
|
||||||
case PPP_ACK_SENT_STATE:
|
case PPP_ACK_SENT_STATE:
|
||||||
NewState(PPP_STOPPED_STATE);
|
NewState(PPP_STOPPED_STATE);
|
||||||
fPhase = PPP_TERMINATION_PHASE;
|
NewPhase(PPP_TERMINATION_PHASE);
|
||||||
locker.UnlockNow();
|
locker.UnlockNow();
|
||||||
ThisLayerFinished();
|
ThisLayerFinished();
|
||||||
break;
|
break;
|
||||||
@@ -574,9 +668,9 @@ PPPStateMachine::RCRBadEvent(mbuf *nak, mbuf *reject)
|
|||||||
case PPP_REQ_SENT_STATE:
|
case PPP_REQ_SENT_STATE:
|
||||||
case PPP_ACK_RCVD_STATE:
|
case PPP_ACK_RCVD_STATE:
|
||||||
locker.UnlockNow();
|
locker.UnlockNow();
|
||||||
if(!nak && mtod(nak, lcp_packet*)->length > 3)
|
if(!nak && ntohs(mtod(nak, lcp_packet*)->length) > 3)
|
||||||
SendConfigureNak(nak);
|
SendConfigureNak(nak);
|
||||||
else if(!reject && mtod(reject, lcp_packet*)->length > 3)
|
else if(!reject && ntohs(mtod(reject, lcp_packet*)->length) > 3)
|
||||||
SendConfigureNak(reject);
|
SendConfigureNak(reject);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -790,7 +884,7 @@ PPPStateMachine::RTAEvent(mbuf *packet)
|
|||||||
|
|
||||||
// receive unknown code
|
// receive unknown code
|
||||||
void
|
void
|
||||||
PPPStateMachine::RUCEvent(mbuf *packet, uint16 protocol)
|
PPPStateMachine::RUCEvent(mbuf *packet, uint16 protocol, uint8 type)
|
||||||
{
|
{
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
@@ -802,7 +896,7 @@ PPPStateMachine::RUCEvent(mbuf *packet, uint16 protocol)
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
locker.UnlockNow();
|
locker.UnlockNow();
|
||||||
SendCodeReject(packet, protocol);
|
SendCodeReject(packet, protocol, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -972,7 +1066,7 @@ PPPStateMachine::RCREvent(mbuf *packet)
|
|||||||
|
|
||||||
|
|
||||||
// ReceiveCodeReject
|
// ReceiveCodeReject
|
||||||
// LCP received a code-reject packet and we look if it is acceptable.
|
// LCP received a code/protocol-reject packet and we look if it is acceptable.
|
||||||
// From here we call our Good/Bad counterparts.
|
// From here we call our Good/Bad counterparts.
|
||||||
void
|
void
|
||||||
PPPStateMachine::RXJEvent(mbuf *packet)
|
PPPStateMachine::RXJEvent(mbuf *packet)
|
||||||
@@ -981,6 +1075,7 @@ PPPStateMachine::RXJEvent(mbuf *packet)
|
|||||||
|
|
||||||
if(reject->code == PPP_CODE_REJECT)
|
if(reject->code == PPP_CODE_REJECT)
|
||||||
RXJBadEvent(packet);
|
RXJBadEvent(packet);
|
||||||
|
// we only have basic codes, so there must be something wrong
|
||||||
else if(reject->code == PPP_PROTOCOL_REJECT) {
|
else if(reject->code == PPP_PROTOCOL_REJECT) {
|
||||||
// disable all handlers for rejected protocol type
|
// disable all handlers for rejected protocol type
|
||||||
uint16 rejected = *((uint16*) reject->data);
|
uint16 rejected = *((uint16*) reject->data);
|
||||||
@@ -994,23 +1089,27 @@ PPPStateMachine::RXJEvent(mbuf *packet)
|
|||||||
|
|
||||||
int32 index;
|
int32 index;
|
||||||
PPPProtocol *protocol_handler;
|
PPPProtocol *protocol_handler;
|
||||||
PPPEncapsulator *encapsulator_handler = fFirstEncapsulator;
|
PPPEncapsulator *encapsulator_handler = Interface()->FirstEncapsulator();
|
||||||
|
|
||||||
for(index = 0; index < LCP().CountProtocols(); index++) {
|
for(index = 0; index < Interface()->CountProtocols(); index++) {
|
||||||
protocol_handler = LCP().ProtocolAt(index);
|
protocol_handler = Interface()->ProtocolAt(index);
|
||||||
if(protocol_handler && protocol_handler->Protocol() == rejected)
|
if(protocol_handler && protocol_handler->Protocol() == rejected)
|
||||||
protocol_handler->SetEnabled(false);
|
protocol_handler->SetEnabled(false);
|
||||||
// disable protocol
|
// disable protocol
|
||||||
}
|
}
|
||||||
|
|
||||||
for(; encapsulator_handler;
|
for(; encapsulator_handler;
|
||||||
encapsulator_handler = encapsulator_handler->Next()) {
|
encapsulator_handler = encapsulator_handler->Next()) {
|
||||||
if(encapsulator_handler->Protocol() == rejected)
|
if(encapsulator_handler->Protocol() == rejected)
|
||||||
encapsulator_handler->SetEnabled(false);
|
encapsulator_handler->SetEnabled(false);
|
||||||
// disable encapsulator
|
// disable encapsulator
|
||||||
}
|
}
|
||||||
|
|
||||||
RXJGoodEvent(packet);
|
RXJGoodEvent(packet);
|
||||||
|
|
||||||
|
// notify parent, too
|
||||||
|
if(Interface()->Parent())
|
||||||
|
Interface()->Parent()->StateMachine().RXJEvent(packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1027,11 +1126,12 @@ PPPStateMachine::IllegalEvent(PPP_EVENT event)
|
|||||||
void
|
void
|
||||||
PPPStateMachine::ThisLayerUp()
|
PPPStateMachine::ThisLayerUp()
|
||||||
{
|
{
|
||||||
// TODO:
|
LockerHelper locker(fLock);
|
||||||
// bring all P/Es up
|
|
||||||
// increase until we reach PPP_ESTABLISHED_PHASE or until we actually
|
// We begin with authentication phase and wait until each phase is done.
|
||||||
// find P/Es that need an Up().
|
// We stop when we reach established phase.
|
||||||
// In this case we continue to increase the phase in UpEvent(P/E).
|
NewPhase(PPP_AUTHENTICATION_PHASE);
|
||||||
|
BringHandlersUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1163,7 +1263,7 @@ PPPStateMachine::SendTerminateRequest()
|
|||||||
lcp_packet *request = mtod(m, lcp_packet*);
|
lcp_packet *request = mtod(m, lcp_packet*);
|
||||||
request->code = PPP_TERMINATE_REQUEST;
|
request->code = PPP_TERMINATE_REQUEST;
|
||||||
request->id = fTerminateID = NextID();
|
request->id = fTerminateID = NextID();
|
||||||
request->length = 4;
|
request->length = htons(4);
|
||||||
|
|
||||||
LCP().Send(m);
|
LCP().Send(m);
|
||||||
}
|
}
|
||||||
@@ -1181,7 +1281,7 @@ PPPStateMachine::SendTerminateAck(mbuf *request)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PPPStateMachine::SendCodeReject(mbuf *packet, uint16 protocol)
|
PPPStateMachine::SendCodeReject(mbuf *packet, uint16 protocol, uint8 type)
|
||||||
{
|
{
|
||||||
// TODO:
|
// TODO:
|
||||||
// add the packet to the reject and truncate it if needed
|
// add the packet to the reject and truncate it if needed
|
||||||
@@ -1197,3 +1297,57 @@ PPPStateMachine::SendEchoReply(mbuf *request)
|
|||||||
|
|
||||||
LCP().Send(request);
|
LCP().Send(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// methods for bringing protocols/encapsulators up
|
||||||
|
void
|
||||||
|
PPPStateMachine::BringHandlersUp()
|
||||||
|
{
|
||||||
|
while(Phase() <= PPP_ESTABLISHED_PHASE) {
|
||||||
|
if(BringPhaseUp() > 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if(Phase() == PPP_ESTABLISHED_PHASE) {
|
||||||
|
if(Interface()->Parent())
|
||||||
|
Interface()->Parent()->StateMachine().UpEvent(Interface());
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
// Report(PPP_CONNECTION_REPORT, PPP_UP_SUCCESSFUL, NULL, 0);
|
||||||
|
} else
|
||||||
|
NewPhase(Phase() + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// this returns the number of handlers waiting to go up
|
||||||
|
uint32
|
||||||
|
PPPStateMachine::BringPhaseUp()
|
||||||
|
{
|
||||||
|
uint32 count = 0;
|
||||||
|
PPPProtocol *protocol_handler;
|
||||||
|
PPPEncapsulator *encapsulator_handler = Interface()->FirstEncapsulator();
|
||||||
|
|
||||||
|
for(int32 index = 0; index < Interface()->CountProtocols(); index++) {
|
||||||
|
protocol_handler = Interface()->ProtocolAt(index);
|
||||||
|
if(protocol_handler && protocol_handler->Phase() == Phase()) {
|
||||||
|
if(protocol_handler->IsUpRequested()) {
|
||||||
|
++count;
|
||||||
|
protocol_handler->Up();
|
||||||
|
} else if(protocol_handler->IsGoingUp())
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(; encapsulator_handler;
|
||||||
|
encapsulator_handler = encapsulator_handler->Next()) {
|
||||||
|
if(encapsulator_handler && encapsulator_handler->Phase() == Phase()) {
|
||||||
|
if(encapsulator_handler->IsUpRequested()) {
|
||||||
|
++count;
|
||||||
|
encapsulator_handler->Up();
|
||||||
|
} else if(encapsulator_handler->IsGoingUp())
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user