summaryrefslogtreecommitdiff
path: root/res/res_pjsip_outbound_registration.c
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2015-11-17 14:53:57 -0600
committerRichard Mudgett <rmudgett@digium.com>2015-11-18 13:26:49 -0600
commiteaf898ac881585c23ac0fcb31c5369809c68b1bb (patch)
treee30053beaeace9f6b34fe316ccba5f62df6da932 /res/res_pjsip_outbound_registration.c
parente90bb44b76d1c34817b5ad7db34c1c595c644702 (diff)
res_pjsip_outbound_registration.c: Fix 423 response handling.
Receiving a 423 Interval Too Brief response after authentication for an outbound registration attempt results in assuming that the registrar has rejected the registration permanently. If there are no configured retries for fatal responses then the outbound registration is stopped for that endpoint. For registrations, PJSIP/PJPROJECT intercepts the handling of 423 responses and does not include any authentication in the updated registration request. When the updated request is challenged then the Asterisk code assumes that we were challenged again because the peer rejected the authentication we sent earlier. * Made registration challenges keep track of the CSeq number to determine if the received challenge response was for the request we thought we sent. If the response's CSeq number differs from the CSeq number we last sent with authentication then authenticate again because it is a challenge to a different request. Change-Id: I81b4bd36d1be095bab606e34b8b44e6302971b09
Diffstat (limited to 'res/res_pjsip_outbound_registration.c')
-rw-r--r--res/res_pjsip_outbound_registration.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/res/res_pjsip_outbound_registration.c b/res/res_pjsip_outbound_registration.c
index 7ff5f1619..2fd5b8c48 100644
--- a/res/res_pjsip_outbound_registration.c
+++ b/res/res_pjsip_outbound_registration.c
@@ -335,6 +335,8 @@ struct sip_outbound_registration_client_state {
unsigned int auth_rejection_permanent;
/*! \brief Determines whether SIP Path support should be advertised */
unsigned int support_path;
+ /*! CSeq number of last sent auth request. */
+ unsigned int auth_cseq;
/*! \brief Serializer for stuff and things */
struct ast_taskprocessor *serializer;
/*! \brief Configured authentication credentials */
@@ -758,15 +760,27 @@ static int handle_registration_response(void *data)
ast_debug(1, "Processing REGISTER response %d from server '%s' for client '%s'\n",
response->code, server_uri, client_uri);
- if (!response->client_state->auth_attempted &&
- (response->code == 401 || response->code == 407)) {
+ if ((response->code == 401 || response->code == 407)
+ && (!response->client_state->auth_attempted
+ || response->rdata->msg_info.cseq->cseq != response->client_state->auth_cseq)) {
+ int res;
+ pjsip_cseq_hdr *cseq_hdr;
pjsip_tx_data *tdata;
+
if (!ast_sip_create_request_with_auth(&response->client_state->outbound_auths,
response->rdata, response->old_request, &tdata)) {
response->client_state->auth_attempted = 1;
ast_debug(1, "Sending authenticated REGISTER to server '%s' from client '%s'\n",
server_uri, client_uri);
- if (registration_client_send(response->client_state, tdata) == PJ_SUCCESS) {
+ pjsip_tx_data_add_ref(tdata);
+ res = registration_client_send(response->client_state, tdata);
+
+ /* Save the cseq that actually got sent. */
+ cseq_hdr = (pjsip_cseq_hdr *) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CSEQ,
+ NULL);
+ response->client_state->auth_cseq = cseq_hdr->cseq;
+ pjsip_tx_data_dec_ref(tdata);
+ if (res == PJ_SUCCESS) {
ao2_ref(response, -1);
return 0;
}