[asterisk-commits] rizzo: branch rizzo/astobj2 r75526 - /team/rizzo/astobj2/channels/chan_sip.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Jul 18 01:36:24 CDT 2007


Author: rizzo
Date: Wed Jul 18 01:36:23 2007
New Revision: 75526

URL: http://svn.digium.com/view/asterisk?view=rev&rev=75526
Log:
initial cleanup for better support of natted sessions
(this and subsequent changes are also strong trunk candidates):

- remove the 'ourport' variable, the same information is in bindaddr.sin_port

- change the 'ourip' field in a sip_pvt to a sockaddr_in, so it has
  room to store a port number as well. Use it to store the externally
  visible address/port for the SIP messages (computed using any
  applicable technique, e.g. stun or "externip" or whatever);

The above reveals a lot of duplicate sections of code around
the call to ast_sip_ouraddrfor(), and also a mixed usage of 'ourip'
as the address for media sessions as well.

Remaining changes (yet to make) will need to:
- re-engineer sip_ouraddrfor() to remove the duplications;
- separate the field used to store media addresses from the
  one used for SIP addresses.
- bring in proper stun support for the various sessions.


Modified:
    team/rizzo/astobj2/channels/chan_sip.c

Modified: team/rizzo/astobj2/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/rizzo/astobj2/channels/chan_sip.c?view=diff&rev=75526&r1=75525&r2=75526
==============================================================================
--- team/rizzo/astobj2/channels/chan_sip.c (original)
+++ team/rizzo/astobj2/channels/chan_sip.c Wed Jul 18 01:36:23 2007
@@ -1032,7 +1032,7 @@
 	time_t lastrtptx;			/*!< Last RTP sent */
 	int rtptimeout;				/*!< RTP timeout time */
 	struct sockaddr_in recv;		/*!< Received as */
-	struct in_addr ourip;			/*!< Our IP */
+	struct sockaddr_in ourip;		/*!< Our IP (as seen from the outside) */
 	struct ast_channel *owner;		/*!< Who owns us (if we have an owner) */
 	struct sip_route *route;		/*!< Head of linked list of routing steps (fm Record-Route) */
 	int route_persistant;			/*!< Is this the "real" route? */
@@ -1404,7 +1404,6 @@
 static struct ast_ha *localaddr;
 
 static struct in_addr __ourip;
-static int ourport;
 static struct sockaddr_in debugaddr;
 
 static struct ast_config *notify_types;		/*!< The list of manual NOTIFY types we know how to send */
@@ -2175,7 +2174,8 @@
 
 	/* z9hG4bK is a magic cookie.  See RFC 3261 section 8.1.1.7 */
 	ast_string_field_build(p, via, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x%s",
-			 ast_inet_ntoa(p->ourip), ourport, p->branch, rport);
+			ast_inet_ntoa(p->ourip.sin_addr),
+			ntohs(bindaddr.sin_port), p->branch, rport);
 }
 
 /*! \brief NAT fix - decide which IP address to use for ASterisk server?
@@ -4837,7 +4837,7 @@
 {
 	char buf[33];
 
-	const char *host = S_OR(pvt->fromdomain, ast_inet_ntoa(pvt->ourip));
+	const char *host = S_OR(pvt->fromdomain, ast_inet_ntoa(pvt->ourip.sin_addr));
 	
 	ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host);
 
@@ -4913,12 +4913,13 @@
 	if (intended_method != SIP_OPTIONS)	/* Peerpoke has it's own system */
 		p->timer_t1 = SIP_TIMER_T1;	/* Default SIP retransmission timer T1 (RFC 3261) */
 
+	p->ourip.sin_port = bindaddr.sin_port; /* XXX later, update with stun or similar */
 	if (sin) {
 		p->sa = *sin;
-		if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
-			p->ourip = __ourip;
+		if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip.sin_addr))
+			p->ourip.sin_addr = __ourip;
 	} else
-		p->ourip = __ourip;
+		p->ourip.sin_addr = __ourip;
 
 	/* Copy global flags to this PVT at setup. */
 	ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
