📄 aaa_peer_fsm.cxx
字号:
/* BEGIN_COPYRIGHT *//* *//* Open Diameter: Open-source software for the Diameter and *//* Diameter related protocols *//* *//* Copyright (C) 2002-2004 Open Diameter Project *//* *//* This library is free software; you can redistribute it and/or modify *//* it under the terms of the GNU Lesser General Public License as *//* published by the Free Software Foundation; either version 2.1 of the *//* License, or (at your option) any later version. *//* *//* This library is distributed in the hope that it will be useful, *//* but WITHOUT ANY WARRANTY; without even the implied warranty of *//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *//* Lesser General Public License for more details. *//* *//* You should have received a copy of the GNU Lesser General Public *//* License along with this library; if not, write to the Free Software *//* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *//* USA. *//* *//* In addition, when you copy and redistribute some or the entire part of *//* the source code of this software with or without modification, you *//* MUST include this copyright notice in each copy. *//* *//* If you make any changes that are appeared to be useful, please send *//* sources that include the changed part to *//* diameter-developers@lists.sourceforge.net so that we can reflect your *//* changes to one unified version of this software. *//* *//* END_COPYRIGHT */#include "aaa_data_defs.h"#include "aaa_peer_fsm.h"#include "aaa_route_msg_router.h"#define AAA_PEER_CONNECT_ATTEMPT_TOUT 30AAA_PeerStateTable AAA_PeerStateMachine::m_StateTable;class AAA_ApplicationIdLookup{ public: static inline bool Find(diameter_unsigned32_t id, AAA_ApplicationIdLst &lst) { AAA_ApplicationIdLst::iterator i = lst.begin(); for (; i!= lst.end(); i++) { if ((*i == AAA_RELAY_APPLICATION_ID) || (*i == id)) { return true; } } return false; } static inline bool Find(diameter_unsigned32_t id, AAA_ApplicationIdLst *lst[], int count) { for (int i=0; i<count; i++) { if (Find(id, *(lst[i]))) { return true; } } return false; } static inline bool Find(diameter_unsigned32_t id, AAA_VendorSpecificIdLst &lst) { AAA_VendorSpecificIdLst::iterator i = lst.begin(); for (; i != lst.end(); i++) { if (((*i).authAppId == id) || ((*i).acctAppId == id) || ((*i).authAppId == AAA_RELAY_APPLICATION_ID) || ((*i).acctAppId == AAA_RELAY_APPLICATION_ID)) { return true; } } return false; }};void AAA_PeerR_ISendConnReq::operator()(AAA_PeerStateMachine &fsm){ fsm.ScheduleTimer(AAA_PEER_EV_TIMEOUT, AAA_PEER_CONNECT_ATTEMPT_TOUT, 0, AAA_PEER_EV_TIMEOUT);} void AAA_PeerR_AcceptSendCEA::operator()(AAA_PeerStateMachine &fsm){ fsm.PeerData().m_IOResponder = fsm.m_CurrentPeerEventParam->m_IO; std::auto_ptr<AAAMessage> cer = fsm.m_CurrentPeerEventParam->m_Msg; fsm.DisassembleCE(*cer); std::string message; diameter_unsigned32_t rcode; bool valid = fsm.ValidatePeer(rcode, message); fsm.SendCEA(rcode, message); if (! valid) { AAA_LOG(LM_INFO, "(%P|%t) %s in connection attempt, discarding\n", message.data()); fsm.Cleanup(); } else { fsm.CancelTimer(AAA_PEER_EV_TIMEOUT); fsm.ScheduleTimer(AAA_PEER_EV_WATCHDOG, AAA_CFG_TRANSPORT()->watchdog_timeout, 0, AAA_PEER_EV_WATCHDOG); fsm.PeerFsmConnected(); }}void AAA_PeerI_SendCER::operator()(AAA_PeerStateMachine &fsm){ AAA_LOG(LM_DEBUG, "(%P|%t) Connection attempt accepted\n"); fsm.PeerData().m_IOInitiator = fsm.m_CurrentPeerEventParam->m_IO; fsm.SendCER();}void AAA_Peer_ConnNack::operator()(AAA_PeerStateMachine &fsm){ fsm.Cleanup(); if (AAA_CFG_TRANSPORT()->retry_interval > 0) { fsm.ScheduleTimer(AAA_PEER_EV_CONN_RETRY, AAA_CFG_TRANSPORT()->retry_interval, 0, AAA_PEER_EV_CONN_RETRY); } fsm.PeerFsmError(AAA_UNABLE_TO_COMPLY);}void AAA_Peer_Cleanup::operator()(AAA_PeerStateMachine &fsm){ fsm.Cleanup();}void AAA_Peer_Retry::operator()(AAA_PeerStateMachine &fsm){ AAA_LOG(LM_INFO, "(%P|%t) Retrying peer connection\n"); fsm.CancelTimer(AAA_PEER_EV_CONN_RETRY); reinterpret_cast<AAA_PeerEntry*>(&fsm)->Start();}void AAA_PeerR_Accept::operator()(AAA_PeerStateMachine &fsm){ fsm.PeerData().m_IOResponder = fsm.m_CurrentPeerEventParam->m_IO; std::auto_ptr<AAAMessage> cer = fsm.m_CurrentPeerEventParam->m_Msg; fsm.DisassembleCE(*cer); std::string message; diameter_unsigned32_t rcode; if (! fsm.ValidatePeer(rcode, message)) { AAA_LOG(LM_INFO, "(%P|%t) %s during election, discarding\n", message.data()); fsm.Cleanup(); } else { AAA_LOG(LM_DEBUG, "(%P|%t) *** Peer capabilities accepted ***\n"); }}void AAA_Peer_Error::operator()(AAA_PeerStateMachine &fsm){ AAA_LOG(LM_INFO, "(%P|%t) Timeout occurred or non-CEA message received\n"); fsm.Cleanup(); if (AAA_CFG_TRANSPORT()->retry_interval > 0) { fsm.ScheduleTimer(AAA_PEER_EV_CONN_RETRY, AAA_CFG_TRANSPORT()->retry_interval, 0, AAA_PEER_EV_CONN_RETRY); } fsm.PeerFsmError(AAA_LIMITED_SUCCESS);}void AAA_Peer_ProcessCEA::operator()(AAA_PeerStateMachine &fsm){ std::auto_ptr<AAAMessage> cea = fsm.m_CurrentPeerEventParam->m_Msg; AAA_MsgResultCode rcode(*cea); if (rcode.InterpretedResultCode() == AAA_MsgResultCode::RCODE_SUCCESS) { fsm.DisassembleCE(*cea); fsm.CancelTimer(AAA_PEER_EV_TIMEOUT); fsm.ScheduleTimer(AAA_PEER_EV_WATCHDOG, AAA_CFG_TRANSPORT()->watchdog_timeout, 0, AAA_PEER_EV_WATCHDOG); AAA_LOG(LM_DEBUG, "(%P|%t) *** Local capabilities accepted by peer ***\n"); fsm.PeerFsmConnected(); } else { AAA_Utf8AvpContainerWidget errorMsg(cea->acl); diameter_utf8string_t *strMsg = errorMsg.GetAvp (AAA_AVPNAME_ERRORMESSAGE); if (strMsg) { AAA_LOG(LM_INFO, "(%P|%t) Peer returned an error on CEA: %s\n", strMsg->data()); } fsm.Cleanup(); }}void AAA_PeerR_AcceptElect::operator()(AAA_PeerStateMachine &fsm){ fsm.PeerData().m_IOResponder = fsm.m_CurrentPeerEventParam->m_IO; std::auto_ptr<AAAMessage> cer = fsm.m_CurrentPeerEventParam->m_Msg; fsm.DisassembleCE(*cer); std::string message; diameter_unsigned32_t rcode; if (! fsm.ValidatePeer(rcode, message)) { AAA_LOG(LM_INFO, "(%P|%t) %s during election, discarding\n", message.data()); fsm.Cleanup(AAA_PeerStateMachine::CLEANUP_ALL & ~AAA_PeerStateMachine::CLEANUP_IO_I); } else { fsm.Elect(); }}void AAA_PeerI_SendCERElect::operator()(AAA_PeerStateMachine &fsm){ fsm.PeerData().m_IOInitiator = fsm.m_CurrentPeerEventParam->m_IO; fsm.SendCER(); fsm.Elect();}void AAA_PeerR_SendCEA::operator()(AAA_PeerStateMachine &fsm){ fsm.PeerData().m_IOResponder = fsm.m_CurrentPeerEventParam->m_IO; std::string message = "Capabilities negotiation completed successfully (win-election)"; fsm.SendCEA(AAA_SUCCESS, message); fsm.CancelTimer(AAA_PEER_EV_TIMEOUT); fsm.ScheduleTimer(AAA_PEER_EV_WATCHDOG, AAA_CFG_TRANSPORT()->watchdog_timeout, 0, AAA_PEER_EV_WATCHDOG); AAA_LOG(LM_DEBUG, "(%P|%t) %s\n", message.data()); fsm.PeerFsmConnected();}void AAA_PeerR_SendCEAOpen::operator()(AAA_PeerStateMachine &fsm){ std::auto_ptr<AAAMessage> cer = fsm.m_CurrentPeerEventParam->m_Msg; fsm.DisassembleCE(*cer); std::string message; diameter_unsigned32_t rcode; if (! fsm.ValidatePeer(rcode, message)) { AAA_LOG(LM_INFO, "(%P|%t) %s during cap re-negotiation\n", message.data()); } else { AAA_LOG(LM_DEBUG, "(%P|%t) *** Peer capabilities accepted ***\n"); } fsm.SendCEA(rcode, message);}void AAA_PeerR_DisconnectResp::operator()(AAA_PeerStateMachine &fsm){ AAA_LOG(LM_DEBUG, "(%P|%t) Disconnecting responder\n"); fsm.PeerData().m_IOResponder.reset();}void AAA_PeerR_DisconnectIOpen::operator()(AAA_PeerStateMachine &fsm){ std::auto_ptr<AAAMessage> cea = fsm.m_CurrentPeerEventParam->m_Msg; AAA_MsgResultCode rcode(*cea); if (rcode.InterpretedResultCode() == AAA_MsgResultCode::RCODE_SUCCESS) { fsm.DisassembleCE(*cea); fsm.CancelTimer(AAA_PEER_EV_TIMEOUT); fsm.ScheduleTimer(AAA_PEER_EV_WATCHDOG, AAA_CFG_TRANSPORT()->watchdog_timeout, 0, AAA_PEER_EV_WATCHDOG); fsm.PeerData().m_IOResponder.reset(); AAA_LOG(LM_DEBUG, "(%P|%t) *** Initiator capabilities accepted ***\n"); fsm.PeerFsmConnected(); } else { AAA_Utf8AvpContainerWidget errorMsg(cea->acl); diameter_utf8string_t *strMsg = errorMsg.GetAvp (AAA_AVPNAME_ERRORMESSAGE); if (strMsg) { AAA_LOG(LM_INFO, "(%P|%t) Peer returned an error on CEA: %s\n", strMsg->data()); } fsm.Cleanup(); }}void AAA_PeerR_Reject::operator()(AAA_PeerStateMachine &fsm){ AAA_LOG(LM_DEBUG, "(%P|%t) Responder connection attempt rejected\n"); std::auto_ptr<AAA_IO_Base> io = fsm.m_CurrentPeerEventParam->m_IO; std::auto_ptr<AAAMessage> msg = fsm.m_CurrentPeerEventParam->m_Msg; io.reset();}void AAA_PeerI_DisconnectSendCEA::operator()(AAA_PeerStateMachine &fsm){ std::string message = "Capabilities negotiation completed successfully (win-election)"; fsm.PeerData().m_IOInitiator.reset(); fsm.SendCEA(AAA_SUCCESS, message); fsm.CancelTimer(AAA_PEER_EV_TIMEOUT); fsm.ScheduleTimer(AAA_PEER_EV_WATCHDOG, AAA_CFG_TRANSPORT()->watchdog_timeout, 0, AAA_PEER_EV_WATCHDOG); AAA_LOG(LM_DEBUG, "(%P|%t) %s\n", message.data()); fsm.PeerFsmConnected();}void AAA_PeerR_SendMessage::operator()(AAA_PeerStateMachine &fsm){#if ASYNC_SEND boost::shared_ptr<AAAMessage> msg = fsm.DequeueSendMsg(); if (fsm.Send(*msg, fsm.PeerData().m_IOResponder.get()) < 0) { AAA_LOG(LM_INFO, "(%P|%t) Error sending message: %d\n", msg->hdr.code); }#endif}void AAA_Peer_Process::operator()(AAA_PeerStateMachine &fsm){ std::auto_ptr<AAAMessage> msg = fsm.m_CurrentPeerEventParam->m_Msg; AAA_MsgQuery query(*msg); if (query.IsRequest()) { AAA_MSG_ROUTER()->RequestMsg(msg, reinterpret_cast<AAA_PeerEntry*>(&fsm)); } else { AAA_MSG_ROUTER()->AnswerMsg(msg, reinterpret_cast<AAA_PeerEntry*>(&fsm)); }}void AAA_PeerProcessDWRSendDWA::operator()(AAA_PeerStateMachine &fsm){ std::auto_ptr<AAAMessage> dwr = fsm.m_CurrentPeerEventParam->m_Msg; fsm.DisassembleDW(*dwr); // TBD: do failover here std::string message = "Successful device watchdog"; fsm.SendDWA(AAA_SUCCESS, message);}void AAA_Peer_ProcessDWA::operator()(AAA_PeerStateMachine &fsm){ std::auto_ptr<AAAMessage> dwa = fsm.m_CurrentPeerEventParam->m_Msg; AAA_MsgResultCode rcode(*dwa); if (rcode.InterpretedResultCode() == AAA_MsgResultCode::RCODE_SUCCESS) { fsm.DisassembleDW(*dwa); } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -