From 1bb45e28f8f596dfc7f5b336aa1791ca9c38e348 Mon Sep 17 00:00:00 2001 From: Wenpeng Song <wenpeng.song@iopsys.eu> Date: Mon, 3 Mar 2025 16:24:56 +0000 Subject: [PATCH] Fix issues in registration retry mechanism, REF 15851 * 408 response received from the server should be handled the same as other codes like 503 * Introduce response code 444 from pjsip while no response been received to differentiate it with 408 which is from the server * there should have no retry during recovery flow if no retry-after, retry should only happened during the first round if no retry-after. --- res/res_pjsip_outbound_registration.c | 12 +++--- ...n-444-while-register-request-timeout.patch | 43 +++++++++++++++++++ 2 files changed, 49 insertions(+), 6 deletions(-) create mode 100644 third-party/pjproject/patches/0020-return-444-while-register-request-timeout.patch diff --git a/res/res_pjsip_outbound_registration.c b/res/res_pjsip_outbound_registration.c index 44df5800f3..7fb72de4df 100644 --- a/res/res_pjsip_outbound_registration.c +++ b/res/res_pjsip_outbound_registration.c @@ -1833,7 +1833,7 @@ static int handle_registration_response(void *data) } } - if (response->code == 408 || response->code == 503 || response->code == 500 || response->code == 504 || response->code == 600) { + if (response->code == 408 || response->code == 444 || response->code == 503 || response->code == 500 || response->code == 504 || response->code == 600) { int retry = 1; int waiting_time = registration->retry_after; @@ -1862,8 +1862,8 @@ static int handle_registration_response(void *data) if (response->retry_after){ waiting_time = response->retry_after; - } else if (response->code == 408 || client_state->attempts >= 2) { - /* failover when 408, or received twice with other response */ + } else if (response->code == 444 || client_state->attempts >= 2 || client_state->waiting_time_upper_bound) { + /* failover directly when not received any response(444 from pjsip), or received twice with other response, or under recovery-flow(second round) */ client_state->attempts = 0; retry = sip_registration_failover(response); } @@ -1873,7 +1873,7 @@ static int handle_registration_response(void *data) update_client_state_status(client_state, SIP_REGISTRATION_REJECTED_TEMPORARY); sip_outbound_registration_send_ubus_event("UNREGISTERED", response->expiration, client_uri); - if (response->code == 408 || client_state->attempts == 0){ + if (response->code == 444 || client_state->attempts == 0){ ast_debug(1, "%s: Registration re-try to the next address immediately.\n", client_state->registration_name); registration_resend(response); } else { @@ -2084,7 +2084,7 @@ static int handle_registration_response(void *data) /* If we have been instructed to retry after a period of time, schedule it as such */ schedule_retry(response, response->retry_after, server_uri, client_uri, client_num); } else if (client_state->failover_max_retries && - (response->code == 408 || response->code == 503 || response->code == 500)) { + (response->code == 408 || response->code == 444 || response->code == 503 || response->code == 500)) { if (client_state->failover_max_retries >= 0 && client_state->failover_retries >= client_state->failover_max_retries) { update_client_state_status(client_state, SIP_REGISTRATION_REJECTED_PERMANENT); @@ -2132,7 +2132,7 @@ static int handle_registration_response(void *data) client_state->retries++; schedule_retry(response, client_state->retry_interval, server_uri, client_uri, client_num); } - } else if (response->code == 408 || response->code == 503 || response->code == 500 || response->code == 504 || response->code == 600) { + } else if (response->code == 408 || response->code == 444 || response->code == 503 || response->code == 500 || response->code == 504 || response->code == 600) { int waiting_time = registration->retry_after; // All addresses had been tried, now try transport2 if possible diff --git a/third-party/pjproject/patches/0020-return-444-while-register-request-timeout.patch b/third-party/pjproject/patches/0020-return-444-while-register-request-timeout.patch new file mode 100644 index 0000000000..bd1f918824 --- /dev/null +++ b/third-party/pjproject/patches/0020-return-444-while-register-request-timeout.patch @@ -0,0 +1,43 @@ +From 42a3189210f3790acdd128845403b96c5d03d090 Mon Sep 17 00:00:00 2001 +From: "wenpeng.song" <wenpeng.song@iopsys.eu> +Date: Mon, 3 Mar 2025 12:48:19 +0100 +Subject: [PATCH] return 444 while register request timeout + +--- + pjsip/src/pjsip/sip_msg.c | 2 ++ + pjsip/src/pjsip/sip_transaction.c | 6 +++++- + 2 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/pjsip/src/pjsip/sip_msg.c b/pjsip/src/pjsip/sip_msg.c +index c375ca9b1..7a67783c4 100644 +--- a/pjsip/src/pjsip/sip_msg.c ++++ b/pjsip/src/pjsip/sip_msg.c +@@ -243,6 +243,8 @@ static int init_status_phrase() + pj_strset2( &status_phrase[702], "Unable to resolve destination server"); + pj_strset2( &status_phrase[703], "Error sending message to destination server"); + ++ pj_strset2( &status_phrase[444], "No response received"); ++ + return 1; + } + +diff --git a/pjsip/src/pjsip/sip_transaction.c b/pjsip/src/pjsip/sip_transaction.c +index cf9795dbb..7d3ebe258 100644 +--- a/pjsip/src/pjsip/sip_transaction.c ++++ b/pjsip/src/pjsip/sip_transaction.c +@@ -2630,7 +2630,11 @@ static pj_status_t tsx_on_state_calling( pjsip_transaction *tsx, + tsx->transport_flag &= ~(TSX_HAS_PENDING_RESCHED); + + /* Set status code */ +- tsx_set_status_code(tsx, PJSIP_SC_TSX_TIMEOUT, NULL); ++ if(tsx->method.id == PJSIP_REGISTER_METHOD){ ++ tsx_set_status_code(tsx, 444, NULL); ++ } else { ++ tsx_set_status_code(tsx, PJSIP_SC_TSX_TIMEOUT, NULL); ++ } + + /* Inform TU. */ + tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, +-- +2.43.0 + -- GitLab