Coverage Report

Created: 2025-08-26 06:38

/src/rtpproxy/modules/ice_lite/rtpp_ice_lite.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 2019-2020 Sippy Software, Inc., http://www.sippysoft.com
3
 * Copyright (c) 2019 Maxim Sobolev <sobomax@sippysoft.com>
4
 * Copyright (c) 2019 Razvan Crainea <razvan@opensips.org>
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 * 1. Redistributions of source code must retain the above copyright
10
 *    notice, this list of conditions and the following disclaimer.
11
 * 2. Redistributions in binary form must reproduce the above copyright
12
 *    notice, this list of conditions and the following disclaimer in the
13
 *    documentation and/or other materials provided with the distribution.
14
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25
 * SUCH DAMAGE.
26
 *
27
 */
28
29
#include <sys/types.h>
30
#include <sys/socket.h>
31
#include <arpa/inet.h>
32
#include <stdatomic.h>
33
#include <assert.h>
34
#include <stdbool.h>
35
#include <stddef.h>
36
#include <stdint.h>
37
#include <stdlib.h>
38
#include <stdio.h>
39
#include <string.h>
40
41
#include "config_pp.h"
42
43
#include "rtpp_types.h"
44
#include "rtpp_debug.h"
45
#include "rtpp_module.h"
46
#include "rtpp_module_wthr.h"
47
#include "rtpp_module_cplane.h"
48
#include "rtpp_log.h"
49
#include "rtpp_log_obj.h"
50
#include "rtpp_codeptr.h"
51
#include "rtpp_refcnt.h"
52
#include "rtpp_cfg.h"
53
#include "rtpp_wi.h"
54
#include "rtpp_wi_sgnl.h"
55
#include "rtpp_wi_data.h"
56
#include "rtpp_queue.h"
57
#include "rtpp_stream.h"
58
#include "rtp.h"
59
#include "rtpp_network.h"
60
#include "rtpp_time.h"
61
#include "rtp_packet.h"
62
#include "rtpp_packetops.h"
63
#include "rtpp_timeout_data.h"
64
#include "rtpp_command_args.h"
65
#include "rtpp_command_sub.h"
66
#include "rtpp_util.h"
67
#include "rtpp_session.h"
68
#include "rtpp_stream.h"
69
#include "rtpp_pipe.h"
70
#include "rtpp_proc_async.h"
71
#include "rtpp_netio_async.h"
72
#include "rtpp_netaddr.h"
73
#include "rtpp_linker_set.h"
74
#include "advanced/packet_processor.h"
75
#include "advanced/pproc_manager.h"
76
77
#include "rtpp_re.h"
78
#include "re_types.h"
79
#include "re_fmt.h"
80
#include "re_sa.h"
81
#include "re_ice.h"
82
#include "re_udp.h"
83
#include "re_mem.h"
84
#include "re_list.h"
85
#include "re_tmr.h"
86
#include "re_mbuf.h"
87
#include "re_stun.h"
88
#include "ice/ice.h"
89
90
struct rtpp_module_priv {
91
    struct rtpp_minfo *mself;
92
};
93
94
struct ila_sock {
95
    struct sa laddr;
96
    struct rtpp_netaddr *raddr;
97
    struct sthread_args *sender;
98
    struct rtpp_stream *strmp_in;
99
    udp_helper_recv_h *rh;
100
    void *rh_arg;
101
};
102
103
struct mux_demux_ctx {
104
    struct rtpp_stream *strmp_in;
105
    struct rtpp_stream *strmp_out;
106
    struct pproc_manager *unreg;
107
};
108
109
struct ice_lite_agent_cfg {
110
    struct rtpp_refcnt *rcnt;
111
    pthread_mutex_t state_lock;
112
    struct icem *icem;
113
    struct ila_sock *sock;
114
    struct mbuf *mb;
115
    _Atomic(bool) completed;
116
    struct mux_demux_ctx rtcp_dmx_ctx;
117
    struct mux_demux_ctx rtcp_mx_ctx;
118
    struct rtpp_minfo *mself;
119
};
120
121
static struct rtpp_module_priv *rtpp_ice_lite_ctor(const struct rtpp_cfg *,
122
  struct rtpp_minfo *);
123
static void rtpp_ice_lite_dtor(struct rtpp_module_priv *);
124
static void rtpp_ice_lite_worker(const struct rtpp_wthrdata *);
125
static int rtpp_ice_lite_handle_command(struct rtpp_module_priv *,
126
  const struct rtpp_subc_ctx *);
