Changeset 4262 for pjproject/trunk


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

Location:
pjproject/trunk
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip-apps/src/pjsua/pjsua_app.c

    r4218 r4262  
    171171static void stereo_demo(); 
    172172#endif 
    173 static pj_status_t create_ipv6_media_transports(void); 
    174173pj_status_t app_destroy(void); 
    175174 
     
    877876 
    878877        case OPT_NO_UDP: /* no-udp */ 
    879             if (cfg->no_tcp) { 
    880               PJ_LOG(1,(THIS_FILE,"Error: can not disable both TCP and UDP")); 
     878            if (cfg->no_tcp && !cfg->use_tls) { 
     879              PJ_LOG(1,(THIS_FILE,"Error: cannot disable both TCP and UDP")); 
    881880              return PJ_EINVAL; 
    882881            } 
     
    890889 
    891890        case OPT_NO_TCP: /* no-tcp */ 
    892             if (cfg->no_udp) { 
    893               PJ_LOG(1,(THIS_FILE,"Error: can not disable both TCP and UDP")); 
     891            if (cfg->no_udp && !cfg->use_tls) { 
     892              PJ_LOG(1,(THIS_FILE,"Error: cannot disable both TCP and UDP")); 
    894893              return PJ_EINVAL; 
    895894            } 
     
    59085907            pjsua_acc_get_config(aid, &acc_cfg); 
    59095908            app_config_init_video(&acc_cfg); 
     5909            if (app_config.ipv6) 
     5910                acc_cfg.ipv6_media_use = PJSUA_IPV6_ENABLED; 
    59105911            pjsua_acc_modify(aid, &acc_cfg); 
    59115912        } 
     
    59445945        pjsua_acc_set_online_status(current_acc, PJ_TRUE); 
    59455946 
     5947    } 
     5948 
     5949    /* Add TCP IPv6 transport unless it's disabled. */ 
     5950    if (!app_config.no_tcp && app_config.ipv6) { 
     5951        pjsua_acc_id aid; 
     5952        pjsip_transport_type_e type = PJSIP_TRANSPORT_TCP6; 
     5953 
     5954        tcp_cfg.port += 10; 
     5955 
     5956        status = pjsua_transport_create(type, 
     5957                                        &tcp_cfg, 
     5958                                        &transport_id); 
     5959        if (status != PJ_SUCCESS) 
     5960            goto on_error; 
     5961 
     5962        /* Add local account */ 
     5963        pjsua_acc_add_local(transport_id, PJ_TRUE, &aid); 
     5964        if (PJMEDIA_HAS_VIDEO) { 
     5965            pjsua_acc_config acc_cfg; 
     5966            pjsua_acc_get_config(aid, &acc_cfg); 
     5967            app_config_init_video(&acc_cfg); 
     5968            if (app_config.ipv6) 
     5969                acc_cfg.ipv6_media_use = PJSUA_IPV6_ENABLED; 
     5970            pjsua_acc_modify(aid, &acc_cfg); 
     5971        } 
     5972        //pjsua_acc_set_transport(aid, transport_id); 
     5973        pjsua_acc_set_online_status(current_acc, PJ_TRUE); 
    59465974    } 
    59475975 
     
    59776005        pjsua_acc_set_online_status(acc_id, PJ_TRUE); 
    59786006    } 
     6007 
     6008    /* Add TLS IPv6 transport unless it's disabled. */ 
     6009    if (app_config.use_tls && app_config.ipv6) { 
     6010        pjsua_acc_id aid; 
     6011        pjsip_transport_type_e type = PJSIP_TRANSPORT_TLS6; 
     6012 
     6013        tcp_cfg.port += 10; 
     6014 
     6015        status = pjsua_transport_create(type, 
     6016                                        &tcp_cfg, 
     6017                                        &transport_id); 
     6018        if (status != PJ_SUCCESS) 
     6019            goto on_error; 
     6020 
     6021        /* Add local account */ 
     6022        pjsua_acc_add_local(transport_id, PJ_TRUE, &aid); 
     6023        if (PJMEDIA_HAS_VIDEO) { 
     6024            pjsua_acc_config acc_cfg; 
     6025            pjsua_acc_get_config(aid, &acc_cfg); 
     6026            app_config_init_video(&acc_cfg); 
     6027            if (app_config.ipv6) 
     6028                acc_cfg.ipv6_media_use = PJSUA_IPV6_ENABLED; 
     6029            pjsua_acc_modify(aid, &acc_cfg); 
     6030        } 
     6031        //pjsua_acc_set_transport(aid, transport_id); 
     6032        pjsua_acc_set_online_status(current_acc, PJ_TRUE); 
     6033    } 
     6034 
    59796035#endif 
    59806036 
     
    60266082#endif 
    60276083    } 
    6028  
    6029     /* Add RTP transports */ 
    6030     if (app_config.ipv6) 
    6031         status = create_ipv6_media_transports(); 
    6032   #if DISABLED_FOR_TICKET_1185 
    6033     else 
    6034         status = pjsua_media_transports_create(&app_config.rtp_cfg); 
    6035   #endif 
    6036     if (status != PJ_SUCCESS) 
    6037         goto on_error; 
    60386084 
    60396085    /* Use null sound device? */ 
     
    62526298#endif 
    62536299 
    6254 static pj_status_t create_ipv6_media_transports(void) 
    6255 { 
    6256     pjsua_media_transport tp[PJSUA_MAX_CALLS]; 
    6257     pj_status_t status; 
    6258     int port = app_config.rtp_cfg.port; 
    6259     unsigned i; 
    6260  
    6261     for (i=0; i<app_config.cfg.max_calls; ++i) { 
    6262         enum { MAX_RETRY = 10 }; 
    6263         pj_sock_t sock[2]; 
    6264         pjmedia_sock_info si; 
    6265         unsigned j; 
    6266  
    6267         /* Get rid of uninitialized var compiler warning with MSVC */ 
    6268         status = PJ_SUCCESS; 
    6269  
    6270         for (j=0; j<MAX_RETRY; ++j) { 
    6271             unsigned k; 
    6272  
    6273             for (k=0; k<2; ++k) { 
    6274                 pj_sockaddr bound_addr; 
    6275  
    6276                 status = pj_sock_socket(pj_AF_INET6(), pj_SOCK_DGRAM(), 0, &sock[k]); 
    6277                 if (status != PJ_SUCCESS) 
    6278                     break; 
    6279  
    6280                 status = pj_sockaddr_init(pj_AF_INET6(), &bound_addr, 
    6281                                           &app_config.rtp_cfg.bound_addr,  
    6282                                           (unsigned short)(port+k)); 
    6283                 if (status != PJ_SUCCESS) 
    6284                     break; 
    6285  
    6286                 status = pj_sock_bind(sock[k], &bound_addr,  
    6287                                       pj_sockaddr_get_len(&bound_addr)); 
    6288                 if (status != PJ_SUCCESS) 
    6289                     break; 
    6290             } 
    6291             if (status != PJ_SUCCESS) { 
    6292                 if (k==1) 
    6293                     pj_sock_close(sock[0]); 
    6294  
    6295                 if (port != 0) 
    6296                     port += 10; 
    6297                 else 
    6298                     break; 
    6299  
    6300                 continue; 
    6301             } 
    6302  
    6303             pj_bzero(&si, sizeof(si)); 
    6304             si.rtp_sock = sock[0]; 
    6305             si.rtcp_sock = sock[1]; 
    6306          
    6307             pj_sockaddr_init(pj_AF_INET6(), &si.rtp_addr_name,  
    6308                              &app_config.rtp_cfg.public_addr,  
    6309                              (unsigned short)(port)); 
    6310             pj_sockaddr_init(pj_AF_INET6(), &si.rtcp_addr_name,  
    6311                              &app_config.rtp_cfg.public_addr,  
    6312                              (unsigned short)(port+1)); 
    6313  
    6314             status = pjmedia_transport_udp_attach(pjsua_get_pjmedia_endpt(), 
    6315                                                   NULL, 
    6316                                                   &si, 
    6317                                                   0, 
    6318                                                   &tp[i].transport); 
    6319             if (port != 0) 
    6320                 port += 10; 
    6321             else 
    6322                 break; 
    6323  
    6324             if (status == PJ_SUCCESS) 
    6325                 break; 
    6326         } 
    6327  
    6328         if (status != PJ_SUCCESS) { 
    6329             pjsua_perror(THIS_FILE, "Error creating IPv6 UDP media transport",  
    6330                          status); 
    6331             for (j=0; j<i; ++j) { 
    6332                 pjmedia_transport_close(tp[j].transport); 
    6333             } 
    6334             return status; 
    6335         } 
    6336     } 
    6337  
    6338 #if DISABLED_FOR_TICKET_1185 
    6339     return pjsua_media_transports_attach(tp, i, PJ_TRUE); 
    6340 #else 
    6341     return PJ_ENOTSUP; 
    6342 #endif 
    6343 } 
    6344  
  • pjproject/trunk/pjsip/include/pjsip/sip_transport_tls.h

    r3999 r4262  
    262262 * instance of SIP TLS transport factory and register it to the 
    263263 * transport manager. 
     264 * 
     265 * See also #pjsip_tls_transport_start2() which supports IPv6. 
    264266 * 
    265267 * @param endpt         The SIP endpoint. 
     
    295297                                               pjsip_tpfactory **p_factory); 
    296298 
    297  
     299/** 
     300 * Variant of #pjsip_tls_transport_start() that supports IPv6. To instantiate 
     301 * IPv6 listener, set the address family of the "local" argument to IPv6 
     302 * (the host and port part may be left unspecified if not desired, i.e. by 
     303 * filling them with zeroes). 
     304 * 
     305 * @param endpt         The SIP endpoint. 
     306 * @param opt           Optional TLS settings. 
     307 * @param local         Optional local address to bind, or specify the 
     308 *                      address to bind the server socket to. Both IP 
     309 *                      interface address and port fields are optional. 
     310 *                      If IP interface address is not specified, socket 
     311 *                      will be bound to any address. If port is not 
     312 *                      specified, socket will be bound to any port 
     313 *                      selected by the operating system. 
     314 * @param a_name        Optional published address, which is the address to be 
     315 *                      advertised as the address of this SIP transport. 
     316 *                      If this argument is NULL, then the bound address 
     317 *                      will be used as the published address. 
     318 * @param async_cnt     Number of simultaneous asynchronous accept() 
     319 *                      operations to be supported. It is recommended that 
     320 *                      the number here corresponds to the number of 
     321 *                      processors in the system (or the number of SIP 
     322 *                      worker threads). 
     323 * @param p_factory     Optional pointer to receive the instance of the 
     324 *                      SIP TLS transport factory just created. 
     325 * 
     326 * @return              PJ_SUCCESS when the transport has been successfully 
     327 *                      started and registered to transport manager, or 
     328 *                      the appropriate error code. 
     329 */ 
     330PJ_DECL(pj_status_t) pjsip_tls_transport_start2(pjsip_endpoint *endpt, 
     331                                                const pjsip_tls_setting *opt, 
     332                                                const pj_sockaddr *local, 
     333                                                const pjsip_host_port *a_name, 
     334                                                unsigned async_cnt, 
     335                                                pjsip_tpfactory **p_factory); 
    298336 
    299337PJ_END_DECL 
  • pjproject/trunk/pjsip/include/pjsip/sip_types.h

    r3553 r4262  
    9393 
    9494    /** TCP over IPv6 */ 
    95     PJSIP_TRANSPORT_TCP6 = PJSIP_TRANSPORT_TCP + PJSIP_TRANSPORT_IPV6 
     95    PJSIP_TRANSPORT_TCP6 = PJSIP_TRANSPORT_TCP + PJSIP_TRANSPORT_IPV6, 
     96 
     97    /** TLS over IPv6 */ 
     98    PJSIP_TRANSPORT_TLS6 = PJSIP_TRANSPORT_TLS + PJSIP_TRANSPORT_IPV6 
    9699 
    97100} pjsip_transport_type_e; 
  • pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h

    r4254 r4262  
    26912691 
    26922692/** 
     2693 * Specify how IPv6 transport should be used in account config. 
     2694 */ 
     2695typedef enum pjsua_ipv6_use 
     2696{ 
     2697    /** 
     2698     * IPv6 is not used. 
     2699     */ 
     2700    PJSUA_IPV6_DISABLED, 
     2701 
     2702    /** 
     2703     * IPv6 is enabled. 
     2704     */ 
     2705    PJSUA_IPV6_ENABLED 
     2706 
     2707} pjsua_ipv6_use; 
     2708 
     2709/** 
    26932710 * This structure describes account configuration to be specified when 
    26942711 * adding a new account with #pjsua_acc_add(). Application MUST initialize 
     
    30893106     */ 
    30903107    pjsua_transport_config rtp_cfg; 
     3108 
     3109    /** 
     3110     * Specify whether IPv6 should be used on media. 
     3111     */ 
     3112    pjsua_ipv6_use              ipv6_media_use; 
    30913113 
    30923114    /** 
  • pjproject/trunk/pjsip/src/pjsip/sip_transport.c

    r4239 r4262  
    199199        PJSIP_TRANSPORT_RELIABLE 
    200200    }, 
     201    { 
     202        PJSIP_TRANSPORT_TLS6, 
     203        5061, 
     204        {"TLS", 3}, 
     205        "TLS IPv6 transport", 
     206        PJSIP_TRANSPORT_RELIABLE | PJSIP_TRANSPORT_SECURE 
     207    }, 
    201208}; 
    202209 
     
    12801287                status = get_net_interface(f->type, &prm->dst_host, 
    12811288                                           &tmp_str); 
    1282                 if (status != PJ_SUCCESS) 
    1283                     goto on_return; 
    1284                 pj_strdup(pool, &prm->ret_addr, &tmp_str); 
     1289                if (status == PJ_SUCCESS) { 
     1290                    pj_strdup(pool, &prm->ret_addr, &tmp_str); 
     1291                } else { 
     1292                    /* It could fail "normally" on certain cases, e.g. 
     1293                     * when connecting to IPv6 link local address, it 
     1294                     * will wail with EINVAL. 
     1295                     * In this case, fallback to use the default interface 
     1296                     * rather than failing the call. 
     1297                     */ 
     1298                    PJ_PERROR(5,(THIS_FILE, status, "Warning: unable to " 
     1299                                 "determine local interface")); 
     1300                    pj_strdup(pool, &prm->ret_addr, &f->addr_name.host); 
     1301                    status = PJ_SUCCESS; 
     1302                } 
    12851303            } else { 
    12861304                pj_strdup(pool, &prm->ret_addr, &f->addr_name.host); 
  • 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); 
  • 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); 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_acc.c

    r4229 r4262  
    11901190        acc->cfg.rtp_cfg =  cfg->rtp_cfg; 
    11911191    } 
     1192 
     1193    acc->cfg.ipv6_media_use = cfg->ipv6_media_use; 
    11921194 
    11931195    /* STUN and Media customization */ 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c

    r4224 r4262  
    20682068        pjsip_tpfactory *tcp; 
    20692069        pjsip_tcp_transport_cfg tcp_cfg; 
    2070  
    2071         pjsip_tcp_transport_cfg_default(&tcp_cfg, pj_AF_INET()); 
     2070        int af; 
     2071 
     2072        af = (type==PJSIP_TRANSPORT_TCP6) ? pj_AF_INET6() : pj_AF_INET(); 
     2073        pjsip_tcp_transport_cfg_default(&tcp_cfg, af); 
    20722074 
    20732075        /* Supply default config if it's not specified */ 
     
    21192121 
    21202122#if defined(PJSIP_HAS_TLS_TRANSPORT) && PJSIP_HAS_TLS_TRANSPORT!=0 
    2121     } else if (type == PJSIP_TRANSPORT_TLS) { 
     2123    } else if (type == PJSIP_TRANSPORT_TLS || type == PJSIP_TRANSPORT_TLS6) { 
    21222124        /* 
    21232125         * Create TLS transport. 
     
    21262128        pjsip_host_port a_name; 
    21272129        pjsip_tpfactory *tls; 
    2128         pj_sockaddr_in local_addr; 
     2130        pj_sockaddr local_addr; 
     2131        int af; 
    21292132 
    21302133        /* Supply default config if it's not specified */ 
     
    21362139 
    21372140        /* Init local address */ 
    2138         pj_sockaddr_in_init(&local_addr, 0, 0); 
     2141        af = (type==PJSIP_TRANSPORT_TLS) ? pj_AF_INET() : pj_AF_INET6(); 
     2142        pj_sockaddr_init(af, &local_addr, NULL, 0); 
    21392143 
    21402144        if (cfg->port) 
    2141             local_addr.sin_port = pj_htons((pj_uint16_t)cfg->port); 
     2145            pj_sockaddr_set_port(&local_addr, (pj_uint16_t)cfg->port); 
    21422146 
    21432147        if (cfg->bound_addr.slen) { 
    2144             status = pj_sockaddr_in_set_str_addr(&local_addr,&cfg->bound_addr); 
     2148            status = pj_sockaddr_set_str_addr(af, &local_addr, 
     2149                                              &cfg->bound_addr); 
    21452150            if (status != PJ_SUCCESS) { 
    21462151                pjsua_perror(THIS_FILE,  
     
    21562161            a_name.host = cfg->public_addr; 
    21572162 
    2158         status = pjsip_tls_transport_start(pjsua_var.endpt,  
    2159                                            &cfg->tls_setting,  
    2160                                            &local_addr, &a_name, 1, &tls); 
     2163        status = pjsip_tls_transport_start2(pjsua_var.endpt, 
     2164                                            &cfg->tls_setting, 
     2165                                            &local_addr, &a_name, 1, &tls); 
    21612166        if (status != PJ_SUCCESS) { 
    21622167            pjsua_perror(THIS_FILE, "Error creating SIP TLS listener",  
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c

    r4254 r4262  
    237237    }; 
    238238    int i; 
    239     pj_sockaddr_in bound_addr; 
    240     pj_sockaddr_in mapped_addr[2]; 
     239    pj_bool_t use_ipv6; 
     240    int af; 
     241    pj_sockaddr bound_addr; 
     242    pj_sockaddr mapped_addr[2]; 
    241243    pj_status_t status = PJ_SUCCESS; 
    242     char addr_buf[PJ_INET6_ADDRSTRLEN+2]; 
     244    char addr_buf[PJ_INET6_ADDRSTRLEN+10]; 
    243245    pj_sock_t sock[2]; 
    244246 
     247    use_ipv6 = (pjsua_var.acc[call_med->call->acc_id].cfg.ipv6_media_use != 
     248                PJSUA_IPV6_DISABLED); 
     249    af = use_ipv6 ? pj_AF_INET6() : pj_AF_INET(); 
     250 
    245251    /* Make sure STUN server resolution has completed */ 
    246     if (pjsua_sip_acc_is_using_stun(call_med->call->acc_id)) { 
     252    if (!use_ipv6 && pjsua_sip_acc_is_using_stun(call_med->call->acc_id)) { 
    247253        status = resolve_stun_server(PJ_TRUE); 
    248254        if (status != PJ_SUCCESS) { 
     
    261267        sock[i] = PJ_INVALID_SOCKET; 
    262268 
    263     bound_addr.sin_addr.s_addr = PJ_INADDR_ANY; 
     269    pj_sockaddr_init(af, &bound_addr, NULL, 0); 
    264270    if (cfg->bound_addr.slen) { 
    265         status = pj_sockaddr_in_set_str_addr(&bound_addr, &cfg->bound_addr); 
     271        status = pj_sockaddr_set_str_addr(af, &bound_addr, &cfg->bound_addr); 
    266272        if (status != PJ_SUCCESS) { 
    267273            pjsua_perror(THIS_FILE, "Unable to resolve transport bind address", 
     
    275281 
    276282        /* Create RTP socket. */ 
    277         status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &sock[0]); 
     283        status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &sock[0]); 
    278284        if (status != PJ_SUCCESS) { 
    279285            pjsua_perror(THIS_FILE, "socket() error", status); 
     
    287293 
    288294        /* Bind RTP socket */ 
    289         status=pj_sock_bind_in(sock[0], pj_ntohl(bound_addr.sin_addr.s_addr), 
    290                                next_rtp_port); 
     295        pj_sockaddr_set_port(&bound_addr, next_rtp_port); 
     296        status=pj_sock_bind(sock[0], &bound_addr, 
     297                            pj_sockaddr_get_len(&bound_addr)); 
    291298        if (status != PJ_SUCCESS) { 
    292299            pj_sock_close(sock[0]); 
     
    296303 
    297304        /* Create RTCP socket. */ 
    298         status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &sock[1]); 
     305        status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &sock[1]); 
    299306        if (status != PJ_SUCCESS) { 
    300307            pjsua_perror(THIS_FILE, "socket() error", status); 
     
    309316 
    310317        /* Bind RTCP socket */ 
    311         status=pj_sock_bind_in(sock[1], pj_ntohl(bound_addr.sin_addr.s_addr), 
    312                                (pj_uint16_t)(next_rtp_port+1)); 
     318        pj_sockaddr_set_port(&bound_addr, (pj_uint16_t)(next_rtp_port+1)); 
     319        status=pj_sock_bind(sock[1], &bound_addr, 
     320                            pj_sockaddr_get_len(&bound_addr)); 
    313321        if (status != PJ_SUCCESS) { 
    314322            pj_sock_close(sock[0]); 
     
    324332         * and make sure that the mapped RTCP port is adjacent with the RTP. 
    325333         */ 
    326         if (pjsua_sip_acc_is_using_stun(call_med->call->acc_id) && 
     334        if (!use_ipv6 && pjsua_sip_acc_is_using_stun(call_med->call->acc_id) && 
    327335            pjsua_var.stun_srv.addr.sa_family != 0) 
    328336        { 
    329337            char ip_addr[32]; 
    330338            pj_str_t stun_srv; 
     339            pj_sockaddr_in resolved_addr[2]; 
    331340            pjstun_setting stun_opt; 
    332341 
     
    341350                             pj_ntohs(pjsua_var.stun_srv.ipv4.sin_port); 
    342351            status=pjstun_get_mapped_addr2(&pjsua_var.cp.factory, &stun_opt, 
    343                                            2, sock, mapped_addr); 
     352                                           2, sock, resolved_addr); 
    344353            if (status != PJ_SUCCESS) { 
    345354                pjsua_perror(THIS_FILE, "STUN resolve error", status); 
     
    347356            } 
    348357 
     358            pj_sockaddr_cp(&mapped_addr[0], &resolved_addr[0]); 
     359            pj_sockaddr_cp(&mapped_addr[1], &resolved_addr[1]); 
     360 
    349361#if PJSUA_REQUIRE_CONSECUTIVE_RTCP_PORT 
    350             if (pj_ntohs(mapped_addr[1].sin_port) == 
    351                 pj_ntohs(mapped_addr[0].sin_port)+1) 
     362            if (pj_sockaddr_get_port(&mapped_addr[1]) == 
     363                pj_sockaddr_get_port(&mapped_addr[0])+1) 
    352364            { 
    353365                /* Success! */ 
     
    361373            sock[1] = PJ_INVALID_SOCKET; 
    362374#else 
    363             if (pj_ntohs(mapped_addr[1].sin_port) != 
    364                 pj_ntohs(mapped_addr[0].sin_port)+1) 
     375            if (pj_sockaddr_get_port(&mapped_addr[1]) != 
     376                pj_sockaddr_get_port(&mapped_addr[0])+1) 
    365377            { 
    366378                PJ_LOG(4,(THIS_FILE, 
    367379                          "Note: STUN mapped RTCP port %d is not adjacent" 
    368380                          " to RTP port %d", 
    369                           pj_ntohs(mapped_addr[1].sin_port), 
    370                           pj_ntohs(mapped_addr[0].sin_port))); 
     381                          pj_sockaddr_get_port(&mapped_addr[1]), 
     382                          pj_sockaddr_get_port(&mapped_addr[0]))); 
    371383            } 
    372384            /* Success! */ 
     
    376388        } else if (cfg->public_addr.slen) { 
    377389 
    378             status = pj_sockaddr_in_init(&mapped_addr[0], &cfg->public_addr, 
    379                                         (pj_uint16_t)next_rtp_port); 
     390            status = pj_sockaddr_init(af, &mapped_addr[0], &cfg->public_addr, 
     391                                      (pj_uint16_t)next_rtp_port); 
    380392            if (status != PJ_SUCCESS) 
    381393                goto on_error; 
    382394 
    383             status = pj_sockaddr_in_init(&mapped_addr[1], &cfg->public_addr, 
    384                                         (pj_uint16_t)(next_rtp_port+1)); 
     395            status = pj_sockaddr_init(af, &mapped_addr[1], &cfg->public_addr, 
     396                                      (pj_uint16_t)(next_rtp_port+1)); 
    385397            if (status != PJ_SUCCESS) 
    386398                goto on_error; 
     
    390402        } else { 
    391403 
    392             if (bound_addr.sin_addr.s_addr == 0) { 
     404            if (!pj_sockaddr_has_addr(&bound_addr)) { 
    393405                pj_sockaddr addr; 
    394406 
    395407                /* Get local IP address. */ 
    396                 status = pj_gethostip(pj_AF_INET(), &addr); 
     408                status = pj_gethostip(af, &addr); 
    397409                if (status != PJ_SUCCESS) 
    398410                    goto on_error; 
    399411 
    400                 bound_addr.sin_addr.s_addr = addr.ipv4.sin_addr.s_addr; 
     412                pj_sockaddr_copy_addr(&bound_addr, &addr); 
    401413            } 
    402414 
    403415            for (i=0; i<2; ++i) { 
    404                 pj_sockaddr_in_init(&mapped_addr[i], NULL, 0); 
    405                 mapped_addr[i].sin_addr.s_addr = bound_addr.sin_addr.s_addr; 
    406             } 
    407  
    408             mapped_addr[0].sin_port=pj_htons((pj_uint16_t)next_rtp_port); 
    409             mapped_addr[1].sin_port=pj_htons((pj_uint16_t)(next_rtp_port+1)); 
     416                pj_sockaddr_init(af, &mapped_addr[i], NULL, 0); 
     417                pj_sockaddr_copy_addr(&mapped_addr[i], &bound_addr); 
     418                pj_sockaddr_set_port(&mapped_addr[i], 
     419                                     (pj_uint16_t)(next_rtp_port+i)); 
     420            } 
     421 
    410422            break; 
    411423        } 
     
    420432 
    421433    skinfo->rtp_sock = sock[0]; 
    422     pj_memcpy(&skinfo->rtp_addr_name, 
    423               &mapped_addr[0], sizeof(pj_sockaddr_in)); 
     434    pj_sockaddr_cp(&skinfo->rtp_addr_name, &mapped_addr[0]); 
    424435 
    425436    skinfo->rtcp_sock = sock[1]; 
    426     pj_memcpy(&skinfo->rtcp_addr_name, 
    427               &mapped_addr[1], sizeof(pj_sockaddr_in)); 
     437    pj_sockaddr_cp(&skinfo->rtcp_addr_name, &mapped_addr[1]); 
    428438 
    429439    PJ_LOG(4,(THIS_FILE, "RTP socket reachable at %s", 
     
    19091919            /* Add connection line, if none */ 
    19101920            if (m->conn == NULL && sdp->conn == NULL) { 
     1921                pj_bool_t use_ipv6; 
     1922 
     1923                use_ipv6 = (pjsua_var.acc[call->acc_id].cfg.ipv6_media_use != 
     1924                            PJSUA_IPV6_DISABLED); 
     1925 
    19111926                m->conn = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_conn); 
    19121927                m->conn->net_type = pj_str("IN"); 
    1913                 m->conn->addr_type = pj_str("IP4"); 
    1914                 m->conn->addr = pj_str("127.0.0.1"); 
     1928                if (use_ipv6) { 
     1929                    m->conn->addr_type = pj_str("IP6"); 
     1930                    m->conn->addr = pj_str("::1"); 
     1931                } else { 
     1932                    m->conn->addr_type = pj_str("IP4"); 
     1933                    m->conn->addr = pj_str("127.0.0.1"); 
     1934                } 
    19151935            } 
    19161936 
Note: See TracChangeset for help on using the changeset viewer.