[Freeswitch-svn] [commit] r13553 - freeswitch/branches/brian/trunk/src/mod/endpoints/mod_sofia

FreeSWITCH SVN brian at freeswitch.org
Tue Jun 2 14:02:47 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-svn mailing list