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

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Sat Jun 30 15:37:08 CDT 2007


Author: rizzo
Date: Sat Jun 30 15:37:08 2007
New Revision: 72798

URL: http://svn.digium.com/view/asterisk?view=rev&rev=72798
Log:
blind merge from trunk up to rev 59083


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=72798&r1=72797&r2=72798
==============================================================================
--- team/rizzo/astobj2/channels/chan_sip.c (original)
+++ team/rizzo/astobj2/channels/chan_sip.c Sat Jun 30 15:37:08 2007
@@ -568,6 +568,8 @@
 static int global_autoframing;          /*!< Turn autoframing on or off. */
 static enum transfermodes global_allowtransfer;	/*!< SIP Refer restriction scheme */
 static struct sip_proxy global_outboundproxy;   /*!< Outbound proxy */
+
+static int global_matchexterniplocally;	/*!< Match externip/externhost setting against localnet setting */
 
 /*! \brief Codecs that we support by default: */
 static int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263;
@@ -2170,7 +2172,7 @@
 
 	if (localaddr && externip.sin_addr.s_addr &&
 	    ast_apply_ha(localaddr, &theirs) &&
-	    !ast_apply_ha(localaddr, &ours)) {
+	    (!global_matchexterniplocally || !ast_apply_ha(localaddr, &ours))) {
 		if (externexpire && time(NULL) >= externexpire) {
 			struct ast_hostent ahp;
 			struct hostent *hp;
@@ -5472,7 +5474,7 @@
 	int codec;
 	int destiterator = 0;
 	int iterator;
-	int sendonly = 0;
+	int sendonly = -1;
 	int numberofports;
 	struct ast_rtp *newaudiortp, *newvideortp, *newtextrtp; /* Buffers for codec handling */
 	int newjointcapability;				/* Negotiated capability */
@@ -5629,14 +5631,20 @@
 			} else {
 				/* XXX This could block for a long time, and block the main thread! XXX */
 				if (audio) {
-					if ( !(hp = ast_gethostbyname(host, &audiohp)))
+					if ( !(hp = ast_gethostbyname(host, &audiohp))) {
 						ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in secondary c= line, '%s'\n", c);
+						return -2;
+					}
 				} else if (video) {
-					if (!(vhp = ast_gethostbyname(host, &videohp)))
+					if (!(vhp = ast_gethostbyname(host, &videohp))) {
 						ast_log(LOG_WARNING, "Unable to lookup RTP video host in secondary c= line, '%s'\n", c);
+						return -2;
+					}
 				} else if (text) {
-					if (!(thp = ast_gethostbyname(host, &texthp)))
+					if (!(thp = ast_gethostbyname(host, &texthp))) {
 						ast_log(LOG_WARNING, "Unable to lookup RTP text host in secondary c= line, '%s'\n", c);
+						return -2;
+					}
 				}
 			}
 
@@ -5744,13 +5752,16 @@
 				continue;
 		}
 		if (!strcasecmp(a, "sendonly")) {
-			sendonly = 1;
+			if (sendonly == -1)
+				sendonly = 1;
 			continue;
 		} else if (!strcasecmp(a, "inactive")) {
-			sendonly = 2;
+			if (sendonly == -1)
+				sendonly = 2;
 			continue;
 		}  else if (!strcasecmp(a, "sendrecv")) {
-			sendonly = 0;
+			if (sendonly == -1)
+				sendonly = 0;
 			continue;
 		} else if (strlen(a) > 5 && !strncasecmp(a, "ptime", 5)) {
 			char *tmp = strrchr(a, ':');
@@ -6024,39 +6035,32 @@
 		ast_set_write_format(p->owner, p->owner->writeformat);
 	}
 	
