diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h index 9baceb9444..c52f17aae4 100644 --- a/include/asterisk/res_pjsip.h +++ b/include/asterisk/res_pjsip.h @@ -179,17 +179,6 @@ struct ast_sip_contact_status { int64_t rtt; }; -/*! - * \brief A transport to be used for messages to a contact - */ -struct ast_sip_contact_transport { - AST_DECLARE_STRING_FIELDS( - /*! Full URI of the contact */ - AST_STRING_FIELD(uri); - ); - pjsip_transport *transport; -}; - /*! * \brief A SIP address of record */ @@ -889,37 +878,6 @@ struct ast_sip_contact *ast_sip_location_retrieve_contact_from_aor_list(const ch */ struct ast_sip_contact *ast_sip_location_retrieve_contact(const char *contact_name); -/*! - * \brief Add a transport for a contact to use - */ - -void ast_sip_location_add_contact_transport(struct ast_sip_contact_transport *ct); - -/*! - * \brief Delete a transport for a contact that went away - */ -void ast_sip_location_delete_contact_transport(struct ast_sip_contact_transport *ct); - -/*! - * \brief Retrieve a contact_transport, by URI - * - * \param contact_uri URI of the contact - * - * \retval NULL if not found - * \retval non-NULL if found - */ -struct ast_sip_contact_transport *ast_sip_location_retrieve_contact_transport_by_uri(const char *contact_uri); - -/*! - * \brief Retrieve a contact_transport, by transport - * - * \param transport transport the contact uses - * - * \retval NULL if not found - * \retval non-NULL if found - */ -struct ast_sip_contact_transport *ast_sip_location_retrieve_contact_transport_by_transport(pjsip_transport *transport); - /*! * \brief Add a new contact to an AOR * diff --git a/res/res_pjsip.c b/res/res_pjsip.c index 37762e6cf6..80cef06e55 100644 --- a/res/res_pjsip.c +++ b/res/res_pjsip.c @@ -1369,7 +1369,10 @@ static int sip_dialog_create_from(pj_pool_t *pool, pj_str_t *from, const char *u /* Get the local bound address for the transport that will be used when communicating with the provided URI */ if (pjsip_tpmgr_find_local_addr(pjsip_endpt_get_tpmgr(ast_sip_get_pjsip_endpoint()), pool, type, selector, &local_addr, &local_port) != PJ_SUCCESS) { - return -1; + + /* If no local address can be retrieved using the transport manager use the host one */ + pj_strdup(pool, &local_addr, pj_gethostname()); + local_port = pjsip_transport_get_default_port_for_type(PJSIP_TRANSPORT_UDP); } /* If IPv6 was specified in the transport, set the proper type */ @@ -1423,22 +1426,6 @@ static int sip_get_tpselector_from_endpoint(const struct ast_sip_endpoint *endpo return 0; } -static int sip_get_tpselector_from_uri(const char *uri, pjsip_tpselector *selector) -{ - RAII_VAR(struct ast_sip_contact_transport *, contact_transport, NULL, ao2_cleanup); - - contact_transport = ast_sip_location_retrieve_contact_transport_by_uri(uri); - - if (!contact_transport) { - return -1; - } - - selector->type = PJSIP_TPSELECTOR_TRANSPORT; - selector->u.transport = contact_transport->transport; - - return 0; -} - pjsip_dialog *ast_sip_create_dialog_uac(const struct ast_sip_endpoint *endpoint, const char *uri, const char *request_user) { char enclosed_uri[PJSIP_MAX_URL_SIZE]; @@ -1457,7 +1444,7 @@ pjsip_dialog *ast_sip_create_dialog_uac(const struct ast_sip_endpoint *endpoint, return NULL; } - if (sip_get_tpselector_from_uri(uri, &selector) && sip_get_tpselector_from_endpoint(endpoint, &selector)) { + if (sip_get_tpselector_from_endpoint(endpoint, &selector)) { pjsip_dlg_terminate(dlg); return NULL; } @@ -2104,8 +2091,6 @@ static int load_module(void) ast_res_pjsip_init_options_handling(0); - ast_res_pjsip_init_contact_transports(); - ast_module_ref(ast_module_info->self); return AST_MODULE_LOAD_SUCCESS; diff --git a/res/res_pjsip/location.c b/res/res_pjsip/location.c index 7f4889fe88..14f58552ae 100644 --- a/res/res_pjsip/location.c +++ b/res/res_pjsip/location.c @@ -26,9 +26,6 @@ #include "asterisk/sorcery.h" #include "include/res_pjsip_private.h" -#define CONTACT_TRANSPORTS_BUCKETS 7 -static struct ao2_container *contact_transports; - /*! \brief Destructor for AOR */ static void aor_destroy(void *obj) { @@ -74,48 +71,6 @@ static void *contact_alloc(const char *name) return contact; } -/*! \brief Callback function for finding a contact_transport by URI */ -static int contact_transport_find_by_uri(void *obj, void *arg, int flags) -{ - struct ast_sip_contact_transport *ct = obj; - const char *contact_uri = arg; - - return (!strcmp(ct->uri, contact_uri)) ? CMP_MATCH | CMP_STOP : 0; -} - -/*! \brief Callback function for finding a contact_transport by transport */ -static int contact_transport_find_by_transport(void *obj, void *arg, int flags) -{ - struct ast_sip_contact_transport *ct = obj; - pjsip_transport *transport = arg; - - return (ct->transport == transport) ? CMP_MATCH | CMP_STOP : 0; -} - -void ast_sip_location_add_contact_transport(struct ast_sip_contact_transport *ct) -{ - ao2_link(contact_transports, ct); - - return; -} - -void ast_sip_location_delete_contact_transport(struct ast_sip_contact_transport *ct) -{ - ao2_unlink(contact_transports, ct); - - return; -} - -struct ast_sip_contact_transport *ast_sip_location_retrieve_contact_transport_by_uri(const char *contact_uri) -{ - return ao2_callback(contact_transports, 0, contact_transport_find_by_uri, (void *)contact_uri); -} - -struct ast_sip_contact_transport *ast_sip_location_retrieve_contact_transport_by_transport(pjsip_transport *transport) -{ - return ao2_callback(contact_transports, 0, contact_transport_find_by_transport, transport); -} - struct ast_sip_aor *ast_sip_location_retrieve_aor(const char *aor_name) { return ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "aor", aor_name); @@ -449,16 +404,3 @@ int ast_sip_initialize_sorcery_location(struct ast_sorcery *sorcery) return 0; } -int ast_res_pjsip_init_contact_transports(void) -{ - if (contact_transports) { - ao2_t_ref(contact_transports, -1, "Remove old contact transports"); - } - - contact_transports = ao2_t_container_alloc_options(AO2_ALLOC_OPT_LOCK_RWLOCK, CONTACT_TRANSPORTS_BUCKETS, NULL, NULL, "Create container for contact transports"); - if (!contact_transports) { - return -1; - } - - return 0; -} diff --git a/res/res_pjsip/pjsip_options.c b/res/res_pjsip/pjsip_options.c index b0c8edb461..c8c7843689 100644 --- a/res/res_pjsip/pjsip_options.c +++ b/res/res_pjsip/pjsip_options.c @@ -263,10 +263,9 @@ static int qualify_contact(struct ast_sip_contact *contact) ao2_ref(contact, +1); if (pjsip_endpt_send_request(ast_sip_get_pjsip_endpoint(), tdata, -1, contact, qualify_contact_cb) != PJ_SUCCESS) { - pjsip_tx_data_dec_ref(tdata); + /* The callback will be called so we don't need to drop the contact ref*/ ast_log(LOG_ERROR, "Unable to send request to qualify contact %s\n", contact->uri); - ao2_ref(contact, -1); return -1; } diff --git a/res/res_pjsip/security_events.c b/res/res_pjsip/security_events.c index 6bdb6cb399..0135d33518 100644 --- a/res/res_pjsip/security_events.c +++ b/res/res_pjsip/security_events.c @@ -33,35 +33,24 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/res_pjsip.h" #include "asterisk/security_events.h" -static int find_transport_in_use(void *obj, void *arg, int flags) -{ - struct ast_sip_transport *transport = obj; - pjsip_rx_data *rdata = arg; - - if ((transport->state->transport == rdata->tp_info.transport) || - (transport->state->factory && !pj_strcmp(&transport->state->factory->addr_name.host, &rdata->tp_info.transport->local_name.host) && - transport->state->factory->addr_name.port == rdata->tp_info.transport->local_name.port)) { - return CMP_MATCH | CMP_STOP; - } - - return 0; -} - static enum ast_transport security_event_get_transport(pjsip_rx_data *rdata) { - RAII_VAR(struct ao2_container *, transports, NULL, ao2_cleanup); - RAII_VAR(struct ast_sip_transport *, transport, NULL, ao2_cleanup); - - /* It should be impossible for these to fail as the transport has to exist for the message to exist */ - transports = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "transport", AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL); - - ast_assert(transports != NULL); - - transport = ao2_callback(transports, 0, find_transport_in_use, rdata); - - ast_assert(transport != NULL); - - return transport->type; + if (rdata->tp_info.transport->key.type == PJSIP_TRANSPORT_UDP || + rdata->tp_info.transport->key.type == PJSIP_TRANSPORT_UDP6) { + return AST_TRANSPORT_UDP; + } else if (rdata->tp_info.transport->key.type == PJSIP_TRANSPORT_TCP || + rdata->tp_info.transport->key.type == PJSIP_TRANSPORT_TCP6) { + return AST_TRANSPORT_TCP; + } else if (rdata->tp_info.transport->key.type == PJSIP_TRANSPORT_TLS || + rdata->tp_info.transport->key.type == PJSIP_TRANSPORT_TLS6) { + return AST_TRANSPORT_TLS; + } else if (!strcmp(rdata->tp_info.transport->type_name, "WS")) { + return AST_TRANSPORT_WS; + } else if (!strcmp(rdata->tp_info.transport->type_name, "WSS")) { + return AST_TRANSPORT_WSS; + } else { + return 0; + } } static void security_event_populate(pjsip_rx_data *rdata, char *call_id, size_t call_id_size, struct ast_sockaddr *local, struct ast_sockaddr *remote) diff --git a/res/res_pjsip_transport_websocket.c b/res/res_pjsip_transport_websocket.c index f36ede3a6a..22962dab0d 100644 --- a/res/res_pjsip_transport_websocket.c +++ b/res/res_pjsip_transport_websocket.c @@ -95,13 +95,8 @@ static pj_status_t ws_destroy(pjsip_transport *transport) static int transport_shutdown(void *data) { - RAII_VAR(struct ast_sip_contact_transport *, ct, NULL, ao2_cleanup); pjsip_transport *transport = data; - if ((ct = ast_sip_location_retrieve_contact_transport_by_transport(transport))) { - ast_sip_location_delete_contact_transport(ct); - } - pjsip_transport_shutdown(transport); return 0; } @@ -220,6 +215,7 @@ static void websocket_cb(struct ast_websocket *session, struct ast_variable *par struct ast_taskprocessor *serializer = NULL; struct transport_create_data create_data; struct ws_transport *transport = NULL; + struct transport_read_data read_data; if (ast_websocket_set_nonblock(session)) { ast_websocket_unref(session); @@ -240,9 +236,9 @@ static void websocket_cb(struct ast_websocket *session, struct ast_variable *par } transport = create_data.transport; + read_data.transport = transport; while (ast_wait_for_input(ast_websocket_fd(session), -1) > 0) { - struct transport_read_data read_data; enum ast_websocket_opcode opcode; int fragmented; @@ -251,9 +247,7 @@ static void websocket_cb(struct ast_websocket *session, struct ast_variable *par } if (opcode == AST_WEBSOCKET_OPCODE_TEXT || opcode == AST_WEBSOCKET_OPCODE_BINARY) { - read_data.transport = transport; - - ast_sip_push_task(serializer, transport_read, &read_data); + ast_sip_push_task_synchronous(serializer, transport_read, &read_data); } else if (opcode == AST_WEBSOCKET_OPCODE_CLOSE) { break; } @@ -265,73 +259,12 @@ static void websocket_cb(struct ast_websocket *session, struct ast_variable *par ast_websocket_unref(session); } -/*! - * \brief Session supplement handler for avoiding DNS lookup on bogus address. - */ -static void websocket_outgoing_request(struct ast_sip_session *session, struct pjsip_tx_data *tdata) -{ - char contact_uri[PJSIP_MAX_URL_SIZE] = { 0, }; - RAII_VAR(struct ast_sip_contact_transport *, ct, NULL, ao2_cleanup); - pjsip_tpselector selector = { .type = PJSIP_TPSELECTOR_TRANSPORT, }; - - const pjsip_sip_uri *request_uri = pjsip_uri_get_uri(tdata->msg->line.req.uri); - - if (pj_stricmp2(&request_uri->transport_param, "WS") && pj_stricmp2(&request_uri->transport_param, "WSS")) { - return; - } - - pjsip_uri_print(PJSIP_URI_IN_REQ_URI, request_uri, contact_uri, sizeof(contact_uri)); - - if (!(ct = ast_sip_location_retrieve_contact_transport_by_uri(contact_uri))) { - return; - } - - selector.u.transport = ct->transport; - - pjsip_tx_data_set_transport(tdata, &selector); - - tdata->dest_info.addr.count = 1; - tdata->dest_info.addr.entry[0].type = ct->transport->key.type; - tdata->dest_info.addr.entry[0].addr = ct->transport->key.rem_addr; - tdata->dest_info.addr.entry[0].addr_len = ct->transport->addr_len; -} - -static struct ast_sip_session_supplement websocket_supplement = { - .outgoing_request = websocket_outgoing_request, -}; - -/*! - * \brief Destructor for ast_sip_contact_transport - */ -static void contact_transport_destroy(void *obj) -{ - struct ast_sip_contact_transport *ct = obj; - - ast_string_field_free_memory(ct); -} - -static void *contact_transport_alloc(void) -{ - struct ast_sip_contact_transport *ct = ao2_alloc(sizeof(*ct), contact_transport_destroy); - - if (!ct) { - return NULL; - } - - if (ast_string_field_init(ct, 256)) { - ao2_cleanup(ct); - return NULL; - } - - return ct; -} - /*! * \brief Store the transport a message came in on, so it can be used for outbound messages to that contact. */ static pj_bool_t websocket_on_rx_msg(pjsip_rx_data *rdata) { - pjsip_contact_hdr *contact_hdr = NULL; + pjsip_contact_hdr *contact; long type = rdata->tp_info.transport->key.type; @@ -339,24 +272,16 @@ static pj_bool_t websocket_on_rx_msg(pjsip_rx_data *rdata) return PJ_FALSE; } - if ((contact_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, NULL))) { - RAII_VAR(struct ast_sip_contact_transport *, ct, NULL, ao2_cleanup); - char contact_uri[PJSIP_MAX_URL_SIZE]; + if ((contact = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, NULL)) && + (PJSIP_URI_SCHEME_IS_SIP(contact->uri) || PJSIP_URI_SCHEME_IS_SIPS(contact->uri))) { + pjsip_sip_uri *uri = pjsip_uri_get_uri(contact->uri); - pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, pjsip_uri_get_uri(contact_hdr->uri), contact_uri, sizeof(contact_uri)); - - if (!(ct = ast_sip_location_retrieve_contact_transport_by_uri(contact_uri))) { - if (!(ct = contact_transport_alloc())) { - return PJ_FALSE; - } - - ast_string_field_set(ct, uri, contact_uri); - ct->transport = rdata->tp_info.transport; - - ast_sip_location_add_contact_transport(ct); - } + pj_cstr(&uri->host, rdata->pkt_info.src_name); + uri->port = rdata->pkt_info.src_port; } + rdata->msg_info.via->rport_param = 0; + return PJ_FALSE; } @@ -376,8 +301,6 @@ static int load_module(void) return AST_MODULE_LOAD_DECLINE; } - ast_sip_session_register_supplement(&websocket_supplement); - if (ast_websocket_add_protocol("sip", websocket_cb)) { ast_sip_unregister_service(&websocket_module); return AST_MODULE_LOAD_DECLINE; @@ -389,7 +312,6 @@ static int load_module(void) static int unload_module(void) { ast_sip_unregister_service(&websocket_module); - ast_sip_session_unregister_supplement(&websocket_supplement); ast_websocket_remove_protocol("sip", websocket_cb); return 0;