mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-10 14:51:09 +00:00
Merge "pjsip / hep: Provide correct local address for Websockets." into 13
This commit is contained in:
@@ -343,6 +343,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;});
|
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.
|
* \brief Get whether the WebSocket session is using a secure transport or not.
|
||||||
*
|
*
|
||||||
|
@@ -91,35 +91,44 @@ static pj_status_t logging_on_tx_msg(pjsip_tx_data *tdata)
|
|||||||
pjsip_cid_hdr *cid_hdr;
|
pjsip_cid_hdr *cid_hdr;
|
||||||
pjsip_from_hdr *from_hdr;
|
pjsip_from_hdr *from_hdr;
|
||||||
pjsip_to_hdr *to_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));
|
capture_info = hepv3_create_capture_info(tdata->buf.start, (size_t)(tdata->buf.cur - tdata->buf.start));
|
||||||
if (!capture_info) {
|
if (!capture_info) {
|
||||||
return PJ_SUCCESS;
|
return PJ_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Attempt to determine what IP address will we send this packet out of */
|
if (!(tdata->tp_info.transport->flag & PJSIP_TRANSPORT_RELIABLE)) {
|
||||||
pjsip_tpmgr_fla2_param_default(&prm);
|
pjsip_tpmgr_fla2_param 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 */
|
/* Attempt to determine what IP address will we send this packet out of */
|
||||||
if (pjsip_tpmgr_find_local_addr2(pjsip_endpt_get_tpmgr(ast_sip_get_pjsip_endpoint()), tdata->pool, &prm) != PJ_SUCCESS) {
|
pjsip_tpmgr_fla2_param_default(&prm);
|
||||||
pj_sockaddr_print(&tdata->tp_info.transport->local_addr, local_buf, sizeof(local_buf), 3);
|
prm.tp_type = tdata->tp_info.transport->key.type;
|
||||||
} else {
|
pj_strset2(&prm.dst_host, tdata->tp_info.dst_name);
|
||||||
if (prm.tp_type & PJSIP_TRANSPORT_IPV6) {
|
prm.local_if = PJ_TRUE;
|
||||||
snprintf(local_buf, sizeof(local_buf), "[%.*s]:%hu",
|
|
||||||
(int)pj_strlen(&prm.ret_addr),
|
/* If we can't get the local address use what we have already */
|
||||||
pj_strbuf(&prm.ret_addr),
|
if (pjsip_tpmgr_find_local_addr2(pjsip_endpt_get_tpmgr(ast_sip_get_pjsip_endpoint()), tdata->pool, &prm) != PJ_SUCCESS) {
|
||||||
prm.ret_port);
|
pj_sockaddr_print(&tdata->tp_info.transport->local_addr, local_buf, sizeof(local_buf), 3);
|
||||||
} else {
|
} else {
|
||||||
snprintf(local_buf, sizeof(local_buf), "%.*s:%hu",
|
if (prm.tp_type & PJSIP_TRANSPORT_IPV6) {
|
||||||
(int)pj_strlen(&prm.ret_addr),
|
snprintf(local_buf, sizeof(local_buf), "[%.*s]:%hu",
|
||||||
pj_strbuf(&prm.ret_addr),
|
(int)pj_strlen(&prm.ret_addr),
|
||||||
prm.ret_port);
|
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);
|
pj_sockaddr_print(&tdata->tp_info.dst_addr, remote_buf, sizeof(remote_buf), 3);
|
||||||
|
|
||||||
cid_hdr = PJSIP_MSG_CID_HDR(tdata->msg);
|
cid_hdr = PJSIP_MSG_CID_HDR(tdata->msg);
|
||||||
@@ -152,7 +161,6 @@ static pj_bool_t logging_on_rx_msg(pjsip_rx_data *rdata)
|
|||||||
char remote_buf[256];
|
char remote_buf[256];
|
||||||
char *uuid;
|
char *uuid;
|
||||||
struct hepv3_capture_info *capture_info;
|
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);
|
capture_info = hepv3_create_capture_info(&rdata->pkt_info.packet, rdata->pkt_info.len);
|
||||||
if (!capture_info) {
|
if (!capture_info) {
|
||||||
@@ -164,27 +172,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);
|
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 */
|
if (!(rdata->tp_info.transport->flag & PJSIP_TRANSPORT_RELIABLE)) {
|
||||||
pjsip_tpmgr_fla2_param_default(&prm);
|
pjsip_tpmgr_fla2_param 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 */
|
/* Attempt to determine what IP address we probably received this packet on */
|
||||||
if (pjsip_tpmgr_find_local_addr2(pjsip_endpt_get_tpmgr(ast_sip_get_pjsip_endpoint()), rdata->tp_info.pool, &prm) != PJ_SUCCESS) {
|
pjsip_tpmgr_fla2_param_default(&prm);
|
||||||
pj_sockaddr_print(&rdata->tp_info.transport->local_addr, local_buf, sizeof(local_buf), 3);
|
prm.tp_type = rdata->tp_info.transport->key.type;
|
||||||
} else {
|
pj_strset2(&prm.dst_host, rdata->pkt_info.src_name);
|
||||||
if (prm.tp_type & PJSIP_TRANSPORT_IPV6) {
|
prm.local_if = PJ_TRUE;
|
||||||
snprintf(local_buf, sizeof(local_buf), "[%.*s]:%hu",
|
|
||||||
(int)pj_strlen(&prm.ret_addr),
|
/* If we can't get the local address use what we have already */
|
||||||
pj_strbuf(&prm.ret_addr),
|
if (pjsip_tpmgr_find_local_addr2(pjsip_endpt_get_tpmgr(ast_sip_get_pjsip_endpoint()), rdata->tp_info.pool, &prm) != PJ_SUCCESS) {
|
||||||
prm.ret_port);
|
pj_sockaddr_print(&rdata->tp_info.transport->local_addr, local_buf, sizeof(local_buf), 3);
|
||||||
} else {
|
} else {
|
||||||
snprintf(local_buf, sizeof(local_buf), "%.*s:%hu",
|
if (prm.tp_type & PJSIP_TRANSPORT_IPV6) {
|
||||||
(int)pj_strlen(&prm.ret_addr),
|
snprintf(local_buf, sizeof(local_buf), "[%.*s]:%hu",
|
||||||
pj_strbuf(&prm.ret_addr),
|
(int)pj_strlen(&prm.ret_addr),
|
||||||
prm.ret_port);
|
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);
|
uuid = assign_uuid(&rdata->msg_info.cid->id, &rdata->msg_info.to->tag, &rdata->msg_info.from->tag);
|
||||||
|
@@ -87,18 +87,19 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
|||||||
|
|
||||||
/*! \brief Structure definition for session */
|
/*! \brief Structure definition for session */
|
||||||
struct ast_websocket {
|
struct ast_websocket {
|
||||||
FILE *f; /*!< Pointer to the file instance used for writing and reading */
|
FILE *f; /*!< Pointer to the file instance used for writing and reading */
|
||||||
int fd; /*!< File descriptor for the session, only used for polling */
|
int fd; /*!< File descriptor for the session, only used for polling */
|
||||||
struct ast_sockaddr address; /*!< Address of the remote client */
|
struct ast_sockaddr remote_address; /*!< Address of the remote client */
|
||||||
enum ast_websocket_opcode opcode; /*!< Cached opcode for multi-frame messages */
|
struct ast_sockaddr local_address; /*!< Our local address */
|
||||||
size_t payload_len; /*!< Length of the payload */
|
enum ast_websocket_opcode opcode; /*!< Cached opcode for multi-frame messages */
|
||||||
char *payload; /*!< Pointer to the payload */
|
size_t payload_len; /*!< Length of the payload */
|
||||||
size_t reconstruct; /*!< Number of bytes before a reconstructed payload will be returned and a new one started */
|
char *payload; /*!< Pointer to the payload */
|
||||||
int timeout; /*!< The timeout for operations on the socket */
|
size_t reconstruct; /*!< Number of bytes before a reconstructed payload will be returned and a new one started */
|
||||||
unsigned int secure:1; /*!< Bit to indicate that the transport is secure */
|
int timeout; /*!< The timeout for operations on the socket */
|
||||||
unsigned int closing:1; /*!< Bit to indicate that the session is in the process of being closed */
|
unsigned int secure:1; /*!< Bit to indicate that the transport is secure */
|
||||||
unsigned int close_sent:1; /*!< Bit to indicate that the session close opcode has been sent and no further data will be sent */
|
unsigned int closing:1; /*!< Bit to indicate that the session is in the process of being closed */
|
||||||
struct websocket_client *client; /*!< Client object when connected as a client websocket */
|
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 */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! \brief Hashing function for protocols */
|
/*! \brief Hashing function for protocols */
|
||||||
@@ -183,7 +184,7 @@ static void session_destroy_fn(void *obj)
|
|||||||
if (session->f) {
|
if (session->f) {
|
||||||
fclose(session->f);
|
fclose(session->f);
|
||||||
ast_verb(2, "WebSocket connection %s '%s' closed\n", session->client ? "to" : "from",
|
ast_verb(2, "WebSocket connection %s '%s' closed\n", session->client ? "to" : "from",
|
||||||
ast_sockaddr_stringify(&session->address));
|
ast_sockaddr_stringify(&session->remote_address));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -316,7 +317,7 @@ int AST_OPTIONAL_API_NAME(ast_websocket_close)(struct ast_websocket *session, ui
|
|||||||
fclose(session->f);
|
fclose(session->f);
|
||||||
session->f = NULL;
|
session->f = NULL;
|
||||||
ast_verb(2, "WebSocket connection %s '%s' forcefully closed due to fatal write error\n",
|
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);
|
ao2_unlock(session);
|
||||||
@@ -429,7 +430,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)
|
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)
|
int AST_OPTIONAL_API_NAME(ast_websocket_is_secure)(struct ast_websocket *session)
|
||||||
@@ -890,12 +896,22 @@ int AST_OPTIONAL_API_NAME(ast_websocket_uri_cb)(struct ast_tcptls_session_instan
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get our local address for the connected socket */
|
||||||
|
if (ast_getsockname(ser->fd, &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);
|
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 */
|
/* Populate the session with all the needed details */
|
||||||
session->f = ser->f;
|
session->f = ser->f;
|
||||||
session->fd = ser->fd;
|
session->fd = ser->fd;
|
||||||
ast_sockaddr_copy(&session->address, &ser->remote_address);
|
ast_sockaddr_copy(&session->remote_address, &ser->remote_address);
|
||||||
session->opcode = -1;
|
session->opcode = -1;
|
||||||
session->reconstruct = DEFAULT_RECONSTRUCTION_CEILING;
|
session->reconstruct = DEFAULT_RECONSTRUCTION_CEILING;
|
||||||
session->secure = ser->ssl ? 1 : 0;
|
session->secure = ser->ssl ? 1 : 0;
|
||||||
@@ -1350,7 +1366,7 @@ static enum ast_websocket_result websocket_client_connect(struct ast_websocket *
|
|||||||
ws->f = ws->client->ser->f;
|
ws->f = ws->client->ser->f;
|
||||||
ws->fd = ws->client->ser->fd;
|
ws->fd = ws->client->ser->fd;
|
||||||
ws->secure = ws->client->ser->ssl ? 1 : 0;
|
ws->secure = ws->client->ser->ssl ? 1 : 0;
|
||||||
ast_sockaddr_copy(&ws->address, &ws->client->ser->remote_address);
|
ast_sockaddr_copy(&ws->remote_address, &ws->client->ser->remote_address);
|
||||||
return WS_OK;
|
return WS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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);
|
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()) {
|
if (newtransport->transport.key.rem_addr.addr.sa_family == pj_AF_INET6()) {
|
||||||
newtransport->transport.key.type = transport_type_wss_ipv6;
|
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 {
|
} else {
|
||||||
newtransport->transport.key.type = transport_type_wss;
|
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);
|
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);
|
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);
|
||||||
newtransport->transport.local_name.host.slen = pj_ansi_strlen(newtransport->transport.local_name.host.ptr);
|
pj_strdup2(pool, &newtransport->transport.local_name.host, ast_sockaddr_stringify_host(ast_websocket_local_address(newtransport->ws_session)));
|
||||||
newtransport->transport.local_name.port = pj_sockaddr_get_port(&newtransport->transport.key.rem_addr);
|
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.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);
|
newtransport->transport.info = (char *)pj_pool_alloc(newtransport->transport.pool, 64);
|
||||||
|
Reference in New Issue
Block a user