-		if (sin.sin_addr.s_addr && !sendonly) {
-			ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
-			/* Activate a re-invite */
-			ast_queue_frame(p->owner, &ast_null_frame);
-		} else if (!sin.sin_addr.s_addr || sendonly) {
-			ast_queue_control_data(p->owner, AST_CONTROL_HOLD, 
+	if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) {
+		ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
+		/* Activate a re-invite */
+		ast_queue_frame(p->owner, &ast_null_frame);
+		/* Queue Manager Unhold event */
+		append_history(p, "Unhold", "%s", req->data);
+		if (global_callevents)
+			manager_event(EVENT_FLAG_CALL, "Unhold",
+				      "Channel: %s\r\n"
+				      "Uniqueid: %s\r\n",
+				      p->owner->name,
+				      p->owner->uniqueid);
+		if (global_notifyhold)
+			sip_peer_hold(p, FALSE);
+		ast_clear_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */
+	} else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) {
+		ast_queue_control_data(p->owner, AST_CONTROL_HOLD, 
 					       S_OR(p->mohsuggest, NULL),
 					       !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
-			if (sendonly)
-				ast_rtp_stop(p->rtp);
-			/* RTCP needs to go ahead, even if we're on hold!!! */
-			/* Activate a re-invite */
-			ast_queue_frame(p->owner, &ast_null_frame);
-		}
-
-	/* Manager Hold and Unhold events must be generated, if necessary */
-	if (sin.sin_addr.s_addr && !sendonly) {
-		if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
-			append_history(p, "Unhold", "%s", req->data);
-			if (global_callevents)
-				manager_event(EVENT_FLAG_CALL, "Unhold",
-					"Channel: %s\r\n"
-					"Uniqueid: %s\r\n",
-					p->owner->name, 
-					p->owner->uniqueid);
-			if (global_notifyhold)
-				sip_peer_hold(p, FALSE);
-		} 
-		ast_clear_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD);	/* Clear both flags */
-	} else if (!sin.sin_addr.s_addr || sendonly ) {
-		/* No address for RTP, we're on hold */
+		if (sendonly)
+			ast_rtp_stop(p->rtp);
+		/* RTCP needs to go ahead, even if we're on hold!!! */
+		/* Activate a re-invite */
+		ast_queue_frame(p->owner, &ast_null_frame);
+		/* Queue Manager Hold event */
 		append_history(p, "Hold", "%s", req->data);
-
 		if (global_callevents && !ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
 			manager_event(EVENT_FLAG_CALL, "Hold",
 				"Channel: %s\r\n"
@@ -8172,7 +8176,18 @@
 	
 	/* Fromdomain is what we are registering to, regardless of actual
 	   host name from SRV */
-	snprintf(addr, sizeof(addr), "sip:%s", S_OR(p->fromdomain, r->hostname));
+	if (!ast_strlen_zero(p->fromdomain)) {
+		if (r->portno && r->portno != STANDARD_SIP_PORT)
+			snprintf(addr, sizeof(addr), "sip:%s:%d", p->fromdomain, r->portno);
+		else
+			snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain);
+	} else {
+		if (r->portno && r->portno != STANDARD_SIP_PORT)
+			snprintf(addr, sizeof(addr), "sip:%s:%d", r->hostname, r->portno);
+		else
+			snprintf(addr, sizeof(addr), "sip:%s", r->hostname);
+	}
+
 	ast_string_field_set(p, uri, addr);
 
 	p->branch ^= ast_random();
@@ -10239,6 +10254,10 @@
 	}
 	{
 		char *tmp = ast_strdupa(of);
+		/* We need to be able to handle auth-headers looking like
+			<sip:8164444422;phone-context=+1 at 1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43>
+		*/
+		tmp = strsep(&tmp, ";");
 		if (ast_is_shrinkable_phonenumber(tmp))
 			ast_shrink_phone_number(tmp);
 		ast_string_field_set(p, cid_num, tmp);
@@ -13378,9 +13397,10 @@
 
 		case 200:	/* 200 OK */
 			p->authtries = 0;	/* Reset authentication counter */
-			if (sipmethod == SIP_MESSAGE) {
-				/* We successfully transmitted a message */
-				set_destroy(p);
+			if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) {
+				/* We successfully transmitted a message 
+					or a video update request in INFO */
+				/* Nothing happens here - the message is inside a dialog */
 			} else if (sipmethod == SIP_INVITE) {
 				handle_response_invite(p, resp, rest, req, seqno);
 			} else if (sipmethod == SIP_NOTIFY) {
@@ -13517,7 +13537,8 @@
 				if ((option_verbose > 2) && (resp != 487))
 					ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr));
 	
-				stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
+				if (sipmethod == SIP_INVITE)
+					stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
 
 				/* XXX Locking issues?? XXX */
 				switch(resp) {
@@ -13561,14 +13582,15 @@
 					break;
 				default:
 					/* Send hangup */	
-					if (owner)
+					if (owner && sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO)
 						ast_queue_hangup(p->owner);
 					break;
 				}
 				/* ACK on invite */
 				if (sipmethod == SIP_INVITE) 
 					transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
-				sip_alreadygone(p);
+				if (sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO)
+					sip_alreadygone(p);
 				if (!p->owner)
 					set_destroy(p);
 			} else if ((resp >= 100) && (resp < 200)) {
@@ -13624,10 +13646,10 @@
 				}
 			} else if (sipmethod == SIP_BYE)
 				set_destroy(p);
