[asterisk-commits] mmichelson: branch 13 r431424 - in /branches/13: ./ channels/chan_sip.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Jan 29 14:44:10 CST 2015


Author: mmichelson
Date: Thu Jan 29 14:44:07 2015
New Revision: 431424

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=431424
Log:
Use SIPS URIs in Contact headers when appropriate.

RFC 3261 sections 8.1.1.8 and 12.1.1 dictate specific
scenarios when we are required to use SIPS URIs in Contact
headers. Asterisk's non-compliance with this could actually
cause calls to get dropped when communicating with clients
that are strict about checking the Contact header.

Both of the SIP stacks in Asterisk suffered from this issue.
This changeset corrects the behavior in chan_sip.

ASTERISK-24646 #close
Reported by Stephan Eisvogel

Review: https://reviewboard.asterisk.org/r/4346
........

Merged revisions 431423 from http://svn.asterisk.org/svn/asterisk/branches/11

Modified:
    branches/13/   (props changed)
    branches/13/channels/chan_sip.c

Propchange: branches/13/
------------------------------------------------------------------------------
--- branch-11-merged (original)
+++ branch-11-merged Thu Jan 29 14:44:07 2015
@@ -1,1 +1,1 @@
-/branches/11:1-429517,429539,429632,429783,429804,429825,429867,429893,429982,430009,430126,430415,430487,430506,430564,430589,430795,430798,430920,430993,430996-430997,431049,431135,431187,431218,431384
+/branches/11:1-429517,429539,429632,429783,429804,429825,429867,429893,429982,430009,430126,430415,430487,430506,430564,430589,430795,430798,430920,430993,430996-430997,431049,431135,431187,431218,431384,431423

Modified: branches/13/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/branches/13/channels/chan_sip.c?view=diff&rev=431424&r1=431423&r2=431424
==============================================================================
--- branches/13/channels/chan_sip.c (original)
+++ branches/13/channels/chan_sip.c Thu Jan 29 14:44:07 2015
@@ -1446,7 +1446,7 @@
 static void set_destination(struct sip_pvt *p, const char *uri);
 static void add_date(struct sip_request *req);
 static void add_expires(struct sip_request *req, int expires);
-static void build_contact(struct sip_pvt *p);
+static void build_contact(struct sip_pvt *p, struct sip_request *req, int incoming);
 
 /*------Request handling functions */
 static int handle_incoming(struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, int *recount, int *nounlock);
@@ -13838,22 +13838,110 @@
 	if (!ast_strlen_zero(c)) {
 		ast_string_field_set(p, uri, c);
 	}
