📄 aaa_peer_fsm.cxx
字号:
} else if (localHost.length() > peerHost.length()) { peerHost += std::string(localHost.length() - peerHost.length(), char(0x80)); } else if (localHost == peerHost) { // advertising the same hostname Cleanup(); return; } for (unsigned int i=0; i<localHost.size(); i++) { if (localHost[i] == peerHost[i]) { continue; } else if (localHost[i] > peerHost[i]) { Notify(AAA_PEER_EV_WIN_ELECTION); AAA_LOG(LM_INFO, "(%P|%t) ***** Local peer wins election *****\n"); return; } else { break; } } AAA_LOG(LM_INFO, "(%P|%t) ***** Peer (%s) wins election *****\n", peerHost.data());}void AAA_PeerStateMachine::Cleanup(unsigned int flags){ AAA_PeerCapabilities &cap = m_Data.m_PeerCapabilities; cap.m_Host = ""; cap.m_Realm = ""; while (! cap.m_HostIpLst.empty()) { diameter_address_t *ip = cap.m_HostIpLst.front(); cap.m_HostIpLst.pop_front(); delete ip; } cap.m_VendorId = 0; cap.m_ProductName = ""; cap.m_OriginStateId = 0; AAA_ApplicationIdLst *idList[] = { &cap.m_SupportedVendorIdLst, &cap.m_AuthAppIdLst, &cap.m_AcctAppIdLst }; for (int i=0; i<sizeof(idList)/sizeof(AAA_ApplicationIdLst*); i++) { while (! idList[i]->empty()) { idList[i]->pop_front(); } } while (! cap.m_VendorSpecificId.empty()) { AAA_VendorSpecificIdLst::iterator x = cap.m_VendorSpecificId.begin(); AAA_ApplicationIdLst &id = (*x).vendorIdLst; while (! id.empty()) { id.pop_front(); } cap.m_VendorSpecificId.pop_front(); } cap.m_InbandSecurityId = 0; cap.m_FirmwareRevision = 0; CancelTimer(AAA_PEER_EV_TIMEOUT); CancelTimer(AAA_PEER_EV_WATCHDOG); CancelTimer(AAA_PEER_EV_CONN_RETRY); if (flags & CLEANUP_FSM) { AAA_StateMachineWithTimer<AAA_PeerStateMachine>::Stop(); } if (flags & CLEANUP_IO_R) { m_Data.m_IOResponder.reset(); } if (flags & CLEANUP_IO_I) { m_Data.m_IOInitiator.reset(); } if (flags & CLEANUP_FSM) { m_CurrentPeerEventParam->m_Msg.reset(); m_CurrentPeerEventParam->m_IO.reset(); AAA_StateMachineWithTimer<AAA_PeerStateMachine>::Start(); } m_CleanupEvent = true;}int AAA_PeerStateMachine::RawSend(std::auto_ptr<AAAMessage> &msg, AAA_IO_Base *io){ AAAMessageBlock *aBuffer = NULL; for (int blockCnt = 1; blockCnt <= AAA_MsgCollector::MAX_MSG_BLOCK; blockCnt ++) { aBuffer = AAAMessageBlock::Acquire (AAA_MsgCollector::MAX_MSG_LENGTH * blockCnt); msg->acl.reset(); HeaderParser hp; hp.setRawData(aBuffer); hp.setAppData(&msg->hdr); hp.setDictData(PARSE_STRICT); try { hp.parseAppToRaw(); } catch (AAAErrorStatus &st) { ACE_UNUSED_ARG(st); aBuffer->Release(); return (-1); } PayloadParser pp; pp.setRawData(aBuffer); pp.setAppData(&msg->acl); pp.setDictData(msg->hdr.getDictHandle()); try { pp.parseAppToRaw(); } catch (AAAErrorStatus &st) { aBuffer->Release(); int type, code; st.get(type, code); if ((type == NORMAL) && (code == AAA_OUT_OF_SPACE)) { if (blockCnt < AAA_MsgCollector::MAX_MSG_BLOCK) { msg->acl.reset(); continue; } AAA_LOG(LM_ERROR, "(%P|%t) Not enough block space for transmission\n"); } return (-1); } msg->hdr.length = aBuffer->wr_ptr() - aBuffer->base(); try { hp.parseAppToRaw(); } catch (AAAErrorStatus st) { aBuffer->Release(); return (-1); } break; } aBuffer->length(msg->hdr.length); return io->Send(aBuffer);}void AAA_PeerStateMachine::DumpPeerCapabilities(){ AAA_PeerCapabilities &cap = m_Data.m_PeerCapabilities; AAA_LOG(LM_INFO, "(%P|%t) Peer Capabilities\n"); AAA_LOG(LM_INFO, "(%P|%t) Hostname : %s\n", cap.m_Host.data()); AAA_LOG(LM_INFO, "(%P|%t) Realm : %s\n", cap.m_Realm.data()); AAA_HostIpLst::iterator x = cap.m_HostIpLst.begin(); for (; x != cap.m_HostIpLst.end(); x++) { AAA_LOG(LM_INFO, "(%P|%t) Host IP : type=%d, %s\n", (*x)->type, inet_ntoa(*((struct in_addr*)(*x)->value.data()))); } AAA_LOG(LM_INFO, "(%P|%t) VendorId : %d\n", cap.m_VendorId); AAA_LOG(LM_INFO, "(%P|%t) Product Name : %s\n", cap.m_ProductName.data()); AAA_LOG(LM_INFO, "(%P|%t) Orig State : %d\n", cap.m_OriginStateId); AAA_ApplicationIdLst *idList[] = { &cap.m_SupportedVendorIdLst, &cap.m_AuthAppIdLst, &cap.m_AcctAppIdLst }; char *label[] = { "Supported Vendor Id", "Auth Application Id", "Acct Application Id" }; for (int i=0; i < sizeof(idList)/sizeof(AAA_ApplicationIdLst*); i++) { AAA_ApplicationIdLst::iterator x = idList[i]->begin(); for (; x != idList[i]->end(); x++) { AAA_LOG(LM_INFO, "(%P|%t) %s : %d\n", label[i], *x); } } AAA_VendorSpecificIdLst::iterator y = cap.m_VendorSpecificId.begin(); for (; y != cap.m_VendorSpecificId.end(); y++) { AAA_LOG(LM_INFO, "(%P|%t) Vendor Specific Id : "); if ((*y).authAppId > 0) { AAA_LOG(LM_INFO, " Auth=%d ", (*y).authAppId); } if ((*y).acctAppId > 0) { AAA_LOG(LM_INFO, " Acct=%d ", (*y).acctAppId); } AAA_LOG(LM_INFO, "%s\n", (((*y).authAppId == 0) && ((*y).acctAppId == 0)) ? "---" : ""); AAA_ApplicationIdLst::iterator z = (*y).vendorIdLst.begin(); for (; z != (*y).vendorIdLst.end(); z++) { AAA_LOG(LM_INFO, "(%P|%t) vendor id=%d\n", *z); } } AAA_LOG(LM_INFO, "(%P|%t) Inband Sec : %d\n", cap.m_InbandSecurityId); AAA_LOG(LM_INFO, "(%P|%t) Firmware Ver : %d\n", cap.m_FirmwareRevision);}bool AAA_PeerStateMachine::ValidatePeer(diameter_unsigned32_t &rcode, std::string &message){ /* 5.3. Capabilities Exchange When two Diameter peers establish a transport connection, they MUST exchange the Capabilities Exchange messages, as specified in the peer state machine (see Section 5.6). This message allows the discovery of a peer's identity and its capabilities (protocol version number, supported Diameter applications, security mechanisms, etc.) The receiver only issues commands to its peers that have advertised support for the Diameter application that defines the command. A Diameter node MUST cache the supported applications in order to ensure that unrecognized commands and/or AVPs are not unnecessarily sent to a peer. A receiver of a Capabilities-Exchange-Req (CER) message that does not have any applications in common with the sender MUST return a Capabilities-Exchange-Answer (CEA) with the Result-Code AVP set to AAA_NO_COMMON_APPLICATION, and SHOULD disconnect the transport layer connection. Note that receiving a CER or CEA from a peer advertising itself as a Relay (see Section 2.4) MUST be interpreted as having common applications with the peer. */ bool found = false; AAA_PeerCapabilities &cap = m_Data.m_PeerCapabilities; AAA_ApplicationIdLst *localIdList[] = { &AAA_CFG_GENERAL()->supportedVendorIdLst, &AAA_CFG_GENERAL()->authAppIdLst, &AAA_CFG_GENERAL()->acctAppIdLst }; AAA_ApplicationIdLst *idList[] = { &cap.m_SupportedVendorIdLst, &cap.m_AuthAppIdLst, &cap.m_AcctAppIdLst }; for (int i=0; i < sizeof(idList)/sizeof(AAA_ApplicationIdLst*); i++) { AAA_ApplicationIdLst::iterator x = idList[i]->begin(); for (; x != idList[i]->end(); x++) { if (AAA_ApplicationIdLookup::Find(*x, localIdList, sizeof(localIdList)/sizeof(AAA_ApplicationIdLst*))) { found = true; break; } if (AAA_ApplicationIdLookup::Find (*x, AAA_CFG_GENERAL()->vendorSpecificId)) { found = true; break; } } if (found) { break; } } if (! found) { AAA_VendorSpecificIdLst::iterator i = cap.m_VendorSpecificId.begin(); for (; i != cap.m_VendorSpecificId.end(); i++) { if (AAA_ApplicationIdLookup::Find((*i).authAppId, localIdList, sizeof(localIdList)/sizeof(AAA_ApplicationIdLst*))) { found = true; break; } if (AAA_ApplicationIdLookup::Find((*i).acctAppId, localIdList, sizeof(localIdList)/sizeof(AAA_ApplicationIdLst*))) { found = true; break; } if (AAA_ApplicationIdLookup::Find ((*i).authAppId, AAA_CFG_GENERAL()->vendorSpecificId)) { found = true; break; } if (AAA_ApplicationIdLookup::Find ((*i).acctAppId, AAA_CFG_GENERAL()->vendorSpecificId)) { found = true; break; } } } if (! found) { rcode = AAA_NO_COMMON_APPLICATION; message = "No common application id"; return false; } /* Similarly, a receiver of a Capabilities-Exchange-Req (CER) message that does not have any security mechanisms in common with the sender MUST return a Capabilities-Exchange-Answer (CEA) with the Result-Code AVP set to AAA_NO_COMMON_SECURITY, and SHOULD disconnect the transport layer connection. */ if (m_Data.m_TLS != (cap.m_InbandSecurityId ? true : false)) { rcode = AAA_NO_COMMON_SECURITY; message = "No matching in-band security id"; return false; } /* The CER and CEA messages MUST NOT be proxied, redirected or relayed. Since the CER/CEA messages cannot be proxied, it is still possible that an upstream agent receives a message for which it has no available peers to handle the application that corresponds to the Command-Code. In such instances, the 'E' bit is set in the answer message (see Section 7.) with the Result-Code AVP set to AAA_UNABLE_TO_DELIVER to inform the downstream to take action (e.g., re-routing request to an alternate peer). With the exception of the Capabilities-Exchange-Request message, a message of type Request that includes the Auth-Application-Id or Acct-Application-Id AVPs, or a message with an application-specific command code, MAY only be forwarded to a host that has explicitly advertised support for the application (or has advertised the Relay Application Identifier). */ rcode = AAA_SUCCESS; message = "Capabilities negotiation completed successfully"; return true;}void AAA_PeerStateMachine::MsgIdTxMessage(AAAMessage &msg){ if (msg.hdr.flags.r) { m_Data.m_PeerCapabilities.m_MsgId.m_LastTxHopId = AAA_HOPBYHOP_GEN()->Get(); m_Data.m_PeerCapabilities.m_MsgId.m_LastTxEndId = AAA_ENDTOEND_GEN()->Get(); msg.hdr.hh = m_Data.m_PeerCapabilities.m_MsgId.m_LastTxHopId; msg.hdr.ee = m_Data.m_PeerCapabilities.m_MsgId.m_LastTxEndId; } else { msg.hdr.hh = m_Data.m_PeerCapabilities.m_MsgId.m_LastRxHopId; msg.hdr.ee = m_Data.m_PeerCapabilities.m_MsgId.m_LastRxEndId; }}bool AAA_PeerStateMachine::MsgIdRxMessage(AAAMessage &msg){ if (msg.hdr.flags.r) { m_Data.m_PeerCapabilities.m_MsgId.m_LastRxHopId = msg.hdr.hh; m_Data.m_PeerCapabilities.m_MsgId.m_LastRxEndId = msg.hdr.ee; return (true); } return ((msg.hdr.hh == m_Data.m_PeerCapabilities.m_MsgId.m_LastTxHopId) && (msg.hdr.ee == m_Data.m_PeerCapabilities.m_MsgId.m_LastTxEndId));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -