diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h index c97e4b5..d8e172f 100644 --- a/include/asterisk/res_pjsip.h +++ b/include/asterisk/res_pjsip.h @@ -1368,6 +1368,16 @@ struct ast_taskprocessor *ast_sip_create_serializer_group_named(const char *name struct ast_taskprocessor *ast_sip_get_distributor_serializer(pjsip_rx_data *rdata); /*! + * \brief Record the task's serializer name on the tdata structure. + * \since 13.15.0 + * + * \param tdata The outgoing message. + * + * \retval PJ_SUCCESS. + */ +pj_status_t ast_sip_record_request_serializer(pjsip_tx_data *tdata); + +/*! * \brief Set a serializer on a SIP dialog so requests and responses are automatically serialized * * Passing a NULL serializer is a way to remove a serializer from a dialog. diff --git a/res/res_pjsip.c b/res/res_pjsip.c index e4a9b98..4b458b0 100644 --- a/res/res_pjsip.c +++ b/res/res_pjsip.c @@ -3549,6 +3549,7 @@ static pj_status_t endpt_send_request(struct ast_sip_endpoint *endpoint, if (!cb && token) { /* Silly. Without a callback we cannot do anything with token. */ + pjsip_tx_data_dec_ref(tdata); return PJ_EINVAL; } @@ -3602,6 +3603,8 @@ static pj_status_t endpt_send_request(struct ast_sip_endpoint *endpoint, } } + ast_sip_record_request_serializer(tdata); + /* We need to insure that the wrapper and tdata are available when the * transaction callback is executed. */ diff --git a/res/res_pjsip/pjsip_distributor.c b/res/res_pjsip/pjsip_distributor.c index 7900611..98bb455 100644 --- a/res/res_pjsip/pjsip_distributor.c +++ b/res/res_pjsip/pjsip_distributor.c @@ -29,12 +29,11 @@ static int distribute(void *data); static pj_bool_t distributor(pjsip_rx_data *rdata); -static pj_status_t record_serializer(pjsip_tx_data *tdata); static pjsip_module distributor_mod = { .name = {"Request Distributor", 19}, .priority = PJSIP_MOD_PRIORITY_TSX_LAYER - 6, - .on_tx_request = record_serializer, + .on_tx_request = ast_sip_record_request_serializer, .on_rx_request = distributor, .on_rx_response = distributor, }; @@ -65,16 +64,7 @@ struct unidentified_request{ /*! Pool of serializers to use if not supplied. */ static struct ast_taskprocessor *distributor_pool[DISTRIBUTOR_POOL_SIZE]; -/*! - * \internal - * \brief Record the task's serializer name on the tdata structure. - * \since 14.0.0 - * - * \param tdata The outgoing message. - * - * \retval PJ_SUCCESS. - */ -static pj_status_t record_serializer(pjsip_tx_data *tdata) +pj_status_t ast_sip_record_request_serializer(pjsip_tx_data *tdata) { struct ast_taskprocessor *serializer; @@ -120,12 +110,12 @@ static struct ast_taskprocessor *find_request_serializer(pjsip_rx_data *rdata) tsx = pjsip_tsx_layer_find_tsx(&tsx_key, PJ_TRUE); if (!tsx) { - ast_debug(1, "Could not find %.*s transaction for %d response.\n", - (int) pj_strlen(&rdata->msg_info.cseq->method.name), - pj_strbuf(&rdata->msg_info.cseq->method.name), - rdata->msg_info.msg->line.status.code); + ast_debug(1, "Could not find transaction for %s.\n", + pjsip_rx_data_get_info(rdata)); return NULL; } + ast_debug(3, "Found transaction %s for %s.\n", + tsx->obj_name, pjsip_rx_data_get_info(rdata)); if (tsx->last_tx) { const char *serializer_name; @@ -402,21 +392,14 @@ static pj_bool_t distributor(pjsip_rx_data *rdata) if (serializer) { /* We have a serializer so we know where to send the message. */ } else if (rdata->msg_info.msg->type == PJSIP_RESPONSE_MSG) { - ast_debug(3, "No dialog serializer for response %s. Using request transaction as basis\n", + ast_debug(3, "No dialog serializer for %s. Using request transaction as basis.\n", pjsip_rx_data_get_info(rdata)); serializer = find_request_serializer(rdata); if (!serializer) { - if (ast_taskprocessor_alert_get()) { - /* We're overloaded, ignore the unmatched response. */ - ast_debug(3, "Taskprocessor overload alert: Ignoring unmatched '%s'.\n", - pjsip_rx_data_get_info(rdata)); - return PJ_TRUE; - } - /* - * Pick a serializer for the unmatched response. Maybe - * the stack can figure out what it is for, or we really - * should just toss it regardless. + * Pick a serializer for the unmatched response. + * We couldn't determine what serializer originally + * sent the request or the serializer is gone. */ serializer = ast_sip_get_distributor_serializer(rdata); } @@ -760,7 +743,7 @@ static int distribute(void *data) .start_mod = &distributor_mod, .idx_after_start = 1, }; - pj_bool_t handled; + pj_bool_t handled = PJ_FALSE; pjsip_rx_data *rdata = data; int is_request = rdata->msg_info.msg->type == PJSIP_REQUEST_MSG; int is_ack = is_request ? rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD : 0; diff --git a/res/res_pjsip_mwi.c b/res/res_pjsip_mwi.c index fb6e6b8..5ae2af5 100644 --- a/res/res_pjsip_mwi.c +++ b/res/res_pjsip_mwi.c @@ -502,6 +502,7 @@ static int send_unsolicited_mwi_notify_to_contact(void *obj, void *arg, int flag body.subtype = MWI_SUBTYPE; body_text = ast_str_create(64); if (!body_text) { + pjsip_tx_data_dec_ref(tdata); return 0; } @@ -517,6 +518,7 @@ static int send_unsolicited_mwi_notify_to_contact(void *obj, void *arg, int flag if (ast_sip_pubsub_generate_body_content(body.type, body.subtype, &body_data, &body_text)) { ast_log(LOG_WARNING, "Unable to generate SIP MWI NOTIFY body.\n"); ast_free(body_text); + pjsip_tx_data_dec_ref(tdata); return 0; } diff --git a/res/res_pjsip_outbound_publish.c b/res/res_pjsip_outbound_publish.c index 35eedf0..7c0b64b 100644 --- a/res/res_pjsip_outbound_publish.c +++ b/res/res_pjsip_outbound_publish.c @@ -349,6 +349,7 @@ static int send_unpublish_task(void *data) pjsip_tx_data_set_transport(tdata, &selector); } + ast_sip_record_request_serializer(tdata); pjsip_publishc_send(client->client, tdata); } @@ -598,6 +599,7 @@ static int sip_publish_client_service_queue(void *data) pjsip_tx_data_set_transport(tdata, &selector); } + ast_sip_record_request_serializer(tdata); status = pjsip_publishc_send(client->client, tdata); if (status == PJ_EBUSY) { /* We attempted to send the message but something else got there first */ @@ -910,6 +912,7 @@ static void sip_outbound_publish_callback(struct pjsip_publishc_cbparam *param) pjsip_tx_data_set_transport(tdata, &selector); } + ast_sip_record_request_serializer(tdata); pjsip_publishc_send(client->client, tdata); } client->auth_attempts++; diff --git a/res/res_pjsip_outbound_registration.c b/res/res_pjsip_outbound_registration.c index da15f19..6c615f0 100644 --- a/res/res_pjsip_outbound_registration.c +++ b/res/res_pjsip_outbound_registration.c @@ -528,6 +528,7 @@ static pj_status_t registration_client_send(struct sip_outbound_registration_cli */ ast_sip_set_tpselector_from_transport_name(client_state->transport_name, &selector); pjsip_regc_set_transport(client_state->client, &selector); + ast_sip_record_request_serializer(tdata); status = pjsip_regc_send(client_state->client, tdata); /* If the attempt to send the message failed and the callback was not invoked we need to