Coverage Report

Created: 2025-07-18 07:10

/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
}