[asterisk-commits] twilson: branch group/srtp_reboot r254404 - in /team/group/srtp_reboot/channe...
SVN commits to the Asterisk project
asterisk-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 asterisk-commits
mailing list