[Freeswitch-branches] [commit] r13553 - freeswitch/branches/brian/trunk/src/mod/endpoints/mod_sofia
FreeSWITCH SVN
brian at freeswitch.org
Tue Jun 2 14:02:48 PDT 2009
Author: brian
Date: Tue Jun 2 16:02:47 2009
New Revision: 13553
Log:
adding NAT patch to my branch so others can help
Modified:
freeswitch/branches/brian/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
freeswitch/branches/brian/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h
freeswitch/branches/brian/trunk/src/mod/endpoints/mod_sofia/sofia.c
freeswitch/branches/brian/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c
freeswitch/branches/brian/trunk/src/mod/endpoints/mod_sofia/sofia_presence.c
freeswitch/branches/brian/trunk/src/mod/endpoints/mod_sofia/sofia_sla.c
Modified: freeswitch/branches/brian/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
==============================================================================
--- freeswitch/branches/brian/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c (original)
+++ freeswitch/branches/brian/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c Tue Jun 2 16:02:47 2009
@@ -394,6 +394,7 @@
if (!sofia_test_flag(tech_pvt, TFLAG_BYE)) {
nua_bye(tech_pvt->nh,
SIPTAG_REASON_STR(reason),
+ TAG_IF(!switch_strlen_zero(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
TAG_IF(!switch_strlen_zero(bye_headers), SIPTAG_HEADER_STR(bye_headers)),
TAG_END());
}
@@ -407,7 +408,6 @@
nua_cancel(tech_pvt->nh,
SIPTAG_REASON_STR(reason),
TAG_IF(!switch_strlen_zero(bye_headers), SIPTAG_HEADER_STR(bye_headers)),
- TAG_IF(!switch_strlen_zero(bye_headers), SIPTAG_HEADER_STR(bye_headers)),
TAG_END());
}
} else {
@@ -2644,6 +2644,9 @@
}
} else {
+ char *dup_dest = NULL, *dest_host, *dest_user;
+
+
if (!(dest = strchr(profile_name, '/'))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid URL\n");
cause = SWITCH_CAUSE_INVALID_NUMBER_FORMAT;
@@ -2661,10 +2664,17 @@
profile_name = profile->domain_name;
}
+ dup_dest = strdup(dest);
+ switch_assert(dup_dest != NULL);
+ sofia_glue_get_user_host(dup_dest, &dest_user, &dest_host);
+ tech_pvt->remote_ip = switch_core_session_sprintf(nsession, "%s", dest_host);
+ switch_safe_free(dup_dest);
+
if (!strncasecmp(dest, "sip:", 4) || !strncasecmp(dest, "sips:", 5)) {
tech_pvt->dest = switch_core_session_strdup(nsession, dest);
} else if ((host = strchr(dest, '%'))) {
char buf[128];
+
*host = '@';
tech_pvt->e_dest = switch_core_session_strdup(nsession, dest);
*host++ = '\0';
@@ -2678,6 +2688,7 @@
}
} else if (!(host = strchr(dest, '@'))) {
char buf[128];
+
tech_pvt->e_dest = switch_core_session_strdup(nsession, dest);
if (sofia_reg_find_reg_url(profile, dest, profile_name, buf, sizeof(buf))) {
tech_pvt->dest = switch_core_session_strdup(nsession, buf);
@@ -3217,6 +3228,8 @@
mod_sofia_globals.running = 1;
switch_mutex_unlock(mod_sofia_globals.mutex);
+ mod_sofia_globals.auto_nat = (switch_core_get_variable("nat_type") ? 1 : 0);
+
switch_queue_create(&mod_sofia_globals.presence_queue, SOFIA_QUEUE_SIZE, mod_sofia_globals.pool);
switch_queue_create(&mod_sofia_globals.mwi_queue, SOFIA_QUEUE_SIZE, mod_sofia_globals.pool);
Modified: freeswitch/branches/brian/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h
==============================================================================
--- freeswitch/branches/brian/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h (original)
+++ freeswitch/branches/brian/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h Tue Jun 2 16:02:47 2009
@@ -192,6 +192,7 @@
PFLAG_MESSAGE_QUERY_ON_REGISTER,
PFLAG_RTP_AUTOFLUSH_DURING_BRIDGE,
PFLAG_PROXY_FOLLOW_REDIRECT,
+ PFLAG_AUTO_NAT,
/* No new flags below this line */
PFLAG_MAX
} PFLAGS;
@@ -272,6 +273,7 @@
char guess_mask_str[16];
int debug_presence;
int auto_restart;
+ int auto_nat;
};
extern struct mod_sofia_globals mod_sofia_globals;
@@ -408,9 +410,13 @@
char *extsipip;
char *username;
char *url;
+ char *public_url;
char *bindurl;
char *tls_url;
+ char *tls_public_url;
char *tls_bindurl;
+ char *tcp_public_contact;
+ char *tls_public_contact;
char *tcp_contact;
char *tls_contact;
char *sla_contact;
@@ -489,6 +495,7 @@
uint32_t timer_t2;
uint32_t timer_t4;
char *contact_user;
+ char *local_network;
};
struct private_object {
@@ -613,6 +620,7 @@
switch_rtp_bug_flag_t rtp_bugs;
switch_codec_implementation_t read_impl;
switch_codec_implementation_t write_impl;
+ char *user_via;
};
struct callback_t {
Modified: freeswitch/branches/brian/trunk/src/mod/endpoints/mod_sofia/sofia.c
==============================================================================
--- freeswitch/branches/brian/trunk/src/mod/endpoints/mod_sofia/sofia.c (original)
+++ freeswitch/branches/brian/trunk/src/mod/endpoints/mod_sofia/sofia.c Tue Jun 2 16:02:47 2009
@@ -766,6 +766,7 @@
sofia_event_callback, /* Callback for processing events */
profile, /* Additional data to pass to callback */
NUTAG_URL(profile->bindurl),
+ NTATAG_USER_VIA(1),
TAG_IF(!strchr(profile->sipip, ':'), SOATAG_AF(SOA_AF_IP4_ONLY)),
TAG_IF(strchr(profile->sipip, ':'), SOATAG_AF(SOA_AF_IP6_ONLY)),
TAG_IF(sofia_test_pflag(profile, PFLAG_TLS), NUTAG_SIPS_URL(profile->tls_bindurl)),
@@ -1759,6 +1760,8 @@
}
} else if(!strcasecmp(var, "context")) {
profile->context = switch_core_strdup(profile->pool, val);
+ } else if (!strcasecmp(var, "local-network-acl")) {
+ profile->local_network = switch_core_strdup(profile->pool, val);
} else if (!strcasecmp(var, "force-register-domain")) {
profile->reg_domain = switch_core_strdup(profile->pool, val);
} else if (!strcasecmp(var, "force-register-db-domain")) {
@@ -2163,8 +2166,11 @@
if (!strcmp(val, "0.0.0.0")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid IP 0.0.0.0 replaced with %s\n", mod_sofia_globals.guess_ip);
+ } else if (!strcasecmp(val, "auto-nat")) {
+ ip = mod_sofia_globals.auto_nat ? switch_core_get_variable("nat_public_addr") : mod_sofia_globals.guess_ip;
+ sofia_set_pflag(profile, PFLAG_AUTO_NAT);
} else {
- ip = strcasecmp(val, "auto") ? val : mod_sofia_globals.guess_ip;
+ ip = strcasecmp(val, "auto") ? val : mod_sofia_globals.guess_ip;
}
profile->extrtpip = switch_core_strdup(profile->pool, ip);
} else {
@@ -2198,6 +2204,9 @@
if (!strcasecmp(val, "0.0.0.0")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid IP 0.0.0.0 replaced with %s\n", mod_sofia_globals.guess_ip);
+ } else if (!strcasecmp(val, "auto-nat")) {
+ ip = mod_sofia_globals.auto_nat ? switch_core_get_variable("nat_public_addr") : mod_sofia_globals.guess_ip;
+ sofia_set_pflag(profile, PFLAG_AUTO_NAT);
} else if (strcasecmp(val, "auto")) {
switch_port_t port = 0;
if (sofia_glue_ext_address_lookup(profile, NULL, &myip, &port, val, profile->pool) == SWITCH_STATUS_SUCCESS) {
@@ -2210,6 +2219,8 @@
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid ext-sip-ip\n");
}
+ } else if (!strcasecmp(var, "local-network-acl")) {
+ profile->local_network = switch_core_strdup(profile->pool, val);
} else if (!strcasecmp(var, "force-register-domain")) {
profile->reg_domain = switch_core_strdup(profile->pool, val);
} else if (!strcasecmp(var, "force-register-db-domain")) {
@@ -2264,7 +2275,7 @@
} else if (!strcasecmp(var, "manage-shared-appearance")) {
if (switch_true(val)) {
sofia_set_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE);
- profile->sla_contact = switch_core_sprintf(profile->pool, "sip:sla-agent@%s", profile->sipip);
+ profile->sla_contact = switch_core_sprintf(profile->pool, "sla-agent");
}
} else if (!strcasecmp(var, "disable-srv")) {
if (switch_true(val)) {
@@ -2548,7 +2559,18 @@
if (!profile->sipdomain) {
profile->sipdomain = switch_core_strdup(profile->pool, profile->sipip);
}
- if (profile->extsipip) {
+ if (profile->extsipip && sofia_test_pflag(profile, PFLAG_AUTO_NAT)) {
+ char *ipv6 = strchr(profile->extsipip, ':');
+ profile->public_url = switch_core_sprintf(profile->pool,
+ "sip:%s@%s%s%s:%d",
+ profile->contact_user,
+ ipv6 ? "[" : "",
+ profile->extsipip,
+ ipv6 ? "]" : "",
+ profile->sip_port);
+ }
+
+ if (profile->extsipip && !sofia_test_pflag(profile, PFLAG_AUTO_NAT)) {
char *ipv6 = strchr(profile->extsipip, ':');
profile->url = switch_core_sprintf(profile->pool,
"sip:%s@%s%s%s:%d",
@@ -2571,7 +2593,11 @@
}
profile->tcp_contact = switch_core_sprintf(profile->pool, "%s;transport=tcp", profile->url);
-
+
+ if(sofia_test_pflag(profile, PFLAG_AUTO_NAT)) {
+ profile->tcp_public_contact = switch_core_sprintf(profile->pool, "%s;transport=tcp", profile->public_url);
+ }
+
if (profile->bind_params) {
char *bindurl = profile->bindurl;
profile->bindurl = switch_core_sprintf(profile->pool, "%s;%s", bindurl, profile->bind_params);
@@ -2585,7 +2611,18 @@
profile->tls_sip_port = atoi(SOFIA_DEFAULT_TLS_PORT);
}
- if (profile->extsipip) {
+ if (profile->extsipip && sofia_test_pflag(profile, PFLAG_AUTO_NAT)) {
+ char *ipv6 = strchr(profile->extsipip, ':');
+ profile->tls_public_url = switch_core_sprintf(profile->pool,
+ "sip:%s@%s%s%s:%d",
+ profile->contact_user,
+ ipv6 ? "[" : "",
+ profile->extsipip,
+ ipv6 ? "]" : "",
+ profile->tls_sip_port);
+ }
+
+ if (profile->extsipip && !sofia_test_pflag(profile, PFLAG_AUTO_NAT)) {
char *ipv6 = strchr(profile->extsipip, ':');
profile->tls_url =
switch_core_sprintf(profile->pool,
@@ -2632,6 +2669,9 @@
profile->tls_cert_dir = switch_core_sprintf(profile->pool, "%s/ssl", SWITCH_GLOBAL_dirs.conf_dir);
}
profile->tls_contact = switch_core_sprintf(profile->pool, "%s;transport=tls", profile->tls_url);
+ if (sofia_test_pflag(profile, PFLAG_AUTO_NAT)) {
+ profile->tls_public_contact = switch_core_sprintf(profile->pool, "%s;transport=tls", profile->tls_public_url);
+ }
}
}
if (profile) {
@@ -4309,6 +4349,7 @@
get_addr(network_ip, sizeof(network_ip), my_addrinfo->ai_addr, my_addrinfo->ai_addrlen);
network_port = ntohs(((struct sockaddr_in *) msg_addrinfo(nua_current_request(nua))->ai_addr)->sin_port);
+
if (sofia_test_pflag(profile, PFLAG_AGGRESSIVE_NAT_DETECTION)) {
if (sip && sip->sip_via) {
const char *port = sip->sip_via->v_port;
@@ -4428,6 +4469,12 @@
tech_pvt->remote_ip = switch_core_session_strdup(session, network_ip);
tech_pvt->remote_port = network_port;
+
+ if (sofia_test_pflag(profile, PFLAG_AUTO_NAT) && !switch_check_network_list_ip(tech_pvt->remote_ip, profile->local_network)) {
+ sofia_transport_t transport = sofia_glue_url2transport(sip->sip_contact->m_url);
+ tech_pvt->user_via = switch_core_session_sprintf(session, "SIP/2.0/%s %s;rport", sofia_glue_transport2str(transport),
+ profile->extsipip);
+ }
channel = tech_pvt->channel = switch_core_session_get_channel(session);
@@ -4626,7 +4673,8 @@
const char *url;
- if ((url = (sofia_glue_transport_has_tls(transport)) ? profile->tls_url : profile->url)) {
+ if ((url = (sofia_glue_transport_has_tls(transport)) ? profile->tls_url :
+ (switch_check_network_list_ip(tech_pvt->remote_ip, profile->local_network)) ? profile->url : profile->public_url)) {
if (strchr(url, '>')) {
tech_pvt->reply_contact = switch_core_session_sprintf(session, "%s;transport=%s", url, sofia_glue_transport2str(transport));
} else {
Modified: freeswitch/branches/brian/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c
==============================================================================
--- freeswitch/branches/brian/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c (original)
+++ freeswitch/branches/brian/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c Tue Jun 2 16:02:47 2009
@@ -642,15 +642,16 @@
switch_rtp_release_port(tech_pvt->profile->rtpip, tech_pvt->local_sdp_audio_port);
}
-
tech_pvt->local_sdp_audio_ip = ip;
+
if (!(tech_pvt->local_sdp_audio_port = switch_rtp_request_port(tech_pvt->profile->rtpip))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "No RTP ports available!\n");
return SWITCH_STATUS_FALSE;
}
+
sdp_port = tech_pvt->local_sdp_audio_port;
- if (!(use_ip = switch_channel_get_variable(tech_pvt->channel, "rtp_adv_audio_ip"))) {
+ if (!(use_ip = switch_channel_get_variable(tech_pvt->channel, "rtp_adv_audio_ip")) && !sofia_test_pflag(tech_pvt->profile, PFLAG_AUTO_NAT)) {
if (tech_pvt->profile->extrtpip) {
use_ip = tech_pvt->profile->extrtpip;
}
@@ -663,9 +664,24 @@
return SWITCH_STATUS_FALSE;
}
}
-
- tech_pvt->adv_sdp_audio_ip = switch_core_session_strdup(tech_pvt->session, ip);
+ if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
+ if (tech_pvt->remote_ip && sofia_test_pflag(tech_pvt->profile, PFLAG_AUTO_NAT) &&
+ !switch_check_network_list_ip(tech_pvt->remote_ip, tech_pvt->profile->local_network)) {
+ tech_pvt->adv_sdp_audio_ip = switch_core_session_strdup(tech_pvt->session, tech_pvt->profile->extrtpip);
+ } else {
+ tech_pvt->adv_sdp_audio_ip = switch_core_session_strdup(tech_pvt->session, ip);
+ }
+ } else {
+
+ if (tech_pvt->remote_ip && sofia_test_pflag(tech_pvt->profile, PFLAG_AUTO_NAT) &&
+ !switch_check_network_list_ip(tech_pvt->remote_ip, tech_pvt->profile->local_network)) {
+ tech_pvt->adv_sdp_audio_ip = switch_core_session_strdup(tech_pvt->session, tech_pvt->profile->extrtpip);
+ } else {
+ tech_pvt->adv_sdp_audio_ip = switch_core_session_strdup(tech_pvt->session, ip);
+ }
+ }
+
tech_pvt->adv_sdp_audio_port = sdp_port;
switch_snprintf(tmp, sizeof(tmp), "%d", sdp_port);
@@ -1257,10 +1273,19 @@
check_decode(cid_num, session);
if (!tech_pvt->from_str) {
- const char* sipip = tech_pvt->profile->extsipip ? tech_pvt->profile->extsipip : tech_pvt->profile->sipip;
- const char* format = strchr(sipip, ':') ? "\"%s\" <sip:%s%s[%s]>" : "\"%s\" <sip:%s%s%s>";
+ const char* sipip;
+ const char* format;
const char *alt = NULL;
+ if (sofia_test_pflag(tech_pvt->profile, PFLAG_AUTO_NAT)) {
+ sipip = (switch_check_network_list_ip(tech_pvt->remote_ip, tech_pvt->profile->local_network))
+ ? tech_pvt->profile->sipip : tech_pvt->profile->extsipip;
+ } else {
+ sipip = tech_pvt->profile->extsipip ? tech_pvt->profile->extsipip : tech_pvt->profile->sipip;
+ }
+
+ format = strchr(sipip, ':') ? "\"%s\" <sip:%s%s[%s]>" : "\"%s\" <sip:%s%s%s>";
+
if ((alt = switch_channel_get_variable(channel, "sip_invite_domain"))) {
sipip = alt;
}
@@ -1303,7 +1328,7 @@
const char *invite_from_params = switch_channel_get_variable(tech_pvt->channel, "sip_invite_from_params");
const char *from_var = switch_channel_get_variable(tech_pvt->channel, "sip_from_uri");
const char *from_display = switch_channel_get_variable(tech_pvt->channel, "sip_from_display");
-
+
if (switch_strlen_zero(tech_pvt->dest)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "URL Error!\n");
return SWITCH_STATUS_FALSE;
@@ -1365,6 +1390,13 @@
tech_pvt->transport = SOFIA_TRANSPORT_UDP;
}
}
+
+ if (sofia_test_pflag(tech_pvt->profile, PFLAG_AUTO_NAT) && !switch_check_network_list_ip(tech_pvt->remote_ip, tech_pvt->profile->local_network)) {
+ const char *transport = sofia_glue_transport2str(tech_pvt->transport);
+ tech_pvt->user_via = switch_core_session_sprintf(session, "SIP/2.0/%s %s;rport",
+ transport, tech_pvt->profile->extsipip);
+ }
+
if (!sofia_test_pflag(tech_pvt->profile, PFLAG_TLS) && sofia_glue_transport_has_tls(tech_pvt->transport)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "TLS not supported by profile\n");
@@ -1374,8 +1406,18 @@
if (switch_strlen_zero(tech_pvt->invite_contact)) {
const char * contact;
if ((contact = switch_channel_get_variable(channel, "sip_contact_user"))) {
- char *ip_addr = (tech_pvt->profile->extsipip) ? tech_pvt->profile->extsipip : tech_pvt->profile->sipip;
- char *ipv6 = strchr(ip_addr, ':');
+ char *ip_addr;
+ char *ipv6;
+
+ if (sofia_test_pflag(tech_pvt->profile, PFLAG_AUTO_NAT)) {
+ ip_addr = (switch_check_network_list_ip(tech_pvt->remote_ip, tech_pvt->profile->local_network))
+ ? tech_pvt->profile->sipip : tech_pvt->profile->extsipip;
+ } else {
+ ip_addr = tech_pvt->profile->extsipip ? tech_pvt->profile->extsipip : tech_pvt->profile->sipip;
+ }
+
+ ipv6 = strchr(ip_addr, ':');
+
if (sofia_glue_transport_has_tls(tech_pvt->transport)) {
tech_pvt->invite_contact = switch_core_session_sprintf(session, "sip:%s@%s%s%s:%d", contact,
ipv6 ? "[" : "", ip_addr, ipv6 ? "]" : "",
@@ -1388,7 +1430,12 @@
if (sofia_glue_transport_has_tls(tech_pvt->transport)) {
tech_pvt->invite_contact = tech_pvt->profile->tls_url;
} else {
- tech_pvt->invite_contact = tech_pvt->profile->url;
+ if (sofia_test_pflag(tech_pvt->profile, PFLAG_AUTO_NAT) &&
+ !switch_check_network_list_ip(tech_pvt->remote_ip, tech_pvt->profile->local_network)) {
+ tech_pvt->invite_contact = tech_pvt->profile->public_url;
+ } else {
+ tech_pvt->invite_contact = tech_pvt->profile->url;
+ }
}
}
}
@@ -1603,6 +1650,7 @@
nua_invite(tech_pvt->nh,
NUTAG_AUTOANSWER(0),
NUTAG_SESSION_TIMER(session_timeout),
+ TAG_IF(!switch_strlen_zero(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
TAG_IF(!switch_strlen_zero(tech_pvt->rpid), SIPTAG_REMOTE_PARTY_ID_STR(tech_pvt->rpid)),
TAG_IF(!switch_strlen_zero(tech_pvt->preferred_id), SIPTAG_P_PREFERRED_IDENTITY_STR(tech_pvt->preferred_id)),
TAG_IF(!switch_strlen_zero(tech_pvt->asserted_id), SIPTAG_P_ASSERTED_IDENTITY_STR(tech_pvt->asserted_id)),
@@ -1630,14 +1678,23 @@
private_object_t *tech_pvt = switch_core_session_get_private(session);
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_caller_profile_t *caller_profile;
- const char *sipip, *format;
+ const char *sipip, *format, *contact_url;
switch_assert(tech_pvt != NULL);
switch_mutex_lock(tech_pvt->sofia_mutex);
caller_profile = switch_channel_get_caller_profile(channel);
- sipip = tech_pvt->profile->extsipip ? tech_pvt->profile->extsipip : tech_pvt->profile->sipip;
+ if (sofia_test_pflag(tech_pvt->profile, PFLAG_AUTO_NAT)) {
+ sipip = (switch_check_network_list_ip(tech_pvt->remote_ip, tech_pvt->profile->local_network))
+ ? tech_pvt->profile->sipip : tech_pvt->profile->extsipip;
+ contact_url = tech_pvt->profile->public_url;
+ } else {
+ sipip = tech_pvt->profile->extsipip ? tech_pvt->profile->extsipip : tech_pvt->profile->sipip;
+ contact_url = tech_pvt->profile->url;
+ }
+
format = strchr(sipip, ':') ? "\"%s\" <sip:%s@[%s]>" : "\"%s\" <sip:%s@%s>";
+
if ((tech_pvt->from_str = switch_core_session_sprintf(session, format,
caller_profile->caller_id_name,
caller_profile->caller_id_number, sipip))) {
@@ -1646,12 +1703,15 @@
tech_pvt->nh2 = nua_handle(tech_pvt->profile->nua, NULL,
SIPTAG_TO_STR(tech_pvt->dest),
- SIPTAG_FROM_STR(tech_pvt->from_str), SIPTAG_CONTACT_STR(tech_pvt->profile->url), TAG_END());
+ SIPTAG_FROM_STR(tech_pvt->from_str),
+ SIPTAG_CONTACT_STR(contact_url),
+ TAG_END());
nua_handle_bind(tech_pvt->nh2, tech_pvt->sofia_private);
nua_invite(tech_pvt->nh2,
- SIPTAG_CONTACT_STR(tech_pvt->profile->url),
+ SIPTAG_CONTACT_STR(contact_url),
+ TAG_IF(!switch_strlen_zero(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
SOATAG_ADDRESS(tech_pvt->adv_sdp_audio_ip),
SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str),
SOATAG_REUSE_REJECTED(1),
Modified: freeswitch/branches/brian/trunk/src/mod/endpoints/mod_sofia/sofia_presence.c
==============================================================================
--- freeswitch/branches/brian/trunk/src/mod/endpoints/mod_sofia/sofia_presence.c (original)
+++ freeswitch/branches/brian/trunk/src/mod/endpoints/mod_sofia/sofia_presence.c Tue Jun 2 16:02:47 2009
@@ -306,12 +306,10 @@
for_everyone = 1;
}
-
dup_account = strdup(account);
switch_assert(dup_account != NULL);
sofia_glue_get_user_host(dup_account, &user, &host);
-
if ((pname = switch_event_get_header(event, "sofia-profile"))) {
if (!(profile = sofia_glue_find_profile(pname))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No profile %s\n", pname);
@@ -375,11 +373,11 @@
}
if (for_everyone) {
- sql = switch_mprintf("select sip_user,sip_host,contact,profile_name,'%q' "
+ sql = switch_mprintf("select sip_user,sip_host,contact,profile_name,network_ip,'%q' "
"from sip_registrations where sip_user='%q' and sip_host='%q'",
stream.data, user, host);
} else if (call_id) {
- sql = switch_mprintf("select sip_user,sip_host,contact,profile_name,'%q' "
+ sql = switch_mprintf("select sip_user,sip_host,contact,profile_name,network_ip,'%q' "
"from sip_registrations where sip_user='%q' and sip_host='%q' and call_id='%q'",
stream.data, user, host, call_id);
}
@@ -1363,7 +1361,7 @@
profile = ext_profile;
}
}
-
+
if (!(nh = nua_handle_by_call_id(h->profile->nua, call_id))) {
if (profile->debug) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Cannot find handle for %s\n", call_id);
@@ -1379,7 +1377,10 @@
nua_handle_bind(nh, &mod_sofia_globals.keep_private);
nua_notify(nh, SIPTAG_SUBSCRIPTION_STATE_STR("active"),
- SIPTAG_EVENT_STR(event), SIPTAG_CONTENT_TYPE_STR("application/simple-message-summary"), SIPTAG_PAYLOAD_STR(body), TAG_END());
+ SIPTAG_EVENT_STR(event),
+ SIPTAG_CONTENT_TYPE_STR("application/simple-message-summary"),
+ SIPTAG_PAYLOAD_STR(body),
+ TAG_END());
switch_safe_free(id);
@@ -1401,13 +1402,14 @@
char *event = "message-summary";
char *contact, *o_contact = argv[2];
char *profile_name = argv[3];
- char *body = argv[4];
+ char *network_ip = argv[4];
+ char *body = argv[5];
char *id = NULL;
nua_handle_t *nh;
struct mwi_helper *h = (struct mwi_helper *) pArg;
sofia_profile_t *ext_profile = NULL, *profile = h->profile;
- char *route = NULL, *route_uri = NULL;
- char *p;
+ char *route = NULL, *route_uri = NULL, *user_via = NULL;
+ char *p, *contact_str;
if (profile_name && strcasecmp(profile_name, h->profile->name)) {
if ((ext_profile = sofia_glue_find_profile(profile_name))) {
@@ -1415,9 +1417,24 @@
}
}
- id = switch_mprintf("sip:%s@%s", sub_to_user, sub_to_host);
+ id = switch_mprintf("sip:%s@%s", sub_to_user, switch_check_network_list_ip(network_ip, profile->local_network) ? sub_to_host : profile->extsipip);
contact = sofia_glue_get_url_from_contact(o_contact, 1);
+
+ if (sofia_test_pflag(profile, PFLAG_AUTO_NAT) && !switch_check_network_list_ip(network_ip, profile->local_network)) {
+ char *ptr = NULL;
+ if ((ptr = sofia_glue_find_parameter(o_contact, "transport="))) {
+ sofia_transport_t transport = sofia_glue_str2transport(ptr);
+ user_via = switch_mprintf("SIP/2.0/%s %s;rport", sofia_glue_transport2str(transport), profile->extsipip);
+ printf("user_via -> %s\n", user_via);
+ } else {
+ user_via = switch_mprintf("SIP/2.0/UDP %s;rport", profile->extsipip);
+ }
+
+ contact_str = profile->public_url;
+ } else {
+ contact_str = profile->url;
+ }
if ((route = strstr(contact, ";fs_path=")) && (route = strdup(route + 9))) {
for (p = route; p && *p ; p++) {
@@ -1455,17 +1472,23 @@
}
}
- nh = nua_handle(profile->nua, NULL, NUTAG_URL(contact), SIPTAG_FROM_STR(id), SIPTAG_TO_STR(id), SIPTAG_CONTACT_STR(h->profile->url), TAG_END());
+ nh = nua_handle(profile->nua, NULL, NUTAG_URL(contact),
+ SIPTAG_FROM_STR(id), SIPTAG_TO_STR(id),
+ SIPTAG_CONTACT_STR(contact_str), TAG_END());
nua_handle_bind(nh, &mod_sofia_globals.destroy_private);
nua_notify(nh,
NUTAG_NEWSUB(1),
TAG_IF(route_uri, NUTAG_PROXY(route_uri)),
- SIPTAG_EVENT_STR(event), SIPTAG_CONTENT_TYPE_STR("application/simple-message-summary"), SIPTAG_PAYLOAD_STR(body), TAG_END());
+ TAG_IF(!switch_strlen_zero(user_via), SIPTAG_VIA_STR(user_via)),
+ SIPTAG_EVENT_STR(event),
+ SIPTAG_CONTENT_TYPE_STR("application/simple-message-summary"),
+ SIPTAG_PAYLOAD_STR(body), TAG_END());
switch_safe_free(contact);
switch_safe_free(id);
switch_safe_free(route);
+ switch_safe_free(user_via);
if (ext_profile) {
sofia_glue_release_profile(ext_profile);
}
@@ -1508,6 +1531,7 @@
char *port;
char new_port[25] = "";
char *is_nat = NULL;
+ int is_auto_nat = 0;
const char *ipv6;
if (!(contact && sip->sip_contact->m_url)) {
@@ -1518,6 +1542,10 @@
get_addr(network_ip, sizeof(network_ip), my_addrinfo->ai_addr, my_addrinfo->ai_addrlen);
network_port = ntohs(((struct sockaddr_in *) msg_addrinfo(nua_current_request(nua))->ai_addr)->sin_port);
+ if (sofia_test_pflag(profile, PFLAG_AUTO_NAT) && !switch_check_network_list_ip(network_ip, profile->local_network)) {
+ is_auto_nat = 1;
+ }
+
tl_gets(tags, NUTAG_SUBSTATE_REF(sub_state), TAG_END());
event = sip_header_as_string(profile->home, (void *) sip->sip_event);
@@ -1777,25 +1805,41 @@
network_port,
params);
}
+
+
+ if (is_auto_nat) {
+ contactstr = profile->public_url;
+ } else {
+ contactstr = profile->url;
+ }
+
if (switch_stristr("port=tcp", contact->m_url->url_params)) {
- contactstr = profile->tcp_contact;
+ if (is_auto_nat) {
+ contactstr = profile->tcp_public_contact;
+ } else {
+ contactstr = profile->tcp_contact;
+ }
} else if (switch_stristr("port=tls", contact->m_url->url_params)) {
- contactstr = profile->tls_contact;
+ if (is_auto_nat) {
+ contactstr = profile->tls_contact;
+ } else {
+ contactstr = profile->tls_public_contact;
+ }
}
-
if (nh && nh->nh_ds && nh->nh_ds->ds_usage) {
nua_dialog_usage_set_refresh_range(nh->nh_ds->ds_usage, exp_delta + SUB_OVERLAP, exp_delta + SUB_OVERLAP);
}
- nua_respond(nh, SIP_202_ACCEPTED, SIPTAG_CONTACT_STR(contactstr), NUTAG_WITH_THIS(nua),
+ nua_respond(nh, SIP_202_ACCEPTED,
+ SIPTAG_CONTACT_STR(contactstr),
+ NUTAG_WITH_THIS(nua),
SIPTAG_SUBSCRIPTION_STATE_STR(sstr),
SIPTAG_EXPIRES_STR(exp_delta_str),
TAG_IF(sticky, NUTAG_PROXY(sticky)), TAG_END());
switch_safe_free(sticky);
-
}
sent_reply++;
Modified: freeswitch/branches/brian/trunk/src/mod/endpoints/mod_sofia/sofia_sla.c
==============================================================================
--- freeswitch/branches/brian/trunk/src/mod/endpoints/mod_sofia/sofia_sla.c (original)
+++ freeswitch/branches/brian/trunk/src/mod/endpoints/mod_sofia/sofia_sla.c Tue Jun 2 16:02:47 2009
@@ -76,6 +76,12 @@
struct sla_helper sh = { { 0 } };
char *contact_str = strip_uri(full_contact);
sofia_transport_t transport = sofia_glue_url2transport(sip->sip_contact->m_url);
+ su_addrinfo_t *my_addrinfo = msg_addrinfo(nua_current_request(nua));
+ char network_ip[80];
+ int network_port = 0;
+
+ get_addr(network_ip, sizeof(network_ip), my_addrinfo->ai_addr, my_addrinfo->ai_addrlen);
+ network_port = ntohs(((struct sockaddr_in *) msg_addrinfo(nua_current_request(nua))->ai_addr)->sin_port);
sql = switch_mprintf("select call_id from sip_shared_appearance_dialogs where hostname='%q' and profile_name='%q' and contact_str='%q'",
mod_sofia_globals.hostname, profile->name, contact_str);
@@ -99,8 +105,13 @@
nua_handle_bind(nh, &mod_sofia_globals.keep_private);
switch_snprintf(exp_str, sizeof(exp_str), "%ld", exptime + 30);
- switch_snprintf(my_contact, sizeof(my_contact), "<%s;transport=%s>;expires=%s", profile->sla_contact, sofia_glue_transport2str(transport), exp_str);
-
+ if (sofia_test_pflag(profile, PFLAG_AUTO_NAT) && !switch_check_network_list_ip(network_ip, profile->local_network)) {
+ switch_snprintf(my_contact, sizeof(my_contact), "<sip:%s@%s;transport=%s>;expires=%s", profile->sla_contact,
+ profile->extsipip, sofia_glue_transport2str(transport), exp_str);
+ } else {
+ switch_snprintf(my_contact, sizeof(my_contact), "<sip:%s@%s;transport=%s>;expires=%s", profile->sla_contact,
+ profile->sipip, sofia_glue_transport2str(transport), exp_str);
+ }
nua_subscribe(nh,
SIPTAG_TO(sip->sip_to),
SIPTAG_FROM(sip->sip_to),
@@ -125,8 +136,14 @@
char *sql = NULL;
char *route_uri = NULL;
char *sla_contact = NULL;
+ su_addrinfo_t *my_addrinfo = msg_addrinfo(nua_current_request(nua));
+ char network_ip[80];
+ int network_port = 0;
sofia_transport_t transport = sofia_glue_url2transport(sip->sip_contact->m_url);
+
+ get_addr(network_ip, sizeof(network_ip), my_addrinfo->ai_addr, my_addrinfo->ai_addrlen);
+ network_port = ntohs(((struct sockaddr_in *) msg_addrinfo(nua_current_request(nua))->ai_addr)->sin_port);
/*
* XXX MTK FIXME - we don't look at the tag to see if NUTAG_SUBSTATE(nua_substate_terminated) or
* a Subscription-State header with state "terminated" and/or expiration of 0. So we never forget
@@ -187,8 +204,12 @@
*p++ = '\0';
}
}
-
- sla_contact = switch_mprintf("<%s;transport=%s>", profile->sla_contact, sofia_glue_transport2str(transport));
+
+ if (sofia_test_pflag(profile, PFLAG_AUTO_NAT) && !switch_check_network_list_ip(network_ip, profile->local_network)) {
+ sla_contact = switch_mprintf("<sip:%s@%s;transport=%s>", profile->sla_contact, profile->extsipip, sofia_glue_transport2str(transport));
+ } else {
+ sla_contact = switch_mprintf("<sip:%s@%s;transport=%s>", profile->sla_contact, profile->extsipip, sofia_glue_transport2str(transport));
+ }
nua_respond(nh, SIP_202_ACCEPTED, SIPTAG_CONTACT_STR(sla_contact), NUTAG_WITH_THIS(nua),
TAG_IF(route_uri, NUTAG_PROXY(route_uri)),
More information about the Freeswitch-branches
mailing list