@@ -6623,12 +6624,13 @@
 	/* Initialize the bare minimum */
 	p->method = intended_method;
 
+	p->ourip.sin_port = bindaddr.sin_port;
 	if (sin) {
 		p->sa = *sin;
-		if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
-			p->ourip = __ourip;
+		if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip.sin_addr))
+			p->ourip.sin_addr = __ourip;
 	} else
-		p->ourip = __ourip;
+		p->ourip.sin_addr = __ourip;
 
 	p->branch = ast_random();
 	make_our_tag(p->tag, sizeof(p->tag));
@@ -6927,12 +6929,12 @@
 		udptldest.sin_port = p->udptlredirip.sin_port;
 		udptldest.sin_addr = p->udptlredirip.sin_addr;
 	} else {
-		udptldest.sin_addr = p->ourip;
-		udptldest.sin_port = udptlsin.sin_port;
+		udptldest.sin_addr = p->ourip.sin_addr;
+		udptldest.sin_port = udptlsin.sin_port;	/* XXX are we sure ? */
 	}
 	
-	if (debug) 
-		ast_log(LOG_DEBUG, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(udptlsin.sin_port));
+	if (debug)  /* XXX is the message correct ? */
+		ast_log(LOG_DEBUG, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip.sin_addr), ntohs(udptlsin.sin_port));
 	
 	/* We break with the "recommendation" and send our IP, in order that our
 	   peer doesn't have to ast_gethostbyname() us */
@@ -7018,7 +7020,8 @@
 		dest->sin_port = p->redirip.sin_port;
 		dest->sin_addr = p->redirip.sin_addr;
 	} else {
-		dest->sin_addr = p->ourip;
+		/* XXX need to handle NAT */
+		dest->sin_addr = p->ourip.sin_addr;
 		dest->sin_port = sin->sin_port;
 	}
 	if (needvideo) {
@@ -7027,7 +7030,8 @@
 			vdest->sin_addr = p->vredirip.sin_addr;
 			vdest->sin_port = p->vredirip.sin_port;
 		} else {
-			vdest->sin_addr = p->ourip;
+			/* XXX need to handle NAT */
+			vdest->sin_addr = p->ourip.sin_addr;
 			vdest->sin_port = vsin->sin_port;
 		}
 	}
@@ -7117,7 +7121,7 @@
 	get_our_media_address(p, needvideo, &sin, &vsin, &tsin, &dest, &vdest);
 
 	if (debug)
-		ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(sin.sin_port));
+		ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip.sin_addr), ntohs(sin.sin_port));
 		
 	/* Ok, we need video. Let's add what we need for video and set codecs.
 	   Video is handled differently than audio since we can not transcode. */
@@ -7128,7 +7132,7 @@
 		if (p->maxcallbitrate)
 			snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate);
 		if (debug) 
-			ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(vsin.sin_port));	
+			ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip.sin_addr), ntohs(vsin.sin_port));	
 	}
         /* Check if we need text in this call */
 	if((capability & AST_FORMAT_TEXT_MASK) && !ast_test_flag(&p->flags[1], SIP_PAGE2_NOTEXT)) {
@@ -7154,13 +7158,13 @@
 			tdest.sin_addr = p->tredirip.sin_addr;
 			tdest.sin_port = p->tredirip.sin_port;
 		} else {
-			tdest.sin_addr = p->ourip;
+			tdest.sin_addr = p->ourip.sin_addr;
 			tdest.sin_port = tsin.sin_port;
 		}
 		ast_str_append(&m_text, 0, "m=text %d RTP/AVP", ntohs(tdest.sin_port));
 
 		if (debug) 
-			ast_verbose("Text is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(tsin.sin_port));
+			ast_verbose("Text is at %s port %d\n", ast_inet_ntoa(p->ourip.sin_addr), ntohs(tsin.sin_port));
 	}
 
 	/* Start building generic SDP headers */
@@ -7480,11 +7484,11 @@
 	/* Construct Contact: header */
 	char port[16];
 	port[0] = '\0';
