1
0
mirror of https://github.com/signalwire/freeswitch.git synced 2025-03-03 17:30:37 +00:00

Merge ca017c8f73280d185f16813205a5bcb8ef3cf8e0 into 5e82e4f305dbf3760b6f6e3ba8fb70c3de30a6b9

This commit is contained in:
Aron Podrigal 2025-01-31 16:48:22 +00:00 committed by GitHub
commit 96636a7cee
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 112 additions and 53 deletions

@ -422,16 +422,17 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session)
const char *gateway_name = NULL;
sofia_gateway_t *gateway_ptr = NULL;
if ((gateway_name = switch_channel_get_variable(channel, "sip_gateway_name"))) {
gateway_ptr = sofia_reg_find_gateway(gateway_name);
}
if (!tech_pvt) {
return SWITCH_STATUS_SUCCESS;
}
switch_mutex_lock(tech_pvt->sofia_mutex);
if (tech_pvt->gateway_name && tech_pvt->profile) {
gateway_name = tech_pvt->gateway_name;
gateway_ptr = sofia_reg_find_profile_gateway(tech_pvt->profile, gateway_name);
}
if (!switch_channel_test_flag(channel, CF_ANSWERED)) {
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
@ -3569,7 +3570,7 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t
sofia_glue_del_every_gateway(profile);
stream->write_function(stream, "+OK every gateway marked for deletion.\n");
} else {
if ((gateway_ptr = sofia_reg_find_gateway(argv[2]))) {
if ((gateway_ptr = sofia_reg_find_profile_gateway(profile, argv[2]))) {
sofia_glue_del_gateway(gateway_ptr);
sofia_reg_release_gateway(gateway_ptr);
stream->write_function(stream, "+OK gateway marked for deletion.\n");
@ -3682,7 +3683,7 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t
}
}
stream->write_function(stream, "+OK\n");
} else if ((gateway_ptr = sofia_reg_find_gateway(gname))) {
} else if ((gateway_ptr = sofia_reg_find_profile_gateway(profile, gname))) {
if (gateway_ptr->state != REG_STATE_NOREG) {
gateway_ptr->retry = 0;
gateway_ptr->state = REG_STATE_UNREGED;
@ -3715,7 +3716,7 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t
}
}
stream->write_function(stream, "+OK\n");
} else if ((gateway_ptr = sofia_reg_find_gateway(gname))) {
} else if ((gateway_ptr = sofia_reg_find_profile_gateway(profile, gname))) {
if (gateway_ptr->state != REG_STATE_NOREG) {
gateway_ptr->retry = 0;
gateway_ptr->state = REG_STATE_UNREGISTER;

@ -1121,6 +1121,9 @@ switch_status_t sofia_reg_add_gateway(sofia_profile_t *profile, const char *key,
sofia_gateway_t *sofia_reg_find_gateway__(const char *file, const char *func, int line, const char *key);
#define sofia_reg_find_gateway(x) sofia_reg_find_gateway__(__FILE__, __SWITCH_FUNC__, __LINE__, x)
sofia_gateway_t *sofia_reg_find_profile_gateway__(const char *file, const char *func, int line, sofia_profile_t *profile, const char *key);
#define sofia_reg_find_profile_gateway(p, x) sofia_reg_find_profile_gateway__(__FILE__, __SWITCH_FUNC__, __LINE__, p, x)
sofia_gateway_t *sofia_reg_find_gateway_by_realm__(const char *file, const char *func, int line, const char *key);
#define sofia_reg_find_gateway_by_realm(x) sofia_reg_find_gateway_by_realm__(__FILE__, __SWITCH_FUNC__, __LINE__, x)

@ -747,7 +747,7 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status,
}
if (!(gateway = sofia_reg_find_gateway(sofia_private->gateway_name))) {
if (!(gateway = sofia_reg_find_profile_gateway(profile, sofia_private->gateway_name))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Gateway information missing\n");
goto error;
}
@ -1491,7 +1491,7 @@ static void our_sofia_event_callback(nua_event_t event,
if (sofia_private && sofia_private != &mod_sofia_globals.destroy_private && sofia_private != &mod_sofia_globals.keep_private) {
if (!zstr(sofia_private->gateway_name)) {
if (!(gateway = sofia_reg_find_gateway(sofia_private->gateway_name))) {
if (!(gateway = sofia_reg_find_profile_gateway(profile,sofia_private->gateway_name))) {
return;
}
} else if (!zstr(sofia_private->uuid)) {
@ -1520,7 +1520,7 @@ static void our_sofia_event_callback(nua_event_t event,
}
if (tech_pvt->gateway_name) {
gateway = sofia_reg_find_gateway(tech_pvt->gateway_name);
gateway = sofia_reg_find_profile_gateway(profile,tech_pvt->gateway_name);
}
if (channel && switch_channel_down(channel)) {
@ -2099,7 +2099,7 @@ static void our_sofia_event_callback(nua_event_t event,
if (sofia_private && !zstr(sofia_private->gateway_name)) {
sofia_gateway_t *gateway = NULL;
if ((gateway = sofia_reg_find_gateway(sofia_private->gateway_name))) {
if ((gateway = sofia_reg_find_profile_gateway(profile,sofia_private->gateway_name))) {
gateway->state = REG_STATE_FAILED;
gateway->failure_status = status;
sofia_reg_release_gateway(gateway);
@ -3790,8 +3790,12 @@ static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag,
}
switch_mutex_lock(mod_sofia_globals.hash_mutex);
if (switch_core_hash_find(mod_sofia_globals.gateway_hash, name) && (gp = switch_core_hash_find(mod_sofia_globals.gateway_hash, pkey)) && !gp->deleted) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignoring duplicate gateway '%s'\n", name);
if ((gp = switch_core_hash_find(mod_sofia_globals.gateway_hash, pkey)) && !gp->deleted) {
if (sofia_reg_add_gateway(profile, name, gp) == SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Added gateway to hash '%s'\n", name);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignoring duplicate gateway '%s'\n", name);
}
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
free(pkey);
goto skip;
@ -4219,7 +4223,9 @@ static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag,
parse_gateway_subscriptions(profile, gateway, gw_subs_tag);
}
sofia_reg_add_gateway(profile, gateway->name, gateway);
if (sofia_reg_add_gateway(profile, gateway->name, gateway) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Skipped gateway '%s' on profile '%s'\n", gateway->name, profile->name);
}
}
@ -6446,7 +6452,7 @@ static void sofia_handle_sip_r_options(switch_core_session_t *session, int statu
switch_bool_t do_fire_gateway_state_event = SWITCH_FALSE;
if (sofia_private && !zstr(sofia_private->gateway_name)) {
gateway = sofia_reg_find_gateway(sofia_private->gateway_name);
gateway = sofia_reg_find_profile_gateway(profile,sofia_private->gateway_name);
sofia_private->destroy_me = 1;
}
@ -11309,13 +11315,13 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
sofia_gateway_t *gateway = NULL;
char *extension = NULL;
if (gw_name && ((gateway = sofia_reg_find_gateway(gw_name)))) {
if (gw_name && ((gateway = sofia_reg_find_profile_gateway(profile, gw_name)))) {
gw_param_name = NULL;
extension = gateway->extension;
}
if (!gateway && gw_param_name) {
if ((gateway = sofia_reg_find_gateway(gw_param_name))) {
if ((gateway = sofia_reg_find_profile_gateway(profile, gw_param_name))) {
extension = gateway->real_extension;
}
}

@ -2265,9 +2265,16 @@ void sofia_glue_del_profile(sofia_profile_t *profile)
for (gp = profile->gateways; gp; gp = gp->next) {
char *pkey = switch_mprintf("%s::%s", profile->name, gp->name);
// Only delete from hash if this gateway matches ours.
if (switch_core_hash_find(mod_sofia_globals.gateway_hash, gp->name) == gp) {
switch_core_hash_delete(mod_sofia_globals.gateway_hash, gp->name);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removing gateway on profile %s from hash %s.\n", profile->name, gp->name);
}
if (switch_core_hash_find(mod_sofia_globals.gateway_hash, pkey) == gp) {
switch_core_hash_delete(mod_sofia_globals.gateway_hash, pkey);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removing gateway on profile %s from hash %s.\n", profile->name, pkey);
}
switch_core_hash_delete(mod_sofia_globals.gateway_hash, gp->name);
switch_core_hash_delete(mod_sofia_globals.gateway_hash, pkey);
switch_safe_free(pkey);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "deleted gateway %s from profile %s\n", gp->name, profile->name);
}

@ -4478,7 +4478,7 @@ void sofia_presence_handle_sip_r_subscribe(int status,
}
if (!(gateway = sofia_reg_find_gateway(sofia_private->gateway_name))) {
if (!(gateway = sofia_reg_find_profile_gateway(profile,sofia_private->gateway_name))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Gateway information missing\n");
return;
}

@ -322,13 +322,15 @@ void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now)
switch_mutex_lock(profile->gw_mutex);
for (gateway_ptr = profile->gateways; gateway_ptr; gateway_ptr = gateway_ptr->next) {
if (gateway_ptr->deleted) {
char *pkey = switch_mprintf("%s::%s", profile->name, gateway_ptr->name);
switch_assert(pkey);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removing gateway on profile %s from hash %s.\n", profile->name, pkey);
switch_core_hash_delete(mod_sofia_globals.gateway_hash, pkey);
free(pkey);
if ((check = switch_core_hash_find(mod_sofia_globals.gateway_hash, gateway_ptr->name)) && check == gateway_ptr) {
char *pkey = switch_mprintf("%s::%s", profile->name, gateway_ptr->name);
switch_assert(pkey);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removing gateway %s from hash.\n", pkey);
switch_core_hash_delete(mod_sofia_globals.gateway_hash, pkey);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removing gateway on profile %s from hash %s.\n", profile->name, gateway_ptr->name);
switch_core_hash_delete(mod_sofia_globals.gateway_hash, gateway_ptr->name);
free(pkey);
}
if (gateway_ptr->state == REG_STATE_NOREG || gateway_ptr->state == REG_STATE_DOWN) {
@ -2581,14 +2583,13 @@ void sofia_reg_handle_sip_r_register(int status,
{
sofia_gateway_t *gateway = NULL;
if (!sofia_private) {
if (!profile || !sofia_private) {
nua_handle_destroy(nh);
return;
}
if (!zstr(sofia_private->gateway_name)) {
gateway = sofia_reg_find_gateway(sofia_private->gateway_name);
gateway = sofia_reg_find_profile_gateway(profile, sofia_private->gateway_name);
}
if (gateway) {
@ -2760,7 +2761,7 @@ void sofia_reg_handle_sip_r_challenge(int status,
if (!gateway) {
if (gw_name) {
var_gateway = sofia_reg_find_gateway((char *) gw_name);
var_gateway = sofia_reg_find_profile_gateway(profile,(char *) gw_name);
}
@ -2774,13 +2775,17 @@ void sofia_reg_handle_sip_r_challenge(int status,
if ((p = strchr(rb, '"'))) {
*p = '\0';
}
if (!(var_gateway = sofia_reg_find_gateway(rb))) {
if (!(var_gateway = sofia_reg_find_profile_gateway(profile, rb))) {
var_gateway = sofia_reg_find_gateway_by_realm(rb);
if(var_gateway && var_gateway->profile != profile) {
sofia_reg_release_gateway(var_gateway);
var_gateway = NULL;
}
}
}
if (!var_gateway && sip && sip->sip_to) {
var_gateway = sofia_reg_find_gateway(sip->sip_to->a_url->url_host);
var_gateway = sofia_reg_find_profile_gateway(profile,sip->sip_to->a_url->url_host);
}
if (var_gateway) {
@ -3490,7 +3495,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
name = "anonymous";
}
if ((gateway_ptr = sofia_reg_find_gateway(name))) {
if ((gateway_ptr = sofia_reg_find_profile_gateway(profile, name))) {
reg_state_t ostate = gateway_ptr->state;
gateway_ptr->retry = 0;
if (exptime) {
@ -3516,7 +3521,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
argc = switch_separate_string(mydata, ',', argv, (sizeof(argv) / sizeof(argv[0])));
for (x = 0; x < argc; x++) {
if ((gateway_ptr = sofia_reg_find_gateway((char *) argv[x]))) {
if ((gateway_ptr = sofia_reg_find_profile_gateway(profile,(char *) argv[x]))) {
reg_state_t ostate = gateway_ptr->state;
gateway_ptr->retry = 0;
if (exptime) {
@ -3619,6 +3624,26 @@ sofia_gateway_t *sofia_reg_find_gateway__(const char *file, const char *func, in
}
sofia_gateway_t *sofia_reg_find_profile_gateway__(const char *file, const char *func, int line, sofia_profile_t *profile, const char *key) {
char *pkey = NULL;
sofia_gateway_t *gw = NULL;
if (!strstr(key, "::")) {
pkey = switch_mprintf("%s::%s", profile->name, key);
key = pkey;
}
gw = sofia_reg_find_gateway__(file, func, line, key);
switch_safe_free(pkey);
if (gw) {
if (gw->profile != profile) {
sofia_reg_release_gateway__(file, func, line, gw);
gw = NULL;
}
}
return gw;
}
sofia_gateway_t *sofia_reg_find_gateway_by_realm__(const char *file, const char *func, int line, const char *key)
{
sofia_gateway_t *gateway = NULL;
@ -3684,42 +3709,59 @@ switch_status_t sofia_reg_add_gateway(sofia_profile_t *profile, const char *key,
{
switch_status_t status = SWITCH_STATUS_FALSE;
char *pkey = switch_mprintf("%s::%s", profile->name, key);
sofia_gateway_t *gp;
switch_mutex_lock(profile->gw_mutex);
gateway->next = profile->gateways;
profile->gateways = gateway;
switch_mutex_unlock(profile->gw_mutex);
sofia_gateway_t *unqualified_gw;
sofia_gateway_t *qualified_gw;
switch_mutex_lock(mod_sofia_globals.hash_mutex);
if ((gp = switch_core_hash_find(mod_sofia_globals.gateway_hash, key))) {
if (gp->deleted) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removing deleted gateway from hash.\n");
switch_core_hash_delete(mod_sofia_globals.gateway_hash, gp->name);
switch_core_hash_delete(mod_sofia_globals.gateway_hash, pkey);
if ((unqualified_gw = switch_core_hash_find(mod_sofia_globals.gateway_hash, key))) {
// regardless of the profile this belongs to, if it has been deleted, we remove it so we can add ours.
if (unqualified_gw->deleted) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removing deleted gateway from hash %s.\n", key);
switch_core_hash_delete(mod_sofia_globals.gateway_hash, key);
unqualified_gw = NULL;
}
}
if (!switch_core_hash_find(mod_sofia_globals.gateway_hash, key) && !switch_core_hash_find(mod_sofia_globals.gateway_hash, pkey)) {
status = switch_core_hash_insert(mod_sofia_globals.gateway_hash, key, gateway);
status |= switch_core_hash_insert(mod_sofia_globals.gateway_hash, pkey, gateway);
if (status != SWITCH_STATUS_SUCCESS) {
status = SWITCH_STATUS_FALSE;
if ((qualified_gw = switch_core_hash_find(mod_sofia_globals.gateway_hash, pkey))) {
if (qualified_gw->profile == profile) {
if (qualified_gw->deleted) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Re-adding gateway into hash %s.\n", pkey);
status = switch_core_hash_insert(mod_sofia_globals.gateway_hash, pkey, gateway);
}
} else {
qualified_gw = NULL;
}
} else {
status = SWITCH_STATUS_FALSE;
status = switch_core_hash_insert(mod_sofia_globals.gateway_hash, pkey, gateway);
qualified_gw = gateway;
}
if (status == SWITCH_STATUS_SUCCESS) {
switch_mutex_lock(profile->gw_mutex);
gateway->next = profile->gateways;
profile->gateways = gateway;
switch_mutex_unlock(profile->gw_mutex);
}
// insert namespaced version profile::gateway
if (qualified_gw) {
// insert un-namespaced name if it does not exist
if (!unqualified_gw) {
status = switch_core_hash_insert(mod_sofia_globals.gateway_hash, key, gateway);
} else {
status = SWITCH_STATUS_INUSE;
}
}
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
free(pkey);
if (status == SWITCH_STATUS_SUCCESS) {
switch_event_t *s_event;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Added gateway '%s' to profile '%s'\n", gateway->name, gateway->profile->name);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Added gateway '%s' for profile '%s'\n", gateway->name, gateway->profile->name);
if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_GATEWAY_ADD) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "Gateway", gateway->name);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile-name", gateway->profile->name);