Navigation


Changeset 706:4ffbc9f1e922 in freeDiameter for extensions/app_radgw/rgwx_sip.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
  • extensions/app_radgw/rgwx_sip.c

    r705 r706  
    5858/* This macro converts a RADIUS attribute to a Diameter AVP of type OctetString */
    5959#define CONV2DIAM_STR( _dictobj_ )      \
    60         CHECK_PARAMS( attr->length >= 2 );                                              \
     60        CHECK_PARAMS( attr->length >= sizeof(struct radius_attr_hdr) );                 \
    6161        /* Create the AVP with the specified dictionary model */                        \
    6262        CHECK_FCT( fd_msg_avp_new ( cs->dict._dictobj_, 0, &avp ) );                    \
    63         value.os.len = attr->length - 2;                                                \
    64         value.os.data = (unsigned char *)(attr + 1);                                    \
     63        value.os.len = attr->length - sizeof(struct radius_attr_hdr);                   \
     64        value.os.data = (os0_t)(attr + 1);                                              \
    6565        CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );                               \
    6666        /* Add the AVP in the Diameter message. */                                      \
     
    6868
    6969#define CONV2DIAM_STR_AUTH( _dictobj_ ) \
    70         CHECK_PARAMS( attr->length >= 2 );                                              \
     70        CHECK_PARAMS( attr->length >= sizeof(struct radius_attr_hdr) );                 \
    7171        /* Create the AVP with the specified dictionary model */                        \
    7272        CHECK_FCT( fd_msg_avp_new ( cs->dict._dictobj_, 0, &avp ) );                    \
    73         value.os.len = attr->length - 2;                                                \
    74         value.os.data = (unsigned char *)(attr + 1);                                    \
     73        value.os.len = attr->length - sizeof(struct radius_attr_hdr);                   \
     74        value.os.data = (os0_t)(attr + 1);                                              \
    7575        CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );                               \
    7676        /* Add the AVP in the Diameter message. */                                      \
    77         CHECK_FCT( fd_msg_avp_add ( auth, MSG_BRW_LAST_CHILD, avp) );           \
     77        CHECK_FCT( fd_msg_avp_add ( auth, MSG_BRW_LAST_CHILD, avp) );                   \
    7878               
    7979/* Same thing, for scalar AVPs of 32 bits */
    8080#define CONV2DIAM_32B( _dictobj_ )      \
    81         CHECK_PARAMS( attr->length == 6 );                                              \
     81        CHECK_PARAMS( attr->length == sizeof(struct radius_attr_hdr)+sizeof(uint32_t) );\
    8282        CHECK_FCT( fd_msg_avp_new ( cs->dict._dictobj_, 0, &avp ) );                    \
    8383        {                                                                               \
    8484                uint8_t * v = (uint8_t *)(attr + 1);                                    \
    8585                value.u32  = (v[0] << 24)                                               \
    86                            | (v[1] << 16)                                               \
    87                            | (v[2] <<  8)                                               \
    88                            |  v[3] ;                                                    \
     86                           | (v[1] << 16)                                               \
     87                           | (v[2] <<  8)                                               \
     88                           |  v[3] ;                                                    \
    8989        }                                                                               \
    9090        CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );                               \
    91         CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) );
     91        CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) );               \
    9292                               
    9393                               
     
    145145{
    146146        struct fd_list chain;
    147     char * sid;
     147    os0_t sid;
    148148    size_t sidlen;
    149     char * nonce;
     149    os0_t nonce;
    150150    size_t noncelen;
    151151   
    152152};
    153153
    154 static int nonce_add_element(char * nonce, size_t noncelen,char * sid, size_t sidlen, struct rgwp_config * state)
     154static int nonce_add_element(os0_t nonce, size_t noncelen, os0_t sid, size_t sidlen, struct rgwp_config * state)
    155155{
    156156        CHECK_PARAMS(nonce && state && sid && sidlen && noncelen);
     
    159159        CHECK_MALLOC(newelt=malloc(sizeof(noncechain)));
    160160       
    161         CHECK_MALLOC(newelt->nonce=malloc(noncelen));
    162         memcpy(newelt->nonce,nonce,noncelen);
     161        CHECK_MALLOC(newelt->nonce= os0dup(nonce, noncelen));
    163162        newelt->noncelen=noncelen;
    164163       
    165         CHECK_MALLOC(newelt->sid=malloc(sidlen));
    166         memcpy(newelt->sid,sid,sidlen);
     164        CHECK_MALLOC(newelt->sid=os0dup(sid, sidlen));
    167165        newelt->sidlen=sidlen;
    168166       
     
    198196*/
    199197//Retrieve sid from nonce
    200 static char * nonce_get_sid(char * nonce, size_t noncelen, size_t * sidlen, struct rgwp_config *state)
     198static os0_t nonce_get_sid(os0_t nonce, size_t noncelen, size_t * sidlen, struct rgwp_config *state)
    201199{
    202200        struct fd_list * li;
    203         char *sid=NULL;
     201        os0_t sid=NULL;
    204202       
    205203        CHECK_PARAMS_DO(nonce && state && noncelen && sidlen, return NULL);
    206204        *sidlen=0;
    207205       
    208         //**Start mutex
     206        // **Start mutex
    209207        CHECK_POSIX_DO(pthread_mutex_lock(&state->nonce_mutex),);
    210208        for(li=state->listnonce.next;li!=&state->listnonce;li=li->next)
     
    212210                noncechain *temp=(noncechain *)li;
    213211               
    214                 if(temp->noncelen==noncelen && strncmp(temp->nonce,nonce, noncelen)==0)
     212                if (!fd_os_cmp(temp->nonce, temp->noncelen, nonce, noncelen))
    215213                {
    216214                        fd_list_unlink (li);
     
    224222        }
    225223        CHECK_POSIX_DO(pthread_mutex_unlock(&state->nonce_mutex),);
    226         //***Stop mutex
     224        // ***Stop mutex
    227225        return sid;
    228226}
     
    230228static void nonce_deletelistnonce(struct rgwp_config *state)
    231229{
    232         //**Start mutex
     230        // **Start mutex
    233231        CHECK_POSIX_DO(pthread_mutex_lock(&state->nonce_mutex),);
    234232        while(!(FD_IS_LIST_EMPTY(&state->listnonce)) )
     
    243241        }
    244242        CHECK_POSIX_DO(pthread_mutex_unlock(&state->nonce_mutex),);
    245         //***Stop mutex
     243        // ***Stop mutex
    246244}
    247245
     
    338336        int got_Dresponse = 0;
    339337        int got_Dalgorithm = 0;
    340         char * sid = NULL;
    341         char * un=NULL;
     338        os0_t sid = NULL;
     339        size_t sidlen;
     340        os0_t un=NULL;
    342341        size_t  un_len;
    343342        size_t nattr_used = 0;
     
    352351        if(*session)
    353352        {
    354                 TRACE_DEBUG(INFO,"We are not supposed to receive a session in radSIP plugin.");
     353                TRACE_DEBUG(INFO,"INTERNAL ERROR: We are not supposed to receive a session in radSIP plugin.");
    355354                return EINVAL;
    356355        }
     
    371370                                {
    372371                                        TRACE_DEBUG(ANNOYING, "Found a User-Name attribute: '%.*s'", attr->length- sizeof(struct radius_attr_hdr), (char *)(attr+1));
    373                                         un = (char *)(attr + 1);
     372                                        un = (os0_t)(attr + 1);
    374373                                        un_len =attr->length - sizeof(struct radius_attr_hdr);
    375374                                }
     
    396395                                got_Dnonce = 1;
    397396                               
    398                                 size_t sidlen;
    399                                
    400                                 sid=nonce_get_sid((char *)(attr+1),attr->length-2,&sidlen,cs);
     397                                sid=nonce_get_sid((os0_t)(attr+1), attr->length - sizeof(struct radius_attr_hdr), &sidlen, cs);
    401398                                if(!sid)
    402399                                {
     
    406403                                CHECK_FCT(fd_sess_fromsid (sid, sidlen, session, NULL));
    407404                                free(sid);
    408                                                                
     405                                                       
    409406                               
    410407                        break;
     
    432429        if (!*session) {
    433430               
    434                 char * fqdn;
    435                 char * realm;
     431                DiamId_t fqdn;
     432                size_t fqdn_len;
     433                DiamId_t realm;
     434                size_t realm_len;
    436435               
    437436               
     
    439438               
    440439                /* Get information on the RADIUS client */
    441                 CHECK_FCT( rgw_clients_get_origin(cli, &fqdn, &realm) );
    442                
    443                 int len;
     440                CHECK_FCT( rgw_clients_get_origin(cli, &fqdn, &fqdn_len, &realm, &realm_len) );
     441               
    444442                /* Create a new Session-Id. The format is: {fqdn;hi32;lo32;username;diamid} */
    445443                CHECK_MALLOC( sid = malloc(un_len + 1 /* ';' */ + fd_g_config->cnf_diamid_len + 1 /* '\0' */) );
    446                 len = sprintf(sid, "%.*s;%s", (int)un_len, un, fd_g_config->cnf_diamid);
    447                 CHECK_FCT( fd_sess_new(session, fqdn, sid, len) );
     444                sidlen = sprintf((char *)sid, "%.*s;%s", (int)un_len, un, fd_g_config->cnf_diamid);
     445                CHECK_FCT( fd_sess_new(session, fqdn, fqdn_len, sid, sidlen) );
    448446                free(sid);
    449447        }
     
    453451       
    454452        int i = 0;
    455         if (un) {
    456                 /* Is there an '@' in the user name? We don't care for decorated NAI here */
    457                 for (i = un_len - 2; i > 0; i--) {
    458                         if (un[i] == '@') {
    459                                 i++;
    460                                 break;
    461                         }
     453       
     454        /* Is there an '@' in the user name? We don't care for decorated NAI here */
     455        for (i = un_len - 2; i > 0; i--) {
     456                if (un[i] == '@') {
     457                        i++;
     458                        break;
    462459                }
    463460        }
     461
    464462        if (i == 0) {
    465463                /* Not found in the User-Name => we use the local domain of this gateway */
    466                 value.os.data = (unsigned char *)fd_g_config->cnf_diamrlm;
     464                value.os.data = (os0_t)fd_g_config->cnf_diamrlm;
    467465                value.os.len  = fd_g_config->cnf_diamrlm_len;
    468466        } else {
    469                 value.os.data = (unsigned char *)(un + i);
     467                value.os.data = un + i;
    470468                value.os.len  = un_len - i;
    471469        }
     
    475473       
    476474        /* Now, add the Session-Id AVP at beginning of Diameter message */
    477         CHECK_FCT( fd_sess_getsid(*session, &sid) );
     475        CHECK_FCT( fd_sess_getsid(*session, &sid, &sidlen) );
    478476       
    479477        TRACE_DEBUG(FULL, "[sip.rgwx] Translating new message for session '%s'...", sid);
     
    481479        /* Add the Session-Id AVP as first AVP */
    482480        CHECK_FCT( fd_msg_avp_new ( cs->dict.Session_Id, 0, &avp ) );
    483         value.os.data = (unsigned char *)sid;
    484         value.os.len = strlen(sid);
     481        value.os.data = sid;
     482        value.os.len = sidlen;
    485483        CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
    486484        CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_FIRST_CHILD, avp) );
     
    552550                CHECK_FCT( fd_msg_avp_add ( auth_data, MSG_BRW_LAST_CHILD, auth) );
    553551        }
    554         char * temp=NULL,*sipuri=NULL;
    555552
    556553        for (idx = 0; idx < rad_req->attr_used; idx++)
     
    597594                        {
    598595                                //We extract Realm from Digest_URI
    599                                 char *realm=NULL;
    600                        
    601                                 CHECK_MALLOC(temp=malloc(attr->length -1));
    602                                 strncpy(temp, (char *)(attr + 1), attr->length -2);
    603                                 temp[attr->length-2] = '\0';
    604                        
    605                                 realm = strtok( (char *)(temp), "@" );
    606                                 realm = strtok( NULL, "@" );
    607                                 free(temp);
    608                                 temp=NULL;
     596                                DiamId_t realm=NULL;
     597                                size_t realm_len;
     598                                os0_t temp;
     599                               
     600                                temp = (os0_t)(attr + 1);
     601                               
     602                                for (i=attr->length - sizeof(struct radius_attr_hdr) - 1; i>=0; i--) {
     603                                        if (temp[i] == '@') {
     604                                                realm = (DiamId_t)temp + i + 1;
     605                                                CHECK_FCT_DO( fd_os_validate_DiameterIdentity(&realm, &realm_len, 1),
     606                                                        realm = NULL );
     607                                                break;
     608                                        }
     609                                }
     610                       
    609611                                if(realm!=NULL)
    610612                                {
    611613                                        CHECK_FCT( fd_msg_avp_new ( cs->dict.Digest_Realm, 0, &avp ) );
    612                                         value.os.data=(unsigned char *)realm;
    613                                         value.os.len=strlen(realm);
     614                                        value.os.data=(os0_t)realm;
     615                                        value.os.len=realm_len;
    614616                                        CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
    615617                                        CHECK_FCT( fd_msg_avp_add ( auth, MSG_BRW_LAST_CHILD, avp) );
     
    617619                                        //We add SIP-Server-URI AVP because SIP server is registrar (through gateway)
    618620                                        CHECK_FCT( fd_msg_avp_new ( cs->dict.SIP_Server_URI, 0, &avp ) );
    619                                         value.os.data=(unsigned char *)realm;
    620                                         value.os.len=strlen(realm);
     621                                        value.os.data=(os0_t)realm;
     622                                        value.os.len=realm_len;
    621623                                        CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
    622624                                        CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) );
    623625                                       
     626                                        free(realm);
    624627                                }
    625628                                else
     
    641644                        //We add SIP-Server-URI AVP because SIP server is registrar (through gateway)
    642645                        CHECK_FCT( fd_msg_avp_new ( cs->dict.SIP_Server_URI, 0, &avp ) );
    643                        
    644                        
    645                         CHECK_MALLOC(temp=malloc(attr->length -1));
    646                         strncpy(temp, (char *)(attr + 1), attr->length -2);
    647                        
    648                        
    649                         CHECK_MALLOC(sipuri=malloc(attr->length +3));
    650                         strcpy(sipuri,"sip:");
    651                         strcat(sipuri,(const char *)temp);
    652                         value.os.data=(unsigned char *)sipuri;
    653                         value.os.len=attr->length +2;
     646                        os0_t temp;
     647                        #define SIP_PREFIX      "sip:"
     648                        size_t temp_len = attr->length - sizeof(struct radius_attr_hdr) + CONSTSTRLEN(SIP_PREFIX) + 1;
     649                        CHECK_MALLOC( temp = malloc(temp_len) );
     650                        temp_len = snprintf((char *)temp, temp_len, SIP_PREFIX "%.*s", attr->length - sizeof(struct radius_attr_hdr), (char *)(attr + 1));
     651                       
     652                        value.os.data=temp;
     653                        value.os.len=temp_len;
    654654                       
    655655                        free(temp);
    656                         temp=NULL;
     656                       
    657657                        CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
    658658                        CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) );
     
    689689                        {
    690690                                //[Note 3] If Digest-Algorithm is missing, 'MD5' is assumed.
     691                                #define DIGEST_ALGO_MD5 "MD5"
    691692                                                                               
    692693                                CHECK_FCT( fd_msg_avp_new ( cs->dict.Digest_Algorithm, 0, &avp ) );                     
    693694                                                                               
    694                                 value.os.data = (unsigned char *)"MD5";
    695                                 value.os.len = strlen((const char *)value.os.data);
     695                                value.os.data = (os0_t)DIGEST_ALGO_MD5;
     696                                value.os.len = CONSTSTRLEN(DIGEST_ALGO_MD5) - 1;
    696697                                CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );                                       
    697698                                CHECK_FCT( fd_msg_avp_add ( auth, MSG_BRW_LAST_CHILD, avp) );   
     
    831832                                        /* Retrieve the request identified which was stored in the session */
    832833                                        if (session) {
    833                                                 char *sid=NULL;
     834                                                os0_t sid=NULL;
    834835                                                size_t sidlen;
    835                                                 fd_sess_getsid (session, &sid );
    836                                                 sidlen=strlen(sid);
     836                                                fd_sess_getsid (session, &sid, &sidlen );
    837837                                               
    838                                                 nonce_add_element((char *)ahdr->avp_value->os.data,ahdr->avp_value->os.len, sid,sidlen, cs);
     838                                                nonce_add_element(ahdr->avp_value->os.data, ahdr->avp_value->os.len, sid, sidlen, cs);
    839839                                        }
    840840                                        break;
Note: See TracChangeset for help on using the changeset viewer.