127
static struct pproc_act rtpp_ice_lite_rtcp_dmx(const struct pkt_proc_ctx *);
128
static struct pproc_act rtpp_ice_lite_rtcp_mx(const struct pkt_proc_ctx *);
129
static struct pproc_act rtpp_ice_lite_enqueue(const struct pkt_proc_ctx *);
130
static int ril_ice_taste(struct pkt_proc_ctx *);
131
132
#ifdef RTPP_CHECK_LEAKS
133
#include "rtpp_memdeb_internal.h"
134
void *_libre_memdeb;
135
RTPP_MEMDEB_APP_STATIC;
136
#endif
137
138
const struct rtpp_minfo RTPP_MOD_SELF = {
139
    .descr.name = "ice_lite",
140
    .descr.ver = MI_VER_INIT(),
141
    .descr.module_id = 5,
142
    .proc.ctor = rtpp_ice_lite_ctor,
143
    .proc.dtor = rtpp_ice_lite_dtor,
144
    .wapi = &(const struct rtpp_wthr_handlers){
145
        .main_thread = rtpp_ice_lite_worker,
146
        .queue_size = RTPQ_MEDIUM_CB_LEN,
147
     },
148
    .capi = &(const struct rtpp_cplane_handlers){.ul_subc_handle = rtpp_ice_lite_handle_command},
149
    .fn = &(struct rtpp_minfo_fset){0},
150
#ifdef RTPP_CHECK_LEAKS
151
    .memdeb_p = &MEMDEB_SYM
152
#endif
153
};
154
#if defined(LIBRTPPROXY)
155
DATA_SET(rtpp_modules, RTPP_MOD_SELF);
156
#endif
157
158
struct wipkt {
159
    struct rtp_packet *pkt;
160
    struct ice_lite_agent_cfg *ila_c;
161
    struct rtpp_stream *strmp_in;
162
};
163
164
void
165
re_dbg_printf(int level, const char *buf, int len)
166
752
{
167
#if defined(RTPP_DEBUG)
168
    fprintf(stderr, "%.*s", len, buf);
169
#endif
170
752
}
171
172
int
173
udp_register_helper(struct udp_helper **uhp, struct udp_sock *us, int layer,
174
  udp_helper_send_h *sh, udp_helper_recv_h *rh, void *arg)