-			else if (sipmethod == SIP_MESSAGE)
-				/* We successfully transmitted a message */
-				/* XXX Why destroy this pvt after message transfer? Bad */
-				set_destroy(p);
+			else if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO)
+				/* We successfully transmitted a message or
+					a video update request in INFO */
+				;
 			else if (sipmethod == SIP_BYE) 
 				/* Ok, we're ready to go */
 				set_destroy(p);
@@ -15526,9 +15548,25 @@
 			p->subscribed = CPIM_PIDF_XML;    /* RFC 3863 format */
 		} else if (strstr(accept, "application/xpidf+xml")) {
 			p->subscribed = XPIDF_XML;        /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */
+		} else if (ast_strlen_zero(accept)) {
+			if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */
+				transmit_response(p, "489 Bad Event", req);
+
+				ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n",
+					p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri);
+				ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);	
+				return 0;
+			}
+			/* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least.
+			   so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */
+
 		} else {
 			/* Can't find a format for events that we know about */
-			transmit_response(p, "489 Bad Event", req);
+			char mybuf[200];
+			snprintf(mybuf,sizeof(mybuf),"489 Bad Event (format %s)", accept);
+			transmit_response(p, mybuf, req);
+			ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format: '%s' pvt: subscribed: %d, stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n",
+				accept, (int)p->subscribed, p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri);
 			set_destroy(p);
 			return 0;
 		}
@@ -15789,6 +15827,10 @@
 		if (sscanf(e, "%d %n", &respid, &len) != 1) {
 			ast_log(LOG_WARNING, "Invalid response: '%s'\n", e);
 		} else {
+			if (respid <= 0) {
+				ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid);
+				return 0;
+			}
 			/* More SIP ridiculousness, we have to ignore bogus contacts in 100 etc responses */
 			if ((respid == 200) || ((respid >= 300) && (respid <= 399)))
 				extract_uri(p, req);
@@ -15861,7 +15903,7 @@
 	}
 
 	if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY)) {
-		transmit_response(p, "503 Server error", req);
+		transmit_response(p, "400 Bad request", req);
 		sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
 		return -1;
 	}
@@ -17485,6 +17527,8 @@
 	global_callevents = FALSE;
 	global_t1min = DEFAULT_T1MIN;		
 
+	global_matchexterniplocally = FALSE;
+
 	/* Copy the default jb config over global_jbconf */
 	memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
 
@@ -17527,6 +17571,7 @@
 		M_INT_GE0("rtpkeepalive", global_rtpkeepalive, 0)
 		M_BOOL("compactheaders", compactheaders)
 		M_STR("notifymimetype", default_notifymime)
+		M_BOOL("limitonpeer", global_limitonpeers)	/* accept a missing trailing 's' */
 		M_BOOL("limitonpeers", global_limitonpeers)
 		M_BOOL("directrtpsetup", global_directrtpsetup)
 		M_BOOL("notifyringing", global_notifyringing)
@@ -17656,6 +17701,7 @@
 			} } )
 		M_BOOL("callevents", global_callevents)
 		M_INT_GE0("maxcallbitrate", default_maxcallbitrate, DEFAULT_MAX_CALL_BITRATE)
+		M_BOOL("matchexterniplocally", global_matchexterniplocally)
 		M_END(ast_log(LOG_NOTICE, "sip.conf [general]: unknown option %s = %s\n",
 			v->name, v->value); )
 	}
@@ -18301,7 +18347,7 @@
 static int sip_get_codec(struct ast_channel *chan)
 {
 	struct sip_pvt *p = chan->tech_pvt;
-	return p->peercapability;	
+	return p->peercapability ? p->peercapability : p->capability;
 }
 
 /*! \brief Send a poke to all known peers 




More information about the asterisk-commits mailing list