Navigation


Changeset 89:3f8b437bcb66 in freeDiameter


Ignore:
Timestamp:
Dec 7, 2009, 4:56:42 PM (14 years ago)
Author:
Sebastien Decugis <sdecugis@nict.go.jp>
Branch:
default
Phase:
public
Message:

Added some default routing handlers

Files:
3 edited

Legend:

Unmodified
Added
Removed
  • freeDiameter/dispatch.c

    r87 r89  
    6767
    6868
    69 /* Note2: if the message is still for local delivery, we should test for duplicate
     69/* Note: if the message is for local delivery, we should test for duplicate
    7070  (draft-asveren-dime-dupcons-00). This may conflict with path validation decisions, no clear answer yet */
    7171
     72
  • freeDiameter/routing.c

    r88 r89  
    305305        return 0;
    306306}
    307 
    308307
    309308/* The (routing-in) thread -- see description in freeDiameter.h */
     
    743742}
    744743
     744/* First OUT callback: prevent sending to peers that do not support the message application */
     745static int dont_send_if_no_common_app(void * cbdata, struct msg * msg, struct fd_list * candidates)
     746{
     747        struct fd_list * li;
     748        struct msg_hdr * hdr;
     749       
     750        TRACE_ENTRY("%p %p %p", cbdata, msg, candidates);
     751        CHECK_PARAMS(msg && candidates);
     752       
     753        CHECK_FCT( fd_msg_hdr(msg, &hdr) );
     754       
     755        /* For Base Diameter Protocol, every peer is supposed to support it, so skip */
     756        if (hdr->msg_appl == 0)
     757                return 0;
     758       
     759        /* Otherwise, check that the peers support the application */
     760        for (li = candidates->next; li != candidates; li = li->next) {
     761                struct rtd_candidate *c = (struct rtd_candidate *) li;
     762                struct fd_peer * peer;
     763                struct fd_app *found;
     764                CHECK_FCT( fd_peer_getbyid( c->diamid, (void *)&peer ) );
     765                if (peer && (peer->p_hdr.info.runtime.pir_relay == 0)) {
     766                        /* Check if the remote peer advertised the message's appli */
     767                        CHECK_FCT( fd_app_check(&peer->p_hdr.info.runtime.pir_apps, hdr->msg_appl, &found) );
     768                        if (!found)
     769                                c->score += FD_SCORE_NO_DELIVERY;
     770                }
     771        }
     772
     773        return 0;
     774}
     775
     776/* Second OUT callback: Detect if the Destination-Host and Destination-Realm match the peer */
     777static int score_destination_avp(void * cbdata, struct msg * msg, struct fd_list * candidates)
     778{
     779        struct fd_list * li;
     780        struct avp * avp;
     781        union avp_value *dh = NULL, *dr = NULL;
     782       
     783        TRACE_ENTRY("%p %p %p", cbdata, msg, candidates);
     784        CHECK_PARAMS(msg && candidates);
     785       
     786        /* Search the Destination-Host and Destination-Realm AVPs -- we could also use fd_msg_search_avp here, but this one is slightly more efficient */
     787        CHECK_FCT(  fd_msg_browse(msg, MSG_BRW_FIRST_CHILD, &avp, NULL) );
     788        while (avp) {
     789                struct avp_hdr * ahdr;
     790                CHECK_FCT(  fd_msg_avp_hdr( avp, &ahdr ) );
     791
     792                if (! (ahdr->avp_flags & AVP_FLAG_VENDOR)) {
     793                        switch (ahdr->avp_code) {
     794                                case AC_DESTINATION_HOST:
     795                                        /* Parse this AVP */
     796                                        CHECK_FCT( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict ) );
     797                                        ASSERT( ahdr->avp_value );
     798                                        dh = ahdr->avp_value;
     799                                        break;
     800
     801                                case AC_DESTINATION_REALM:
     802                                        /* Parse this AVP */
     803                                        CHECK_FCT( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict ) );
     804                                        ASSERT( ahdr->avp_value );
     805                                        dr = ahdr->avp_value;
     806                                        break;
     807                        }
     808                }
     809
     810                if (dh && dr)
     811                        break;
     812
     813                /* Go to next AVP */
     814                CHECK_FCT(  fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL) );
     815        }
     816       
     817        /* Now, check each candidate against these AVP values */
     818        for (li = candidates->next; li != candidates; li = li->next) {
     819                struct rtd_candidate *c = (struct rtd_candidate *) li;
     820                struct fd_peer * peer;
     821                CHECK_FCT( fd_peer_getbyid( c->diamid, (void *)&peer ) );
     822                if (peer) {
     823                        if (dh
     824                                && (dh->os.len == strlen(peer->p_hdr.info.pi_diamid))
     825                                && (strncasecmp(peer->p_hdr.info.pi_diamid, dh->os.data, dh->os.len) == 0)) {
     826                                /* The candidate is the Destination-Host */
     827                                c->score += FD_SCORE_FINALDEST;
     828                        } else {
     829                                if (dr  && peer->p_hdr.info.runtime.pir_realm
     830                                        && (dr->os.len == strlen(peer->p_hdr.info.runtime.pir_realm))
     831                                        && (strncasecmp(peer->p_hdr.info.runtime.pir_realm, dr->os.data, dr->os.len) == 0)) {
     832                                        /* The candidate's realm matchs the Destination-Realm */
     833                                        c->score += FD_SCORE_REALM;
     834                                }
     835                        }
     836                }
     837        }
     838
     839        return 0;
     840}
     841
    745842static pthread_t rt_out = (pthread_t)NULL;
    746843static pthread_t rt_in  = (pthread_t)NULL;
     
    753850       
    754851        /* Later: TODO("Set the thresholds for the IN and OUT queues to create more routing threads as needed"); */
     852       
     853        /* Register the built-in callbacks */
     854        CHECK_FCT( fd_rt_out_register( dont_send_if_no_common_app, NULL, 10, NULL ) );
     855        CHECK_FCT( fd_rt_out_register( score_destination_avp, NULL, 10, NULL ) );
     856       
    755857        return 0;
    756858}
  • include/freeDiameter/freeDiameter.h

    r87 r89  
    565565        FD_SCORE_DEFAULT         =   5, /* The peer is a default route for all messages */
    566566        FD_SCORE_DEFAULT_REALM   =  10, /* The peer is a default route for this realm */
     567        FD_SCORE_REALM           =  15, /* The peer belongs to Destination-Realm of the message */
    567568        FD_SCORE_REDIR_HOST      =  25, /* If there is a redirect rule with ALL_HOST for these message and peer */
    568569        FD_SCORE_REDIR_APP       =  30, /* If there is a redirect rule with ALL_APPLICATION for these message and peer */
     
    571572        FD_SCORE_REDIR_USER      =  45, /* If there is a redirect rule with ALL_USER for these message and peer */
    572573        FD_SCORE_REDIR_SESSION   =  50, /* If there is a redirect rule with ALL_SESSION for these message and peer */
    573         FD_SCORE_FINALDEST       = 100  /* If the peer is the final recipient of the message, it receives a big score. */
     574        FD_SCORE_FINALDEST       = 100  /* If the peer is the final recipient of the message (i.e. matching Destination-Host), it receives a big score. */
    574575};
    575576
Note: See TracChangeset for help on using the changeset viewer.