Changeset 1126 for pjproject/trunk


Ignore:
Timestamp:
Apr 2, 2007 11:30:14 AM (18 years ago)
Author:
bennylp
Message:

ICE: work in progress

Location:
pjproject/trunk
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/src/pjmedia/transport_ice.c

    r1114 r1126  
    8989 
    9090 
    91  
     91/* 
     92 * Create ICE media transport. 
     93 */ 
    9294PJ_DEF(pj_status_t) pjmedia_ice_create(pjmedia_endpt *endpt, 
    9395                                       const char *name, 
     
    132134 
    133135 
     136/* 
     137 * Destroy ICE media transport. 
     138 */ 
    134139PJ_DEF(pj_status_t) pjmedia_ice_destroy(pjmedia_transport *tp) 
    135140{ 
     
    138143    if (tp_ice->ice_st) { 
    139144        pj_ice_strans_destroy(tp_ice->ice_st); 
    140         //Must not touch tp_ice after ice_st is destroyed! 
    141         //(it has the pool) 
    142         //tp_ice->ice_st = NULL; 
     145        /*Must not touch tp_ice after ice_st is destroyed! 
     146         (it has the pool) 
     147         tp_ice->ice_st = NULL; 
     148         */ 
    143149    } 
    144150 
     
    147153 
    148154 
     155/* 
     156 * Start media transport initialization. 
     157 */ 
    149158PJ_DEF(pj_status_t) pjmedia_ice_start_init( pjmedia_transport *tp, 
    150159                                            unsigned options, 
     
    186195 
    187196 
     197/* 
     198 * Get the status of media transport initialization. 
     199 */ 
    188200PJ_DEF(pj_status_t) pjmedia_ice_get_init_status(pjmedia_transport *tp) 
    189201{ 
     
    193205 
    194206 
     207/* 
     208 * Get the component for the specified component ID. 
     209 */ 
    195210PJ_DEF(pj_status_t) pjmedia_ice_get_comp( pjmedia_transport *tp, 
    196211                                          unsigned comp_id, 
     
    205220} 
    206221 
    207 PJ_DEF(pj_ice_strans*) pjmedia_ice_get_ice_st(pjmedia_transport *tp) 
    208 { 
    209     struct transport_ice *tp_ice = (struct transport_ice*)tp; 
    210     return tp_ice->ice_st; 
    211 } 
    212  
    213  
     222 
     223/* 
     224 * Create ICE! This happens when: 
     225 *  - UAC is ready to send offer 
     226 *  - UAS have just received an offer. 
     227 */ 
    214228PJ_DEF(pj_status_t) pjmedia_ice_init_ice(pjmedia_transport *tp, 
    215229                                         pj_ice_sess_role role, 
     
    222236 
    223237 
     238/* 
     239 * For both UAC and UAS, pass in the SDP before sending it to remote. 
     240 * This will add ICE attributes to the SDP. 
     241 */ 
    224242PJ_DEF(pj_status_t) pjmedia_ice_modify_sdp(pjmedia_transport *tp, 
    225243                                           pj_pool_t *pool, 
     
    306324 
    307325 
     326/* Parse a=candidate line */ 
    308327static pj_status_t parse_cand(pj_pool_t *pool, 
    309328                              const pj_str_t *orig_input, 
     
    391410} 
    392411 
    393 static void set_no_ice(struct transport_ice *tp_ice) 
     412 
     413/* Disable ICE when SDP from remote doesn't contain a=candidate line */ 
     414static void set_no_ice(struct transport_ice *tp_ice, const char *reason) 
    394415{ 
    395416    PJ_LOG(4,(tp_ice->ice_st->obj_name,  
    396               "Remote does not support ICE, disabling local ICE")); 
     417              "Disabling local ICE, reason=%s", reason)); 
    397418    pjmedia_ice_stop_ice(&tp_ice->base); 
    398419} 
    399420 
    400421 
     422/* 
     423 * Start ICE checks when both offer and answer are available. 
     424 */ 
    401425PJ_DEF(pj_status_t) pjmedia_ice_start_ice(pjmedia_transport *tp, 
    402426                                          pj_pool_t *pool, 
     
    410434    const pjmedia_sdp_media *sdp_med; 
    411435    pj_bool_t remote_is_lite = PJ_FALSE; 
     436    pj_bool_t ice_mismatch = PJ_FALSE; 
    412437    const pj_str_t STR_CANDIDATE = {"candidate", 9}; 
    413438    const pj_str_t STR_ICE_LITE = {"ice-lite", 8}; 
     439    const pj_str_t STR_ICE_MISMATCH = {"ice-mismatch", 12}; 
    414440    pj_str_t uname, pass; 
    415441    pj_status_t status; 
     
    428454                                      "ice-ufrag", NULL); 
    429455        if (attr == NULL) { 
    430             set_no_ice(tp_ice); 
     456            set_no_ice(tp_ice, "ice-ufrag attribute not found"); 
    431457            return PJ_SUCCESS; 
    432458        } 
     
    442468                                      "ice-pwd", NULL); 
    443469        if (attr == NULL) { 
    444             set_no_ice(tp_ice); 
     470            set_no_ice(tp_ice, "ice-pwd attribute not found"); 
    445471            return PJ_SUCCESS; 
    446472        } 
     
    455481        attr = sdp_med->attr[i]; 
    456482 
    457         if (pj_strcmp(&attr->name, &STR_ICE_LITE)==0) 
     483        if (pj_strcmp(&attr->name, &STR_ICE_LITE)==0) { 
    458484            remote_is_lite = PJ_TRUE; 
     485            continue; 
     486        } 
     487 
     488        if (pj_strcmp(&attr->name, &STR_ICE_MISMATCH)==0) { 
     489            ice_mismatch = PJ_TRUE; 
     490            continue; 
     491        } 
    459492 
    460493        if (pj_strcmp(&attr->name, &STR_CANDIDATE)!=0) 
     
    466499 
    467500        cand_cnt++; 
     501    } 
     502 
     503    /* Handle ice-mismatch case */ 
     504    if (ice_mismatch) { 
     505        set_no_ice(tp_ice, "ice-mismatch detected"); 
     506        return PJ_SUCCESS; 
    468507    } 
    469508 
  • pjproject/trunk/pjnath/include/pjnath/config.h

    r1110 r1126  
    3131 * @{ 
    3232 */ 
     33 
     34 
     35/* ************************************************************************** 
     36 * GENERAL 
     37 */ 
     38 
     39/** 
     40 * The log level for PJNATH error display. 
     41 * 
     42 * default 1 
     43 */ 
     44#ifndef PJNATH_ERROR_LEVEL 
     45#   define PJNATH_ERROR_LEVEL                       1 
     46#endif 
     47 
    3348 
    3449/* ************************************************************************** 
  • pjproject/trunk/pjnath/include/pjnath/ice_session.h

    r1114 r1126  
    9797} pj_ice_cand_type; 
    9898 
    99  
    100 /** 
    101  * This enumeration describes the default preference for the ICE 
    102  * candidate types as described by ICE standard. 
    103  */ 
    104 enum pj_ice_type_pref 
    105 { 
    106     PJ_ICE_HOST_PREF        = 126,  /**< Preference value for host.     */ 
    107     PJ_ICE_SRFLX_PREF       = 100,  /**< Preference value for SRFLX.    */ 
    108     PJ_ICE_PRFLX_PREF       = 110,  /**< Preference value for PRFLX     */ 
    109     PJ_ICE_RELAYED_PREF     = 0     /**< Preference value for relay     */ 
    110 }; 
    11199 
    112100/** Forward declaration for pj_ice_sess */ 
     
    274262     * Check priority. 
    275263     */ 
    276     pj_uint64_t          prio; 
     264    pj_timestamp         prio; 
    277265 
    278266    /** 
     
    446434    pj_ice_sess_role     role;                      /**< ICE role.          */ 
    447435    pj_timestamp         tie_breaker;               /**< Tie breaker value  */ 
     436    pj_uint8_t          *prefs;                     /**< Type preference.   */ 
    448437    pj_bool_t            is_complete;               /**< Complete?          */ 
    449438    pj_status_t          ice_status;                /**< Error status.      */ 
     
    567556 
    568557/** 
     558 * Assign a custom preference values for ICE candidate types. By assigning 
     559 * custom preference value, application can control the order of candidates 
     560 * to be checked first. The default preference settings is to use 126 for  
     561 * host candidates, 100 for server reflexive candidates, 110 for peer  
     562 * reflexive candidates, an 0 for relayed candidates. 
     563 * 
     564 * Note that this function must be called before any candidates are added 
     565 * to the ICE session. 
     566 * 
     567 * @param ice           The ICE session. 
     568 * @param prefs         Array of candidate preference value. The values are 
     569 *                      put in the array indexed by the candidate type as 
     570 *                      specified in pj_ice_cand_type. 
     571 * 
     572 * @return              PJ_SUCCESS on success, or the appropriate error code. 
     573 */ 
     574PJ_DECL(pj_status_t) pj_ice_sess_set_prefs(pj_ice_sess *ice, 
     575                                           const pj_uint8_t prefs[4]); 
     576 
     577 
     578 
     579/** 
    569580 * Add a candidate to this ICE session. Application must add candidates for 
    570581 * each components ID before it can start pairing the candidates and  
     
    596607                                          unsigned *p_cand_id); 
    597608 
     609#if 0 
     610/* Temporarily disabled to reduce size, since we don't need this yet */ 
     611 
    598612/** 
    599613 * Find default candidate for the specified component ID, using this 
     
    613627                                                   unsigned comp_id, 
    614628                                                   int *p_cand_id); 
     629#endif 
    615630 
    616631/** 
  • pjproject/trunk/pjnath/include/pjnath/stun_auth.h

    r1110 r1126  
    226226             * PJ_FALSE, 438 (Stale Nonce) response will be created. 
    227227             * 
     228             * This callback is optional. 
     229             * 
    228230             * @param msg       The STUN message where the nonce was received. 
    229231             * @param user_data The user data as specified in the credential. 
  • pjproject/trunk/pjnath/include/pjnath/stun_msg.h

    r1114 r1126  
    12291229 * @return              The message string output. 
    12301230 */ 
     1231#if PJ_LOG_MAX_LEVEL > 0 
    12311232PJ_DECL(char*) pj_stun_msg_dump(const pj_stun_msg *msg, 
    12321233                                char *buffer, 
    12331234                                unsigned length, 
    12341235                                unsigned *printed_len); 
     1236#else 
     1237#   define pj_stun_msg_dump(msg, buf, length, printed_len)  "" 
     1238#endif 
    12351239 
    12361240 
  • pjproject/trunk/pjnath/include/pjnath/types.h

    r1114 r1126  
    3838 * Initialize pjnath library. 
    3939 * 
    40  * @return  Initialization status. 
     40 * @return          Initialization status. 
    4141 */ 
    4242PJ_DECL(pj_status_t) pjnath_init(void); 
     43 
     44 
     45/** 
     46 * Display error to the log. 
     47 * 
     48 * @param sender    The sender name. 
     49 * @param title     Title message. 
     50 * @param status    The error status. 
     51 */ 
     52#if PJNATH_ERROR_LEVEL <= PJ_LOG_MAX_LEVEL 
     53PJ_DECL(void) pjnath_perror(const char *sender, const char *title, 
     54                            pj_status_t status); 
     55#else 
     56# define pjnath_perror(sender, title, status) 
     57#endif 
     58 
    4359 
    4460 
     
    148164 * the usage of ICE in SIP/SDP offer/answer. 
    149165 *  
     166 * 
    150167 * \subsection PJNATH_ICE_ARCH ICE Library Organization 
    151168 *  
  • pjproject/trunk/pjnath/src/pjnath/errno.c

    r1101 r1126  
    1919#include <pjnath/errno.h> 
    2020#include <pjnath/stun_msg.h> 
     21#include <pj/log.h> 
    2122#include <pj/string.h> 
    2223 
     
    166167} 
    167168 
     169 
     170#if PJNATH_ERROR_LEVEL <= PJ_LOG_MAX_LEVEL 
     171 
     172PJ_DEF(void) pjnath_perror(const char *sender, const char *title, 
     173                           pj_status_t status) 
     174{ 
     175    char errmsg[PJ_ERR_MSG_SIZE]; 
     176 
     177    pj_strerror(status, errmsg, sizeof(errmsg)); 
     178 
     179#if PJNATH_ERROR_LEVEL==1 
     180    PJ_LOG(1,(sender, "%s: %s", title, errmsg)); 
     181#elif PJNATH_ERROR_LEVEL==2 
     182    PJ_LOG(2,(sender, "%s: %s", title, errmsg)); 
     183#elif PJNATH_ERROR_LEVEL==3 
     184    PJ_LOG(3,(sender, "%s: %s", title, errmsg)); 
     185#elif PJNATH_ERROR_LEVEL==4 
     186    PJ_LOG(4,(sender, "%s: %s", title, errmsg)); 
     187#elif PJNATH_ERROR_LEVEL==5 
     188    PJ_LOG(5,(sender, "%s: %s", title, errmsg)); 
     189#else 
     190# error Invalid PJNATH_ERROR_LEVEL value 
     191#endif 
     192} 
     193 
     194#endif  /* PJNATH_ERROR_LEVEL <= PJ_LOG_MAX_LEVEL */ 
     195 
  • pjproject/trunk/pjnath/src/pjnath/ice_session.c

    r1114 r1126  
    4141 
    4242/* String names for pj_ice_sess_check_state */ 
     43#if PJ_LOG_MAX_LEVEL >= 4 
    4344static const char *check_state_name[] =  
    4445{ 
     
    5657    "Completed" 
    5758}; 
     59#endif  /* PJ_LOG_MAX_LEVEL >= 4 */ 
    5860 
    5961static const char *role_names[] =  
     
    6163    "Controlled", 
    6264    "Controlling" 
     65}; 
     66 
     67/* Default ICE session preferences, according to draft-ice */ 
     68static pj_uint8_t cand_type_prefs[4] = 
     69{ 
     70    126,    /**< PJ_ICE_HOST_PREF       */ 
     71    100,    /**< PJ_ICE_SRFLX_PREF.     */ 
     72    110,    /**< PJ_ICE_PRFLX_PREF      */ 
     73    0       /**< PJ_ICE_RELAYED_PREF    */ 
    6374}; 
    6475 
     
    7283typedef struct stun_data 
    7384{ 
    74     pj_ice_sess *ice; 
    75     unsigned     lcand_id; 
     85    pj_ice_sess         *ice; 
    7686    pj_ice_sess_cand    *lcand; 
    7787} stun_data; 
     
    7989typedef struct timer_data 
    8090{ 
    81     pj_ice_sess         *ice; 
    82     pj_ice_sess_checklist       *clist; 
     91    pj_ice_sess             *ice; 
     92    pj_ice_sess_checklist   *clist; 
    8393} timer_data; 
    8494 
     
    132142                                          int *data_type, 
    133143                                          pj_str_t *data); 
    134 static pj_bool_t stun_auth_verify_nonce(const pj_stun_msg *msg, 
    135                                         void *user_data, 
    136                                         const pj_str_t *realm, 
    137                                         const pj_str_t *username, 
    138                                         const pj_str_t *nonce); 
    139144 
    140145 
     
    189194    pj_pool_t *pool; 
    190195    pj_ice_sess *ice; 
    191     char tmp[64]; 
    192     pj_str_t s; 
    193196    unsigned i; 
    194197    pj_status_t status; 
     
    205208    ice->tie_breaker.u32.hi = pj_rand(); 
    206209    ice->tie_breaker.u32.lo = pj_rand(); 
     210    ice->prefs = cand_type_prefs; 
    207211 
    208212    pj_ansi_snprintf(ice->obj_name, sizeof(ice->obj_name), 
     
    227231 
    228232    if (local_ufrag == NULL) { 
    229         pj_ansi_snprintf(tmp, sizeof(tmp), "%x%x", pj_rand(), pj_rand()); 
    230         s = pj_str(tmp); 
    231         local_ufrag = &s; 
    232     } 
    233     pj_strdup(ice->pool, &ice->rx_ufrag, local_ufrag); 
     233        ice->rx_ufrag.ptr = pj_pool_alloc(ice->pool, 16); 
     234        pj_create_random_string(ice->rx_ufrag.ptr, 16); 
     235    } else { 
     236        pj_strdup(ice->pool, &ice->rx_ufrag, local_ufrag); 
     237    } 
    234238 
    235239    if (local_passwd == NULL) { 
    236         pj_ansi_snprintf(tmp, sizeof(tmp), "%x%x", pj_rand(), pj_rand()); 
    237         s = pj_str(tmp); 
    238         local_passwd = &s; 
    239     } 
    240     pj_strdup(ice->pool, &ice->rx_pass, local_passwd); 
     240        ice->rx_pass.ptr = pj_pool_alloc(ice->pool, 16); 
     241        pj_create_random_string(ice->rx_pass.ptr, 16); 
     242    } else { 
     243        pj_strdup(ice->pool, &ice->rx_pass, local_passwd); 
     244    } 
    241245 
    242246 
     
    313317    } 
    314318 
     319    return PJ_SUCCESS; 
     320} 
     321 
     322 
     323/* 
     324 * Change type preference 
     325 */ 
     326PJ_DEF(pj_status_t) pj_ice_sess_set_prefs(pj_ice_sess *ice, 
     327                                          const pj_uint8_t prefs[4]) 
     328{ 
     329    PJ_ASSERT_RETURN(ice && prefs, PJ_EINVAL); 
     330    ice->prefs = pj_pool_calloc(ice->pool, PJ_ARRAY_SIZE(prefs),  
     331                                sizeof(pj_uint8_t)); 
     332    pj_memcpy(ice->prefs, prefs, sizeof(prefs)); 
    315333    return PJ_SUCCESS; 
    316334} 
     
    422440 
    423441 
    424 static pj_bool_t stun_auth_verify_nonce(const pj_stun_msg *msg, 
    425                                         void *user_data, 
    426                                         const pj_str_t *realm, 
    427                                         const pj_str_t *username, 
    428                                         const pj_str_t *nonce) 
    429 { 
    430     /* We don't use NONCE */ 
    431     PJ_UNUSED_ARG(msg); 
    432     PJ_UNUSED_ARG(user_data); 
    433     PJ_UNUSED_ARG(realm); 
    434     PJ_UNUSED_ARG(username); 
    435     PJ_UNUSED_ARG(nonce); 
    436     return PJ_TRUE; 
    437 } 
    438  
    439  
    440 static pj_uint32_t CALC_CAND_PRIO(pj_ice_cand_type type, 
     442static pj_uint32_t CALC_CAND_PRIO(pj_ice_sess *ice, 
     443                                  pj_ice_cand_type type, 
    441444                                  pj_uint32_t local_pref, 
    442445                                  pj_uint32_t comp_id) 
    443446{ 
    444     pj_uint32_t type_pref[] = 
    445     { 
    446         PJ_ICE_HOST_PREF, 
    447         PJ_ICE_SRFLX_PREF, 
    448         PJ_ICE_PRFLX_PREF, 
    449         PJ_ICE_RELAYED_PREF 
    450     }; 
    451  
    452     return ((type_pref[type] & 0xFF) << 24) +  
     447    return ((ice->prefs[type] & 0xFF) << 24) +  
    453448           ((local_pref & 0xFFFF)    << 8) + 
    454449           (((256 - comp_id) & 0xFF) << 0); 
     
    493488    lcand->type = type; 
    494489    pj_strdup(ice->pool, &lcand->foundation, foundation); 
    495     lcand->prio = CALC_CAND_PRIO(type, local_pref, lcand->comp_id); 
     490    lcand->prio = CALC_CAND_PRIO(ice, type, local_pref, lcand->comp_id); 
    496491    pj_memcpy(&lcand->addr, addr, addr_len); 
    497492    pj_memcpy(&lcand->base_addr, base_addr, addr_len); 
     
    521516    sd = PJ_POOL_ZALLOC_T(ice->pool, struct stun_data); 
    522517    sd->ice = ice; 
    523     sd->lcand_id = GET_LCAND_ID(lcand); 
    524518    sd->lcand = lcand; 
    525519    pj_stun_session_set_user_data(lcand->stun_sess, sd); 
     
    531525    auth_cred.data.dyn_cred.get_cred = &stun_auth_get_cred; 
    532526    auth_cred.data.dyn_cred.get_password = &stun_auth_get_password; 
    533     auth_cred.data.dyn_cred.verify_nonce = &stun_auth_verify_nonce; 
    534527    auth_cred.data.dyn_cred.user_data = lcand->stun_sess; 
    535528    pj_stun_session_set_credential(lcand->stun_sess, &auth_cred); 
     
    563556 
    564557/* Find default candidate ID for the component */ 
     558#if 0 
    565559PJ_DEF(pj_status_t) pj_ice_sess_find_default_cand(pj_ice_sess *ice, 
    566560                                                  unsigned comp_id, 
     
    630624    return PJ_EBUG; 
    631625} 
     626#endif  /* if 0 */ 
    632627 
    633628 
     
    640635#endif 
    641636 
    642 static pj_uint64_t CALC_CHECK_PRIO(const pj_ice_sess *ice,  
    643                                    const pj_ice_sess_cand *lcand, 
    644                                    const pj_ice_sess_cand *rcand) 
     637static pj_timestamp CALC_CHECK_PRIO(const pj_ice_sess *ice,  
     638                                    const pj_ice_sess_cand *lcand, 
     639                                    const pj_ice_sess_cand *rcand) 
    645640{ 
    646641    pj_uint32_t O, A; 
     642    pj_timestamp prio; 
     643 
     644    /* Original formula: 
     645     *   pair priority = 2^32*MIN(O,A) + 2*MAX(O,A) + (O>A?1:0) 
     646     */ 
    647647 
    648648    if (ice->role == PJ_ICE_SESS_ROLE_CONTROLLING) { 
     
    654654    } 
    655655 
     656    /* 
    656657    return ((pj_uint64_t)1 << 32) * MIN(O, A) + 
    657658           (pj_uint64_t)2 * MAX(O, A) + (O>A ? 1 : 0); 
    658 } 
    659  
     659    */ 
     660 
     661    prio.u32.hi = MIN(O,A); 
     662    prio.u32.lo = (MAX(O, A) << 1) + (O>A ? 1 : 0); 
     663 
     664    return prio; 
     665} 
     666 
     667 
     668PJ_INLINE(int) CMP_CHECK_PRIO(const pj_ice_sess_check *c1, 
     669                              const pj_ice_sess_check *c2) 
     670{ 
     671    return pj_cmp_timestamp(&c1->prio, &c2->prio); 
     672} 
     673 
     674 
     675#if PJ_LOG_MAX_LEVEL >= 4 
    660676static const char *dump_check(char *buffer, unsigned bufsize, 
    661677                              const pj_ice_sess_checklist *clist, 
     
    691707} 
    692708 
    693 #if PJ_LOG_MAX_LEVEL >= 4 
    694709static void dump_checklist(const char *title, const pj_ice_sess *ice,  
    695710                           const pj_ice_sess_checklist *clist) 
     
    747762        unsigned j, highest = i; 
    748763        for (j=i+1; j<clist->count; ++j) { 
    749             if (clist->checks[j].prio > clist->checks[highest].prio) { 
     764            if (CMP_CHECK_PRIO(&clist->checks[j], &clist->checks[highest]) > 0) { 
    750765                highest = j; 
    751766            } 
     
    828843                ljaddr = &ljcand->addr; 
    829844 
    830             if (sockaddr_cmp(liaddr, ljaddr) == SOCKADDR_EQUAL && 
    831                 sockaddr_cmp(&ricand->addr, &rjcand->addr) == SOCKADDR_EQUAL) 
     845            if (ricand == rjcand &&  
     846                sockaddr_cmp(liaddr, ljaddr) == SOCKADDR_EQUAL) 
    832847            { 
    833848                /* Found duplicate, remove it */ 
     
    835850 
    836851                LOG5((ice->obj_name, "Check %s pruned", 
    837                     dump_check(buf, sizeof(buf), &ice->clist,  
    838                                &clist->checks[j]))); 
     852                     dump_check(buf, sizeof(buf), &ice->clist,  
     853                                &clist->checks[j]))); 
    839854 
    840855                pj_array_erase(clist->checks, sizeof(clist->checks[0]), 
     
    929944            comp->valid_check = check; 
    930945        } else { 
    931             if (comp->valid_check->prio < check->prio) 
     946            if (CMP_CHECK_PRIO(comp->valid_check, check) < 0) 
    932947                comp->valid_check = check; 
    933948        } 
     
    11551170                                        PJ_STUN_BINDING_REQUEST,  
    11561171                                        &check->tdata); 
    1157     if (status != PJ_SUCCESS) 
     1172    if (status != PJ_SUCCESS) { 
     1173        pjnath_perror(ice->obj_name, "Error creating STUN request", status); 
    11581174        return status; 
     1175    } 
    11591176 
    11601177    /* Attach data to be retrieved later when STUN request transaction 
     
    11681185 
    11691186    /* Add PRIORITY */ 
    1170     prio = CALC_CAND_PRIO(PJ_ICE_CAND_TYPE_PRFLX, 65535,  
     1187    prio = CALC_CAND_PRIO(ice, PJ_ICE_CAND_TYPE_PRFLX, 65535,  
    11711188                          lcand->comp_id); 
    11721189    pj_stun_msg_add_uint_attr(check->tdata->pool, check->tdata->msg,  
     
    11901207    if (status != PJ_SUCCESS) { 
    11911208        check->tdata = NULL; 
     1209        pjnath_perror(ice->obj_name, "Error sending STUN request", status); 
    11921210        return status; 
    11931211    } 
     
    12901308} 
    12911309 
     1310 
     1311/* Utility: find string in string array */ 
     1312const pj_str_t *find_str(const pj_str_t *strlist[], unsigned count, 
     1313                         const pj_str_t *str) 
     1314{ 
     1315    unsigned i; 
     1316    for (i=0; i<count; ++i) { 
     1317        if (pj_strcmp(strlist[i], str)==0) 
     1318            return strlist[i]; 
     1319    } 
     1320    return NULL; 
     1321} 
     1322 
    12921323/* Start ICE check */ 
    12931324PJ_DEF(pj_status_t) pj_ice_sess_start_check(pj_ice_sess *ice) 
     
    12951326    pj_ice_sess_checklist *clist; 
    12961327    const pj_ice_sess_cand *cand0; 
    1297     unsigned i; 
     1328    const pj_str_t *flist[PJ_ICE_MAX_CAND]; 
     1329    unsigned i, flist_cnt = 0; 
    12981330 
    12991331    PJ_ASSERT_RETURN(ice, PJ_EINVAL); 
    1300     /* Checklist must be created */ 
     1332 
     1333    /* Checklist must have been created */ 
    13011334    PJ_ASSERT_RETURN(ice->clist.count > 0, PJ_EINVALIDOP); 
    13021335 
    13031336    LOG4((ice->obj_name, "Starting ICE check..")); 
    13041337 
     1338    /* The agent examines the check list for the first media stream (a 
     1339     * media stream is the first media stream when it is described by 
     1340     * the first m-line in the SDP offer and answer).  For that media 
     1341     * stream, it: 
     1342     *  
     1343     * -  Groups together all of the pairs with the same foundation, 
     1344     *  
     1345     * -  For each group, sets the state of the pair with the lowest 
     1346     *    component ID to Waiting.  If there is more than one such pair, 
     1347     *    the one with the highest priority is used. 
     1348     */ 
     1349 
    13051350    clist = &ice->clist; 
    13061351 
    1307     /* Pickup the first pair and set the state to Waiting */ 
    1308     clist->checks[0].state = PJ_ICE_SESS_CHECK_STATE_WAITING; 
    1309     cand0 = clist->checks[0].lcand; 
     1352    /* Pickup the first pair for component 1. */ 
     1353    for (i=0; i<clist->count; ++i) { 
     1354        if (clist->checks[0].lcand->comp_id == 1) 
     1355            break; 
     1356    } 
     1357    if (i == clist->count) { 
     1358        pj_assert(!"Unable to find checklist for component 1"); 
     1359        return PJNATH_EICEINCOMPID; 
     1360    } 
     1361 
     1362    /* Set this check to WAITING */ 
     1363    check_set_state(ice, &clist->checks[i],  
     1364                    PJ_ICE_SESS_CHECK_STATE_WAITING, PJ_SUCCESS); 
     1365    cand0 = clist->checks[i].lcand; 
     1366    flist[flist_cnt++] = &clist->checks[i].lcand->foundation; 
    13101367 
    13111368    /* Find all of the other pairs in that check list with the same 
     
    13131370     * states to Waiting as well. 
    13141371     */ 
    1315     for (i=1; i<clist->count; ++i) { 
     1372    for (++i; i<clist->count; ++i) { 
    13161373        const pj_ice_sess_cand *cand1; 
    13171374 
    13181375        cand1 = clist->checks[i].lcand; 
    13191376 
    1320         if (cand0->comp_id == cand1->comp_id && 
    1321             pj_strcmp(&cand0->foundation, &cand1->foundation)!=0) 
     1377        if (cand1->comp_id==cand0->comp_id && 
     1378            find_str(flist, flist_cnt, &cand1->foundation)==NULL) 
    13221379        { 
    1323             clist->checks[i].state = PJ_ICE_SESS_CHECK_STATE_WAITING; 
     1380            check_set_state(ice, &clist->checks[i],  
     1381                            PJ_ICE_SESS_CHECK_STATE_WAITING, PJ_SUCCESS); 
     1382            flist[flist_cnt++] = &cand1->foundation; 
    13241383        } 
    13251384    } 
     
    13421401{ 
    13431402    stun_data *sd = (stun_data*) pj_stun_session_get_user_data(sess); 
    1344     return (*sd->ice->cb.on_tx_pkt)(sd->ice, sd->lcand->comp_id, sd->lcand_id, 
     1403    pj_ice_sess *ice = sd->ice; 
     1404    return (*sd->ice->cb.on_tx_pkt)(sd->ice, sd->lcand->comp_id,  
     1405                                    GET_LCAND_ID(sd->lcand), 
    13451406                                    pkt, pkt_size,  
    13461407                                    dst_addr, addr_len); 
  • pjproject/trunk/pjnath/src/pjnath/ice_strans.c

    r1114 r1126  
    6666 
    6767/* Utility: print error */ 
    68 #if PJ_LOG_MAX_LEVEL >= 3 
    69 static void ice_st_perror(pj_ice_strans *ice_st, const char *title,  
    70                           pj_status_t status) 
    71 { 
    72     char errmsg[PJ_ERR_MSG_SIZE]; 
    73  
    74     pj_strerror(status, errmsg, sizeof(errmsg)); 
    75     PJ_LOG(3,(ice_st->obj_name, "%s: %s", title, errmsg)); 
    76 } 
    77 #else 
    78 #   define ice_st_perror(ice_st, title, status) 
    79 #endif 
    80  
     68#define ice_st_perror(ice_st,msg,rc) pjnath_perror(ice_st->obj_name,msg,rc) 
    8169 
    8270/*  
     
    345333            pj_sockaddr_in cand_addr; 
    346334            pj_bool_t set_default; 
     335            pj_uint16_t local_pref; 
    347336 
    348337            /* Ignore 127.0.0.0/24 address */ 
     
    359348            if (ifs[i].s_addr == comp->local_addr.ipv4.sin_addr.s_addr) { 
    360349                set_default = PJ_TRUE; 
     350                local_pref = 65535; 
    361351            } else { 
    362352                set_default = PJ_FALSE; 
     353                local_pref = 0; 
    363354            } 
    364355 
    365356            status = add_cand(ice_st, comp, comp_id,  
    366357                              PJ_ICE_CAND_TYPE_HOST,  
    367                               (pj_uint16_t)(65535-i), &cand_addr, 
    368                               set_default); 
     358                              local_pref, &cand_addr, set_default); 
    369359            if (status != PJ_SUCCESS) 
    370360                goto on_error; 
     
    760750    unsigned i; 
    761751    pj_ice_sess_cb ice_cb; 
     752    const pj_uint8_t srflx_prio[4] = { 100, 126, 110, 0 }; 
    762753 
    763754    /* Check arguments */ 
     
    783774    /* Associate user data */ 
    784775    ice_st->ice->user_data = (void*)ice_st; 
     776 
     777    /* If default candidate for components are SRFLX one, upload a custom 
     778     * type priority to ICE session so that SRFLX candidates will get 
     779     * checked first. 
     780     */ 
     781    if (ice_st->comp[0]->default_cand >= 0 && 
     782        ice_st->comp[0]->cand_list[ice_st->comp[0]->default_cand].type  
     783            == PJ_ICE_CAND_TYPE_SRFLX) 
     784    { 
     785        pj_ice_sess_set_prefs(ice_st->ice, srflx_prio); 
     786    } 
     787 
    785788 
    786789    /* Add candidates */ 
  • pjproject/trunk/pjnath/src/pjnath/stun_auth.c

    r1101 r1126  
    270270        pj_bool_t ok; 
    271271 
    272         if (cred->type == PJ_STUN_AUTH_CRED_DYNAMIC) { 
     272        if (cred->type == PJ_STUN_AUTH_CRED_DYNAMIC && 
     273            cred->data.dyn_cred.verify_nonce != NULL)  
     274        { 
    273275            ok=cred->data.dyn_cred.verify_nonce(msg,  
    274276                                                cred->data.dyn_cred.user_data, 
     
    276278                                                &auser->value, 
    277279                                                &anonce->value); 
     280        } else if (cred->type == PJ_STUN_AUTH_CRED_DYNAMIC) { 
     281            ok = PJ_TRUE; 
    278282        } else { 
    279283            if (nonce.slen) { 
  • pjproject/trunk/pjnath/src/pjnath/stun_msg.c

    r1114 r1126  
    140140 
    141141 
    142 struct attr_desc mandatory_attr_desc[] =  
     142static struct attr_desc mandatory_attr_desc[] =  
    143143{ 
    144144    { 
     
    438438    { 
    439439        /* PJ_STUN_ATTR_ICE_CONTROLLED, */ 
    440         "ICE-CCONTROLLED", 
     440        "ICE-CONTROLLED", 
    441441        &decode_uint64_attr, 
    442442        &encode_uint64_attr 
     
    444444    { 
    445445        /* PJ_STUN_ATTR_ICE_CONTROLLING, */ 
    446         "ICE-CCONTROLLING", 
     446        "ICE-CONTROLLING", 
    447447        &decode_uint64_attr, 
    448448        &encode_uint64_attr 
     
    18711871                    /* Already has MESSAGE-INTEGRITY */ 
    18721872                    if (p_response) { 
    1873                         pj_str_t e; 
    1874                         e = pj_str("MESSAGE-INTEGRITY already present"); 
    18751873                        pj_stun_msg_create_response(pool, msg, 
    18761874                                                    PJ_STUN_SC_BAD_REQUEST, 
     
    18851883                    /* Already has FINGERPRINT */ 
    18861884                    if (p_response) { 
    1887                         pj_str_t e; 
    1888                         e = pj_str("FINGERPRINT already present"); 
    18891885                        pj_stun_msg_create_response(pool, msg, 
    18901886                                                    PJ_STUN_SC_BAD_REQUEST, 
     
    18991895                     * after FINGERPRINT or MESSAGE-INTEGRITY */ 
    19001896                    if (p_response) { 
    1901                         pj_str_t e; 
    1902                         e = pj_str("Invalid attribute order"); 
    19031897                        pj_stun_msg_create_response(pool, msg, 
    19041898                                                    PJ_STUN_SC_BAD_REQUEST, 
     
    19131907            if (msg->attr_count >= PJ_STUN_MAX_ATTR) { 
    19141908                if (p_response) { 
    1915                     pj_str_t e; 
    1916  
    1917                     e = pj_str("Too many attributes"); 
    19181909                    pj_stun_msg_create_response(pool, msg, 
    19191910                                                PJ_STUN_SC_BAD_REQUEST, 
    1920                                                 &e, p_response); 
     1911                                                NULL, p_response); 
    19211912                } 
    19221913                return PJNATH_ESTUNTOOMANYATTR; 
  • pjproject/trunk/pjnath/src/pjnath/stun_msg_dump.c

    r1114 r1126  
    2323 
    2424 
     25#if PJ_LOG_MAX_LEVEL > 0 
     26 
     27 
    2528#define APPLY()         if (len < 1 || len >= (end-p)) \ 
    2629                            goto on_return; \ 
     
    245248    return buffer; 
    246249 
     250#undef APPLY 
    247251} 
    248252 
    249253 
    250 #undef APPLY 
     254#endif  /* PJ_LOG_MAX_LEVEL > 0 */ 
     255 
  • pjproject/trunk/pjnath/src/pjnath/stun_session.c

    r1111 r1126  
    4444#endif 
    4545 
    46 #if PJ_LOG_MAX_LEVEL >= 4 
    47 #   define LOG_ERR_(sess, title, rc) stun_perror(sess, title, rc) 
    48 static void stun_perror(pj_stun_session *sess, const char *title,  
    49                         pj_status_t status) 
    50 { 
    51     char errmsg[PJ_ERR_MSG_SIZE]; 
    52  
    53     pj_strerror(status, errmsg, sizeof(errmsg)); 
    54  
    55     PJ_LOG(4,(SNAME(sess), "%s: %s", title, errmsg)); 
    56 } 
    57  
    58 #else 
    59 #   define LOG_ERR_(sess, title, rc) 
    60 #endif 
     46#define LOG_ERR_(sess,title,rc) pjnath_perror(sess->pool->obj_name,title,rc) 
    6147 
    6248#define TDATA_POOL_SIZE             1024 
     
    780766    tdata = tsx_lookup(sess, msg); 
    781767    if (tdata == NULL) { 
    782         PJ_LOG(4,(SNAME(sess),  
     768        PJ_LOG(5,(SNAME(sess),  
    783769                  "Transaction not found, response silently discarded")); 
    784770        return PJ_SUCCESS; 
  • pjproject/trunk/pjnath/src/pjnath/stun_transaction.c

    r1114 r1126  
    5151                                      pj_timer_entry *timer); 
    5252 
    53 static void stun_perror(pj_stun_client_tsx *tsx, const char *title, 
    54                         pj_status_t status) 
    55 { 
    56     char errmsg[PJ_ERR_MSG_SIZE]; 
    57  
    58     pj_strerror(status, errmsg, sizeof(errmsg)); 
    59     PJ_LOG(4,(tsx->obj_name, "%s: %s", title, errmsg)); 
    60 } 
    61  
     53#define stun_perror(tsx,msg,rc) pjnath_perror(tsx->obj_name, msg, rc) 
    6254 
    6355/* 
     
    8577    *p_tsx = tsx; 
    8678 
    87     PJ_LOG(4,(tsx->obj_name, "STUN client transaction created")); 
     79    PJ_LOG(5,(tsx->obj_name, "STUN client transaction created")); 
    8880    return PJ_SUCCESS; 
    8981} 
     
    192184    tsx->transmit_count++; 
    193185 
    194     PJ_LOG(4,(tsx->obj_name, "STUN sending message (transmit count=%d)", 
     186    PJ_LOG(5,(tsx->obj_name, "STUN sending message (transmit count=%d)", 
    195187              tsx->transmit_count)); 
    196188    return status; 
Note: See TracChangeset for help on using the changeset viewer.