175
8.05k
{
176
8.05k
    struct ila_sock *sock = (struct ila_sock *)us;
177
8.05k
    assert(sock->rh == NULL && sock->rh_arg == NULL);
178
8.05k
    sock->rh = rh;
179
8.05k
    sock->rh_arg = arg;
180
8.05k
    return (0);
181
8.05k
}
182
183
static void
184
rtpp2re_sa(struct sa *sad, const struct sockaddr *sas)
185
5.01k
{
186
187
5.01k
    memcpy(&sad->u.sa, sas, SA_LEN(sas));
188
5.01k
    sad->len = SA_LEN(sas);
189
5.01k
}
190
191
int
192
udp_send(struct udp_sock *us, const struct sa *dst, struct mbuf *mb)
193
{
194
    struct ila_sock *sock = (struct ila_sock *)us;
195
    struct rtp_packet *packet;
196
197
    packet = rtp_packet_alloc();
198
    if (packet == NULL)
199
        return (ENOMEM);
200
    memcpy(packet->data.buf, mb->buf, mb->end);
201
    packet->size = mb->end;
202
    CALL_SMETHOD(sock->raddr, set, &dst->u.sa, dst->len);
203
    CALL_SMETHOD(sock->strmp_in, send_pkt_to, sock->sender, packet, sock->raddr);
204
    return (0);
205
}
206
207
static bool
208
iscompleted(const struct icem *icem)
209
5.01k
{
210
5.01k
    struct le *le;
211
5.01k
    bool rval = false;
212
213
5.01k
    for (le = icem->validl.head; le; le = le->next) {
214
0
        const struct ice_candpair *cp = le->data;
215
0
        if (!icem_candpair_iscompleted(cp))
216
0
            return false;
217
0
        rval = true;
218
0
    }
219
220
5.01k
    return rval;
221
5.01k
}
222
223
static bool
224
ila_iscompleted(struct ice_lite_agent_cfg *ila_c)
225
41.8k
{
226
41.8k
    return atomic_load_explicit(&ila_c->completed, memory_order_relaxed);
227
41.8k
}
228
229
static void
230
rtpp_ice_lite_worker(const struct rtpp_wthrdata *wp)
231
4
{
232
4
    struct rtpp_wi *wi;
233
4
    struct wipkt *wip;
234
4
    struct rtp_packet *pkt;
235
4
    struct mbuf *mb;
236
4
    struct ice_lite_agent_cfg *ila_c;
237
238
5.01k
    for (;;) {
239
5.01k
        wi = rtpp_queue_get_item(wp->mod_q, 0);
240
5.01k
        if (wi == wp->sigterm) {
241
4
            RTPP_OBJ_DECREF(wi);
242
4
            break;
243
4
        }
244
5.01k
        wip = rtpp_wi_data_get_ptr(wi, sizeof(*wip), sizeof(*wip));
245
5.01k
        pkt = wip->pkt;
246
5.01k
        ila_c = wip->ila_c;
247
5.01k
        pthread_mutex_lock(&ila_c->state_lock);
248
5.01k
        mb = ila_c->mb;
249
5.01k
        assert(pkt->size <= mb->size);
250
5.01k
        memcpy(mb->buf, pkt->data.buf, pkt->size);
251
5.01k
        mb->end = pkt->size;
252
5.01k
        struct sa raddr = {0};
253
5.01k
        rtpp2re_sa(&raddr, sstosa(&pkt->raddr));
254
5.01k
        ila_c->sock->strmp_in = wip->strmp_in;
255
5.01k
        ila_c->sock->rh(&raddr, mb, ila_c->sock->rh_arg);
256
5.01k
        bool completed = iscompleted(ila_c->icem);
257
5.01k
        if (!ila_iscompleted(ila_c) && completed) {
258
0
            RTPP_LOG(ila_c->sock->strmp_in->log, RTPP_LOG_INFO, "ICE completed");
259
0
            CALL_SMETHOD(ila_c->sock->strmp_in, latch_setmode, RTPLM_FORCE_ON);
260
0
            CALL_SMETHOD(ila_c->sock->strmp_in, latch, pkt);
261
0
            atomic_store_explicit(&ila_c->completed, true, memory_order_relaxed);
262
0
        }
263
5.01k
        pthread_mutex_unlock(&ila_c->state_lock);
264
5.01k
        RTPP_OBJ_DECREF(pkt);
265
5.01k
        RTPP_OBJ_DECREF(wi);
266
5.01k
    }
267
4
}
268
269
static void
270
ice_lite_data_dtor(struct ice_lite_agent_cfg *pvt)
271
9.13k
{
272
273
9.13k
    pthread_mutex_destroy(&pvt->state_lock);
274
9.13k
    RTPP_OBJ_DECREF(pvt->sock->raddr);
275
9.13k
    mem_deref(pvt->mb->buf);
276
9.13k
    mem_deref(pvt->mb);
277
9.13k
    mem_deref(pvt->sock);
278
9.13k
    mem_deref(pvt->icem);
279
9.13k
    RC_DECREF(pvt->mself->super_rcnt);
280
9.13k
}
281
282
int
283
udp_local_get(const struct udp_sock *us, struct sa *local)
284
8.05k
{
285
8.05k
    struct ila_sock *sock = (struct ila_sock *)us;
286
8.05k
    *local = sock->laddr;
287
8.05k
    return (0);
288
8.05k
}
289
290
static struct ice_lite_agent_cfg *
291
ice_lite_data_ctor(int lufrag_len, int lpwd_len, struct rtpp_minfo *mself)
292
9.88k
{
293
9.88k
    struct ice_lite_agent_cfg *ila_c;
294
9.88k
    rtpp_str_mutble_t lufrag, lpwd;
295
9.88k
    uint64_t tiebrk = 1;
296
297
9.88k
    ila_c = mod_rzmalloc(sizeof(*ila_c), offsetof(typeof(*ila_c), rcnt));
298
9.88k
    if (ila_c == NULL)
299
0
        goto e0;
300
9.88k
    atomic_init(&ila_c->completed, false);
301
9.88k
    lufrag.s = alloca(lufrag_len + 1);
302
9.88k
    lpwd.s = alloca(lpwd_len + 1);
303
9.88k
    if (lufrag.s == NULL || lpwd.s == NULL)
304
0
        goto e1;
305
9.88k
    lufrag.len = lufrag_len;
306
9.88k
    generate_random_string(lufrag.s, lufrag.len);
307
9.88k
    lpwd.len = lpwd_len;
308
9.88k
    generate_random_string(lpwd.s, lpwd.len);
309
9.88k
    if (icem_alloc(&ila_c->icem, ICE_MODE_LITE, ICE_ROLE_CONTROLLED, IPPROTO_UDP, 0,
310
9.88k
      tiebrk, lufrag.s, lpwd.s, NULL, NULL) != 0)
311
752
        goto e1;
312
9.13k
    ila_c->sock = mem_zalloc(sizeof(*ila_c->sock), NULL);
313
9.13k
    if (ila_c->sock == NULL)
314
0
        goto e2;
315
9.13k
    ila_c->mb = mem_zalloc(sizeof(*ila_c->mb), NULL);
316
9.13k
    if (ila_c->mb == NULL)
317
0
        goto e3;
318
9.13k
    ila_c->mb->buf = mem_zalloc(MAX_RPKT_LEN, NULL);
319
9.13k
    if (ila_c->mb->buf == NULL)
320
0
        goto e4;
321
9.13k
    ila_c->mb->size = MAX_RPKT_LEN;
322
9.13k
    ila_c->sock->raddr = rtpp_netaddr_ctor();
323
9.13k
    if (ila_c->sock->raddr == NULL)
324
0
        goto e5;
325
9.13k
    if (pthread_mutex_init(&ila_c->state_lock, NULL) != 0)
326
0
        goto e6;
327
9.13k
    RC_INCREF(mself->super_rcnt);
328
9.13k
    ila_c->mself = mself;
329
9.13k
    CALL_SMETHOD(ila_c->rcnt, attach, (rtpp_refcnt_dtor_t)ice_lite_data_dtor, ila_c);
330
9.13k
    return (ila_c);
331
0
e6:
332
0
    RTPP_OBJ_DECREF(ila_c->sock->raddr);
333
0
e5:
334
0
    mem_deref(ila_c->mb->buf);
335
0
e4:
336
0
    mem_deref(ila_c->mb);
337
0
e3:
338
0
    mem_deref(ila_c->sock);
339
0
e2:
340
0
    mem_deref(ila_c->icem);
341
752
e1:
342
752
    mod_free(ila_c);
343
752
e0:
344
752
    return (NULL);
345
752
}
346
347
static int
348
ila_set_rauth(struct ice_lite_agent_cfg *ila_c, const rtpp_str_t *ice_rufrag,
349
  const rtpp_str_t *ice_rpwd)
