/src/rtpproxy/modules/dtls_gw/rtpp_dtls_gw.c
Line | Count | Source |
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 "rtpp_bindaddr.h" |
78 | | #include "advanced/packet_processor.h" |
79 | | #include "advanced/pproc_manager.h" |
80 | | |
81 | | #include "rtpp_dtls.h" |
82 | | #include "rtpp_dtls_util.h" |
83 | | #include "rtpp_dtls_conn.h" |
84 | | |
85 | | struct rtpp_module_priv { |
86 | | struct rtpp_dtls *dtls_ctx; |
87 | | const struct rtpp_cfg *cfsp; |
88 | | struct rtpp_minfo *mself; |
89 | | }; |
90 | | |
91 | | struct dtls_gw_stream_cfg { |
92 | | struct rtpp_refcnt *rcnt; |
93 | | struct rtpp_dtls_conn *dtls_conn; |
94 | | struct rtpp_minfo *mself; |
95 | | }; |
96 | | |
97 | | enum rtpp_dtls_dir { |
98 | | DTLS_IN, SRTP_IN, RTP_OUT |
99 | | }; |
100 | | |
101 | | struct rtpp_dtls_gw_aux { |
102 | | enum rtpp_dtls_dir direction; |
103 | | struct rtpp_dtls_conn *dtls_conn; |
104 | | struct rtpp_minfo *mself; |
105 | | }; |
106 | | |
107 | | struct wipkt { |
108 | | struct pkt_proc_ctx pktx; |
109 | | struct rtpp_dtls_gw_aux edata; |
110 | | }; |
111 | | |
112 | | static struct rtpp_module_priv *rtpp_dtls_gw_ctor(const struct rtpp_cfg *, |
113 | | struct rtpp_minfo *); |
114 | | static void rtpp_dtls_gw_dtor(struct rtpp_module_priv *); |
115 | | static void rtpp_dtls_gw_worker(const struct rtpp_wthrdata *); |
116 | | static int rtpp_dtls_gw_handle_command(struct rtpp_module_priv *, |
117 | | const struct rtpp_subc_ctx *); |
118 | | static int rtpp_dtls_gw_taste_encrypted(struct pkt_proc_ctx *); |
119 | | static int rtpp_dtls_gw_taste_plain(struct pkt_proc_ctx *); |
120 | | static struct pproc_act rtpp_dtls_gw_enqueue(const struct pkt_proc_ctx *); |
121 | | |
122 | | #ifdef RTPP_CHECK_LEAKS |
123 | | #include "rtpp_memdeb_internal.h" |
124 | | |
125 | | RTPP_MEMDEB_APP_STATIC; |
126 | | #endif |
127 | | |
128 | | const struct rtpp_minfo RTPP_MOD_SELF = { |
129 | | .descr.name = "dtls_gw", |
130 | | .descr.ver = MI_VER_INIT(), |
131 | | .descr.module_id = 4, |
132 | | .proc.ctor = rtpp_dtls_gw_ctor, |
133 | | .proc.dtor = rtpp_dtls_gw_dtor, |
134 | | .wapi = &(const struct rtpp_wthr_handlers){ |
135 | | .main_thread = rtpp_dtls_gw_worker, |
136 | | .queue_size = RTPQ_MEDIUM_CB_LEN, |
137 | | }, |
138 | | .capi = &(const struct rtpp_cplane_handlers){.ul_subc_handle = rtpp_dtls_gw_handle_command}, |
139 | | .fn = &(struct rtpp_minfo_fset){0}, |
140 | | #ifdef RTPP_CHECK_LEAKS |
141 | | .memdeb_p = &MEMDEB_SYM |
142 | | #endif |
143 | | }; |
144 | | #if defined(LIBRTPPROXY) |
145 | | DATA_SET(rtpp_modules, RTPP_MOD_SELF); |
146 | | #endif |
147 | | |
148 | | static void |
149 | | rtpp_dtls_gw_worker(const struct rtpp_wthrdata *wp) |
150 | 4 | { |
151 | 4 | struct rtpp_wi *wi; |
152 | 4 | struct wipkt *wip; |
153 | 4 | struct res_loc res; |
154 | | |
155 | 384k | for (;;) { |
156 | 384k | wi = rtpp_queue_get_item(wp->mod_q, 0); |
157 | 384k | if (wi == wp->sigterm) { |
158 | 4 | RTPP_OBJ_DECREF(wi); |
159 | 4 | break; |
160 | 4 | } |
161 | 384k | wip = rtpp_wi_data_get_ptr(wi, sizeof(*wip), sizeof(*wip)); |
162 | 384k | struct rtpp_dtls_gw_aux *edp = &wip->edata; |
163 | 384k | switch (edp->direction) { |
164 | 63.5k | case DTLS_IN: |
165 | | #if 0 |
166 | | RTPP_LOG(edp->mself->log, RTPP_LOG_DBUG, "Packet from DTLS"); |
167 | | #endif |
168 | 63.5k | CALL_SMETHOD(edp->dtls_conn, dtls_recv, wip->pktx.pktp); |
169 | 63.5k | res = RES_HERE(1); |
170 | 63.5k | break; |
171 | 100k | case SRTP_IN: |
172 | | #if 0 |
173 | | RTPP_LOG(RTPP_MOD_SELF.log, RTPP_LOG_DBUG, "DTLS: packet SRTP->RTP"); |
174 | | #endif |
175 | 100k | res = CALL_SMETHOD(edp->dtls_conn, srtp_recv, &wip->pktx); |
176 | 100k | break; |
177 | 220k | case RTP_OUT: |
178 | | #if 0 |
179 | | RTPP_LOG(RTPP_MOD_SELF.log, RTPP_LOG_DBUG, "DTLS: packet RTP->SRTP"); |
180 | | #endif |
181 | 220k | res = CALL_SMETHOD(edp->dtls_conn, rtp_send, &wip->pktx); |
182 | 220k | break; |
183 | 0 | default: |
184 | 0 | abort(); |
185 | 384k | } |
186 | 384k | if (res.v != 0) { |
187 | 384k | switch (edp->direction) { |
188 | 63.5k | case DTLS_IN: |
189 | 63.5k | break; |
190 | 100k | case SRTP_IN: |
191 | 100k | CALL_SMETHOD(wip->pktx.strmp_in->pcnt_strm, reg_pktin, wip->pktx.pktp); |
192 | | /* Fallthrouth */ |
193 | 320k | case RTP_OUT: |
194 | 320k | CALL_SMETHOD(wip->pktx.strmp_in->pcount, reg_drop, res.loc); |
195 | 320k | CALL_SMETHOD(wip->pktx.strmp_in->pproc_manager, reg_drop); |
196 | 320k | break; |
197 | 384k | } |
198 | 384k | RTPP_OBJ_DECREF(wip->pktx.pktp); |
199 | 384k | } |
200 | 384k | RTPP_OBJ_DECREF(wi); |
201 | 384k | } |
202 | 4 | } |
203 | | |
204 | | static struct dtls_gw_stream_cfg * |
205 | | dtls_gw_data_ctor(struct rtpp_module_priv *pvt, struct rtpp_stream *dtls_strmp) |
206 | 30.9k | { |
207 | 30.9k | struct dtls_gw_stream_cfg *rtps_c; |
208 | | |
209 | 30.9k | rtps_c = mod_rzmalloc(sizeof(*rtps_c), offsetof(struct dtls_gw_stream_cfg, rcnt)); |
210 | 30.9k | if (rtps_c == NULL) { |
211 | 0 | goto e0; |
212 | 0 | } |
213 | 30.9k | rtps_c->dtls_conn = CALL_METHOD(pvt->dtls_ctx, newconn, dtls_strmp); |
214 | 30.9k | if (rtps_c->dtls_conn == NULL) { |
215 | 0 | goto e1; |
216 | 0 | } |
217 | 30.9k | rtps_c->mself = pvt->mself; |
218 | 30.9k | RC_INCREF(pvt->mself->super_rcnt); |
219 | 30.9k | RTPP_OBJ_DTOR_ATTACH_RC_s(rtps_c, pvt->mself->super_rcnt); |
220 | 30.9k | RTPP_OBJ_DTOR_ATTACH_RC_s(rtps_c, rtps_c->dtls_conn->rcnt); |
221 | 30.9k | RTPP_OBJ_DTOR_ATTACH_s(rtps_c, GET_SMETHOD(rtps_c->dtls_conn, godead), |
222 | 30.9k | rtps_c->dtls_conn); |
223 | 30.9k | rtps_c->mself = pvt->mself; |
224 | 30.9k | return (rtps_c); |
225 | 0 | e1: |
226 | 0 | mod_free(rtps_c); |
227 | 0 | e0: |
228 | 0 | return (NULL); |
229 | 0 | } |
230 | | |
231 | | static int |
232 | | rtpp_dtls_gw_setup_sender(struct rtpp_module_priv *pvt, |
233 | | struct rtpp_session *spa, struct rtpp_stream *dtls_strmp) |
234 | 8.90k | { |
235 | 8.90k | int sidx, lport; |
236 | 8.90k | struct rtpp_socket *fd, *fds[2]; |
237 | | |
238 | 8.90k | fd = CALL_SMETHOD(dtls_strmp, get_skt, HEREVAL); |
239 | 8.90k | if (fd != NULL) { |
240 | 1.17k | RTPP_OBJ_DECREF(fd); |
241 | 1.17k | return (0); |
242 | 1.17k | } |
243 | | |
244 | 7.72k | if (spa->rtp->stream[0] == dtls_strmp) { |
245 | 0 | sidx = 0; |
246 | 7.72k | } else if (spa->rtp->stream[1] == dtls_strmp) { |
247 | 7.72k | sidx = 1; |
248 | 7.72k | } else { |
249 | 0 | abort(); |
250 | 0 | } |
251 | | |
252 | 7.72k | if (rtpp_create_listener(pvt->cfsp, dtls_strmp->laddr->addr, &lport, fds, |
253 | 7.72k | dtls_strmp->tos) == -1) |
254 | 66 | return (-1); |
255 | 7.72k | CALL_SMETHOD(pvt->cfsp->sessinfo, append, spa, sidx, fds); |
256 | 7.65k | CALL_METHOD(pvt->cfsp->rtpp_proc_cf, nudge); |
257 | 7.65k | RTPP_OBJ_DECREF(fds[0]); |
258 | 7.65k | RTPP_OBJ_DECREF(fds[1]); |
259 | 7.65k | dtls_strmp->port = lport; |
260 | 7.65k | spa->rtcp->stream[sidx]->port = lport + 1; |
261 | 7.65k | if (spa->complete == 0) { |
262 | 7.59k | CALL_SMETHOD(pvt->cfsp->rtpp_stats, updatebyname, "nsess_complete", 1); |
263 | 7.59k | CALL_SMETHOD(spa->rtp->stream[0]->ttl, reset_with, |
264 | 7.59k | pvt->cfsp->max_ttl); |
265 | 7.59k | CALL_SMETHOD(spa->rtp->stream[1]->ttl, reset_with, |
266 | 7.59k | pvt->cfsp->max_ttl); |
267 | 7.59k | } |
268 | 7.65k | spa->complete = 1; |
269 | 7.65k | return (0); |
270 | 7.72k | } |
271 | | |
272 | | enum rdg_cmd {RDG_CMD_A, RDG_CMD_P, RDG_CMD_S, RDG_CMD_D, RDG_CMD_U}; |
273 | | |
274 | | static int |
275 | | rtpp_dtls_gw_handle_command(struct rtpp_module_priv *pvt, |
276 | | const struct rtpp_subc_ctx *ctxp) |
277 | 48.3k | { |
278 | 48.3k | struct dtls_gw_stream_cfg *rtps_c; |
279 | 48.3k | enum rtpp_dtls_mode my_mode; |
280 | 48.3k | struct rdc_peer_spec rdfs, *rdfsp; |
281 | 48.3k | const rtpp_str_t * argv = rtpp_str_fix(&ctxp->subc_args->v[1]); |
282 | 48.3k | int argc = ctxp->subc_args->c - 1; |
283 | 48.3k | struct rtpp_stream *dtls_strmp; |
284 | 48.3k | int rlen; |
285 | 48.3k | char *rcp; |
286 | 48.3k | enum rdg_cmd rdg_cmd; |
287 | | |
288 | 48.3k | if (argc != 1 && argc != 3 && argc != 4) { |
289 | 532 | RTPP_LOG(pvt->mself->log, RTPP_LOG_ERR, "expected 1, 3 or 4 parameters: %d", |
290 | 532 | argc); |
291 | 532 | return (-1); |
292 | 532 | } |
293 | | |
294 | 47.8k | switch (argv[0].s[0] | argv[0].s[1]) { |
295 | 3.85k | case 'a': |
296 | 15.1k | case 'A': |
297 | 15.1k | if (argc != 3 && argc != 4) |
298 | 208 | goto invalmode; |
299 | 14.8k | rdfs.peer_mode = RTPP_DTLS_ACTIVE; |
300 | 14.8k | rdg_cmd = RDG_CMD_A; |
301 | 14.8k | break; |
302 | | |
303 | 3.44k | case 'p': |
304 | 9.27k | case 'P': |
305 | 9.27k | if (argc != 3 && argc != 4) |
306 | 330 | goto invalmode; |
307 | 8.94k | rdfs.peer_mode = RTPP_DTLS_PASSIVE; |
308 | 8.94k | rdg_cmd = RDG_CMD_P; |
309 | 8.94k | break; |
310 | | |
311 | 2.40k | case 's': |
312 | 19.9k | case 'S': |
313 | 19.9k | if (argc != 1) |
314 | 85 | goto invalmode; |
315 | 19.8k | rdg_cmd = RDG_CMD_S; |
316 | 19.8k | break; |
317 | | |
318 | 1.18k | case 'd': |
319 | 1.44k | case 'D': |
320 | 1.44k | if (argc != 1) |
321 | 82 | goto invalmode; |
322 | 1.36k | rdg_cmd = RDG_CMD_D; |
323 | 1.36k | break; |
324 | | |
325 | 1.37k | case 'u': |
326 | 1.73k | case 'U': |
327 | 1.73k | if (argc != 1) |
328 | 297 | goto invalmode; |
329 | 1.43k | rdg_cmd = RDG_CMD_U; |
330 | 1.43k | break; |
331 | | |
332 | 310 | default: |
333 | 310 | goto invalmode; |
334 | 47.8k | } |
335 | | |
336 | 46.4k | switch (rdg_cmd) { |
337 | 14.8k | case RDG_CMD_A: |
338 | 23.8k | case RDG_CMD_P: |
339 | 23.8k | if (argv[1].len > sizeof(rdfs.alg_buf)) |
340 | 101 | goto invalalg; |
341 | 167k | for (int i = 0; i < argv[1].len; i++) { |
342 | 144k | rdfs.alg_buf[i] = argv[1].s[i]; |
343 | 144k | if (rdfs.alg_buf[i] >= 'a') |
344 | 48.3k | rdfs.alg_buf[i] -= ('a' - 'A'); |
345 | 144k | } |
346 | 23.7k | rdfs.algorithm.len = argv[1].len; |
347 | 23.7k | rdfs.algorithm.s = rdfs.alg_buf; |
348 | 23.7k | rdfs.fingerprint = &argv[2]; |
349 | 23.7k | rdfs.ssrc = (argc == 4) ? &argv[3] : NULL; |
350 | 23.7k | rdfsp = &rdfs; |
351 | | /* Fallthrough */ |
352 | 25.0k | case RDG_CMD_D: |
353 | 25.0k | dtls_strmp = ctxp->env->strmp_in; |
354 | 25.0k | break; |
355 | | |
356 | 19.8k | case RDG_CMD_S: |
357 | 19.8k | rdfsp = NULL; |
358 | | /* Fallthrough */ |
359 | 21.2k | case RDG_CMD_U: |
360 | 21.2k | dtls_strmp = ctxp->env->strmp_out; |
361 | 21.2k | break; |
362 | 46.4k | } |
363 | | |
364 | 46.3k | struct packet_processor_if dtls_in_poi; |
365 | | |
366 | 46.3k | int lookup_res = CALL_SMETHOD(dtls_strmp->pproc_manager, lookup, pvt, &dtls_in_poi); |
367 | 46.3k | if (lookup_res != 0) { |
368 | 15.1k | rtps_c = dtls_in_poi.arg; |
369 | 15.1k | } |
370 | | |
371 | 46.3k | if (rdg_cmd == RDG_CMD_D || rdg_cmd == RDG_CMD_U) { |
372 | 2.80k | if (lookup_res == 0) { |
373 | 305 | return (-1); |
374 | 305 | } |
375 | 2.80k | CALL_SMETHOD(dtls_strmp->pproc_manager, unreg, pvt); |
376 | 2.49k | CALL_SMETHOD(dtls_strmp->pproc_manager->reverse, unreg, pvt + 1); |
377 | 2.49k | goto out; |
378 | 2.80k | } |
379 | | |
380 | 43.5k | if (lookup_res == 0) { |
381 | 30.9k | rtps_c = dtls_gw_data_ctor(pvt, dtls_strmp); |
382 | 30.9k | if (rtps_c == NULL) { |
383 | 0 | return (-1); |
384 | 0 | } |
385 | 30.9k | } |
386 | 43.5k | if (rdfsp != NULL && rdfs.peer_mode == RTPP_DTLS_PASSIVE) { |
387 | 8.90k | if (rtpp_dtls_gw_setup_sender(pvt, ctxp->env->sessp, dtls_strmp) != 0) { |
388 | 66 | goto e0; |
389 | 66 | } |
390 | 8.90k | } |
391 | 43.5k | my_mode = CALL_SMETHOD(rtps_c->dtls_conn, setmode, rdfsp); |
392 | 43.5k | if (my_mode == RTPP_DTLS_MODERR) { |
393 | 5.26k | goto e0; |
394 | 5.26k | } |
395 | 38.2k | if (lookup_res == 0) { |
396 | 25.7k | dtls_in_poi = (struct packet_processor_if){ |
397 | 25.7k | .descr = "dtls (srtp->rtp)", |
398 | 25.7k | .taste = rtpp_dtls_gw_taste_encrypted, |
399 | 25.7k | .enqueue = rtpp_dtls_gw_enqueue, |
400 | 25.7k | .key = pvt, |
401 | 25.7k | .arg = rtps_c, |
402 | 25.7k | .rcnt = rtps_c->rcnt |
403 | 25.7k | }; |
404 | 25.7k | if (CALL_SMETHOD(dtls_strmp->pproc_manager, reg, PPROC_ORD_DECRYPT, &dtls_in_poi) < 0) { |
405 | 0 | goto e0; |
406 | 0 | } |
407 | 25.7k | const struct packet_processor_if dtls_out_poi = { |
408 | 25.7k | .descr = "dtls (rtp->srtp)", |
409 | 25.7k | .taste = rtpp_dtls_gw_taste_plain, |
410 | 25.7k | .enqueue = rtpp_dtls_gw_enqueue, |
411 | 25.7k | .key = pvt + 1, |
412 | 25.7k | .arg = rtps_c, |
413 | 25.7k | .rcnt = rtps_c->rcnt |
414 | 25.7k | }; |
415 | 25.7k | if (CALL_SMETHOD(dtls_strmp->pproc_manager->reverse, reg, PPROC_ORD_ENCRYPT, &dtls_out_poi) < 0) { |
416 | 0 | goto e1; |
417 | 0 | } |
418 | 25.7k | } |
419 | 38.2k | if (rdfsp == NULL) { |
420 | 19.8k | rcp = ctxp->resp->buf_t; |
421 | 19.8k | rlen = sizeof(ctxp->resp->buf_t); |
422 | | |
423 | 19.8k | switch (my_mode) { |
424 | 9.07k | case RTPP_DTLS_ACTPASS: |
425 | 9.07k | strlcpy(rcp, "actpass ", rlen); |
426 | 9.07k | rcp += strlen("actpass "); |
427 | 9.07k | rlen -= strlen("actpass "); |
428 | 9.07k | break; |
429 | | |
430 | 35 | case RTPP_DTLS_ACTIVE: |
431 | 35 | strlcpy(rcp, "active ", rlen); |
432 | 35 | rcp += strlen("active "); |
433 | 35 | rlen -= strlen("active "); |
434 | 35 | break; |
435 | | |
436 | 10.7k | case RTPP_DTLS_PASSIVE: |
437 | 10.7k | strlcpy(rcp, "passive ", rlen); |
438 | 10.7k | rcp += strlen("passive "); |
439 | 10.7k | rlen -= strlen("passive "); |
440 | 10.7k | break; |
441 | | |
442 | 0 | default: |
443 | 0 | abort(); |
444 | 19.8k | } |
445 | | |
446 | 19.8k | strlcpy(rcp, pvt->dtls_ctx->fingerprint, rlen); |
447 | 19.8k | } |
448 | 40.7k | out: |
449 | 40.7k | RTPP_OBJ_DECREF(rtps_c); |
450 | 40.7k | return (0); |
451 | | |
452 | 101 | invalalg: |
453 | 101 | RTPP_LOG(pvt->mself->log, RTPP_LOG_ERR, "invalid algorithm: \"%s\"", |
454 | 101 | argv[1].s); |
455 | 101 | return (-1); |
456 | 1.31k | invalmode: |
457 | 1.31k | RTPP_LOG(pvt->mself->log, RTPP_LOG_ERR, "invalid mode: \"%s\"", |
458 | 1.31k | argv[0].s); |
459 | 1.31k | return (-1); |
460 | 0 | e1: |
461 | 0 | CALL_SMETHOD(dtls_strmp->pproc_manager, unreg, pvt); |
462 | 5.33k | e0: |
463 | 5.33k | RTPP_OBJ_DECREF(rtps_c); |
464 | 5.33k | return (-1); |
465 | 0 | } |
466 | | |
467 | | static int |
468 | | rtpp_dtls_gw_taste_encrypted(struct pkt_proc_ctx *pktxp) |
469 | 172k | { |
470 | 172k | struct dtls_gw_stream_cfg *rtps_c; |
471 | 172k | static __thread struct rtpp_dtls_gw_aux dtls_in = {.direction = DTLS_IN}; |
472 | 172k | static __thread struct rtpp_dtls_gw_aux strp_in = {.direction = SRTP_IN}; |
473 | 172k | struct rtpp_dtls_gw_aux *rdgap; |
474 | | |
475 | 172k | if (!rtpp_is_dtls_tst(pktxp)) |
476 | 103k | rdgap = &strp_in; |
477 | 69.2k | else |
478 | 69.2k | rdgap = &dtls_in; |
479 | 172k | rtps_c = pktxp->pproc->arg; |
480 | 172k | rdgap->dtls_conn = rtps_c->dtls_conn; |
481 | 172k | rdgap->mself = rtps_c->mself; |
482 | 172k | pktxp->auxp = rdgap; |
483 | 172k | return (1); |
484 | 172k | } |
485 | | |
486 | | static int |
487 | | rtpp_dtls_gw_taste_plain(struct pkt_proc_ctx *pktxp) |
488 | 229k | { |
489 | 229k | struct dtls_gw_stream_cfg *rtps_c; |
490 | 229k | static __thread struct rtpp_dtls_gw_aux rtp_out = {.direction = RTP_OUT}; |
491 | | |
492 | 229k | if (pktxp->strmp_out == NULL) |
493 | 0 | return (0); |
494 | 229k | rtps_c = pktxp->pproc->arg; |
495 | 229k | rtp_out.dtls_conn = rtps_c->dtls_conn; |
496 | 229k | rtp_out.mself = rtps_c->mself; |
497 | 229k | pktxp->auxp = &rtp_out; |
498 | 229k | return (1); |
499 | 229k | } |
500 | | |
501 | | static struct pproc_act |
502 | | rtpp_dtls_gw_enqueue(const struct pkt_proc_ctx *pktxp) |
503 | 402k | { |
504 | 402k | struct rtpp_dtls_gw_aux *edata; |
505 | 402k | struct rtpp_wi *wi; |
506 | 402k | struct wipkt *wip; |
507 | | |
508 | 402k | edata = (struct rtpp_dtls_gw_aux *)pktxp->auxp; |
509 | 402k | wi = rtpp_wi_malloc_udata((void **)&wip, sizeof(struct wipkt)); |
510 | 402k | if (wi == NULL) |
511 | 0 | return (PPROC_ACT_DROP); |
512 | 402k | wip->edata = *edata; |
513 | 402k | RTPP_OBJ_BORROW_s(wi, edata->dtls_conn); |
514 | 402k | wip->pktx = *pktxp; |
515 | 402k | wip->pktx.rsp = NULL; |
516 | 402k | RTPP_OBJ_BORROW_s(wi, pktxp->strmp_in); |
517 | 402k | if (pktxp->strmp_out != NULL) |
518 | 402k | RTPP_OBJ_BORROW_s(wi, pktxp->strmp_out); |
519 | 402k | if (rtpp_queue_put_item(wi, edata->mself->wthr.mod_q) != 0) { |
520 | 18.0k | RTPP_OBJ_DECREF(wi); |
521 | 18.0k | return (PPROC_ACT_DROP); |
522 | 18.0k | } |
523 | | |
524 | 384k | return (PPROC_ACT_TAKE); |
525 | 402k | } |
526 | | |
527 | | static struct rtpp_module_priv * |
528 | | rtpp_dtls_gw_ctor(const struct rtpp_cfg *cfsp, struct rtpp_minfo *mself) |
529 | 4 | { |
530 | 4 | struct rtpp_module_priv *pvt; |
531 | 4 | static int srtp_inited = 0; |
532 | | |
533 | 4 | pvt = mod_zmalloc(sizeof(struct rtpp_module_priv)); |
534 | 4 | if (pvt == NULL) { |
535 | 0 | goto e0; |
536 | 0 | } |
537 | 4 | pvt->dtls_ctx = rtpp_dtls_ctor(cfsp, mself); |
538 | 4 | if (pvt->dtls_ctx == NULL) { |
539 | 0 | goto e1; |
540 | 0 | } |
541 | 4 | if (!srtp_inited && srtp_init() != 0) { |
542 | 0 | goto e2; |
543 | 0 | } |
544 | 4 | srtp_inited = 1; |
545 | 4 | pvt->cfsp = cfsp; |
546 | 4 | pvt->mself = mself; |
547 | 4 | return (pvt); |
548 | 0 | e2: |
549 | 0 | RTPP_OBJ_DECREF(pvt->dtls_ctx); |
550 | 0 | e1: |
551 | 0 | mod_free(pvt); |
552 | 0 | e0: |
553 | 0 | return (NULL); |
554 | 0 | } |
555 | | |
556 | | static void |
557 | | rtpp_dtls_gw_dtor(struct rtpp_module_priv *pvt) |
558 | 4 | { |
559 | | |
560 | 4 | srtp_shutdown(); |
561 | 4 | RTPP_OBJ_DECREF(pvt->dtls_ctx); |
562 | 4 | mod_free(pvt); |
563 | 4 | return; |
564 | 4 | } |