-	if (ourport != STANDARD_SIP_PORT)
-		snprintf(port, sizeof(port), ":%6d", ourport);
+	if (ntohs(p->ourip.sin_port) != STANDARD_SIP_PORT)
+		snprintf(port, sizeof(port), ":%6d", ntohs(p->ourip.sin_port));
 	ast_string_field_build(p, our_contact, "<sip:%s%s%s%s>",
 		p->exten, ast_strlen_zero(p->exten) ? "" : "@",
-		ast_inet_ntoa(p->ourip), port);
+		ast_inet_ntoa(p->ourip.sin_addr), port);
 }
 
 /*! \brief Build the Remote Party-ID & From using callingpres options */
@@ -7554,7 +7558,7 @@
 		break;
 	}
 	
-	fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip));
+	fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip.sin_addr));
 
 	snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain);
 	if (send_pres_tags)
@@ -7633,10 +7637,10 @@
 		l = tmp_l;
 	}
 
-	if (ourport != STANDARD_SIP_PORT && ast_strlen_zero(p->fromdomain))
-		snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), ourport, p->tag);
+	if (ntohs(p->ourip.sin_port) != STANDARD_SIP_PORT && ast_strlen_zero(p->fromdomain))
+		snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip.sin_addr)), ntohs(p->ourip.sin_port), p->tag);
 	else
-		snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), p->tag);
+		snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip.sin_addr)), p->tag);
 
 	/* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */
 	if (!ast_strlen_zero(p->fullcontact)) {
@@ -7985,7 +7989,7 @@
 
 	ast_str_append(&out, 0, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no");
 	ast_str_append(&out, 0, "Message-Account: sip:%s@%s\r\n",
-		S_OR(vmexten, default_vmexten), S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)));
+		S_OR(vmexten, default_vmexten), S_OR(p->fromdomain, ast_inet_ntoa(p->ourip.sin_addr)));
         /* Cisco has a bug in the SIP stack where it can't accept the
 	 (0/0) notification. This can temporarily be disabled in
 	 sip.conf with the "buggymwi" option */
@@ -8226,8 +8230,9 @@
 		  based on whether the remote host is on the external or
 		  internal network so we can register through nat
 		 */
-		if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
-			p->ourip = bindaddr.sin_addr;
+		p->ourip.sin_port = bindaddr.sin_port; /* XXX nat... */
+		if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip.sin_addr))
+			p->ourip.sin_addr = bindaddr.sin_addr;
 		build_contact(p);
 	}
 
@@ -11887,7 +11892,7 @@
 	ast_cli(fd, "  Received Address:       %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port));
 	ast_cli(fd, "  SIP Transfer mode:      %s\n", transfermode2str(cur->allowtransfer));
 	ast_cli(fd, "  NAT Support:            %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT)));
-	ast_cli(fd, "  Audio IP:               %s %s\n", ast_inet_ntoa(cur->redirip.sin_addr.s_addr ? cur->redirip.sin_addr : cur->ourip), cur->redirip.sin_addr.s_addr ? "(Outside bridge)" : "(local)" );
+	ast_cli(fd, "  Audio IP:               %s %s\n", ast_inet_ntoa(cur->redirip.sin_addr.s_addr ? cur->redirip.sin_addr : cur->ourip.sin_addr), cur->redirip.sin_addr.s_addr ? "(Outside bridge)" : "(local)" );
 	ast_cli(fd, "  Our Tag:                %s\n", cur->tag);
 	ast_cli(fd, "  Their Tag:              %s\n", cur->theirtag);
 	ast_cli(fd, "  SIP User agent:         %s\n", cur->useragent);
@@ -12321,8 +12326,9 @@
 			add_header(&req, var->name, var->value);
 
 		/* Recalculate our side, and recalculate Call ID */
-		if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
-			p->ourip = __ourip;
+		p->ourip.sin_port = bindaddr.sin_port; /* XXX nat */
+		if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip.sin_addr))
+			p->ourip.sin_addr = __ourip;
 		build_via(p);
 		build_callid_pvt(p);
 		ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]);
