[Freeswitch-svn] [commit] r8511 - freeswitch/trunk/src/mod/endpoints/mod_sofia

Freeswitch SVN anthm at freeswitch.org
Wed May 21 17:49:27 EDT 2008


Author: anthm
Date: Wed May 21 17:49:27 2008
New Revision: 8511

Modified:
   freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h
   freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c
   freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_presence.c
   freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_reg.c

Log:
swatting at NAT

Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h	(original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h	Wed May 21 17:49:27 2008
@@ -556,7 +556,7 @@
 switch_call_cause_t sofia_glue_sip_cause_to_freeswitch(int status);
 void sofia_glue_do_xfer_invite(switch_core_session_t *session);
 uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, 
-								  sofia_regtype_t regtype, char *key, uint32_t keylen, switch_event_t **v_event);
+								  sofia_regtype_t regtype, char *key, uint32_t keylen, switch_event_t **v_event, const char *is_nat);
 extern switch_endpoint_interface_t *sofia_endpoint_interface;
 void sofia_presence_set_chat_hash(private_object_t *tech_pvt, sip_t const *sip);
 switch_status_t sofia_on_hangup(switch_core_session_t *session);

Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c	(original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c	Wed May 21 17:49:27 2008
@@ -2670,7 +2670,9 @@
 			const char *port = sip->sip_via->v_port;
 			const char *host = sip->sip_via->v_host;
 			
-			if (host && strcmp(network_ip, host)) {
+			if (host && sip->sip_via->v_received) {
+				is_nat = "via received";
+			} else if (host && strcmp(network_ip, host)) {
 				is_nat = "via host";
 			} else if (port && atoi(port) != network_port) {
 				is_nat = "via port";
@@ -2737,7 +2739,7 @@
 		if (!strcmp(network_ip, profile->sipip) && network_port == profile->sip_port) {
 			calling_myself++;
 		} else {
-			if (sofia_reg_handle_register(nua, profile, nh, sip, REG_INVITE, key, sizeof(key), &v_event)) {
+			if (sofia_reg_handle_register(nua, profile, nh, sip, REG_INVITE, key, sizeof(key), &v_event, NULL)) {
 				if (v_event) {
 					switch_event_destroy(&v_event);
 				}

Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_presence.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_presence.c	(original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_presence.c	Wed May 21 17:49:27 2008
@@ -1136,7 +1136,7 @@
 	char *sub_to_user = argv[0];
 	char *sub_to_host = argv[1];
 	char *event = "message-summary";
-	char *contact = argv[2];
+	char *contact, *o_contact = argv[2];
 	char *body = argv[3];
 	char *id = NULL;
 	nua_handle_t *nh;
@@ -1145,7 +1145,7 @@
 	
 	id = switch_mprintf("sip:%s@%s", sub_to_user, sub_to_host);
 
-	contact = sofia_glue_get_url_from_contact(contact, 0);
+	contact = sofia_glue_get_url_from_contact(o_contact, 1);
 	
 	nh = nua_handle(h->profile->nua, NULL,
 					NUTAG_URL(contact),
@@ -1156,8 +1156,10 @@
 	
 	nua_notify(nh,
 			   NUTAG_NEWSUB(1),
+			   TAG_IF(strstr(o_contact, ";nat"), NUTAG_PROXY(contact)),
 			   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);
 	
 	return 0;
@@ -1189,40 +1191,97 @@
 		switch_event_t *sevent;
 		int sub_state;
 		int sent_reply = 0;
+		su_addrinfo_t *my_addrinfo = msg_addrinfo(nua_current_request(nua));
+		int network_port = 0;
+		char network_ip[80];
+		const char *contact_host, *contact_user;
+		char *port;
+		char new_port[25] = "";
+		char *is_nat = NULL;
+
+		if (!(contact && sip->sip_contact->m_url)) {
+			nua_respond(nh, 481, "INVALID SUBSCRIPTION", TAG_END());
+			return;
+		}
+
+		get_addr(network_ip, sizeof(network_ip), &((struct sockaddr_in *) my_addrinfo->ai_addr)->sin_addr);
+		network_port = ntohs(((struct sockaddr_in *) msg_addrinfo(nua_current_request(nua))->ai_addr)->sin_port);
 
 		tl_gets(tags,
 				NUTAG_SUBSTATE_REF(sub_state), TAG_END());
 
 		event = sip_header_as_string(profile->home, (void *) sip->sip_event);
 
-		if (contact) {
-			char *port = (char *) contact->m_url->url_port;
-			char new_port[25] = "";
-
-			display = contact->m_display;
-
-			if (switch_strlen_zero(display)) {
-				if (from) {
-					display = from->a_display;
-					if (switch_strlen_zero(display)) {
-						display = "\"user\"";
-					}
+		port = (char *) contact->m_url->url_port;
+		contact_host = sip->sip_contact->m_url->url_host;
+		contact_user = sip->sip_contact->m_url->url_user;
+			
+		display = contact->m_display;
+
+		if (switch_strlen_zero(display)) {
+			if (from) {
+				display = from->a_display;
+				if (switch_strlen_zero(display)) {
+					display = "\"user\"";
 				}
-			} else {
-				display = "\"user\"";
 			}
-
-			if (port) {
-				switch_snprintf(new_port, sizeof(new_port), ":%s", port);
+		} else {
+			display = "\"user\"";
+		}
+			
+		if ((profile->pflags & PFLAG_AGGRESSIVE_NAT_DETECTION)) {
+			if (sip && sip->sip_via) {
+				const char *port = sip->sip_via->v_port;
+				const char *host = sip->sip_via->v_host;
+					
+				if (host && sip->sip_via->v_received) {
+					is_nat = "via received";
+				} else if (host && strcmp(network_ip, host)) {
+					is_nat = "via host";
+				} else if (port && atoi(port) != network_port) {
+					is_nat = "via port";
+				}
 			}
+		}
 			
-			if (contact->m_url->url_params) {
-				contact_str = switch_mprintf("%s <sip:%s@%s%s;%s>",
-											 display, contact->m_url->url_user, contact->m_url->url_host, new_port, contact->m_url->url_params);
-			} else {
-				contact_str = switch_mprintf("%s <sip:%s@%s%s>", display, contact->m_url->url_user, contact->m_url->url_host, new_port);
+		if (!is_nat && profile->nat_acl_count) {
+			uint32_t x = 0;
+			int ok = 1;
+			char *last_acl = NULL;
+				
+			if (!switch_strlen_zero(contact_host)) {
+				for (x = 0 ; x < profile->nat_acl_count; x++) {
+					last_acl = profile->nat_acl[x];
+					if (!(ok = switch_check_network_list_ip(contact_host, last_acl))) {
+						break;
+					}
+				}
+					
+				if (ok) {
+					is_nat = last_acl;
+				}
 			}
 		}
+			
+			
+		if (is_nat) {
+			contact_host = network_ip;
+			switch_snprintf(new_port, sizeof(new_port), ":%d", network_port);
+			port = NULL;
+		}
+
+
+		if (port) {
+			switch_snprintf(new_port, sizeof(new_port), ":%s", port);
+		}
+			
+		if (contact->m_url->url_params) {
+			contact_str = switch_mprintf("%s <sip:%s@%s%s;%s>%s",
+										 display, contact->m_url->url_user, contact_host, new_port, contact->m_url->url_params, is_nat ? ";nat" : "");
+		} else {
+			contact_str = switch_mprintf("%s <sip:%s@%s%s>%s", display, contact->m_url->url_user, contact_host, new_port, is_nat ? ";nat" : "");
+		}
+		
 
 		if (to) {
 			to_str = switch_mprintf("sip:%s@%s", to->a_url->url_user, to->a_url->url_host);	//, to->a_url->url_port);
@@ -1336,14 +1395,25 @@
 	
 		switch_mutex_unlock(profile->ireg_mutex);
 
+
 		if (status < 200) {
-			nua_respond(nh, SIP_202_ACCEPTED,
+			char *sticky = NULL;
+			
+			if (is_nat) {
+				sticky = switch_mprintf("sip:%s@%s:%d", contact_user, network_ip, network_port);
+			}
+
+			nua_respond(nh, SIP_202_ACCEPTED,						
 						NUTAG_WITH_THIS(nua),
 						SIPTAG_SUBSCRIPTION_STATE_STR(sstr), 
+						TAG_IF(sticky, NUTAG_PROXY(sticky)),
 						//SIPTAG_FROM(sip->sip_to),
 						//SIPTAG_TO(sip->sip_from),
 						//SIPTAG_CONTACT_STR(contact_str),
 						TAG_END());
+
+			switch_safe_free(sticky);
+
 		}
 		
 		sent_reply++;

Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_reg.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_reg.c	(original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_reg.c	Wed May 21 17:49:27 2008
@@ -333,7 +333,7 @@
 	
 
 	if (now) {
-		switch_snprintf(sql, sizeof(sql), "select * from sip_registrations where status like '%%NATHACK%%'");
+		switch_snprintf(sql, sizeof(sql), "select * from sip_registrations where status like '%%AUTO-NAT%%'");
 		sofia_glue_execute_sql_callback(profile,
 										SWITCH_TRUE,
 										NULL,
@@ -414,7 +414,7 @@
 }
 
 uint8_t sofia_reg_handle_register(nua_t * nua, sofia_profile_t *profile, nua_handle_t * nh, sip_t const *sip, sofia_regtype_t regtype, char *key,
-								  uint32_t keylen, switch_event_t **v_event)
+								  uint32_t keylen, switch_event_t **v_event, const char *is_nat)
 {
 	sip_to_t const *to = NULL;
 	sip_expires_t const *expires = NULL;
@@ -466,7 +466,15 @@
 		const char *port = contact->m_url->url_port;
 		char new_port[25] = "";
 		display = contact->m_display;
-
+		const char *contact_host = contact->m_url->url_host;
+		
+		if (is_nat) {
+			reg_desc = "Registered(AUTO-NAT)";
+			contact_host = network_ip;
+			switch_snprintf(new_port, sizeof(new_port), ":%d", network_port);
+			port = NULL;
+		}
+		
 		if (switch_strlen_zero(display)) {
 			if (to) {
 				display = to->a_display;
@@ -481,10 +489,10 @@
 		}
 
 		if (contact->m_url->url_params) {
-			switch_snprintf(contact_str, sizeof(contact_str), "%s <sip:%s@%s%s;%s>",
-							display, contact->m_url->url_user, contact->m_url->url_host, new_port, contact->m_url->url_params);
+			switch_snprintf(contact_str, sizeof(contact_str), "%s <sip:%s@%s%s;%s>%s",
+							display, contact->m_url->url_user, contact_host, new_port, contact->m_url->url_params, is_nat ? ";nat" : "");
 		} else {
-			switch_snprintf(contact_str, sizeof(contact_str), "%s <sip:%s@%s%s>", display, contact->m_url->url_user, contact->m_url->url_host, new_port);
+			switch_snprintf(contact_str, sizeof(contact_str), "%s <sip:%s@%s%s>%s", display, contact->m_url->url_user, contact_host, new_port, is_nat ? ";nat" : "");
 		}
 	}
 
@@ -537,7 +545,7 @@
 					if (strstr(v_contact_str, "tls")) {
 						reg_desc = "Registered(TLSHACK)";
 					} else {
-						reg_desc = "Registered(NATHACK)";
+						reg_desc = "Registered(AUTO-NAT)";
 						exptime = 20;
 					}
 					nat_hack = 1;
@@ -609,8 +617,6 @@
 		sql = switch_mprintf("insert into sip_registrations values ('%q', '%q','%q','%q','%q', '%q', %ld, '%q')", call_id,
 							 to_user, to_host, contact_str, reg_desc,
 							 rpid, (long) switch_timestamp(NULL) + (long) exptime * 2, agent);
-
-		
 		if (sql) {
 			sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
 		}
@@ -747,6 +753,7 @@
 	su_addrinfo_t *my_addrinfo = msg_addrinfo(nua_current_request(nua));
 	sofia_regtype_t type = REG_REGISTER;
 	int network_port = 0;
+	char *is_nat = NULL;
 
 	get_addr(network_ip, sizeof(network_ip), &((struct sockaddr_in *) my_addrinfo->ai_addr)->sin_addr);
 	network_port = ntohs(((struct sockaddr_in *) msg_addrinfo(nua_current_request(nua))->ai_addr)->sin_port);
@@ -765,6 +772,45 @@
 		goto end;
 	}
 
+	if ((profile->pflags & PFLAG_AGGRESSIVE_NAT_DETECTION)) {
+		if (sip && sip->sip_via) {
+			const char *port = sip->sip_via->v_port;
+			const char *host = sip->sip_via->v_host;
+			
+			if (host && sip->sip_via->v_received) {
+				is_nat = "via received";
+			} else if (host && strcmp(network_ip, host)) {
+				is_nat = "via host";
+			} else if (port && atoi(port) != network_port) {
+				is_nat = "via port";
+			}
+		}
+	}
+
+	if (!is_nat && profile->nat_acl_count) {
+		uint32_t x = 0;
+		int ok = 1;
+		char *last_acl = NULL;
+		const char *contact_host = NULL;
+
+		if (sip && sip->sip_contact && sip->sip_contact->m_url) {
+			contact_host = sip->sip_contact->m_url->url_host;
+		}
+
+		if (!switch_strlen_zero(contact_host)) {
+			for (x = 0 ; x < profile->nat_acl_count; x++) {
+				last_acl = profile->nat_acl[x];
+				if (!(ok = switch_check_network_list_ip(contact_host, last_acl))) {
+					break;
+				}
+			}
+			
+			if (ok) {
+				is_nat = last_acl;
+			}
+		}
+	}
+
 	if (profile->reg_acl_count) {
 		uint32_t x = 0;
 		int ok = 1;
@@ -796,7 +842,7 @@
 		goto end;
 	}
 
-	sofia_reg_handle_register(nua, profile, nh, sip, type, key, sizeof(key), &v_event);
+	sofia_reg_handle_register(nua, profile, nh, sip, type, key, sizeof(key), &v_event, is_nat);
 
 	if (v_event) {
 		switch_event_fire(&v_event);



More information about the Freeswitch-svn mailing list