FFmpeg
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
srtpproto.c
Go to the documentation of this file.
1 /*
2  * SRTP network protocol
3  * Copyright (c) 2012 Martin Storsjo
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "libavutil/opt.h"
23 #include "avformat.h"
24 #include "avio_internal.h"
25 #include "url.h"
26 
27 #include "internal.h"
28 #include "srtp.h"
29 
30 typedef struct SRTPProtoContext {
31  const AVClass *class;
33  const char *out_suite, *out_params;
34  const char *in_suite, *in_params;
35  struct SRTPContext srtp_out, srtp_in;
38 
39 #define D AV_OPT_FLAG_DECODING_PARAM
40 #define E AV_OPT_FLAG_ENCODING_PARAM
41 static const AVOption options[] = {
42  { "srtp_out_suite", "", offsetof(SRTPProtoContext, out_suite), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E },
43  { "srtp_out_params", "", offsetof(SRTPProtoContext, out_params), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E },
44  { "srtp_in_suite", "", offsetof(SRTPProtoContext, in_suite), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E },
45  { "srtp_in_params", "", offsetof(SRTPProtoContext, in_params), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E },
46  { NULL }
47 };
48 
49 static const AVClass srtp_context_class = {
50  .class_name = "srtp",
51  .item_name = av_default_item_name,
52  .option = options,
53  .version = LIBAVUTIL_VERSION_INT,
54 };
55 
56 static int srtp_close(URLContext *h)
57 {
59  ff_srtp_free(&s->srtp_out);
60  ff_srtp_free(&s->srtp_in);
61  ffurl_close(s->rtp_hd);
62  s->rtp_hd = NULL;
63  return 0;
64 }
65 
66 static int srtp_open(URLContext *h, const char *uri, int flags)
67 {
69  char hostname[256], buf[1024], path[1024];
70  int rtp_port, ret;
71 
72  if (s->out_suite && s->out_params)
73  if ((ret = ff_srtp_set_crypto(&s->srtp_out, s->out_suite, s->out_params)) < 0)
74  goto fail;
75  if (s->in_suite && s->in_params)
76  if ((ret = ff_srtp_set_crypto(&s->srtp_in, s->in_suite, s->in_params)) < 0)
77  goto fail;
78 
79  av_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &rtp_port,
80  path, sizeof(path), uri);
81  ff_url_join(buf, sizeof(buf), "rtp", NULL, hostname, rtp_port, "%s", path);
82  if ((ret = ffurl_open(&s->rtp_hd, buf, flags, &h->interrupt_callback, NULL)) < 0)
83  goto fail;
84 
86  sizeof(s->encryptbuf)) - 14;
87  h->is_streamed = 1;
88  return 0;
89 
90 fail:
91  srtp_close(h);
92  return ret;
93 }
94 
95 static int srtp_read(URLContext *h, uint8_t *buf, int size)
96 {
98  int ret;
99 start:
100  ret = ffurl_read(s->rtp_hd, buf, size);
101  if (ret > 0 && s->srtp_in.aes) {
102  if (ff_srtp_decrypt(&s->srtp_in, buf, &ret) < 0)
103  goto start;
104  }
105  return ret;
106 }
107 
108 static int srtp_write(URLContext *h, const uint8_t *buf, int size)
109 {
110  SRTPProtoContext *s = h->priv_data;
111  if (!s->srtp_out.aes)
112  return ffurl_write(s->rtp_hd, buf, size);
113  size = ff_srtp_encrypt(&s->srtp_out, buf, size, s->encryptbuf,
114  sizeof(s->encryptbuf));
115  if (size < 0)
116  return size;
117  return ffurl_write(s->rtp_hd, s->encryptbuf, size);
118 }
119 
121 {
122  SRTPProtoContext *s = h->priv_data;
123  return ffurl_get_file_handle(s->rtp_hd);
124 }
125 
126 static int srtp_get_multi_file_handle(URLContext *h, int **handles,
127  int *numhandles)
128 {
129  SRTPProtoContext *s = h->priv_data;
130  return ffurl_get_multi_file_handle(s->rtp_hd, handles, numhandles);
131 }
132 
134  .name = "srtp",
135  .url_open = srtp_open,
136  .url_read = srtp_read,
137  .url_write = srtp_write,
138  .url_close = srtp_close,
139  .url_get_file_handle = srtp_get_file_handle,
140  .url_get_multi_file_handle = srtp_get_multi_file_handle,
141  .priv_data_size = sizeof(SRTPProtoContext),
142  .priv_data_class = &srtp_context_class,
144 };