Ignore:
Timestamp:
Aug 7, 2012 2:18:15 AM (12 years ago)
Author:
bennylp
Message:

Fixed #1412: Account specific NAT settings: STUN, ICE, and TURN

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_acc.c

    r4185 r4218  
    134134    pjsua_transport_config_dup(pool, &dst->rtp_cfg, &src->rtp_cfg); 
    135135 
     136    pjsua_ice_config_dup(pool, &dst->ice_cfg, &src->ice_cfg); 
     137    pjsua_turn_config_dup(pool, &dst->turn_cfg, &src->turn_cfg); 
     138 
    136139    pj_strdup(pool, &dst->ka_data, &src->ka_data); 
    137140} 
     
    284287     */ 
    285288#if PJSUA_ADD_ICE_TAGS 
    286     if (pjsua_var.media_cfg.enable_ice) { 
     289    if (acc_cfg->ice_cfg.enable_ice) { 
    287290        unsigned new_len; 
    288291        pj_str_t new_prm; 
     
    347350            acc->rfc5626_regprm.slen = len; 
    348351        } 
     352    } 
     353 
     354    /* If account's ICE and TURN customization is not set, then 
     355     * initialize it with the settings from the global media config. 
     356     */ 
     357    if (acc->cfg.ice_cfg_use == PJSUA_ICE_CONFIG_USE_DEFAULT) { 
     358        pjsua_ice_config_from_media_config(NULL, &acc->cfg.ice_cfg, 
     359                                        &pjsua_var.media_cfg); 
     360    } 
     361    if (acc->cfg.turn_cfg_use == PJSUA_TURN_CONFIG_USE_DEFAULT) { 
     362        pjsua_turn_config_from_media_config(NULL, &acc->cfg.turn_cfg, 
     363                                            &pjsua_var.media_cfg); 
    349364    } 
    350365 
     
    11531168    } 
    11541169 
     1170    /* Video settings */ 
     1171    acc->cfg.vid_in_auto_show = cfg->vid_in_auto_show; 
     1172    acc->cfg.vid_out_auto_transmit = cfg->vid_out_auto_transmit; 
     1173    acc->cfg.vid_wnd_flags = cfg->vid_wnd_flags; 
     1174    acc->cfg.vid_cap_dev = cfg->vid_cap_dev; 
     1175    acc->cfg.vid_rend_dev = cfg->vid_rend_dev; 
     1176    acc->cfg.vid_stream_rc_cfg = cfg->vid_stream_rc_cfg; 
     1177 
     1178    /* Media settings */ 
     1179    if (pj_stricmp(&acc->cfg.rtp_cfg.public_addr, &cfg->rtp_cfg.public_addr) || 
     1180        pj_stricmp(&acc->cfg.rtp_cfg.bound_addr, &cfg->rtp_cfg.bound_addr)) 
     1181    { 
     1182        pjsua_transport_config_dup(acc->pool, &acc->cfg.rtp_cfg, 
     1183                                   &cfg->rtp_cfg); 
     1184    } else { 
     1185        /* ..to save memory by not using the pool */ 
     1186        acc->cfg.rtp_cfg =  cfg->rtp_cfg; 
     1187    } 
     1188 
     1189    /* STUN and Media customization */ 
     1190    if (acc->cfg.sip_stun_use != cfg->sip_stun_use) { 
     1191        acc->cfg.sip_stun_use = cfg->sip_stun_use; 
     1192        update_reg = PJ_TRUE; 
     1193    } 
     1194    acc->cfg.media_stun_use = cfg->media_stun_use; 
     1195 
     1196    /* ICE settings */ 
     1197    acc->cfg.ice_cfg_use = cfg->ice_cfg_use; 
     1198    switch (acc->cfg.ice_cfg_use) { 
     1199    case PJSUA_ICE_CONFIG_USE_DEFAULT: 
     1200        /* Copy ICE settings from media settings so that we don't need to 
     1201         * check the media config if we look for ICE config. 
     1202         */ 
     1203        pjsua_ice_config_from_media_config(NULL, &acc->cfg.ice_cfg, 
     1204                                        &pjsua_var.media_cfg); 
     1205        break; 
     1206    case PJSUA_ICE_CONFIG_USE_CUSTOM: 
     1207        pjsua_ice_config_dup(acc->pool, &acc->cfg.ice_cfg, &cfg->ice_cfg); 
     1208        break; 
     1209    } 
     1210 
     1211    /* TURN settings */ 
     1212    acc->cfg.turn_cfg_use = cfg->turn_cfg_use; 
     1213    switch (acc->cfg.turn_cfg_use) { 
     1214    case PJSUA_TURN_CONFIG_USE_DEFAULT: 
     1215        /* Copy TURN settings from media settings so that we don't need to 
     1216         * check the media config if we look for TURN config. 
     1217         */ 
     1218        pjsua_turn_config_from_media_config(NULL, &acc->cfg.turn_cfg, 
     1219                                            &pjsua_var.media_cfg); 
     1220        break; 
     1221    case PJSUA_TURN_CONFIG_USE_CUSTOM: 
     1222        pjsua_turn_config_dup(acc->pool, &acc->cfg.turn_cfg, 
     1223                              &cfg->turn_cfg); 
     1224        break; 
     1225    } 
     1226 
     1227    acc->cfg.use_srtp = cfg->use_srtp; 
     1228 
     1229    /* Call hold type */ 
     1230    acc->cfg.call_hold_type = cfg->call_hold_type; 
     1231 
    11551232    /* Unregister first */ 
    11561233    if (unreg_first) { 
     
    11741251        pjsua_start_mwi(acc_id, PJ_TRUE); 
    11751252    } 
    1176  
    1177     /* Video settings */ 
    1178     acc->cfg.vid_in_auto_show = cfg->vid_in_auto_show; 
    1179     acc->cfg.vid_out_auto_transmit = cfg->vid_out_auto_transmit; 
    1180     acc->cfg.vid_wnd_flags = cfg->vid_wnd_flags; 
    1181     acc->cfg.vid_cap_dev = cfg->vid_cap_dev; 
    1182     acc->cfg.vid_rend_dev = cfg->vid_rend_dev; 
    1183  
    1184     /* Call hold type */ 
    1185     acc->cfg.call_hold_type = cfg->call_hold_type; 
    11861253 
    11871254on_return: 
     
    15161583        char *tmp; 
    15171584        const char *beginquote, *endquote; 
     1585        char transport_param[32]; 
    15181586        int len; 
    15191587 
     
    15261594        } 
    15271595 
     1596        /* Don't add transport parameter if it's UDP */ 
     1597        if (tp->key.type != PJSIP_TRANSPORT_UDP && 
     1598                tp->key.type != PJSIP_TRANSPORT_UDP6) 
     1599        { 
     1600            pj_ansi_snprintf(transport_param, sizeof(transport_param), 
     1601                             ";transport=%s", 
     1602                             pjsip_transport_get_type_name(tp->key.type)); 
     1603        } else { 
     1604            transport_param[0] = '\0'; 
     1605        } 
     1606 
    15281607        tmp = (char*) pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE); 
    15291608        len = pj_ansi_snprintf(tmp, PJSIP_MAX_URL_SIZE, 
    1530                                "<sip:%.*s%s%s%.*s%s:%d;transport=%s%.*s%s>%.*s", 
     1609                               "<sip:%.*s%s%s%.*s%s:%d%s%.*s%s>%.*s", 
    15311610                               (int)acc->user_part.slen, 
    15321611                               acc->user_part.ptr, 
     
    15371616                               endquote, 
    15381617                               rport, 
    1539                                tp->type_name, 
     1618                               transport_param, 
    15401619                               (int)acc->cfg.contact_uri_params.slen, 
    15411620                               acc->cfg.contact_uri_params.ptr, 
     
    21472226} 
    21482227 
     2228pj_bool_t pjsua_sip_acc_is_using_stun(pjsua_acc_id acc_id) 
     2229{ 
     2230    pjsua_acc *acc = &pjsua_var.acc[acc_id]; 
     2231 
     2232    return acc->cfg.sip_stun_use != PJSUA_STUN_USE_DISABLED && 
     2233            pjsua_var.ua_cfg.stun_srv_cnt != 0; 
     2234} 
    21492235 
    21502236/* 
     
    21542240                                                pj_bool_t renew) 
    21552241{ 
     2242    pjsua_acc *acc; 
    21562243    pj_status_t status = 0; 
    21572244    pjsip_tx_data *tdata = 0; 
     
    21662253 
    21672254    PJSUA_LOCK(); 
     2255 
     2256    acc = &pjsua_var.acc[acc_id]; 
    21682257 
    21692258    /* Cancel any re-registration timer */ 
     
    22332322                                       &pjsua_var.acc[acc_id].via_addr, 
    22342323                                       pjsua_var.acc[acc_id].via_tp); 
     2324        } else if (!pjsua_sip_acc_is_using_stun(acc_id)) { 
     2325            /* Choose local interface to use in Via if acc is not using 
     2326             * STUN 
     2327             */ 
     2328            pjsua_acc_get_uac_addr(acc_id, tdata->pool, 
     2329                                   &acc->cfg.reg_uri, 
     2330                                   &tdata->via_addr, 
     2331                                   NULL, NULL, 
     2332                                   &tdata->via_tp); 
    22352333        } 
    22362334 
     
    26132711} 
    26142712 
    2615  
    2616 PJ_DEF(pj_status_t) pjsua_acc_create_uac_contact( pj_pool_t *pool, 
    2617                                                   pj_str_t *contact, 
    2618                                                   pjsua_acc_id acc_id, 
    2619                                                   const pj_str_t *suri) 
     2713/* Get local transport address suitable to be used for Via or Contact address 
     2714 * to send request to the specified destination URI. 
     2715 */ 
     2716pj_status_t pjsua_acc_get_uac_addr(pjsua_acc_id acc_id, 
     2717                                   pj_pool_t *pool, 
     2718                                   const pj_str_t *dst_uri, 
     2719                                   pjsip_host_port *addr, 
     2720                                   pjsip_transport_type_e *p_tp_type, 
     2721                                   int *secure, 
     2722                                   const void **p_tp) 
    26202723{ 
    26212724    pjsua_acc *acc; 
     
    26232726    pj_status_t status; 
    26242727    pjsip_transport_type_e tp_type = PJSIP_TRANSPORT_UNSPECIFIED; 
    2625     pj_str_t local_addr; 
     2728    unsigned flag; 
    26262729    pjsip_tpselector tp_sel; 
    2627     unsigned flag; 
    2628     int secure; 
    2629     int local_port; 
    2630     const char *beginquote, *endquote; 
    2631     char transport_param[32]; 
    2632     const char *ob = ";ob"; 
    2633  
    2634      
     2730    pjsip_tpmgr *tpmgr; 
     2731    pjsip_tpmgr_fla2_param tfla2_prm; 
     2732 
    26352733    PJ_ASSERT_RETURN(pjsua_acc_is_valid(acc_id), PJ_EINVAL); 
    26362734    acc = &pjsua_var.acc[acc_id]; 
    26372735 
    2638     /* If force_contact is configured, then use use it */ 
    2639     if (acc->cfg.force_contact.slen) { 
    2640         *contact = acc->cfg.force_contact; 
    2641         return PJ_SUCCESS; 
    2642     } 
    2643  
    2644     /* If route-set is configured for the account, then URI is the  
     2736    /* If route-set is configured for the account, then URI is the 
    26452737     * first entry of the route-set. 
    26462738     */ 
    26472739    if (!pj_list_empty(&acc->route_set)) { 
    2648         sip_uri = (pjsip_sip_uri*)  
     2740        sip_uri = (pjsip_sip_uri*) 
    26492741                  pjsip_uri_get_uri(acc->route_set.next->name_addr.uri); 
    26502742    } else { 
     
    26522744        pjsip_uri *uri; 
    26532745 
    2654         pj_strdup_with_null(pool, &tmp, suri); 
     2746        pj_strdup_with_null(pool, &tmp, dst_uri); 
    26552747 
    26562748        uri = pjsip_parse_uri(pool, tmp.ptr, tmp.slen, 0); 
     
    26722764    } else 
    26732765        tp_type = pjsip_transport_get_type_from_name(&sip_uri->transport_param); 
    2674      
     2766 
    26752767    if (tp_type == PJSIP_TRANSPORT_UNSPECIFIED) 
    26762768        return PJSIP_EUNSUPTRANSPORT; 
     
    26832775 
    26842776    flag = pjsip_transport_get_flag_from_type(tp_type); 
    2685     secure = (flag & PJSIP_TRANSPORT_SECURE) != 0; 
    26862777 
    26872778    /* Init transport selector. */ 
    2688     pjsua_init_tpselector(pjsua_var.acc[acc_id].cfg.transport_id, &tp_sel); 
     2779    pjsua_init_tpselector(acc->cfg.transport_id, &tp_sel); 
    26892780 
    26902781    /* Get local address suitable to send request from */ 
    2691     status = pjsip_tpmgr_find_local_addr(pjsip_endpt_get_tpmgr(pjsua_var.endpt), 
    2692                                          pool, tp_type, &tp_sel,  
    2693                                          &local_addr, &local_port); 
     2782    pjsip_tpmgr_fla2_param_default(&tfla2_prm); 
     2783    tfla2_prm.tp_type = tp_type; 
     2784    tfla2_prm.tp_sel = &tp_sel; 
     2785    tfla2_prm.dst_host = sip_uri->host; 
     2786    tfla2_prm.local_if = (!pjsua_sip_acc_is_using_stun(acc_id) || 
     2787                          (flag & PJSIP_TRANSPORT_RELIABLE)); 
     2788 
     2789    tpmgr = pjsip_endpt_get_tpmgr(pjsua_var.endpt); 
     2790    status = pjsip_tpmgr_find_local_addr2(tpmgr, pool, &tfla2_prm); 
     2791    if (status != PJ_SUCCESS) 
     2792        return status; 
     2793 
     2794    addr->host = tfla2_prm.ret_addr; 
     2795    addr->port = tfla2_prm.ret_port; 
     2796 
     2797    if (p_tp_type) 
     2798        *p_tp_type = tp_type; 
     2799 
     2800    if (secure) { 
     2801        *secure = (flag & PJSIP_TRANSPORT_SECURE) != 0; 
     2802    } 
     2803 
     2804    if (p_tp) 
     2805        *p_tp = tfla2_prm.ret_tp; 
     2806 
     2807    return PJ_SUCCESS; 
     2808} 
     2809 
     2810 
     2811PJ_DEF(pj_status_t) pjsua_acc_create_uac_contact( pj_pool_t *pool, 
     2812                                                  pj_str_t *contact, 
     2813                                                  pjsua_acc_id acc_id, 
     2814                                                  const pj_str_t *suri) 
     2815{ 
     2816    pjsua_acc *acc; 
     2817    pj_status_t status; 
     2818    pjsip_transport_type_e tp_type; 
     2819    pjsip_host_port addr; 
     2820    int secure; 
     2821    const char *beginquote, *endquote; 
     2822    char transport_param[32]; 
     2823    const char *ob = ";ob"; 
     2824 
     2825     
     2826    PJ_ASSERT_RETURN(pjsua_acc_is_valid(acc_id), PJ_EINVAL); 
     2827    acc = &pjsua_var.acc[acc_id]; 
     2828 
     2829    /* If force_contact is configured, then use use it */ 
     2830    if (acc->cfg.force_contact.slen) { 
     2831        *contact = acc->cfg.force_contact; 
     2832        return PJ_SUCCESS; 
     2833    } 
     2834 
     2835    status = pjsua_acc_get_uac_addr(acc_id, pool, suri, &addr, 
     2836                                    &tp_type, &secure, NULL); 
    26942837    if (status != PJ_SUCCESS) 
    26952838        return status; 
     
    27262869                                     (acc->user_part.slen?"@":""), 
    27272870                                     beginquote, 
    2728                                      (int)local_addr.slen, 
    2729                                      local_addr.ptr, 
     2871                                     (int)addr.host.slen, 
     2872                                     addr.host.ptr, 
    27302873                                     endquote, 
    2731                                      local_port, 
     2874                                     addr.port, 
    27322875                                     transport_param, 
    27332876                                     (int)acc->cfg.contact_uri_params.slen, 
     
    27612904    pj_str_t local_addr; 
    27622905    pjsip_tpselector tp_sel; 
     2906    pjsip_tpmgr *tpmgr; 
     2907    pjsip_tpmgr_fla2_param tfla2_prm; 
    27632908    unsigned flag; 
    27642909    int secure; 
     
    28482993 
    28492994    /* Get local address suitable to send request from */ 
    2850     status = pjsip_tpmgr_find_local_addr(pjsip_endpt_get_tpmgr(pjsua_var.endpt), 
    2851                                          pool, tp_type, &tp_sel, 
    2852                                          &local_addr, &local_port); 
     2995    pjsip_tpmgr_fla2_param_default(&tfla2_prm); 
     2996    tfla2_prm.tp_type = tp_type; 
     2997    tfla2_prm.tp_sel = &tp_sel; 
     2998    tfla2_prm.dst_host = sip_uri->host; 
     2999    tfla2_prm.local_if = (!pjsua_sip_acc_is_using_stun(acc_id) || 
     3000                          (flag & PJSIP_TRANSPORT_RELIABLE)); 
     3001 
     3002    tpmgr = pjsip_endpt_get_tpmgr(pjsua_var.endpt); 
     3003    status = pjsip_tpmgr_find_local_addr2(tpmgr, pool, &tfla2_prm); 
    28533004    if (status != PJ_SUCCESS) 
    28543005        return status; 
     3006 
     3007    local_addr = tfla2_prm.ret_addr; 
     3008    local_port = tfla2_prm.ret_port; 
     3009 
    28553010 
    28563011    /* Enclose IPv6 address in square brackets */ 
Note: See TracChangeset for help on using the changeset viewer.