[Freeswitch-svn] [commit] r8391 - in freeswitch/trunk: conf/sip_profiles src/mod/endpoints/mod_sofia

Freeswitch SVN anthm at freeswitch.org
Tue May 13 19:22:21 EDT 2008


Author: anthm
Date: Tue May 13 19:22:21 2008
New Revision: 8391

Modified:
   freeswitch/trunk/conf/sip_profiles/internal.xml
   freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
   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_glue.c
   freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_reg.c

Log:
fix many nat woes, see changes to default config for details

Modified: freeswitch/trunk/conf/sip_profiles/internal.xml
==============================================================================
--- freeswitch/trunk/conf/sip_profiles/internal.xml	(original)
+++ freeswitch/trunk/conf/sip_profiles/internal.xml	Tue May 13 19:22:21 2008
@@ -35,10 +35,12 @@
     <!-- ip address to bind to -->
     <param name="sip-ip" value="$${local_ip_v4}"/>
     <param name="hold-music" value="$${hold_music}"/>
+    <param name="apply-register-acl" value="rfc1918"/>
+    <param name="apply-nat-acl" value="rfc1918"/>
     <!--<param name="enable-timer" value="false"/>-->
     <!--<param name="enable-100rel" value="false"/>-->
-    <!--<param name="apply-inbound-acl" value="lan"/>-->
-    <!--<param name="apply-register-acl" value="lan"/>-->
+    <!--<param name="apply-inbound-acl" value="rfc1918"/>-->
+    <!--<param name="apply-register-acl" value="rfc1918"/>-->
     <!--<param name="dtmf-type" value="info"/>-->
     <param name="record-template" value="$${base_dir}/recordings/${caller_id_number}.${strftime(%Y-%m-%d-%H-%M-%S)}.wav"/>
     <!--enable to use presense and mwi -->

Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c	(original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c	Tue May 13 19:22:21 2008
@@ -339,6 +339,7 @@
 	const char *val;
 	const char *b_sdp = NULL;
 	int is_proxy = 0;
+	char *sticky = NULL;
 
 	if (switch_test_flag(tech_pvt, TFLAG_ANS) || switch_channel_test_flag(channel, CF_OUTBOUND)) {
 		return SWITCH_STATUS_SUCCESS;
@@ -405,9 +406,19 @@
 			session_timeout = v_session_timeout;
 		}
 	}
+	
+	if (switch_test_flag(tech_pvt, TFLAG_NAT) ||
+		(val = switch_channel_get_variable(channel, "sip-force-contact")) || 
+		((val = switch_channel_get_variable(channel, "sip_sticky_contact")) && switch_true(val))) {
+		sticky = tech_pvt->record_route;
+		session_timeout = 20;
+	}
+
+	
 
 	nua_respond(tech_pvt->nh, SIP_200_OK,
 				NUTAG_AUTOANSWER(0),
+				TAG_IF(sticky, NUTAG_PROXY(tech_pvt->record_route)),
 				NUTAG_SESSION_TIMER(session_timeout),
 				SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
 				SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str),
@@ -1039,6 +1050,9 @@
 		break;
 	case SWITCH_MESSAGE_INDICATE_PROGRESS:
 		{
+			char *sticky = NULL;
+			const char *val = NULL;
+
 			if (!switch_test_flag(tech_pvt, TFLAG_ANS) && !switch_test_flag(tech_pvt, TFLAG_EARLY_MEDIA)) {
 				
 				switch_set_flag_locked(tech_pvt, TFLAG_EARLY_MEDIA);
@@ -1087,9 +1101,18 @@
 					}
 				}
 				switch_channel_mark_pre_answered(channel);
