[Asterisk-code-review] res pjsip: Re-use IP version of signaling (SIP) for media (R... (asterisk[14])

Alexander Traud asteriskteam at digium.com
Sat Aug 20 14:24:53 CDT 2016


Alexander Traud has uploaded a new change for review.

  https://gerrit.asterisk.org/3664

Change subject: res_pjsip: Re-use IP version of signaling (SIP) for media (RTP).
......................................................................

res_pjsip: Re-use IP version of signaling (SIP) for media (RTP).

Previously, the parameter rtp_ipv6 had to be configured for each endpoint in the
file pjsip.conf, in advance, before a SIP client connected to Asterisk. That
defeated the idea of an IPv4/IPv6 Dual Stack server, for which the IP versions
of the client is *not* known in advance. This was no issue for the channel
driver chan_sip and therefore this was changed in res_pjsip only.

ASTERISK-26309 #close

Change-Id: I01a85a8c6723fcc12e86139f80e090e2078d04bb
---
M configs/samples/pjsip.conf.sample
M contrib/scripts/sip_to_pjsip/sip_to_pjsip.py
M res/res_pjsip_sdp_rtp.c
M res/res_pjsip_session.c
M res/res_pjsip_t38.c
5 files changed, 78 insertions(+), 32 deletions(-)


  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/64/3664/1

diff --git a/configs/samples/pjsip.conf.sample b/configs/samples/pjsip.conf.sample
index 0d1c039..6d749aa 100644
--- a/configs/samples/pjsip.conf.sample
+++ b/configs/samples/pjsip.conf.sample
@@ -112,9 +112,6 @@
 ; the prefix "external_" will only apply to communication with addresses
 ; outside the range set with "local_net=".
 ;
-; 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.
-;
 ; You can have more than one of any type of transport, as long as it doesn't
 ; use the same resources (bind address, port, etc) as the others.
 
@@ -294,8 +291,6 @@
 ; If using the TLS enabled transport, you may want the "media_encryption=sdes"
 ; option to additionally enable SRTP, though they are not mutually inclusive.
 ;
-; Use the "rtp_ipv6=yes" option if you want to utilize RTP over an ipv6 transport.
-;
 ; If this endpoint were remote, and it was using a transport configured for NAT
 ; then you likely want to use "direct_media=no" to prevent audio issues.
 
@@ -314,8 +309,6 @@
 ;
 ;transport=transport-tls
 ;media_encryption=sdes
-;transport=transport-udp-ipv6
-;rtp_ipv6=yes
 ;transport=transport-udp-nat
 ;direct_media=no
 ;
@@ -646,7 +639,6 @@
                         ; must be provided (default: "")
 ;rewrite_contact=no     ; Allow Contact header to be rewritten with the source
                         ; IP address port (default: "no")
-;rtp_ipv6=no    ; Allow use of IPv6 for RTP traffic (default: "no")
 ;rtp_symmetric=no       ; Enforce that RTP must be symmetric (default: "no")
 ;send_diversion=yes     ; Send the Diversion header conveying the diversion
                         ; information to the called user agent (default: "yes")
@@ -699,8 +691,6 @@
                         ; (default: "0")
 ;t38_udptl_nat=no       ; Whether NAT support is enabled on UDPTL sessions
                         ; (default: "no")
-;t38_udptl_ipv6=no      ; Whether IPv6 is used for UDPTL Sessions (default:
-                        ; "no")
 ;tone_zone=     ; Set which country s indications to use for channels created
                 ; for this endpoint (default: "")
 ;language=      ; Set the default language to use for channels created for this
diff --git a/contrib/scripts/sip_to_pjsip/sip_to_pjsip.py b/contrib/scripts/sip_to_pjsip/sip_to_pjsip.py
index ee01edf..898f226 100755
--- a/contrib/scripts/sip_to_pjsip/sip_to_pjsip.py
+++ b/contrib/scripts/sip_to_pjsip/sip_to_pjsip.py
@@ -368,8 +368,7 @@
 ###############################################################################
 
 # options in pjsip.conf on an endpoint that have no sip.conf equivalent:
-# type, rtp_ipv6, 100rel, trust_id_outbound, aggregate_mwi,
-# connected_line_method
+# type, 100rel, trust_id_outbound, aggregate_mwi, connected_line_method
 
 # known sip.conf peer keys that can be mapped to a pjsip.conf section/key
 peer_map = [
diff --git a/res/res_pjsip_sdp_rtp.c b/res/res_pjsip_sdp_rtp.c
index 6610ef1..ef9faec 100644
--- a/res/res_pjsip_sdp_rtp.c
+++ b/res/res_pjsip_sdp_rtp.c
@@ -1074,8 +1074,22 @@
 	    (!use_override_prefs && !ast_format_cap_has_type(session->endpoint->media.codecs, media_type))) {
 		/* 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;
+		}
 	}
 
 	if (!(media = pj_pool_zalloc(pool, sizeof(struct pjmedia_sdp_media))) ||
@@ -1101,10 +1115,11 @@
 	}
 
 	/* 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;
 	}
@@ -1115,9 +1130,8 @@
 	}
 
 	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;
 
@@ -1252,8 +1266,24 @@
 	}
 
 	/* 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 = setup_media_encryption(session, session_media, remote, remote_stream);
diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c
index 315393f..af58c12 100644
--- a/res/res_pjsip_session.c
+++ b/res/res_pjsip_session.c
@@ -2954,13 +2954,25 @@
 			}
 		}
 	} 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()));
 		}
 	}
 
diff --git a/res/res_pjsip_t38.c b/res/res_pjsip_t38.c
index 76720ac..b75c22c 100644
--- a/res/res_pjsip_t38.c
+++ b/res/res_pjsip_t38.c
@@ -255,12 +255,24 @@
 /*! \brief Initializes UDPTL support on a session, only done when actually needed */
 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;
 	}
 
@@ -700,14 +712,6 @@
 		return -1;
 	}
 
-	/* 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;
 }
 
@@ -731,6 +735,7 @@
 	struct ast_sockaddr addr;
 	char tmp[512];
 	pj_str_t stmp;
+	unsigned int ip6;
 
 	if (!session->endpoint->media.t38.enabled) {
 		ast_debug(3, "Not creating outgoing SDP stream: T.38 not enabled\n");
@@ -754,8 +759,18 @@
 	media->desc.media = pj_str(session_media->stream_type);
 	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;
 	}
@@ -766,7 +781,7 @@
 	}
 
 	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);
 	media->desc.port = (pj_uint16_t) ast_sockaddr_port(&addr);

-- 
To view, visit https://gerrit.asterisk.org/3664
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I01a85a8c6723fcc12e86139f80e090e2078d04bb
Gerrit-PatchSet: 1
Gerrit-Project: asterisk
Gerrit-Branch: 14
Gerrit-Owner: Alexander Traud <pabstraud at compuserve.com>



More information about the asterisk-code-review mailing list