00001
00054 #include "routing.h"
00055 #include "config.h"
00056 #include "peermanager.h"
00057 #include "diameter_api.h"
00058
00059 extern dp_config *config;
00068 int peer_handles_application(peer *p,int app_id,int vendor_id)
00069 {
00070 int i;
00071 if (!p || !p->applications || !p->applications_cnt) return 0;
00072 for(i=0;i<p->applications_cnt;i++)
00073 if (p->applications[i].id==app_id && p->applications[i].vendor==vendor_id) return 1;
00074 return 0;
00075 }
00076
00082 peer* get_first_connected_route(routing_entry *r,int app_id,int vendor_id)
00083 {
00084 routing_entry *i;
00085 peer *p;
00086 for(i=r;i;i=i->next){
00087 p = get_peer_by_fqdn(&(r->fqdn));
00088 if (p && (p->state==I_Open || p->state==R_Open) && peer_handles_application(p,app_id,vendor_id)) return p;
00089 }
00090 return 0;
00091 }
00092
00102 peer* get_routing_peer(AAAMessage *m)
00103 {
00104 str destination_realm={0,0},destination_host={0,0};
00105 AAA_AVP *avp,*avp_vendor,*avp2;
00106 AAA_AVP_LIST group;
00107 peer *p;
00108 routing_realm *rr;
00109 int app_id=0,vendor_id=0;
00110
00111 app_id = m->applicationId;
00112 avp = AAAFindMatchingAVP(m,0,AVP_Vendor_Specific_Application_Id,0,AAA_FORWARD_SEARCH);
00113 if (avp){
00114 group = AAAUngroupAVPS(avp->data);
00115 avp_vendor = AAAFindMatchingAVPList(group,group.head,AVP_Vendor_Id,0,0);
00116 avp2 = AAAFindMatchingAVPList(group,group.head,AVP_Auth_Application_Id,0,0);
00117 if (avp_vendor&&avp2){
00118 vendor_id = get_4bytes(avp_vendor->data.s);
00119 app_id = get_4bytes(avp2->data.s);
00120 }
00121 avp2 = AAAFindMatchingAVPList(group,group.head,AVP_Acct_Application_Id,0,0);
00122 if (avp_vendor&&avp2){
00123 vendor_id = get_4bytes(avp_vendor->data.s);
00124 app_id = get_4bytes(avp2->data.s);
00125 }
00126 AAAFreeAVPList(&group);
00127 }
00128
00129 avp = AAAFindMatchingAVP(m,0,AVP_Destination_Host,0,AAA_FORWARD_SEARCH);
00130 if (avp) destination_host = avp->data;
00131
00132 if (destination_host.len){
00133
00134 p = get_peer_by_fqdn(&destination_host);
00135 if (p && (p->state==I_Open || p->state==R_Open) && peer_handles_application(p,app_id,vendor_id)) return p;
00136
00137 }
00138
00139 avp = AAAFindMatchingAVP(m,0,AVP_Destination_Realm,0,AAA_FORWARD_SEARCH);
00140 if (avp) destination_realm = avp->data;
00141
00142 if (!config->r_table) {
00143 LOG(L_ERR,"ERROR:get_routing_peer(): Empty routing table.\n");
00144 return 0;
00145 }
00146
00147 if (destination_realm.len){
00148
00149 for(rr=config->r_table->realms;rr;rr=rr->next)
00150 if (rr->realm.len == destination_realm.len &&
00151 strncasecmp(rr->realm.s,destination_realm.s,destination_realm.len)==0)
00152 break;
00153 if (rr) {
00154 p = get_first_connected_route(rr->routes,app_id,vendor_id);
00155 if (p) return p;
00156 else LOG(L_ERR,"ERROR:get_routing_peer(): No connected Route peer found for Realm <%.*s>. Trying DefaultRoutes next...\n",
00157 destination_realm.len,destination_realm.s);
00158 }
00159 }
00160
00161
00162 p = get_first_connected_route(config->r_table->routes,app_id,vendor_id);
00163 if (!p){
00164 LOG(L_ERR,"ERROR:get_routing_peer(): No connected DefaultRoute peer found.\n");
00165 }
00166 return p;
00167 }