Merge "ari: Implement 'debug all' and request/response logging"
[asterisk/asterisk.git] / res / res_pjsip_outbound_authenticator_digest.c
index 1e411f1..4bbac34 100644 (file)
@@ -102,38 +102,57 @@ cleanup:
 }
 
 static int digest_create_request_with_auth(const struct ast_sip_auth_vector *auths, pjsip_rx_data *challenge,
-               pjsip_transaction *tsx, pjsip_tx_data **new_request)
+               pjsip_tx_data *old_request, pjsip_tx_data **new_request)
 {
        pjsip_auth_clt_sess auth_sess;
+       pjsip_cseq_hdr *cseq;
+       pj_status_t status;
 
        if (pjsip_auth_clt_init(&auth_sess, ast_sip_get_pjsip_endpoint(),
-                               tsx->pool, 0) != PJ_SUCCESS) {
+                               old_request->pool, 0) != PJ_SUCCESS) {
                ast_log(LOG_WARNING, "Failed to initialize client authentication session\n");
                return -1;
        }
 
        if (set_outbound_authentication_credentials(&auth_sess, auths, challenge)) {
                ast_log(LOG_WARNING, "Failed to set authentication credentials\n");
+#if defined(HAVE_PJSIP_AUTH_CLT_DEINIT)
+               /* In case it is not a noop here in the future. */
+               pjsip_auth_clt_deinit(&auth_sess);
+#endif
                return -1;
        }
 
-       switch (pjsip_auth_clt_reinit_req(&auth_sess, challenge,
-                               tsx->last_tx, new_request)) {
+       status = pjsip_auth_clt_reinit_req(&auth_sess, challenge, old_request, new_request);
+#if defined(HAVE_PJSIP_AUTH_CLT_DEINIT)
+       /* Release any cached auths */
+       pjsip_auth_clt_deinit(&auth_sess);
+#endif
+       switch (status) {
        case PJ_SUCCESS:
+               /* PJSIP creates a new transaction for new_request (meaning it creates a new
+                * branch). However, it recycles the Call-ID, from-tag, and CSeq from the
+                * original request. Some SIP implementations will not process the new request
+                * since the CSeq is the same as the original request. Incrementing it here
+                * fixes the interop issue
+                */
+               cseq = pjsip_msg_find_hdr((*new_request)->msg, PJSIP_H_CSEQ, NULL);
+               ast_assert(cseq != NULL);
+               ++cseq->cseq;
                return 0;
        case PJSIP_ENOCREDENTIAL:
-               ast_log(LOG_WARNING, "Unable to create request with auth."
-                               "No auth credentials for any realms in challenge.\n");
+               ast_log(LOG_WARNING,
+                       "Unable to create request with auth.  No auth credentials for any realms in challenge.\n");
                break;
        case PJSIP_EAUTHSTALECOUNT:
-               ast_log(LOG_WARNING, "Unable to create request with auth."
-                               "Number of stale retries exceeded\n");
+               ast_log(LOG_WARNING,
+                       "Unable to create request with auth.  Number of stale retries exceeded.\n");
                break;
        case PJSIP_EFAILEDCREDENTIAL:
-               ast_log(LOG_WARNING, "Authentication credentials not accepted by server\n");
+               ast_log(LOG_WARNING, "Authentication credentials not accepted by server.\n");
                break;
        default:
-               ast_log(LOG_WARNING, "Unable to create request with auth. Unknown failure\n");
+               ast_log(LOG_WARNING, "Unable to create request with auth. Unknown failure.\n");
                break;
        }
 
@@ -146,6 +165,8 @@ static struct ast_sip_outbound_authenticator digest_authenticator = {
 
 static int load_module(void)
 {
+       CHECK_PJSIP_MODULE_LOADED();
+
        if (ast_sip_register_outbound_authenticator(&digest_authenticator)) {
                return AST_MODULE_LOAD_DECLINE;
        }
@@ -159,7 +180,8 @@ static int unload_module(void)
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP authentication resource",
-               .load = load_module,
-               .unload = unload_module,
-               .load_pri = AST_MODPRI_CHANNEL_DEPEND,
+       .support_level = AST_MODULE_SUPPORT_CORE,
+       .load = load_module,
+       .unload = unload_module,
+       .load_pri = AST_MODPRI_CHANNEL_DEPEND,
 );