⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aaa_route_msg_router.cxx

📁 Diameter协议栈
💻 CXX
📖 第 1 页 / 共 3 页
字号:
        else {            AAA_LOG(LM_INFO, "(%P|%t) DestRealm(%s) in routing table but no matching app Id\n",                    DestRealm.data());	}    }    catch (...) {    }    return (AAA_ROUTE_RESULT_NEXT_CHAIN);}AAA_ROUTE_RESULT AAA_MsgRouter::RcRejected::Lookup(std::auto_ptr<AAAMessage> &msg,                                                   AAA_PeerEntry *&dest){    /*       6.1.  Diameter Request Routing Overview                     .                     .                     .         4. If none of the above is successful, an answer is returned with the            Result-Code set to AAA_UNABLE_TO_DELIVER, with the E-bit set.     */    AAA_LOG(LM_INFO, "(%P|%t) Router cannot deliver message, sending back with an error\n");    return (AAA_ROUTE_RESULT_SUCCESS);}AAA_ROUTE_RESULT AAA_MsgRouter::DcLocal::Process(std::auto_ptr<AAAMessage> msg,                                                 AAA_PeerEntry *source,                                                 AAA_PeerEntry *dest){    if (m_Arg.m_RedirectAgent.IsRedirected(msg)) {        return (m_Arg.m_RedirectAgent.Answer(msg, source, dest) == 0) ?            AAA_ROUTE_RESULT_SUCCESS: AAA_ROUTE_RESULT_FAILED;    }    if (msg->hdr.flags.e) {        return ErrorHandling(msg, source, dest);    }    else if (dest) {        return (dest->Send(msg) >= 0) ?            AAA_ROUTE_RESULT_SUCCESS: AAA_ROUTE_RESULT_FAILED;    }    else {        // original request must have been locally generated        m_Arg[AAA_MsgRouterHandlerTable::H_LOCAL]->            Answer(msg, source, dest);    }    return (AAA_ROUTE_RESULT_SUCCESS);}AAA_ROUTE_RESULT AAA_MsgRouter::DcLocal::ErrorHandling(std::auto_ptr<AAAMessage> msg,                                                      AAA_PeerEntry *source,                                                      AAA_PeerEntry *dest){    /*      Result-Code AVP values that are used to report protocol errors MUST      only be present in answer messages whose 'E' bit is set.  When a      request message is received that causes a protocol error, an answer      message is returned with the 'E' bit set, and the Result-Code AVP is      set to the appropriate protocol error value.  As the answer is sent      back towards the originator of the request, each proxy or relay agent      MAY take action on the message.                          1. Request        +---------+ Link Broken                +-------------------------->|Diameter |----///----+                |     +---------------------|         |           v         +------+--+  | 2. answer + 'E' set | Relay 2 |     +--------+         |Diameter |<-+ (Unable to Forward) +---------+     |Diameter|         |         |                                        |  Home  |         | Relay 1 |--+                     +---------+     | Server |         +---------+  |   3. Request        |Diameter |     +--------+                      +-------------------->|         |           ^                                            | Relay 3 |-----------+                                            +---------+            Figure 7:  Example of Protocol Error causing answer message       Figure 7 provides an example of a message forwarded upstream by a      Diameter relay.  When the message is received by Relay 2, and it      detects that it cannot forward the request to the home server, an      answer message is returned with the 'E' bit set and the Result-Code      AVP set to DIAMETER_UNABLE_TO_DELIVER.    */    AAA_MsgResultCode rcode(*msg);    switch (rcode.ResultCode()) {       case AAA_UNABLE_TO_DELIVER:           // TBD: Attempt to re-route       default:           if (dest) {               return (dest->Send(msg) >= 0) ?                   AAA_ROUTE_RESULT_SUCCESS: AAA_ROUTE_RESULT_FAILED;           }           else {               // original request must have been locally generated               m_Arg[AAA_MsgRouterHandlerTable::H_ERROR]->                  Answer(msg, source, dest);          }          break;    }    return (AAA_ROUTE_RESULT_SUCCESS);}int AAA_MsgRouter::DcLocal::RequestMsg(std::auto_ptr<AAAMessage> msg,                                       AAA_PeerEntry *source,                                       AAA_PeerEntry *dest){    if (source) {        Add(msg->hdr.hh, msg, source, dest);        m_Arg[AAA_MsgRouterHandlerTable::H_LOCAL]->            Request(msg, source, dest);    }    else {        AAA_LOG(LM_INFO, "(%P|%t) **** Looped back message, discarded ***\n");        AAA_MsgDump::Dump(*msg);    }    return (0);}AAA_ROUTE_RESULT AAA_MsgRouter::DcForward::Process(std::auto_ptr<AAAMessage> msg,                                                   AAA_PeerEntry *source,                                                   AAA_PeerEntry *dest){    return m_Arg.m_rcLocal.Delivery().Process(msg, source, dest);}int AAA_MsgRouter::DcForward::LoopDetection(std::auto_ptr<AAAMessage> &msg){    /*      A relay or proxy agent MUST check for forwarding loops when receiving      requests.  A loop is detected if the server finds its own identity in      a Route-Record AVP.  When such an event occurs, the agent MUST answer      with the Result-Code AVP set to AAA_LOOP_DETECTED.    */    AAA_IdentityAvpContainerWidget rrecord(msg->acl);    diameter_identity_t *rteRec = rrecord.GetAvp(AAA_AVPNAME_ROUTERECORD);    for (int p=1; rteRec; p++) {        if (*rteRec == (AAA_CFG_TRANSPORT()->identity)) {            // send back answer            msg->hdr.flags.r = 0;            AAA_MsgResultCode rcode(*msg);            rcode.ResultCode(AAA_LOOP_DETECTED);            AAA_LOG(LM_INFO, "(%P|%t) !!! WARNING !!!: Route record shows a loop in the message, sending back with error\n");            return (0);        }        rteRec = rrecord.GetAvp(AAA_AVPNAME_ROUTERECORD, p);    }    return (-1);}int AAA_MsgRouter::DcForward::RequestMsg(std::auto_ptr<AAAMessage> msg,                                         AAA_PeerEntry *source,                                         AAA_PeerEntry *dest){    if (LoopDetection(msg) == 0) {        if (source) {            return (source->Send(msg) >= 0) ? 0 : (-1);        }        else {            // request must have been locally generated            m_Arg[AAA_MsgRouterHandlerTable::H_ERROR]->                Request(msg, source, dest);            return (-1);        }    }    /*       The Diameter protocol requires that agents maintain       transaction state, which is used for failover purposes.       Transaction state implies that upon forwarding a request,       the Hop-by-Hop identifier is saved; the field is replaced       with a locally unique identifier, which is restored to its       original value when the corresponding answer is received.       The request's state is released upon receipt of the answer.       A stateless agent is one that only maintains transaction       state.     */    int h2hIndex, rcode;    if (source) {        int localHH = AAA_HOPBYHOP_GEN()->Get();        h2hIndex = Add(localHH, msg, source, dest);        msg->hdr.hh = localHH;    }    else {        // locally generated        if (msg->hdr.hh == 0) {            msg->hdr.hh = AAA_HOPBYHOP_GEN()->Get();        }        if (msg->hdr.ee == 0){            msg->hdr.ee = AAA_ENDTOEND_GEN()->Get();        }        h2hIndex = Add(msg->hdr.hh, msg, source, dest);    }        rcode = (dest->Send(msg) >= 0) ? 0 : (-1);        if (h2hIndex > 0) {        StoreRequestMessage(h2hIndex, msg);    }    return rcode;}AAA_ROUTE_RESULT AAA_MsgRouter::DcRouted::Process(std::auto_ptr<AAAMessage> msg,                                                  AAA_PeerEntry *source,                                                  AAA_PeerEntry *dest){    /*      6.2.2.  Relaying and Proxying Answers       If the answer is for a request which was proxied or relayed, the       agent MUST restore the original value of the Diameter header's Hop-       by-Hop Identifier field.       If the last Proxy-Info AVP in the message is targeted to the local       Diameter server, the AVP MUST be removed before the answer is       forwarded.       If a relay or proxy agent receives an answer with a Result-Code AVP       indicating a failure, it MUST NOT modify the contents of the AVP.       Any additional local errors detected SHOULD be logged, but not       reflected in the Result-Code AVP.  If the agent receives an answer       message with a Result-Code AVP indicating success, and it wishes to       modify the AVP to indicate an error, it MUST modify the Result-Code       AVP to contain the appropriate error in the message destined towards       the access device as well as include the Error-Reporting-Host AVP and       it MUST issue an STR on behalf of the access device.       The agent MUST then send the answer to the host that it received the       original request from.    */    if (m_Arg.m_RedirectAgent.IsRedirected(msg)) {        return (m_Arg.m_RedirectAgent.Answer(msg, source, dest) == 0) ?            AAA_ROUTE_RESULT_SUCCESS: AAA_ROUTE_RESULT_FAILED;    }    AAA_ROUTE_RESULT result = AAA_ROUTE_RESULT_SUCCESS;    if (! dest) {        // original request must have been locally generated        AAA_MsgRouterHandlerTable::H_TYPE type = (msg->hdr.flags.e) ?              AAA_MsgRouterHandlerTable::H_ERROR : AAA_MsgRouterHandlerTable::H_LOCAL;        m_Arg[type]->Answer(msg, source, dest);    }    else {        AAA_MsgRouterHandlerTable::H_TYPE type = (msg->hdr.flags.e) ?              AAA_MsgRouterHandlerTable::H_ERROR : AAA_MsgRouterHandlerTable::H_PROXY;        m_Arg[type]->Answer(msg, source, dest);        result = (dest->Send(msg) >= 0) ? AAA_ROUTE_RESULT_SUCCESS :               AAA_ROUTE_RESULT_FAILED;    }    return result;}int AAA_MsgRouter::DcRouted::RequestMsg(std::auto_ptr<AAAMessage> msg,                                        AAA_PeerEntry *source,                                        AAA_PeerEntry *dest){    AAA_IdentityAvpContainerWidget destRealm(msg->acl);    diameter_identity_t *DestRealm = destRealm.GetAvp(AAA_AVPNAME_DESTREALM);    if (! DestRealm) {        throw (0);    }        AAA_RouteEntry *route = AAA_ROUTE_TABLE()->Lookup(*DestRealm);    if (route == NULL) {        throw (0);    }    if (route->Action() == AAA_ROUTE_ACTION_LOCAL) {        return m_Arg.m_rcLocal.Delivery().RequestMsg(msg, source, dest);    }    else if (route->Action() == AAA_ROUTE_ACTION_REDIRECT) {        return m_Arg.m_RedirectAgent.Request(msg, source, dest);    }    else {        /*          6.1.8.  Relaying and Proxying Requests           A relay or proxy agent MUST append a Route-Record AVP to all requests           forwarded.  The AVP contains the identity of the peer the request was           received from.           The Hop-by-Hop identifier in the request is saved, and replaced with           a locally unique value.  The source of the request is also saved,           which includes the IP address, port and protocol.           A relay or proxy agent MAY include the Proxy-Info AVP in requests if           it requires access to any local state information when the           corresponding response is received.  Proxy-Info AVP has certain           security implications and SHOULD contain an embedded HMAC with a           node-local key.  Alternatively, it MAY simply use local storage to           store state information.           The message is then forwarded to the next hop, as identified in the           Realm Routing Table.           Figure 6 provides an example of message routing using the procedures           listed in these sections.             (Origin-Host=nas.mno.net)    (Origin-Host=nas.mno.net)             (Origin-Realm=mno.net)       (Origin-Realm=mno.net)             (Destination-Realm=example.com)  (Destination-                                               Realm=example.com)                                          (Route-Record=nas.example.net)             +------+      ------>      +------+      ------>      +------+             |      |     (Request)     |      |      (Request)    |      |             | NAS  +-------------------+ DRL  +-------------------+ HMS  |             |      |                   |      |                   |      |             +------+     <------       +------+     <------       +------+            example.net    (Answer)   example.net     (Answer)   example.com                (Origin-Host=hms.example.com)   (Origin-Host=hms.example.com)                (Origin-Realm=example.com)      (Origin-Realm=example.com)                        Figure 6: Routing of Diameter messages        */        if (m_Arg.m_rcForward.Delivery().LoopDetection(msg) == 0) {            return (source->Send(msg) >= 0) ? 0 : (-1);        }        AAA_IdentityAvpWidget rrecord(AAA_AVPNAME_ROUTERECORD);        rrecord.Get() = AAA_CFG_TRANSPORT()->identity;        msg->acl.add(rrecord());        if (route->Action() == AAA_ROUTE_ACTION_PROXY) {            if (m_Arg[AAA_MsgRouterHandlerTable::H_PROXY]->                    Request(msg, source, dest) != 0) {                // Proxy has enforced a policy.                 // Message will not be sent.                return (0);            }        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -