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/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.