📄 eap_peerfsm.cxx
字号:
class AcStartTimer : public EapPeerAction { void operator()(EapPeerSwitchStateMachine &sm) { sm.ScheduleTimer(EvTo, sm.AuthPeriod()); EAP_LOG(LM_DEBUG, "Peer: Timer Started.\n"); } }; class AcCheckRxQueue : public EapPeerAction { void operator()(EapPeerSwitchStateMachine &sm) { EapMessageQueue &q = sm.RxQueue(); // if rxQueue is active, generate message reception event. if (q.message_count()>0) sm.Event(EapPeerSwitchStateMachine::EvRxMsg); // otherwise, wait external event } }; class AcReceiveMsg : public EapPeerAction { void operator()(EapPeerSwitchStateMachine &sm) { AAAMessageBlock *msg; EapMessageQueue &q = sm.RxQueue(); // dequeue a message from receiving queue. q.dequeue_head((ACE_Message_Block*&)msg); sm.SetRxMessage(msg); msg->rd_ptr(msg->base()); // parse the message EapHeaderParser hp; EapHeader header; hp.setAppData(&header); hp.setRawData(msg); hp.parseRawToApp(); ACE_Byte code = header.code; ACE_Byte id = header.identifier; // Check code if (code != Request && code != Success && code != Failure) { // Invalid code. Delete the message. sm.Event(EvElse); return; } // rxReq if (code == Request) { // Check identifier if (sm.ReceivedFirstRequest() && id == sm.LastIdentifier()) { // We are on the "rxReq && reqId == lastId" branch. // This is a duplicate request. If there is a valid // request for which a response was already returned, // send the copy of the response. Otherwise, discard the // request. if (sm.LastIdValidity()) { sm.Event(EvSgRetransmit); } else { sm.Event(EvElse); } } else { // Set the received identifier to the currentId sm.CurrentIdentifier() = id; if (!sm.ReceivedFirstRequest()) sm.ReceivedFirstRequest()=true; SubAcParseRequest(sm); } } else if (code == Success) { EAP_LOG(LM_DEBUG, "Peer: Success received.\n"); SubAcCheckSuccessCondition(sm); } else // if (code == Failure) { EAP_LOG(LM_DEBUG, "Peer: Failure received.\n"); SubAcCheckFailureCondition(sm); } } }; class AcCheckIdentity : public EapPeerAction { void operator()(EapPeerSwitchStateMachine &sm) { sm.CancelTimer(sm.InputIdentityTimerType()); if (sm.FutureIdentity().ready()) { sm.FutureIdentity().get(sm.PeerIdentity()); sm.InputIdentityTask().suspend(); sm.Notify(EvSgUserInputFinished); sm.CancelTimer(sm.InputIdentityTimerType()); } else { sm.ScheduleTimer(EvToCheckIdentity, 0, 100000, sm.InputIdentityTimerType()); } } }; /// Internal event definition enum event { EvUCT=100, EvSgNewMethod, EvSgContMethod, EvSgEnterMethod, EvSgNoEnterMethod, EvSgSuccess, EvSgFailure, EvSgRetransmit, EvSgUserInputFinished, EvSgNotificationOutputFinished, EvRxRequest, EvRxSuccess, EvRxFailure, EvRxNotification, EvRxIdentity, EvElse, EvTo, EvToCheckIdentity, }; /// Internal state definition enum state { StDisabled, StInitialize, StIdle, StReceived, StMethod, StGetMethod, StDiscard, StRetransmit, StSendResponse, StIdentity, StNotification, StSuccess, StFailure }; AcInitialize acInitialize; AcRetransmit acRetransmit; AcCheckTimeoutCondition acCheckTimeoutCondition; AcSendSuccess acSendSuccess; AcSendFailure acSendFailure; AcBuildResp acBuildResp; AcDoIntegrityCheck acDoIntegrityCheck; AcDoPolicyCheck acDoPolicyCheck; AcDiscard acDiscard; AcBuildNak acBuildNak; AcParseNotification acParseNotification; AcBuildNotification acBuildNotification; AcParseIdentity acParseIdentity; AcBuildIdentity acBuildIdentity; AcStartTimer acStartTimer; AcCheckRxQueue acCheckRxQueue; AcReceiveMsg acReceiveMsg; AcCheckIdentity acCheckIdentity; EapPeerSwitchStateTable_S() { AddStateTableEntry(StDisabled, EapPeerSwitchStateMachine::EvSgPortEnabled, StInitialize, acInitialize); AddStateTableEntry(StInitialize, EvUCT, StIdle, acStartTimer); AddStateTableEntry(StIdle, EapPeerSwitchStateMachine::EvRxMsg, StReceived, acReceiveMsg); AddStateTableEntry(StIdle, EvTo, StIdle, acCheckTimeoutCondition); AddStateTableEntry(StIdle, EvSgSuccess, StSuccess, acSendSuccess); AddStateTableEntry(StIdle, EvSgFailure, StFailure, acSendFailure); AddStateTableEntry(StReceived, EvSgSuccess, StSuccess, acSendSuccess); AddStateTableEntry(StReceived, EvSgFailure, StFailure, acSendFailure); AddStateTableEntry(StReceived, EvSgRetransmit, StRetransmit, acRetransmit); AddStateTableEntry(StReceived, EvSgContMethod, StMethod, acDoIntegrityCheck); AddStateTableEntry(StReceived, EvSgNewMethod, StGetMethod, acDoPolicyCheck); AddStateTableEntry(StReceived, EvRxNotification, StNotification, acParseNotification); AddStateTableEntry(StReceived, EvRxIdentity, StIdentity, acParseIdentity); AddStateTableEntry(StReceived, EvElse, StDiscard, acDiscard); AddStateTableEntry(StIdentity, EvSgUserInputFinished, StIdentity, acBuildIdentity); AddStateTableEntry(StIdentity, EvUCT, StSendResponse, acBuildResp); // The following two entries are needed because identity // processing is asynchronously done. AddStateTableEntry(StIdentity, EvTo, StFailure, acSendFailure); AddStateTableEntry(StIdentity, EvToCheckIdentity, StIdentity, acCheckIdentity); AddWildcardStateTableEntry(StIdentity, StIdentity); AddStateTableEntry(StNotification, EvSgNotificationOutputFinished, StNotification, acBuildNotification); AddStateTableEntry(StNotification, EvUCT, StSendResponse, acBuildResp); // The following two entries are needed because identity // processing is asynchronously done. AddStateTableEntry(StNotification, EvTo, StFailure, acSendFailure); AddStateTableEntry(StNotification, EvElse, StDiscard, acDiscard); AddWildcardStateTableEntry(StNotification, StIdentity); AddStateTableEntry(StGetMethod, EvSgEnterMethod, StMethod, acDoIntegrityCheck); AddStateTableEntry(StGetMethod, EvSgNoEnterMethod, StSendResponse, acBuildNak); AddWildcardStateTableEntry(StGetMethod, StGetMethod); AddStateTableEntry(StMethod, EapPeerSwitchStateMachine::EvSgValidReq, StSendResponse, acBuildResp); AddStateTableEntry(StMethod, EapPeerSwitchStateMachine::EvSgInvalidReq, StDiscard, acDiscard); AddStateTableEntry(StMethod, EvSgFailure, StFailure, acSendFailure); // The following two entries are needed because method // processing is asynchronously done. AddStateTableEntry(StMethod, EvTo, StMethod, acCheckTimeoutCondition); AddStateTableEntry(StMethod, EvSgSuccess, StSuccess, acSendSuccess); AddWildcardStateTableEntry(StMethod, StMethod); AddStateTableEntry(StDiscard, EvUCT, StIdle, acCheckRxQueue); AddStateTableEntry(StSuccess, EapPeerSwitchStateMachine::EvRxMsg, StSuccess, acReceiveMsg); AddWildcardStateTableEntry(StSuccess, StSuccess); AddStateTableEntry(StFailure, EapPeerSwitchStateMachine::EvRxMsg, StFailure, acReceiveMsg); AddWildcardStateTableEntry(StFailure, StFailure); AddStateTableEntry(StRetransmit, EvUCT, StSendResponse); AddStateTableEntry(StSendResponse, EvUCT, StIdle, acCheckRxQueue); InitialState(StDisabled); }; static void SubAcCheckSuccessCondition(EapPeerSwitchStateMachine &sm) { if (sm.Decision() != EapPeerSwitchStateMachine::FAIL) { sm.Event(EvSgSuccess); } else if (sm.MethodState() != EapPeerSwitchStateMachine::CONT) { sm.Event(EvSgFailure); } else { sm.Event(EvElse); } } static void SubAcCheckFailureCondition(EapPeerSwitchStateMachine &sm) { if (sm.MethodState() != EapPeerSwitchStateMachine::CONT && sm.Decision() != EapPeerSwitchStateMachine::UNCOND_SUCC) { sm.Event(EvSgFailure); } else { sm.Event(EvElse); } } static void SubAcParseRequest(EapPeerSwitchStateMachine &sm) { EAP_LOG(LM_DEBUG, "Peer: Parse Request.\n"); AAAMessageBlock *msg=sm.rxMessage; // parse the request EapRequestParser parser; EapRequest req; parser.setAppData(&req); parser.setRawData(msg); parser.parseRawToApp(); EapType type = sm.reqMethod = req.GetType(); if (type == EapType(2)) // Notification { if (!sm.NotificationAllowed()) // Discard the notification if the peer is not allowed to // process the notification. { sm.Event(EvElse); } else { // Set the current method type sm.CurrentMethod() = type; // Extract the notification string. std::string notifStr(msg->rd_ptr(), msg->size()- (msg->rd_ptr()-msg->base())); // Execute the notification callback. sm.Notification(notifStr); // Generate an event to send Response/Notification. sm.Event(EvRxNotification); } } else if (sm.CurrentMethod() == EapType(0) && type == EapType(1)) { // This is an Identity request. sm.Event(EvRxIdentity); } else if (sm.CurrentMethod() == EapType(0)) { EAP_LOG(LM_DEBUG, "Peer: New Method.\n"); sm.Event(EvSgNewMethod); } else if (type == sm.CurrentMethod() && sm.MethodState() != EapPeerSwitchStateMachine::DONE) { sm.Event(EvSgContMethod); } else { sm.Event(EvElse); } } static void SubAcSendResp(EapPeerSwitchStateMachine &sm) { AAAMessageBlock *msg = sm.GetTxMessage(); // Call Send callback function. sm.Notify(EvUCT); sm.Send(msg); }};typedef ACE_Singleton<EapPeerSwitchStateTable_S, ACE_Recursive_Thread_Mutex> EapPeerSwitchStateTable;const ACE_UINT16 EapPeerSwitchStateMachine::defaultAuthPeriod=10;EapPeerSwitchStateMachine::EapPeerSwitchStateMachine(ACE_Reactor &r, EapJobHandle &h) : EapSwitchStateMachine(r, h), EapStateMachine<EapPeerSwitchStateMachine> (*this, *EapPeerSwitchStateTable::instance(), r, *this, "peer"), authPeriod(defaultAuthPeriod), receivedFirstRequest(false), inputIdentityTimerType(AAA_TimerTypeAllocator::instance()->Allocate()){ inputIdentityTask.Set(this);}voidEapPeerSwitchStateMachine::Start() throw(AAA_Error){ // Set the current policy element to point to the initial policy // element. policy.CurrentPolicyElement(policy.InitialPolicyElement()); // Delete the last executed method if any. DeleteMethodStateMachine(); EapStateMachine<EapPeerSwitchStateMachine>::Start(); lastIdValidity = false; currentIdentifier = 0; currentMethod = EapType(0); keyAvailable = false; keyData.resize(0); Notify(EvSgPortEnabled);}voidEapPeerSwitchStateMachine::Receive(AAAMessageBlock* msg){ // Enqueue the received message with increasing reference counter // and generate a notification event. Since rxQueue is thread-safe, // enqueue_tail does not need session mutex lock. rxQueue.enqueue_tail(AAAMessageBlock::Acquire(msg)); Notify(EapPeerSwitchStateMachine::EvRxMsg);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -