|
|
|
@ -38,7 +38,6 @@
|
|
|
|
|
#include "asterisk/res_pjsip_session.h"
|
|
|
|
|
#include "asterisk/taskprocessor.h"
|
|
|
|
|
|
|
|
|
|
static int transport_type_ws;
|
|
|
|
|
static int transport_type_wss;
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
@ -149,6 +148,7 @@ static int transport_create(void *data)
|
|
|
|
|
pjsip_endpoint *endpt = ast_sip_get_pjsip_endpoint();
|
|
|
|
|
struct pjsip_tpmgr *tpmgr = pjsip_endpt_get_tpmgr(endpt);
|
|
|
|
|
|
|
|
|
|
char *ws_addr_str;
|
|
|
|
|
pj_pool_t *pool;
|
|
|
|
|
pj_str_t buf;
|
|
|
|
|
pj_status_t status;
|
|
|
|
@ -183,9 +183,23 @@ static int transport_create(void *data)
|
|
|
|
|
goto on_error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pj_sockaddr_parse(pj_AF_UNSPEC(), 0, pj_cstr(&buf, ast_sockaddr_stringify(ast_websocket_remote_address(newtransport->ws_session))), &newtransport->transport.key.rem_addr);
|
|
|
|
|
/*
|
|
|
|
|
* The type_name here is mostly used by log messages eihter in
|
|
|
|
|
* pjproject or Asterisk. Other places are reconstituting subscriptions
|
|
|
|
|
* after a restart (which could never work for a websocket connection anyway),
|
|
|
|
|
* received MESSAGE requests to set PJSIP_TRANSPORT, and most importantly
|
|
|
|
|
* by pjproject when generating the Via header.
|
|
|
|
|
*/
|
|
|
|
|
newtransport->transport.type_name = ast_websocket_is_secure(newtransport->ws_session)
|
|
|
|
|
? "WSS" : "WS";
|
|
|
|
|
|
|
|
|
|
ws_addr_str = ast_sockaddr_stringify(ast_websocket_remote_address(newtransport->ws_session));
|
|
|
|
|
ast_debug(4, "Creating websocket transport for %s:%s\n",
|
|
|
|
|
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 = ast_websocket_is_secure(newtransport->ws_session) ? transport_type_wss : transport_type_ws;
|
|
|
|
|
newtransport->transport.key.type = transport_type_wss;
|
|
|
|
|
|
|
|
|
|
newtransport->transport.addr_len = pj_sockaddr_get_len(&newtransport->transport.key.rem_addr);
|
|
|
|
|
|
|
|
|
@ -196,7 +210,6 @@ static int transport_create(void *data)
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
newtransport->transport.type_name = (char *)pjsip_transport_get_type_name(newtransport->transport.key.type);
|
|
|
|
|
newtransport->transport.flag = pjsip_transport_get_flag_from_type((pjsip_transport_type_e)newtransport->transport.key.type);
|
|
|
|
|
newtransport->transport.info = (char *)pj_pool_alloc(newtransport->transport.pool, 64);
|
|
|
|
|
|
|
|
|
@ -382,19 +395,27 @@ 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_ws && type != (long)transport_type_wss) {
|
|
|
|
|
if (type != (long) transport_type_wss) {
|
|
|
|
|
return PJ_FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((contact = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, NULL)) && !contact->star &&
|
|
|
|
|
(PJSIP_URI_SCHEME_IS_SIP(contact->uri) || PJSIP_URI_SCHEME_IS_SIPS(contact->uri))) {
|
|
|
|
|
contact = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, NULL);
|
|
|
|
|
if (contact
|
|
|
|
|
&& !contact->star
|
|
|
|
|
&& (PJSIP_URI_SCHEME_IS_SIP(contact->uri) || PJSIP_URI_SCHEME_IS_SIPS(contact->uri))) {
|
|
|
|
|
pjsip_sip_uri *uri = pjsip_uri_get_uri(contact->uri);
|
|
|
|
|
const pj_str_t *txp_str = &STR_WS;
|
|
|
|
|
|
|
|
|
|
ast_debug(4, "%s re-writing Contact URI from %.*s:%d%s%.*s to %s:%d;transport=%s\n",
|
|
|
|
|
pjsip_rx_data_get_info(rdata),
|
|
|
|
|
(int)pj_strlen(&uri->host), pj_strbuf(&uri->host), uri->port,
|
|
|
|
|
pj_strlen(&uri->transport_param) ? ";transport=" : "",
|
|
|
|
|
(int)pj_strlen(&uri->transport_param), pj_strbuf(&uri->transport_param),
|
|
|
|
|
rdata->pkt_info.src_name ?: "", rdata->pkt_info.src_port, pj_strbuf(txp_str));
|
|
|
|
|
|
|
|
|
|
pj_cstr(&uri->host, rdata->pkt_info.src_name);
|
|
|
|
|
uri->port = rdata->pkt_info.src_port;
|
|
|
|
|
ast_debug(4, "Re-wrote Contact URI host/port to %.*s:%d\n",
|
|
|
|
|
(int)pj_strlen(&uri->host), pj_strbuf(&uri->host), uri->port);
|
|
|
|
|
pj_strdup(rdata->tp_info.pool, &uri->transport_param, &STR_WS);
|
|
|
|
|
pj_strdup(rdata->tp_info.pool, &uri->transport_param, txp_str);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rdata->msg_info.via->rport_param = 0;
|
|
|
|
@ -429,8 +450,16 @@ static int load_module(void)
|
|
|
|
|
{
|
|
|
|
|
CHECK_PJSIP_MODULE_LOADED();
|
|
|
|
|
|
|
|
|
|
pjsip_transport_register_type(PJSIP_TRANSPORT_RELIABLE, "WS", 5060, &transport_type_ws);
|
|
|
|
|
pjsip_transport_register_type(PJSIP_TRANSPORT_RELIABLE | PJSIP_TRANSPORT_SECURE, "WS", 5060, &transport_type_wss);
|
|
|
|
|
/*
|
|
|
|
|
* We only need one transport type 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.
|
|
|
|
|
*/
|
|
|
|
|
pjsip_transport_register_type(PJSIP_TRANSPORT_RELIABLE | PJSIP_TRANSPORT_SECURE, "ws", 5060, &transport_type_wss);
|
|
|
|
|
|
|
|
|
|
if (ast_sip_register_service(&websocket_module) != PJ_SUCCESS) {
|
|
|
|
|
return AST_MODULE_LOAD_DECLINE;
|
|
|
|
|