Coverage Report

Created: 2026-05-30 06:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}