350
6.57k
{
351
352
6.57k
    pthread_mutex_lock(&ila_c->state_lock);
353
6.57k
    if (icem_sdp_decode(ila_c->icem, "ice-ufrag", ice_rufrag->s) != 0)
354
0
        goto e0;
355
6.57k
    if (icem_sdp_decode(ila_c->icem, "ice-pwd", ice_rpwd->s) != 0)
356
0
        goto e0;
357
6.57k
    pthread_mutex_unlock(&ila_c->state_lock);
358
6.57k
    return 0;
359
0
e0:
360
0
    pthread_mutex_unlock(&ila_c->state_lock);
361
0
    return -1;
362
6.57k
}
363
364
enum ril_cmd {RIL_CMD_A, RIL_CMD_C, RIL_CMD_S, RIL_CMD_D, RIL_CMD_U};
365
16.1k
#define ICE_COMPID_RTP  1
366
#define ICE_COMPID_RTCP 2
367
368
3.43k
#define ICE_LUFRAG_LEN 4
369
3.43k
#define ICE_LPWD_LEN 24
370
371
static int
372
ice_lite_candidate(struct ice_lite_agent_cfg *ila_c, int c, const rtpp_str_t *v)
373
21.4k
{
374
21.4k
    struct rtpp_command_argsp args = {.c = c, .v = v};
375
21.4k
    pthread_mutex_lock(&ila_c->state_lock);
376
21.4k
    int err = rtpp_cand_decode(ila_c->icem, &args, ila_c->mself->log);
377
21.4k
    pthread_mutex_unlock(&ila_c->state_lock);
378
21.4k
    return (err);
379
21.4k
}
380
381
static int
382
cand_printf_handler(const char *p, size_t size, void *arg)
383
167k
{
384
167k
    rtpp_str_mutble_t *resp = (rtpp_str_mutble_t *)arg;
385
167k
    if (size + 1 > resp->len)
386
626
        return (ENOMEM);
387
166k
    int len = url_quote(p, resp->s, size, resp->len);
388
166k
    if (len < 0)
389
77
        return (ENOMEM);
390
166k
    resp->s += len;
391
166k
    resp->len -= len;
392
166k
    return (0);
393
166k
}
394
395
53.7k
#define APPEND(bs, ss) ({size_t len = strlcpy(bs->s, ss, bs->len); \
396
53.7k
  int err = (len > bs->len); bs->len -= (err) ? 0:len, bs->s += (err) ? 0:len; err;})