+
+
+				if (switch_test_flag(tech_pvt, TFLAG_NAT) ||
+					(val = switch_channel_get_variable(channel, "sip-force-contact")) || 
+					((val = switch_channel_get_variable(channel, "sip_sticky_contact")) && switch_true(val))) {
+					sticky = tech_pvt->record_route;
+				}
+
 				nua_respond(tech_pvt->nh,
 							SIP_183_SESSION_PROGRESS,
 							NUTAG_AUTOANSWER(0),
+							TAG_IF(sticky, NUTAG_PROXY(tech_pvt->record_route)),
 							SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
 							SOATAG_REUSE_REJECTED(1),
 							SOATAG_ORDERED_USER(1),
@@ -1865,6 +1888,8 @@
 		switch_ivr_transfer_variable(session, nsession, "sip_auto_answer");
 		switch_ivr_transfer_variable(session, nsession, SOFIA_SIP_HEADER_PREFIX_T);
 		switch_ivr_transfer_variable(session, nsession, "sip_video_fmtp");
+		switch_ivr_transfer_variable(session, nsession, "sip-force-contact");
+		switch_ivr_transfer_variable(session, nsession, "sip_sticky_contact");
 
 		if (switch_core_session_compare(session, nsession)) {
 			/* It's another sofia channel! so lets cache what they use as a pt for telephone event so 

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	Tue May 13 19:22:21 2008
@@ -172,7 +172,7 @@
 	TFLAG_REFER = (1 << 17),
 	TFLAG_NOHUP = (1 << 18),
 	TFLAG_XFER = (1 << 19),
-	TFLAG_RESERVED = (1 << 20),
+	TFLAG_NAT = (1 << 20),
 	TFLAG_BUGGY_2833 = (1 << 21),
 	TFLAG_SIP_HOLD = (1 << 22),
 	TFLAG_INB_NOMEDIA = (1 << 23),
@@ -330,6 +330,8 @@
 	uint32_t acl_count;
 	char *reg_acl[SOFIA_MAX_ACL];
 	uint32_t reg_acl_count;
+	char *nat_acl[SOFIA_MAX_ACL];
+	uint32_t nat_acl_count;
 
 };
 
@@ -394,6 +396,7 @@
 	char *gateway_name;
 	char *local_crypto_key;
 	char *remote_crypto_key;
+	char *record_route;
 	int crypto_tag;
 	unsigned char local_raw_key[SWITCH_RTP_MAX_CRYPTO_LEN];
 	unsigned char remote_raw_key[SWITCH_RTP_MAX_CRYPTO_LEN];
@@ -434,6 +437,8 @@
 	uint32_t video_count;
 	sofia_dtmf_t dtmf_type;
 	int q850_cause;
+	char *remote_ip;
+	int remote_port;
 };
 
 struct callback_t {
@@ -444,7 +449,8 @@
 
 typedef enum {
 	REG_REGISTER,
-	REG_INVITE
+	REG_AUTO_REGISTER,
+	REG_INVITE,
 } sofia_regtype_t;
 
 typedef enum {

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	Tue May 13 19:22:21 2008
@@ -1299,6 +1299,12 @@
 						profile->username = switch_core_strdup(profile->pool, val);
 					} else if (!strcasecmp(var, "context")) {
 						profile->context = switch_core_strdup(profile->pool, val);
+					} else if (!strcasecmp(var, "apply-nat-acl")) {
+						if (profile->acl_count < SOFIA_MAX_ACL) {
+							profile->nat_acl[profile->nat_acl_count++] = switch_core_strdup(profile->pool, val);
+						} else {
+							switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SOFIA_MAX_ACL);
+						}
 					} else if (!strcasecmp(var, "apply-inbound-acl")) {
 						if (profile->acl_count < SOFIA_MAX_ACL) {
 							profile->acl[profile->acl_count++] = switch_core_strdup(profile->pool, val);
@@ -1529,6 +1535,9 @@
 	if (gateway) {
 		if (status == 200 || status == 404) {
 			//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "ping success %s\n", gateway->name);
+			if (gateway->state == REG_STATE_FAILED) {
+				gateway->state = REG_STATE_UNREGED;
+			}
 			gateway->status = SOFIA_GATEWAY_UP;
 		} else {
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "ping failed %s\n", gateway->name);
@@ -2637,7 +2646,7 @@
 	uint32_t sess_max = switch_core_session_limit(0);
 	int is_auth = 0, calling_myself = 0;
 	su_addrinfo_t *my_addrinfo = msg_addrinfo(nua_current_request(nua));
-	
+	int network_port = 0;
 
 	if (sess_count >= sess_max || !(profile->pflags & PFLAG_RUNNING)) {
 		nua_respond(nh, 503, "Maximum Calls In Progress", SIPTAG_RETRY_AFTER_STR("300"), TAG_END());
@@ -2652,6 +2661,7 @@
 
 	
 	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);
 
 	if (profile->acl_count) {
 		uint32_t x = 0;
@@ -2679,8 +2689,7 @@
 
 
 	if ((profile->pflags & PFLAG_AUTH_CALLS) || (!(profile->pflags & PFLAG_BLIND_AUTH) && (sip->sip_proxy_authorization || sip->sip_authorization))) {
-		int rport = ntohs(((struct sockaddr_in *) msg_addrinfo(nua_current_request(nua))->ai_addr)->sin_port);
-		if (!strcmp(network_ip, profile->sipip) && rport == profile->sip_port) {
+		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)) {
@@ -2714,6 +2723,16 @@
 	}
 	switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
 
+	tech_pvt->remote_ip = switch_core_session_strdup(session, network_ip);
+	tech_pvt->remote_port = network_port;
+
+	if (sip->sip_contact && sip->sip_contact->m_url) {
+		tech_pvt->record_route = switch_core_session_sprintf(session, "sip:%s@%s:%d", 
+															 sip->sip_contact->m_url->url_user, 
+															 tech_pvt->remote_ip,
+															 tech_pvt->remote_port);
+	}
+
 	if (*key != '\0') {
 		tech_pvt->key = switch_core_session_strdup(session, key);
 	}
@@ -3127,6 +3146,34 @@
 			switch_assert(sql);
 			sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
 		}
+
+
+		if (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 && sip->sip_contact->m_url->url_host) {
+				contact_host = sip->sip_contact->m_url->url_host;
+			}
+			if (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) {
+					switch_set_flag(tech_pvt, TFLAG_NAT);
+					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Setting NAT mode based on acl %s\n", last_acl);
+				}
+			}
+		}
+
+
+
 		
 		return;
 	}

Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c	(original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c	Tue May 13 19:22:21 2008
@@ -868,6 +868,7 @@
 	uint32_t session_timeout = 0;
 	const char *val;
 	const char *rep;
+	char *sticky;
 
 	rep = switch_channel_get_variable(channel, SOFIA_REPLACES_HEADER);
 
@@ -1001,6 +1002,17 @@
 								  TAG_END());
 
 
+		if (switch_test_flag(tech_pvt, TFLAG_NAT) ||
+			(val = switch_channel_get_variable(channel, "sip-force-contact")) || 
+			((val = switch_channel_get_variable(channel, "sip_sticky_contact")) && switch_true(val))) {
+			tech_pvt->record_route = switch_core_session_strdup(tech_pvt->session, url_str);
+			sticky = tech_pvt->record_route;
+			session_timeout = 20;
+		}
+
+
+
+
 		/* TODO: We should use the new tags for making an rpid and add profile options to turn this on/off */
 		if (switch_test_flag(caller_profile, SWITCH_CPF_HIDE_NAME)) {
 			priv = "name";
@@ -1091,6 +1103,7 @@
 		sofia_glue_tech_patch_sdp(tech_pvt);
 	}
 
+
 	nua_invite(tech_pvt->nh,
 			   NUTAG_AUTOANSWER(0),
 			   NUTAG_SESSION_TIMER(session_timeout),

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	Tue May 13 19:22:21 2008
@@ -495,7 +495,8 @@
 		authorization = sip->sip_proxy_authorization;
 	}
 
-	if (regtype == REG_REGISTER && (profile->pflags & PFLAG_BLIND_REG)) {
+	if (regtype == REG_AUTO_REGISTER || (regtype == REG_REGISTER && (profile->pflags & PFLAG_BLIND_REG))) {
+		regtype = REG_REGISTER;
 		goto reg;
 	}
 
@@ -716,19 +717,29 @@
 	switch_event_t *v_event = NULL;
 	char network_ip[80];
 	su_addrinfo_t *my_addrinfo = msg_addrinfo(nua_current_request(nua));
-	
+	sofia_regtype_t type = REG_REGISTER;
+
 	if (profile->reg_acl_count) {
 		uint32_t x = 0;
+		int ok = 1;
+		char *last_acl = NULL;
 
 		get_addr(network_ip, sizeof(network_ip), &((struct sockaddr_in *) my_addrinfo->ai_addr)->sin_addr);
-		
+
 		for (x = 0 ; x < profile->reg_acl_count; x++) {
-			if (!switch_check_network_list_ip(network_ip, profile->reg_acl[x])) {
-				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "IP %s Rejected by acl %s\n", network_ip,  profile->reg_acl[x]);
-				nua_respond(nh, SIP_403_FORBIDDEN, NUTAG_WITH_THIS(nua), TAG_END());
-				goto end;
+			last_acl = profile->reg_acl[x];
+			if (!(ok = switch_check_network_list_ip(network_ip, last_acl))) {
+				break;
 			}
 		}
+		
+		if (ok && !(profile->pflags & PFLAG_BLIND_REG)) {
+			type = REG_AUTO_REGISTER;
+		} else if (!ok) {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "IP %s Rejected by acl %s\n", network_ip,  profile->reg_acl[x]);
+			nua_respond(nh, SIP_403_FORBIDDEN, NUTAG_WITH_THIS(nua), TAG_END());
+			goto end;
+		}
 	}
 
 
@@ -749,7 +760,7 @@
 		goto end;
 	}
 
-	sofia_reg_handle_register(nua, profile, nh, sip, REG_REGISTER, key, sizeof(key), &v_event);
+	sofia_reg_handle_register(nua, profile, nh, sip, type, key, sizeof(key), &v_event);
 
 	if (v_event) {
 		switch_event_fire(&v_event);



More information about the Freeswitch-svn mailing list