Ignore:
Timestamp:
Aug 18, 2014 8:54:43 AM (10 years ago)
Author:
bennylp
Message:

Closed #1677: Contact uses source port in initial registration.

File:
1 edited

Legend:

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

    r4713 r4888  
    29342934} 
    29352935 
     2936/* 
     2937 * Internal: 
     2938 *  determine if an address is a valid IP address, and if it is, 
     2939 *  return the IP version (4 or 6). 
     2940 */ 
     2941static int get_ip_addr_ver(const pj_str_t *host) 
     2942{ 
     2943    pj_in_addr dummy; 
     2944    pj_in6_addr dummy6; 
     2945 
     2946    /* First check with inet_aton() */ 
     2947    if (pj_inet_aton(host, &dummy) > 0) 
     2948        return 4; 
     2949 
     2950    /* Then check if this is an IPv6 address */ 
     2951    if (pj_inet_pton(pj_AF_INET6(), host, &dummy6) == PJ_SUCCESS) 
     2952        return 6; 
     2953 
     2954    /* Not an IP address */ 
     2955    return 0; 
     2956} 
     2957 
    29362958/* Get local transport address suitable to be used for Via or Contact address 
    29372959 * to send request to the specified destination URI. 
     
    30153037        return status; 
    30163038 
     3039    /* Set this as default return value. This may be changed below 
     3040     * for TCP/TLS 
     3041     */ 
    30173042    addr->host = tfla2_prm.ret_addr; 
    30183043    addr->port = tfla2_prm.ret_port; 
     3044 
     3045    /* For TCP/TLS, acc may request to specify source port */ 
     3046    if (acc->cfg.contact_rewrite_use_src_port) { 
     3047        pjsip_host_info dinfo; 
     3048        pjsip_transport *tp = NULL; 
     3049        pj_addrinfo ai; 
     3050        pj_bool_t log_written = PJ_FALSE; 
     3051 
     3052        status = pjsip_get_dest_info((pjsip_uri*)sip_uri, NULL, 
     3053                                     pool, &dinfo); 
     3054 
     3055        if (status==PJ_SUCCESS && (dinfo.flag & PJSIP_TRANSPORT_RELIABLE)==0) { 
     3056            /* Not TCP or TLS. No need to do this */ 
     3057            status = PJ_EINVALIDOP; 
     3058            log_written = PJ_TRUE; 
     3059        } 
     3060 
     3061        if (status==PJ_SUCCESS && 
     3062            get_ip_addr_ver(&dinfo.addr.host)==0 && 
     3063            pjsua_var.ua_cfg.nameserver_count) 
     3064        { 
     3065            /* If nameserver is configured, PJSIP will resolve destinations 
     3066             * by their DNS SRV record first. On the other hand, we will 
     3067             * resolve destination with DNS A record via pj_getaddrinfo(). 
     3068             * They may yield different IP addresses, hence causing different 
     3069             * TCP/TLS connection to be created and hence different source 
     3070             * address. 
     3071             */ 
     3072            PJ_LOG(4,(THIS_FILE, "Warning: cannot use source TCP/TLS socket" 
     3073                      " address for Contact when nameserver is configured.")); 
     3074            status = PJ_ENOTSUP; 
     3075            log_written = PJ_TRUE; 
     3076        } 
     3077 
     3078        if (status == PJ_SUCCESS) { 
     3079            unsigned cnt=1; 
     3080            int af; 
     3081 
     3082            af = (dinfo.type & PJSIP_TRANSPORT_IPV6)? PJ_AF_INET6 : PJ_AF_INET; 
     3083            status = pj_getaddrinfo(af, &dinfo.addr.host, &cnt, &ai); 
     3084        } 
     3085 
     3086        if (status == PJ_SUCCESS) { 
     3087            int addr_len = pj_sockaddr_get_len(&ai.ai_addr); 
     3088            pj_uint16_t port = dinfo.addr.port; 
     3089 
     3090            if (port==0) { 
     3091                port = (dinfo.flag & PJSIP_TRANSPORT_SECURE) ? 5061 : 5060; 
     3092            } 
     3093            pj_sockaddr_set_port(&ai.ai_addr, port); 
     3094            status = pjsip_endpt_acquire_transport(pjsua_var.endpt, 
     3095                                                   dinfo.type, 
     3096                                                   &ai.ai_addr, 
     3097                                                   addr_len, 
     3098                                                   &tp_sel, &tp); 
     3099        } 
     3100 
     3101        if (status == PJ_SUCCESS && (tp->local_name.port == 0 || 
     3102                                     tp->local_name.host.slen==0 || 
     3103                                     *tp->local_name.host.ptr=='0')) 
     3104        { 
     3105            /* Trap zero port or "0.0.0.0" address. */ 
     3106            /* The TCP/TLS transport is still connecting and unfortunately 
     3107             * this OS doesn't report the bound local address in this state. 
     3108             */ 
     3109            PJ_LOG(4,(THIS_FILE, "Unable to get transport local port " 
     3110                      "for Contact address (OS doesn't support)")); 
     3111            status = PJ_ENOTSUP; 
     3112            log_written = PJ_TRUE; 
     3113        } 
     3114 
     3115        if (status == PJ_SUCCESS) { 
     3116            /* Got the local transport address */ 
     3117            pj_strdup(pool, &addr->host, &tp->local_name.host); 
     3118            addr->port = tp->local_name.port; 
     3119        } 
     3120 
     3121        if (tp) { 
     3122            /* Here the transport's ref counter WILL reach zero. But the 
     3123             * transport will NOT get destroyed because it should have an 
     3124             * idle timer. 
     3125             */ 
     3126            pjsip_transport_dec_ref(tp); 
     3127            tp = NULL; 
     3128        } 
     3129 
     3130        if (status != PJ_SUCCESS && !log_written) { 
     3131            PJ_PERROR(4,(THIS_FILE, status, "Unable to use source local " 
     3132                         "TCP socket address for Contact")); 
     3133        } 
     3134        status = PJ_SUCCESS; 
     3135    } 
    30193136 
    30203137    if (p_tp_type) 
Note: See TracChangeset for help on using the changeset viewer.