[Asterisk-code-review] res pjsip transport websocket: Add support for IPv6. (asterisk[13])

Joshua Colp asteriskteam at digium.com
Tue Mar 14 18:50:18 CDT 2017


Joshua Colp has submitted this change and it was merged. ( https://gerrit.asterisk.org/5134 )

Change subject: res_pjsip_transport_websocket: Add support for IPv6.
......................................................................


res_pjsip_transport_websocket: Add support for IPv6.

This change adds a PJSIP patch (which has been contributed upstream)
to allow the registration of IPv6 transport types.

Using this the res_pjsip_transport_websocket module now registers
an IPv6 Websocket transport and uses it for the corresponding
traffic.

ASTERISK-26685

Change-Id: Id1f9126f995b31dc38db8fdb58afd289b4ad1647
---
M res/res_pjsip.c
M res/res_pjsip_outbound_registration.c
M res/res_pjsip_transport_websocket.c
A third-party/pjproject/patches/0014-Add-pjsip-transport-register-type-ipv6.patch
4 files changed, 100 insertions(+), 32 deletions(-)

Approvals:
  Kevin Harwell: Looks good to me, but someone else must approve
  Mark Michelson: Looks good to me, approved
  George Joseph: Looks good to me, but someone else must approve
  Anonymous Coward #1000019: Verified



diff --git a/res/res_pjsip.c b/res/res_pjsip.c
index 54a0a5f..347658f 100644
--- a/res/res_pjsip.c
+++ b/res/res_pjsip.c
@@ -2755,7 +2755,7 @@
 	pj_str_t tmp, local_addr;
 	pjsip_uri *uri;
 	pjsip_sip_uri *sip_uri;
-	pjsip_transport_type_e type = PJSIP_TRANSPORT_UNSPECIFIED;
+	pjsip_transport_type_e type;
 	int local_port;
 	char default_user[PJSIP_MAX_URL_SIZE];
 
@@ -2775,21 +2775,21 @@
 	sip_uri = pjsip_uri_get_uri(uri);
 
 	/* Determine the transport type to use */
+	type = pjsip_transport_get_type_from_name(&sip_uri->transport_param);
 	if (PJSIP_URI_SCHEME_IS_SIPS(sip_uri)) {
-		type = PJSIP_TRANSPORT_TLS;
+		if (type == PJSIP_TRANSPORT_UNSPECIFIED
+			|| !(pjsip_transport_get_flag_from_type(type) & PJSIP_TRANSPORT_SECURE)) {
+			type = PJSIP_TRANSPORT_TLS;
+		}
 	} else if (!sip_uri->transport_param.slen) {
 		type = PJSIP_TRANSPORT_UDP;
-	} else {
-		type = pjsip_transport_get_type_from_name(&sip_uri->transport_param);
-	}
-
-	if (type == PJSIP_TRANSPORT_UNSPECIFIED) {
+	} else if (type == PJSIP_TRANSPORT_UNSPECIFIED) {
 		return -1;
 	}
 
 	/* If the host is IPv6 turn the transport into an IPv6 version */
-	if (pj_strchr(&sip_uri->host, ':') && type < PJSIP_TRANSPORT_START_OTHER) {
-		type = (pjsip_transport_type_e)(((int)type) + PJSIP_TRANSPORT_IPV6);
+	if (pj_strchr(&sip_uri->host, ':')) {
+		type |= PJSIP_TRANSPORT_IPV6;
 	}
 
 	if (!ast_strlen_zero(domain)) {
@@ -2813,8 +2813,8 @@
 	}
 
 	/* If IPv6 was specified in the transport, set the proper type */
-	if (pj_strchr(&local_addr, ':') && type < PJSIP_TRANSPORT_START_OTHER) {
-		type = (pjsip_transport_type_e)(((int)type) + PJSIP_TRANSPORT_IPV6);
+	if (pj_strchr(&local_addr, ':')) {
+		type |= PJSIP_TRANSPORT_IPV6;
 	}
 
 	from->ptr = pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE);
diff --git a/res/res_pjsip_outbound_registration.c b/res/res_pjsip_outbound_registration.c
index 7a0b60a..ee1894f 100644
--- a/res/res_pjsip_outbound_registration.c
+++ b/res/res_pjsip_outbound_registration.c
@@ -1087,7 +1087,7 @@
 	pj_str_t tmp, local_addr;
 	pjsip_uri *uri;
 	pjsip_sip_uri *sip_uri;
-	pjsip_transport_type_e type = PJSIP_TRANSPORT_UNSPECIFIED;
+	pjsip_transport_type_e type;
 	int local_port;
 
 	pj_strdup_with_null(pool, &tmp, target);
@@ -1099,20 +1099,20 @@
 
 	sip_uri = pjsip_uri_get_uri(uri);
 
+	type = pjsip_transport_get_type_from_name(&sip_uri->transport_param);
 	if (PJSIP_URI_SCHEME_IS_SIPS(sip_uri)) {
-		type = PJSIP_TRANSPORT_TLS;
+		if (type == PJSIP_TRANSPORT_UNSPECIFIED
+			|| !(pjsip_transport_get_flag_from_type(type) & PJSIP_TRANSPORT_SECURE)) {
+			type = PJSIP_TRANSPORT_TLS;
+		}
 	} else if (!sip_uri->transport_param.slen) {
 		type = PJSIP_TRANSPORT_UDP;
-	} else {
-		type = pjsip_transport_get_type_from_name(&sip_uri->transport_param);
-	}
-
-	if (type == PJSIP_TRANSPORT_UNSPECIFIED) {
+	} else if (type == PJSIP_TRANSPORT_UNSPECIFIED) {
 		return -1;
 	}
 
 	if (pj_strchr(&sip_uri->host, ':')) {
-		type = (pjsip_transport_type_e)(((int)type) + PJSIP_TRANSPORT_IPV6);
+		type |= PJSIP_TRANSPORT_IPV6;
 	}
 
 	if (pjsip_tpmgr_find_local_addr(pjsip_endpt_get_tpmgr(ast_sip_get_pjsip_endpoint()),
@@ -1121,7 +1121,7 @@
 	}
 
 	if (!pj_strchr(&sip_uri->host, ':') && pj_strchr(&local_addr, ':')) {
-		type = (pjsip_transport_type_e)(((int)type) + PJSIP_TRANSPORT_IPV6);
+		type |= PJSIP_TRANSPORT_IPV6;
 	}
 
 	contact->ptr = pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE);
diff --git a/res/res_pjsip_transport_websocket.c b/res/res_pjsip_transport_websocket.c
index ff8e346..1b9d616 100644
--- a/res/res_pjsip_transport_websocket.c
+++ b/res/res_pjsip_transport_websocket.c
@@ -39,6 +39,7 @@
 #include "asterisk/taskprocessor.h"
 
 static int transport_type_wss;
+static int transport_type_wss_ipv6;
 
 /*!
  * \brief Wrapper for pjsip_transport, for storing the WebSocket session
@@ -198,15 +199,20 @@
 		newtransport->transport.type_name, ws_addr_str);
 
 	pj_sockaddr_parse(pj_AF_UNSPEC(), 0, pj_cstr(&buf, ws_addr_str), &newtransport->transport.key.rem_addr);
-	newtransport->transport.key.rem_addr.addr.sa_family = pj_AF_INET();
-	newtransport->transport.key.type = transport_type_wss;
+	if (newtransport->transport.key.rem_addr.addr.sa_family == pj_AF_INET6()) {
+		newtransport->transport.key.type = transport_type_wss_ipv6;
+		newtransport->transport.local_name.host.ptr = (char *)pj_pool_alloc(pool, PJ_INET6_ADDRSTRLEN);
+		pj_sockaddr_print(&newtransport->transport.key.rem_addr, newtransport->transport.local_name.host.ptr, PJ_INET6_ADDRSTRLEN, 0);
+	} else {
+		newtransport->transport.key.type = transport_type_wss;
+		newtransport->transport.local_name.host.ptr = (char *)pj_pool_alloc(pool, PJ_INET_ADDRSTRLEN);
+		pj_sockaddr_print(&newtransport->transport.key.rem_addr, newtransport->transport.local_name.host.ptr, PJ_INET_ADDRSTRLEN, 0);
+	}
 
 	newtransport->transport.addr_len = pj_sockaddr_get_len(&newtransport->transport.key.rem_addr);
 
 	pj_sockaddr_cp(&newtransport->transport.local_addr, &newtransport->transport.key.rem_addr);
 
-	newtransport->transport.local_name.host.ptr = (char *)pj_pool_alloc(pool, newtransport->transport.addr_len+4);
-	pj_sockaddr_print(&newtransport->transport.key.rem_addr, newtransport->transport.local_name.host.ptr, newtransport->transport.addr_len+4, 0);
 	newtransport->transport.local_name.host.slen = pj_ansi_strlen(newtransport->transport.local_name.host.ptr);
 	newtransport->transport.local_name.port = pj_sockaddr_get_port(&newtransport->transport.key.rem_addr);
 
@@ -271,8 +277,6 @@
 	rdata->pkt_info.zero = 0;
 
 	pj_sockaddr_parse(pj_AF_UNSPEC(), 0, pj_cstr(&buf, ast_sockaddr_stringify(ast_websocket_remote_address(session))), &rdata->pkt_info.src_addr);
-	rdata->pkt_info.src_addr.addr.sa_family = pj_AF_INET();
-
 	rdata->pkt_info.src_addr_len = sizeof(rdata->pkt_info.src_addr);
 
 	pj_ansi_strcpy(rdata->pkt_info.src_name, ast_sockaddr_stringify_host(ast_websocket_remote_address(session)));
@@ -395,7 +399,7 @@
 
 	long type = rdata->tp_info.transport->key.type;
 
-	if (type != (long) transport_type_wss) {
+	if (type != (long) transport_type_wss && type != (long) transport_type_wss_ipv6) {
 		return PJ_FALSE;
 	}
 
@@ -451,15 +455,17 @@
 	CHECK_PJSIP_MODULE_LOADED();
 
 	/*
-	 * We only need one transport type defined.  Firefox and Chrome
-	 * do not support anything other than secure websockets anymore.
+	 * We only need one transport type name (ws) defined.  Firefox
+	 * and Chrome do not support anything other than secure websockets
+	 * anymore.
 	 *
 	 * Also we really cannot have two transports with the same name
-	 * because it would be ambiguous.  Outgoing requests may try to
-	 * find the transport by name and pjproject only finds the first
-	 * one registered.
+	 * and address family because it would be ambiguous.  Outgoing
+	 * requests may try to find the transport by name and pjproject
+	 * only finds the first one registered.
 	 */
 	pjsip_transport_register_type(PJSIP_TRANSPORT_RELIABLE | PJSIP_TRANSPORT_SECURE, "ws", 5060, &transport_type_wss);
+	pjsip_transport_register_type(PJSIP_TRANSPORT_RELIABLE | PJSIP_TRANSPORT_SECURE | PJSIP_TRANSPORT_IPV6, "ws", 5060, &transport_type_wss_ipv6);
 
 	if (ast_sip_register_service(&websocket_module) != PJ_SUCCESS) {
 		return AST_MODULE_LOAD_DECLINE;
diff --git a/third-party/pjproject/patches/0014-Add-pjsip-transport-register-type-ipv6.patch b/third-party/pjproject/patches/0014-Add-pjsip-transport-register-type-ipv6.patch
new file mode 100644
index 0000000..796473a
--- /dev/null
+++ b/third-party/pjproject/patches/0014-Add-pjsip-transport-register-type-ipv6.patch
@@ -0,0 +1,62 @@
+From daeb0956524606b597704a90b54d81340e10b3e4 Mon Sep 17 00:00:00 2001
+From: Joshua Colp <jcolp at digium.com>
+Date: Tue, 7 Mar 2017 12:32:49 +0000
+Subject: [PATCH] Add support for registering IPv6 transport type.
+
+This change allows an IPv6 transport type to be registered
+and used. The IPv4 transport is found (if available) and the
+IPv4 flag added to its type to match how the finding of
+IPv6 transport types works.
+---
+ pjsip/src/pjsip/sip_transport.c | 15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/pjsip/src/pjsip/sip_transport.c b/pjsip/src/pjsip/sip_transport.c
+index 7df6138..ce72814 100644
+--- a/pjsip/src/pjsip/sip_transport.c
++++ b/pjsip/src/pjsip/sip_transport.c
+@@ -236,6 +236,7 @@ PJ_DEF(pj_status_t) pjsip_transport_register_type( unsigned tp_flag,
+ 						   int *p_tp_type)
+ {
+     unsigned i;
++    pjsip_transport_type_e parent = 0;
+ 
+     PJ_ASSERT_RETURN(tp_flag && tp_name && def_port, PJ_EINVAL);
+     PJ_ASSERT_RETURN(pj_ansi_strlen(tp_name) <
+@@ -243,6 +244,11 @@ PJ_DEF(pj_status_t) pjsip_transport_register_type( unsigned tp_flag,
+ 		     PJ_ENAMETOOLONG);
+ 
+     for (i=1; i<PJ_ARRAY_SIZE(transport_names); ++i) {
++        if (tp_flag & PJSIP_TRANSPORT_IPV6 &&
++            pj_stricmp2(&transport_names[i].name, tp_name) == 0)
++        {
++	    parent = transport_names[i].type;
++        }
+ 	if (transport_names[i].type == 0)
+ 	    break;
+     }
+@@ -250,14 +256,19 @@ PJ_DEF(pj_status_t) pjsip_transport_register_type( unsigned tp_flag,
+     if (i == PJ_ARRAY_SIZE(transport_names))
+ 	return PJ_ETOOMANY;
+ 
+-    transport_names[i].type = (pjsip_transport_type_e)i;
++    if (tp_flag & PJSIP_TRANSPORT_IPV6 && parent) {
++        transport_names[i].type = parent | PJSIP_TRANSPORT_IPV6;
++    } else {
++        transport_names[i].type = (pjsip_transport_type_e)i;
++    }
++
+     transport_names[i].port = (pj_uint16_t)def_port;
+     pj_ansi_strcpy(transport_names[i].name_buf, tp_name);
+     transport_names[i].name = pj_str(transport_names[i].name_buf);
+     transport_names[i].flag = tp_flag;
+ 
+     if (p_tp_type)
+-	*p_tp_type = i;
++	*p_tp_type = transport_names[i].type;
+ 
+     return PJ_SUCCESS;
+ }
+-- 
+2.7.4
+

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

Gerrit-MessageType: merged
Gerrit-Change-Id: Id1f9126f995b31dc38db8fdb58afd289b4ad1647
Gerrit-PatchSet: 6
Gerrit-Project: asterisk
Gerrit-Branch: 13
Gerrit-Owner: Joshua Colp <jcolp at digium.com>
Gerrit-Reviewer: Anonymous Coward #1000019
Gerrit-Reviewer: George Joseph <gjoseph at digium.com>
Gerrit-Reviewer: Joshua Colp <jcolp at digium.com>
Gerrit-Reviewer: Kevin Harwell <kharwell at digium.com>
Gerrit-Reviewer: Mark Michelson <mmichelson at digium.com>
Gerrit-Reviewer: Richard Mudgett <rmudgett at digium.com>



More information about the asterisk-code-review mailing list