From cf398e1a442bc54c05d68837fcad6258cecc7dfe Mon Sep 17 00:00:00 2001 From: Brian West <brian@freeswitch.org> Date: Mon, 22 Nov 2010 14:59:25 -0600 Subject: [PATCH] FS-535: tested but please test MORE. --- src/mod/endpoints/mod_sofia/mod_sofia.h | 1 + src/mod/endpoints/mod_sofia/sofia_glue.c | 36 +++++++++++++++++++++++- src/mod/endpoints/mod_sofia/sofia_reg.c | 33 +++++++++++++++++++--- 3 files changed, 65 insertions(+), 5 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 750fb60c15..c1244c05f1 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -957,6 +957,7 @@ void sofia_presence_event_thread_start(void); void sofia_reg_expire_call_id(sofia_profile_t *profile, const char *call_id, int reboot); switch_status_t sofia_glue_tech_choose_video_port(private_object_t *tech_pvt, int force); switch_status_t sofia_glue_tech_set_video_codec(private_object_t *tech_pvt, int force); +char *sofia_glue_get_register_host(const char *uri); const char *sofia_glue_strip_proto(const char *uri); switch_status_t reconfig_sofia(sofia_profile_t *profile); void sofia_glue_del_gateway(sofia_gateway_t *gp); diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index fa828607bd..23d3f2904e 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -5734,6 +5734,41 @@ char *sofia_glue_execute_sql2str(sofia_profile_t *profile, switch_mutex_t *mutex return ret; } +char *sofia_glue_get_register_host(const char *uri) +{ + char *register_host = NULL; + const char *s; + char *p = NULL; + + if ((s = switch_stristr("sip:", uri))) { + s += 4; + } else if ((s = switch_stristr("sips:", uri))) { + s += 5; + } + + if (!s) { + return NULL; + } + + register_host = strdup(s); + + /* remove port for register_host for testing nat acl take into account + ipv6 addresses which are required to have brackets around the addr + */ + if ((p = strchr(register_host, ']')) && (*(p + 1) == ':')) { + *(p + 1) = '\0'; + } else { + if ((p = strrchr(register_host, ':'))) { + *p = '\0'; + } + } + + /* register_proxy should always start with "sip:" or "sips:" */ + assert(register_host); + + return register_host; +} + const char *sofia_glue_strip_proto(const char *uri) { char *p; @@ -5983,7 +6018,6 @@ void sofia_glue_tech_simplify(private_object_t *tech_pvt) } } - void sofia_glue_build_vid_refresh_message(switch_core_session_t *session, const char *pl) { switch_core_session_message_t *msg; diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index 4bb879659c..14a7bfdd2c 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -142,16 +142,22 @@ void sofia_sub_check_gateway(sofia_profile_t *profile, time_t now) int ss_state = nua_callstate_authenticating; sub_state_t ostate = gw_sub_ptr->state; char *user_via = NULL; + char *register_host = NULL; if (!now) { gw_sub_ptr->state = ostate = SUB_STATE_UNSUBED; gw_sub_ptr->expires_str = "0"; } - if (sofia_glue_check_nat(gateway_ptr->profile, gateway_ptr->register_proxy)) { + register_host = sofia_glue_get_register_host(gateway_ptr->register_proxy); + + /* check for NAT and place a Via header if necessary (hostname or non-local IP) */ + if (sofia_glue_check_nat(gateway_ptr->profile, register_host)) { user_via = sofia_glue_create_external_via(NULL, gateway_ptr->profile, gateway_ptr->register_transport); } + switch_safe_free(register_host); + switch (ostate) { case SUB_STATE_NOSUB: break; @@ -189,7 +195,15 @@ void sofia_sub_check_gateway(sofia_profile_t *profile, time_t now) nua_handle_bind(gateway_ptr->nh, gateway_ptr->sofia_private); if (now) { - nua_subscribe(gateway_ptr->sub_nh, NUTAG_URL(gateway_ptr->register_url), TAG_IF(user_via, SIPTAG_VIA_STR(user_via)), SIPTAG_EVENT_STR(gw_sub_ptr->event), SIPTAG_ACCEPT_STR(gw_sub_ptr->content_type), SIPTAG_TO_STR(gateway_ptr->register_from), SIPTAG_FROM_STR(gateway_ptr->register_from), SIPTAG_CONTACT_STR(gateway_ptr->register_contact), SIPTAG_EXPIRES_STR(gw_sub_ptr->expires_str), // sofia stack bases its auto-refresh stuff on this + nua_subscribe(gateway_ptr->sub_nh, + NUTAG_URL(gateway_ptr->register_url), + TAG_IF(user_via, SIPTAG_VIA_STR(user_via)), + SIPTAG_EVENT_STR(gw_sub_ptr->event), + SIPTAG_ACCEPT_STR(gw_sub_ptr->content_type), + SIPTAG_TO_STR(gateway_ptr->register_from), + SIPTAG_FROM_STR(gateway_ptr->register_from), + SIPTAG_CONTACT_STR(gateway_ptr->register_contact), + SIPTAG_EXPIRES_STR(gw_sub_ptr->expires_str), /* sofia stack bases its auto-refresh stuff on this */ TAG_NULL()); gw_sub_ptr->retry = now + gw_sub_ptr->retry_seconds; } else { @@ -266,6 +280,7 @@ void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now) for (gateway_ptr = profile->gateways; gateway_ptr; gateway_ptr = gateway_ptr->next) { reg_state_t ostate = gateway_ptr->state; char *user_via = NULL; + char *register_host = NULL; if (!now) { gateway_ptr->state = ostate = REG_STATE_UNREGED; @@ -277,10 +292,15 @@ void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now) nua_handle_t *nh = nua_handle(profile->nua, NULL, NUTAG_URL(gateway_ptr->register_url), TAG_END()); sofia_private_t *pvt; - if (sofia_glue_check_nat(gateway_ptr->profile, gateway_ptr->register_proxy)) { + register_host = sofia_glue_get_register_host(gateway_ptr->register_proxy); + + /* check for NAT and place a Via header if necessary (hostname or non-local IP) */ + if (sofia_glue_check_nat(gateway_ptr->profile, register_host)) { user_via = sofia_glue_create_external_via(NULL, gateway_ptr->profile, gateway_ptr->register_transport); } + switch_safe_free(register_host); + pvt = malloc(sizeof(*pvt)); switch_assert(pvt); memset(pvt, 0, sizeof(*pvt)); @@ -335,10 +355,15 @@ void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now) sofia_reg_new_handle(gateway_ptr, now ? 1 : 0); } - if (sofia_glue_check_nat(gateway_ptr->profile, gateway_ptr->register_proxy)) { + register_host = sofia_glue_get_register_host(gateway_ptr->register_proxy); + + /* check for NAT and place a Via header if necessary (hostname or non-local IP) */ + if (sofia_glue_check_nat(gateway_ptr->profile, register_host)) { user_via = sofia_glue_create_external_via(NULL, gateway_ptr->profile, gateway_ptr->register_transport); } + switch_safe_free(register_host); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Registering %s\n", gateway_ptr->name); if (now) {