Mercurial > hg > freeDiameter
changeset 89:3f8b437bcb66
Added some default routing handlers
author | Sebastien Decugis <sdecugis@nict.go.jp> |
---|---|
date | Mon, 07 Dec 2009 16:56:42 +0900 |
parents | 9e2db1647d6f |
children | 2c9444152e4b |
files | freeDiameter/dispatch.c freeDiameter/routing.c include/freeDiameter/freeDiameter.h |
diffstat | 3 files changed, 107 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/freeDiameter/dispatch.c Mon Dec 07 15:51:09 2009 +0900 +++ b/freeDiameter/dispatch.c Mon Dec 07 16:56:42 2009 +0900 @@ -66,6 +66,7 @@ } -/* Note2: if the message is still for local delivery, we should test for duplicate +/* Note: if the message is for local delivery, we should test for duplicate (draft-asveren-dime-dupcons-00). This may conflict with path validation decisions, no clear answer yet */ +
--- a/freeDiameter/routing.c Mon Dec 07 15:51:09 2009 +0900 +++ b/freeDiameter/routing.c Mon Dec 07 16:56:42 2009 +0900 @@ -305,7 +305,6 @@ return 0; } - /* The (routing-in) thread -- see description in freeDiameter.h */ static void * routing_in_thr(void * arg) { @@ -742,6 +741,104 @@ return NULL; } +/* First OUT callback: prevent sending to peers that do not support the message application */ +static int dont_send_if_no_common_app(void * cbdata, struct msg * msg, struct fd_list * candidates) +{ + struct fd_list * li; + struct msg_hdr * hdr; + + TRACE_ENTRY("%p %p %p", cbdata, msg, candidates); + CHECK_PARAMS(msg && candidates); + + CHECK_FCT( fd_msg_hdr(msg, &hdr) ); + + /* For Base Diameter Protocol, every peer is supposed to support it, so skip */ + if (hdr->msg_appl == 0) + return 0; + + /* Otherwise, check that the peers support the application */ + for (li = candidates->next; li != candidates; li = li->next) { + struct rtd_candidate *c = (struct rtd_candidate *) li; + struct fd_peer * peer; + struct fd_app *found; + CHECK_FCT( fd_peer_getbyid( c->diamid, (void *)&peer ) ); + if (peer && (peer->p_hdr.info.runtime.pir_relay == 0)) { + /* Check if the remote peer advertised the message's appli */ + CHECK_FCT( fd_app_check(&peer->p_hdr.info.runtime.pir_apps, hdr->msg_appl, &found) ); + if (!found) + c->score += FD_SCORE_NO_DELIVERY; + } + } + + return 0; +} + +/* Second OUT callback: Detect if the Destination-Host and Destination-Realm match the peer */ +static int score_destination_avp(void * cbdata, struct msg * msg, struct fd_list * candidates) +{ + struct fd_list * li; + struct avp * avp; + union avp_value *dh = NULL, *dr = NULL; + + TRACE_ENTRY("%p %p %p", cbdata, msg, candidates); + CHECK_PARAMS(msg && candidates); + + /* Search the Destination-Host and Destination-Realm AVPs -- we could also use fd_msg_search_avp here, but this one is slightly more efficient */ + CHECK_FCT( fd_msg_browse(msg, MSG_BRW_FIRST_CHILD, &avp, NULL) ); + while (avp) { + struct avp_hdr * ahdr; + CHECK_FCT( fd_msg_avp_hdr( avp, &ahdr ) ); + + if (! (ahdr->avp_flags & AVP_FLAG_VENDOR)) { + switch (ahdr->avp_code) { + case AC_DESTINATION_HOST: + /* Parse this AVP */ + CHECK_FCT( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict ) ); + ASSERT( ahdr->avp_value ); + dh = ahdr->avp_value; + break; + + case AC_DESTINATION_REALM: + /* Parse this AVP */ + CHECK_FCT( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict ) ); + ASSERT( ahdr->avp_value ); + dr = ahdr->avp_value; + break; + } + } + + if (dh && dr) + break; + + /* Go to next AVP */ + CHECK_FCT( fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL) ); + } + + /* Now, check each candidate against these AVP values */ + for (li = candidates->next; li != candidates; li = li->next) { + struct rtd_candidate *c = (struct rtd_candidate *) li; + struct fd_peer * peer; + CHECK_FCT( fd_peer_getbyid( c->diamid, (void *)&peer ) ); + if (peer) { + if (dh + && (dh->os.len == strlen(peer->p_hdr.info.pi_diamid)) + && (strncasecmp(peer->p_hdr.info.pi_diamid, dh->os.data, dh->os.len) == 0)) { + /* The candidate is the Destination-Host */ + c->score += FD_SCORE_FINALDEST; + } else { + if (dr && peer->p_hdr.info.runtime.pir_realm + && (dr->os.len == strlen(peer->p_hdr.info.runtime.pir_realm)) + && (strncasecmp(peer->p_hdr.info.runtime.pir_realm, dr->os.data, dr->os.len) == 0)) { + /* The candidate's realm matchs the Destination-Realm */ + c->score += FD_SCORE_REALM; + } + } + } + } + + return 0; +} + static pthread_t rt_out = (pthread_t)NULL; static pthread_t rt_in = (pthread_t)NULL; @@ -752,6 +849,11 @@ CHECK_POSIX( pthread_create( &rt_in, NULL, routing_in_thr, NULL) ); /* Later: TODO("Set the thresholds for the IN and OUT queues to create more routing threads as needed"); */ + + /* Register the built-in callbacks */ + CHECK_FCT( fd_rt_out_register( dont_send_if_no_common_app, NULL, 10, NULL ) ); + CHECK_FCT( fd_rt_out_register( score_destination_avp, NULL, 10, NULL ) ); + return 0; }
--- a/include/freeDiameter/freeDiameter.h Mon Dec 07 15:51:09 2009 +0900 +++ b/include/freeDiameter/freeDiameter.h Mon Dec 07 16:56:42 2009 +0900 @@ -564,13 +564,14 @@ FD_SCORE_LOAD_BALANCE = 1, /* Use this to differentiate between several peers with the same score */ FD_SCORE_DEFAULT = 5, /* The peer is a default route for all messages */ FD_SCORE_DEFAULT_REALM = 10, /* The peer is a default route for this realm */ + FD_SCORE_REALM = 15, /* The peer belongs to Destination-Realm of the message */ FD_SCORE_REDIR_HOST = 25, /* If there is a redirect rule with ALL_HOST for these message and peer */ FD_SCORE_REDIR_APP = 30, /* If there is a redirect rule with ALL_APPLICATION for these message and peer */ FD_SCORE_REDIR_REALM = 35, /* If there is a redirect rule with ALL_REALM for these message and peer */ FD_SCORE_REDIR_REALM_APP = 40, /* If there is a redirect rule with REALM_AND_APPLICATION for these message and peer */ FD_SCORE_REDIR_USER = 45, /* If there is a redirect rule with ALL_USER for these message and peer */ FD_SCORE_REDIR_SESSION = 50, /* If there is a redirect rule with ALL_SESSION for these message and peer */ - FD_SCORE_FINALDEST = 100 /* If the peer is the final recipient of the message, it receives a big score. */ + FD_SCORE_FINALDEST = 100 /* If the peer is the final recipient of the message (i.e. matching Destination-Host), it receives a big score. */ }; /*