-
-}
-
-/*! \brief Build contact header - the contact header we send out */
-static void build_contact(struct sip_pvt *p)
+}
+
+/*!
+ * \brief Determine if, as a UAS, we need to use a SIPS Contact.
+ *
+ * This uses the rules defined in RFC 3261 section 12.1.1 to
+ * determine if a SIPS URI should be used as the Contact header
+ * when responding to incoming SIP requests.
+ *
+ * \param req The incoming SIP request
+ * \retval 0 SIPS is not required
+ * \retval 1 SIPS is required
+ */
+static int uas_sips_contact(struct sip_request *req)
+{
+	const char *record_route = sip_get_header(req, "Record-Route");
+
+	if (!strncmp(REQ_OFFSET_TO_STR(req, rlpart2), "sips:", 5)) {
+		return 1;
+	}
+
+	if (record_route) {
+		char *record_route_uri = get_in_brackets(ast_strdupa(record_route));
+
+		if (!strncmp(record_route_uri, "sips:", 5)) {
+			return 1;
+		}
+	} else {
+		const char *contact = sip_get_header(req, "Contact");
+		char *contact_uri = get_in_brackets(ast_strdupa(contact));
+
+		if (!strncmp(contact_uri, "sips:", 5)) {
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+/*!
+ * \brief Determine if, as a UAC, we need to use a SIPS Contact.
+ *
+ * This uses the rules defined in RFC 3621 section 8.1.1.8 to
+ * determine if a SIPS URI should be used as the Contact header
+ * on our outgoing request.
+ *
+ * \param req The outgoing SIP request
+ * \retval 0 SIPS is not required
+ * \retval 1 SIPS is required
+ */
+static int uac_sips_contact(struct sip_request *req)
+{
+	const char *route = sip_get_header(req, "Route");
+
+	if (!strncmp(REQ_OFFSET_TO_STR(req, rlpart2), "sips:", 5)) {
+		return 1;
+	}
+
+	if (route) {
+		char *route_uri = get_in_brackets(ast_strdupa(route));
+
+		if (!strncmp(route_uri, "sips:", 5)) {
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+/*!
+ * \brief Build contact header
+ *
+ * This is the Contact header that we send out in SIP requests and responses
+ * involving this sip_pvt.
+ *
+ * The incoming parameter is used to tell if we are building the request parameter
+ * is an incoming SIP request that we are building the Contact header in response to,
+ * or if the req parameter is an outbound SIP request that we will later be adding
+ * the Contact header to.
+ *
+ * \param p The sip_pvt where the built Contact will be saved.
+ * \param req The request that triggered the creation of a Contact header.
+ * \param incoming Indicates if the Contact header is being created for a response to an incoming request
+ */
+static void build_contact(struct sip_pvt *p, struct sip_request *req, int incoming)
 {
 	char tmp[SIPBUFSIZE];
 	char *user = ast_uri_encode(p->exten, tmp, sizeof(tmp), ast_uri_sip_user);
+	int use_sips;
+
+	if (incoming) {
+		use_sips = uas_sips_contact(req);
+	} else {
+		use_sips = uac_sips_contact(req);
+	}
 
 	if (p->socket.type == AST_TRANSPORT_UDP) {
-		ast_string_field_build(p, our_contact, "<sip:%s%s%s>", user,
-			ast_strlen_zero(user) ? "" : "@", ast_sockaddr_stringify_remote(&p->ourip));
+		ast_string_field_build(p, our_contact, "<%s:%s%s%s>", use_sips ? "sips" : "sip",
+			user, ast_strlen_zero(user) ? "" : "@",
+			ast_sockaddr_stringify_remote(&p->ourip));
 	} else {
-		ast_string_field_build(p, our_contact, "<sip:%s%s%s;transport=%s>", user,
-			ast_strlen_zero(user) ? "" : "@", ast_sockaddr_stringify_remote(&p->ourip),
-			sip_get_transport(p->socket.type));
+		ast_string_field_build(p, our_contact, "<%s:%s%s%s;transport=%s>",
+			use_sips ? "sips" : "sip", user, ast_strlen_zero(user) ? "" : "@",
+			ast_sockaddr_stringify_remote(&p->ourip), sip_get_transport(p->socket.type));
 	}
 }
 
@@ -14049,7 +14137,7 @@
 	add_header(req, "From", from);
 	add_header(req, "To", to);
 	ast_string_field_set(p, exten, l);
-	build_contact(p);
+	build_contact(p, req, 0);
 	add_header(req, "Contact", p->our_contact);
 	add_header(req, "Call-ID", p->callid);
 	add_header(req, "CSeq", tmp_n);
@@ -14478,7 +14566,6 @@
 	set_socket_transport(&mwi->call->socket, mwi->transport);
 	mwi->call->socket.port = htons(mwi->portno);
 	ast_sip_ouraddrfor(&mwi->call->sa, &mwi->call->ourip, mwi->call);
-	build_contact(mwi->call);
 	build_via(mwi->call);
 
 	/* Change the dialog callid. */
@@ -15446,7 +15533,6 @@
 		  internal network so we can register through nat
 		 */
 		ast_sip_ouraddrfor(&p->sa, &p->ourip, p);
-		build_contact(p);
 	}
 
 	/* set up a timeout */
@@ -15526,6 +15612,7 @@
 	}
 
 	add_expires(&req, r->expiry);
+	build_contact(p, &req, 0);
 	add_header(&req, "Contact", p->our_contact);
 
 	initialize_initreq(p, &req);
@@ -17055,7 +17142,7 @@
 	}
 
 	ast_string_field_set(p, exten, name);
-	build_contact(p);
+	build_contact(p, req, 1);
 	if (req->ignore) {
 		/* Expires is a special case, where we only want to load the peer if this isn't a deregistration attempt */
 		const char *expires = sip_get_header(req, "Expires");
@@ -18601,8 +18688,9 @@
 		if (t)
 			*t = '\0';
 
-		if (ast_strlen_zero(p->our_contact))
-			build_contact(p);
+		if (ast_strlen_zero(p->our_contact)) {
+			build_contact(p, req, 1);
+		}
 	}
 
 	of = get_in_brackets(of);
@@ -24747,7 +24835,7 @@
 
 	/* must go through authentication before getting here */
 	gotdest = get_destination(p, req, NULL);
-	build_contact(p);
+	build_contact(p, req, 1);
 
 	if (ast_strlen_zero(p->context))
 		ast_string_field_set(p, context, sip_cfg.default_context);
@@ -25513,8 +25601,8 @@
 			goto request_invite_cleanup;
 		}
 		gotdest = get_destination(p, NULL, &cc_recall_core_id);	/* Get destination right away */
-		extract_uri(p, req);			/* Get the Contact URI */
-		build_contact(p);			/* Build our contact header */
+		extract_uri(p, req);        /* Get the Contact URI */
+		build_contact(p, req, 1);   /* Build our contact header */
 
 		if (p->rtp) {
 			ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
@@ -27422,7 +27510,7 @@
 
 	/* Get full contact header - this needs to be used as a request URI in NOTIFY's */
 	parse_ok_contact(p, req);
-	build_contact(p);
+	build_contact(p, req, 1);
 
 	/* Initialize tag for new subscriptions */
 	if (ast_strlen_zero(p->tag)) {




More information about the asterisk-commits mailing list