/src/rtpproxy/modules/dtls_gw/rtpp_dtls_gw.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2022 Sippy Software, Inc., http://www.sippysoft.com |
3 | | * |
4 | | * Redistribution and use in source and binary forms, with or without |
5 | | * modification, are permitted provided that the following conditions |
6 | | * are met: |
7 | | * 1. Redistributions of source code must retain the above copyright |
8 | | * notice, this list of conditions and the following disclaimer. |
9 | | * 2. Redistributions in binary form must reproduce the above copyright |
10 | | * notice, this list of conditions and the following disclaimer in the |
11 | | * documentation and/or other materials provided with the distribution. |
12 | | * |
13 | | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
14 | | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
15 | | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
16 | | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
17 | | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
18 | | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
19 | | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
20 | | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
21 | | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
22 | | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
23 | | * SUCH DAMAGE. |
24 | | * |
25 | | */ |
26 | | |
27 | | #include <sys/types.h> |
28 | | #include <sys/socket.h> |
29 | | #include <arpa/inet.h> |
30 | | #include <stdatomic.h> |
31 | | #include <stdbool.h> |
32 | | #include <stddef.h> |
33 | | #include <stdint.h> |
34 | | #include <stdlib.h> |
35 | | #include <stdio.h> |
36 | | #include <string.h> |
37 | | |
38 | | #include <srtp2/srtp.h> |
39 | | |
40 | | #include "config_pp.h" |
41 | | |
42 | | #include "rtpp_types.h" |
43 | | #include "rtpp_debug.h" |
44 | | #include "rtpp_module.h" |
45 | | #include "rtpp_module_wthr.h" |
46 | | #include "rtpp_module_cplane.h" |
47 | | #include "rtpp_log.h" |
48 | | #include "rtpp_log_obj.h" |
49 | | #include "rtpp_codeptr.h" |
50 | | #include "rtpp_refcnt.h" |
51 | | #include "rtpp_cfg.h" |
52 | | #include "rtpp_wi.h" |
53 | | #include "rtpp_wi_sgnl.h" |
54 | | #include "rtpp_wi_data.h" |
55 | | #include "rtpp_queue.h" |
56 | | #include "rtpp_stream.h" |
57 | | #include "rtp.h" |
58 | | #include "rtpp_time.h" |
59 | | #include "rtp_packet.h" |
60 | | #include "rtpp_packetops.h" |
61 | | #include "rtpp_command.h" |
62 | | #include "rtpp_command_args.h" |
63 | | #include "rtpp_command_sub.h" |
64 | | #include "rtpp_util.h" |
65 | | #include "rtpp_socket.h" |
66 | | #include "rtpp_sessinfo.h" |
67 | | #include "rtpp_session.h" |
68 | | #include "rtpp_stats.h" |
69 | | #include "rtpp_stream.h" |
70 | | #include "rtpp_pipe.h" |
71 | | #include "rtpp_proc_async.h" |
72 | | #include "rtpp_ttl.h" |
73 | | #include "rtpp_util.h" |
74 | | #include "rtpp_pcount.h" |
75 | | #include "rtpp_pcnt_strm.h" |
76 | | #include "rtpp_linker_set.h" |
77 | | #include "advanced/packet_processor.h" |
78 | | #include "advanced/pproc_manager.h" |
79 | | |
80 | | #include "rtpp_dtls.h" |
81 | | #include "rtpp_dtls_util.h" |
82 | | #include "rtpp_dtls_conn.h" |
83 | | |
84 | | struct rtpp_module_priv { |
85 | | struct rtpp_dtls *dtls_ctx; |
86 | | const struct rtpp_cfg *cfsp; |
87 | | struct rtpp_minfo *mself; |
88 | | }; |
89 | | |
90 | | struct dtls_gw_stream_cfg { |
91 | | struct rtpp_refcnt *rcnt; |
92 | | struct rtpp_dtls_conn *dtls_conn; |
93 | | struct rtpp_minfo *mself; |
94 | | }; |
95 | | |
96 | | enum rtpp_dtls_dir { |
97 | | DTLS_IN, SRTP_IN, RTP_OUT |
98 | | }; |
99 | | |
100 | | struct rtpp_dtls_gw_aux { |
101 | | enum rtpp_dtls_dir direction; |
102 | | struct rtpp_dtls_conn *dtls_conn; |
103 | | struct rtpp_minfo *mself; |
104 | | }; |
105 | | |
106 | | struct wipkt { |
107 | | struct pkt_proc_ctx pktx; |
108 | | struct rtpp_dtls_gw_aux edata; |
109 | | }; |
110 | | |
111 | | static struct rtpp_module_priv *rtpp_dtls_gw_ctor(const struct rtpp_cfg *, |
112 | | struct rtpp_minfo *); |
113 | | static void rtpp_dtls_gw_dtor(struct rtpp_module_priv *); |
114 | | static void rtpp_dtls_gw_worker(const struct rtpp_wthrdata *); |
115 | | static int rtpp_dtls_gw_handle_command(struct rtpp_module_priv *, |
116 | | const struct rtpp_subc_ctx *); |
117 | | static int rtpp_dtls_gw_taste_encrypted(struct pkt_proc_ctx *); |
118 | | static int rtpp_dtls_gw_taste_plain(struct pkt_proc_ctx *); |
119 | | static struct pproc_act rtpp_dtls_gw_enqueue(const struct pkt_proc_ctx *); |
120 | | |
121 | | #ifdef RTPP_CHECK_LEAKS |
122 | | #include "rtpp_memdeb_internal.h" |
123 | | |
124 | | RTPP_MEMDEB_APP_STATIC; |
125 | | #endif |
126 | | |
127 | | const struct rtpp_minfo RTPP_MOD_SELF = { |
128 | | .descr.name = "dtls_gw", |
129 | | .descr.ver = MI_VER_INIT(), |
130 | | .descr.module_id = 4, |
131 | | .proc.ctor = rtpp_dtls_gw_ctor, |
132 | | .proc.dtor = rtpp_dtls_gw_dtor, |
133 | | .wapi = &(const struct rtpp_wthr_handlers){ |
134 | | .main_thread = rtpp_dtls_gw_worker, |
135 | | .queue_size = RTPQ_MEDIUM_CB_LEN, |
136 | | }, |
137 | | .capi = &(const struct rtpp_cplane_handlers){.ul_subc_handle = rtpp_dtls_gw_handle_command}, |
138 | | .fn = &(struct rtpp_minfo_fset){0}, |
139 | | #ifdef RTPP_CHECK_LEAKS |
140 | | .memdeb_p = &MEMDEB_SYM |
141 | | #endif |
142 | | }; |
143 | | #if defined(LIBRTPPROXY) |
144 | | DATA_SET(rtpp_modules, RTPP_MOD_SELF); |
145 | | #endif |
146 | | |
147 | | static void |
148 | | rtpp_dtls_gw_worker(const struct rtpp_wthrdata *wp) |
149 | 4 | { |
150 | 4 | struct rtpp_wi *wi; |
151 | 4 | struct wipkt *wip; |
152 | 4 | struct res_loc res; |
153 | | |
154 | 297k | for (;;) { |
155 | 297k | wi = rtpp_queue_get_item(wp->mod_q, 0); |
156 | 297k | if (wi == wp->sigterm) { |
157 | 4 | RTPP_OBJ_DECREF(wi); |
158 | 4 | break; |
159 | 4 | } |
160 | 297k | wip = rtpp_wi_data_get_ptr(wi, sizeof(*wip), sizeof(*wip)); |
161 | 297k | struct rtpp_dtls_gw_aux *edp = &wip->edata; |
162 | 297k | switch (edp->direction) { |
163 | 34.6k | case DTLS_IN: |
164 | | #if 0 |
165 | | RTPP_LOG(edp->mself->log, RTPP_LOG_DBUG, "Packet from DTLS"); |
166 | | #endif |
167 | 34.6k | CALL_SMETHOD(edp->dtls_conn, dtls_recv, wip->pktx.pktp); |
168 | 34.6k | res = RES_HERE(1); |
169 | 34.6k | break; |
170 | 92.5k | case SRTP_IN: |
171 | | #if 0 |
172 | | RTPP_LOG(RTPP_MOD_SELF.log, RTPP_LOG_DBUG, "DTLS: packet SRTP->RTP"); |
173 | | #endif |
174 | 92.5k | res = CALL_SMETHOD(edp->dtls_conn, srtp_recv, &wip->pktx); |
175 | 92.5k | break; |
176 | 169k | case RTP_OUT: |
177 | | #if 0 |
178 | | RTPP_LOG(RTPP_MOD_SELF.log, RTPP_LOG_DBUG, "DTLS: packet RTP->SRTP"); |
179 | | #endif |
180 | 169k | res = CALL_SMETHOD(edp->dtls_conn, rtp_send, &wip->pktx); |
181 | 169k | break; |
182 | 0 | default: |
183 | 0 | abort(); |
184 | 297k | } |
185 | 297k | if (res.v != 0) { |
186 | 297k | switch (edp->direction) { |
187 | 34.6k | case DTLS_IN: |
188 | 34.6k | break; |
189 | 92.5k | case SRTP_IN: |
190 | 92.5k | CALL_SMETHOD(wip->pktx.strmp_in->pcnt_strm, reg_pktin, wip->pktx.pktp); |
191 | | /* Fallthrouth */ |
192 | 262k | case RTP_OUT: |
193 | 262k | CALL_SMETHOD(wip->pktx.strmp_in->pcount, reg_drop, res.loc); |
194 | 262k | CALL_SMETHOD(wip->pktx.strmp_in->pproc_manager, reg_drop); |
195 | 262k | break; |
196 | 297k | } |
197 | 297k | RTPP_OBJ_DECREF(wip->pktx.pktp); |
198 | 297k | } |
199 | 297k | RTPP_OBJ_DECREF(wi); |
200 | 297k | } |
201 | 4 | } |
202 | | |
203 | | static struct dtls_gw_stream_cfg * |
204 | | dtls_gw_data_ctor(struct rtpp_module_priv *pvt, struct rtpp_stream *dtls_strmp) |
205 | 28.0k | { |
206 | 28.0k | struct dtls_gw_stream_cfg *rtps_c; |
207 | | |
208 | 28.0k | rtps_c = mod_rzmalloc(sizeof(*rtps_c), offsetof(struct dtls_gw_stream_cfg, rcnt)); |
209 | 28.0k | if (rtps_c == NULL) { |
210 | 0 | goto e0; |
211 | 0 | } |
212 | 28.0k | rtps_c->dtls_conn = CALL_METHOD(pvt->dtls_ctx, newconn, dtls_strmp); |
213 | 28.0k | if (rtps_c->dtls_conn == NULL) { |
214 | 0 | goto e1; |
215 | 0 | } |
216 | 28.0k | rtps_c->mself = pvt->mself; |
217 | 28.0k | RC_INCREF(pvt->mself->super_rcnt); |
218 | 28.0k | RTPP_OBJ_DTOR_ATTACH_RC(rtps_c, pvt->mself->super_rcnt); |
219 | 28.0k | RTPP_OBJ_DTOR_ATTACH_RC(rtps_c, rtps_c->dtls_conn->rcnt); |
220 | 28.0k | RTPP_OBJ_DTOR_ATTACH(rtps_c, GET_SMETHOD(rtps_c->dtls_conn, godead), |
221 | 28.0k | rtps_c->dtls_conn); |
222 | 28.0k | rtps_c->mself = pvt->mself; |
223 | 28.0k | return (rtps_c); |
224 | 0 | e1: |
225 | 0 | mod_free(rtps_c); |
226 | 0 | e0: |
227 | 0 | return (NULL); |
228 | 0 | } |
229 | | |
230 | | static int |
231 | | rtpp_dtls_gw_setup_sender(struct rtpp_module_priv *pvt, |
232 | | struct rtpp_session *spa, struct rtpp_stream *dtls_strmp) |
233 | 8.36k | { |
234 | 8.36k | int sidx, lport; |
235 | 8.36k | struct rtpp_socket *fd, *fds[2]; |
236 | | |
237 | 8.36k | fd = CALL_SMETHOD(dtls_strmp, get_skt, HEREVAL); |
238 | 8.36k | if (fd != NULL) { |
239 | 1.49k | RTPP_OBJ_DECREF(fd); |
240 | 1.49k | return (0); |
241 | 1.49k | } |
242 | | |
243 | 6.87k | if (spa->rtp->stream[0] == dtls_strmp) { |
244 | 0 | sidx = 0; |
245 | 6.87k | } else if (spa->rtp->stream[1] == dtls_strmp) { |
246 | 6.87k | sidx = 1; |
247 | 6.87k | } else { |
248 | 0 | abort(); |
249 | 0 | } |
250 | | |
251 | 6.87k | if (rtpp_create_listener(pvt->cfsp, dtls_strmp->laddr, &lport, fds) == -1) |
252 | 0 | return (-1); |
253 | 6.87k | CALL_SMETHOD(pvt->cfsp->sessinfo, append, spa, sidx, fds); |
254 | 6.87k | CALL_METHOD(pvt->cfsp->rtpp_proc_cf, nudge); |
255 | 6.87k | RTPP_OBJ_DECREF(fds[0]); |
256 | 6.87k | RTPP_OBJ_DECREF(fds[1]); |
257 | 6.87k | dtls_strmp->port = lport; |
258 | 6.87k | spa->rtcp->stream[sidx]->port = lport + 1; |
259 | 6.87k | if (spa->complete == 0) { |
260 | 6.80k | CALL_SMETHOD(pvt->cfsp->rtpp_stats, updatebyname, "nsess_complete", 1); |
261 | 6.80k | CALL_SMETHOD(spa->rtp->stream[0]->ttl, reset_with, |
262 | 6.80k | pvt->cfsp->max_ttl); |
263 | 6.80k | CALL_SMETHOD(spa->rtp->stream[1]->ttl, reset_with, |
264 | 6.80k | pvt->cfsp->max_ttl); |
265 | 6.80k | } |
266 | 6.87k | spa->complete = 1; |
267 | 6.87k | return (0); |
268 | 6.87k | } |
269 | | |
270 | | enum rdg_cmd {RDG_CMD_A, RDG_CMD_P, RDG_CMD_S, RDG_CMD_D, RDG_CMD_U}; |
271 | | |
272 | | static int |
273 | | rtpp_dtls_gw_handle_command(struct rtpp_module_priv *pvt, |
274 | | const struct rtpp_subc_ctx *ctxp) |
275 | 43.4k | { |
276 | 43.4k | struct dtls_gw_stream_cfg *rtps_c; |
277 | 43.4k | enum rtpp_dtls_mode my_mode; |
278 | 43.4k | struct rdc_peer_spec rdfs, *rdfsp; |
279 | 43.4k | const rtpp_str_t * argv = rtpp_str_fix(&ctxp->subc_args->v[1]); |
280 | 43.4k | int argc = ctxp->subc_args->c - 1; |
281 | 43.4k | struct rtpp_stream *dtls_strmp; |
282 | 43.4k | int rlen; |
283 | 43.4k | char *rcp; |
284 | 43.4k | enum rdg_cmd rdg_cmd; |
285 | | |
286 | 43.4k | if (argc != 1 && argc != 3 && argc != 4) { |
287 | 503 | RTPP_LOG(pvt->mself->log, RTPP_LOG_ERR, "expected 1, 3 or 4 parameters: %d", |
288 | 503 | argc); |
289 | 503 | return (-1); |
290 | 503 | } |
291 | | |
292 | 42.9k | switch (argv[0].s[0] | argv[0].s[1]) { |
293 | 3.48k | case 'a': |
294 | 12.9k | case 'A': |
295 | 12.9k | if (argc != 3 && argc != 4) |
296 | 205 | goto invalmode; |
297 | 12.7k | rdfs.peer_mode = RTPP_DTLS_ACTIVE; |
298 | 12.7k | rdg_cmd = RDG_CMD_A; |
299 | 12.7k | break; |
300 | | |
301 | 3.61k | case 'p': |
302 | 8.58k | case 'P': |
303 | 8.58k | if (argc != 3 && argc != 4) |
304 | 206 | goto invalmode; |
305 | 8.38k | rdfs.peer_mode = RTPP_DTLS_PASSIVE; |
306 | 8.38k | rdg_cmd = RDG_CMD_P; |
307 | 8.38k | break; |
308 | | |
309 | 2.89k | case 's': |
310 | 18.3k | case 'S': |
311 | 18.3k | if (argc != 1) |
312 | 110 | goto invalmode; |
313 | 18.2k | rdg_cmd = RDG_CMD_S; |
314 | 18.2k | break; |
315 | | |
316 | 1.29k | case 'd': |
317 | 1.36k | case 'D': |
318 | 1.36k | if (argc != 1) |
319 | 132 | goto invalmode; |
320 | 1.23k | rdg_cmd = RDG_CMD_D; |
321 | 1.23k | break; |
322 | | |
323 | 1.17k | case 'u': |
324 | 1.54k | case 'U': |
325 | 1.54k | if (argc != 1) |
326 | 279 | goto invalmode; |
327 | 1.26k | rdg_cmd = RDG_CMD_U; |
328 | 1.26k | break; |
329 | | |
330 | 158 | default: |
331 | 158 | goto invalmode; |
332 | 42.9k | } |
333 | | |
334 | 41.8k | switch (rdg_cmd) { |
335 | 12.7k | case RDG_CMD_A: |
336 | 21.1k | case RDG_CMD_P: |
337 | 21.1k | if (argv[1].len > sizeof(rdfs.alg_buf)) |
338 | 122 | goto invalalg; |
339 | 148k | for (int i = 0; i < argv[1].len; i++) { |
340 | 127k | rdfs.alg_buf[i] = argv[1].s[i]; |
341 | 127k | if (rdfs.alg_buf[i] >= 'a') |
342 | 41.3k | rdfs.alg_buf[i] -= ('a' - 'A'); |
343 | 127k | } |
344 | 21.0k | rdfs.algorithm.len = argv[1].len; |
345 | 21.0k | rdfs.algorithm.s = rdfs.alg_buf; |
346 | 21.0k | rdfs.fingerprint = &argv[2]; |
347 | 21.0k | rdfs.ssrc = (argc == 4) ? &argv[3] : NULL; |
348 | 21.0k | rdfsp = &rdfs; |
349 | | /* Fallthrough */ |
350 | 22.2k | case RDG_CMD_D: |
351 | 22.2k | dtls_strmp = ctxp->strmp_in; |
352 | 22.2k | break; |
353 | | |
354 | 18.2k | case RDG_CMD_S: |
355 | 18.2k | rdfsp = NULL; |
356 | | /* Fallthrough */ |
357 | 19.4k | case RDG_CMD_U: |
358 | 19.4k | dtls_strmp = ctxp->strmp_out; |
359 | 19.4k | break; |
360 | 41.8k | } |
361 | | |
362 | 41.7k | struct packet_processor_if dtls_in_poi; |
363 | | |
364 | 41.7k | int lookup_res = CALL_SMETHOD(dtls_strmp->pproc_manager, lookup, pvt, &dtls_in_poi); |
365 | 41.7k | if (lookup_res != 0) { |
366 | 13.6k | rtps_c = dtls_in_poi.arg; |
367 | 13.6k | } |
368 | | |
369 | 41.7k | if (rdg_cmd == RDG_CMD_D || rdg_cmd == RDG_CMD_U) { |
370 | 2.49k | if (lookup_res == 0) { |
371 | 108 | return (-1); |
372 | 108 | } |
373 | 2.49k | CALL_SMETHOD(dtls_strmp->pproc_manager, unreg, pvt); |
374 | 2.39k | CALL_SMETHOD(dtls_strmp->pproc_manager->reverse, unreg, pvt + 1); |
375 | 2.39k | goto out; |
376 | 2.49k | } |
377 | | |
378 | 39.2k | if (lookup_res == 0) { |
379 | 28.0k | rtps_c = dtls_gw_data_ctor(pvt, dtls_strmp); |
380 | 28.0k | if (rtps_c == NULL) { |
381 | 0 | return (-1); |
382 | 0 | } |
383 | 28.0k | } |
384 | 39.2k | if (rdfsp != NULL && rdfs.peer_mode == RTPP_DTLS_PASSIVE) { |
385 | 8.36k | if (rtpp_dtls_gw_setup_sender(pvt, ctxp->sessp, dtls_strmp) != 0) { |
386 | 0 | goto e0; |
387 | 0 | } |
388 | 8.36k | } |
389 | 39.2k | my_mode = CALL_SMETHOD(rtps_c->dtls_conn, setmode, rdfsp); |
390 | 39.2k | if (my_mode == RTPP_DTLS_MODERR) { |
391 | 4.57k | goto e0; |
392 | 4.57k | } |
393 | 34.6k | if (lookup_res == 0) { |
394 | 23.6k | dtls_in_poi = (struct packet_processor_if){ |
395 | 23.6k | .descr = "dtls (srtp->rtp)", |
396 | 23.6k | .taste = rtpp_dtls_gw_taste_encrypted, |
397 | 23.6k | .enqueue = rtpp_dtls_gw_enqueue, |
398 | 23.6k | .key = pvt, |
399 | 23.6k | .arg = rtps_c, |
400 | 23.6k | .rcnt = rtps_c->rcnt |
401 | 23.6k | }; |
402 | 23.6k | if (CALL_SMETHOD(dtls_strmp->pproc_manager, reg, PPROC_ORD_DECRYPT, &dtls_in_poi) < 0) { |
403 | 0 | goto e0; |
404 | 0 | } |
405 | 23.6k | const struct packet_processor_if dtls_out_poi = { |
406 | 23.6k | .descr = "dtls (rtp->srtp)", |
407 | 23.6k | .taste = rtpp_dtls_gw_taste_plain, |
408 | 23.6k | .enqueue = rtpp_dtls_gw_enqueue, |
409 | 23.6k | .key = pvt + 1, |
410 | 23.6k | .arg = rtps_c, |
411 | 23.6k | .rcnt = rtps_c->rcnt |
412 | 23.6k | }; |
413 | 23.6k | if (CALL_SMETHOD(dtls_strmp->pproc_manager->reverse, reg, PPROC_ORD_ENCRYPT, &dtls_out_poi) < 0) { |
414 | 0 | goto e1; |
415 | 0 | } |
416 | 23.6k | } |
417 | 34.6k | if (rdfsp == NULL) { |
418 | 18.2k | rcp = ctxp->resp->buf_t; |
419 | 18.2k | rlen = sizeof(ctxp->resp->buf_t); |
420 | | |
421 | 18.2k | switch (my_mode) { |
422 | 9.00k | case RTPP_DTLS_ACTPASS: |
423 | 9.00k | strlcpy(rcp, "actpass ", rlen); |
424 | 9.00k | rcp += strlen("actpass "); |
425 | 9.00k | rlen -= strlen("actpass "); |
426 | 9.00k | break; |
427 | | |
428 | 72 | case RTPP_DTLS_ACTIVE: |
429 | 72 | strlcpy(rcp, "active ", rlen); |
430 | 72 | rcp += strlen("active "); |
431 | 72 | rlen -= strlen("active "); |
432 | 72 | break; |
433 | | |
434 | 9.12k | case RTPP_DTLS_PASSIVE: |
435 | 9.12k | strlcpy(rcp, "passive ", rlen); |
436 | 9.12k | rcp += strlen("passive "); |
437 | 9.12k | rlen -= strlen("passive "); |
438 | 9.12k | break; |
439 | | |
440 | 0 | default: |
441 | 0 | abort(); |
442 | 18.2k | } |
443 | | |
444 | 18.2k | strlcpy(rcp, pvt->dtls_ctx->fingerprint, rlen); |
445 | 18.2k | } |
446 | 37.0k | out: |
447 | 37.0k | RTPP_OBJ_DECREF(rtps_c); |
448 | 37.0k | return (0); |
449 | | |
450 | 122 | invalalg: |
451 | 122 | RTPP_LOG(pvt->mself->log, RTPP_LOG_ERR, "invalid algorithm: \"%s\"", |
452 | 122 | argv[1].s); |
453 | 122 | return (-1); |
454 | 1.09k | invalmode: |
455 | 1.09k | RTPP_LOG(pvt->mself->log, RTPP_LOG_ERR, "invalid mode: \"%s\"", |
456 | 1.09k | argv[0].s); |
457 | 1.09k | return (-1); |
458 | 0 | e1: |
459 | 0 | CALL_SMETHOD(dtls_strmp->pproc_manager, unreg, pvt); |
460 | 4.57k | e0: |
461 | 4.57k | RTPP_OBJ_DECREF(rtps_c); |
462 | 4.57k | return (-1); |
463 | 0 | } |
464 | | |
465 | | static int |
466 | | rtpp_dtls_gw_taste_encrypted(struct pkt_proc_ctx *pktxp) |
467 | 128k | { |
468 | 128k | struct dtls_gw_stream_cfg *rtps_c; |
469 | 128k | static __thread struct rtpp_dtls_gw_aux dtls_in = {.direction = DTLS_IN}; |
470 | 128k | static __thread struct rtpp_dtls_gw_aux strp_in = {.direction = SRTP_IN}; |
471 | 128k | struct rtpp_dtls_gw_aux *rdgap; |
472 | | |
473 | 128k | if (!rtpp_is_dtls_tst(pktxp)) |
474 | 93.0k | rdgap = &strp_in; |
475 | 35.6k | else |
476 | 35.6k | rdgap = &dtls_in; |
477 | 128k | rtps_c = pktxp->pproc->arg; |
478 | 128k | rdgap->dtls_conn = rtps_c->dtls_conn; |
479 | 128k | rdgap->mself = rtps_c->mself; |
480 | 128k | pktxp->auxp = rdgap; |
481 | 128k | return (1); |
482 | 128k | } |
483 | | |
484 | | static int |
485 | | rtpp_dtls_gw_taste_plain(struct pkt_proc_ctx *pktxp) |
486 | 171k | { |
487 | 171k | struct dtls_gw_stream_cfg *rtps_c; |
488 | 171k | static __thread struct rtpp_dtls_gw_aux rtp_out = {.direction = RTP_OUT}; |
489 | | |
490 | 171k | if (pktxp->strmp_out == NULL) |
491 | 0 | return (0); |
492 | 171k | rtps_c = pktxp->pproc->arg; |
493 | 171k | rtp_out.dtls_conn = rtps_c->dtls_conn; |
494 | 171k | rtp_out.mself = rtps_c->mself; |
495 | 171k | pktxp->auxp = &rtp_out; |
496 | 171k | return (1); |
497 | 171k | } |
498 | | |
499 | | static struct pproc_act |
500 | | rtpp_dtls_gw_enqueue(const struct pkt_proc_ctx *pktxp) |
501 | 300k | { |
502 | 300k | struct rtpp_dtls_gw_aux *edata; |
503 | 300k | struct rtpp_wi *wi; |
504 | 300k | struct wipkt *wip; |
505 | | |
506 | 300k | edata = (struct rtpp_dtls_gw_aux *)pktxp->auxp; |
507 | 300k | wi = rtpp_wi_malloc_udata((void **)&wip, sizeof(struct wipkt)); |
508 | 300k | if (wi == NULL) |
509 | 0 | return (PPROC_ACT_DROP); |
510 | 300k | wip->edata = *edata; |
511 | 300k | RTPP_OBJ_BORROW(wi, edata->dtls_conn); |
512 | 300k | wip->pktx = *pktxp; |
513 | 300k | wip->pktx.rsp = NULL; |
514 | 300k | RTPP_OBJ_BORROW(wi, pktxp->strmp_in); |
515 | 300k | if (pktxp->strmp_out != NULL) |
516 | 300k | RTPP_OBJ_BORROW(wi, pktxp->strmp_out); |
517 | 300k | if (rtpp_queue_put_item(wi, edata->mself->wthr.mod_q) != 0) { |
518 | 3.14k | RTPP_OBJ_DECREF(wi); |
519 | 3.14k | return (PPROC_ACT_DROP); |
520 | 3.14k | } |
521 | | |
522 | 297k | return (PPROC_ACT_TAKE); |
523 | 300k | } |
524 | | |
525 | | static struct rtpp_module_priv * |
526 | | rtpp_dtls_gw_ctor(const struct rtpp_cfg *cfsp, struct rtpp_minfo *mself) |
527 | 4 | { |
528 | 4 | struct rtpp_module_priv *pvt; |
529 | 4 | static int srtp_inited = 0; |
530 | | |
531 | 4 | pvt = mod_zmalloc(sizeof(struct rtpp_module_priv)); |
532 | 4 | if (pvt == NULL) { |
533 | 0 | goto e0; |
534 | 0 | } |
535 | 4 | pvt->dtls_ctx = rtpp_dtls_ctor(cfsp, mself); |
536 | 4 | if (pvt->dtls_ctx == NULL) { |
537 | 0 | goto e1; |
538 | 0 | } |
539 | 4 | if (!srtp_inited && srtp_init() != 0) { |
540 | 0 | goto e2; |
541 | 0 | } |
542 | 4 | srtp_inited = 1; |
543 | 4 | pvt->cfsp = cfsp; |
544 | 4 | pvt->mself = mself; |
545 | 4 | return (pvt); |
546 | 0 | e2: |
547 | 0 | RTPP_OBJ_DECREF(pvt->dtls_ctx); |
548 | 0 | e1: |
549 | 0 | mod_free(pvt); |
550 | 0 | e0: |
551 | 0 | return (NULL); |
552 | 0 | } |
553 | | |
554 | | static void |
555 | | rtpp_dtls_gw_dtor(struct rtpp_module_priv *pvt) |
556 | 4 | { |
557 | | |
558 | 4 | srtp_shutdown(); |
559 | 4 | RTPP_OBJ_DECREF(pvt->dtls_ctx); |
560 | 4 | mod_free(pvt); |
561 | 4 | return; |
562 | 4 | } |