summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/asterisk/http_websocket.h9
-rw-r--r--res/res_hep_pjsip.c90
-rw-r--r--res/res_http_websocket.c50
-rw-r--r--res/res_pjsip_transport_websocket.c12
4 files changed, 98 insertions, 63 deletions
diff --git a/include/asterisk/http_websocket.h b/include/asterisk/http_websocket.h
index cd49dbe48..2180ef46b 100644
--- a/include/asterisk/http_websocket.h
+++ b/include/asterisk/http_websocket.h
@@ -345,6 +345,15 @@ AST_OPTIONAL_API(int, ast_websocket_fd, (struct ast_websocket *session), { errno
AST_OPTIONAL_API(struct ast_sockaddr *, ast_websocket_remote_address, (struct ast_websocket *session), {return NULL;});
/*!
+ * \brief Get the local address for a WebSocket connection session.
+ *
+ * \retval ast_sockaddr Local address
+ *
+ * \since 13.19.0
+ */
+AST_OPTIONAL_API(struct ast_sockaddr *, ast_websocket_local_address, (struct ast_websocket *session), {return NULL;});
+
+/*!
* \brief Get whether the WebSocket session is using a secure transport or not.
*
* \retval 0 if unsecure
diff --git a/res/res_hep_pjsip.c b/res/res_hep_pjsip.c
index 13efbfa6a..b5be4a102 100644
--- a/res/res_hep_pjsip.c
+++ b/res/res_hep_pjsip.c
@@ -89,35 +89,44 @@ static pj_status_t logging_on_tx_msg(pjsip_tx_data *tdata)
pjsip_cid_hdr *cid_hdr;
pjsip_from_hdr *from_hdr;
pjsip_to_hdr *to_hdr;
- pjsip_tpmgr_fla2_param prm;
capture_info = hepv3_create_capture_info(tdata->buf.start, (size_t)(tdata->buf.cur - tdata->buf.start));
if (!capture_info) {
return PJ_SUCCESS;
}
- /* Attempt to determine what IP address will we send this packet out of */
- pjsip_tpmgr_fla2_param_default(&prm);
- prm.tp_type = tdata->tp_info.transport->key.type;
- pj_strset2(&prm.dst_host, tdata->tp_info.dst_name);
- prm.local_if = PJ_TRUE;
+ if (!(tdata->tp_info.transport->flag & PJSIP_TRANSPORT_RELIABLE)) {
+ pjsip_tpmgr_fla2_param prm;
- /* If we can't get the local address use what we have already */
- if (pjsip_tpmgr_find_local_addr2(pjsip_endpt_get_tpmgr(ast_sip_get_pjsip_endpoint()), tdata->pool, &prm) != PJ_SUCCESS) {
- pj_sockaddr_print(&tdata->tp_info.transport->local_addr, local_buf, sizeof(local_buf), 3);
- } else {
- if (prm.tp_type & PJSIP_TRANSPORT_IPV6) {
- snprintf(local_buf, sizeof(local_buf), "[%.*s]:%hu",
- (int)pj_strlen(&prm.ret_addr),
- pj_strbuf(&prm.ret_addr),
- prm.ret_port);
+ /* Attempt to determine what IP address will we send this packet out of */
+ pjsip_tpmgr_fla2_param_default(&prm);
+ prm.tp_type = tdata->tp_info.transport->key.type;
+ pj_strset2(&prm.dst_host, tdata->tp_info.dst_name);
+ prm.local_if = PJ_TRUE;
+
+ /* If we can't get the local address use what we have already */
+ if (pjsip_tpmgr_find_local_addr2(pjsip_endpt_get_tpmgr(ast_sip_get_pjsip_endpoint()), tdata->pool, &prm) != PJ_SUCCESS) {
+ pj_sockaddr_print(&tdata->tp_info.transport->local_addr, local_buf, sizeof(local_buf), 3);
} else {
- snprintf(local_buf, sizeof(local_buf), "%.*s:%hu",
- (int)pj_strlen(&prm.ret_addr),
- pj_strbuf(&prm.ret_addr),
- prm.ret_port);
+ if (prm.tp_type & PJSIP_TRANSPORT_IPV6) {
+ snprintf(local_buf, sizeof(local_buf), "[%.*s]:%hu",
+ (int)pj_strlen(&prm.ret_addr),
+ pj_strbuf(&prm.ret_addr),
+ prm.ret_port);
+ } else {
+ snprintf(local_buf, sizeof(local_buf), "%.*s:%hu",
+ (int)pj_strlen(&prm.ret_addr),
+ pj_strbuf(&prm.ret_addr),
+ prm.ret_port);
+ }
}
+ } else {
+ /* For reliable transports they can only ever come from the transport
+ * local address.
+ */
+ pj_sockaddr_print(&tdata->tp_info.transport->local_addr, local_buf, sizeof(local_buf), 3);
}
+
pj_sockaddr_print(&tdata->tp_info.dst_addr, remote_buf, sizeof(remote_buf), 3);
cid_hdr = PJSIP_MSG_CID_HDR(tdata->msg);
@@ -150,7 +159,6 @@ static pj_bool_t logging_on_rx_msg(pjsip_rx_data *rdata)
char remote_buf[256];
char *uuid;
struct hepv3_capture_info *capture_info;
- pjsip_tpmgr_fla2_param prm;
capture_info = hepv3_create_capture_info(&rdata->pkt_info.packet, rdata->pkt_info.len);
if (!capture_info) {
@@ -162,27 +170,33 @@ static pj_bool_t logging_on_rx_msg(pjsip_rx_data *rdata)
}
pj_sockaddr_print(&rdata->pkt_info.src_addr, remote_buf, sizeof(remote_buf), 3);
- /* Attempt to determine what IP address we probably received this packet on */
- pjsip_tpmgr_fla2_param_default(&prm);
- prm.tp_type = rdata->tp_info.transport->key.type;
- pj_strset2(&prm.dst_host, rdata->pkt_info.src_name);
- prm.local_if = PJ_TRUE;
+ if (!(rdata->tp_info.transport->flag & PJSIP_TRANSPORT_RELIABLE)) {
+ pjsip_tpmgr_fla2_param prm;
- /* If we can't get the local address use what we have already */
- if (pjsip_tpmgr_find_local_addr2(pjsip_endpt_get_tpmgr(ast_sip_get_pjsip_endpoint()), rdata->tp_info.pool, &prm) != PJ_SUCCESS) {
- pj_sockaddr_print(&rdata->tp_info.transport->local_addr, local_buf, sizeof(local_buf), 3);
- } else {
- if (prm.tp_type & PJSIP_TRANSPORT_IPV6) {
- snprintf(local_buf, sizeof(local_buf), "[%.*s]:%hu",
- (int)pj_strlen(&prm.ret_addr),
- pj_strbuf(&prm.ret_addr),
- prm.ret_port);
+ /* Attempt to determine what IP address we probably received this packet on */
+ pjsip_tpmgr_fla2_param_default(&prm);
+ prm.tp_type = rdata->tp_info.transport->key.type;
+ pj_strset2(&prm.dst_host, rdata->pkt_info.src_name);
+ prm.local_if = PJ_TRUE;
+
+ /* If we can't get the local address use what we have already */
+ if (pjsip_tpmgr_find_local_addr2(pjsip_endpt_get_tpmgr(ast_sip_get_pjsip_endpoint()), rdata->tp_info.pool, &prm) != PJ_SUCCESS) {
+ pj_sockaddr_print(&rdata->tp_info.transport->local_addr, local_buf, sizeof(local_buf), 3);
} else {
- snprintf(local_buf, sizeof(local_buf), "%.*s:%hu",
- (int)pj_strlen(&prm.ret_addr),
- pj_strbuf(&prm.ret_addr),
- prm.ret_port);
+ if (prm.tp_type & PJSIP_TRANSPORT_IPV6) {
+ snprintf(local_buf, sizeof(local_buf), "[%.*s]:%hu",
+ (int)pj_strlen(&prm.ret_addr),
+ pj_strbuf(&prm.ret_addr),
+ prm.ret_port);
+ } else {
+ snprintf(local_buf, sizeof(local_buf), "%.*s:%hu",
+ (int)pj_strlen(&prm.ret_addr),
+ pj_strbuf(&prm.ret_addr),
+ prm.ret_port);
+ }
}
+ } else {
+ pj_sockaddr_print(&rdata->tp_info.transport->local_addr, local_buf, sizeof(local_buf), 3);
}
uuid = assign_uuid(&rdata->msg_info.cid->id, &rdata->msg_info.to->tag, &rdata->msg_info.from->tag);
diff --git a/res/res_http_websocket.c b/res/res_http_websocket.c
index 8e9aae9dd..c1f9a29d6 100644
--- a/res/res_http_websocket.c
+++ b/res/res_http_websocket.c
@@ -86,18 +86,19 @@
/*! \brief Structure definition for session */
struct ast_websocket {
- struct ast_iostream *stream; /*!< iostream of the connection */
- struct ast_sockaddr address; /*!< Address of the remote client */
- enum ast_websocket_opcode opcode; /*!< Cached opcode for multi-frame messages */
- size_t payload_len; /*!< Length of the payload */
- char *payload; /*!< Pointer to the payload */
- size_t reconstruct; /*!< Number of bytes before a reconstructed payload will be returned and a new one started */
- int timeout; /*!< The timeout for operations on the socket */
- unsigned int secure:1; /*!< Bit to indicate that the transport is secure */
- unsigned int closing:1; /*!< Bit to indicate that the session is in the process of being closed */
- unsigned int close_sent:1; /*!< Bit to indicate that the session close opcode has been sent and no further data will be sent */
- struct websocket_client *client; /*!< Client object when connected as a client websocket */
- char session_id[AST_UUID_STR_LEN]; /*!< The identifier for the websocket session */
+ struct ast_iostream *stream; /*!< iostream of the connection */
+ struct ast_sockaddr remote_address; /*!< Address of the remote client */
+ struct ast_sockaddr local_address; /*!< Our local address */
+ enum ast_websocket_opcode opcode; /*!< Cached opcode for multi-frame messages */
+ size_t payload_len; /*!< Length of the payload */
+ char *payload; /*!< Pointer to the payload */
+ size_t reconstruct; /*!< Number of bytes before a reconstructed payload will be returned and a new one started */
+ int timeout; /*!< The timeout for operations on the socket */
+ unsigned int secure:1; /*!< Bit to indicate that the transport is secure */
+ unsigned int closing:1; /*!< Bit to indicate that the session is in the process of being closed */
+ unsigned int close_sent:1; /*!< Bit to indicate that the session close opcode has been sent and no further data will be sent */
+ struct websocket_client *client; /*!< Client object when connected as a client websocket */
+ char session_id[AST_UUID_STR_LEN]; /*!< The identifier for the websocket session */
};
/*! \brief Hashing function for protocols */
@@ -183,7 +184,7 @@ static void session_destroy_fn(void *obj)
ast_iostream_close(session->stream);
session->stream = NULL;
ast_verb(2, "WebSocket connection %s '%s' closed\n", session->client ? "to" : "from",
- ast_sockaddr_stringify(&session->address));
+ ast_sockaddr_stringify(&session->remote_address));
}
}
@@ -318,7 +319,7 @@ int AST_OPTIONAL_API_NAME(ast_websocket_close)(struct ast_websocket *session, ui
ast_iostream_close(session->stream);
session->stream = NULL;
ast_verb(2, "WebSocket connection %s '%s' forcefully closed due to fatal write error\n",
- session->client ? "to" : "from", ast_sockaddr_stringify(&session->address));
+ session->client ? "to" : "from", ast_sockaddr_stringify(&session->remote_address));
}
ao2_unlock(session);
@@ -432,7 +433,12 @@ int AST_OPTIONAL_API_NAME(ast_websocket_fd)(struct ast_websocket *session)
struct ast_sockaddr * AST_OPTIONAL_API_NAME(ast_websocket_remote_address)(struct ast_websocket *session)
{
- return &session->address;
+ return &session->remote_address;
+}
+
+struct ast_sockaddr * AST_OPTIONAL_API_NAME(ast_websocket_local_address)(struct ast_websocket *session)
+{
+ return &session->local_address;
}
int AST_OPTIONAL_API_NAME(ast_websocket_is_secure)(struct ast_websocket *session)
@@ -899,11 +905,21 @@ int AST_OPTIONAL_API_NAME(ast_websocket_uri_cb)(struct ast_tcptls_session_instan
return 0;
}
+ /* Get our local address for the connected socket */
+ if (ast_getsockname(ast_iostream_get_fd(ser->stream), &session->local_address)) {
+ ast_log(LOG_WARNING, "WebSocket connection from '%s' could not be accepted - failed to get local address\n",
+ ast_sockaddr_stringify(&ser->remote_address));
+ websocket_bad_request(ser);
+ ao2_ref(session, -1);
+ ao2_ref(protocol_handler, -1);
+ return 0;
+ }
+
ast_verb(2, "WebSocket connection from '%s' for protocol '%s' accepted using version '%d'\n", ast_sockaddr_stringify(&ser->remote_address), protocol ? : "", version);
/* Populate the session with all the needed details */
session->stream = ser->stream;
- ast_sockaddr_copy(&session->address, &ser->remote_address);
+ ast_sockaddr_copy(&session->remote_address, &ser->remote_address);
session->opcode = -1;
session->reconstruct = DEFAULT_RECONSTRUCTION_CEILING;
session->secure = ast_iostream_get_ssl(ser->stream) ? 1 : 0;
@@ -1357,7 +1373,7 @@ static enum ast_websocket_result websocket_client_connect(struct ast_websocket *
ws->stream = ws->client->ser->stream;
ws->secure = ast_iostream_get_ssl(ws->stream) ? 1 : 0;
ws->client->ser->stream = NULL;
- ast_sockaddr_copy(&ws->address, &ws->client->ser->remote_address);
+ ast_sockaddr_copy(&ws->remote_address, &ws->client->ser->remote_address);
return WS_OK;
}
diff --git a/res/res_pjsip_transport_websocket.c b/res/res_pjsip_transport_websocket.c
index 22ec19540..b5b6a3e0a 100644
--- a/res/res_pjsip_transport_websocket.c
+++ b/res/res_pjsip_transport_websocket.c
@@ -206,20 +206,16 @@ static int transport_create(void *data)
pj_sockaddr_parse(pj_AF_UNSPEC(), 0, pj_cstr(&buf, ws_addr_str), &newtransport->transport.key.rem_addr);
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.slen = pj_ansi_strlen(newtransport->transport.local_name.host.ptr);
- newtransport->transport.local_name.port = pj_sockaddr_get_port(&newtransport->transport.key.rem_addr);
+ ws_addr_str = ast_sockaddr_stringify(ast_websocket_local_address(newtransport->ws_session));
+ pj_sockaddr_parse(pj_AF_UNSPEC(), 0, pj_cstr(&buf, ws_addr_str), &newtransport->transport.local_addr);
+ pj_strdup2(pool, &newtransport->transport.local_name.host, ast_sockaddr_stringify_host(ast_websocket_local_address(newtransport->ws_session)));
+ newtransport->transport.local_name.port = ast_sockaddr_port(ast_websocket_local_address(newtransport->ws_session));
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);