--- res/res_pjsip_sdp_rtp.c (Asterisk 13.10.0) +++ res/res_pjsip_sdp_rtp.c (working copy) @@ -1057,6 +1057,20 @@ /* If no type formats are configured don't add a stream */ return 0; - } else if (!session_media->rtp && create_rtp(session, session_media, session->endpoint->media.rtp.ipv6)) { - return -1; + } else if (!session_media->rtp) { + unsigned int ip6; + + if (session->contact) { + /* IP6 addresses contain at least one colon. IP4 do not, because + * a port is stored in another variable: contact->via_port + */ + ip6 = strstr(session->contact->via_addr, ":") ? 1 : 0; + } else { + ast_log(LOG_ERROR, "Cannot determine whether to use IP4 or IP6; falling back to rtp_ipv6 of endpoint. Please, report as issue!\n"); + ip6 = session->endpoint->media.rtp.ipv6; + } + + if (create_rtp(session, session_media, ip6)) { + return -1; + } } @@ -1084,8 +1098,9 @@ /* Add connection level details */ + ast_rtp_instance_get_local_address(session_media->rtp, &addr); if (direct_media_enabled) { hostip = ast_sockaddr_stringify_fmt(&session_media->direct_media_addr, AST_SOCKADDR_STR_ADDR); } else if (ast_strlen_zero(session->endpoint->media.address)) { - hostip = ast_sip_get_host_ip_string(session->endpoint->media.rtp.ipv6 ? pj_AF_INET6() : pj_AF_INET()); + hostip = ast_sip_get_host_ip_string((ast_sockaddr_is_ipv6(&addr)) ? pj_AF_INET6() : pj_AF_INET()); } else { hostip = session->endpoint->media.address; @@ -1098,7 +1113,6 @@ media->conn->net_type = STR_IN; - media->conn->addr_type = session->endpoint->media.rtp.ipv6 ? STR_IP6 : STR_IP4; + media->conn->addr_type = (ast_sockaddr_is_ipv6(&addr)) ? STR_IP6 : STR_IP4; pj_strdup2(pool, &media->conn->addr, hostip); - ast_rtp_instance_get_local_address(session_media->rtp, &addr); media->desc.port = direct_media_enabled ? ast_sockaddr_port(&session_media->direct_media_addr) : (pj_uint16_t) ast_sockaddr_port(&addr); media->desc.port_count = 1; @@ -1235,6 +1249,22 @@ /* Create an RTP instance if need be */ - if (!session_media->rtp && create_rtp(session, session_media, session->endpoint->media.rtp.ipv6)) { - return -1; + if (!session_media->rtp) { + unsigned int ip6; + + if (remote_stream->conn) { /* query RTP, but c= is optional */ + ip6 = pj_stricmp2(&remote_stream->conn->addr_type, "IP4"); + } else if (session->contact) { /* query SIP */ + /* IP6 addresses contain at least one colon. IP4 do not, because + * a port is stored in another variable: contact->via_port + */ + ip6 = strstr(session->contact->via_addr, ":") ? 1 : 0; + } else { + ast_log(LOG_ERROR, "Cannot determine whether to use IP4 or IP6; falling back to rtp_ipv6 of endpoint. Please, report as issue!\n"); + ip6 = session->endpoint->media.rtp.ipv6; + } + + if (create_rtp(session, session_media, ip6)) { + return -1; + } } --- res/res_pjsip_session.c (Asterisk 13.10.0) +++ res/res_pjsip_session.c (working copy) @@ -2844,11 +2844,23 @@ } } else { + unsigned int ip6; + + if (session->contact) { + /* IP6 addresses contain at least one colon. IP4 do not, because + * a port is stored in another variable: contact->via_port + */ + ip6 = strstr(session->contact->via_addr, ":") ? 1 : 0; + } else { + ast_log(LOG_ERROR, "Cannot determine whether to use IP4 or IP6; falling back to rtp_ipv6 of endpoint. Please, report as issue!\n"); + ip6 = session->endpoint->media.rtp.ipv6; + } + local->origin.net_type = STR_IN; - local->origin.addr_type = session->endpoint->media.rtp.ipv6 ? STR_IP6 : STR_IP4; + local->origin.addr_type = ip6 ? STR_IP6 : STR_IP4; if (!ast_strlen_zero(session->endpoint->media.address)) { pj_strdup2(inv->pool_prov, &local->origin.addr, session->endpoint->media.address); } else { - pj_strdup2(inv->pool_prov, &local->origin.addr, ast_sip_get_host_ip_string(session->endpoint->media.rtp.ipv6 ? pj_AF_INET6() : pj_AF_INET())); + pj_strdup2(inv->pool_prov, &local->origin.addr, ast_sip_get_host_ip_string(ip6 ? pj_AF_INET6() : pj_AF_INET())); } } --- res/res_pjsip_t38.c (Asterisk 13.10.0) +++ res/res_pjsip_t38.c (working copy) @@ -256,10 +256,22 @@ static int t38_initialize_session(struct ast_sip_session *session, struct ast_sip_session_media *session_media) { + unsigned int ip6; + if (session_media->udptl) { return 0; } + if (session->contact) { + /* IP6 addresses contain at least one colon. IP4 do not, because + * a port is stored in another variable: contact->via_port + */ + ip6 = strstr(session->contact->via_addr, ":") ? 1 : 0; + } else { + ast_log(LOG_ERROR, "Cannot determine whether to use IP4 or IP6; falling back to t38_udptl_ipv6 of endpoint. Please, report as issue!\n"); + ip6 = session->endpoint->media.t38.ipv6; + } + if (!(session_media->udptl = ast_udptl_new_with_bindaddr(NULL, NULL, 0, - session->endpoint->media.t38.ipv6 ? &address_ipv6 : &address_ipv4))) { + ip6 ? &address_ipv6 : &address_ipv4))) { return -1; } @@ -699,12 +711,4 @@ } - /* Check the address family to make sure it matches configured */ - if ((ast_sockaddr_is_ipv6(addrs) && !session->endpoint->media.t38.ipv6) || - (ast_sockaddr_is_ipv4(addrs) && session->endpoint->media.t38.ipv6)) { - /* The address does not match configured */ - ast_debug(3, "Declining, provided host does not match configured address family\n"); - return -1; - } - return 1; } @@ -730,4 +734,5 @@ char tmp[512]; pj_str_t stmp; + unsigned int ip6; if (!session->endpoint->media.t38.enabled) { @@ -753,6 +758,16 @@ media->desc.transport = STR_UDPTL; + if (session->contact) { + /* IP6 addresses contain at least one colon. IP4 do not, because + * a port is stored in another variable: contact->via_port + */ + ip6 = strstr(session->contact->via_addr, ":") ? 1 : 0; + } else { + ast_log(LOG_ERROR, "Cannot determine whether to use IP4 or IP6; falling back to t38_udptl_ipv6 of endpoint. Please, report as issue!\n"); + ip6 = session->endpoint->media.t38.ipv6; + } + if (ast_strlen_zero(session->endpoint->media.address)) { - hostip = ast_sip_get_host_ip_string(session->endpoint->media.t38.ipv6 ? pj_AF_INET6() : pj_AF_INET()); + hostip = ast_sip_get_host_ip_string(ip6 ? pj_AF_INET6() : pj_AF_INET()); } else { hostip = session->endpoint->media.address; @@ -765,5 +780,5 @@ media->conn->net_type = STR_IN; - media->conn->addr_type = session->endpoint->media.t38.ipv6 ? STR_IP6 : STR_IP4; + media->conn->addr_type = ip6 ? STR_IP6 : STR_IP4; pj_strdup2(pool, &media->conn->addr, hostip); ast_udptl_get_us(session_media->udptl, &addr); --- contrib/scripts/sip_to_pjsip/sip_to_pjsip.py (Asterisk 13.10.0) +++ contrib/scripts/sip_to_pjsip/sip_to_pjsip.py (working copy) @@ -371,2 +371 @@ -# type, rtp_ipv6, 100rel, trust_id_outbound, aggregate_mwi, -# connected_line_method +# type, 100rel, trust_id_outbound, aggregate_mwi, connected_line_method --- configs/samples/pjsip.conf.sample (Asterisk 13.10.0) +++ configs/samples/pjsip.conf.sample (working copy) @@ -115,3 +114,0 @@ -; IPv6: For endpoints using IPv6, remember to set "rtp_ipv6=yes" so that the RTP -; engine will also be able to bind to an IPv6 address. -; @@ -297,2 +293,0 @@ -; Use the "rtp_ipv6=yes" option if you want to utilize RTP over an ipv6 transport. -; @@ -317,2 +311,0 @@ -;transport=transport-udp-ipv6 -;rtp_ipv6=yes @@ -647 +639,0 @@ -;rtp_ipv6=no ; Allow use of IPv6 for RTP traffic (default: "no") @@ -696,2 +687,0 @@ -;t38_udptl_ipv6=no ; Whether IPv6 is used for UDPTL Sessions (default: - ; "no")