[svn-commits] twilson: branch group/srtp_reboot r254404 - in /team/group/srtp_reboot/channe...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Wed Mar 24 21:15:59 CDT 2010


Author: twilson
Date: Wed Mar 24 21:15:54 2010
New Revision: 254404

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=254404
Log:
First attempt at adding multi-session support for SRTP

Testing was done to make sure that a normal SRTP call would go through, but
I don't have any video phones that support SRTP that don't crash, so nopromises
yet that this completely works.

Modified:
    team/group/srtp_reboot/channels/chan_sip.c
    team/group/srtp_reboot/channels/sip/include/sip.h

Modified: team/group/srtp_reboot/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/group/srtp_reboot/channels/chan_sip.c?view=diff&rev=254404&r1=254403&r2=254404
==============================================================================
--- team/group/srtp_reboot/channels/chan_sip.c (original)
+++ team/group/srtp_reboot/channels/chan_sip.c Wed Mar 24 21:15:54 2010
@@ -1308,8 +1308,8 @@
 static void handle_response(struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno);
 
 /*------ SRTP Support -------- */
-static int setup_srtp(struct sip_pvt *p);
-static int process_crypto(struct sip_pvt *p, const char *a);
+static int setup_srtp(struct sip_srtp **srtp);
+static int process_crypto(struct sip_pvt *p, struct ast_rtp_instance *rtp, struct sip_srtp **srtp, const char *a);
 
 /*------ T38 Support --------- */
 static int transmit_response_with_t38_sdp(struct sip_pvt *p, char *msg, struct sip_request *req, int retrans);
@@ -4198,8 +4198,18 @@
 			ast_clear_flag(&p->flags[0], SIP_REINVITE);
 		}
 
-		if (!p->srtp && setup_srtp(p) < 0) {
-			ast_log(LOG_WARNING, "SRTP setup failed\n");
+		if (p->rtp && !p->srtp && setup_srtp(&p->srtp) < 0) {
+			ast_log(LOG_WARNING, "SRTP audio setup failed\n");
+			return -1;
+		}
+
+		if (p->vrtp && !p->vsrtp && setup_srtp(&p->vsrtp) < 0) {
+			ast_log(LOG_WARNING, "SRTP video setup failed\n");
+			return -1;
+		}
+
+		if (p->trtp && !p->vsrtp && setup_srtp(&p->tsrtp) < 0) {
+			ast_log(LOG_WARNING, "SRTP text setup failed\n");
 			return -1;
 		}
 	}
