Ignore:
Timestamp:
Sep 20, 2012 6:00:23 AM (12 years ago)
Author:
bennylp
Message:

Fixed #1585: IPv6 support for SIP TCP and TLS transports and PJSUA-LIB v2

File:
1 edited

Legend:

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

    r4260 r4262  
    5858    pjsip_tpmgr             *tpmgr; 
    5959    pj_activesock_t         *asock; 
     60    pj_sockaddr              bound_addr; 
    6061    pj_qos_type              qos_type; 
    6162    pj_qos_params            qos_params; 
     
    142143                              pj_pool_t *pool, 
    143144                              pj_sock_t sock, pj_bool_t is_server, 
    144                               const pj_sockaddr_in *local, 
    145                               const pj_sockaddr_in *remote, 
     145                              const pj_sockaddr *local, 
     146                              const pj_sockaddr *remote, 
    146147                              struct tcp_transport **p_tcp); 
    147148 
     
    160161static void sockaddr_to_host_port( pj_pool_t *pool, 
    161162                                   pjsip_host_port *host_port, 
    162                                    const pj_sockaddr_in *addr ) 
     163                                   const pj_sockaddr *addr ) 
    163164{ 
    164165    host_port->host.ptr = (char*) pj_pool_alloc(pool, PJ_INET6_ADDRSTRLEN+4); 
    165     pj_sockaddr_print(addr, host_port->host.ptr, PJ_INET6_ADDRSTRLEN+4, 2); 
     166    pj_sockaddr_print(addr, host_port->host.ptr, PJ_INET6_ADDRSTRLEN+4, 0); 
    166167    host_port->host.slen = pj_ansi_strlen(host_port->host.ptr); 
    167168    host_port->port = pj_sockaddr_get_port(addr); 
     
    268269    listener = PJ_POOL_ZALLOC_T(pool, struct tcp_listener); 
    269270    listener->factory.pool = pool; 
    270     listener->factory.type = PJSIP_TRANSPORT_TCP; 
    271     listener->factory.type_name = "tcp"; 
     271    listener->factory.type = cfg->af==pj_AF_INET() ? PJSIP_TRANSPORT_TCP : 
     272                                                     PJSIP_TRANSPORT_TCP6; 
     273    listener->factory.type_name = (char*) 
     274                pjsip_transport_get_type_name(listener->factory.type); 
    272275    listener->factory.flag =  
    273         pjsip_transport_get_flag_from_type(PJSIP_TRANSPORT_TCP); 
     276        pjsip_transport_get_flag_from_type(listener->factory.type); 
    274277    listener->qos_type = cfg->qos_type; 
    275278    pj_memcpy(&listener->qos_params, &cfg->qos_params, 
     
    277280 
    278281    pj_ansi_strcpy(listener->factory.obj_name, "tcplis"); 
    279  
    280     status = pj_lock_create_recursive_mutex(pool, "tcplis",  
     282    if (listener->factory.type==PJSIP_TRANSPORT_TCP6) 
     283        pj_ansi_strcat(listener->factory.obj_name, "6"); 
     284 
     285    status = pj_lock_create_recursive_mutex(pool, listener->factory.obj_name, 
    281286                                            &listener->factory.lock); 
    282287    if (status != PJ_SUCCESS) 
     
    293298                                2, listener->factory.obj_name,  
    294299                                "SIP TCP listener socket"); 
     300 
     301    /* Bind address may be different than factory.local_addr because 
     302     * factory.local_addr will be resolved below. 
     303     */ 
     304    pj_sockaddr_cp(&listener->bound_addr, &cfg->bind_addr); 
    295305 
    296306    /* Bind socket */ 
     
    328338            pj_sockaddr hostip; 
    329339 
    330             status = pj_gethostip(pj_AF_INET(), &hostip); 
     340            status = pj_gethostip(listener->bound_addr.addr.sa_family, 
     341                                  &hostip); 
    331342            if (status != PJ_SUCCESS) 
    332343                goto on_error; 
    333344 
    334             pj_memcpy(pj_sockaddr_get_addr(listener_addr), 
    335                       pj_sockaddr_get_addr(&hostip), 
    336                       pj_sockaddr_get_addr_len(&hostip)); 
     345            pj_sockaddr_copy_addr(listener_addr, &hostip); 
    337346        } 
    338347 
     
    340349        sockaddr_to_host_port(listener->factory.pool,  
    341350                              &listener->factory.addr_name,  
    342                               (pj_sockaddr_in*)listener_addr); 
     351                              listener_addr); 
    343352    } 
    344353 
     
    537546                               pj_pool_t *pool, 
    538547                               pj_sock_t sock, pj_bool_t is_server, 
    539                                const pj_sockaddr_in *local, 
    540                                const pj_sockaddr_in *remote, 
     548                               const pj_sockaddr *local, 
     549                               const pj_sockaddr *remote, 
    541550                               struct tcp_transport **p_tcp) 
    542551{ 
     
    546555    pj_activesock_cb tcp_callback; 
    547556    const pj_str_t ka_pkt = PJSIP_TCP_KEEP_ALIVE_DATA; 
     557    char print_addr[PJ_INET6_ADDRSTRLEN+10]; 
    548558    pj_status_t status; 
    549559     
     
    581591    } 
    582592 
    583     tcp->base.key.type = PJSIP_TRANSPORT_TCP; 
    584     pj_memcpy(&tcp->base.key.rem_addr, remote, sizeof(pj_sockaddr_in)); 
    585     tcp->base.type_name = "tcp"; 
    586     tcp->base.flag = pjsip_transport_get_flag_from_type(PJSIP_TRANSPORT_TCP); 
     593    tcp->base.key.type = listener->factory.type; 
     594    pj_sockaddr_cp(&tcp->base.key.rem_addr, remote); 
     595    tcp->base.type_name = (char*) 
     596                          pjsip_transport_get_type_name(tcp->base.key.type); 
     597    tcp->base.flag = pjsip_transport_get_flag_from_type(tcp->base.key.type); 
    587598 
    588599    tcp->base.info = (char*) pj_pool_alloc(pool, 64); 
    589     pj_ansi_snprintf(tcp->base.info, 64, "TCP to %s:%d", 
    590                      pj_inet_ntoa(remote->sin_addr),  
    591                      (int)pj_ntohs(remote->sin_port)); 
    592  
    593     tcp->base.addr_len = sizeof(pj_sockaddr_in); 
    594     pj_memcpy(&tcp->base.local_addr, local, sizeof(pj_sockaddr_in)); 
     600    pj_ansi_snprintf(tcp->base.info, 64, "%s to %s", 
     601                     tcp->base.type_name, 
     602                     pj_sockaddr_print(remote, print_addr, 
     603                                       sizeof(print_addr), 3)); 
     604 
     605    tcp->base.addr_len = pj_sockaddr_get_len(remote); 
     606    pj_sockaddr_cp(&tcp->base.local_addr, local); 
    595607    sockaddr_to_host_port(pool, &tcp->base.local_name, local); 
    596608    sockaddr_to_host_port(pool, &tcp->base.remote_name, remote); 
     
    602614    tcp->base.do_shutdown = &tcp_shutdown; 
    603615    tcp->base.destroy = &tcp_destroy_transport; 
    604  
    605616 
    606617    /* Create active socket */ 
     
    802813    pj_pool_t *pool; 
    803814    pj_ssize_t size; 
    804     pj_sockaddr_in *rem_addr; 
     815    pj_sockaddr *rem_addr; 
    805816    void *readbuf[1]; 
    806817    pj_status_t status; 
     
    825836 
    826837    tcp->rdata.pkt_info.src_addr = tcp->base.key.rem_addr; 
    827     tcp->rdata.pkt_info.src_addr_len = sizeof(pj_sockaddr_in); 
    828     rem_addr = (pj_sockaddr_in*) &tcp->base.key.rem_addr; 
    829     pj_ansi_strcpy(tcp->rdata.pkt_info.src_name, 
    830                    pj_inet_ntoa(rem_addr->sin_addr)); 
    831     tcp->rdata.pkt_info.src_port = pj_ntohs(rem_addr->sin_port); 
     838    tcp->rdata.pkt_info.src_addr_len = sizeof(tcp->rdata.pkt_info.src_addr); 
     839    rem_addr = &tcp->base.key.rem_addr; 
     840    pj_sockaddr_print(rem_addr, tcp->rdata.pkt_info.src_name, 
     841                      sizeof(tcp->rdata.pkt_info.src_name), 0); 
     842    tcp->rdata.pkt_info.src_port = pj_sockaddr_get_port(rem_addr); 
    832843 
    833844    size = sizeof(tcp->rdata.pkt_info.packet); 
     
    859870    struct tcp_transport *tcp; 
    860871    pj_sock_t sock; 
    861     pj_sockaddr_in local_addr; 
     872    pj_sockaddr local_addr; 
    862873    pj_status_t status; 
    863874 
     
    866877                     addr_len && p_transport, PJ_EINVAL); 
    867878 
    868     /* Check that address is a sockaddr_in */ 
    869     PJ_ASSERT_RETURN(rem_addr->addr.sa_family == pj_AF_INET() && 
    870                      addr_len == sizeof(pj_sockaddr_in), PJ_EINVAL); 
     879    /* Check that address is a sockaddr_in or sockaddr_in6*/ 
     880    PJ_ASSERT_RETURN((rem_addr->addr.sa_family == pj_AF_INET() && 
     881                      addr_len == sizeof(pj_sockaddr_in)) || 
     882                     (rem_addr->addr.sa_family == pj_AF_INET6() && 
     883                      addr_len == sizeof(pj_sockaddr_in6)), PJ_EINVAL); 
    871884 
    872885 
    873886    listener = (struct tcp_listener*)factory; 
    874887 
    875      
    876888    /* Create socket */ 
    877     status = pj_sock_socket(pj_AF_INET(), pj_SOCK_STREAM(), 0, &sock); 
     889    status = pj_sock_socket(rem_addr->addr.sa_family, pj_SOCK_STREAM(), 
     890                            0, &sock); 
    878891    if (status != PJ_SUCCESS) 
    879892        return status; 
     
    885898                                "outgoing SIP TCP socket"); 
    886899 
    887     /* Bind to any port */ 
    888     status = pj_sock_bind_in(sock, 0, 0); 
     900    /* Bind to listener's address and any port */ 
     901    pj_bzero(&local_addr, sizeof(local_addr)); 
     902    pj_sockaddr_cp(&local_addr, &listener->bound_addr); 
     903    pj_sockaddr_set_port(&local_addr, 0); 
     904 
     905    status = pj_sock_bind(sock, &local_addr, 
     906                          pj_sockaddr_get_len(&local_addr)); 
    889907    if (status != PJ_SUCCESS) { 
    890908        pj_sock_close(sock); 
     
    893911 
    894912    /* Get the local port */ 
    895     addr_len = sizeof(pj_sockaddr_in); 
     913    addr_len = sizeof(local_addr); 
    896914    status = pj_sock_getsockname(sock, &local_addr, &addr_len); 
    897915    if (status != PJ_SUCCESS) { 
     
    901919 
    902920    /* Initially set the address from the listener's address */ 
    903     local_addr.sin_addr.s_addr =  
    904         ((pj_sockaddr_in*)&listener->factory.local_addr)->sin_addr.s_addr; 
     921    if (!pj_sockaddr_has_addr(&local_addr)) { 
     922        pj_sockaddr_copy_addr(&local_addr, &listener->factory.local_addr); 
     923    } 
    905924 
    906925    /* Create the transport descriptor */ 
    907926    status = tcp_create(listener, NULL, sock, PJ_FALSE, &local_addr,  
    908                         (pj_sockaddr_in*)rem_addr, &tcp); 
     927                        rem_addr, &tcp); 
    909928    if (status != PJ_SUCCESS) 
    910929        return status; 
     
    914933    tcp->has_pending_connect = PJ_TRUE; 
    915934    status = pj_activesock_start_connect(tcp->asock, tcp->base.pool, rem_addr, 
    916                                          sizeof(pj_sockaddr_in)); 
     935                                         addr_len); 
    917936    if (status == PJ_SUCCESS) { 
    918937        on_connect_complete(tcp->asock, PJ_SUCCESS); 
     
    926945         * set is different now that asynchronous connect() is started. 
    927946         */ 
    928         addr_len = sizeof(pj_sockaddr_in); 
     947        addr_len = sizeof(local_addr); 
    929948        if (pj_sock_getsockname(sock, &local_addr, &addr_len)==PJ_SUCCESS) { 
    930             pj_sockaddr_in *tp_addr = (pj_sockaddr_in*)&tcp->base.local_addr; 
     949            pj_sockaddr *tp_addr = &tcp->base.local_addr; 
    931950 
    932951            /* Some systems (like old Win32 perhaps) may not set local address 
    933952             * properly before socket is fully connected. 
    934953             */ 
    935             if (tp_addr->sin_addr.s_addr != local_addr.sin_addr.s_addr && 
    936                 local_addr.sin_addr.s_addr != 0)  
     954            if (pj_sockaddr_cmp(tp_addr, &local_addr) && 
     955                pj_sockaddr_get_port(&local_addr) != 0) 
    937956            { 
    938                 tp_addr->sin_addr.s_addr = local_addr.sin_addr.s_addr; 
    939                 tp_addr->sin_port = local_addr.sin_port; 
     957                pj_sockaddr_cp(tp_addr, &local_addr); 
    940958                sockaddr_to_host_port(tcp->base.pool, &tcp->base.local_name, 
    941959                                      &local_addr); 
     
    973991    char addr[PJ_INET6_ADDRSTRLEN+10]; 
    974992    pjsip_tp_state_callback state_cb; 
     993    pj_sockaddr tmp_src_addr; 
    975994    pj_status_t status; 
    976995 
     
    9961015                                "incoming SIP TCP socket"); 
    9971016 
     1017    /* tcp_create() expect pj_sockaddr, so copy src_addr to temporary var, 
     1018     * just in case. 
     1019     */ 
     1020    pj_bzero(&tmp_src_addr, sizeof(tmp_src_addr)); 
     1021    pj_sockaddr_cp(&tmp_src_addr, src_addr); 
     1022 
    9981023    /*  
    9991024     * Incoming connection! 
     
    10011026     */ 
    10021027    status = tcp_create( listener, NULL, sock, PJ_TRUE, 
    1003                          (const pj_sockaddr_in*)&listener->factory.local_addr, 
    1004                          (const pj_sockaddr_in*)src_addr, &tcp); 
     1028                         &listener->factory.local_addr, 
     1029                         &tmp_src_addr, &tcp); 
    10051030    if (status == PJ_SUCCESS) { 
    10061031        status = tcp_start_read(tcp); 
     
    11061131     
    11071132    /* Check the address is supported */ 
    1108     PJ_ASSERT_RETURN(rem_addr && addr_len==sizeof(pj_sockaddr_in), PJ_EINVAL); 
    1109  
    1110  
     1133    PJ_ASSERT_RETURN(rem_addr && (addr_len==sizeof(pj_sockaddr_in) || 
     1134                                  addr_len==sizeof(pj_sockaddr_in6)), 
     1135                     PJ_EINVAL); 
    11111136 
    11121137    /* Init op key. */ 
     
    12891314{ 
    12901315    struct tcp_transport *tcp; 
    1291     pj_sockaddr_in addr; 
     1316    pj_sockaddr addr; 
    12921317    int addrlen; 
    12931318    pjsip_tp_state_callback state_cb; 
     
    13341359     * on some systems, like old Win32 probably?). 
    13351360     */ 
    1336     addrlen = sizeof(pj_sockaddr_in); 
     1361    addrlen = sizeof(addr); 
    13371362    if (pj_sock_getsockname(tcp->sock, &addr, &addrlen)==PJ_SUCCESS) { 
    1338         pj_sockaddr_in *tp_addr = (pj_sockaddr_in*)&tcp->base.local_addr; 
     1363        pj_sockaddr *tp_addr = &tcp->base.local_addr; 
    13391364 
    13401365        if (pj_sockaddr_has_addr(&addr) && 
    1341             tp_addr->sin_addr.s_addr != addr.sin_addr.s_addr)  
     1366            pj_sockaddr_cmp(&addr, tp_addr) != 0) 
    13421367        { 
    1343             tp_addr->sin_addr.s_addr = addr.sin_addr.s_addr; 
    1344             tp_addr->sin_port = addr.sin_port; 
     1368            pj_sockaddr_cp(tp_addr, &addr); 
    13451369            sockaddr_to_host_port(tcp->base.pool, &tcp->base.local_name, 
    13461370                                  tp_addr); 
Note: See TracChangeset for help on using the changeset viewer.