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_tls.c

    r4259 r4262  
    5656    pjsip_tpmgr             *tpmgr; 
    5757    pj_ssl_sock_t           *ssock; 
     58    pj_sockaddr              bound_addr; 
    5859    pj_ssl_cert_t           *cert; 
    5960    pjsip_tls_setting        tls_setting; 
     
    148149                              pj_ssl_sock_t *ssock,  
    149150                              pj_bool_t is_server, 
    150                               const pj_sockaddr_in *local, 
    151                               const pj_sockaddr_in *remote, 
     151                              const pj_sockaddr *local, 
     152                              const pj_sockaddr *remote, 
    152153                              const pj_str_t *remote_name, 
    153154                              struct tls_transport **p_tls); 
     
    167168static void sockaddr_to_host_port( pj_pool_t *pool, 
    168169                                   pjsip_host_port *host_port, 
    169                                    const pj_sockaddr_in *addr ) 
     170                                   const pj_sockaddr *addr ) 
    170171{ 
    171172    host_port->host.ptr = (char*) pj_pool_alloc(pool, PJ_INET6_ADDRSTRLEN+4); 
    172     pj_sockaddr_print(addr, host_port->host.ptr, PJ_INET6_ADDRSTRLEN+4, 2); 
     173    pj_sockaddr_print(addr, host_port->host.ptr, PJ_INET6_ADDRSTRLEN+4, 0); 
    173174    host_port->host.slen = pj_ansi_strlen(host_port->host.ptr); 
    174175    host_port->port = pj_sockaddr_get_port(addr); 
     
    236237PJ_DEF(pj_status_t) pjsip_tls_transport_start (pjsip_endpoint *endpt, 
    237238                                               const pjsip_tls_setting *opt, 
    238                                                const pj_sockaddr_in *local, 
     239                                               const pj_sockaddr_in *local_in, 
    239240                                               const pjsip_host_port *a_name, 
    240241                                               unsigned async_cnt, 
    241242                                               pjsip_tpfactory **p_factory) 
    242243{ 
     244    pj_sockaddr local; 
     245 
     246    if (local_in) 
     247        pj_sockaddr_cp(&local, local_in); 
     248 
     249    return pjsip_tls_transport_start2(endpt, opt, (local_in? &local : NULL), 
     250                                      a_name, async_cnt, p_factory); 
     251} 
     252 
     253PJ_DEF(pj_status_t) pjsip_tls_transport_start2( pjsip_endpoint *endpt, 
     254                                                const pjsip_tls_setting *opt, 
     255                                                const pj_sockaddr *local, 
     256                                                const pjsip_host_port *a_name, 
     257                                                unsigned async_cnt, 
     258                                                pjsip_tpfactory **p_factory) 
     259{ 
    243260    pj_pool_t *pool; 
     261    pj_bool_t is_ipv6; 
     262    int af; 
    244263    struct tls_listener *listener; 
    245264    pj_ssl_sock_param ssock_param; 
    246     pj_sockaddr_in *listener_addr; 
     265    pj_sockaddr *listener_addr; 
    247266    pj_bool_t has_listener; 
    248267    pj_status_t status; 
     
    251270    PJ_ASSERT_RETURN(endpt && async_cnt, PJ_EINVAL); 
    252271 
     272    is_ipv6 = (local && local->addr.sa_family == pj_AF_INET6()); 
     273    af = is_ipv6 ? pj_AF_INET6() : pj_AF_INET(); 
     274 
    253275    /* Verify that address given in a_name (if any) is valid */ 
    254276    if (a_name && a_name->host.slen) { 
    255         pj_sockaddr_in tmp; 
    256  
    257         status = pj_sockaddr_in_init(&tmp, &a_name->host,  
    258                                      (pj_uint16_t)a_name->port); 
    259         if (status != PJ_SUCCESS || tmp.sin_addr.s_addr == PJ_INADDR_ANY || 
    260             tmp.sin_addr.s_addr == PJ_INADDR_NONE) 
     277        pj_sockaddr tmp; 
     278 
     279        status = pj_sockaddr_init(af, &tmp, &a_name->host, 
     280                                  (pj_uint16_t)a_name->port); 
     281        if (status != PJ_SUCCESS || !pj_sockaddr_has_addr(&tmp) || 
     282            (!is_ipv6 && tmp.ipv4.sin_addr.s_addr == PJ_INADDR_NONE)) 
    261283        { 
    262284            /* Invalid address */ 
     
    271293    listener = PJ_POOL_ZALLOC_T(pool, struct tls_listener); 
    272294    listener->factory.pool = pool; 
    273     listener->factory.type = PJSIP_TRANSPORT_TLS; 
    274     listener->factory.type_name = "tls"; 
     295    if (is_ipv6) 
     296        listener->factory.type = PJSIP_TRANSPORT_TLS6; 
     297    else 
     298        listener->factory.type = PJSIP_TRANSPORT_TLS; 
     299    listener->factory.type_name = (char*) 
     300                pjsip_transport_get_type_name(listener->factory.type); 
    275301    listener->factory.flag =  
    276         pjsip_transport_get_flag_from_type(PJSIP_TRANSPORT_TLS); 
     302        pjsip_transport_get_flag_from_type(listener->factory.type); 
    277303 
    278304    pj_ansi_strcpy(listener->factory.obj_name, "tlslis"); 
     305    if (is_ipv6) 
     306        pj_ansi_strcat(listener->factory.obj_name, "6"); 
    279307 
    280308    if (opt) 
     
    283311        pjsip_tls_setting_default(&listener->tls_setting); 
    284312 
    285     status = pj_lock_create_recursive_mutex(pool, "tlslis",  
     313    status = pj_lock_create_recursive_mutex(pool, listener->factory.obj_name, 
    286314                                            &listener->factory.lock); 
    287315    if (status != PJ_SUCCESS) 
     
    293321    /* Build SSL socket param */ 
    294322    pj_ssl_sock_param_default(&ssock_param); 
     323    ssock_param.sock_af = af; 
    295324    ssock_param.cb.on_accept_complete = &on_accept_complete; 
    296325    ssock_param.cb.on_data_read = &on_data_read; 
     
    339368        goto on_error; 
    340369 
    341     listener_addr = (pj_sockaddr_in*)&listener->factory.local_addr; 
     370    /* Bind address may be different than factory.local_addr because 
     371     * factory.local_addr will be resolved below. 
     372     */ 
     373    listener_addr = &listener->factory.local_addr; 
    342374    if (local) { 
    343375        pj_sockaddr_cp((pj_sockaddr_t*)listener_addr,  
    344376                       (const pj_sockaddr_t*)local); 
     377        pj_sockaddr_cp(&listener->bound_addr, local); 
    345378    } else { 
    346         pj_sockaddr_in_init(listener_addr, NULL, 0); 
     379        pj_sockaddr_init(af, listener_addr, NULL, 0); 
     380        pj_sockaddr_init(af, &listener->bound_addr, NULL, 0); 
    347381    } 
    348382 
     
    402436         * interface address as the transport's address. 
    403437         */ 
    404         if (listener_addr->sin_addr.s_addr == 0) { 
     438        if (!pj_sockaddr_has_addr(listener_addr)) { 
    405439            pj_sockaddr hostip; 
    406440 
    407             status = pj_gethostip(pj_AF_INET(), &hostip); 
     441            status = pj_gethostip(af, &hostip); 
    408442            if (status != PJ_SUCCESS) 
    409443                goto on_error; 
    410444 
    411             listener_addr->sin_addr.s_addr = hostip.ipv4.sin_addr.s_addr; 
     445            pj_sockaddr_copy_addr(listener_addr, &hostip); 
    412446        } 
    413447 
     
    419453    /* If port is zero, get the bound port */ 
    420454    if (listener->factory.addr_name.port == 0) { 
    421         listener->factory.addr_name.port = pj_ntohs(listener_addr->sin_port); 
     455        listener->factory.addr_name.port = pj_sockaddr_get_port(listener_addr); 
    422456    } 
    423457 
     
    536570                               pj_ssl_sock_t *ssock, 
    537571                               pj_bool_t is_server, 
    538                                const pj_sockaddr_in *local, 
    539                                const pj_sockaddr_in *remote, 
     572                               const pj_sockaddr *local, 
     573                               const pj_sockaddr *remote, 
    540574                               const pj_str_t *remote_name, 
    541575                               struct tls_transport **p_tls) 
     
    543577    struct tls_transport *tls; 
    544578    const pj_str_t ka_pkt = PJSIP_TLS_KEEP_ALIVE_DATA; 
     579    char print_addr[PJ_INET6_ADDRSTRLEN+10]; 
    545580    pj_status_t status; 
    546581     
     
    580615        pj_strdup(pool, &tls->remote_name, remote_name); 
    581616 
    582     tls->base.key.type = PJSIP_TRANSPORT_TLS; 
    583     pj_memcpy(&tls->base.key.rem_addr, remote, sizeof(pj_sockaddr_in)); 
    584     tls->base.type_name = "tls"; 
    585     tls->base.flag = pjsip_transport_get_flag_from_type(PJSIP_TRANSPORT_TLS); 
     617    tls->base.key.type = listener->factory.type; 
     618    pj_sockaddr_cp(&tls->base.key.rem_addr, remote); 
     619    tls->base.type_name = (char*) 
     620                          pjsip_transport_get_type_name(tls->base.key.type); 
     621    tls->base.flag = pjsip_transport_get_flag_from_type(tls->base.key.type); 
    586622 
    587623    tls->base.info = (char*) pj_pool_alloc(pool, 64); 
    588     pj_ansi_snprintf(tls->base.info, 64, "TLS to %s:%d", 
    589                      pj_inet_ntoa(remote->sin_addr),  
    590                      (int)pj_ntohs(remote->sin_port)); 
    591  
    592     tls->base.addr_len = sizeof(pj_sockaddr_in); 
     624    pj_ansi_snprintf(tls->base.info, 64, "%s to %s", 
     625                     tls->base.type_name, 
     626                     pj_sockaddr_print(remote, print_addr, 
     627                                       sizeof(print_addr), 3)); 
     628 
     629 
     630    tls->base.addr_len = pj_sockaddr_get_len(remote); 
    593631    tls->base.dir = is_server? PJSIP_TP_DIR_INCOMING : PJSIP_TP_DIR_OUTGOING; 
    594632     
     
    601639    } 
    602640     
    603     sockaddr_to_host_port(pool, &tls->base.local_name,  
    604                           (pj_sockaddr_in*)&tls->base.local_addr); 
     641    sockaddr_to_host_port(pool, &tls->base.local_name, &tls->base.local_addr); 
    605642    if (tls->remote_name.slen) { 
    606643        tls->base.remote_name.host = tls->remote_name; 
    607         tls->base.remote_name.port = pj_sockaddr_in_get_port(remote); 
     644        tls->base.remote_name.port = pj_sockaddr_get_port(remote); 
    608645    } else { 
    609646        sockaddr_to_host_port(pool, &tls->base.remote_name, remote); 
     
    795832    pj_pool_t *pool; 
    796833    pj_ssize_t size; 
    797     pj_sockaddr_in *rem_addr; 
     834    pj_sockaddr *rem_addr; 
    798835    void *readbuf[1]; 
    799836    pj_status_t status; 
     
    818855 
    819856    tls->rdata.pkt_info.src_addr = tls->base.key.rem_addr; 
    820     tls->rdata.pkt_info.src_addr_len = sizeof(pj_sockaddr_in); 
    821     rem_addr = (pj_sockaddr_in*) &tls->base.key.rem_addr; 
    822     pj_ansi_strcpy(tls->rdata.pkt_info.src_name, 
    823                    pj_inet_ntoa(rem_addr->sin_addr)); 
    824     tls->rdata.pkt_info.src_port = pj_ntohs(rem_addr->sin_port); 
     857    tls->rdata.pkt_info.src_addr_len = sizeof(tls->rdata.pkt_info.src_addr); 
     858    rem_addr = &tls->base.key.rem_addr; 
     859    pj_sockaddr_print(rem_addr, tls->rdata.pkt_info.src_name, 
     860                          sizeof(tls->rdata.pkt_info.src_name), 0); 
     861    tls->rdata.pkt_info.src_port = pj_sockaddr_get_port(rem_addr); 
    825862 
    826863    size = sizeof(tls->rdata.pkt_info.packet); 
     
    855892    pj_ssl_sock_t *ssock; 
    856893    pj_ssl_sock_param ssock_param; 
    857     pj_sockaddr_in local_addr; 
     894    pj_sockaddr local_addr; 
    858895    pj_str_t remote_name; 
    859896    pj_status_t status; 
     
    863900                     addr_len && p_transport, PJ_EINVAL); 
    864901 
    865     /* Check that address is a sockaddr_in */ 
    866     PJ_ASSERT_RETURN(rem_addr->addr.sa_family == pj_AF_INET() && 
    867                      addr_len == sizeof(pj_sockaddr_in), PJ_EINVAL); 
     902    /* Check that address is a sockaddr_in or sockaddr_in6*/ 
     903    PJ_ASSERT_RETURN((rem_addr->addr.sa_family == pj_AF_INET() && 
     904                      addr_len == sizeof(pj_sockaddr_in)) || 
     905                     (rem_addr->addr.sa_family == pj_AF_INET6() && 
     906                      addr_len == sizeof(pj_sockaddr_in6)), PJ_EINVAL); 
    868907 
    869908 
     
    882921    /* Build SSL socket param */ 
    883922    pj_ssl_sock_param_default(&ssock_param); 
     923    ssock_param.sock_af = (factory->type & PJSIP_TRANSPORT_IPV6) ? 
     924                            pj_AF_INET6() : pj_AF_INET(); 
    884925    ssock_param.cb.on_connect_complete = &on_connect_complete; 
    885926    ssock_param.cb.on_data_read = &on_data_read; 
     
    932973    } 
    933974 
    934     /* Initially set bind address to PJ_INADDR_ANY port 0 */ 
    935     pj_sockaddr_in_init(&local_addr, NULL, 0); 
     975    /* Initially set bind address to listener's bind address */ 
     976    pj_sockaddr_init(listener->bound_addr.addr.sa_family, 
     977                     &local_addr, NULL, 0); 
     978    pj_sockaddr_copy_addr(&local_addr, &listener->bound_addr); 
    936979 
    937980    /* Create the transport descriptor */ 
    938981    status = tls_create(listener, pool, ssock, PJ_FALSE, &local_addr,  
    939                         (pj_sockaddr_in*)rem_addr, &remote_name, &tls); 
     982                        rem_addr, &remote_name, &tls); 
    940983    if (status != PJ_SUCCESS) 
    941984        return status; 
     
    9841027 
    9851028            sockaddr_to_host_port(tls->base.pool, &tls->base.local_name, 
    986                                   (pj_sockaddr_in*)&tls->base.local_addr); 
     1029                                  &tls->base.local_addr); 
    9871030        } 
    9881031 
     
    10181061    char addr[PJ_INET6_ADDRSTRLEN+10]; 
    10191062    pjsip_tp_state_callback state_cb; 
     1063    pj_sockaddr tmp_src_addr; 
    10201064    pj_bool_t is_shutdown; 
    10211065    pj_status_t status; 
     
    10451089    } 
    10461090 
     1091    /* Copy to larger buffer, just in case */ 
     1092    pj_bzero(&tmp_src_addr, sizeof(tmp_src_addr)); 
     1093    pj_sockaddr_cp(&tmp_src_addr, src_addr); 
     1094 
    10471095    /*  
    10481096     * Incoming connection! 
     
    10501098     */ 
    10511099    status = tls_create( listener, NULL, new_ssock, PJ_TRUE, 
    1052                          (const pj_sockaddr_in*)&listener->factory.local_addr, 
    1053                          (const pj_sockaddr_in*)src_addr, NULL, &tls); 
     1100                         &listener->factory.local_addr, 
     1101                         &tmp_src_addr, NULL, &tls); 
    10541102     
    10551103    if (status != PJ_SUCCESS) 
     
    12011249     
    12021250    /* Check the address is supported */ 
    1203     PJ_ASSERT_RETURN(rem_addr && addr_len==sizeof(pj_sockaddr_in), PJ_EINVAL); 
    1204  
    1205  
     1251    PJ_ASSERT_RETURN(rem_addr && (addr_len==sizeof(pj_sockaddr_in) || 
     1252                                  addr_len==sizeof(pj_sockaddr_in6)), 
     1253                     PJ_EINVAL); 
    12061254 
    12071255    /* Init op key. */ 
     
    13851433    struct tls_transport *tls; 
    13861434    pj_ssl_sock_info ssl_info; 
    1387     pj_sockaddr_in addr, *tp_addr; 
     1435    pj_sockaddr addr, *tp_addr; 
    13881436    pjsip_tp_state_callback state_cb; 
    13891437    pj_bool_t is_shutdown; 
     
    14231471     * on some systems, like old Win32 probably?). 
    14241472     */ 
    1425     tp_addr = (pj_sockaddr_in*)&tls->base.local_addr; 
     1473    tp_addr = &tls->base.local_addr; 
    14261474    pj_sockaddr_cp((pj_sockaddr_t*)&addr,  
    14271475                   (pj_sockaddr_t*)&ssl_info.local_addr); 
    1428     if (tp_addr->sin_addr.s_addr != addr.sin_addr.s_addr) { 
    1429         tp_addr->sin_addr.s_addr = addr.sin_addr.s_addr; 
    1430         tp_addr->sin_port = addr.sin_port; 
     1476    if (pj_sockaddr_cmp(tp_addr, &addr) != 0) { 
     1477        pj_sockaddr_cp(tp_addr, &addr); 
    14311478        sockaddr_to_host_port(tls->base.pool, &tls->base.local_name, 
    14321479                              tp_addr); 
Note: See TracChangeset for help on using the changeset viewer.