mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-12 15:45:18 +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
parent
a860bf63e1
commit
2a85888262
@@ -2755,7 +2755,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];
|
||||
|
||||
@@ -2775,21 +2775,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)) {
|
||||
@@ -2813,8 +2813,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);
|
||||
|
@@ -1087,7 +1087,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);
|
||||
@@ -1099,20 +1099,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()),
|
||||
@@ -1121,7 +1121,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