Navigation


Changes in / [1257:55d0867dd8b8:1263:285287f22041] in freeDiameter


Ignore:
Files:
1 added
10 edited

Legend:

Unmodified
Added
Removed
  • extensions/dict_dcca_3gpp/dict_dcca_3gpp.c

    r1231 r1262  
    1038710387                struct dict_avp_request vpa;
    1038810388                vpa.avp_vendor = 10415;
     10389                vpa.avp_name = "Address-Domain";
     10390                CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
     10391                struct local_rules_definition rules[] =
     10392                        {
     10393                                { { .avp_vendor = 10415, .avp_name = "Domain-Name" }, RULE_OPTIONAL, -1, 1 },
     10394                                { { .avp_vendor = 10415, .avp_name = "3GPP-IMSI-MCC-MNC" }, RULE_OPTIONAL, -1, 1 },
     10395                        };
     10396                        PARSE_loc_rules(rules, rule_avp);
     10397        }
     10398
     10399        {
     10400                struct dict_object *rule_avp;
     10401                struct dict_avp_request vpa;
     10402                vpa.avp_vendor = 10415;
    1038910403                vpa.avp_name = "Application-Server-Information";
    1039010404                CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
     
    1039310407                                { { .avp_vendor = 10415, .avp_name = "Application-Server" }, RULE_REQUIRED, -1, 1 },
    1039410408                                { { .avp_vendor = 10415, .avp_name = "Application-Provided-Called-Party-Address" }, RULE_OPTIONAL, -1, -1 },
     10409                        };
     10410                        PARSE_loc_rules(rules, rule_avp);
     10411        }
     10412
     10413        {
     10414                struct dict_object *rule_avp;
     10415                struct dict_avp_request vpa;
     10416                vpa.avp_vendor = 10415;
     10417                vpa.avp_name = "Destination-Interface";
     10418                CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
     10419                struct local_rules_definition rules[] =
     10420                        {
     10421                                { { .avp_vendor = 10415, .avp_name = "Interface-Id" }, RULE_OPTIONAL, -1, 1 },
     10422                                { { .avp_vendor = 10415, .avp_name = "Interface-Text" }, RULE_OPTIONAL, -1, 1 },
     10423                                { { .avp_vendor = 10415, .avp_name = "Interface-Port" }, RULE_OPTIONAL, -1, 1 },
     10424                                { { .avp_vendor = 10415, .avp_name = "Interface-Type" }, RULE_OPTIONAL, -1, 1 },
    1039510425                        };
    1039610426                        PARSE_loc_rules(rules, rule_avp);
     
    1048710517                struct dict_avp_request vpa;
    1048810518                vpa.avp_vendor = 10415;
     10519                vpa.avp_name = "Message-Class";
     10520                CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
     10521                struct local_rules_definition rules[] =
     10522                        {
     10523                                { { .avp_vendor = 10415, .avp_name = "Class-Identifier" }, RULE_OPTIONAL, -1, 1 },
     10524                                { { .avp_vendor = 10415, .avp_name = "Token-Text" }, RULE_OPTIONAL, -1, 1 },
     10525                        };
     10526                        PARSE_loc_rules(rules, rule_avp);
     10527        }
     10528
     10529        {
     10530                struct dict_object *rule_avp;
     10531                struct dict_avp_request vpa;
     10532                vpa.avp_vendor = 10415;
    1048910533                vpa.avp_name = "MMS-Information";
    1049010534                CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
     
    1054510589
    1054610590        {
    10547                 /* Used-Service-Unit */
    10548                 /* additional allowed AVPs */
    10549                 struct dict_object *rule_avp;
    10550                 struct dict_avp_request vpa;
    10551                 vpa.avp_vendor = 0;
    10552                 vpa.avp_name = "Used-Service-Unit";
    10553                 CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
    10554                 struct local_rules_definition rules[] =
    10555                         {
    10556                                 { { .avp_vendor = 10415, .avp_name = "Reporting-Reason" }, RULE_OPTIONAL, -1, 1 },
    10557                                 { { .avp_vendor = 10415, .avp_name = "Event-Charging-TimeStamp" }, RULE_OPTIONAL, -1, -1 },
    10558                         };
    10559                 PARSE_loc_rules(rules, rule_avp);
    10560         }
    10561 
    10562         {
    1056310591                struct dict_object *rule_avp;
    1056410592                struct dict_avp_request vpa;
     
    1058710615                                { { .avp_vendor = 10415, .avp_name = "Address-Data" }, RULE_OPTIONAL, -1, 1 },
    1058810616                                { { .avp_vendor = 10415, .avp_name = "Address-Domain" }, RULE_OPTIONAL, -1, 1 },
     10617                        };
     10618                        PARSE_loc_rules(rules, rule_avp);
     10619        }
     10620
     10621        {
     10622                struct dict_object *rule_avp;
     10623                struct dict_avp_request vpa;
     10624                vpa.avp_vendor = 10415;
     10625                vpa.avp_name = "Originator-Interface";
     10626                CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
     10627                struct local_rules_definition rules[] =
     10628                        {
     10629                                { { .avp_vendor = 10415, .avp_name = "Interface-Id" }, RULE_OPTIONAL, -1, 1 },
     10630                                { { .avp_vendor = 10415, .avp_name = "Interface-Text" }, RULE_OPTIONAL, -1, 1 },
     10631                                { { .avp_vendor = 10415, .avp_name = "Interface-Port" }, RULE_OPTIONAL, -1, 1 },
     10632                                { { .avp_vendor = 10415, .avp_name = "Interface-Type" }, RULE_OPTIONAL, -1, 1 },
    1058910633                        };
    1059010634                        PARSE_loc_rules(rules, rule_avp);
     
    1068410728                struct dict_avp_request vpa;
    1068510729                vpa.avp_vendor = 10415;
     10730                vpa.avp_name = "Recipient-Info";
     10731                CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
     10732                struct local_rules_definition rules[] =
     10733                        {
     10734                                { { .avp_vendor = 10415, .avp_name = "Destination-Interface" }, RULE_OPTIONAL, -1, 1 },
     10735                                { { .avp_vendor = 10415, .avp_name = "Recipient-Address" }, RULE_OPTIONAL, -1, -1 },
     10736                                { { .avp_vendor = 10415, .avp_name = "Recipient-Received-Address" }, RULE_OPTIONAL, -1, -1 },
     10737                                { { .avp_vendor = 10415, .avp_name = "Recipient-SCCP-Address" }, RULE_OPTIONAL, -1, 1 },
     10738                                { { .avp_vendor = 10415, .avp_name = "SM-Protocol-ID" }, RULE_OPTIONAL, -1, 1 },
     10739                        };
     10740                        PARSE_loc_rules(rules, rule_avp);
     10741        }
     10742
     10743        {
     10744                struct dict_object *rule_avp;
     10745                struct dict_avp_request vpa;
     10746                vpa.avp_vendor = 10415;
     10747                vpa.avp_name = "Recipient-Received-Address";
     10748                CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
     10749                struct local_rules_definition rules[] =
     10750                        {
     10751                                { { .avp_vendor = 10415, .avp_name = "Address-Type" }, RULE_OPTIONAL, -1, 1 },
     10752                                { { .avp_vendor = 10415, .avp_name = "Address-Data" }, RULE_OPTIONAL, -1, 1 },
     10753                                { { .avp_vendor = 10415, .avp_name = "Address-Domain" }, RULE_OPTIONAL, -1, 1 },
     10754                        };
     10755                        PARSE_loc_rules(rules, rule_avp);
     10756        }
     10757
     10758        {
     10759                struct dict_object *rule_avp;
     10760                struct dict_avp_request vpa;
     10761                vpa.avp_vendor = 10415;
    1068610762                vpa.avp_name = "SDP-Media-Component";
    1068710763                CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
     
    1078610862        }
    1078710863
     10864        {
     10865                /* Used-Service-Unit */
     10866                /* additional allowed AVPs */
     10867                struct dict_object *rule_avp;
     10868                struct dict_avp_request vpa;
     10869                vpa.avp_vendor = 0;
     10870                vpa.avp_name = "Used-Service-Unit";
     10871                CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
     10872                struct local_rules_definition rules[] =
     10873                        {
     10874                                { { .avp_vendor = 10415, .avp_name = "Reporting-Reason" }, RULE_OPTIONAL, -1, 1 },
     10875                                { { .avp_vendor = 10415, .avp_name = "Event-Charging-TimeStamp" }, RULE_OPTIONAL, -1, -1 },
     10876                        };
     10877                PARSE_loc_rules(rules, rule_avp);
     10878        }
     10879
    1078810880        /* OMA */
    1078910881        {
  • extensions/rt_redirect/CMakeLists.txt

    r717 r1260  
    99        redir_fwd.c
    1010        redir_out.c
     11        uthash.h
    1112        )
    1213
  • extensions/rt_redirect/redir_entries.c

    r740 r1260  
    11/*********************************************************************************************************
    22* Software License Agreement (BSD License)                                                               *
    3 * Author: Sebastien Decugis <sdecugis@freediameter.net>                                                  *
     3* Authors: Sebastien Decugis <sdecugis@freediameter.net>                                                 *
     4* and Thomas Klausner <tk@giga.or.at>                                                                    *
    45*                                                                                                        *
    5 * Copyright (c) 2011, WIDE Project and NICT                                                              *
     6* Copyright (c) 2011, 2014, WIDE Project and NICT                                                        *
    67* All rights reserved.                                                                                   *
    78*                                                                                                        *
     
    3536
    3637#include "rt_redir.h"
     38#include "uthash.h"
    3739
    3840/* The array with all entries ordered by their data */
    3941struct redir_line redirects_usages[H_U_MAX + 1];
     42
     43/* for symmetry reasons, hash tables for all types exist, but only ALL_SESSION and ALL_USER will be used */
     44struct redir_entry *redirect_hash_table[H_U_MAX+1];
    4045
    4146/* Initialize the array */
     
    4348{
    4449        int i;
    45        
     50
    4651        TRACE_ENTRY("");
    47        
     52
    4853        /* redirects_usages */
    4954        memset(&redirects_usages, 0, sizeof(redirects_usages));
    50        
     55
    5156        for (i = 0; i <= H_U_MAX; i++) {
     57                /* only one of the two will be used for each type, but initialize both to be on the safe side */
     58
     59                /* initialize list */
    5260                CHECK_POSIX( pthread_rwlock_init( &redirects_usages[i].lock, NULL) );
    5361                fd_list_init( &redirects_usages[i].sentinel, &redirects_usages[i] );
    54         }
    55        
     62
     63                /* initialize hash table */
     64                redirect_hash_table[i] = NULL;
     65        }
     66
    5667        /* initialize the scores */
    5768        redirects_usages[ DONT_CACHE            ].score = FD_SCORE_REDIR_ONCE;
     
    6677}
    6778
     79int redir_entry_fini()
     80{
     81        int i;
     82        struct redir_entry *current_entry, *tmp;
     83
     84        /* Empty all entries */
     85        CHECK_POSIX_DO( pthread_mutex_lock(&redir_exp_peer_lock),   );
     86        for (i = 0; i <= H_U_MAX; i++) {
     87                CHECK_POSIX_DO( pthread_rwlock_wrlock( &redirects_usages[i].lock), );
     88                switch(i) {
     89                case ALL_SESSION:
     90                case ALL_USER:
     91                        HASH_ITER(hh, redirect_hash_table[i], current_entry, tmp) {
     92                                HASH_DEL(redirect_hash_table[i], current_entry);
     93                                CHECK_FCT_DO( redir_entry_destroy(current_entry), );
     94                        }
     95                        break;
     96                default:
     97                        while (!FD_IS_LIST_EMPTY(&redirects_usages[i].sentinel)) {
     98                                struct redir_entry * e = redirects_usages[i].sentinel.next->o;
     99                                fd_list_unlink(&e->redir_list);
     100                                CHECK_FCT_DO( redir_entry_destroy(e), );
     101                        }
     102                }
     103                CHECK_POSIX_DO( pthread_rwlock_unlock( &redirects_usages[i].lock), );
     104                CHECK_POSIX_DO( pthread_rwlock_destroy( &redirects_usages[i].lock), );
     105        }
     106        CHECK_POSIX_DO( pthread_mutex_unlock(&redir_exp_peer_lock),   );
     107
     108        return 0;
     109}
    68110
    69111/* Create a new redir_entry and add the correct data */
     
    73115        os0_t s;
    74116        size_t l;
    75        
     117
    76118        TRACE_ENTRY("%p %p %d %p %p %zd %p %zd", e, targets, rhu, qry, nh, nhlen, oh, ohlen)
    77119        ASSERT(e && targets && (rhu <= H_U_MAX) && qry && nh && nhlen && oh && ohlen);
    78        
     120
    79121        CHECK_MALLOC( entry = malloc(sizeof(struct redir_entry)) );
    80122        memset(entry, 0, sizeof(struct redir_entry));
    81        
     123
    82124        entry->eyec = REDIR_ENTRY_EYEC;
    83        
     125
    84126        CHECK_MALLOC( entry->from.s = os0dup(nh, nhlen) );
    85127        entry->from.l = nhlen;
    86        
     128
    87129        fd_list_init(&entry->target_peers_list, entry);
    88130        fd_list_move_end(&entry->target_peers_list, targets);
    89        
     131
    90132        fd_list_init(&entry->exp_list, entry);
    91        
     133
    92134        entry->type = rhu;
     135        /* list entry for putting into redirects_usage; also doubles as pointer into that list so it can be removed easily */
    93136        fd_list_init(&entry->redir_list, entry);
    94137        /* finally initialize the data */
     
    97140                        entry->data.message.msg = qry;
    98141                        break;
    99                        
     142
    100143                case ALL_SESSION:
    101144                        {
     
    114157                        }
    115158                        break;
    116                
     159
    117160                case ALL_REALM:
    118161                        {
     
    132175                        }
    133176                        break;
    134                                
     177
    135178                case REALM_AND_APPLICATION:
    136179                        {
     
    156199                        }
    157200                        break;
    158                                
     201
    159202                case ALL_APPLICATION:
    160203                        {
     
    164207                        }
    165208                        break;
    166                        
     209
    167210                case ALL_HOST:
    168211                        CHECK_MALLOC( entry->data.host.s = os0dup(oh, ohlen) );
    169212                        entry->data.host.l = ohlen;
    170213                        break;
    171                        
     214
    172215                case ALL_USER:
    173216                        {
     
    187230                        }
    188231                        break;
    189                
     232
    190233                default:
    191234                        ASSERT(0);
    192235                        return EINVAL;
    193236        }
    194        
     237
    195238        /* We're done */
    196239        *e = entry;
     
    203246        unsigned long v1 = (unsigned long) d1->message.msg;
    204247        unsigned long v2 = (unsigned long) d2->message.msg;
    205         if (v1 > v2) 
     248        if (v1 > v2)
    206249                return 1;
    207250        if (v1 < v2)
     
    211254/* Compare two applications (REALM_AND_APPLICATION and ALL_APPLICATION) */
    212255static int compare_entries_appl(union matchdata * d1, union matchdata * d2) {
    213         if (d1->app.a > d2->app.a) 
     256        if (d1->app.a > d2->app.a)
    214257                return 1;
    215         if (d1->app.a < d2->app.a) 
     258        if (d1->app.a < d2->app.a)
    216259                return -1;
    217260        return 0;
     
    238281{
    239282        struct fd_list * li;
    240        
     283        struct redir_entry * r = NULL;
     284
    241285        TRACE_ENTRY("%p", e);
    242286        CHECK_PARAMS(e && (e->eyec == REDIR_ENTRY_EYEC));
    243        
     287
    244288        /* Write-Lock the line */
    245289        CHECK_POSIX( pthread_rwlock_wrlock( RWLOCK_REDIR(e) ) );
    246        
    247         for (li = redirects_usages[e->type].sentinel.next; li != &redirects_usages[e->type].sentinel; li = li->next) {
    248                 struct redir_entry * n = li->o;
    249                 int cmp = redir_entry_cmp_key[e->type](&e->data, &n->data);
    250                 if (cmp <= 0)
    251                         break;
    252         }
    253        
    254         fd_list_insert_before(li, &e->redir_list);
    255        
     290
     291        switch (e->type) {
     292        case ALL_SESSION:
     293                HASH_FIND(hh, redirect_hash_table[e->type], e->data.session.s, e->data.session.l, r);
     294                if (r) {
     295                        /* previously existing entry, delete it from hash and free it */
     296                        HASH_DELETE(hh, redirect_hash_table[e->type], r);
     297                        CHECK_FCT_DO( redir_entry_destroy(r), );
     298                }
     299                HASH_ADD_KEYPTR(hh, redirect_hash_table[e->type], e->data.session.s, e->data.session.l, e);
     300                break;
     301        case ALL_USER:
     302                HASH_FIND(hh, redirect_hash_table[e->type], e->data.user.s, e->data.user.l, r);
     303                if (r) {
     304                        /* previously existing entry, delete it from hash and free it */
     305                        HASH_DELETE(hh, redirect_hash_table[e->type], r);
     306                        CHECK_FCT_DO( redir_entry_destroy(r), );
     307                }
     308                HASH_ADD_KEYPTR(hh, redirect_hash_table[e->type], e->data.user.s, e->data.user.l, e);
     309                break;
     310        default:
     311                for (li = redirects_usages[e->type].sentinel.next; li != &redirects_usages[e->type].sentinel; li = li->next) {
     312                        struct redir_entry * n = li->o;
     313                        int cmp = redir_entry_cmp_key[e->type](&e->data, &n->data);
     314                        if (cmp <= 0)
     315                                break;
     316                }
     317
     318                fd_list_insert_before(li, &e->redir_list);
     319                break;
     320        }
     321
    256322        /* unLock the line */
    257323        CHECK_POSIX( pthread_rwlock_unlock( RWLOCK_REDIR(e) ) );
     
    263329int redir_entry_destroy(struct redir_entry * e)
    264330{
     331        struct redir_entry *match;
    265332        TRACE_ENTRY("%p", e);
    266333        CHECK_PARAMS(e && (e->eyec == REDIR_ENTRY_EYEC));
    267        
    268         /* If the entry is linked, lock the rwlock also */
    269         if (!FD_IS_LIST_EMPTY(&e->redir_list)) {
    270                 CHECK_POSIX( pthread_rwlock_wrlock( RWLOCK_REDIR(e) ) );
    271                 fd_list_unlink(&e->redir_list);
    272                 CHECK_POSIX( pthread_rwlock_unlock( RWLOCK_REDIR(e) ) );
    273         }
    274        
     334
     335        switch (e->type) {
     336        case ALL_SESSION:
     337                /* If the entry is in the hash table, lock the rwlock also */
     338                HASH_FIND(hh, redirect_hash_table[e->type], e->data.session.s, e->data.session.l, match);
     339                if (match) {
     340                        /* TODO: check if e == match? */
     341                        CHECK_POSIX( pthread_rwlock_wrlock( RWLOCK_REDIR(e) ) );
     342                        HASH_DELETE(hh, redirect_hash_table[e->type], match);
     343                        CHECK_POSIX( pthread_rwlock_unlock( RWLOCK_REDIR(e) ) );
     344                }
     345                break;
     346        case ALL_USER:
     347                /* If the entry is in the hash table, lock the rwlock also */
     348                HASH_FIND(hh, redirect_hash_table[e->type], e->data.user.s, e->data.user.l, match);
     349                if (match) {
     350                        /* TODO: check if e == match? */
     351                        CHECK_POSIX( pthread_rwlock_wrlock( RWLOCK_REDIR(e) ) );
     352                        HASH_DELETE(hh, redirect_hash_table[e->type], match);
     353                        CHECK_POSIX( pthread_rwlock_unlock( RWLOCK_REDIR(e) ) );
     354                }
     355                break;
     356        default:
     357                /* If the entry is linked, lock the rwlock also */
     358                if (!FD_IS_LIST_EMPTY(&e->redir_list)) {
     359                        CHECK_POSIX( pthread_rwlock_wrlock( RWLOCK_REDIR(e) ) );
     360                        fd_list_unlink(&e->redir_list);
     361                        CHECK_POSIX( pthread_rwlock_unlock( RWLOCK_REDIR(e) ) );
     362                }
     363                break;
     364        }
     365
    275366        /* Now unlink from other list */
    276367        fd_list_unlink(&e->exp_list);
    277        
     368
    278369        /* Empty the targets list */
    279370        while (!FD_IS_LIST_EMPTY(&e->target_peers_list)) {
    280371                struct redir_host * h = (struct redir_host *)e->target_peers_list.next->o;
    281                
     372
    282373                fd_list_unlink(&h->chain);
    283374                free(h->id);
    284375                free(h);
    285376        }
    286        
     377
    287378        /* Now we can destroy the data safely */
    288379        switch (e->type) {
     
    312403                        return EINVAL;
    313404        }
    314        
     405
    315406        free(e->from.s);
    316        
     407
    317408        free(e);
    318409        return 0;
  • extensions/rt_redirect/redir_expiry.c

    r740 r1259  
    4141/* Entries by their ascending expiration date, to accelerate the work of the expire thread */
    4242static struct fd_list  expire_list = FD_LIST_INITIALIZER(expire_list);
    43 static pthread_cond_t  exp_cnd  = PTHREAD_COND_INITIALIZER; 
     43static pthread_cond_t  exp_cnd  = PTHREAD_COND_INITIALIZER;
    4444
    4545pthread_mutex_t redir_exp_peer_lock = PTHREAD_MUTEX_INITIALIZER;
    4646
    4747/* The thread that handles expired entries cleanup. */
    48 void * redir_exp_thr_fct(void * arg) 
     48void * redir_exp_thr_fct(void * arg)
    4949{
    5050        fd_log_threadname ( "Redirects/expire" );
     
    5353        CHECK_POSIX_DO( pthread_mutex_lock(&redir_exp_peer_lock),  goto fatal_error );
    5454        pthread_cleanup_push( fd_cleanup_mutex, &redir_exp_peer_lock );
    55        
     55
    5656        do {
    5757                struct timespec now;
    5858                struct redir_entry * first;
    59 again:         
     59again:
    6060                /* Check if there are expiring entries available */
    6161                if (FD_IS_LIST_EMPTY(&expire_list)) {
     
    6565                        goto again;
    6666                }
    67                
     67
    6868                /* Get the pointer to the entry that expires first */
    6969                first = (struct redir_entry *)(expire_list.next->o);
    70                
     70
    7171                /* Get the current time */
    7272                CHECK_SYS_DO(  clock_gettime(CLOCK_REALTIME, &now),  break  );
     
    7474                /* If first session is not expired, we just wait until it happens */
    7575                if ( TS_IS_INFERIOR( &now, &first->timeout ) ) {
    76                        
    77                         CHECK_POSIX_DO2(  pthread_cond_timedwait( &exp_cnd, &redir_exp_peer_lock, &first->timeout ), 
     76
     77                        CHECK_POSIX_DO2(  pthread_cond_timedwait( &exp_cnd, &redir_exp_peer_lock, &first->timeout ),
    7878                                        ETIMEDOUT, /* ETIMEDOUT is a normal error, continue */,
    7979                                        /* on other error, */ break );
    80        
     80
    8181                        /* on wakeup, loop */
    8282                        goto again;
    8383                }
    84                
     84
    8585                /* Now, the first entry in the list is expired; destroy it */
    86                
     86
    8787                CHECK_FCT_DO( redir_entry_destroy( first ), break );
    88                
     88
    8989        } while (1);
    90        
     90
    9191        pthread_cleanup_pop( 0 );
    9292        CHECK_POSIX_DO( pthread_mutex_unlock(&redir_exp_peer_lock),  );
    93        
     93
    9494fatal_error:
    9595        TRACE_DEBUG(INFO, "A system error occurred in redirect module! Expiry thread is terminating...");
     
    104104        TRACE_ENTRY("%p %d", e, duration);
    105105        CHECK_PARAMS(e && (e->eyec == REDIR_ENTRY_EYEC) && duration );
    106        
     106
    107107        /* Unlink in case it was already set before */
    108108        fd_list_unlink(&e->exp_list);
    109        
     109
    110110        /* Get current time */
    111111        CHECK_SYS(  clock_gettime(CLOCK_REALTIME, &e->timeout)  );
    112        
     112
    113113        /* Add the duration */
    114114        e->timeout.tv_sec += duration;
    115        
     115
    116116        /* now search the next element in the list */
    117117        for (li = expire_list.next; li != &expire_list; li = li->next) {
    118118                struct redir_entry * n = li->o;
    119                
     119
    120120                if ( TS_IS_INFERIOR( &e->timeout, &n->timeout ) )
    121121                        break;
    122        
     122
    123123        }
    124        
     124
    125125        /* Insert before this element */
    126126        fd_list_insert_before(li, &e->exp_list);
    127        
     127
    128128        /* Signal the expiry thread if needed */
    129129        if (e->exp_list.prev == &expire_list) { /* it is the first element */
    130130                CHECK_POSIX( pthread_cond_signal(&exp_cnd) );
    131131        }
    132        
     132
    133133        /* Done */
    134134        return 0;
  • extensions/rt_redirect/redir_fwd.c

    r1127 r1259  
    5959        int nbrh = 0;
    6060        struct redir_entry * entry;
    61        
     61
    6262        TRACE_ENTRY("%p %p", cbdata, msg);
    63        
     63
    6464        CHECK_PARAMS(msg && *msg);
    65        
     65
    6666        m = *msg;
    67        
     67
    6868        /* First get the header */
    6969        CHECK_FCT( fd_msg_hdr(m, &hdr) );
    70        
     70
    7171        /* Check if we have an error */
    7272        ASSERT(!(hdr->msg_flags & CMD_FLAG_REQUEST));
     
    7575                return 0;
    7676        }
    77        
     77
    7878        /* Now get the AVPs we are interested in */
    7979        CHECK_FCT(  fd_msg_browse(m, MSG_BRW_FIRST_CHILD, &avp, NULL)  );
    8080        while (avp) {
    8181                struct avp_hdr * ahdr;
    82                        
     82
    8383                CHECK_FCT(  fd_msg_avp_hdr( avp, &ahdr )  );
    8484                if (! (ahdr->avp_flags & AVP_FLAG_VENDOR)) {
     
    9090                                        a_oh = ahdr->avp_value;
    9191                                        break;
    92                                        
     92
    9393                                case AC_RESULT_CODE:
    9494                                        /* Parse this AVP */
     
    9696                                        ASSERT( ahdr->avp_value );
    9797                                        a_rc = ahdr->avp_value;
    98                                        
     98
    9999                                        if (a_rc->u32 != ER_DIAMETER_REDIRECT_INDICATION) {
    100100                                                /* It is not a REDIRECT error, we don't do anything */
     
    102102                                        }
    103103                                        break;
    104                                        
     104
    105105                                case AC_REDIRECT_HOST:
    106106                                        {
     
    112112                                                int      l4 = 0;
    113113                                                char     proto = 0;
    114                                                
     114
    115115                                                /* Parse this AVP */
    116116                                                CHECK_FCT( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict, NULL ) );
    117117                                                ASSERT( ahdr->avp_value );
    118                                                
     118
    119119                                                nbrh++;
    120                                                
    121                                                 CHECK_FCT_DO( fd_os_parse_DiameterURI(ahdr->avp_value->os.data, ahdr->avp_value->os.len, 
     120
     121                                                CHECK_FCT_DO( fd_os_parse_DiameterURI(ahdr->avp_value->os.data, ahdr->avp_value->os.len,
    122122                                                                        &id, &len, &secure, &port, &l4, &proto),
    123123                                                        {
     
    125125                                                                break;
    126126                                                        } );
    127                                                
     127
    128128                                                /* Now check if the transport & protocol are supported */
    129129                                                if (proto && (proto != 'd')) {
     
    137137                                                        break;
    138138                                                }
    139                                                
     139
    140140                                                /* It looks OK, save this entry. */
    141                                                
     141
    142142                                                CHECK_MALLOC( h = malloc(sizeof(struct redir_host)) );
    143143                                                memset(h, 0, sizeof(struct redir_host));
     
    146146                                                h->len = len;
    147147                                                /* later: secure, port */
    148                                                
     148
    149149                                                /* The list is kept ordered by id so that it is faster to compare to candidates later */
    150150                                                for (li = task.rh.next; li != &task.rh; li = li->next) {
     
    183183                CHECK_FCT(  fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL)  );
    184184        }
    185        
     185
    186186        /* Check we have received the necessary information */
    187187        if (!a_rc) {
     
    189189                goto out;
    190190        }
    191        
     191
    192192        if (!a_oh) {
    193193                TRACE_DEBUG(FULL, "Invalid Diameter answer without an Origin-Host AVP, Redirect module gave up");
    194194                goto out;
    195195        }
    196        
     196
    197197        if (FD_IS_LIST_EMPTY(&task.rh)) {
    198198                TRACE_DEBUG(FULL, "Diameter answer with a DIAMETER_REDIRECT_INDICATION Result-Code AVP but no valid/supported Redirect-Host AVP, Redirect module gave up");
     
    204204                goto out;
    205205        }
    206        
     206
    207207        /* It looks like we can process the Redirect indication */
    208        
     208
    209209        /* Search for the peers we already know */
    210210        for (li = task.rh.next; li != &task.rh; li = li->next) {
    211211                struct redir_host * h = li->o;
    212212                struct peer_hdr * peer;
    213                
     213
    214214                CHECK_FCT( fd_peer_getbyid( h->id, h->len, 1, &peer ) );
    215215                if (peer) {
     
    221221                }
    222222        }
    223        
     223
    224224        TRACE_DEBUG(FULL, "Redirect module: received %d Redirect-Hosts, %d are known peers, %d have an OPEN connection", nbrh, known, actives);
    225        
     225
    226226        /* in this version, we only redirect when there are known active peers. TODO: add new peers via fd_peer_add when no active peer is available */
    227        
     227
    228228        if (!actives) {
    229229                TRACE_DEBUG(INFO, "Unable to comply to Redirect indication: none of the peers included is in OPEN state");
    230230                goto out;
    231231        }
    232        
     232
    233233        /* From this point, we will re-send the query to a different peer, so stop forwarding the answer here */
    234234        *msg = NULL;
    235        
     235
    236236        /* Get the query's routing data & add the new error */
    237237        CHECK_FCT( fd_msg_answ_getq(m, &q) );
     
    239239        CHECK_FCT( fd_msg_source_get( m, &nh, &nhlen ) );
    240240        CHECK_FCT( fd_rtd_error_add(rtd, nh, nhlen, a_oh->os.data, a_oh->os.len, a_rc->u32, NULL, NULL) );
    241        
     241
    242242        /* Create a redir_rule  */
    243243        CHECK_FCT( redir_entry_new(&entry, &task.rh, task.rhu, q, nh, nhlen, a_oh->os.data, a_oh->os.len) );
    244                
     244
    245245        CHECK_POSIX(  pthread_mutex_lock(&redir_exp_peer_lock)  );
    246246        /* Insert in the split list */
     
    253253        CHECK_FCT( fd_msg_answ_detach(m) );
    254254        CHECK_FCT( fd_msg_free(m) );
    255        
     255
    256256        /* Send it */
    257257        CHECK_FCT( fd_msg_send(&q, NULL, NULL) );
    258        
     258
    259259        /* Done! */
    260        
     260
    261261out:
    262262        while (!FD_IS_LIST_EMPTY(&task.rh)) {
     
    266266                free(h);
    267267        }
    268                
     268
    269269        return 0;
    270270
  • extensions/rt_redirect/redir_out.c

    r1216 r1260  
    11/*********************************************************************************************************
    22* Software License Agreement (BSD License)                                                               *
    3 * Author: Sebastien Decugis <sdecugis@freediameter.net>                                                  *
     3* Authors: Sebastien Decugis <sdecugis@freediameter.net>                                                 *
     4* and Thomas Klausner <tk@giga.or.at>                                                                    *
    45*                                                                                                        *
    5 * Copyright (c) 2013, WIDE Project and NICT                                                              *
     6* Copyright (c) 2013, 2014, WIDE Project and NICT                                                        *
    67* All rights reserved.                                                                                   *
    78*                                                                                                        *
     
    4142{
    4243        TRACE_ENTRY("%d %p %p %p", type, msg, data, nodata);
    43        
     44
    4445        /* Initialize the data area */
    4546        memset(data, 0, sizeof(union matchdata));
    4647        *nodata = 0;
    47        
     48
    4849        /* Now, find the appropriate information, depending on type */
    4950        switch (type) {
     
    5152                        data->message.msg = msg;
    5253                        break;
    53                        
     54
    5455                case ALL_SESSION:
    5556                        {
     
    6566                        }
    6667                        break;
    67                
     68
    6869                case ALL_REALM:
    6970                        {
     
    8283                        }
    8384                        break;
    84                                
     85
    8586                case REALM_AND_APPLICATION:
    8687                        {
     
    9697                                        data->realm_app.s = ahdr->avp_value->os.data;
    9798                                        data->realm_app.l = ahdr->avp_value->os.len;
    98                                        
     99
    99100                                        /* and then the application */
    100101                                        {
     
    107108                        }
    108109                        break;
    109                                
     110
    110111                case ALL_APPLICATION:
    111112                        {
     
    116117                        }
    117118                        break;
    118                        
     119
    119120                case ALL_HOST:
    120121                                /* This is more complex, we need to match with all candidates in each rule, it'll be done later */
    121122                        break;
    122                        
     123
    123124                case ALL_USER:
    124125                        {
     
    137138                        }
    138139                        break;
    139                
     140
    140141                default:
    141142                        ASSERT(0);
     
    153154        struct rtd_candidate * c_oh = NULL;
    154155        int cmp;
    155        
     156
    156157        TRACE_ENTRY("%p %p %p", e, msg, candidates);
    157158        ASSERT( e && msg && candidates );
    158        
     159
    159160        if (FD_IS_LIST_EMPTY(candidates)) {
    160161                TRACE_DEBUG(ANNOYING, "Skip Redirect rule since candidates list is empty");
    161162                return 0;
    162163        }
    163        
     164
    164165        /* Now search common peers between e->target_peers_list and candidates */
    165166        TRACE_DEBUG(ANNOYING, "Message %p matches a Redirect rule (t:%d, @%p), processing candidates list", msg, e->type, e);
    166        
     167
    167168        /* First, decrease the score of the host that we received the previous Redirect from, in case it is in the list */
    168169        for (lic = candidates->next; lic != candidates; lic = lic->next) {
    169170                struct rtd_candidate * cand = (struct rtd_candidate *) lic;
    170                
     171
    171172                /* Special case: ALL_HOST rules: we decrease the score of the Origin-Host if present */
    172173                if (e->type == ALL_HOST) {
     
    179180                        }
    180181                }
    181                
     182
    182183                cmp = fd_os_cmp(cand->diamid, cand->diamidlen, e->from.s, e->from.l);
    183184                if (!cmp) {
     
    185186                        cand->score += FD_SCORE_SENT_REDIRECT;
    186187                }
    187                
    188         }
    189        
     188
     189        }
     190
    190191        if ((e->type == ALL_HOST) && (c_oh == NULL)) {
    191192                /* The rule does not apply, we're done */
    192193                return 0;
    193194        }
    194        
     195
    195196        /* for each candidate, if it is found in the target_peers list, we add the rule's score to this candidate */
    196197        for (lic = candidates->next; lic != candidates; lic = lic->next) {
    197198                /* the candidates list is not guaranteed to be ordered at this time, so we cannot avoid the two imbricated loops */
    198199                struct rtd_candidate * cand = (struct rtd_candidate *) lic;
    199                
     200
    200201                /* Is this candidate in the "Redirect-Host" list ? We must search caseinsentive here. */
    201202                for (lirh = e->target_peers_list.next; lirh != &e->target_peers_list; lirh = lirh->next) {
    202203                        struct redir_host * host = lirh->o;
    203204                        int cont;
    204                        
     205
    205206                        cmp = fd_os_almostcasesrch( cand->diamid, cand->diamidlen, host->id, host->len, &cont );
    206                        
     207
    207208                        if (cmp == 0) {
    208209                                TRACE_DEBUG(FULL, "Redirect msg %p: peer '%.*s' += %d (rule t:%d @%p)", msg, (int)cand->diamidlen, cand->diamid, redirects_usages[e->type].score, e->type, e);
     
    214215                }
    215216        }
    216        
     217
    217218        return 0;
    218219}
    219220
     221static int redir_exist_for_type(int rule_type)
     222{
     223        int ret;
     224
     225        switch(rule_type) {
     226        case ALL_SESSION:
     227        case ALL_USER:
     228                ret = redirect_hash_table[rule_type] != NULL;
     229                break;
     230        default:
     231                ret = !FD_IS_LIST_EMPTY(&redirects_usages[rule_type].sentinel);
     232                break;
     233        }
     234        return ret;
     235}
     236
     237static int match_message(int rule_type, struct msg *msg, union matchdata *data, struct fd_list * candidates)
     238{
     239        struct fd_list * li;
     240        struct redir_entry * e = NULL;
     241        int ret = 0;
     242
     243        switch(rule_type) {
     244        case ALL_SESSION:
     245                HASH_FIND(hh, redirect_hash_table[rule_type], data->session.s, data->session.l, e);
     246                if (e) {
     247                        /* This message matches a rule, apply */
     248                        CHECK_FCT_DO( ret = apply_rule(e, msg, candidates), break );
     249                }
     250                break;
     251        case ALL_USER:
     252                HASH_FIND(hh, redirect_hash_table[rule_type], data->user.s, data->user.l, e);
     253                if (e) {
     254                        /* This message matches a rule, apply */
     255                        CHECK_FCT_DO( ret = apply_rule(e, msg, candidates), break );
     256                }
     257                break;
     258        default:
     259                /* Attempt each rule we have stored */
     260                for (li = redirects_usages[rule_type].sentinel.next; li != &redirects_usages[rule_type].sentinel; li = li->next) {
     261                        e = li->o;
     262
     263                        /* Does it match ? */
     264                        if (rule_type != ALL_HOST) { /* this one is an exception, we handle it separately */
     265                                int cmp = redir_entry_cmp_key[rule_type](data, &e->data);
     266                                if (cmp > 0)
     267                                        continue;
     268                                if (cmp < 0)
     269                                        break;
     270                        }
     271
     272                        /* This rule matches (or we are in ALL_HOST), apply */
     273                        CHECK_FCT_DO( ret = apply_rule(e, msg, candidates), break );
     274
     275                        /* If this was a DONT_CACHE rule, we unlink it, so that it will not be used again */
     276                        if (rule_type == DONT_CACHE) {
     277                                li = li->prev;
     278                                fd_list_unlink( li->next );
     279                                /* We cannot delete here without taking the mutex, which would mean we have first to release the lock...
     280                                   just let expiry garbage collect the rule */
     281                        }
     282                }
     283        }
     284
     285        return ret;
     286}
    220287
    221288/* OUT callback */
     
    224291        int i, ret = 0;
    225292        struct msg * msg = *pmsg;
    226        
     293
    227294        TRACE_ENTRY("%p %p %p", cbdata, msg, candidates);
    228        
     295
    229296        for (i = 0; i <= H_U_MAX; i++) {
    230297                /* Lock the line. We write lock in case of DONT_CACHE so we can directly unlink the entry. read in other cases is sufficient */
     
    234301                        CHECK_POSIX( pthread_rwlock_rdlock( &redirects_usages[i].lock ) );
    235302                }
    236                
    237                 if (!FD_IS_LIST_EMPTY(&redirects_usages[i].sentinel)) {
     303
     304                if (redir_exist_for_type(i)) {
    238305                        union matchdata data;
    239306                        int nodata; /* The message does not allow to apply this rule, skip */
    240                        
     307
    241308                        /* Retrieve the data that may match in the message */
    242309                        CHECK_FCT_DO( ret = get_data_to_match(i, msg, &data, &nodata), goto out );
    243                        
    244                         /* If this message may match some of our rules */
    245                         if (!nodata) {
    246                                 struct fd_list * li;
    247                                 /* Attempt each rule we have stored */
    248                                 for (li = redirects_usages[i].sentinel.next; li != &redirects_usages[i].sentinel; li = li->next) {
    249                                         struct redir_entry * e = li->o;
    250                                        
    251                                         /* Does it match ? */
    252                                         if (i != ALL_HOST) { /* this one is an exception, we handle it separately */
    253                                                 int cmp = redir_entry_cmp_key[i](&data, &e->data);
    254                                                 if (cmp > 0)
    255                                                         continue;
    256                                                 if (cmp < 0)
    257                                                         break;
    258                                         }
    259                                        
    260                                         /* This rule matches (or we are in ALL_HOST), apply */
    261                                         CHECK_FCT_DO( ret = apply_rule(e, msg, candidates), goto out );
    262                                        
    263                                         /* If this was a DONT_CACHE rule, we unlink it, so that it will not be used again */
    264                                         if (i == DONT_CACHE) {
    265                                                 li=li->prev;
    266                                                 fd_list_unlink( li->next );
    267                                                 /* We cannot delete here without taking the mutex, which would mean we have first to release the lock...
    268                                                         just let expiry garbage collet the rule */
    269                                         }
    270                                 }
    271                         }
    272                
    273                 }
    274 out:           
     310
     311                        /* If data found for this type of rule, then try matching it */
     312                        if (!nodata)
     313                                ret = match_message(i, msg, &data, candidates);
     314                }
     315out:
    275316                CHECK_POSIX( pthread_rwlock_unlock( &redirects_usages[i].lock ) );
    276317                if (ret)
    277318                        return ret;
    278319        }
    279        
     320
    280321        return 0;
    281322}
  • extensions/rt_redirect/rt_redir.c

    r740 r1260  
    11/*********************************************************************************************************
    22* Software License Agreement (BSD License)                                                               *
    3 * Author: Sebastien Decugis <sdecugis@freediameter.net>                                                  *
     3* Authors: Sebastien Decugis <sdecugis@freediameter.net>                                                 *
     4* and Thomas Klausner <tk@giga.or.at>                                                                    *
    45*                                                                                                        *
    5 * Copyright (c) 2011, WIDE Project and NICT                                                              *
     6* Copyright (c) 2011, 2014, WIDE Project and NICT                                                        *
    67* All rights reserved.                                                                                   *
    78*                                                                                                        *
     
    4748{
    4849        TRACE_ENTRY("");
    49        
     50
    5051        /* Dictionary objects */
    5152        CHECK_FCT(  fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Destination-Realm", &redir_dict_dr, ENOENT)  );
     
    5455        /* Initialize the entries array */
    5556        CHECK_FCT( redir_entry_init() );
    56        
     57
    5758        /* Start the expire thread */
    5859        CHECK_POSIX( pthread_create( &exp_thr, NULL, redir_exp_thr_fct, NULL ) );
    59        
     60
    6061        /* Register the callback that receives the answers and processes when it contains a Redirect indication. */
    6162        CHECK_FCT( fd_rt_fwd_register ( redir_fwd_cb, NULL, RT_FWD_ANS, &fwd_hdl ) );
     
    7273void fd_ext_fini(void)
    7374{
    74         int i;
    75        
    7675        /* Unregister the callbacks */
    7776        if (fwd_hdl) {
     
    8180                CHECK_FCT_DO( fd_rt_out_unregister(out_hdl, NULL), );
    8281        }
    83        
     82
    8483        /* Stop the expiry thread */
    8584        CHECK_FCT_DO( fd_thr_term(&exp_thr), );
    86        
     85
    8786        /* Empty all entries */
    88         CHECK_POSIX_DO( pthread_mutex_lock(&redir_exp_peer_lock),   );
    89         for (i = 0; i <= H_U_MAX; i++) {
    90                 CHECK_POSIX_DO( pthread_rwlock_wrlock( &redirects_usages[i].lock), );
    91                 while (!FD_IS_LIST_EMPTY(&redirects_usages[i].sentinel)) {
    92                         struct redir_entry * e = redirects_usages[i].sentinel.next->o;
    93                         fd_list_unlink(&e->redir_list);
    94                         CHECK_FCT_DO( redir_entry_destroy(e), );
    95                 }
    96                 CHECK_POSIX_DO( pthread_rwlock_unlock( &redirects_usages[i].lock), );
    97                 CHECK_POSIX_DO( pthread_rwlock_destroy( &redirects_usages[i].lock), );
    98         }
    99         CHECK_POSIX_DO( pthread_mutex_unlock(&redir_exp_peer_lock),   );
    100        
     87        redir_entry_fini();
     88
    10189        return;
    10290}
  • extensions/rt_redirect/rt_redir.h

    r1235 r1260  
    11/*********************************************************************************************************
    22* Software License Agreement (BSD License)                                                               *
    3 * Author: Sebastien Decugis <sdecugis@freediameter.net>                                                  *
    4 *                                                                                                        *
    5 * Copyright (c) 2013, WIDE Project and NICT                                                              *
     3* Author: Sebastien Decugis <sdecugis@freediameter.net> and                                              *
     4* Thomas Klausner <tk@giga.or.at>                                                                        *
     5*                                                                                                        *
     6* Copyright (c) 2013, 2014, WIDE Project and NICT                                                        *
    67* All rights reserved.                                                                                   *
    78*                                                                                                        *
     
    3738#include <freeDiameter/extension.h>
    3839
     40#include "uthash.h"
     41
    3942/* There are 2 locks in this module. The priority is established as follow to avoid deadlocks:
    4043exp_peer mutex > usages rwlock.
    41 (e.g., the rwlock can be taken while holding the mutex, but not the other way) 
     44(e.g., the rwlock can be taken while holding the mutex, but not the other way)
    4245*/
    4346
     
    5962/* Expiration time set for DONT_CACHE tasks, so that the entry is found when the code is called back */
    6063#define DEFAULT_EXPIRE_TIME 10 /* seconds */
    61        
     64
    6265/* Structure to store a parsed Redirect-Host */
    6366struct redir_host {
    64         struct fd_list chain; 
    65        
     67        struct fd_list chain;
     68
    6669        DiamId_t id;    /* malloc'd */
    6770        size_t   len;
    68         /* We don't use the following yet because we don't support dynamic new connections 
     71        /* We don't use the following yet because we don't support dynamic new connections
    6972        int      secure;
    7073        uint16_t port;
     
    117120        } user;
    118121};
    119        
     122
    120123
    121124/* Structure to store a Redirect indication */
    122125struct redir_entry {
    123126        uint32_t eyec; /* must be REDIR_ENTRY_EYEC, used for debug only */
    124        
     127
    125128        struct {
    126129                os0_t s; /* alloc'd, must be freed */
     
    130133        struct fd_list   target_peers_list; /* The list of Redirect-Hosts for this entry */
    131134
    132         struct timespec  timeout;  /* When does this entry expires? */
     135        struct timespec  timeout;  /* When does this entry expire? */
    133136        struct fd_list   exp_list; /* chain in the expire_list list, ordered by expiration date, protected by exp_peer_lock */
    134        
    135         enum redir_h_u type;  /* Type of this entry */
     137
     138        enum redir_h_u type;       /* Type of this entry */
    136139        struct fd_list redir_list; /* link in redirects_usages lists. Lists are ordered by the data value. Protected by rw locks */
    137         union matchdata data;   /* The strings are duplicated & must be freed in this structure */
     140        union matchdata data;      /* The strings are duplicated & must be freed in this structure */
     141        UT_hash_handle hh;         /* magic entry for hash table */
    138142};
    139143
     
    145149};
    146150extern struct redir_line redirects_usages[];
     151/* the hash table where entries are stored for ALL_SESSION and ALL_USER */
     152extern struct redir_entry *redirect_hash_table[];
    147153
    148154/* Accelerator to the line lock */
     
    158164/* Functions on redir_entry */
    159165int redir_entry_init();
     166int redir_entry_fini();
    160167int redir_entry_new(struct redir_entry ** e, struct fd_list * targets, uint32_t rhu, struct msg * qry, DiamId_t nh, size_t nhlen, os0_t oh, size_t ohlen);
    161168extern int (*redir_entry_cmp_key[])(union matchdata * , union matchdata *); /* compare functions */
  • include/freeDiameter/libfdproto.h

    r1248 r1258  
    484484                || (fd_debug_one_file && !strcmp(fd_debug_one_file, file) ))
    485485                return 2; /* Level override */
    486         if (level <= fd_g_debug_lvl)
     486        if ((int)level <= fd_g_debug_lvl)
    487487                return 1; /* Normal level */
    488488        return 0;  /* No trace */
  • libfdproto/dictionary_functions.c

    r1225 r1261  
    201201                                memcpy(&s.sin6.sin6_port, avp_value->os.data + 18, 2);
    202202                        break;
     203                case 8:
     204                        /* E.164 */
     205                        CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "%.*s", avp_value->os.len-2, avp_value->os.data+2), return NULL);
     206                        return *buf;
    203207                default:
    204208                        CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "[unsupported family: 0x%hx]", fam), return NULL);
Note: See TracChangeset for help on using the changeset viewer.