diff --git a/conf/sofia.conf.xml b/conf/sofia.conf.xml index 22c55188ba..84930c8661 100644 --- a/conf/sofia.conf.xml +++ b/conf/sofia.conf.xml @@ -24,6 +24,8 @@ <!--<param name="expire-seconds" value="60"/>--> <!--/// do not register ///--> <!--<param name="register" value="false"/>--> + <!--How many seconds before a retry when a failure or timeout occurs --> + <!--<param name="retry_seconds" value="30"/>--> <!--</gateway>--> </gateways> diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index cb86539955..80a0e1ed11 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -1060,8 +1060,11 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t for (gp = profile->gateways; gp; gp = gp->next) { assert(gp->state < REG_STATE_LAST); - stream->write_function(stream, "%25s\t%s\t %32s\t%s\n", gp->name, "gateway", gp->register_to, sofia_state_names[gp->state]); - + stream->write_function(stream, "%25s\t%s\t %32s\t%s", gp->name, "gateway", gp->register_to, sofia_state_names[gp->state]); + if (gp->state == REG_STATE_FAILED || gp->state == REG_STATE_TRYING) { + stream->write_function(stream, " (retry: %ds)", gp->retry - time(NULL)); + } + stream->write_function(stream, "\n"); } } @@ -1087,6 +1090,7 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t return SWITCH_STATUS_SUCCESS; } + if (!strcasecmp(argv[1], "start")) { if (argc > 2 && !strcasecmp(argv[2], "reloadxml")) { if ((xml_root = switch_xml_open_root(1, &err))) { @@ -1107,6 +1111,34 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t return SWITCH_STATUS_SUCCESS; } + if (!strcasecmp(argv[1], "register")) { + char *gname = argv[2]; + sofia_gateway_t *gateway_ptr; + + if (switch_strlen_zero(gname)) { + stream->write_function(stream, "No gateway name provided!\n"); + goto done; + } + + if (!strcasecmp(gname, "all")) { + for (gateway_ptr = profile->gateways; gateway_ptr; gateway_ptr = gateway_ptr->next) { + gateway_ptr->retry = 0; + gateway_ptr->state = REG_STATE_UNREGED; + } + stream->write_function(stream, "+OK\n"); + } else if ((gateway_ptr = sofia_reg_find_gateway(gname))) { + gateway_ptr->retry = 0; + gateway_ptr->state = REG_STATE_UNREGED; + stream->write_function(stream, "+OK\n"); + sofia_reg_release_gateway(gateway_ptr); + } else { + stream->write_function(stream, "Invalid gateway!\n"); + } + + goto done; + } + + if (!strcasecmp(argv[1], "stop") || !strcasecmp(argv[1], "restart")) { int rsec = 30; int diff = (int) (time(NULL) - profile->started); @@ -1134,6 +1166,8 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t } } + done: + if (profile) { sofia_glue_release_profile(profile); } diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index e98de46f0c..628311736e 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -192,6 +192,7 @@ struct sofia_gateway { time_t expires; time_t retry; uint32_t flags; + int32_t retry_seconds; reg_state_t state; switch_memory_pool_t *pool; struct sofia_gateway *next; diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index ecc89eef8b..3b0e7d7483 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -480,8 +480,9 @@ static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag) *extension = NULL, *proxy = NULL, *context = "default", - *expire_seconds = "3600"; - + *expire_seconds = "3600", + *retry_seconds = "30"; + gateway->pool = profile->pool; gateway->profile = profile; gateway->name = switch_core_strdup(gateway->pool, name); @@ -512,6 +513,8 @@ static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag) context = val; } else if (!strcmp(var, "expire-seconds")) { expire_seconds = val; + } else if (!strcmp(var, "retry-seconds")) { + retry_seconds = val; } } @@ -540,6 +543,12 @@ static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag) if (!switch_true(register_str)) { gateway->state = REG_STATE_NOREG; } + + gateway->retry_seconds = atoi(retry_seconds); + if (gateway->retry_seconds < 10) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "INVALID: retry_seconds correcting the value to 30\n"); + gateway->retry_seconds = 30; + } gateway->register_scheme = switch_core_strdup(gateway->pool, scheme); gateway->register_context = switch_core_strdup(gateway->pool, context); gateway->register_realm = switch_core_strdup(gateway->pool, realm); @@ -568,9 +577,7 @@ static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag) } gateway->freq -= 2; - gateway->next = profile->gateways; - profile->gateways = gateway; - + if ((gp = sofia_reg_find_gateway(gateway->name))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignoring duplicate gateway '%s'\n", gateway->name); sofia_reg_release_gateway(gp); @@ -581,6 +588,8 @@ static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignoring duplicate contact '%s'\n", gateway->register_from); sofia_reg_release_gateway(gp); } else { + gateway->next = profile->gateways; + profile->gateways = gateway; sofia_reg_add_gateway(gateway->name, gateway); sofia_reg_add_gateway(gateway->register_from, gateway); sofia_reg_add_gateway(gateway->register_contact, gateway); diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index c3d719429a..673d5608eb 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -92,7 +92,7 @@ void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now) SIPTAG_EXPIRES_STR(gateway_ptr->expires_str), NUTAG_REGISTRAR(gateway_ptr->register_proxy), NUTAG_OUTBOUND("no-options-keepalive"), NUTAG_OUTBOUND("no-validate"), NUTAG_KEEPALIVE(0), TAG_NULL()); - gateway_ptr->retry = now + 10; + gateway_ptr->retry = now + gateway_ptr->retry_seconds; } else { nua_unregister(gateway_ptr->nh, SIPTAG_FROM_STR(gateway_ptr->register_from), @@ -102,7 +102,6 @@ void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now) NUTAG_OUTBOUND("no-options-keepalive"), NUTAG_OUTBOUND("no-validate"), NUTAG_KEEPALIVE(0), TAG_NULL()); } - gateway_ptr->retry = now + time(NULL); gateway_ptr->state = REG_STATE_TRYING; } else { @@ -111,6 +110,7 @@ void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now) } break; + case REG_STATE_FAILED: case REG_STATE_TRYING: if (gateway_ptr->retry && now >= gateway_ptr->retry) { gateway_ptr->state = REG_STATE_UNREGED;