mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 02:37:10 +00:00 
			
		
		
		
	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
This commit is contained in:
		
				
					committed by
					
						 Richard Mudgett
						Richard Mudgett
					
				
			
			
				
	
			
			
			
						parent
						
							ff0569740a
						
					
				
				
					commit
					4e3b0cedba
				
			| @@ -2757,7 +2757,7 @@ static int sip_dialog_create_from(pj_pool_t *pool, pj_str_t *from, const char *u | ||||
| 	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]; | ||||
|  | ||||
| @@ -2777,21 +2777,21 @@ static int sip_dialog_create_from(pj_pool_t *pool, pj_str_t *from, const char *u | ||||
| 	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)) { | ||||
| @@ -2815,8 +2815,8 @@ static int sip_dialog_create_from(pj_pool_t *pool, pj_str_t *from, const char *u | ||||
| 	} | ||||
|  | ||||
| 	/* 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); | ||||
|   | ||||
| @@ -1086,7 +1086,7 @@ static int sip_dialog_create_contact(pj_pool_t *pool, pj_str_t *contact, const c | ||||
| 	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); | ||||
| @@ -1098,20 +1098,20 @@ static int sip_dialog_create_contact(pj_pool_t *pool, pj_str_t *contact, const c | ||||
|  | ||||
| 	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()), | ||||
| @@ -1120,7 +1120,7 @@ static int sip_dialog_create_contact(pj_pool_t *pool, pj_str_t *contact, const c | ||||
| 	} | ||||
|  | ||||
| 	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); | ||||
|   | ||||
| @@ -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 @@ static int transport_create(void *data) | ||||
| 		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 @@ static int transport_read(void *data) | ||||
| 	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 @@ static pj_bool_t websocket_on_rx_msg(pjsip_rx_data *rdata) | ||||
|  | ||||
| 	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 @@ static int load_module(void) | ||||
| 	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; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user