397
398
static int
399
ice_lite_start(struct ice_lite_agent_cfg *ila_c, struct rtpp_stream *isp,
400
  rtpp_str_mutble_t *resp)
401
13.4k
{
402
13.4k
    int err;
403
13.4k
    struct sa *laddr;
404
405
13.4k
    pthread_mutex_lock(&ila_c->state_lock);
406
13.4k
    laddr = &ila_c->sock->laddr;
407
13.4k
    if (laddr->len == 0) {
408
8.05k
        const struct sockaddr *s_laddr = isp->laddr;
409
8.05k
        memcpy(&laddr->u.sa, s_laddr, SA_LEN(s_laddr));
410
8.05k
        laddr->len = SA_LEN(s_laddr);
411
8.05k
        sa_set_port(laddr, isp->port);
412
413
8.05k
        err = icem_comp_add(ila_c->icem, ICE_COMPID_RTP, ila_c->sock);
414
8.05k
        if (err != 0)
415
0
            goto e0;
416
8.05k
        err = icem_cand_add(ila_c->icem, ICE_COMPID_RTP, 0, NULL, laddr);
417
8.05k
        if (err != 0)
418
0
            goto e0;
419
8.05k
    }
420
13.4k
    if (APPEND(resp, ila_c->icem->lufrag) < 0)
421
0
        goto e0;
422
13.4k
    if (APPEND(resp, " ") < 0)
423
0
        goto e0;
424
13.4k
    if (APPEND(resp, ila_c->icem->lpwd) < 0)
425
0
        goto e0;
426
13.4k
    struct re_printf pt = {.vph = cand_printf_handler, .arg = resp};
427
13.4k
    struct list *canlist = icem_lcandl(ila_c->icem);
428
26.1k
    for(struct le *le = canlist->head; le; le = le->next) {
429
13.4k
        if (APPEND(resp, " c:") < 0)
430
0
            goto e0;
431
13.4k
        err = ice_cand_encode(&pt, (struct ice_cand *)le->data);
432
13.4k
        if (err  != 0)
433
703
            goto e0;
434
13.4k
    }
435
12.7k
    pthread_mutex_unlock(&ila_c->state_lock);
436
12.7k
    return (0);
437
703
e0:
438
703
    pthread_mutex_unlock(&ila_c->state_lock);
439
703
    return (-1);
440
13.4k
}
441
442
static struct ice_lite_agent_cfg *
443
ice_lite_activate(struct rtpp_module_priv *pvt, const struct rtpp_subc_ctx *ctxp,
444
  struct rtpp_stream *ice_strmp, int lufrag_len, int lpwd_len)
