Coverage Report

Created: 2026-01-17 07:03

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 "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
314k
    for (;;) {
155
314k
        wi = rtpp_queue_get_item(wp->mod_q, 0);
156
314k
        if (wi == wp->sigterm) {
157
4
            RTPP_OBJ_DECREF(wi);
158
4
            break;
159
4
        }
160
314k
        wip = rtpp_wi_data_get_ptr(wi, sizeof(*wip), sizeof(*wip));
161
314k
        struct rtpp_dtls_gw_aux *edp = &wip->edata;
162
314k
        switch (edp->direction) {
163
37.1k
        case DTLS_IN:
164
#if 0
165
            RTPP_LOG(edp->mself->log, RTPP_LOG_DBUG, "Packet from DTLS");
166
#endif
167
37.1k
            CALL_SMETHOD(edp->dtls_conn, dtls_recv, wip->pktx.pktp);
168
37.1k
            res = RES_HERE(1);
169
37.1k
            break;
170
97.7k
        case SRTP_IN:
171
#if 0
172
            RTPP_LOG(RTPP_MOD_SELF.log, RTPP_LOG_DBUG, "DTLS: packet SRTP->RTP");
173
#endif
174
97.7k
            res = CALL_SMETHOD(edp->dtls_conn, srtp_recv, &wip->pktx);
175
97.7k
            break;
176
179k
        case RTP_OUT:
177
#if 0
178
            RTPP_LOG(RTPP_MOD_SELF.log, RTPP_LOG_DBUG, "DTLS: packet RTP->SRTP");
179
#endif
180
179k
            res = CALL_SMETHOD(edp->dtls_conn, rtp_send, &wip->pktx);
181
179k
            break;
182
0
        default:
183
0
            abort();
184
314k
        }
185
314k
        if (res.v != 0) {
186
314k
            switch (edp->direction) {
187
37.1k
            case DTLS_IN:
188
37.1k
                break;
189
97.7k
            case SRTP_IN:
190
97.7k
                CALL_SMETHOD(wip->pktx.strmp_in->pcnt_strm, reg_pktin, wip->pktx.pktp);
191
                /* Fallthrouth */
192
277k
            case RTP_OUT:
193
277k
                CALL_SMETHOD(wip->pktx.strmp_in->pcount, reg_drop, res.loc);
194
277k
                CALL_SMETHOD(wip->pktx.strmp_in->pproc_manager, reg_drop);
195
277k
                break;
196
314k
            }
197
314k
            RTPP_OBJ_DECREF(wip->pktx.pktp);
198
314k
        }
199
314k
        RTPP_OBJ_DECREF(wi);
200
314k
    }
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
30.4k
{
206
30.4k
    struct dtls_gw_stream_cfg *rtps_c;
207
208
30.4k
    rtps_c = mod_rzmalloc(sizeof(*rtps_c), offsetof(struct dtls_gw_stream_cfg, rcnt));
209
30.4k
    if (rtps_c == NULL) {
210
0
        goto e0;
211
0
    }
212
30.4k
    rtps_c->dtls_conn = CALL_METHOD(pvt->dtls_ctx, newconn, dtls_strmp);
213
30.4k
    if (rtps_c->dtls_conn == NULL) {
214
0
        goto e1;
215
0
    }
216
30.4k
    rtps_c->mself = pvt->mself;
217
30.4k
    RC_INCREF(pvt->mself->super_rcnt);
218
30.4k
    RTPP_OBJ_DTOR_ATTACH_RC(rtps_c, pvt->mself->super_rcnt);
219
30.4k
    RTPP_OBJ_DTOR_ATTACH_RC(rtps_c, rtps_c->dtls_conn->rcnt);
220
30.4k
    RTPP_OBJ_DTOR_ATTACH(rtps_c, GET_SMETHOD(rtps_c->dtls_conn, godead),
221
30.4k
      rtps_c->dtls_conn);
222
30.4k
    rtps_c->mself = pvt->mself;
223
30.4k
    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.61k
{
234
8.61k
    int sidx, lport;
235
8.61k
    struct rtpp_socket *fd, *fds[2];
236
237
8.61k
    fd = CALL_SMETHOD(dtls_strmp, get_skt, HEREVAL);
238
8.61k
    if (fd != NULL) {
239
1.01k
        RTPP_OBJ_DECREF(fd);
240
1.01k
        return (0);
241
1.01k
    }
242
243
7.60k
    if (spa->rtp->stream[0] == dtls_strmp) {
244
0
        sidx = 0;
245
7.60k
    } else if (spa->rtp->stream[1] == dtls_strmp) {
246
7.60k
        sidx = 1;
247
7.60k
    } else {
248
0
        abort();
249
0
    }
250
251
7.60k
    if (rtpp_create_listener(pvt->cfsp, dtls_strmp->laddr, &lport, fds) == -1)
252
34
        return (-1);
253
7.60k
    CALL_SMETHOD(pvt->cfsp->sessinfo, append, spa, sidx, fds);
254
7.57k
    CALL_METHOD(pvt->cfsp->rtpp_proc_cf, nudge);
255
7.57k
    RTPP_OBJ_DECREF(fds[0]);
256
7.57k
    RTPP_OBJ_DECREF(fds[1]);
257
7.57k
    dtls_strmp->port = lport;
258
7.57k
    spa->rtcp->stream[sidx]->port = lport + 1;
259
7.57k
    if (spa->complete == 0) {
260
7.50k
        CALL_SMETHOD(pvt->cfsp->rtpp_stats, updatebyname, "nsess_complete", 1);
261
7.50k
        CALL_SMETHOD(spa->rtp->stream[0]->ttl, reset_with,
262
7.50k
          pvt->cfsp->max_ttl);
263
7.50k
        CALL_SMETHOD(spa->rtp->stream[1]->ttl, reset_with,
264
7.50k
          pvt->cfsp->max_ttl);
265
7.50k
    }
266
7.57k
    spa->complete = 1;
267
7.57k
    return (0);
268
7.60k
}
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
47.6k
{
276
47.6k
    struct dtls_gw_stream_cfg *rtps_c;
277
47.6k
    enum rtpp_dtls_mode my_mode;
278
47.6k
    struct rdc_peer_spec rdfs, *rdfsp;
279
47.6k
    const rtpp_str_t * argv = rtpp_str_fix(&ctxp->subc_args->v[1]);
280
47.6k
    int argc = ctxp->subc_args->c - 1;
281
47.6k
    struct rtpp_stream *dtls_strmp;
282
47.6k
    int rlen;
283
47.6k
    char *rcp;
284
47.6k
    enum rdg_cmd rdg_cmd;
285
286
47.6k
    if (argc != 1 && argc != 3 && argc != 4) {
287
665
        RTPP_LOG(pvt->mself->log, RTPP_LOG_ERR, "expected 1, 3 or 4 parameters: %d",
288
665
          argc);
289
665
        return (-1);
290
665
    }
291
292
46.9k
    switch (argv[0].s[0] | argv[0].s[1]) {
293
4.34k
    case 'a':
294
15.1k
    case 'A':
295
15.1k
        if (argc != 3 && argc != 4)
296
219
            goto invalmode;
297
14.9k
        rdfs.peer_mode = RTPP_DTLS_ACTIVE;
298
14.9k
        rdg_cmd = RDG_CMD_A;
299
14.9k
        break;
300
301
3.49k
    case 'p':
302
8.84k
    case 'P':
303
8.84k
        if (argc != 3 && argc != 4)
304
212
            goto invalmode;
305
8.62k
        rdfs.peer_mode = RTPP_DTLS_PASSIVE;
306
8.62k
        rdg_cmd = RDG_CMD_P;
307
8.62k
        break;
308
309
2.78k
    case 's':
310
19.3k
    case 'S':
311
19.3k
        if (argc != 1)
312
77
            goto invalmode;
313
19.3k
        rdg_cmd = RDG_CMD_S;
314
19.3k
        break;
315
316
1.12k
    case 'd':
317
1.24k
    case 'D':
318
1.24k
        if (argc != 1)
319
72
            goto invalmode;
320
1.17k
        rdg_cmd = RDG_CMD_D;
321
1.17k
        break;
322
323
1.27k
    case 'u':
324
1.93k
    case 'U':
325
1.93k
        if (argc != 1)
326
592
            goto invalmode;
327
1.34k
        rdg_cmd = RDG_CMD_U;
328
1.34k
        break;
329
330
333
    default:
331
333
        goto invalmode;
332
46.9k
    }
333
334
45.4k
    switch (rdg_cmd) {
335
14.9k
    case RDG_CMD_A:
336
23.6k
    case RDG_CMD_P:
337
23.6k
        if (argv[1].len > sizeof(rdfs.alg_buf))
338
202
            goto invalalg;
339
162k
        for (int i = 0; i < argv[1].len; i++) {
340
138k
            rdfs.alg_buf[i] = argv[1].s[i];
341
138k
            if (rdfs.alg_buf[i] >= 'a')
342
45.1k
                rdfs.alg_buf[i] -= ('a' - 'A');
343
138k
        }
344
23.4k
        rdfs.algorithm.len = argv[1].len;
345
23.4k
        rdfs.algorithm.s = rdfs.alg_buf;
346
23.4k
        rdfs.fingerprint = &argv[2];
347
23.4k
        rdfs.ssrc = (argc == 4) ? &argv[3] : NULL;
348
23.4k
        rdfsp = &rdfs;
349
        /* Fallthrough */
350
24.5k
    case RDG_CMD_D:
351
24.5k
        dtls_strmp = ctxp->strmp_in;
352
24.5k
        break;
353
354
19.3k
    case RDG_CMD_S:
355
19.3k
        rdfsp = NULL;
356
        /* Fallthrough */
357
20.6k
    case RDG_CMD_U:
358
20.6k
        dtls_strmp = ctxp->strmp_out;
359
20.6k
        break;
360
45.4k
    }
361
362
45.2k
    struct packet_processor_if dtls_in_poi;
363
364
45.2k
    int lookup_res = CALL_SMETHOD(dtls_strmp->pproc_manager, lookup, pvt, &dtls_in_poi);
365
45.2k
    if (lookup_res != 0) {
366
14.5k
        rtps_c = dtls_in_poi.arg;
367
14.5k
    }
368
369
45.2k
    if (rdg_cmd == RDG_CMD_D || rdg_cmd == RDG_CMD_U) {
370
2.51k
        if (lookup_res == 0) {
371
182
            return (-1);
372
182
        }
373
2.51k
        CALL_SMETHOD(dtls_strmp->pproc_manager, unreg, pvt);
374
2.33k
        CALL_SMETHOD(dtls_strmp->pproc_manager->reverse, unreg, pvt + 1);
375
2.33k
        goto out;
376
2.51k
    }
377
378
42.7k
    if (lookup_res == 0) {
379
30.4k
        rtps_c = dtls_gw_data_ctor(pvt, dtls_strmp);
380
30.4k
        if (rtps_c == NULL) {
381
0
            return (-1);
382
0
        }
383
30.4k
    }
384
42.7k
    if (rdfsp != NULL && rdfs.peer_mode == RTPP_DTLS_PASSIVE) {
385
8.61k
        if (rtpp_dtls_gw_setup_sender(pvt, ctxp->sessp, dtls_strmp) != 0) {
386
34
            goto e0;
387
34
        }
388
8.61k
    }
389
42.6k
    my_mode = CALL_SMETHOD(rtps_c->dtls_conn, setmode, rdfsp);
390
42.6k
    if (my_mode == RTPP_DTLS_MODERR) {
391
5.71k
        goto e0;
392
5.71k
    }
393
36.9k
    if (lookup_res == 0) {
394
24.9k
        dtls_in_poi = (struct packet_processor_if){
395
24.9k
            .descr = "dtls (srtp->rtp)",
396
24.9k
            .taste = rtpp_dtls_gw_taste_encrypted,
397
24.9k
            .enqueue = rtpp_dtls_gw_enqueue,
398
24.9k
            .key = pvt,
399
24.9k
            .arg = rtps_c,
400
24.9k
            .rcnt = rtps_c->rcnt
401
24.9k
        };
402
24.9k
        if (CALL_SMETHOD(dtls_strmp->pproc_manager, reg, PPROC_ORD_DECRYPT, &dtls_in_poi) < 0) {
403
0
            goto e0;
404
0
        }
405
24.9k
        const struct packet_processor_if dtls_out_poi = {
406
24.9k
            .descr = "dtls (rtp->srtp)",
407
24.9k
            .taste = rtpp_dtls_gw_taste_plain,
408
24.9k
            .enqueue = rtpp_dtls_gw_enqueue,
409
24.9k
            .key = pvt + 1,
410
24.9k
            .arg = rtps_c,
411
24.9k
            .rcnt = rtps_c->rcnt
412
24.9k
        };
413
24.9k
        if (CALL_SMETHOD(dtls_strmp->pproc_manager->reverse, reg, PPROC_ORD_ENCRYPT, &dtls_out_poi) < 0) {
414
0
            goto e1;
415
0
        }
416
24.9k
    }
417
36.9k
    if (rdfsp == NULL) {
418
19.3k
        rcp = ctxp->resp->buf_t;
419
19.3k
        rlen = sizeof(ctxp->resp->buf_t);
420
421
19.3k
        switch (my_mode) {
422
9.22k
        case RTPP_DTLS_ACTPASS:
423
9.22k
            strlcpy(rcp, "actpass ", rlen);
424
9.22k
            rcp += strlen("actpass ");
425
9.22k
            rlen -= strlen("actpass ");
426
9.22k
            break;
427
428
67
        case RTPP_DTLS_ACTIVE:
429
67
            strlcpy(rcp, "active ", rlen);
430
67
            rcp += strlen("active ");
431
67
            rlen -= strlen("active ");
432
67
            break;
433
434
10.0k
        case RTPP_DTLS_PASSIVE:
435
10.0k
            strlcpy(rcp, "passive ", rlen);
436
10.0k
            rcp += strlen("passive ");
437
10.0k
            rlen -= strlen("passive ");
438
10.0k
            break;
439
440
0
        default:
441
0
            abort();
442
19.3k
        }
443
444
19.3k
        strlcpy(rcp, pvt->dtls_ctx->fingerprint, rlen);
445
19.3k
    }
446
39.2k
out:
447
39.2k
    RTPP_OBJ_DECREF(rtps_c);
448
39.2k
    return (0);
449
450
202
invalalg:
451
202
    RTPP_LOG(pvt->mself->log, RTPP_LOG_ERR, "invalid algorithm: \"%s\"",
452
202
      argv[1].s);
453
202
    return (-1);
454
1.50k
invalmode:
455
1.50k
    RTPP_LOG(pvt->mself->log, RTPP_LOG_ERR, "invalid mode: \"%s\"",
456
1.50k
      argv[0].s);
457
1.50k
    return (-1);
458
0
e1:
459
0
    CALL_SMETHOD(dtls_strmp->pproc_manager, unreg, pvt);
460
5.75k
e0:
461
5.75k
    RTPP_OBJ_DECREF(rtps_c);
462
5.75k
    return (-1);
463
0
}
464
465
static int
466
rtpp_dtls_gw_taste_encrypted(struct pkt_proc_ctx *pktxp)
467
135k
{
468
135k
    struct dtls_gw_stream_cfg *rtps_c;
469
135k
    static __thread struct rtpp_dtls_gw_aux dtls_in = {.direction = DTLS_IN};
470
135k
    static __thread struct rtpp_dtls_gw_aux strp_in = {.direction = SRTP_IN};
471
135k
    struct rtpp_dtls_gw_aux *rdgap;
472
473
135k
    if (!rtpp_is_dtls_tst(pktxp))
474
98.2k
        rdgap = &strp_in;
475
37.6k
    else
476
37.6k
        rdgap = &dtls_in;
477
135k
    rtps_c = pktxp->pproc->arg;
478
135k
    rdgap->dtls_conn = rtps_c->dtls_conn;
479
135k
    rdgap->mself = rtps_c->mself;
480
135k
    pktxp->auxp = rdgap;
481
135k
    return (1);
482
135k
}
483
484
static int
485
rtpp_dtls_gw_taste_plain(struct pkt_proc_ctx *pktxp)
486
181k
{
487
181k
    struct dtls_gw_stream_cfg *rtps_c;
488
181k
    static __thread struct rtpp_dtls_gw_aux rtp_out = {.direction = RTP_OUT};
489
490
181k
    if (pktxp->strmp_out == NULL)
491
0
        return (0);
492
181k
    rtps_c = pktxp->pproc->arg;
493
181k
    rtp_out.dtls_conn = rtps_c->dtls_conn;
494
181k
    rtp_out.mself = rtps_c->mself;
495
181k
    pktxp->auxp = &rtp_out;
496
181k
    return (1);
497
181k
}
498
499
static struct pproc_act
500
rtpp_dtls_gw_enqueue(const struct pkt_proc_ctx *pktxp)
501
317k
{
502
317k
    struct rtpp_dtls_gw_aux *edata;
503
317k
    struct rtpp_wi *wi;
504
317k
    struct wipkt *wip;
505
506
317k
    edata = (struct rtpp_dtls_gw_aux *)pktxp->auxp;
507
317k
    wi = rtpp_wi_malloc_udata((void **)&wip, sizeof(struct wipkt));
508
317k
    if (wi == NULL)
509
0
        return (PPROC_ACT_DROP);
510
317k
    wip->edata = *edata;
511
317k
    RTPP_OBJ_BORROW(wi, edata->dtls_conn);
512
317k
    wip->pktx = *pktxp;
513
317k
    wip->pktx.rsp = NULL;
514
317k
    RTPP_OBJ_BORROW(wi, pktxp->strmp_in);
515
317k
    if (pktxp->strmp_out != NULL)
516
317k
        RTPP_OBJ_BORROW(wi, pktxp->strmp_out);
517
317k
    if (rtpp_queue_put_item(wi, edata->mself->wthr.mod_q) != 0) {
518
2.29k
        RTPP_OBJ_DECREF(wi);
519
2.29k
        return (PPROC_ACT_DROP);
520
2.29k
    }
521
522
314k
    return (PPROC_ACT_TAKE);
523
317k
}
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
}