X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=modules%2Fdemux%2Frtp.c;h=ee99286a276e272fc76e1d584cb45da996c4c45b;hb=0d8adc76dbf01e54ef043a07a623982a7fa9a426;hp=6dcc186e4aa578af9deaa0b2e88133362aa2cd37;hpb=51a5b2bedc0dd99f556c3fb64ffa8450c5401a44;p=vlc diff --git a/modules/demux/rtp.c b/modules/demux/rtp.c index 6dcc186e4a..ee99286a27 100644 --- a/modules/demux/rtp.c +++ b/modules/demux/rtp.c @@ -39,11 +39,21 @@ #include #include "rtp.h" +#include #define RTP_CACHING_TEXT N_("RTP de-jitter buffer length (msec)") #define RTP_CACHING_LONGTEXT N_( \ "How long to wait for late RTP packets (and delay the performance)." ) +#define SRTP_KEY_TEXT N_("SRTP key (hexadecimal)") +#define SRTP_KEY_LONGTEXT N_( \ + "RTP packets will be authenticated and deciphered "\ + "with this Secure RTP master shared secret key.") + +#define SRTP_SALT_TEXT N_("SRTP salt (hexadecimal)") +#define SRTP_SALT_LONGTEXT N_( \ + "Secure RTP requires a (non-secret) master salt value.") + #define RTP_MAX_SRC_TEXT N_("Maximum RTP sources") #define RTP_MAX_SRC_LONGTEXT N_( \ "How many distinct active RTP sources are allowed at a time." ) @@ -79,6 +89,10 @@ vlc_module_begin (); add_integer ("rtp-caching", 1000, NULL, RTP_CACHING_TEXT, RTP_CACHING_LONGTEXT, true); change_integer_range (0, 65535); + add_string ("srtp-key", "", NULL, + SRTP_KEY_TEXT, SRTP_KEY_LONGTEXT, false); + add_string ("srtp-salt", "", NULL, + SRTP_SALT_TEXT, SRTP_SALT_LONGTEXT, false); add_integer ("rtp-max-src", 1, NULL, RTP_MAX_SRC_TEXT, RTP_MAX_SRC_LONGTEXT, true); change_integer_range (1, 255); @@ -162,14 +176,18 @@ static int Open (vlc_object_t *obj) dport = 5004; /* avt-profile-1 port */ /* Try to connect */ - int fd = -1; + int fd = -1, rtcp_fd = -1; switch (tp) { case IPPROTO_UDP: case IPPROTO_UDPLITE: - fd = net_OpenDgram (obj, dhost, dport, shost, sport, AF_UNSPEC, - tp); + fd = net_OpenDgram (obj, dhost, (dport + 1) & ~1, + shost, (sport + 1) & ~1, AF_UNSPEC, tp); + if (fd == -1) + break; + rtcp_fd = net_OpenDgram (obj, dhost, dport | 1, shost, + sport ? (sport | 1) : 0, AF_UNSPEC, tp); break; case IPPROTO_DCCP: @@ -180,15 +198,15 @@ static int Open (vlc_object_t *obj) #endif #ifdef SOCK_DCCP var_Create (obj, "dccp-service", VLC_VAR_STRING); - var_SetString (obj, "dccp-service", "RTPV"); - fd = net_Connect (obj, shost, sport, SOCK_DCCP, tp); + var_SetString (obj, "dccp-service", "RTPV"); /* FIXME: RTPA? */ + fd = net_Connect (obj, shost, (sport + 1) & ~1, SOCK_DCCP, tp); #else msg_Err (obj, "DCCP support not included"); #endif break; case IPPROTO_TCP: - fd = net_Connect (obj, shost, sport, SOCK_STREAM, tp); + fd = net_Connect (obj, shost, (sport + 1) & ~1, SOCK_STREAM, tp); break; } @@ -200,8 +218,16 @@ static int Open (vlc_object_t *obj) /* Initializes demux */ demux_sys_t *p_sys = malloc (sizeof (*p_sys)); if (p_sys == NULL) - goto error; + { + net_Close (fd); + if (rtcp_fd != -1) + net_Close (rtcp_fd); + return VLC_EGENERIC; + } + p_sys->srtp = NULL; + p_sys->fd = fd; + p_sys->rtcp_fd = rtcp_fd; p_sys->caching = var_CreateGetInteger (obj, "rtp-caching"); p_sys->max_src = var_CreateGetInteger (obj, "rtp-max-src"); p_sys->timeout = var_CreateGetInteger (obj, "rtp-timeout"); @@ -218,12 +244,32 @@ static int Open (vlc_object_t *obj) if (p_sys->session == NULL) goto error; - p_sys->fd = fd; + char *key = var_CreateGetNonEmptyString (demux, "srtp-key"); + if (key) + { + p_sys->srtp = srtp_create (SRTP_ENCR_AES_CM, SRTP_AUTH_HMAC_SHA1, 10, + SRTP_PRF_AES_CM, SRTP_RCC_MODE1); + if (p_sys->srtp == NULL) + { + free (key); + goto error; + } + + char *salt = var_CreateGetNonEmptyString (demux, "srtp-salt"); + errno = srtp_setkeystring (p_sys->srtp, key, salt ? salt : ""); + free (salt); + free (key); + if (errno) + { + msg_Err (obj, "bad SRTP key/salt combination (%m)"); + goto error; + } + } + return VLC_SUCCESS; error: - net_Close (fd); - free (p_sys); + Close (obj); return VLC_EGENERIC; } @@ -236,7 +282,12 @@ static void Close (vlc_object_t *obj) demux_t *demux = (demux_t *)obj; demux_sys_t *p_sys = demux->p_sys; - rtp_session_destroy (demux, p_sys->session); + if (p_sys->srtp) + srtp_destroy (p_sys->srtp); + if (p_sys->session) + rtp_session_destroy (demux, p_sys->session); + if (p_sys->rtcp_fd != -1) + net_Close (p_sys->rtcp_fd); net_Close (p_sys->fd); free (p_sys); } @@ -330,7 +381,7 @@ static block_t *rtp_dgram_recv (demux_t *demux, int fd) len = net_Read (VLC_OBJECT (demux), fd, NULL, block->p_buffer, block->i_buffer, false); if (((len <= 0) && fd_dead (fd)) - || demux->b_die) + || !vlc_object_alive (demux)) { block_Release (block); return NULL; @@ -568,8 +619,8 @@ static int Demux (demux_t *demux) block_t *block; block = p_sys->framed_rtp - ? rtp_dgram_recv (demux, p_sys->fd) - : rtp_stream_recv (demux, p_sys->fd); + ? rtp_stream_recv (demux, p_sys->fd) + : rtp_dgram_recv (demux, p_sys->fd); if (!block) return 0; @@ -580,6 +631,17 @@ static int Demux (demux_t *demux) if (ptype >= 72 && ptype <= 76) goto drop; /* Muxed RTCP, ignore for now */ + if (p_sys->srtp) + { + size_t len = block->i_buffer; + if (srtp_recv (p_sys->srtp, block->p_buffer, &len)) + { + msg_Dbg (demux, "SRTP authentication/decryption failed"); + goto drop; + } + block->i_buffer = len; + } + /* Not using SDP, we need to guess the payload format used */ /* see http://www.iana.org/assignments/rtp-parameters */ if (p_sys->autodetect) @@ -621,7 +683,7 @@ static int Demux (demux_t *demux) msg_Dbg (demux, "detected MPEG Audio"); pt.init = mpa_init; pt.decode = mpa_decode; - pt.frequency = 44100; + pt.frequency = 90000; break; case 32: