Hello!
On 05.03.20 at 19:08 Asterisk Development Team wrote:
> * ASTERISK-28746 - res_pjsip_outbound_registration keeps
> retrying the first entry in a SRV record set
> (Reported by
> George Joseph)
I just tested the new version 16.9.0.rc1 and promptly got an error with
this patch. With Deutsche Telekom, you always get a SRV record set. On
the other hand, you mostly have to register 3 numbers - each must be
registered on its own - to the same destination. Therefore, on startup,
there are 3 registers done to the same destination. Often, one of the
three numbers fails to register on the first attempt and therefore, it
is done twice.
With this patch, you're now using the second of usually 3 SRV entries
and registration is done successfully (which would have worked too, if
you would have used the first entry again, because it's just a very
temporary problem) - but all succeeding calls (outgoing INVITEs) are now
rejected (403 Forbidden), because they are going to the first entry of
the SRV record set - which fails on Deutsche Telekom, because they await
all subsequent actions to be done at the same server as the registration
was done.
Therefore, this patch is a no go for all users of Deutsche Telekom or
any other provider relying on all actions to be done to always the same
destination IP.
Therefore, please make this new feature switchable or add another
feature, which takes care to always use the same destination IP as
initially used for the registration. You have to take care, too, that
there is more than one number at the same time - but all of them using
the same destination SRV hostname, but they could have different IP
addresses - but each number must use its own IP which was initially used
for the register.
For convenience, I attached the reverse patch to remove the offending
patch which makes asterisk mainly unusable for users of Deutsche Telekom.
Thanks
Michael
--- b/res/res_pjsip_outbound_registration.c
+++ a/res/res_pjsip_outbound_registration.c
@@ -334,14 +334,6 @@
* module unload.
*/
pjsip_regc *client;
- /*!
- * \brief Last tdata sent
- * We need the original tdata to resend a request on auth failure
- * or timeout. On an auth failure, we use the original tdata
- * to initialize the new tdata for the authorized response. On a timeout
- * we need it to skip failed SRV entries if any.
- */
- pjsip_tx_data *last_tdata;
/*! \brief Timer entry for retrying on temporal responses */
pj_timer_entry timer;
/*! \brief Optional line parameter placed into Contact */
@@ -552,13 +544,6 @@
/* Due to the message going out the callback may now be invoked, so bump the count */
ao2_ref(client_state, +1);
/*
- * We also bump tdata in expectation of saving it to client_state->last_tdata.
- * We have to do it BEFORE pjsip_regc_send because if it succeeds, it decrements
- * the ref count on its own.
- */
- pjsip_tx_data_add_ref(tdata);
-
- /*
* Set the transport in case transports were reloaded.
* When pjproject removes the extraneous error messages produced,
* we can check status and only set the transport and resend if there was an error
@@ -567,26 +552,13 @@
pjsip_regc_set_transport(client_state->client, &selector);
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
+ * drop the reference we just added
- /*
- * If the attempt to send the message failed and the callback was not invoked we need to
- * drop the references we just added
*/
if ((status != PJ_SUCCESS) && !(*callback_invoked)) {
- pjsip_tx_data_dec_ref(tdata);
ao2_ref(client_state, -1);
- return status;
}
- /*
- * Decref the old last_data before replacing it.
- * BTW, it's quite possible that last_data == tdata
- * if we're trying successive servers in an SRV set.
- */
- if (client_state->last_tdata) {
- pjsip_tx_data_dec_ref(client_state->last_tdata);
- }
- client_state->last_tdata = tdata;
-
return status;
}
@@ -1105,25 +1077,11 @@
retry_after = pjsip_msg_find_hdr(param->rdata->msg_info.msg, PJSIP_H_RETRY_AFTER,
NULL);
response->retry_after = retry_after ? retry_after->ivalue : 0;
-
- /*
- * If we got a response from the server, we have to use the tdata
- * from the transaction, not the tdata saved when we sent the
- * request. If we use the saved tdata, we won't process responses
- * like 423 Interval Too Brief correctly and we'll wind up sending
- * the bad Expires value again.
- */
- pjsip_tx_data_dec_ref(client_state->last_tdata);
-
tsx = pjsip_rdata_get_tsx(param->rdata);
response->old_request = tsx->last_tx;
pjsip_tx_data_add_ref(response->old_request);
pjsip_rx_data_clone(param->rdata, 0, &response->rdata);
- } else {
- /* old_request steals the reference */
- response->old_request = client_state->last_tdata;
}
- client_state->last_tdata = NULL;
/*
* Transfer response reference to serializer task so the
@@ -1169,9 +1127,6 @@
ast_taskprocessor_unreference(client_state->serializer);
ast_free(client_state->transport_name);
ast_free(client_state->registration_name);
- if (client_state->last_tdata) {
- pjsip_tx_data_dec_ref(client_state->last_tdata);
- }
}
/*! \brief Allocator function for registration state */
--
_____________________________________________________________________
-- Bandwidth and Colocation Provided by http://www.api-digital.com --
asterisk-dev mailing list
To UNSUBSCRIBE or update options visit:
http://lists.digium.com/mailman/listinfo/asterisk-dev