Navigation


Changeset 706:4ffbc9f1e922 in freeDiameter for libfdproto/rt_data.c


Ignore:
Timestamp:
Feb 9, 2011, 3:26:58 PM (13 years ago)
Author:
Sebastien Decugis <sdecugis@nict.go.jp>
Branch:
default
Phase:
public
Message:

Large UNTESTED commit with the following changes:

  • Improved DiameterIdentity? handling (esp. interationalization issues), and improve efficiency of some string operations in peers, sessions, and dictionary modules (closes #7)
  • Cleanup in the session module to free only unreferenced sessions (#16)
  • Removed fd_cpu_flush_cache(), replaced by more robust alternatives.
  • Improved peer state machine algorithm to counter SCTP multistream race condition.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libfdproto/rt_data.c

    r662 r706  
    5050/* Items of the errors list */
    5151struct rtd_error {
    52         struct fd_list  chain;  /* link in the list, ordered by nexthop */
    53         char *          nexthop;/* the peer the message was sent to */
    54         char *          erh;    /* the origin of the error */
     52        struct fd_list  chain;  /* link in the list, ordered by nexthop (fd_os_cmp) */
     53        DiamId_t        nexthop;/* the peer the message was sent to */
     54        size_t          nexthoplen; /* cached string length */
     55        DiamId_t        erh;    /* the origin of the error */
     56        size_t          erhlen; /* cached string length */
    5557        uint32_t        code;   /* the error code */
    5658};
     
    107109}
    108110
    109 /* Add a peer to the candidates list */
    110 int  fd_rtd_candidate_add(struct rt_data * rtd, char * peerid, char * realm)
     111/* Add a peer to the candidates list. The source is our local peer list, so no need to care for the case here. */
     112int  fd_rtd_candidate_add(struct rt_data * rtd, DiamId_t peerid, size_t peeridlen, DiamId_t realm, size_t realmlen)
    111113{
    112114        struct fd_list * prev;
    113115        struct rtd_candidate * new;
    114116       
    115         TRACE_ENTRY("%p %p", rtd, peerid);
    116         CHECK_PARAMS(rtd && peerid);
     117        TRACE_ENTRY("%p %p %zd %p %zd", rtd, peerid, peeridlen, realm, realmlen);
     118        CHECK_PARAMS(rtd && peerid && peeridlen);
    117119       
    118120        /* Since the peers are ordered when they are added (fd_g_activ_peers) we search for the position from the end -- this should be efficient */
    119121        for (prev = rtd->candidates.prev; prev != &rtd->candidates; prev = prev->prev) {
    120122                struct rtd_candidate * cp = (struct rtd_candidate *) prev;
    121                 int cmp = strcmp(peerid, cp->diamid);
     123                int cmp = fd_os_cmp(peerid, peeridlen, cp->diamid, cp->diamidlen);
    122124                if (cmp > 0)
    123125                        break;
     
    127129        }
    128130       
     131        /* Create the new entry */
    129132        CHECK_MALLOC( new = malloc(sizeof(struct rtd_candidate)) );
    130133        memset(new, 0, sizeof(struct rtd_candidate) );
    131134        fd_list_init(&new->chain, NULL);
    132         CHECK_MALLOC( new->diamid = strdup(peerid) );
    133         CHECK_MALLOC( new->realm = strdup(realm) );
    134        
     135        CHECK_MALLOC( new->diamid = os0dup(peerid, peeridlen) )
     136        new->diamidlen = peeridlen;
     137        if (realm) {
     138                CHECK_MALLOC( new->realm = os0dup(realm, realmlen) )
     139                new->realmlen = realmlen;
     140        }
     141       
     142        /* insert in the list at the correct position */
    135143        fd_list_insert_after(prev, &new->chain);
    136144       
     
    138146}
    139147
    140 /* Remove a peer from the candidates (if it is found) */
    141 void fd_rtd_candidate_del(struct rt_data * rtd, char * peerid, size_t sz /* if !0, peerid does not need to be \0 terminated */)
     148/* Remove a peer from the candidates (if it is found). Case insensitive search since the names are received from other peers */
     149void fd_rtd_candidate_del(struct rt_data * rtd, uint8_t * id, size_t idsz)
    142150{
    143151        struct fd_list * li;
    144152       
    145         TRACE_ENTRY("%p %p %zd", rtd, peerid, sz);
    146         CHECK_PARAMS_DO( rtd && peerid , return );
     153        TRACE_ENTRY("%p %p %zd", rtd, id, idsz);
     154        CHECK_PARAMS_DO( rtd && id && idsz, return );
     155       
     156        if (!fd_os_is_valid_DiameterIdentity(id, idsz))
     157                /* it cannot be in the list */
     158                return;
    147159       
    148160        for (li = rtd->candidates.next; li != &rtd->candidates; li = li->next) {
    149161                struct rtd_candidate * c = (struct rtd_candidate *) li;
    150                 int cmp;
    151                 if (sz) {
    152                         cmp = strncmp(peerid, c->diamid, sz);
    153                         if (!cmp) {
    154                                 int len = strlen(c->diamid);
    155                                 if (sz < len)
    156                                         cmp = -1;
    157                                 else if (sz == len)
    158                                         cmp = 0;
    159                                 else cmp = 1;
    160                         }
    161                 } else {
    162                         cmp = strcmp(peerid, c->diamid);
    163                 }
     162               
     163                int cmp = fd_os_almostcasecmp(id, idsz, c->diamid, c->diamidlen);
    164164               
    165165                if (!cmp) {
     
    175175                        continue;
    176176               
    177                 /* The list is ordered only if not extracted */
     177                /* The list is guaranteed to be ordered only if not extracted */
    178178                if (! rtd->extracted)
    179179                        break;
     
    183183}
    184184
    185 /* If a peer returned a protocol error for this message, save it so that we don't try to send it there again */
    186 int  fd_rtd_error_add(struct rt_data * rtd, char * sentto, uint8_t * origin, size_t originsz, uint32_t rcode)
     185/* If a peer returned a protocol error for this message, save it so that we don't try to send it there again.
     186 Case insensitive search since the names are received from other peers*/
     187int  fd_rtd_error_add(struct rt_data * rtd, DiamId_t sentto, size_t senttolen, uint8_t * origin, size_t originsz, uint32_t rcode)
    187188{
    188189        struct fd_list * li;
    189190        int match = 0;
    190191       
    191         TRACE_ENTRY("%p %p %p %d", rtd, sentto, origin, rcode);
    192         CHECK_PARAMS( rtd && sentto ); /* origin may be NULL */
     192        TRACE_ENTRY("%p %p %zd %p %zd %u", rtd, sentto, senttolen, origin, originsz, rcode);
     193        CHECK_PARAMS( rtd && sentto && senttolen ); /* origin may be NULL */
    193194       
    194195        /* First add the new error entry */
    195196        for (li = rtd->errors.next; li != &rtd->errors; li = li->next) {
    196197                struct rtd_error * e = (struct rtd_error *) li;
    197                 int cmp = strcmp(sentto, e->nexthop);
     198                int cmp = fd_os_cmp(sentto, senttolen, e->nexthop, e->nexthoplen);
    198199                if (cmp > 0)
    199200                        continue;
     
    203204        }
    204205       
    205         /* If we already had this entry, we should not have sent the message again to this peer... anyway... */
     206        /* If we already had this entry, we should not have sent the message again to this peer... anyway, let's close our eyes. */
     207        /* in the normal case, we save the error */
    206208        if (!match) {
    207209                /* Add a new entry in the error list */
     
    210212                memset(new, 0, sizeof(struct rtd_error));
    211213                fd_list_init(&new->chain, NULL);
    212                 CHECK_MALLOC(new->nexthop = strdup(sentto));
     214
     215                CHECK_MALLOC(new->nexthop = os0dup(sentto, senttolen));
     216                new->nexthoplen = senttolen;
     217               
    213218                if (origin) {
    214                         CHECK_MALLOC( new->erh = malloc(originsz + 1) );
    215                         memcpy(new->erh, origin, originsz);
    216                         new->erh[originsz] = '\0';
     219                        if (!originsz) {
     220                                originsz=strlen((char *)origin);
     221                        } else {
     222                                if (!fd_os_is_valid_DiameterIdentity(origin, originsz)){
     223                                        TRACE_DEBUG(FULL, "Received error %d from peer with invalid Origin-Host AVP, not saved", rcode);
     224                                        origin = NULL;
     225                                        goto after_origin;
     226                                }
     227                        }
     228                        CHECK_MALLOC( new->erh = (DiamId_t)os0dup(origin, originsz) );
     229                        new->erhlen = originsz;
    217230                }
     231after_origin:
    218232                new->code = rcode;
    219233                fd_list_insert_before(li, &new->chain);
     
    221235       
    222236        /* Finally, remove this (these) peers from the candidate list */
    223         fd_rtd_candidate_del(rtd, sentto, 0);
     237        fd_rtd_candidate_del(rtd, (os0_t)sentto, senttolen);
    224238        if (origin)
    225                 fd_rtd_candidate_del(rtd, (char *)origin, originsz);
     239                fd_rtd_candidate_del(rtd, origin, originsz);
    226240       
    227241        /* Done! */
     
    274288                        fd_list_move_end(candidates, &highest);
    275289                       
    276                         /* And the new high score is this reset */
     290                        /* And the new high score is set */
    277291                        hs = c->score;
    278292                }
Note: See TracChangeset for help on using the changeset viewer.