From 553bb13f82a92f5f75af1e231f4cada5ef3ac15d Mon Sep 17 00:00:00 2001 From: Wenpeng Song <wenpeng.song@iopsys.eu> Date: Wed, 15 Jan 2025 09:13:49 +0000 Subject: [PATCH] Add max sessions support per client config, REF 12409 Add and support max_sessions to the pjsip endpoint config, which reflect as `VoiceService. {i}.SIP.Client.{i}.MaxSessions`. No actual behavior changes have been done, just followed the same behavior and add an extra condition check after max session per line as the line_calls count was calculated per endpoint. --- include/asterisk/res_pjsip.h | 1 + res/res_pjsip/pjsip_configuration.c | 3 +++ res/res_pjsip_session.c | 11 +++++++++++ 3 files changed, 15 insertions(+) diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h index 0db9a1917b..02ac1ed7f9 100644 --- a/include/asterisk/res_pjsip.h +++ b/include/asterisk/res_pjsip.h @@ -1103,6 +1103,7 @@ struct ast_sip_endpoint { unsigned int failover_reg_addr; /* the transport name of latest registration */ char *register_transport; + unsigned int max_sessions; }; struct pjsip_register_dest { diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c index 8a3cf2a053..e9bba44565 100644 --- a/res/res_pjsip/pjsip_configuration.c +++ b/res/res_pjsip/pjsip_configuration.c @@ -47,6 +47,8 @@ struct sip_persistent_endpoint { struct ast_endpoint *endpoint; }; +#define DEFAULT_MAX_SESSIONS_PER_CLIENT 0 + /*! \brief Container for persistent endpoint information */ static struct ao2_container *persistent_endpoints; @@ -2354,6 +2356,7 @@ int ast_res_pjsip_initialize_configuration(void) ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "security_negotiation", "no", security_negotiation_handler, security_negotiation_to_str, NULL, 0, 0); ast_sorcery_object_field_register(sip_sorcery, "endpoint", "send_aoc", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, send_aoc)); ast_sorcery_object_field_register(sip_sorcery, "endpoint", "Emergency", "false", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, Emergency)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "max_sessions", __stringify(DEFAULT_MAX_SESSIONS_PER_CLIENT), OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, max_sessions)); if (ast_sip_initialize_sorcery_transport()) { ast_log(LOG_ERROR, "Failed to register SIP transport support with sorcery\n"); diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c index 11edcd9c07..a643ff6ba1 100644 --- a/res/res_pjsip_session.c +++ b/res/res_pjsip_session.c @@ -3485,6 +3485,9 @@ struct ast_sip_session *ast_sip_session_create_outgoing(struct ast_sip_endpoint if (line_calls >= ast_sip_get_max_sessions_per_line()) { ast_log(LOG_WARNING, "Max call per line limit exceeded [%d/%d]\n", line_calls, ast_sip_get_max_sessions_per_line()); SCOPE_EXIT_RTN_VALUE(NULL, "Max call per line limit exceeded\n"); + } else if (endpoint->max_sessions && line_calls >= endpoint->max_sessions) { + ast_log(LOG_WARNING, "Max call per client limit exceeded [%d/%d]\n", line_calls, endpoint->max_sessions); + SCOPE_EXIT_RTN_VALUE(NULL, "Max call per client limit exceeded\n"); } else if (((current_session_count >= ast_sip_get_max_sessions_total()) && (ast_active_calls() != 3)) || ((current_session_count >= ast_sip_get_max_sessions_total()) && (ast_active_channels() >= 7))) { ast_log(LOG_WARNING, "Max call limit exceeded [%d/%d]\n", current_session_count, ast_sip_get_max_sessions_total()); @@ -4379,6 +4382,14 @@ static void handle_new_invite_request(pjsip_rx_data *rdata) pjsip_inv_terminate(inv_session, 486, PJ_FALSE); } SCOPE_EXIT_RTN("Max call per line limit exceeded\n"); + } else if (endpoint->max_sessions && line_calls >= endpoint->max_sessions) { + ast_log(LOG_WARNING, "Max call per client limit exceeded [%d/%d]\n", line_calls, endpoint->max_sessions); + /* Dialog's lock and reference are removed in new_invite_initial_answer */ + if (!new_invite_initial_answer(inv_session, rdata, 486, 486, PJ_FALSE)) { + /* Terminate the session if it wasn't done in the answer */ + pjsip_inv_terminate(inv_session, 486, PJ_FALSE); + } + SCOPE_EXIT_RTN("Max call per client limit exceeded\n"); } else if ((current_session_count == ast_sip_get_max_sessions_total()) || (ast_active_calls() >= ast_sip_get_max_sessions_total())) { ast_log(LOG_WARNING, "Max call limit exceeded [%d/%d]\n", current_session_count, ast_sip_get_max_sessions_total()); /* Dialog's lock and reference are removed in new_invite_initial_answer */ -- GitLab