Changeset 5339 for pjproject


Ignore:
Timestamp:
Jun 8, 2016 3:17:45 AM (8 years ago)
Author:
nanang
Message:

Re #422: Added IPv6 support to PJNATH, changes:

  • Deprecated 'pj_ice_strans_cfg.af', if set, the value will be ignored, address family setting is now specified via transport setting, i.e: 'pj_ice_strans_cfg.stun_tp/turn_tp'.
  • Deprecated 'pj_ice_strans_cfg.stun/turn', for backward compatibility, this field value will be checked if 'pj_ice_strans_cfg.stun_tp_cnt/turn_tp_cnt' is set to zero.
  • Added 'pj_ice_strans_stun_cfg' & 'pj_ice_strans_stun_cfg' and the corresponding 'pj_ice_strans_stun/turn_cfg_default()'
  • Added 'pj_ice_strans_cfg.stun_tp/turn_tp' as replacement of 'pj_ice_strans_cfg.stun/turn', it is now an array so app can have multiple STUN/TURN transports.
  • Added macro PJ_ICE_MAX_STUN/TURN to specify maximum number of STUN/TURN transports in each ICE component in compile-time.
  • Miscellaneous: fixed socket number limit in concurrency test in pjnath-test, updated pjsua_media.c to use new 'pj_ice_strans_cfg' setting.
Location:
pjproject/trunk
Files:
9 edited