@@ -16458,8 +16464,9 @@
 			return 0;
 		}
 		/* Recalculate our side, and recalculate Call ID */
-		if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
-			p->ourip = __ourip;
+		p->ourip.sin_port = bindaddr.sin_port;
+		if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip.sin_addr))
+			p->ourip.sin_addr = __ourip;
 		build_via(p);
 		build_callid_pvt(p);
 		/* Destroy this session after 32 secs */
@@ -16720,8 +16727,9 @@
 		ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr));
 
 	/* Recalculate our side, and recalculate Call ID */
-	if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
-		p->ourip = __ourip;
+	p->ourip.sin_port = bindaddr.sin_port;
+	if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip.sin_addr))
+		p->ourip.sin_addr = __ourip;
 	build_via(p);
 	build_callid_pvt(p);
 
@@ -16896,8 +16904,9 @@
 	if (ast_strlen_zero(p->peername) && ext)
 		ast_string_field_set(p, peername, ext);
 	/* Recalculate our side, and recalculate Call ID */
-	if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
-		p->ourip = __ourip;
+	p->ourip.sin_port = bindaddr.sin_port;
+	if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip.sin_addr))
+		p->ourip.sin_addr = __ourip;
 	build_via(p);
 	build_callid_pvt(p);
 	
@@ -17716,7 +17725,7 @@
 	memset(&global_outboundproxy, 0, sizeof(struct sip_proxy));
 	global_outboundproxy.ip.sin_port = htons(STANDARD_SIP_PORT);
 	global_outboundproxy.ip.sin_family = AF_INET;   /* Type of address: IPv4 */
-	ourport = STANDARD_SIP_PORT;
+	bindaddr.sin_port = htons(STANDARD_SIP_PORT);
 	global_srvlookup = DEFAULT_SRVLOOKUP;
 	global_tos_sip = DEFAULT_TOS_SIP;
 	global_tos_audio = DEFAULT_TOS_AUDIO;
@@ -17948,8 +17957,9 @@
 		M_F("cos_video", ast_str2cos(v->value, &global_cos_video))
 		M_F("cos_text", ast_str2cos(v->value, &global_cos_text))
 		M_F("bindport", {
-			if (sscanf(v->value, "%d", &ourport) == 1) {
-				bindaddr.sin_port = htons(ourport);
+			int i;
+			if (sscanf(v->value, "%d", &i) == 1) {
+				bindaddr.sin_port = htons(i);
 			} else {
 				ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config);
 			} } )