445
9.88k
{
446
9.88k
    struct ice_lite_agent_cfg *ila_c;
447
9.88k
    struct packet_processor_if stun_poi;
448
449
9.88k
    ila_c = ice_lite_data_ctor(lufrag_len, lpwd_len, pvt->mself);
450
9.88k
    if (ila_c == NULL) {
451
752
        goto e0;
452
752
    }
453
9.13k
    stun_poi = (struct packet_processor_if) {
454
9.13k
        .descr = "stun/ice",
455
9.13k
        .taste = ril_ice_taste,
456
9.13k
        .enqueue = rtpp_ice_lite_enqueue,
457
9.13k
        .key = pvt,
458
9.13k
        .arg = ila_c,
459
9.13k
        .rcnt = ila_c->rcnt
460
9.13k
    };
461
9.13k
    if (CALL_SMETHOD(ice_strmp->pproc_manager, reg, PPROC_ORD_RECV,
462
9.13k
      &stun_poi) < 0)
463
0
        goto e1;
464
9.13k
    struct rtpp_stream *rtcp_strmp_in = NULL, *rtcp_strmp_out;
465
9.13k
    int i;
466
15.0k
    for (i = 0; i < 2; i++) {
467
15.0k
        if (ctxp->sessp->rtp->stream[i] != ice_strmp)
468
5.89k
            continue;
469
9.13k
        rtcp_strmp_in = ctxp->sessp->rtcp->stream[i];
470
9.13k
        rtcp_strmp_out = ctxp->sessp->rtcp->stream[i ^ 1];
471
9.13k
        break;
472
15.0k
    }
473
9.13k
    if (i == 2) {
474
0
        goto e2;
475
0
    }
476
9.13k
    if (rtcp_strmp_in != NULL) {
477
9.13k
        struct packet_processor_if rtcp_dmx_poi = {
478
9.13k
            .descr = "rtcp demux",
479
9.13k
            .taste = rtpp_is_rtcp_tst,
480
9.13k
            .enqueue = rtpp_ice_lite_rtcp_dmx,
481
9.13k
            .key = pvt + 1,
482
9.13k
            .arg = &ila_c->rtcp_dmx_ctx,
483
9.13k
            .rcnt = ila_c->rcnt
484
9.13k
        };
485
9.13k
        ila_c->rtcp_dmx_ctx = (struct mux_demux_ctx) {
486
9.13k
            .strmp_in = rtcp_strmp_in,
487
9.13k
            .strmp_out = rtcp_strmp_out,
488
9.13k
        };
489
9.13k
        if (CALL_SMETHOD(ice_strmp->pproc_manager, reg, PPROC_ORD_CT_RECV,
490
9.13k
            &rtcp_dmx_poi) < 0)
491
0
            goto e2;
492
9.13k
        struct packet_processor_if rtcp_mx_poi = {
493
9.13k
            .descr = "rtcp mux",
494
9.13k
            .taste = rtpp_is_rtcp_tst,
495
9.13k
            .enqueue = rtpp_ice_lite_rtcp_mx,
496
9.13k
            .key = pvt + 2,
497
9.13k
            .arg = &ila_c->rtcp_mx_ctx,
498
9.13k
            .rcnt = ila_c->rcnt
499
9.13k
        };
500
9.13k
        ila_c->rtcp_mx_ctx = (struct mux_demux_ctx) {
501
9.13k
            .strmp_in = rtcp_strmp_out,
502
9.13k
            .strmp_out = ice_strmp,
503
9.13k
            .unreg = rtcp_strmp_in->pproc_manager->reverse,
504
9.13k
        };
505
9.13k
        if (CALL_SMETHOD(rtcp_strmp_in->pproc_manager->reverse, reg, PPROC_ORD_CT_SEND,
506
9.13k
            &rtcp_mx_poi) < 0)
507
0
            goto e3;
508
9.13k
    }
509
9.13k
    CALL_SMETHOD(ice_strmp, latch_setmode, RTPLM_FORCE_OFF);
510
9.13k
    return (ila_c);
511
0
e3:
512
0
    CALL_SMETHOD(ice_strmp->pproc_manager, unreg, pvt + 1);
513
0
e2:
514
0
    CALL_SMETHOD(ice_strmp->pproc_manager, unreg, pvt);
515
0
e1:
516
0
    RTPP_OBJ_DECREF(ila_c);
517
752
e0:
518
752
    return (NULL);
519
0
}
520
521
static int
522
rtpp_ice_lite_handle_command(struct rtpp_module_priv *pvt,
523
  const struct rtpp_subc_ctx *ctxp)