Legend:

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

    r4949 r5339  
    5151    pjmedia_transport    base; 
    5252    pj_pool_t           *pool; 
    53     int                  af; 
    5453    unsigned             options;       /**< Transport options.             */ 
    5554 
     
    236235    tp_ice = PJ_POOL_ZALLOC_T(pool, struct transport_ice); 
    237236    tp_ice->pool = pool; 
    238     tp_ice->af = cfg->af; 
    239237    tp_ice->options = options; 
    240238    tp_ice->comp_cnt = comp_cnt; 
     
    823821    pj_sockaddr rem_conn_addr, rtcp_addr; 
    824822    unsigned i; 
     823    int rem_af = 0; 
    825824    pj_status_t status; 
    826825 
     
    849848 
    850849    /* Verify address family matches */ 
     850    /* 
    851851    if ((tp_ice->af==pj_AF_INET() &&  
    852852         pj_strcmp(&rem_conn->addr_type, &STR_IP4)!=0) || 
     
    856856        return PJMEDIA_SDP_ETPORTNOTEQUAL; 
    857857    } 
     858    */ 
     859 
     860    /* Get remote address family */ 
     861    if (pj_strcmp(&rem_conn->addr_type, &STR_IP4)==0) 
     862        rem_af = pj_AF_INET(); 
     863    else if (pj_strcmp(&rem_conn->addr_type, &STR_IP6)==0) 
     864        rem_af = pj_AF_INET6(); 
     865    else 
     866        pj_assert(!"Unsupported address family"); 
    858867 
    859868    /* Assign remote connection address */ 
    860     status = pj_sockaddr_init(tp_ice->af, &rem_conn_addr, &rem_conn->addr, 
     869    status = pj_sockaddr_init(rem_af, &rem_conn_addr, &rem_conn->addr, 
    861870                              (pj_uint16_t)rem_m->desc.port); 
    862871    if (status != PJ_SUCCESS) 
     
    884893            if (rtcp_attr.addr.slen) { 
    885894                /* Verify address family matches */ 
     895                /* 
    886896                if ((tp_ice->af==pj_AF_INET() &&  
    887897                     pj_strcmp(&rtcp_attr.addr_type, &STR_IP4)!=0) || 
     
    891901                    return PJMEDIA_SDP_ETPORTNOTEQUAL; 
    892902                } 
     903                */ 
    893904 
    894905                /* Assign RTCP address */ 
    895                 status = pj_sockaddr_init(tp_ice->af, &rtcp_addr, 
     906                status = pj_sockaddr_init(rem_af, &rtcp_addr, 
    896907                                          &rtcp_attr.addr, 
    897908                                          (pj_uint16_t)rtcp_attr.port); 
     
    901912            } else { 
    902913                /* Assign RTCP address */ 
    903                 status = pj_sockaddr_init(tp_ice->af, &rtcp_addr,  
     914                status = pj_sockaddr_init(rem_af, &rtcp_addr,  
    904915                                          NULL,  
    905916                                          (pj_uint16_t)rtcp_attr.port); 
  • pjproject/trunk/pjnath/include/pjnath/config.h

    r4199 r5339  
    243243#ifndef PJ_ICE_ST_MAX_CAND 
    244244#   define PJ_ICE_ST_MAX_CAND                       8 
     245#endif 
     246 
     247 
     248/** 
     249 * Maximum number of STUN transports for each ICE stream transport component. 
     250 * Valid values are 1 - 64. 
     251 * 
     252 * Default: 2 
     253 */ 
     254#ifndef PJ_ICE_MAX_STUN 
     255#   define PJ_ICE_MAX_STUN                          2 
     256#endif 
     257 
     258 
     259/** 
     260 * Maximum number of TURN transports for each ICE stream transport component. 
     261 * Valid values are 1 - 64. 
     262 * 
     263 * Default: 2 
     264 */ 
     265#ifndef PJ_ICE_MAX_TURN 
     266#   define PJ_ICE_MAX_TURN                          2 
    245267#endif 
    246268 
  • pjproject/trunk/pjnath/include/pjnath/ice_session.h

    r4602 r5339  
    654654 
    655655    /** Array of transport datas */ 
    656     pj_ice_msg_data      tp_data[4]; 
     656    pj_ice_msg_data      tp_data[PJ_ICE_MAX_STUN + PJ_ICE_MAX_TURN]; 
    657657 
    658658    /* List of eearly checks */ 
  • pjproject/trunk/pjnath/include/pjnath/ice_strans.h

    r5282 r5339  
    176176 
    177177/** 
     178 * STUN and local transport settings for ICE stream transport. 
     179 */ 
     180typedef struct pj_ice_strans_stun_cfg 
     181{ 
     182    /** 
     183     * Address family, IPv4 or IPv6. 
     184     * 
     185     * Default value is pj_AF_INET() (IPv4) 
     186     */ 
     187    int                  af; 
     188 
     189    /** 
     190     * Optional configuration for STUN transport. The default 
     191     * value will be initialized with #pj_stun_sock_cfg_default(). 
     192     */ 
     193    pj_stun_sock_cfg     cfg; 
     194 
     195    /** 
     196     * Maximum number of host candidates to be added. If the 
     197     * value is zero, no host candidates will be added. 
     198     * 
     199     * Default: 64 
     200     */ 
     201    unsigned             max_host_cands; 
     202 
     203    /** 
     204     * Include loopback addresses in the host candidates. 
     205     * 
     206     * Default: PJ_FALSE 
     207     */ 
     208    pj_bool_t            loop_addr; 
     209 
     210    /** 
     211     * Specify the STUN server domain or hostname or IP address. 
     212     * If DNS SRV resolution is required, application must fill 
     213     * in this setting with the domain name of the STUN server  
     214     * and set the resolver instance in the \a resolver field. 
     215     * Otherwise if the \a resolver setting is not set, this 
     216     * field will be resolved with hostname resolution and in 
     217     * this case the \a port field must be set. 
     218     * 
     219     * The \a port field should also be set even when DNS SRV 
     220     * resolution is used, in case the DNS SRV resolution fails. 
     221     * 
     222     * When this field is empty, STUN mapped address resolution 
     223     * will not be performed. In this case only ICE host candidates 
     224     * will be added to the ICE transport, unless if \a no_host_cands 
     225     * field is set. In this case, both host and srflx candidates  
     226     * are disabled. 
     227     * 
     228     * If there are more than one STUN candidates per ICE stream 
     229     * transport component, the standard recommends to use the same 
     230     * STUN server for all STUN candidates. 
     231     * 
     232     * The default value is empty. 
     233     */ 
     234    pj_str_t             server; 
     235 
     236    /** 
     237     * The port number of the STUN server, when \a server 
     238     * field specifies a hostname rather than domain name. This 
     239     * field should also be set even when the \a server 
     240     * specifies a domain name, to allow DNS SRV resolution 
     241     * to fallback to DNS A/AAAA resolution when the DNS SRV 
     242     * resolution fails. 
     243     * 
     244     * The default value is PJ_STUN_PORT. 
     245     */ 
     246    pj_uint16_t          port; 
     247 
     248    /** 
     249     * Ignore STUN resolution error and proceed with just local 
     250     * addresses. 
     251     * 
     252     * The default is PJ_FALSE 
     253     */ 
     254    pj_bool_t            ignore_stun_error; 
     255 
     256} pj_ice_strans_stun_cfg; 
     257 
     258 
     259/** 
     260 * TURN transport settings for ICE stream transport. 
     261 */ 
     262typedef struct pj_ice_strans_turn_cfg 
     263{ 
     264    /** 
     265     * Address family, IPv4 or IPv6. 
     266     * 
     267     * Default value is pj_AF_INET() (IPv4) 
     268     */ 
     269    int                  af; 
     270 
     271    /** 
     272     * Optional TURN socket settings. The default values will be 
     273     * initialized by #pj_turn_sock_cfg_default(). This contains 
     274     * settings such as QoS. 
     275     */ 
     276    pj_turn_sock_cfg     cfg; 
     277 
     278    /** 
     279     * Specify the TURN server domain or hostname or IP address. 
     280     * If DNS SRV resolution is required, application must fill 
     281     * in this setting with the domain name of the TURN server  
     282     * and set the resolver instance in the \a resolver field. 
     283     * Otherwise if the \a resolver setting is not set, this 
     284     * field will be resolved with hostname resolution and in 
     285     * this case the \a port field must be set. 
     286     * 
     287     * The \a port field should also be set even when DNS SRV 
     288     * resolution is used, in case the DNS SRV resolution fails. 
     289     * 
     290     * When this field is empty, relay candidate will not be 
     291     * created. 
     292     * 
     293     * The default value is empty. 
     294     */ 
     295    pj_str_t             server; 
     296 
     297    /** 
     298     * The port number of the TURN server, when \a server 
     299     * field specifies a hostname rather than domain name. This 
     300     * field should also be set even when the \a server 
     301     * specifies a domain name, to allow DNS SRV resolution 
     302     * to fallback to DNS A/AAAA resolution when the DNS SRV 
     303     * resolution fails. 
     304     * 
     305     * Default is zero. 
     306     */ 
     307    pj_uint16_t          port; 
     308 
     309    /** 
     310     * Type of connection to the TURN server. 
     311     * 
     312     * Default is PJ_TURN_TP_UDP. 
     313     */ 
     314    pj_turn_tp_type      conn_type; 
     315 
     316    /** 
     317     * Credential to be used for the TURN session. This setting 
     318     * is mandatory. 
     319     * 
     320     * Default is to have no credential. 
     321     */ 
     322    pj_stun_auth_cred    auth_cred; 
     323 
     324    /** 
     325     * Optional TURN Allocate parameter. The default value will be 
     326     * initialized by #pj_turn_alloc_param_default(). 
     327     */ 
     328    pj_turn_alloc_param  alloc_param; 
     329 
     330} pj_ice_strans_turn_cfg; 
     331 
     332 
     333/** 
    178334 * This structure describes ICE stream transport configuration. Application 
    179335 * should initialize the structure by calling #pj_ice_strans_cfg_default() 
     
    183339{ 
    184340    /** 
    185      * Address family, IPv4 or IPv6. Currently only pj_AF_INET() (IPv4) 
    186      * is supported, and this is the default value. 
    187      */ 
    188     int                 af; 
     341     * Warning: this field is deprecated and will be ignored. Please specify 
     342     * transport address family in STUN and TURN transport setting, i.e: 
     343     * \a stun_tp and \a turn_tp. 
     344     */ 
     345    int                  af; 
    189346 
    190347    /** 
     
    214371 
    215372    /** 
    216      * STUN and local transport settings. This specifies the  
    217      * settings for local UDP socket, which will be resolved 
    218      * to get the STUN mapped address. 
    219      */ 
    220     struct { 
    221         /** 
    222          * Optional configuration for STUN transport. The default 
    223          * value will be initialized with #pj_stun_sock_cfg_default(). 
    224          */ 
    225         pj_stun_sock_cfg     cfg; 
    226  
    227         /** 
    228          * Maximum number of host candidates to be added. If the 
    229          * value is zero, no host candidates will be added. 
    230          * 
    231          * Default: 64 
    232          */ 
    233         unsigned             max_host_cands; 
    234  
    235         /** 
    236          * Include loopback addresses in the host candidates. 
    237          * 
    238          * Default: PJ_FALSE 
    239          */ 
    240         pj_bool_t            loop_addr; 
    241  
    242         /** 
    243          * Specify the STUN server domain or hostname or IP address. 
    244          * If DNS SRV resolution is required, application must fill 
    245          * in this setting with the domain name of the STUN server  
    246          * and set the resolver instance in the \a resolver field. 
    247          * Otherwise if the \a resolver setting is not set, this 
    248          * field will be resolved with hostname resolution and in 
    249          * this case the \a port field must be set. 
    250          * 
    251          * The \a port field should also be set even when DNS SRV 
    252          * resolution is used, in case the DNS SRV resolution fails. 
    253          * 
    254          * When this field is empty, STUN mapped address resolution 
    255          * will not be performed. In this case only ICE host candidates 
    256          * will be added to the ICE transport, unless if \a no_host_cands 
    257          * field is set. In this case, both host and srflx candidates  
    258          * are disabled. 
    259          * 
    260          * The default value is empty. 
    261          */ 
    262         pj_str_t             server; 
    263  
    264         /** 
    265          * The port number of the STUN server, when \a server 
    266          * field specifies a hostname rather than domain name. This 
    267          * field should also be set even when the \a server 
    268          * specifies a domain name, to allow DNS SRV resolution 
    269          * to fallback to DNS A/AAAA resolution when the DNS SRV 
    270          * resolution fails. 
    271          * 
    272          * The default value is PJ_STUN_PORT. 
    273          */ 
    274         pj_uint16_t          port; 
    275  
    276         /** 
    277          * Ignore STUN resolution error and proceed with just local 
    278          * addresses. 
    279          * 
    280          * The default is PJ_FALSE 
    281          */ 
    282         pj_bool_t            ignore_stun_error; 
    283  
    284     } stun; 
    285  
    286     /** 
    287      * TURN specific settings. 
    288      */ 
    289     struct { 
    290         /** 
    291          * Optional TURN socket settings. The default values will be 
    292          * initialized by #pj_turn_sock_cfg_default(). This contains 
    293          * settings such as QoS. 
    294          */ 
    295         pj_turn_sock_cfg     cfg; 
    296  
    297         /** 
    298          * Specify the TURN server domain or hostname or IP address. 
    299          * If DNS SRV resolution is required, application must fill 
    300          * in this setting with the domain name of the TURN server  
    301          * and set the resolver instance in the \a resolver field. 
    302          * Otherwise if the \a resolver setting is not set, this 
    303          * field will be resolved with hostname resolution and in 
    304          * this case the \a port field must be set. 
    305          * 
    306          * The \a port field should also be set even when DNS SRV 
    307          * resolution is used, in case the DNS SRV resolution fails. 
    308          * 
    309          * When this field is empty, relay candidate will not be 
    310          * created. 
    311          * 
    312          * The default value is empty. 
    313          */ 
    314         pj_str_t             server; 
    315  
    316         /** 
    317          * The port number of the TURN server, when \a server 
    318          * field specifies a hostname rather than domain name. This 
    319          * field should also be set even when the \a server 
    320          * specifies a domain name, to allow DNS SRV resolution 
    321          * to fallback to DNS A/AAAA resolution when the DNS SRV 
    322          * resolution fails. 
    323          * 
    324          * Default is zero. 
    325          */ 
    326         pj_uint16_t          port; 
    327  
    328         /** 
    329          * Type of connection to the TURN server. 
    330          * 
    331          * Default is PJ_TURN_TP_UDP. 
    332          */ 
    333         pj_turn_tp_type      conn_type; 
    334  
    335         /** 
    336          * Credential to be used for the TURN session. This setting 
    337          * is mandatory. 
    338          * 
    339          * Default is to have no credential. 
    340          */ 
    341         pj_stun_auth_cred    auth_cred; 
    342  
    343         /** 
    344          * Optional TURN Allocate parameter. The default value will be 
    345          * initialized by #pj_turn_alloc_param_default(). 
    346          */ 
    347         pj_turn_alloc_param  alloc_param; 
    348  
    349     } turn; 
     373     * Warning: this field is deprecated, please use \a stun_tp field instead. 
     374     * To maintain backward compatibility, if \a stun_tp_cnt is zero, the 
     375     * value of this field will be copied to \a stun_tp. 
     376     * 
     377     * STUN and local transport settings. This specifies the settings 
     378     * for local UDP socket address and STUN resolved address. 
     379     */ 
     380    pj_ice_strans_stun_cfg stun; 
     381 
     382    /** 
     383     * Number of STUN transports. 
     384     * 
     385     * Default: 0 
     386     */ 
     387    unsigned             stun_tp_cnt; 
     388 
     389    /** 
     390     * STUN and local transport settings. This specifies the settings 
     391     * for local UDP socket address and STUN resolved address. 
     392     */ 
     393    pj_ice_strans_stun_cfg stun_tp[PJ_ICE_MAX_STUN]; 
     394 
     395    /** 
     396     * Warning: this field is deprecated, please use \a turn_tp field instead. 
     397     * To maintain backward compatibility, if \a turn_tp_cnt is zero, the 
     398     * value of this field will be copied to \a turn_tp. 
     399     * 
     400     * TURN transport settings. 
     401     */ 
     402    pj_ice_strans_turn_cfg turn; 
     403 
     404    /** 
     405     * Number of TURN transports. 
     406     * 
     407     * Default: 0 
     408     */ 
     409    unsigned             turn_tp_cnt; 
     410 
     411    /** 
     412     * TURN transport settings. 
     413     */ 
     414    pj_ice_strans_turn_cfg turn_tp[PJ_ICE_MAX_TURN]; 
    350415 
    351416    /** 
     
    467532 
    468533 
     534/**  
     535 * Initialize ICE STUN transport configuration with default values. 
     536 * 
     537 * @param cfg           The configuration to be initialized. 
     538 */ 
     539PJ_DECL(void) pj_ice_strans_stun_cfg_default(pj_ice_strans_stun_cfg *cfg); 
     540 
     541 
     542/**  
     543 * Initialize ICE TURN transport configuration with default values. 
     544 * 
     545 * @param cfg           The configuration to be initialized. 
     546 */ 
     547PJ_DECL(void) pj_ice_strans_turn_cfg_default(pj_ice_strans_turn_cfg *cfg); 
     548 
     549 
    469550/** 
    470551 * Copy configuration. 
  • pjproject/trunk/pjnath/include/pjnath/stun_sock.h

    r4606 r5339  
    372372 * 
    373373 * @param stun_sock     The STUN transport instance. 
    374  * @param domain        The domain, hostname, or IP address of the TURN 
     374 * @param domain        The domain, hostname, or IP address of the STUN 
    375375 *                      server. When this parameter contains domain name, 
    376376 *                      the \a resolver parameter must be set to activate 
  • pjproject/trunk/pjnath/src/pjnath-test/concur_test.c

    r4898 r5339  
    2727#define WORKER_THREAD_CNT       4 
    2828#define SERVER_THREAD_CNT       4 
    29 #define MAX_SOCK_CLIENTS        80 
     29#define MAX_SOCK_CLIENTS        (PJ_IOQUEUE_MAX_HANDLES/2) 
    3030 
    3131struct stun_test_session 
     
    220220    } 
    221221 
     222    /* Give some time to ioqueue to free sockets */ 
     223    pj_thread_sleep(PJ_IOQUEUE_KEY_FREE_DELAY); 
     224 
    222225    return 0; 
    223226} 
  • pjproject/trunk/pjnath/src/pjnath/ice_session.c

    r5221 r5339  
    397397    /* Initialize transport datas */ 
    398398    for (i=0; i<PJ_ARRAY_SIZE(ice->tp_data); ++i) { 
    399         ice->tp_data[i].transport_id = i; 
     399        ice->tp_data[i].transport_id = 0; 
    400400        ice->tp_data[i].has_req_data = PJ_FALSE; 
    401401    } 
     
    724724    pj_status_t status = PJ_SUCCESS; 
    725725    char address[PJ_INET6_ADDRSTRLEN]; 
     726    unsigned i; 
    726727 
    727728    PJ_ASSERT_RETURN(ice && comp_id &&  
     
    748749        rel_addr = base_addr; 
    749750    pj_memcpy(&lcand->rel_addr, rel_addr, addr_len); 
     751 
     752    /* Update transport data */ 
     753    for (i = 0; i < PJ_ARRAY_SIZE(ice->tp_data); ++i) { 
     754        /* Check if this transport has been registered */ 
     755        if (ice->tp_data[i].transport_id == transport_id) 
     756            break; 
     757 
     758        if (ice->tp_data[i].transport_id == 0) { 
     759            /* Found an empty slot, register this transport here */ 
     760            ice->tp_data[i].transport_id = transport_id; 
     761            break; 
     762        } 
     763    } 
     764    pj_assert(i < PJ_ARRAY_SIZE(ice->tp_data) && 
     765              ice->tp_data[i].transport_id == transport_id); 
    750766 
    751767    pj_ansi_strcpy(ice->tmp.txt, pj_sockaddr_print(&lcand->addr, address, 
  • pjproject/trunk/pjnath/src/pjnath/ice_strans.c

    r5282 r5339  
    4949}; 
    5050 
     51 
     52#define CREATE_TP_ID(type, idx)     (pj_uint8_t)((type << 6) | idx) 
     53#define GET_TP_TYPE(transport_id)   ((transport_id & 0xC0) >> 6) 
     54#define GET_TP_IDX(transport_id)    (transport_id & 0x3F) 
     55 
     56 
    5157/* Candidate's local preference values. This is mostly used to 
    5258 * specify preference among candidates with the same type. Since 
     
    149155    unsigned             comp_id;       /**< Component ID.              */ 
    150156 
    151     pj_stun_sock        *stun_sock;     /**< STUN transport.            */ 
    152     pj_turn_sock        *turn_sock;     /**< TURN relay transport.      */ 
    153     pj_bool_t            turn_log_off;  /**< TURN loggin off?           */ 
    154     unsigned             turn_err_cnt;  /**< TURN disconnected count.   */ 
     157    struct { 
     158        pj_stun_sock    *sock;          /**< STUN transport.            */ 
     159    } stun[PJ_ICE_MAX_STUN]; 
     160 
     161    struct { 
     162        pj_turn_sock    *sock;          /**< TURN relay transport.      */ 
     163        pj_bool_t        log_off;       /**< TURN loggin off?           */ 
     164        unsigned         err_cnt;       /**< TURN disconnected count.   */ 
     165    } turn[PJ_ICE_MAX_TURN]; 
    155166 
    156167    unsigned             cand_cnt;      /**< # of candidates/aliaes.    */ 
     
    188199 
    189200 
     201/** 
     202 * This structure describe user data for STUN/TURN sockets of the 
     203 * ICE stream transport. 
     204 */ 
     205typedef struct sock_user_data 
     206{ 
     207    pj_ice_strans_comp      *comp; 
     208    pj_uint8_t               transport_id; 
     209 
     210} sock_user_data; 
     211 
     212 
    190213/* Validate configuration */ 
    191214static pj_status_t pj_ice_strans_cfg_check_valid(const pj_ice_strans_cfg *cfg) 
     
    209232 
    210233    pj_stun_config_init(&cfg->stun_cfg, NULL, 0, NULL, NULL); 
    211     pj_stun_sock_cfg_default(&cfg->stun.cfg); 
    212     pj_turn_alloc_param_default(&cfg->turn.alloc_param); 
    213     pj_turn_sock_cfg_default(&cfg->turn.cfg); 
    214  
     234    pj_ice_strans_stun_cfg_default(&cfg->stun); 
     235    pj_ice_strans_turn_cfg_default(&cfg->turn); 
    215236    pj_ice_sess_options_default(&cfg->opt); 
     237} 
     238 
     239 
     240/* 
     241 * Initialize ICE STUN transport configuration with default values. 
     242 */ 
     243PJ_DEF(void) pj_ice_strans_stun_cfg_default(pj_ice_strans_stun_cfg *cfg) 
     244{ 
     245    pj_bzero(cfg, sizeof(*cfg)); 
    216246 
    217247    cfg->af = pj_AF_INET(); 
    218     cfg->stun.port = PJ_STUN_PORT; 
    219     cfg->turn.conn_type = PJ_TURN_TP_UDP; 
    220  
    221     cfg->stun.max_host_cands = 64; 
    222     cfg->stun.ignore_stun_error = PJ_FALSE; 
     248    cfg->port = PJ_STUN_PORT; 
     249    cfg->max_host_cands = 64; 
     250    cfg->ignore_stun_error = PJ_FALSE; 
     251    pj_stun_sock_cfg_default(&cfg->cfg); 
     252} 
     253 
     254 
     255/* 
     256 * Initialize ICE TURN transport configuration with default values. 
     257 */ 
     258PJ_DEF(void) pj_ice_strans_turn_cfg_default(pj_ice_strans_turn_cfg *cfg) 
     259{ 
     260    pj_bzero(cfg, sizeof(*cfg)); 
     261 
     262    cfg->af = pj_AF_INET(); 
     263    cfg->conn_type = PJ_TURN_TP_UDP; 
     264    pj_turn_alloc_param_default(&cfg->alloc_param); 
     265    pj_turn_sock_cfg_default(&cfg->cfg); 
    223266} 
    224267 
     
    231274                                     const pj_ice_strans_cfg *src) 
    232275{ 
     276    unsigned i; 
     277 
    233278    pj_memcpy(dst, src, sizeof(*src)); 
    234279 
    235280    if (src->stun.server.slen) 
    236281        pj_strdup(pool, &dst->stun.server, &src->stun.server); 
     282 
     283    for (i = 0; i < src->stun_tp_cnt; ++i) { 
     284        if (src->stun_tp[i].server.slen) 
     285            pj_strdup(pool, &dst->stun_tp[i].server, 
     286                      &src->stun_tp[i].server); 
     287    } 
     288 
    237289    if (src->turn.server.slen) 
    238290        pj_strdup(pool, &dst->turn.server, &src->turn.server); 
    239     pj_stun_auth_cred_dup(pool, &dst->turn.auth_cred, 
    240                           &src->turn.auth_cred); 
     291    pj_stun_auth_cred_dup(pool, &dst->turn.auth_cred, &src->turn.auth_cred); 
     292 
     293    for (i = 0; i < src->turn_tp_cnt; ++i) { 
     294        if (src->turn_tp[i].server.slen) 
     295            pj_strdup(pool, &dst->turn_tp[i].server, 
     296                      &src->turn_tp[i].server); 
     297        pj_stun_auth_cred_dup(pool, &dst->turn_tp[i].auth_cred, 
     298                              &src->turn_tp[i].auth_cred); 
     299    } 
    241300} 
    242301 
     
    246305 */ 
    247306static pj_status_t add_update_turn(pj_ice_strans *ice_st, 
    248                                    pj_ice_strans_comp *comp) 
    249 { 
     307                                   pj_ice_strans_comp *comp, 
     308                                   unsigned idx) 
     309{ 
     310    pj_ice_sess_cand *cand = NULL; 
     311    pj_ice_strans_turn_cfg *turn_cfg = &ice_st->cfg.turn_tp[idx]; 
     312    pj_turn_sock_cfg *sock_cfg  = &turn_cfg->cfg; 
     313    unsigned comp_idx = comp->comp_id - 1; 
    250314    pj_turn_sock_cb turn_sock_cb; 
    251     pj_ice_sess_cand *cand = NULL; 
     315    sock_user_data *data; 
    252316    unsigned i; 
     317    pj_uint8_t tp_id; 
    253318    pj_status_t status; 
    254319 
     320    /* Check if TURN transport is configured */ 
     321    if (turn_cfg->server.slen == 0) 
     322        return PJ_SUCCESS; 
     323 
    255324    /* Find relayed candidate in the component */ 
     325    tp_id = CREATE_TP_ID(TP_TURN, idx); 
    256326    for (i=0; i<comp->cand_cnt; ++i) { 
    257         if (comp->cand_list[i].type == PJ_ICE_CAND_TYPE_RELAYED) { 
     327        if (comp->cand_list[i].transport_id == tp_id) { 
    258328            cand = &comp->cand_list[i]; 
    259329            break; 
     
    287357 
    288358    /* Override with component specific QoS settings, if any */ 
    289     if (ice_st->cfg.comp[comp->comp_id-1].qos_type) { 
    290         ice_st->cfg.turn.cfg.qos_type = 
    291             ice_st->cfg.comp[comp->comp_id-1].qos_type; 
    292     } 
    293     if (ice_st->cfg.comp[comp->comp_id-1].qos_params.flags) { 
    294         pj_memcpy(&ice_st->cfg.turn.cfg.qos_params, 
    295                   &ice_st->cfg.comp[comp->comp_id-1].qos_params, 
    296                   sizeof(ice_st->cfg.turn.cfg.qos_params)); 
    297     } 
     359    if (ice_st->cfg.comp[comp_idx].qos_type) 
     360        sock_cfg->qos_type = ice_st->cfg.comp[comp_idx].qos_type; 
     361    if (ice_st->cfg.comp[comp_idx].qos_params.flags) 
     362        pj_memcpy(&sock_cfg->qos_params, 
     363                  &ice_st->cfg.comp[comp_idx].qos_params, 
     364                  sizeof(sock_cfg->qos_params)); 
    298365 
    299366    /* Override with component specific socket buffer size settings, if any */ 
    300     if (ice_st->cfg.comp[comp->comp_id-1].so_rcvbuf_size > 0) { 
    301         ice_st->cfg.turn.cfg.so_rcvbuf_size = 
    302             ice_st->cfg.comp[comp->comp_id-1].so_rcvbuf_size; 
    303     } 
    304     if (ice_st->cfg.comp[comp->comp_id-1].so_sndbuf_size > 0) { 
    305         ice_st->cfg.turn.cfg.so_sndbuf_size = 
    306             ice_st->cfg.comp[comp->comp_id-1].so_sndbuf_size; 
    307     } 
     367    if (ice_st->cfg.comp[comp_idx].so_rcvbuf_size > 0) 
     368        sock_cfg->so_rcvbuf_size = ice_st->cfg.comp[comp_idx].so_rcvbuf_size; 
     369    if (ice_st->cfg.comp[comp_idx].so_sndbuf_size > 0) 
     370        sock_cfg->so_sndbuf_size = ice_st->cfg.comp[comp_idx].so_sndbuf_size; 
     371 
     372    /* Add relayed candidate with pending status if there's no existing one */ 
     373    if (cand == NULL) { 
     374        cand = &comp->cand_list[comp->cand_cnt]; 
     375        cand->type = PJ_ICE_CAND_TYPE_RELAYED; 
     376        cand->status = PJ_EPENDING; 
     377        cand->local_pref = RELAY_PREF; 
     378        cand->transport_id = CREATE_TP_ID(TP_TURN, idx); 
     379        cand->comp_id = (pj_uint8_t) comp->comp_id; 
     380    } 
     381 
     382    /* Allocate and initialize TURN socket data */ 
     383    data = PJ_POOL_ZALLOC_T(ice_st->pool, sock_user_data); 
     384    data->comp = comp; 
     385    data->transport_id = cand->transport_id; 
    308386 
    309387    /* Create the TURN transport */ 
    310     status = pj_turn_sock_create(&ice_st->cfg.stun_cfg, ice_st->cfg.af, 
    311                                  ice_st->cfg.turn.conn_type, 
    312                                  &turn_sock_cb, &ice_st->cfg.turn.cfg, 
    313                                  comp, &comp->turn_sock); 
     388    status = pj_turn_sock_create(&ice_st->cfg.stun_cfg, turn_cfg->af, 
     389                                 turn_cfg->conn_type, 
     390                                 &turn_sock_cb, sock_cfg, 
     391                                 data, &comp->turn[idx].sock); 
    314392    if (status != PJ_SUCCESS) { 
    315393        return status; 
     
    320398 
    321399    /* Start allocation */ 
    322     status=pj_turn_sock_alloc(comp->turn_sock, 
    323                               &ice_st->cfg.turn.server, 
    324                               ice_st->cfg.turn.port, 
     400    status=pj_turn_sock_alloc(comp->turn[idx].sock, 
     401                              &turn_cfg->server, 
     402                              turn_cfg->port, 
    325403                              ice_st->cfg.resolver, 
    326                               &ice_st->cfg.turn.auth_cred, 
    327                               &ice_st->cfg.turn.alloc_param); 
     404                              &turn_cfg->auth_cred, 
     405                              &turn_cfg->alloc_param); 
    328406    if (status != PJ_SUCCESS) { 
    329407        ///sess_dec_ref(ice_st); 
     
    331409    } 
    332410 
    333     /* Add relayed candidate with pending status if there's no existing one */ 
    334     if (cand == NULL) { 
    335         cand = &comp->cand_list[comp->cand_cnt++]; 
    336         cand->type = PJ_ICE_CAND_TYPE_RELAYED; 
    337         cand->status = PJ_EPENDING; 
    338         cand->local_pref = RELAY_PREF; 
    339         cand->transport_id = TP_TURN; 
    340         cand->comp_id = (pj_uint8_t) comp->comp_id; 
    341     } 
     411    /* Commit the relayed candidate. */ 
     412    comp->cand_cnt++; 
    342413 
    343414    PJ_LOG(4,(ice_st->obj_name, 
     
    373444} 
    374445 
     446 
     447static pj_status_t add_stun_and_host(pj_ice_strans *ice_st, 
     448                                     pj_ice_strans_comp *comp, 
     449                                     unsigned idx) 
     450{ 
     451    pj_ice_sess_cand *cand; 
     452    pj_ice_strans_stun_cfg *stun_cfg = &ice_st->cfg.stun_tp[idx]; 
     453    pj_stun_sock_cfg *sock_cfg  = &stun_cfg->cfg; 
     454    unsigned comp_idx = comp->comp_id - 1; 
     455    pj_stun_sock_cb stun_sock_cb; 
     456    sock_user_data *data; 
     457    pj_status_t status; 
     458 
     459    /* Check if STUN transport or host candidate is configured */ 
     460    if (stun_cfg->server.slen == 0 && stun_cfg->max_host_cands == 0) 
     461        return PJ_SUCCESS; 
     462 
     463    /* Initialize STUN socket callback */ 
     464    pj_bzero(&stun_sock_cb, sizeof(stun_sock_cb)); 
     465    stun_sock_cb.on_rx_data = &stun_on_rx_data; 
     466    stun_sock_cb.on_status = &stun_on_status; 
     467    stun_sock_cb.on_data_sent = &stun_on_data_sent; 
     468 
     469    /* Override component specific QoS settings, if any */ 
     470    if (ice_st->cfg.comp[comp_idx].qos_type) { 
     471        sock_cfg->qos_type = ice_st->cfg.comp[comp_idx].qos_type; 
     472    } 
     473    if (ice_st->cfg.comp[comp_idx].qos_params.flags) { 
     474        pj_memcpy(&sock_cfg->qos_params, 
     475                  &ice_st->cfg.comp[comp_idx].qos_params, 
     476                  sizeof(sock_cfg->qos_params)); 
     477    } 
     478 
     479    /* Override component specific socket buffer size settings, if any */ 
     480    if (ice_st->cfg.comp[comp_idx].so_rcvbuf_size > 0) { 
     481        sock_cfg->so_rcvbuf_size = ice_st->cfg.comp[comp_idx].so_rcvbuf_size; 
     482    } 
     483    if (ice_st->cfg.comp[comp_idx].so_sndbuf_size > 0) { 
     484        sock_cfg->so_sndbuf_size = ice_st->cfg.comp[comp_idx].so_sndbuf_size; 
     485    } 
     486 
     487    /* Prepare srflx candidate with pending status. */ 
     488    cand = &comp->cand_list[comp->cand_cnt]; 
     489    cand->type = PJ_ICE_CAND_TYPE_SRFLX; 
     490    cand->status = PJ_EPENDING; 
     491    cand->local_pref = SRFLX_PREF; 
     492    cand->transport_id = CREATE_TP_ID(TP_STUN, idx); 
     493    cand->comp_id = (pj_uint8_t) comp->comp_id; 
     494 
     495    /* Allocate and initialize STUN socket data */ 
     496    data = PJ_POOL_ZALLOC_T(ice_st->pool, sock_user_data); 
     497    data->comp = comp; 
     498    data->transport_id = cand->transport_id; 
     499 
     500    /* Create the STUN transport */ 
     501    status = pj_stun_sock_create(&ice_st->cfg.stun_cfg, NULL, 
     502                                 stun_cfg->af, &stun_sock_cb, 
     503                                 sock_cfg, data, &comp->stun[idx].sock); 
     504    if (status != PJ_SUCCESS) 
     505        return status; 
     506 
     507    /* Start STUN Binding resolution and add srflx candidate 
     508     * only if server is set 
     509     */ 
     510    if (stun_cfg->server.slen) { 
     511        pj_stun_sock_info stun_sock_info; 
     512 
     513        /* Add pending job */ 
     514        ///sess_add_ref(ice_st); 
     515 
     516        PJ_LOG(4,(ice_st->obj_name, 
     517                  "Comp %d: srflx candidate starts Binding discovery", 
     518                  comp->comp_id)); 
     519 
     520        pj_log_push_indent(); 
     521 
     522        /* Start Binding resolution */ 
     523        status = pj_stun_sock_start(comp->stun[idx].sock, &stun_cfg->server, 
     524                                    stun_cfg->port, ice_st->cfg.resolver); 
     525        if (status != PJ_SUCCESS) { 
     526            ///sess_dec_ref(ice_st); 
     527            pj_log_pop_indent(); 
     528            return status; 
     529        } 
     530 
     531        /* Enumerate addresses */ 
     532        status = pj_stun_sock_get_info(comp->stun[idx].sock, &stun_sock_info); 
     533        if (status != PJ_SUCCESS) { 
     534            ///sess_dec_ref(ice_st); 
     535            pj_log_pop_indent(); 
     536            return status; 
     537        } 
     538 
     539        /* Update and commit the srflx candidate. */ 
     540        pj_sockaddr_cp(&cand->base_addr, &stun_sock_info.aliases[0]); 
     541        pj_sockaddr_cp(&cand->rel_addr, &cand->base_addr); 
     542        pj_ice_calc_foundation(ice_st->pool, &cand->foundation, 
     543                               cand->type, &cand->base_addr); 
     544        comp->cand_cnt++; 
     545 
     546        /* Set default candidate to srflx */ 
     547        comp->default_cand = (unsigned)(cand - comp->cand_list); 
     548 
     549        pj_log_pop_indent(); 
     550    } 
     551 
     552    /* Add local addresses to host candidates, unless max_host_cands 
     553     * is set to zero. 
     554     */ 
     555    if (stun_cfg->max_host_cands) { 
     556        pj_stun_sock_info stun_sock_info; 
     557        unsigned i; 
     558 
     559        /* Enumerate addresses */ 
     560        status = pj_stun_sock_get_info(comp->stun[idx].sock, &stun_sock_info); 
     561        if (status != PJ_SUCCESS) 
     562            return status; 
     563 
     564        for (i=0; i<stun_sock_info.alias_cnt && 
     565                  i<stun_cfg->max_host_cands; ++i) 
     566        { 
     567            unsigned j; 
     568            pj_bool_t cand_duplicate = PJ_FALSE; 
     569            char addrinfo[PJ_INET6_ADDRSTRLEN+10]; 
     570            const pj_sockaddr *addr = &stun_sock_info.aliases[i]; 
     571 
     572            /* Leave one candidate for relay */ 
     573            if (comp->cand_cnt >= PJ_ICE_ST_MAX_CAND-1) { 
     574                PJ_LOG(4,(ice_st->obj_name, "Too many host candidates")); 
     575                break; 
     576            } 
     577 
     578            /* Ignore loopback addresses if cfg->stun.loop_addr is unset */ 
     579            if (stun_cfg->loop_addr==PJ_FALSE) { 
     580                if (stun_cfg->af == pj_AF_INET() &&  
     581                    (pj_ntohl(addr->ipv4.sin_addr.s_addr)>>24)==127) 
     582                { 
     583                    continue; 
     584                } 
     585                else if (stun_cfg->af == pj_AF_INET6()) { 
     586                    pj_in6_addr in6addr = {0}; 
     587                    in6addr.s6_addr[15] = 1; 
     588                    if (pj_memcmp(&in6addr, &addr->ipv6.sin6_addr, 
     589                                  sizeof(in6addr))==0) 
     590                    { 
     591                        continue; 
     592                    } 
     593                } 
     594            } 
     595 
     596            cand = &comp->cand_list[comp->cand_cnt]; 
     597 
     598            cand->type = PJ_ICE_CAND_TYPE_HOST; 
     599            cand->status = PJ_SUCCESS; 
     600            cand->local_pref = HOST_PREF; 
     601            cand->transport_id = CREATE_TP_ID(TP_STUN, idx); 
     602            cand->comp_id = (pj_uint8_t) comp->comp_id; 
     603            pj_sockaddr_cp(&cand->addr, addr); 
     604            pj_sockaddr_cp(&cand->base_addr, addr); 
     605            pj_bzero(&cand->rel_addr, sizeof(cand->rel_addr)); 
     606             
     607            /* Check if not already in list */ 
     608            for (j=0; j<comp->cand_cnt; j++) { 
     609                if (ice_cand_equals(cand, &comp->cand_list[j])) { 
     610                    cand_duplicate = PJ_TRUE; 
     611                    break; 
     612                } 
     613            } 
     614 
     615            if (cand_duplicate) { 
     616                PJ_LOG(4, (ice_st->obj_name, 
     617                       "Comp %d: host candidate %s is a duplicate", 
     618                       comp->comp_id, pj_sockaddr_print(&cand->addr, addrinfo, 
     619                       sizeof(addrinfo), 3))); 
     620 
     621                pj_bzero(&cand->addr, sizeof(cand->addr)); 
     622                pj_bzero(&cand->base_addr, sizeof(cand->base_addr)); 
     623                continue; 
     624            } else { 
     625                comp->cand_cnt+=1; 
     626            } 
     627             
     628            pj_ice_calc_foundation(ice_st->pool, &cand->foundation, 
     629                                   cand->type, &cand->base_addr); 
     630 
     631            PJ_LOG(4,(ice_st->obj_name, 
     632                      "Comp %d: host candidate %s added", 
     633                      comp->comp_id, pj_sockaddr_print(&cand->addr, addrinfo, 
     634                                                      sizeof(addrinfo), 3))); 
     635        } 
     636    } 
     637 
     638    return PJ_SUCCESS; 
     639} 
     640 
     641 
    375642/* 
    376643 * Create the component. 
     
    379646{ 
    380647    pj_ice_strans_comp *comp = NULL; 
     648    unsigned i; 
    381649    pj_status_t status; 
    382650 
     
    398666 
    399667    /* Create STUN transport if configured */ 
    400     if (ice_st->cfg.stun.server.slen || ice_st->cfg.stun.max_host_cands) { 
    401         pj_stun_sock_cb stun_sock_cb; 
    402         pj_ice_sess_cand *cand; 
    403  
    404         pj_bzero(&stun_sock_cb, sizeof(stun_sock_cb)); 
    405         stun_sock_cb.on_rx_data = &stun_on_rx_data; 
    406         stun_sock_cb.on_status = &stun_on_status; 
    407         stun_sock_cb.on_data_sent = &stun_on_data_sent; 
    408  
    409         /* Override component specific QoS settings, if any */ 
    410         if (ice_st->cfg.comp[comp_id-1].qos_type) { 
    411             ice_st->cfg.stun.cfg.qos_type = 
    412                 ice_st->cfg.comp[comp_id-1].qos_type; 
    413         } 
    414         if (ice_st->cfg.comp[comp_id-1].qos_params.flags) { 
    415             pj_memcpy(&ice_st->cfg.stun.cfg.qos_params, 
    416                       &ice_st->cfg.comp[comp_id-1].qos_params, 
    417                       sizeof(ice_st->cfg.stun.cfg.qos_params)); 
    418         } 
    419  
    420         /* Override component specific socket buffer size settings, if any */ 
    421         if (ice_st->cfg.comp[comp_id-1].so_rcvbuf_size > 0) { 
    422             ice_st->cfg.stun.cfg.so_rcvbuf_size = 
    423                 ice_st->cfg.comp[comp_id-1].so_rcvbuf_size; 
    424         } 
    425         if (ice_st->cfg.comp[comp_id-1].so_sndbuf_size > 0) { 
    426             ice_st->cfg.stun.cfg.so_sndbuf_size = 
    427                 ice_st->cfg.comp[comp_id-1].so_sndbuf_size; 
    428         } 
    429  
    430         /* Create the STUN transport */ 
    431         status = pj_stun_sock_create(&ice_st->cfg.stun_cfg, NULL, 
    432                                      ice_st->cfg.af, &stun_sock_cb, 
    433                                      &ice_st->cfg.stun.cfg, 
    434                                      comp, &comp->stun_sock); 
     668    for (i=0; i<ice_st->cfg.stun_tp_cnt; ++i) { 
     669        status = add_stun_and_host(ice_st, comp, i); 
    435670        if (status != PJ_SUCCESS) 
    436671            return status; 
    437  
    438         /* Start STUN Binding resolution and add srflx candidate 
    439          * only if server is set 
    440          */ 
    441         if (ice_st->cfg.stun.server.slen) { 
    442             pj_stun_sock_info stun_sock_info; 
    443  
    444             /* Add pending job */ 
    445             ///sess_add_ref(ice_st); 
    446  
    447             PJ_LOG(4,(ice_st->obj_name, 
    448                       "Comp %d: srflx candidate starts Binding discovery", 
    449                       comp_id)); 
    450  
    451             pj_log_push_indent(); 
    452  
    453             /* Start Binding resolution */ 
    454             status = pj_stun_sock_start(comp->stun_sock, 
    455                                         &ice_st->cfg.stun.server, 
    456                                         ice_st->cfg.stun.port, 
    457                                         ice_st->cfg.resolver); 
    458             if (status != PJ_SUCCESS) { 
    459                 ///sess_dec_ref(ice_st); 
    460                 pj_log_pop_indent(); 
    461                 return status; 
    462             } 
    463  
    464             /* Enumerate addresses */ 
    465             status = pj_stun_sock_get_info(comp->stun_sock, &stun_sock_info); 
    466             if (status != PJ_SUCCESS) { 
    467                 ///sess_dec_ref(ice_st); 
    468                 pj_log_pop_indent(); 
    469                 return status; 
    470             } 
    471  
    472             /* Add srflx candidate with pending status. */ 
    473             cand = &comp->cand_list[comp->cand_cnt++]; 
    474             cand->type = PJ_ICE_CAND_TYPE_SRFLX; 
    475             cand->status = PJ_EPENDING; 
    476             cand->local_pref = SRFLX_PREF; 
    477             cand->transport_id = TP_STUN; 
    478             cand->comp_id = (pj_uint8_t) comp_id; 
    479             pj_sockaddr_cp(&cand->base_addr, &stun_sock_info.aliases[0]); 
    480             pj_sockaddr_cp(&cand->rel_addr, &cand->base_addr); 
    481             pj_ice_calc_foundation(ice_st->pool, &cand->foundation, 
    482                                    cand->type, &cand->base_addr); 
    483  
    484             /* Set default candidate to srflx */ 
    485             comp->default_cand = (unsigned)(cand - comp->cand_list); 
    486  
    487             pj_log_pop_indent(); 
    488         } 
    489  
    490         /* Add local addresses to host candidates, unless max_host_cands 
    491          * is set to zero. 
    492          */ 
    493         if (ice_st->cfg.stun.max_host_cands) { 
    494             pj_stun_sock_info stun_sock_info; 
    495             unsigned i; 
    496  
    497             /* Enumerate addresses */ 
    498             status = pj_stun_sock_get_info(comp->stun_sock, &stun_sock_info); 
    499             if (status != PJ_SUCCESS) 
    500                 return status; 
    501  
    502             for (i=0; i<stun_sock_info.alias_cnt && 
    503                       i<ice_st->cfg.stun.max_host_cands; ++i) 
    504             { 
    505                 unsigned j; 
    506                 pj_bool_t cand_duplicate = PJ_FALSE; 
    507                 char addrinfo[PJ_INET6_ADDRSTRLEN+10]; 
    508                 const pj_sockaddr *addr = &stun_sock_info.aliases[i]; 
    509  
    510                 /* Leave one candidate for relay */ 
    511                 if (comp->cand_cnt >= PJ_ICE_ST_MAX_CAND-1) { 
    512                     PJ_LOG(4,(ice_st->obj_name, "Too many host candidates")); 
    513                     break; 
    514                 } 
    515  
    516                 /* Ignore loopback addresses unless cfg->stun.loop_addr 
    517                  * is set 
    518                  */ 
    519                 if ((pj_ntohl(addr->ipv4.sin_addr.s_addr)>>24)==127) { 
    520                     if (ice_st->cfg.stun.loop_addr==PJ_FALSE) 
    521                         continue; 
    522                 } 
    523  
    524                 cand = &comp->cand_list[comp->cand_cnt]; 
    525  
    526                 cand->type = PJ_ICE_CAND_TYPE_HOST; 
    527                 cand->status = PJ_SUCCESS; 
    528                 cand->local_pref = HOST_PREF; 
    529                 cand->transport_id = TP_STUN; 
    530                 cand->comp_id = (pj_uint8_t) comp_id; 
    531                 pj_sockaddr_cp(&cand->addr, addr); 
    532                 pj_sockaddr_cp(&cand->base_addr, addr); 
    533                 pj_bzero(&cand->rel_addr, sizeof(cand->rel_addr)); 
    534              
    535                 /* Check if not already in list */ 
    536                 for (j=0; j<comp->cand_cnt; j++) { 
    537                     if (ice_cand_equals(cand, &comp->cand_list[j])) { 
    538                         cand_duplicate = PJ_TRUE; 
    539                         break; 
    540                     } 
    541                 } 
    542  
    543                 if (cand_duplicate) { 
    544                     PJ_LOG(4, (ice_st->obj_name, 
    545                            "Comp %d: host candidate %s is a duplicate", 
    546                            comp_id, pj_sockaddr_print(&cand->addr, addrinfo, 
    547                            sizeof(addrinfo), 3))); 
    548  
    549                     pj_bzero(&cand->addr, sizeof(cand->addr)); 
    550                     pj_bzero(&cand->base_addr, sizeof(cand->base_addr)); 
    551                     continue; 
    552                 } else { 
    553                     comp->cand_cnt+=1; 
    554                 } 
    555              
    556                 pj_ice_calc_foundation(ice_st->pool, &cand->foundation, 
    557                                        cand->type, &cand->base_addr); 
    558  
    559                 PJ_LOG(4,(ice_st->obj_name, 
    560                           "Comp %d: host candidate %s added", 
    561                           comp_id, pj_sockaddr_print(&cand->addr, addrinfo, 
    562                                                      sizeof(addrinfo), 3))); 
    563             } 
    564         } 
    565672    } 
    566673 
    567674    /* Create TURN relay if configured. */ 
    568     if (ice_st->cfg.turn.server.slen) { 
    569         add_update_turn(ice_st, comp); 
     675    for (i=0; i<ice_st->cfg.turn_tp_cnt; ++i) { 
     676        status = add_update_turn(ice_st, comp, i); 
     677        if (status != PJ_SUCCESS) 
     678            return status; 
    570679    } 
    571680 
     
    630739 
    631740    pj_ice_strans_cfg_copy(pool, &ice_st->cfg, cfg); 
    632     ice_st->cfg.stun.cfg.grp_lock = ice_st->grp_lock; 
    633     ice_st->cfg.turn.cfg.grp_lock = ice_st->grp_lock; 
     741 
     742    /* To maintain backward compatibility, check if old/deprecated setting is set 
     743     * and the new setting is not, copy the value to the new setting. 
     744     */ 
     745    if (cfg->stun_tp_cnt == 0 &&  
     746        (cfg->stun.server.slen || cfg->stun.max_host_cands)) 
     747    { 
     748        ice_st->cfg.stun_tp_cnt = 1; 
     749        ice_st->cfg.stun_tp[0] = ice_st->cfg.stun; 
     750    } 
     751    if (cfg->turn_tp_cnt == 0 && cfg->turn.server.slen) { 
     752        ice_st->cfg.turn_tp_cnt = 1; 
     753        ice_st->cfg.turn_tp[0] = ice_st->cfg.turn; 
     754    } 
     755 
     756    for (i=0; i<ice_st->cfg.stun_tp_cnt; ++i) 
     757        ice_st->cfg.stun_tp[i].cfg.grp_lock = ice_st->grp_lock; 
     758    for (i=0; i<ice_st->cfg.turn_tp_cnt; ++i) 
     759        ice_st->cfg.turn_tp[i].cfg.grp_lock = ice_st->grp_lock; 
    634760    pj_memcpy(&ice_st->cb, cb, sizeof(*cb)); 
    635761 
     
    709835    for (i=0; i<ice_st->comp_cnt; ++i) { 
    710836        if (ice_st->comp[i]) { 
    711             if (ice_st->comp[i]->stun_sock) { 
    712                 pj_stun_sock_destroy(ice_st->comp[i]->stun_sock); 
    713                 ice_st->comp[i]->stun_sock = NULL; 
     837            pj_ice_strans_comp *comp = ice_st->comp[i]; 
     838            unsigned j; 
     839            for (j = 0; j < ice_st->cfg.stun_tp_cnt; ++j) { 
     840                if (comp->stun[j].sock) { 
     841                    pj_stun_sock_destroy(comp->stun[j].sock); 
     842                    comp->stun[j].sock = NULL; 
     843                } 
    714844            } 
    715             if (ice_st->comp[i]->turn_sock) { 
    716                 pj_turn_sock_destroy(ice_st->comp[i]->turn_sock); 
    717                 ice_st->comp[i]->turn_sock = NULL; 
     845            for (j = 0; j < ice_st->cfg.turn_tp_cnt; ++j) { 
     846                if (comp->turn[j].sock) { 
     847                    pj_turn_sock_destroy(comp->turn[j].sock); 
     848                    comp->turn[j].sock = NULL; 
     849                } 
    718850            } 
    719851        } 
     
    9121044 
    9131045        /* Re-enable logging for Send/Data indications */ 
    914         if (comp->turn_sock) { 
     1046        if (ice_st->cfg.turn_tp_cnt) { 
    9151047            PJ_LOG(5,(ice_st->obj_name, 
    916                       "Disabling STUN Indication logging for " 
     1048                      "Enabling STUN Indication logging for " 
    9171049                      "component %d", i+1)); 
    918             pj_turn_sock_set_log(comp->turn_sock, 0xFFFF); 
    919             comp->turn_log_off = PJ_FALSE; 
     1050        } 
     1051        for (j = 0; j < ice_st->cfg.turn_tp_cnt; ++j) { 
     1052            if (comp->turn[j].sock) { 
     1053                pj_turn_sock_set_log(comp->turn[j].sock, 0xFFFF); 
     1054                comp->turn[j].log_off = PJ_FALSE; 
     1055            } 
    9201056        } 
    9211057 
     
    11231259                                             const pj_ice_sess_cand rem_cand[]) 
    11241260{ 
     1261    unsigned n; 
    11251262    pj_status_t status; 
    11261263 
     
    11381275 
    11391276    /* If we have TURN candidate, now is the time to create the permissions */ 
    1140     if (ice_st->comp[0]->turn_sock) { 
     1277    for (n = 0; n < ice_st->cfg.turn_tp_cnt; ++n) { 
    11411278        unsigned i; 
    11421279 
     
    11481285            /* Gather remote addresses for this component */ 
    11491286            for (j=0; j<rem_cand_cnt && count<PJ_ARRAY_SIZE(addrs); ++j) { 
    1150                 if (rem_cand[j].comp_id==i+1) { 
    1151                     pj_memcpy(&addrs[count++], &rem_cand[j].addr, 
    1152                               pj_sockaddr_get_len(&rem_cand[j].addr)); 
     1287                if (rem_cand[j].comp_id==i+1 && 
     1288                    rem_cand[j].addr.addr.sa_family== 
     1289                    ice_st->cfg.turn_tp[n].af) 
     1290                { 
     1291                    pj_sockaddr_cp(&addrs[count++], &rem_cand[j].addr); 
    11531292                } 
    11541293            } 
    11551294 
    11561295            if (count) { 
    1157                 status = pj_turn_sock_set_perm(comp->turn_sock, count, 
     1296                status = pj_turn_sock_set_perm(comp->turn[n].sock, count, 
    11581297                                               addrs, 0); 
    11591298                if (status != PJ_SUCCESS) { 
     
    12281367{ 
    12291368    pj_ice_strans_comp *comp; 
    1230     unsigned def_cand; 
     1369    pj_ice_sess_cand *def_cand; 
    12311370    pj_status_t status; 
    12321371 
     
    12371376 
    12381377    /* Check that default candidate for the component exists */ 
    1239     def_cand = comp->default_cand; 
    1240     if (def_cand >= comp->cand_cnt) 
     1378    if (comp->default_cand >= comp->cand_cnt) 
    12411379        return PJ_EINVALIDOP; 
    12421380 
     
    12621400     
    12631401    pj_grp_lock_release(ice_st->grp_lock); 
     1402 
     1403    def_cand = &comp->cand_list[comp->default_cand]; 
    12641404     
    1265     if (comp->cand_list[def_cand].status == PJ_SUCCESS) { 
    1266  
    1267         if (comp->cand_list[def_cand].type == PJ_ICE_CAND_TYPE_RELAYED) { 
     1405    if (def_cand->status == PJ_SUCCESS) { 
     1406        unsigned tp_idx = GET_TP_IDX(def_cand->transport_id); 
     1407 
     1408        if (def_cand->type == PJ_ICE_CAND_TYPE_RELAYED) { 
    12681409 
    12691410            enum { 
     
    12741415 
    12751416            /* https://trac.pjsip.org/repos/ticket/1316 */ 
    1276             if (comp->turn_sock == NULL) { 
     1417            if (comp->turn[tp_idx].sock == NULL) { 
    12771418                /* TURN socket error */ 
    12781419                return PJ_EINVALIDOP; 
    12791420            } 
    12801421 
    1281             if (!comp->turn_log_off) { 
     1422            if (!comp->turn[tp_idx].log_off) { 
    12821423                /* Disable logging for Send/Data indications */ 
    12831424                PJ_LOG(5,(ice_st->obj_name, 
    12841425                          "Disabling STUN Indication logging for " 
    12851426                          "component %d", comp->comp_id)); 
    1286                 pj_turn_sock_set_log(comp->turn_sock, msg_disable_ind); 
    1287                 comp->turn_log_off = PJ_TRUE; 
     1427                pj_turn_sock_set_log(comp->turn[tp_idx].sock, 
     1428                                     msg_disable_ind); 
     1429                comp->turn[tp_idx].log_off = PJ_TRUE; 
    12881430            } 
    12891431 
    1290             status = pj_turn_sock_sendto(comp->turn_sock, 
     1432            status = pj_turn_sock_sendto(comp->turn[tp_idx].sock, 
    12911433                                         (const pj_uint8_t*)data, 
    12921434                                         (unsigned)data_len, 
     
    12951437                    PJ_SUCCESS : status; 
    12961438        } else { 
    1297             status = pj_stun_sock_sendto(comp->stun_sock, NULL, data, 
     1439            status = pj_stun_sock_sendto(comp->stun[tp_idx].sock, NULL, data, 
    12981440                                         (unsigned)data_len, 0, dst_addr, 
    12991441                                         dst_addr_len); 
     
    13431485            for (i=0; i<ice_st->comp_cnt; ++i) { 
    13441486                const pj_ice_sess_check *check; 
     1487                pj_ice_strans_comp *comp = ice_st->comp[i]; 
    13451488 
    13461489                check = pj_ice_strans_get_valid_pair(ice_st, i+1); 
     
    13481491                    char lip[PJ_INET6_ADDRSTRLEN+10]; 
    13491492                    char rip[PJ_INET6_ADDRSTRLEN+10]; 
     1493                    unsigned tp_idx = GET_TP_IDX(check->lcand->transport_id); 
     1494                    unsigned tp_typ = GET_TP_TYPE(check->lcand->transport_id); 
    13501495 
    13511496                    pj_sockaddr_print(&check->lcand->addr, lip, 
     
    13541499                                      sizeof(rip), 3); 
    13551500 
    1356                     if (check->lcand->transport_id == TP_TURN) { 
     1501                    if (tp_typ == TP_TURN) { 
    13571502                        /* Activate channel binding for the remote address 
    13581503                         * for more efficient data transfer using TURN. 
    13591504                         */ 
    13601505                        status = pj_turn_sock_bind_channel( 
    1361                                         ice_st->comp[i]->turn_sock, 
     1506                                        comp->turn[tp_idx].sock, 
    13621507                                        &check->rcand->addr, 
    13631508                                        sizeof(check->rcand->addr)); 
     
    13671512                                  "Disabling STUN Indication logging for " 
    13681513                                  "component %d", i+1)); 
    1369                         pj_turn_sock_set_log(ice_st->comp[i]->turn_sock, 
     1514                        pj_turn_sock_set_log(comp->turn[tp_idx].sock, 
    13701515                                             msg_disable_ind); 
    1371                         ice_st->comp[i]->turn_log_off = PJ_TRUE; 
     1516                        comp->turn[tp_idx].log_off = PJ_TRUE; 
    13721517                    } 
    13731518 
     
    14171562    char daddr[PJ_INET6_ADDRSTRLEN]; 
    14181563#endif 
     1564    unsigned tp_idx = GET_TP_IDX(transport_id); 
     1565    unsigned tp_typ = GET_TP_TYPE(transport_id); 
    14191566 
    14201567    PJ_ASSERT_RETURN(comp_id && comp_id <= ice_st->comp_cnt, PJ_EINVAL); 
     
    14271574               pj_sockaddr_print(dst_addr, daddr, sizeof(addr), 0), 
    14281575               pj_sockaddr_get_port(dst_addr), 
    1429                transport_id)); 
    1430  
    1431     if (transport_id == TP_TURN) { 
    1432         if (comp->turn_sock) { 
    1433             status = pj_turn_sock_sendto(comp->turn_sock, 
     1576               tp_typ)); 
     1577 
     1578    if (tp_typ == TP_TURN) { 
     1579        if (comp->turn[tp_idx].sock) { 
     1580            status = pj_turn_sock_sendto(comp->turn[tp_idx].sock, 
    14341581                                         (const pj_uint8_t*)pkt, 
    14351582                                         (unsigned)size, 
     
    14381585            status = PJ_EINVALIDOP; 
    14391586        } 
    1440     } else if (transport_id == TP_STUN) { 
    1441         status = pj_stun_sock_sendto(comp->stun_sock, NULL, 
     1587    } else if (tp_typ == TP_STUN) { 
     1588        status = pj_stun_sock_sendto(comp->stun[tp_idx].sock, NULL, 
    14421589                                     pkt, (unsigned)size, 0, 
    14431590                                     dst_addr, dst_addr_len); 
     
    14791626                                 unsigned addr_len) 
    14801627{ 
     1628    sock_user_data *data; 
    14811629    pj_ice_strans_comp *comp; 
    14821630    pj_ice_strans *ice_st; 
    14831631    pj_status_t status; 
    14841632 
    1485     comp = (pj_ice_strans_comp*) pj_stun_sock_get_user_data(stun_sock); 
    1486     if (comp == NULL) { 
     1633    data = (sock_user_data*) pj_stun_sock_get_user_data(stun_sock); 
     1634    if (data == NULL) { 
    14871635        /* We have disassociated ourselves from the STUN socket */ 
    14881636        return PJ_FALSE; 
    14891637    } 
    14901638 
     1639    comp = data->comp; 
    14911640    ice_st = comp->ice_st; 
    14921641 
     
    15071656        /* Hand over the packet to ICE session */ 
    15081657        status = pj_ice_sess_on_rx_pkt(comp->ice_st->ice, comp->comp_id, 
    1509                                        TP_STUN, pkt, pkt_len, 
     1658                                       data->transport_id, 
     1659                                       pkt, pkt_len, 
    15101660                                       src_addr, addr_len); 
    15111661 
     
    15371687                                pj_status_t status) 
    15381688{ 
     1689    sock_user_data *data; 
    15391690    pj_ice_strans_comp *comp; 
    15401691    pj_ice_strans *ice_st; 
    15411692    pj_ice_sess_cand *cand = NULL; 
    15421693    unsigned i; 
     1694    int tp_idx; 
    15431695 
    15441696    pj_assert(status != PJ_EPENDING); 
    15451697 
    1546     comp = (pj_ice_strans_comp*) pj_stun_sock_get_user_data(stun_sock); 
     1698    data = (sock_user_data*) pj_stun_sock_get_user_data(stun_sock); 
     1699    comp = data->comp; 
    15471700    ice_st = comp->ice_st; 
    15481701 
     
    15541707    /* Find the srflx cancidate */ 
    15551708    for (i=0; i<comp->cand_cnt; ++i) { 
    1556         if (comp->cand_list[i].type == PJ_ICE_CAND_TYPE_SRFLX) { 
     1709        if (comp->cand_list[i].type == PJ_ICE_CAND_TYPE_SRFLX && 
     1710            comp->cand_list[i].transport_id == data->transport_id) 
     1711        { 
    15571712            cand = &comp->cand_list[i]; 
    15581713            break; 
     
    15701725    } 
    15711726 
     1727    tp_idx = GET_TP_IDX(data->transport_id); 
     1728 
    15721729    switch (op) { 
    15731730    case PJ_STUN_SOCK_DNS_OP: 
     
    15761733            if (cand) 
    15771734                cand->status = status; 
    1578             if (!ice_st->cfg.stun.ignore_stun_error) { 
     1735            if (!ice_st->cfg.stun_tp[tp_idx].ignore_stun_error) { 
    15791736                sess_fail(ice_st, PJ_ICE_STRANS_OP_INIT, 
    15801737                          "DNS resolution failed", status); 
     
    16561813            if (cand) 
    16571814                cand->status = status; 
    1658             if (!ice_st->cfg.stun.ignore_stun_error || comp->cand_cnt==1) { 
     1815            if (!ice_st->cfg.stun_tp[tp_idx].ignore_stun_error || 
     1816                comp->cand_cnt==1) 
     1817            { 
    16591818                sess_fail(ice_st, PJ_ICE_STRANS_OP_INIT, 
    16601819                          "STUN binding request failed", status); 
     
    16811840            pj_assert(cand != NULL); 
    16821841            cand->status = status; 
    1683             if (!ice_st->cfg.stun.ignore_stun_error) { 
     1842            if (!ice_st->cfg.stun_tp[tp_idx].ignore_stun_error) { 
    16841843                sess_fail(ice_st, PJ_ICE_STRANS_OP_INIT, 
    16851844                          "STUN keep-alive failed", status); 
     
    17021861{ 
    17031862    pj_ice_strans_comp *comp; 
     1863    sock_user_data *data; 
    17041864    pj_status_t status; 
    17051865 
    1706     comp = (pj_ice_strans_comp*) pj_turn_sock_get_user_data(turn_sock); 
    1707     if (comp == NULL) { 
     1866    data = (sock_user_data*) pj_turn_sock_get_user_data(turn_sock); 
     1867    if (data == NULL) { 
    17081868        /* We have disassociated ourselves from the TURN socket */ 
    17091869        return; 
    17101870    } 
     1871 
     1872    comp = data->comp; 
    17111873 
    17121874    pj_grp_lock_add_ref(comp->ice_st->grp_lock); 
     
    17271889        /* Hand over the packet to ICE */ 
    17281890        status = pj_ice_sess_on_rx_pkt(comp->ice_st->ice, comp->comp_id, 
    1729                                        TP_TURN, pkt, pkt_len, 
     1891                                       data->transport_id, pkt, pkt_len, 
    17301892                                       peer_addr, addr_len); 
    17311893 
     
    17461908{ 
    17471909    pj_ice_strans_comp *comp; 
    1748  
    1749     comp = (pj_ice_strans_comp*) pj_turn_sock_get_user_data(turn_sock); 
    1750     if (comp == NULL) { 
     1910    sock_user_data *data; 
     1911    int tp_idx; 
     1912 
     1913    data = (sock_user_data*) pj_turn_sock_get_user_data(turn_sock); 
     1914    if (data == NULL) { 
    17511915        /* Not interested in further state notification once the relay is 
    17521916         * disconnecting. 
     
    17541918        return; 
    17551919    } 
     1920 
     1921    comp = data->comp; 
     1922    tp_idx = GET_TP_IDX(data->transport_id); 
    17561923 
    17571924    PJ_LOG(5,(comp->ice_st->obj_name, "TURN client state changed %s --> %s", 
     
    17671934        unsigned i; 
    17681935 
    1769         comp->turn_err_cnt = 0; 
     1936        comp->turn[tp_idx].err_cnt = 0; 
    17701937 
    17711938        /* Get allocation info */ 
     
    17771944        /* Find relayed candidate in the component */ 
    17781945        for (i=0; i<comp->cand_cnt; ++i) { 
    1779             if (comp->cand_list[i].type == PJ_ICE_CAND_TYPE_RELAYED) { 
     1946            if (comp->cand_list[i].type == PJ_ICE_CAND_TYPE_RELAYED && 
     1947                comp->cand_list[i].transport_id == data->transport_id) 
     1948            { 
    17801949                cand = &comp->cand_list[i]; 
    17811950                break; 
     
    18091978        pj_turn_session_info info; 
    18101979 
    1811         ++comp->turn_err_cnt; 
     1980        ++comp->turn[tp_idx].err_cnt; 
    18121981 
    18131982        pj_turn_sock_get_info(turn_sock, &info); 
     
    18151984        /* Unregister ourself from the TURN relay */ 
    18161985        pj_turn_sock_set_user_data(turn_sock, NULL); 
    1817         comp->turn_sock = NULL; 
     1986        comp->turn[tp_idx].sock = NULL; 
    18181987 
    18191988        /* Set session to fail on error. last_status PJ_SUCCESS means normal 
     
    18251994                sess_fail(comp->ice_st, PJ_ICE_STRANS_OP_INIT, 
    18261995                          "TURN allocation failed", info.last_status); 
    1827             } else if (comp->turn_err_cnt > 1) { 
     1996            } else if (comp->turn[tp_idx].err_cnt > 1) { 
    18281997                sess_fail(comp->ice_st, PJ_ICE_STRANS_OP_KEEP_ALIVE, 
    18291998                          "TURN refresh failed", info.last_status); 
     
    18322001                          "Comp %d: TURN allocation failed, retrying", 
    18332002                          comp->comp_id)); 
    1834                 add_update_turn(comp->ice_st, comp); 
     2003                add_update_turn(comp->ice_st, comp, tp_idx); 
    18352004            } 
    18362005        } 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c

    r5326 r5339  
    845845                        pjsip_endpt_get_timer_heap(pjsua_var.endpt)); 
    846846     
    847     ice_cfg.af = pj_AF_INET(); 
    848847    ice_cfg.resolver = pjsua_var.resolver; 
    849848     
    850849    ice_cfg.opt = acc_cfg->ice_cfg.ice_opt; 
     850 
     851    /* Check if STUN transport is configured */ 
     852    if ((pj_sockaddr_has_addr(&pjsua_var.stun_srv) && 
     853         pjsua_media_acc_is_using_stun(call_med->call->acc_id)) || 
     854        acc_cfg->ice_cfg.ice_max_host_cands != 0) 
     855    { 
     856        ice_cfg.stun_tp_cnt = 1; 
     857        pj_ice_strans_stun_cfg_default(&ice_cfg.stun_tp[0]); 
     858    } 
    851859 
    852860    /* Configure STUN settings */ 
     
    855863    { 
    856864        pj_sockaddr_print(&pjsua_var.stun_srv, stunip, sizeof(stunip), 0); 
    857         ice_cfg.stun.server = pj_str(stunip); 
    858         ice_cfg.stun.port = pj_sockaddr_get_port(&pjsua_var.stun_srv); 
     865        ice_cfg.stun_tp[0].server = pj_str(stunip); 
     866        ice_cfg.stun_tp[0].port = pj_sockaddr_get_port(&pjsua_var.stun_srv); 
    859867    } 
    860868    if (acc_cfg->ice_cfg.ice_max_host_cands >= 0) 
    861         ice_cfg.stun.max_host_cands = acc_cfg->ice_cfg.ice_max_host_cands; 
     869        ice_cfg.stun_tp[0].max_host_cands = acc_cfg->ice_cfg.ice_max_host_cands; 
    862870 
    863871    /* Copy binding port setting to STUN setting */ 
    864     pj_sockaddr_init(ice_cfg.af, &ice_cfg.stun.cfg.bound_addr, 
     872    pj_sockaddr_init(ice_cfg.stun_tp[0].af, &ice_cfg.stun_tp[0].cfg.bound_addr, 
    865873                     &cfg->bound_addr, (pj_uint16_t)cfg->port); 
    866     ice_cfg.stun.cfg.port_range = (pj_uint16_t)cfg->port_range; 
    867     if (cfg->port != 0 && ice_cfg.stun.cfg.port_range == 0) 
    868         ice_cfg.stun.cfg.port_range =  
     874    ice_cfg.stun_tp[0].cfg.port_range = (pj_uint16_t)cfg->port_range; 
     875    if (cfg->port != 0 && ice_cfg.stun_tp[0].cfg.port_range == 0) 
     876        ice_cfg.stun_tp[0].cfg.port_range =  
    869877                                 (pj_uint16_t)(pjsua_var.ua_cfg.max_calls * 10); 
    870878 
    871879    /* Copy QoS setting to STUN setting */ 
    872     ice_cfg.stun.cfg.qos_type = cfg->qos_type; 
    873     pj_memcpy(&ice_cfg.stun.cfg.qos_params, &cfg->qos_params, 
     880    ice_cfg.stun_tp[0].cfg.qos_type = cfg->qos_type; 
     881    pj_memcpy(&ice_cfg.stun_tp[0].cfg.qos_params, &cfg->qos_params, 
    874882              sizeof(cfg->qos_params)); 
    875883 
    876884    /* Configure TURN settings */ 
    877885    if (acc_cfg->turn_cfg.enable_turn) { 
     886        ice_cfg.turn_tp_cnt = 1; 
     887        pj_ice_strans_turn_cfg_default(&ice_cfg.turn_tp[0]); 
    878888        status = parse_host_port(&acc_cfg->turn_cfg.turn_server, 
    879                                  &ice_cfg.turn.server, 
    880                                  &ice_cfg.turn.port); 
    881         if (status != PJ_SUCCESS || ice_cfg.turn.server.slen == 0) { 
     889                                 &ice_cfg.turn_tp[0].server, 
     890                                 &ice_cfg.turn_tp[0].port); 
     891        if (status != PJ_SUCCESS || ice_cfg.turn_tp[0].server.slen == 0) { 
    882892            PJ_LOG(1,(THIS_FILE, "Invalid TURN server setting")); 
    883893            return PJ_EINVAL; 
    884894        } 
    885         if (ice_cfg.turn.port == 0) 
    886             ice_cfg.turn.port = 3479; 
    887         ice_cfg.turn.conn_type = acc_cfg->turn_cfg.turn_conn_type; 
    888         pj_memcpy(&ice_cfg.turn.auth_cred,  
     895        if (ice_cfg.turn_tp[0].port == 0) 
     896            ice_cfg.turn_tp[0].port = 3479; 
     897        ice_cfg.turn_tp[0].conn_type = acc_cfg->turn_cfg.turn_conn_type; 
     898        pj_memcpy(&ice_cfg.turn_tp[0].auth_cred,  
    889899                  &acc_cfg->turn_cfg.turn_auth_cred, 
    890                   sizeof(ice_cfg.turn.auth_cred)); 
     900                  sizeof(ice_cfg.turn_tp[0].auth_cred)); 
    891901 
    892902        /* Copy QoS setting to TURN setting */ 
    893         ice_cfg.turn.cfg.qos_type = cfg->qos_type; 
    894         pj_memcpy(&ice_cfg.turn.cfg.qos_params, &cfg->qos_params, 
     903        ice_cfg.turn_tp[0].cfg.qos_type = cfg->qos_type; 
     904        pj_memcpy(&ice_cfg.turn_tp[0].cfg.qos_params, &cfg->qos_params, 
    895905                  sizeof(cfg->qos_params)); 
    896906 
    897907        /* Copy binding port setting to TURN setting */ 
    898         pj_sockaddr_init(ice_cfg.af, &ice_cfg.turn.cfg.bound_addr, 
     908        pj_sockaddr_init(ice_cfg.turn_tp[0].af, &ice_cfg.turn_tp[0].cfg.bound_addr, 
    899909                         &cfg->bound_addr, (pj_uint16_t)cfg->port); 
    900         ice_cfg.turn.cfg.port_range = (pj_uint16_t)cfg->port_range; 
    901         if (cfg->port != 0 && ice_cfg.turn.cfg.port_range == 0) 
    902             ice_cfg.turn.cfg.port_range =  
     910        ice_cfg.turn_tp[0].cfg.port_range = (pj_uint16_t)cfg->port_range; 
     911        if (cfg->port != 0 && ice_cfg.turn_tp[0].cfg.port_range == 0) 
     912            ice_cfg.turn_tp[0].cfg.port_range =  
    903913                                 (pj_uint16_t)(pjsua_var.ua_cfg.max_calls * 10); 
    904914    } 
    905915 
    906916    /* Configure packet size for STUN and TURN sockets */ 
    907     ice_cfg.stun.cfg.max_pkt_size = PJMEDIA_MAX_MRU; 
    908     ice_cfg.turn.cfg.max_pkt_size = PJMEDIA_MAX_MRU; 
     917    ice_cfg.stun_tp[0].cfg.max_pkt_size = PJMEDIA_MAX_MRU; 
     918    ice_cfg.turn_tp[0].cfg.max_pkt_size = PJMEDIA_MAX_MRU; 
    909919 
    910920    pj_bzero(&ice_cb, sizeof(pjmedia_ice_cb)); 
Note: See TracChangeset for help on using the changeset viewer.