2 * SRTP network protocol
3 * Copyright (c) 2012 Martin Storsjo
5 * This file is part of FFmpeg.
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.
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.
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
22 #include "libavutil/opt.h"
24 #include "avio_internal.h"
31 typedef struct SRTPProtoContext
{
34 const char *out_suite
, *out_params
;
35 const char *in_suite
, *in_params
;
36 struct SRTPContext srtp_out
, srtp_in
;
37 uint8_t encryptbuf
[RTP_MAX_PACKET_LENGTH
];
40 #define D AV_OPT_FLAG_DECODING_PARAM
41 #define E AV_OPT_FLAG_ENCODING_PARAM
42 static const AVOption options
[] = {
43 { "srtp_out_suite", "", offsetof(SRTPProtoContext
, out_suite
), AV_OPT_TYPE_STRING
, { .str
= NULL
}, 0, 0, E
},
44 { "srtp_out_params", "", offsetof(SRTPProtoContext
, out_params
), AV_OPT_TYPE_STRING
, { .str
= NULL
}, 0, 0, E
},
45 { "srtp_in_suite", "", offsetof(SRTPProtoContext
, in_suite
), AV_OPT_TYPE_STRING
, { .str
= NULL
}, 0, 0, E
},
46 { "srtp_in_params", "", offsetof(SRTPProtoContext
, in_params
), AV_OPT_TYPE_STRING
, { .str
= NULL
}, 0, 0, E
},
50 static const AVClass srtp_context_class
= {
52 .item_name
= av_default_item_name
,
54 .version
= LIBAVUTIL_VERSION_INT
,
57 static int srtp_close(URLContext
*h
)
59 SRTPProtoContext
*s
= h
->priv_data
;
60 ff_srtp_free(&s
->srtp_out
);
61 ff_srtp_free(&s
->srtp_in
);
62 ffurl_close(s
->rtp_hd
);
67 static int srtp_open(URLContext
*h
, const char *uri
, int flags
)
69 SRTPProtoContext
*s
= h
->priv_data
;
70 char hostname
[256], buf
[1024], path
[1024];
73 if (s
->out_suite
&& s
->out_params
)
74 if ((ret
= ff_srtp_set_crypto(&s
->srtp_out
, s
->out_suite
, s
->out_params
)) < 0)
76 if (s
->in_suite
&& s
->in_params
)
77 if ((ret
= ff_srtp_set_crypto(&s
->srtp_in
, s
->in_suite
, s
->in_params
)) < 0)
80 av_url_split(NULL
, 0, NULL
, 0, hostname
, sizeof(hostname
), &rtp_port
,
81 path
, sizeof(path
), uri
);
82 ff_url_join(buf
, sizeof(buf
), "rtp", NULL
, hostname
, rtp_port
, "%s", path
);
83 if ((ret
= ffurl_open(&s
->rtp_hd
, buf
, flags
, &h
->interrupt_callback
, NULL
)) < 0)
86 h
->max_packet_size
= FFMIN(s
->rtp_hd
->max_packet_size
,
87 sizeof(s
->encryptbuf
)) - 14;
96 static int srtp_read(URLContext
*h
, uint8_t *buf
, int size
)
98 SRTPProtoContext
*s
= h
->priv_data
;
101 ret
= ffurl_read(s
->rtp_hd
, buf
, size
);
102 if (ret
> 0 && s
->srtp_in
.aes
) {
103 if (ff_srtp_decrypt(&s
->srtp_in
, buf
, &ret
) < 0)
109 static int srtp_write(URLContext
*h
, const uint8_t *buf
, int size
)
111 SRTPProtoContext
*s
= h
->priv_data
;
112 if (!s
->srtp_out
.aes
)
113 return ffurl_write(s
->rtp_hd
, buf
, size
);
114 size
= ff_srtp_encrypt(&s
->srtp_out
, buf
, size
, s
->encryptbuf
,
115 sizeof(s
->encryptbuf
));
118 return ffurl_write(s
->rtp_hd
, s
->encryptbuf
, size
);
121 static int srtp_get_file_handle(URLContext
*h
)
123 SRTPProtoContext
*s
= h
->priv_data
;
124 return ffurl_get_file_handle(s
->rtp_hd
);
127 static int srtp_get_multi_file_handle(URLContext
*h
, int **handles
,
130 SRTPProtoContext
*s
= h
->priv_data
;
131 return ffurl_get_multi_file_handle(s
->rtp_hd
, handles
, numhandles
);
134 URLProtocol ff_srtp_protocol
= {
136 .url_open
= srtp_open
,
137 .url_read
= srtp_read
,
138 .url_write
= srtp_write
,
139 .url_close
= srtp_close
,
140 .url_get_file_handle
= srtp_get_file_handle
,
141 .url_get_multi_file_handle
= srtp_get_multi_file_handle
,
142 .priv_data_size
= sizeof(SRTPProtoContext
),
143 .priv_data_class
= &srtp_context_class
,
144 .flags
= URL_PROTOCOL_FLAG_NETWORK
,