@@ -18202,12 +18212,12 @@
 	if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
 		if (!p->pendinginvite) {
 			if (option_debug > 2) {
-				ast_log(LOG_DEBUG, "Sending reinvite on SIP '%s' - It's UDPTL soon redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(udptl ? p->udptlredirip.sin_addr : p->ourip), udptl ? ntohs(p->udptlredirip.sin_port) : 0);
+				ast_log(LOG_DEBUG, "Sending reinvite on SIP '%s' - It's UDPTL soon redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(udptl ? p->udptlredirip.sin_addr : p->ourip.sin_addr), udptl ? ntohs(p->udptlredirip.sin_port) : 0);
 			}
 			transmit_reinvite_with_sdp(p, TRUE);
 		} else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
 			if (option_debug > 2) {
-				ast_log(LOG_DEBUG, "Deferring reinvite on SIP '%s' - It's UDPTL will be redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(udptl ? p->udptlredirip.sin_addr : p->ourip), udptl ? ntohs(p->udptlredirip.sin_port) : 0);
+				ast_log(LOG_DEBUG, "Deferring reinvite on SIP '%s' - It's UDPTL will be redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(udptl ? p->udptlredirip.sin_addr : p->ourip.sin_addr), udptl ? ntohs(p->udptlredirip.sin_port) : 0);
 			}
 			ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
 		}
@@ -18259,7 +18269,7 @@
 					if (flag)
 						ast_log(LOG_DEBUG, "Sending reinvite on SIP '%s' - It's UDPTL soon redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(p->udptlredirip.sin_addr), ntohs(p->udptlredirip.sin_port));
 					else
-						ast_log(LOG_DEBUG, "Sending reinvite on SIP '%s' - It's UDPTL soon redirected to us (IP %s)\n", p->callid, ast_inet_ntoa(p->ourip));
+						ast_log(LOG_DEBUG, "Sending reinvite on SIP '%s' - It's UDPTL soon redirected to us (IP %s)\n", p->callid, ast_inet_ntoa(p->ourip.sin_addr));
 				}
 				transmit_reinvite_with_sdp(p, TRUE);
 			} else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
@@ -18267,7 +18277,7 @@
 					if (flag)
 						ast_log(LOG_DEBUG, "Deferring reinvite on SIP '%s' - It's UDPTL will be redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(p->udptlredirip.sin_addr), ntohs(p->udptlredirip.sin_port));
 					else
-						ast_log(LOG_DEBUG, "Deferring reinvite on SIP '%s' - It's UDPTL will be redirected to us (IP %s)\n", p->callid, ast_inet_ntoa(p->ourip));
+						ast_log(LOG_DEBUG, "Deferring reinvite on SIP '%s' - It's UDPTL will be redirected to us (IP %s)\n", p->callid, ast_inet_ntoa(p->ourip.sin_addr));
 				}
 				ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
 			}
@@ -18283,7 +18293,7 @@
 			if (flag)
 				ast_log(LOG_DEBUG, "Responding 200 OK on SIP '%s' - It's UDPTL soon redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(p->udptlredirip.sin_addr), ntohs(p->udptlredirip.sin_port));
 			else
-				ast_log(LOG_DEBUG, "Responding 200 OK on SIP '%s' - It's UDPTL soon redirected to us (IP %s)\n", p->callid, ast_inet_ntoa(p->ourip));
+				ast_log(LOG_DEBUG, "Responding 200 OK on SIP '%s' - It's UDPTL soon redirected to us (IP %s)\n", p->callid, ast_inet_ntoa(p->ourip.sin_addr));
 		}
 		pvt->t38.state = T38_ENABLED;
 		p->t38.state = T38_ENABLED;
@@ -18430,15 +18440,15 @@
 		if (chan->_state != AST_STATE_UP) {	/* We are in early state */
 			append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal.");
 			if (option_debug)
-				ast_log(LOG_DEBUG, "Early remote bridge setting SIP '%s' - Sending media to %s\n", p->callid, ast_inet_ntoa(rtp ? p->redirip.sin_addr : p->ourip));
+				ast_log(LOG_DEBUG, "Early remote bridge setting SIP '%s' - Sending media to %s\n", p->callid, ast_inet_ntoa(rtp ? p->redirip.sin_addr : p->ourip.sin_addr));
 		} else if (!p->pendinginvite) {		/* We are up, and have no outstanding invite */
 			if (option_debug > 2) {
-				ast_log(LOG_DEBUG, "Sending reinvite on SIP '%s' - It's audio soon redirected to IP %s\n", p->callid, ast_inet_ntoa(rtp ? p->redirip.sin_addr : p->ourip));
+				ast_log(LOG_DEBUG, "Sending reinvite on SIP '%s' - It's audio soon redirected to IP %s\n", p->callid, ast_inet_ntoa(rtp ? p->redirip.sin_addr : p->ourip.sin_addr));
 			}
 			transmit_reinvite_with_sdp(p, FALSE);
 		} else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
 			if (option_debug > 2) {
-				ast_log(LOG_DEBUG, "Deferring reinvite on SIP '%s' - It's audio will be redirected to IP %s\n", p->callid, ast_inet_ntoa(rtp ? p->redirip.sin_addr : p->ourip));
+				ast_log(LOG_DEBUG, "Deferring reinvite on SIP '%s' - It's audio will be redirected to IP %s\n", p->callid, ast_inet_ntoa(rtp ? p->redirip.sin_addr : p->ourip.sin_addr));
 			}
 			/* We have a pending Invite. Send re-invite when we're done with the invite */
 			ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);	




More information about the asterisk-commits mailing list