524
46.9k
{
525
46.9k
    struct ice_lite_agent_cfg *ila_c;
526
46.9k
    const rtpp_str_t *rufrag, *rpwd;
527
46.9k
    enum ril_cmd ril_cmd;
528
46.9k
    const rtpp_str_t *argv = rtpp_str_fix(&ctxp->subc_args->v[1]);
529
46.9k
    int argc = ctxp->subc_args->c - 1;
530
46.9k
    struct rtpp_stream *ice_strmp;
531
532
46.9k
    if (argc < 1) {
533
232
        RTPP_LOG(pvt->mself->log, RTPP_LOG_ERR,
534
232
          "expected at least 1 parameter: %d", argc);
535
232
        return (-1);
536
232
    }
537
46.7k
    {static int b=0; while (b);}
538
539
46.7k
    switch (argv[0].s[0] | argv[0].s[1]) {
540
642
    case 'a':
541
7.59k
    case 'A':
542
7.59k
        if (argc != 3)
543
266
            goto invalmode;
544
7.33k
        ril_cmd = RIL_CMD_A;
545
7.33k
        break;
546
547
3.33k
    case 'c':
548
21.7k
    case 'C':
549
21.7k
        if (argc < 9)
550
217
            goto invalmode;
551
21.5k
        ril_cmd = RIL_CMD_C;
552
21.5k
        break;
553
554
8.67k
    case 's':
555
13.9k
    case 'S':
556
13.9k
        if (argc != 1)
557
501
            goto invalmode;
558
13.4k
        ril_cmd = RIL_CMD_S;
559
13.4k
        break;
560
561
115
    case 'd':
562
187
    case 'D':
563
187
        if (argc != 1)
564
99
            goto invalmode;
565
88
        ril_cmd = RIL_CMD_D;
566
88
        break;
567
568
2.75k
    case 'u':
569
2.87k
    case 'U':
570
2.87k
        if (argc != 1)
571
154
            goto invalmode;
572
2.71k
        ril_cmd = RIL_CMD_U;
573
2.71k
        break;
574
575
360
    default:
576
360
        goto invalmode;
577
46.7k
    }
578
579
45.1k
    switch (ril_cmd) {
580
7.33k
    case RIL_CMD_A:
581
7.33k
        rufrag = rtpp_str_fix(&argv[1]);
582
7.33k
        rpwd = rtpp_str_fix(&argv[2]);
583
28.8k
    case RIL_CMD_C:
584
28.9k
    case RIL_CMD_D:
585
28.9k
        ice_strmp = ctxp->strmp_in;
586
28.9k
        break;
587
588
13.4k
    case RIL_CMD_S:
589
16.1k
    case RIL_CMD_U:
590
16.1k
        ice_strmp = ctxp->strmp_out;
591
16.1k
        break;
592
45.1k
    }
593
594
45.1k
    struct packet_processor_if stun_poi;
595
596
45.1k
    int lookup_res = CALL_SMETHOD(ice_strmp->pproc_manager, lookup, pvt, &stun_poi);
597
598
45.1k
    if (lookup_res != 0) {
599
35.0k
        ila_c = stun_poi.arg;
600
35.0k
    }
601
602
45.1k
    switch (ril_cmd) {
603
88
    case RIL_CMD_D:
604
2.80k
    case RIL_CMD_U:
605
2.80k
        if (lookup_res == 0)
606
107
            return (-1);
607
2.69k
        RTPP_OBJ_INCREF(ila_c); /* for the unlock */
608
2.69k
        pthread_mutex_lock(&ila_c->state_lock);
609
2.69k
        CALL_SMETHOD(ila_c->rtcp_mx_ctx.unreg, unreg, pvt + 2);
610
2.69k
        CALL_SMETHOD(ice_strmp->pproc_manager, unreg, pvt + 1);
611
2.69k
        CALL_SMETHOD(ice_strmp->pproc_manager, unreg, pvt);
612
2.69k
        CALL_SMETHOD(ice_strmp, latch_setmode, RTPLM_NORMAL);
613
2.69k
        pthread_mutex_unlock(&ila_c->state_lock);
614
2.69k
        RTPP_OBJ_DECREF(ila_c);
615
2.69k
        break;
616
617
21.5k
    case RIL_CMD_C:
618
21.5k
        if (lookup_res == 0)
619
70
            return (-1);
620
21.4k
        if (ice_lite_candidate(ila_c, argc - 1, argv + 1) != 0)
621
454
            goto e0;
622
21.0k
        break;
623
624
21.0k
   case RIL_CMD_S:
625
13.4k
        if (lookup_res == 0) {
626
3.43k
            ila_c = ice_lite_activate(pvt, ctxp, ice_strmp, ICE_LUFRAG_LEN, ICE_LPWD_LEN);
627
3.43k
            if (ila_c == NULL)
628
0
               return (-1);
629
3.43k
        }
630
13.4k
        rtpp_str_mutble_t resp = {.s = ctxp->resp->buf_t, .len = sizeof(ctxp->resp->buf_t)};
631
13.4k
        if (ice_lite_start(ila_c, ice_strmp, &resp) != 0) {
632
703
            goto e0;
633
703
        }
634
12.7k
        break;
635
636
12.7k
    case RIL_CMD_A:
637
7.33k
        if (lookup_res == 0) {
638
6.44k
            ila_c = ice_lite_activate(pvt, ctxp, ice_strmp, rufrag->len, rpwd->len);
639
6.44k
            if (ila_c == NULL)
640
752
                return (-1);
641
6.44k
        }
642
6.57k
        if (ila_set_rauth(ila_c, rufrag, rpwd) != 0)
643
0
            goto e0;
644
6.57k
        break;
645
45.1k
   }
646
647
43.0k
    RTPP_OBJ_DECREF(ila_c);
648
43.0k
    return (0);
649
650
1.59k
invalmode:
651
1.59k
    RTPP_LOG(pvt->mself->log, RTPP_LOG_ERR, "invalid mode: \"%s\"",
652
1.59k
      argv[0].s);
653
1.59k
    return (-1);
654
1.15k
e0:
655
1.15k
    RTPP_OBJ_DECREF(ila_c);
656
1.15k
    return (-1);
657
45.1k
}
658
659
static int
660
ril_ice_taste(struct pkt_proc_ctx *pktx)
661
41.8k
{
662
41.8k
    struct ice_lite_agent_cfg *ila_c;
663
664
41.8k
    ila_c = pktx->pproc->arg;
665
41.8k
    if (!rtpp_is_stun_tst(pktx)) {
666
36.8k
        if (!ila_iscompleted(ila_c)) {
667
36.8k
            pktx->auxp = NULL;
668
36.8k
            return (true);
669
36.8k
        }
670
0
        return (false);
671
36.8k
    }
672
5.01k
    pktx->auxp = ila_c;
673
5.01k
    return (true);
674
41.8k
}
675
676
static struct pproc_act
677
rtpp_ice_lite_enqueue(const struct pkt_proc_ctx *pktx)
678
41.8k
{
679
41.8k
    struct rtpp_wi *wi;
680
41.8k
    struct wipkt *wip;
681
41.8k
    struct ice_lite_agent_cfg *ila_c;
682
683
41.8k
    ila_c = (struct ice_lite_agent_cfg *)pktx->auxp;
684
41.8k
    if (ila_c == NULL)
685
36.8k
        return (PPROC_ACT_DROP);
686
5.01k
    wi = rtpp_wi_malloc_udata((void **)&wip, sizeof(struct wipkt));
687
5.01k
    if (wi == NULL)
688
0
        return (PPROC_ACT_DROP);
689
5.01k
    wip->pkt = pktx->pktp;
690
5.01k
    RTPP_OBJ_BORROW(wi, ila_c);
691
5.01k
    wip->ila_c = ila_c;
692
5.01k
    RTPP_OBJ_BORROW(wi, pktx->strmp_in);
693
5.01k
    wip->strmp_in = pktx->strmp_in;
694
5.01k
    if (rtpp_queue_put_item(wi, ila_c->mself->wthr.mod_q) != 0) {
695
0
        RTPP_OBJ_DECREF(wi);
696
0
        return (PPROC_ACT_DROP);
697
0
    }
698
5.01k
    return (PPROC_ACT_TAKE);
699
5.01k
}
700
701
static struct pproc_act
702
rtpp_ice_lite_rtcp_dmx(const struct pkt_proc_ctx *pktx)
703
0
{
704
0
    struct mux_demux_ctx *ctx = pktx->pproc->arg;
705
0
    struct pkt_proc_ctx opktx = {.strmp_in = ctx->strmp_in, .strmp_out = ctx->strmp_out,
706
0
      .pktp = pktx->pktp, .flags = pktx->flags};
707
0
    return CALL_SMETHOD(opktx.strmp_in->pproc_manager, handleat, &opktx, PPROC_ORD_CT_RECV);
708
0
}
709
710
static struct pproc_act
711
rtpp_ice_lite_rtcp_mx(const struct pkt_proc_ctx *pktx)
712
0
{
713
0
    struct mux_demux_ctx *ctx = pktx->pproc->arg;
714
0
    struct pkt_proc_ctx opktx = {.strmp_in = ctx->strmp_in, .strmp_out = ctx->strmp_out,
715
0
      .pktp = pktx->pktp, .flags = pktx->flags};
716
0
    return CALL_SMETHOD(opktx.strmp_out->pproc_manager->reverse, handleat, &opktx, PPROC_ORD_CT_SEND);
717
0
}
718
719
static struct rtpp_module_priv *
720
rtpp_ice_lite_ctor(const struct rtpp_cfg *cfsp, struct rtpp_minfo *mself)
721
4
{
722
4
    struct rtpp_module_priv *pvt;
723
724
4
    pvt = mod_zmalloc(sizeof(struct rtpp_module_priv));
725
4
    if (pvt == NULL) {
726
0
        goto e0;
727
0
    }
728
#ifdef RTPP_CHECK_LEAKS
729
    _libre_memdeb = *mself->memdeb_p;
730
#endif
731
4
    pvt->mself = mself;
732
4
    return (pvt);
733
734
0
e0:
735
0
    return (NULL);
736
4
}
737
738
static void
739
rtpp_ice_lite_dtor(struct rtpp_module_priv *pvt)
740
4
{
741
742
4
    mod_free(pvt);
743
4
    return;
744
4
}