Ignore:
Timestamp:
Sep 26, 2006 1:21:02 PM (18 years ago)
Author:
bennylp
Message:

Added support for specifying IP address in PJSUA-LIB/pjsua.
This option can be used for example to select the IP
interface of SIP/RTP/RTCP transports, or to specify the
public IP address of NAT/router in case port forwarding is
used.

For SIP transports, this feature works for both UDP and
TCP transports.

Changes:

  • added public_ip field in pjsua_transport_config, and change SIP and media transport creation to consider this option.
  • added --ip-addr option in pjsua
  • added pjsip_tcp_transport_start2() which allows specifying alternate TCP published address when creating TCP transports.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip/src/pjsip/sip_transport_tcp.c

    r721 r742  
    7070{ 
    7171    pjsip_tpfactory          factory; 
    72     char                     obj_name[PJ_MAX_OBJ_NAME]; 
    7372    pj_bool_t                is_registered; 
    7473    pjsip_endpoint          *endpt; 
     
    185184 * TCP listener. 
    186185 */ 
    187 PJ_DEF(pj_status_t) pjsip_tcp_transport_start( pjsip_endpoint *endpt, 
     186PJ_DEF(pj_status_t) pjsip_tcp_transport_start2(pjsip_endpoint *endpt, 
    188187                                               const pj_sockaddr_in *local, 
     188                                               const pjsip_host_port *a_name, 
    189189                                               unsigned async_cnt, 
    190190                                               pjsip_tpfactory **p_factory) 
     
    201201    PJ_ASSERT_RETURN(endpt && async_cnt, PJ_EINVAL); 
    202202 
     203    /* Verify that address given in a_name (if any) is valid */ 
     204    if (a_name && a_name->host.slen) { 
     205        pj_sockaddr_in tmp; 
     206 
     207        status = pj_sockaddr_in_init(&tmp, &a_name->host,  
     208                                     (pj_uint16_t)a_name->port); 
     209        if (status != PJ_SUCCESS || tmp.sin_addr.s_addr == PJ_INADDR_ANY || 
     210            tmp.sin_addr.s_addr == PJ_INADDR_NONE) 
     211        { 
     212            /* Invalid address */ 
     213            return PJ_EINVAL; 
     214        } 
     215    } 
    203216 
    204217    pool = pjsip_endpt_create_pool(endpt, "tcplis", POOL_LIS_INIT,  
     
    215228    listener->sock = PJ_INVALID_SOCKET; 
    216229 
    217     pj_ansi_strcpy(listener->obj_name, "tcp"); 
     230    pj_ansi_strcpy(listener->factory.obj_name, "tcplis"); 
    218231 
    219232    status = pj_lock_create_recursive_mutex(pool, "tcplis",  
     
    246259        goto on_error; 
    247260 
    248     /* If the address returns 0.0.0.0, use the first interface address 
    249      * as the transport's address. 
     261    /* If published host/IP is specified, then use that address as the 
     262     * listener advertised address. 
    250263     */ 
    251     if (listener_addr->sin_addr.s_addr == 0) { 
    252         pj_in_addr hostip; 
    253  
    254         status = pj_gethostip(&hostip); 
    255         if (status != PJ_SUCCESS) 
    256             goto on_error; 
    257  
    258         listener_addr->sin_addr = hostip; 
    259     } 
    260  
    261     pj_ansi_snprintf(listener->obj_name, sizeof(listener->obj_name),  
    262                      "tcp:%d",  (int)pj_ntohs(listener_addr->sin_port)); 
    263  
    264     /* Save the address name */ 
    265     sockaddr_to_host_port(listener->factory.pool,  
    266                           &listener->factory.addr_name, listener_addr); 
     264    if (a_name && a_name->host.slen) { 
     265        /* Copy the address */ 
     266        listener->factory.addr_name = *a_name; 
     267        pj_strdup(listener->factory.pool, &listener->factory.addr_name.host,  
     268                  &a_name->host); 
     269        listener->factory.addr_name.port = a_name->port; 
     270 
     271    } else { 
     272        /* No published address is given, use the bound address */ 
     273 
     274        /* If the address returns 0.0.0.0, use the default 
     275         * interface address as the transport's address. 
     276         */ 
     277        if (listener_addr->sin_addr.s_addr == 0) { 
     278            pj_in_addr hostip; 
     279 
     280            status = pj_gethostip(&hostip); 
     281            if (status != PJ_SUCCESS) 
     282                goto on_error; 
     283 
     284            listener_addr->sin_addr = hostip; 
     285        } 
     286 
     287        /* Save the address name */ 
     288        sockaddr_to_host_port(listener->factory.pool,  
     289                              &listener->factory.addr_name, listener_addr); 
     290    } 
     291 
     292    /* If port is zero, get the bound port */ 
     293    if (listener->factory.addr_name.port == 0) { 
     294        listener->factory.addr_name.port = pj_ntohs(listener_addr->sin_port); 
     295    } 
     296 
     297    pj_ansi_snprintf(listener->factory.obj_name,  
     298                     sizeof(listener->factory.obj_name), 
     299                     "tcplis:%d",  listener->factory.addr_name.port); 
     300 
    267301 
    268302    /* Start listening to the address */ 
     
    320354    } 
    321355 
    322     PJ_LOG(4,(listener->obj_name,  
    323              "SIP TCP listener ready for incoming connections at %s:%d", 
    324              pj_inet_ntoa(listener_addr->sin_addr),  
    325              (int)pj_ntohs(listener_addr->sin_port))); 
     356    PJ_LOG(4,(listener->factory.obj_name,  
     357             "SIP TCP listener ready for incoming connections at %.*s:%d", 
     358             (int)listener->factory.addr_name.host.slen, 
     359             listener->factory.addr_name.host.ptr, 
     360             listener->factory.addr_name.port)); 
    326361 
    327362    /* Return the pointer to user */ 
     
    333368    lis_destroy(&listener->factory); 
    334369    return status; 
     370} 
     371 
     372 
     373/* 
     374 * This is the public API to create, initialize, register, and start the 
     375 * TCP listener. 
     376 */ 
     377PJ_DEF(pj_status_t) pjsip_tcp_transport_start( pjsip_endpoint *endpt, 
     378                                               const pj_sockaddr_in *local, 
     379                                               unsigned async_cnt, 
     380                                               pjsip_tpfactory **p_factory) 
     381{ 
     382    return pjsip_tcp_transport_start2(endpt, local, NULL, async_cnt, p_factory); 
    335383} 
    336384 
     
    374422        pj_pool_t *pool = listener->factory.pool; 
    375423 
    376         PJ_LOG(4,(listener->obj_name,  "SIP TCP listener destroyed")); 
     424        PJ_LOG(4,(listener->factory.obj_name,  "SIP TCP listener destroyed")); 
    377425 
    378426        listener->factory.pool = NULL; 
     
    856904             * Error in accept(). 
    857905             */ 
    858             tcp_perror(listener->obj_name, "Error in accept()", status); 
     906            tcp_perror(listener->factory.obj_name, "Error in accept()",  
     907                       status); 
    859908 
    860909            /* 
     
    866915            ++err_cnt; 
    867916            if (err_cnt >= 10) { 
    868                 PJ_LOG(1, (listener->obj_name,  
     917                PJ_LOG(1, (listener->factory.obj_name,  
    869918                           "Too many errors, listener stopping")); 
    870919            } 
     
    883932            } 
    884933 
    885             PJ_LOG(4,(listener->obj_name,  
     934            PJ_LOG(4,(listener->factory.obj_name,  
    886935                      "TCP listener %.*s:%d: got incoming TCP connection " 
    887936                      "from %s:%d, sock=%d", 
Note: See TracChangeset for help on using the changeset viewer.