]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
res_pjsip: Record the serializer earlier on the tdata. 38/5038/1
authorRichard Mudgett <rmudgett@digium.com>
Sat, 4 Feb 2017 22:00:14 +0000 (16:00 -0600)
committerRichard Mudgett <rmudgett@digium.com>
Mon, 20 Feb 2017 22:13:15 +0000 (16:13 -0600)
When PJPROJECT needs to do a DNS resolution and there is not a cached
entry available, the SIP request message goes out on the PJSIP monitor
thread instead of the original serializer thread.  Thus when the response
comes back it does not get processed by the original sending serializer.

This patch records the serializer on tdata before passing a request
message to PJPROJECT where it can in Asterisk code.  There are several
places in PJPROJECT for outbound registration and publishing support that
would need to record the serializer.  Unfortunately, without replacing the
PJPROJECT DNS resolver as was done in v14 we cannot fix those without
modifying PJPROJECT.

Even if we backported the DNS resolver from v14, the outbound registration
refresh timer does not go out on a serializer thread but the PJSIP monitor
thread.  Fortunately, Asterisk's outbound publish support doesn't use the
auto refresh timer that would also not go out under the serializer thread.

This patch is v13 only.

ASTERISK-26669
ASTERISK-26738

Change-Id: I9997b9ed6dbcebd2c37d6a67dc6dcee9c78914a4

include/asterisk/res_pjsip.h
res/res_pjsip.c
res/res_pjsip/pjsip_distributor.c
res/res_pjsip_outbound_publish.c
res/res_pjsip_outbound_registration.c

index c97e4b5343da5b80c57bda9d6e3323569fee4c6f..d8e172fc585655e08959008713337697596812f5 100644 (file)
@@ -1367,6 +1367,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
  *
index fde6479e99be1978b2cecba9c7943def11d22d51..ae4b1de2dbd119be2775d293d09bc6640dd86d1e 100644 (file)
@@ -3601,6 +3601,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.
         */
index 79006110a7c15efb1ed7cb391417f605aab3e83c..dbf53dbbe9ff1c2d578ca0ac9ae953e9c05c294b 100644 (file)
 
 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;
 
index 35eedf0d2c36413e10612efa2f1540b6d853b2ff..7c0b64b4daa94c5079cf49658e7c9506d707f3c6 100644 (file)
@@ -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++;
index ff6619477b712750df82f696b52acf5f4097c7ab..10a203cffbcfc079b857de2b13792d5e2b3a122e 100644 (file)
@@ -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