@@ -7022,7 +7032,7 @@
 				if (audio) {
 					if (process_sdp_a_sendonly(value, &sendonly))
 						processed = TRUE;
-					else if (!process_crypto(p, value))
+					else if (!process_crypto(p, p->rtp, &p->srtp, value))
 						processed = TRUE;
 					else if (process_sdp_a_audio(value, p, &newaudiortp, &last_rtpmap_codec))
 						processed = TRUE;
@@ -7031,7 +7041,7 @@
 				else if (video) {
 					if (process_sdp_a_sendonly(value, &vsendonly))
 						processed = TRUE;
-					else if (!process_crypto(p, value))
+					else if (!process_crypto(p, p->vrtp, &p->vsrtp, value))
 						processed = TRUE;
 					else if (process_sdp_a_video(value, p, &newvideortp, &last_rtpmap_codec))
 						processed = TRUE;
@@ -7040,6 +7050,8 @@
 				else if (text) {
 					if (process_sdp_a_text(value, p, &newtextrtp, red_fmtp, &red_num_gen, red_data_pt, &last_rtpmap_codec))
 						processed = TRUE;
+					else if (!process_crypto(p, p->trtp, &p->tsrtp, value))
+						processed = TRUE;
 				}
 				/* Image (T.38 FAX) specific scanning */
 				else if (image) {
@@ -7087,12 +7099,12 @@
 		return -4;
 	}
 
-	if (secure_video && !(p->srtp && (ast_test_flag(p->srtp, SRTP_CRYPTO_OFFER_OK)))) {
+	if (secure_video && !(p->vsrtp && (ast_test_flag(p->vsrtp, SRTP_CRYPTO_OFFER_OK)))) {
 		ast_log(LOG_WARNING, "Can't provide secure video requested in SDP offer\n");
 		return -4;
 	}
 
-	if (!p->novideo && !secure_video && p->srtp) {
+	if (!p->novideo && !secure_video && p->vsrtp) {
 		ast_log(LOG_WARNING, "We are requesting SRTP, but they responded without it!\n");
 		return -4;
 	}
@@ -8962,6 +8974,23 @@
 	}
 }
 
+static void get_crypto_attrib(struct sip_srtp *srtp, const char **a_crypto)
+{
+	/* Set encryption properties */
+	if (srtp) {
+		if (!srtp->crypto) {
+			srtp->crypto = sdp_crypto_setup();
+		}
+		if (srtp->crypto && (sdp_crypto_offer(srtp->crypto) >= 0)) {
+			*a_crypto = sdp_crypto_attrib(srtp->crypto);
+		}
+
+		if (!*a_crypto) {
+			ast_log(LOG_WARNING, "No SRTP key management enabled\n");
+		}
+	}
+}
+
 /*! \brief Add Session Description Protocol message
 
     If oldsdp is TRUE, then the SDP version number is not incremented. This mechanism
@@ -8999,6 +9028,8 @@
 	struct ast_str *a_text = ast_str_alloca(1024);  /* Attributes for text */
 	struct ast_str *a_modem = ast_str_alloca(1024); /* Attributes for modem */
 	const char *a_crypto = NULL;
+	const char *v_a_crypto = NULL;
+	const char *t_a_crypto = NULL;
 
 	format_t x;
 	format_t capability = 0;
@@ -9013,7 +9044,6 @@
 	char codecbuf[SIPBUFSIZE];
 	char buf[SIPBUFSIZE];
 	char dummy_answer[256];
-	const char *protocol = NULL;
 
 	/* Set the SDP session name */
 	snprintf(subject, sizeof(subject), "s=%s\r\n", ast_strlen_zero(global_sdpsession) ? "-" : global_sdpsession);
@@ -9061,25 +9091,6 @@
 
 	get_our_media_address(p, needvideo, needtext, &sin, &vsin, &tsin, &dest, &vdest, &tdest);
 
-	/* Set encryption properties */
-	if (p->srtp) {
-		if (p->srtp->crypto) {
-			a_crypto = sdp_crypto_attrib(p->srtp->crypto);
-		} else {
-			p->srtp->crypto = sdp_crypto_setup();
-
-			if (p->srtp->crypto && (sdp_crypto_offer(p->srtp->crypto) >= 0)) {
-				a_crypto = sdp_crypto_attrib(p->srtp->crypto);
-			}
-		}
-
-		if (!a_crypto) {
-			ast_log(LOG_WARNING, "No SRTP key management enabled\n");
-		}
-	}
-
-	protocol = a_crypto ? "SAVP" : "AVP";
-
 	snprintf(owner, sizeof(owner), "o=%s %d %d IN IP4 %s\r\n", ast_strlen_zero(global_sdpowner) ? "-" : global_sdpowner, p->sessionid, p->sessionversion, ast_inet_ntoa(dest.sin_addr));
 
 	snprintf(connection, sizeof(connection), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr));
@@ -9102,7 +9113,9 @@
 		/* 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. */
 		if (needvideo) {
-			ast_str_append(&m_video, 0, "m=video %d RTP/%s", ntohs(vdest.sin_port), protocol);
+			get_crypto_attrib(p->vsrtp, &v_a_crypto);
+			ast_str_append(&m_video, 0, "m=video %d RTP/%s", ntohs(vdest.sin_port),
+				v_a_crypto ? "SAVP" : "AVP");
 
 			/* Build max bitrate string */
 			if (p->maxcallbitrate)
@@ -9116,7 +9129,9 @@
 		if (needtext) {
 			if (sipdebug_text)
 				ast_verbose("Lets set up the text sdp\n");
-			ast_str_append(&m_text, 0, "m=text %d RTP/AVP", ntohs(tdest.sin_port));
+			get_crypto_attrib(p->tsrtp, &t_a_crypto);
+			ast_str_append(&m_text, 0, "m=text %d RTP/%s", ntohs(tdest.sin_port),
+				t_a_crypto ? "SAVP" : "AVP");
 			if (debug) /* XXX should I use tdest below ? */
 				ast_verbose("Text is at %s port %d\n", ast_inet_ntoa(p->ourip.sin_addr), ntohs(tsin.sin_port));	
 
@@ -9127,7 +9142,9 @@
 		/* We break with the "recommendation" and send our IP, in order that our
 		   peer doesn't have to ast_gethostbyname() us */
 
-		ast_str_append(&m_audio, 0, "m=audio %d RTP/%s", ntohs(dest.sin_port), protocol);
+		get_crypto_attrib(p->srtp, &a_crypto);
+		ast_str_append(&m_audio, 0, "m=audio %d RTP/%s", ntohs(dest.sin_port),
+			a_crypto ? "SAVP" : "AVP");
 
 		if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR)
 			hold = "a=recvonly\r\n";
@@ -9290,12 +9307,13 @@
 	if (add_t38)
 		len += m_modem->used + a_modem->used;
 	if (a_crypto) {
-		if (needaudio) {
-			len += strlen(a_crypto);
-		}
-		if (needvideo) {
-			len += strlen(a_crypto);
-		}
+		len += strlen(a_crypto);
+	}
+	if (v_a_crypto) {
+		len += strlen(v_a_crypto);
+	}
+	if (t_a_crypto) {
+		len += strlen(t_a_crypto);
 	}
 	add_header(resp, "Content-Type", "application/sdp");
 	add_header_contentLength(resp, len);
@@ -9321,8 +9339,8 @@
 		add_line(resp, m_video->str);
 		add_line(resp, a_video->str);
 		add_line(resp, hold);	/* Repeat hold for the video stream */
-		if (a_crypto) {
-			add_line(resp, a_crypto);
+		if (v_a_crypto) {
+			add_line(resp, v_a_crypto);
 		}
 	} else if (p->offered_media[SDP_VIDEO].offered) {
 		snprintf(dummy_answer, sizeof(dummy_answer), "m=video 0 RTP/AVP %s\r\n", p->offered_media[SDP_VIDEO].codecs);
@@ -9332,6 +9350,9 @@
 		add_line(resp, m_text->str);
 		add_line(resp, a_text->str);
 		add_line(resp, hold);	/* Repeat hold for the text stream */
+		if (t_a_crypto) {
+			add_line(resp, t_a_crypto);
+		}
 	} else if (p->offered_media[SDP_TEXT].offered) {
 		snprintf(dummy_answer, sizeof(dummy_answer), "m=text 0 RTP/AVP %s\r\n", p->offered_media[SDP_TEXT].codecs);
 		add_line(resp, dummy_answer);
@@ -25048,45 +25069,45 @@
 }
 
 /* SRTP */
-static int setup_srtp(struct sip_pvt *p)
+static int setup_srtp(struct sip_srtp **srtp)
 {
 	if (!ast_rtp_engine_srtp_is_registered()) {
 	   ast_log(LOG_ERROR, "No SRTP module loaded, can't setup SRTP session.\n");
 	   return -1;
 	}
 
-	if (!(p->srtp = sip_srtp_alloc())) {    /* Allocate SRTP data structure */
+	if (!(*srtp = sip_srtp_alloc())) {    /* Allocate SRTP data structure */
 	   return -1;
 	}
 
 	return 0;
 }
 
-static int process_crypto(struct sip_pvt *p, const char *a)
+static int process_crypto(struct sip_pvt *p, struct ast_rtp_instance *rtp, struct sip_srtp **srtp, const char *a)
 {
 	if (strncasecmp(a, "crypto:", 7)) {
 		return -1;
 	}
-	if (!p->srtp) {
+	if (!*srtp) {
 	   if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
 		   ast_log(LOG_WARNING, "Ignoring unexpected crypto attribute in SDP answer\n");
 		   return -1;
 	   }
 
-	   if (setup_srtp(p) < 0) {
+	   if (setup_srtp(srtp) < 0) {
 		   return -1;
 	   }
 	}
 
-	if (!p->srtp->crypto && !(p->srtp->crypto = sdp_crypto_setup())) {
+	if (!(*srtp)->crypto && !((*srtp)->crypto = sdp_crypto_setup())) {
 	   return -1;
 	}
 
-	if (sdp_crypto_process(p->srtp->crypto, a, p->rtp) < 0) {
+	if (sdp_crypto_process((*srtp)->crypto, a, rtp) < 0) {
 	   return -1;
 	}
 
-	ast_set_flag(p->srtp, SRTP_CRYPTO_OFFER_OK);
+	ast_set_flag(*srtp, SRTP_CRYPTO_OFFER_OK);
 
 	return 0;
 }

Modified: team/group/srtp_reboot/channels/sip/include/sip.h
URL: http://svnview.digium.com/svn/asterisk/team/group/srtp_reboot/channels/sip/include/sip.h?view=diff&rev=254404&r1=254403&r2=254404
==============================================================================
--- team/group/srtp_reboot/channels/sip/include/sip.h (original)
+++ team/group/srtp_reboot/channels/sip/include/sip.h Wed Mar 24 21:15:54 2010
@@ -1034,7 +1034,9 @@
 	AST_LIST_HEAD_NOLOCK(request_queue, sip_request) request_queue; /*!< Requests that arrived but could not be processed immediately */
 	struct sip_invite_param *options;   /*!< Options for INVITE */
 	struct sip_st_dlg *stimer;          /*!< SIP Session-Timers */
-	struct sip_srtp *srtp;              /*!< Structure to hold Secure RTP session data */
+	struct sip_srtp *srtp;              /*!< Structure to hold Secure RTP session data for audio */
+	struct sip_srtp *vsrtp;             /*!< Structure to hold Secure RTP session data for video */
+	struct sip_srtp *tsrtp;             /*!< Structure to hold Secure RTP session data for text */
 
 	int red;                            /*!< T.140 RTP Redundancy */
 	int hangupcause;                    /*!< Storage of hangupcause copied from our owner before we disconnect from the AST channel (only used at hangup) */




More information about the svn-commits mailing list