Coverage Report

Created: 2025-11-09 07:07

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/rtpproxy/modules/ice_lite/rtpp_ice_lite.c
Line
Count
Source
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
324
{
167
#if defined(RTPP_DEBUG)
168
    fprintf(stderr, "%.*s", len, buf);
169
#endif
170
324
}
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
7.95k
{
176
7.95k
    struct ila_sock *sock = (struct ila_sock *)us;
177
7.95k
    assert(sock->rh == NULL && sock->rh_arg == NULL);
178
7.95k
    sock->rh = rh;
179
7.95k
    sock->rh_arg = arg;
180
7.95k
    return (0);
181
7.95k
}
182
183
static void
184
rtpp2re_sa(struct sa *sad, const struct sockaddr *sas)
185
5.50k
{
186
187
5.50k
    memcpy(&sad->u.sa, sas, SA_LEN(sas));
188
5.50k
    sad->len = SA_LEN(sas);
189
5.50k
}
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.50k
{
210
5.50k
    struct le *le;
211
5.50k
    bool rval = false;
212
213
5.50k
    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.50k
    return rval;
221
5.50k
}
222
223
static bool
224
ila_iscompleted(struct ice_lite_agent_cfg *ila_c)
225
44.4k
{
226
44.4k
    return atomic_load_explicit(&ila_c->completed, memory_order_relaxed);
227
44.4k
}
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.51k
    for (;;) {
239
5.51k
        wi = rtpp_queue_get_item(wp->mod_q, 0);
240
5.51k
        if (wi == wp->sigterm) {
241
4
            RTPP_OBJ_DECREF(wi);
242
4
            break;
243
4
        }
244
5.50k
        wip = rtpp_wi_data_get_ptr(wi, sizeof(*wip), sizeof(*wip));
245
5.50k
        pkt = wip->pkt;
246
5.50k
        ila_c = wip->ila_c;
247
5.50k
        pthread_mutex_lock(&ila_c->state_lock);
248
5.50k
        mb = ila_c->mb;
249
5.50k
        assert(pkt->size <= mb->size);
250
5.50k
        memcpy(mb->buf, pkt->data.buf, pkt->size);
251
5.50k
        mb->end = pkt->size;
252
5.50k
        struct sa raddr = {0};
253
5.50k
        rtpp2re_sa(&raddr, sstosa(&pkt->raddr));
254
5.50k
        ila_c->sock->strmp_in = wip->strmp_in;
255
5.50k
        ila_c->sock->rh(&raddr, mb, ila_c->sock->rh_arg);
256
5.50k
        bool completed = iscompleted(ila_c->icem);
257
5.50k
        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.50k
        pthread_mutex_unlock(&ila_c->state_lock);
264
5.50k
        RTPP_OBJ_DECREF(pkt);
265
5.50k
        RTPP_OBJ_DECREF(wi);
266
5.50k
    }
267
4
}
268
269
static void
270
ice_lite_data_dtor(struct ice_lite_agent_cfg *pvt)
271
9.01k
{
272
273
9.01k
    pthread_mutex_destroy(&pvt->state_lock);
274
9.01k
    RTPP_OBJ_DECREF(pvt->sock->raddr);
275
9.01k
    mem_deref(pvt->mb->buf);
276
9.01k
    mem_deref(pvt->mb);
277
9.01k
    mem_deref(pvt->sock);
278
9.01k
    mem_deref(pvt->icem);
279
9.01k
    RC_DECREF(pvt->mself->super_rcnt);
280
9.01k
}
281
282
int
283
udp_local_get(const struct udp_sock *us, struct sa *local)
284
7.95k
{
285
7.95k
    struct ila_sock *sock = (struct ila_sock *)us;
286
7.95k
    *local = sock->laddr;
287
7.95k
    return (0);
288
7.95k
}
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.34k
{
293
9.34k
    struct ice_lite_agent_cfg *ila_c;
294
9.34k
    rtpp_str_mutble_t lufrag, lpwd;
295
9.34k
    uint64_t tiebrk = 1;
296
297
9.34k
    ila_c = mod_rzmalloc(sizeof(*ila_c), offsetof(typeof(*ila_c), rcnt));
298
9.34k
    if (ila_c == NULL)
299
0
        goto e0;
300
9.34k
    atomic_init(&ila_c->completed, false);
301
9.34k
    lufrag.s = alloca(lufrag_len + 1);
302
9.34k
    lpwd.s = alloca(lpwd_len + 1);
303
9.34k
    if (lufrag.s == NULL || lpwd.s == NULL)
304
0
        goto e1;
305
9.34k
    lufrag.len = lufrag_len;
306
9.34k
    generate_random_string(lufrag.s, lufrag.len);
307
9.34k
    lpwd.len = lpwd_len;
308
9.34k
    generate_random_string(lpwd.s, lpwd.len);
309
9.34k
    if (icem_alloc(&ila_c->icem, ICE_MODE_LITE, ICE_ROLE_CONTROLLED, IPPROTO_UDP, 0,
310
9.34k
      tiebrk, lufrag.s, lpwd.s, NULL, NULL) != 0)
311
324
        goto e1;
312
9.01k
    ila_c->sock = mem_zalloc(sizeof(*ila_c->sock), NULL);
313
9.01k
    if (ila_c->sock == NULL)
314
0
        goto e2;
315
9.01k
    ila_c->mb = mem_zalloc(sizeof(*ila_c->mb), NULL);
316
9.01k
    if (ila_c->mb == NULL)
317
0
        goto e3;
318
9.01k
    ila_c->mb->buf = mem_zalloc(MAX_RPKT_LEN, NULL);
319
9.01k
    if (ila_c->mb->buf == NULL)
320
0
        goto e4;
321
9.01k
    ila_c->mb->size = MAX_RPKT_LEN;
322
9.01k
    ila_c->sock->raddr = rtpp_netaddr_ctor();
323
9.01k
    if (ila_c->sock->raddr == NULL)
324
0
        goto e5;
325
9.01k
    if (pthread_mutex_init(&ila_c->state_lock, NULL) != 0)
326
0
        goto e6;
327
9.01k
    RC_INCREF(mself->super_rcnt);
328
9.01k
    ila_c->mself = mself;
329
9.01k
    CALL_SMETHOD(ila_c->rcnt, attach, (rtpp_refcnt_dtor_t)ice_lite_data_dtor, ila_c);
330
9.01k
    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
324
e1:
342
324
    mod_free(ila_c);
343
324
e0:
344
324
    return (NULL);
345
324
}
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.62k
{
351
352
6.62k
    pthread_mutex_lock(&ila_c->state_lock);
353
6.62k
    if (icem_sdp_decode(ila_c->icem, "ice-ufrag", ice_rufrag->s) != 0)
354
0
        goto e0;
355
6.62k
    if (icem_sdp_decode(ila_c->icem, "ice-pwd", ice_rpwd->s) != 0)
356
0
        goto e0;
357
6.62k
    pthread_mutex_unlock(&ila_c->state_lock);
358
6.62k
    return 0;
359
0
e0:
360
0
    pthread_mutex_unlock(&ila_c->state_lock);
361
0
    return -1;
362
6.62k
}
363
364
enum ril_cmd {RIL_CMD_A, RIL_CMD_C, RIL_CMD_S, RIL_CMD_D, RIL_CMD_U};
365
15.9k
#define ICE_COMPID_RTP  1
366
#define ICE_COMPID_RTCP 2
367
368
3.14k
#define ICE_LUFRAG_LEN 4
369
3.14k
#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
22.4k
{
374
22.4k
    struct rtpp_command_argsp args = {.c = c, .v = v};
375
22.4k
    pthread_mutex_lock(&ila_c->state_lock);
376
22.4k
    int err = rtpp_cand_decode(ila_c->icem, &args, ila_c->mself->log);
377
22.4k
    pthread_mutex_unlock(&ila_c->state_lock);
378
22.4k
    return (err);
379
22.4k
}
380
381
static int
382
cand_printf_handler(const char *p, size_t size, void *arg)
383
168k
{
384
168k
    rtpp_str_mutble_t *resp = (rtpp_str_mutble_t *)arg;
385
168k
    if (size + 1 > resp->len)
386
712
        return (ENOMEM);
387
167k
    int len = url_quote(p, resp->s, size, resp->len);
388
167k
    if (len < 0)
389
80
        return (ENOMEM);
390
167k
    resp->s += len;
391
167k
    resp->len -= len;
392
167k
    return (0);
393
167k
}
394
395
54.1k
#define APPEND(bs, ss) ({size_t len = strlcpy(bs->s, ss, bs->len); \
396
54.1k
  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.5k
{
402
13.5k
    int err;
403
13.5k
    struct sa *laddr;
404
405
13.5k
    pthread_mutex_lock(&ila_c->state_lock);
406
13.5k
    laddr = &ila_c->sock->laddr;
407
13.5k
    if (laddr->len == 0) {
408
7.95k
        const struct sockaddr *s_laddr = isp->laddr;
409
7.95k
        memcpy(&laddr->u.sa, s_laddr, SA_LEN(s_laddr));
410
7.95k
        laddr->len = SA_LEN(s_laddr);
411
7.95k
        sa_set_port(laddr, isp->port);
412
413
7.95k
        err = icem_comp_add(ila_c->icem, ICE_COMPID_RTP, ila_c->sock);
414
7.95k
        if (err != 0)
415
0
            goto e0;
416
7.95k
        err = icem_cand_add(ila_c->icem, ICE_COMPID_RTP, 0, NULL, laddr);
417
7.95k
        if (err != 0)
418
0
            goto e0;
419
7.95k
    }
420
13.5k
    if (APPEND(resp, ila_c->icem->lufrag) < 0)
421
0
        goto e0;
422
13.5k
    if (APPEND(resp, " ") < 0)
423
0
        goto e0;
424
13.5k
    if (APPEND(resp, ila_c->icem->lpwd) < 0)
425
0
        goto e0;
426
13.5k
    struct re_printf pt = {.vph = cand_printf_handler, .arg = resp};
427
13.5k
    struct list *canlist = icem_lcandl(ila_c->icem);
428
26.2k
    for(struct le *le = canlist->head; le; le = le->next) {
429
13.5k
        if (APPEND(resp, " c:") < 0)
430
0
            goto e0;
431
13.5k
        err = ice_cand_encode(&pt, (struct ice_cand *)le->data);
432
13.5k
        if (err  != 0)
433
792
            goto e0;
434
13.5k
    }
435
12.7k
    pthread_mutex_unlock(&ila_c->state_lock);
436
12.7k
    return (0);
437
792
e0:
438
792
    pthread_mutex_unlock(&ila_c->state_lock);
439
792
    return (-1);
440
13.5k
}
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.34k
{
446
9.34k
    struct ice_lite_agent_cfg *ila_c;
447
9.34k
    struct packet_processor_if stun_poi;
448
449
9.34k
    ila_c = ice_lite_data_ctor(lufrag_len, lpwd_len, pvt->mself);
450
9.34k
    if (ila_c == NULL) {
451
324
        goto e0;
452
324
    }
453
9.01k
    stun_poi = (struct packet_processor_if) {
454
9.01k
        .descr = "stun/ice",
455
9.01k
        .taste = ril_ice_taste,
456
9.01k
        .enqueue = rtpp_ice_lite_enqueue,
457
9.01k
        .key = pvt,
458
9.01k
        .arg = ila_c,
459
9.01k
        .rcnt = ila_c->rcnt
460
9.01k
    };
461
9.01k
    if (CALL_SMETHOD(ice_strmp->pproc_manager, reg, PPROC_ORD_RECV,
462
9.01k
      &stun_poi) < 0)
463
0
        goto e1;
464
9.01k
    struct rtpp_stream_pair rtcp = get_rtcp_pair(ctxp->sessp, ice_strmp);
465
9.01k
    if (rtcp.ret != 0) {
466
0
        goto e2;
467
0
    }
468
9.01k
    if (rtcp.in != NULL) {
469
9.01k
        struct packet_processor_if rtcp_dmx_poi = {
470
9.01k
            .descr = "rtcp demux",
471
9.01k
            .taste = rtpp_is_rtcp_tst,
472
9.01k
            .enqueue = rtpp_ice_lite_rtcp_dmx,
473
9.01k
            .key = pvt + 1,
474
9.01k
            .arg = &ila_c->rtcp_dmx_ctx,
475
9.01k
            .rcnt = ila_c->rcnt
476
9.01k
        };
477
9.01k
        ila_c->rtcp_dmx_ctx = (struct mux_demux_ctx) {
478
9.01k
            .strmp_in = rtcp.in,
479
9.01k
            .strmp_out = rtcp.out,
480
9.01k
        };
481
9.01k
        if (CALL_SMETHOD(ice_strmp->pproc_manager, reg, PPROC_ORD_CT_RECV,
482
9.01k
            &rtcp_dmx_poi) < 0)
483
0
            goto e2;
484
9.01k
        struct packet_processor_if rtcp_mx_poi = {
485
9.01k
            .descr = "rtcp mux",
486
9.01k
            .taste = rtpp_is_rtcp_tst,
487
9.01k
            .enqueue = rtpp_ice_lite_rtcp_mx,
488
9.01k
            .key = pvt + 2,
489
9.01k
            .arg = &ila_c->rtcp_mx_ctx,
490
9.01k
            .rcnt = ila_c->rcnt
491
9.01k
        };
492
9.01k
        ila_c->rtcp_mx_ctx = (struct mux_demux_ctx) {
493
9.01k
            .strmp_in = rtcp.out,
494
9.01k
            .strmp_out = ice_strmp,
495
9.01k
            .unreg = rtcp.in->pproc_manager->reverse,
496
9.01k
        };
497
9.01k
        if (CALL_SMETHOD(rtcp.in->pproc_manager->reverse, reg, PPROC_ORD_CT_SEND,
498
9.01k
            &rtcp_mx_poi) < 0)
499
0
            goto e3;
500
9.01k
    }
501
9.01k
    CALL_SMETHOD(ice_strmp, latch_setmode, RTPLM_FORCE_OFF);
502
9.01k
    return (ila_c);
503
0
e3:
504
0
    CALL_SMETHOD(ice_strmp->pproc_manager, unreg, pvt + 1);
505
0
e2:
506
0
    CALL_SMETHOD(ice_strmp->pproc_manager, unreg, pvt);
507
0
e1:
508
0
    RTPP_OBJ_DECREF(ila_c);
509
324
e0:
510
324
    return (NULL);
511
0
}
512
513
static int
514
rtpp_ice_lite_handle_command(struct rtpp_module_priv *pvt,
515
  const struct rtpp_subc_ctx *ctxp)
516
47.3k
{
517
47.3k
    struct ice_lite_agent_cfg *ila_c;
518
47.3k
    const rtpp_str_t *rufrag, *rpwd;
519
47.3k
    enum ril_cmd ril_cmd;
520
47.3k
    const rtpp_str_t *argv = rtpp_str_fix(&ctxp->subc_args->v[1]);
521
47.3k
    int argc = ctxp->subc_args->c - 1;
522
47.3k
    struct rtpp_stream *ice_strmp;
523
524
47.3k
    if (argc < 1) {
525
129
        RTPP_LOG(pvt->mself->log, RTPP_LOG_ERR,
526
129
          "expected at least 1 parameter: %d", argc);
527
129
        return (-1);
528
129
    }
529
47.2k
    {static int b=0; while (b);}
530
531
47.2k
    switch (argv[0].s[0] | argv[0].s[1]) {
532
165
    case 'a':
533
7.06k
    case 'A':
534
7.06k
        if (argc != 3)
535
116
            goto invalmode;
536
6.94k
        ril_cmd = RIL_CMD_A;
537
6.94k
        break;
538
539
3.41k
    case 'c':
540
22.7k
    case 'C':
541
22.7k
        if (argc < 9)
542
201
            goto invalmode;
543
22.5k
        ril_cmd = RIL_CMD_C;
544
22.5k
        break;
545
546
8.80k
    case 's':
547
14.2k
    case 'S':
548
14.2k
        if (argc != 1)
549
738
            goto invalmode;
550
13.5k
        ril_cmd = RIL_CMD_S;
551
13.5k
        break;
552
553
88
    case 'd':
554
167
    case 'D':
555
167
        if (argc != 1)
556
71
            goto invalmode;
557
96
        ril_cmd = RIL_CMD_D;
558
96
        break;
559
560
2.52k
    case 'u':
561
2.66k
    case 'U':
562
2.66k
        if (argc != 1)
563
141
            goto invalmode;
564
2.52k
        ril_cmd = RIL_CMD_U;
565
2.52k
        break;
566
567
346
    default:
568
346
        goto invalmode;
569
47.2k
    }
570
571
45.6k
    switch (ril_cmd) {
572
6.94k
    case RIL_CMD_A:
573
6.94k
        rufrag = rtpp_str_fix(&argv[1]);
574
6.94k
        rpwd = rtpp_str_fix(&argv[2]);
575
29.4k
    case RIL_CMD_C:
576
29.5k
    case RIL_CMD_D:
577
29.5k
        ice_strmp = ctxp->strmp_in;
578
29.5k
        break;
579
580
13.5k
    case RIL_CMD_S:
581
16.0k
    case RIL_CMD_U:
582
16.0k
        ice_strmp = ctxp->strmp_out;
583
16.0k
        break;
584
45.6k
    }
585
586
45.6k
    struct packet_processor_if stun_poi;
587
588
45.6k
    int lookup_res = CALL_SMETHOD(ice_strmp->pproc_manager, lookup, pvt, &stun_poi);
589
590
45.6k
    if (lookup_res != 0) {
591
36.0k
        ila_c = stun_poi.arg;
592
36.0k
    }
593
594
45.6k
    switch (ril_cmd) {
595
96
    case RIL_CMD_D:
596
2.61k
    case RIL_CMD_U:
597
2.61k
        if (lookup_res == 0)
598
123
            return (-1);
599
2.49k
        RTPP_OBJ_INCREF(ila_c); /* for the unlock */
600
2.49k
        pthread_mutex_lock(&ila_c->state_lock);
601
2.49k
        CALL_SMETHOD(ila_c->rtcp_mx_ctx.unreg, unreg, pvt + 2);
602
2.49k
        CALL_SMETHOD(ice_strmp->pproc_manager, unreg, pvt + 1);
603
2.49k
        CALL_SMETHOD(ice_strmp->pproc_manager, unreg, pvt);
604
2.49k
        CALL_SMETHOD(ice_strmp, latch_setmode, RTPLM_NORMAL);
605
2.49k
        pthread_mutex_unlock(&ila_c->state_lock);
606
2.49k
        RTPP_OBJ_DECREF(ila_c);
607
2.49k
        break;
608
609
22.5k
    case RIL_CMD_C:
610
22.5k
        if (lookup_res == 0)
611
74
            return (-1);
612
22.4k
        if (ice_lite_candidate(ila_c, argc - 1, argv + 1) != 0)
613
501
            goto e0;
614
21.9k
        break;
615
616
21.9k
   case RIL_CMD_S:
617
13.5k
        if (lookup_res == 0) {
618
3.14k
            ila_c = ice_lite_activate(pvt, ctxp, ice_strmp, ICE_LUFRAG_LEN, ICE_LPWD_LEN);
619
3.14k
            if (ila_c == NULL)
620
0
               return (-1);
621
3.14k
        }
622
13.5k
        rtpp_str_mutble_t resp = {.s = ctxp->resp->buf_t, .len = sizeof(ctxp->resp->buf_t)};
623
13.5k
        if (ice_lite_start(ila_c, ice_strmp, &resp) != 0) {
624
792
            goto e0;
625
792
        }
626
12.7k
        break;
627
628
12.7k
    case RIL_CMD_A:
629
6.94k
        if (lookup_res == 0) {
630
6.20k
            ila_c = ice_lite_activate(pvt, ctxp, ice_strmp, rufrag->len, rpwd->len);
631
6.20k
            if (ila_c == NULL)
632
324
                return (-1);
633
6.20k
        }
634
6.62k
        if (ila_set_rauth(ila_c, rufrag, rpwd) != 0)
635
0
            goto e0;
636
6.62k
        break;
637
45.6k
   }
638
639
43.7k
    RTPP_OBJ_DECREF(ila_c);
640
43.7k
    return (0);
641
642
1.61k
invalmode:
643
1.61k
    RTPP_LOG(pvt->mself->log, RTPP_LOG_ERR, "invalid mode: \"%s\"",
644
1.61k
      argv[0].s);
645
1.61k
    return (-1);
646
1.29k
e0:
647
1.29k
    RTPP_OBJ_DECREF(ila_c);
648
1.29k
    return (-1);
649
45.6k
}
650
651
static int
652
ril_ice_taste(struct pkt_proc_ctx *pktx)
653
44.4k
{
654
44.4k
    struct ice_lite_agent_cfg *ila_c;
655
656
44.4k
    ila_c = pktx->pproc->arg;
657
44.4k
    if (!rtpp_is_stun_tst(pktx)) {
658
38.9k
        if (!ila_iscompleted(ila_c)) {
659
38.9k
            pktx->auxp = NULL;
660
38.9k
            return (true);
661
38.9k
        }
662
0
        return (false);
663
38.9k
    }
664
5.50k
    pktx->auxp = ila_c;
665
5.50k
    return (true);
666
44.4k
}
667
668
static struct pproc_act
669
rtpp_ice_lite_enqueue(const struct pkt_proc_ctx *pktx)
670
44.4k
{
671
44.4k
    struct rtpp_wi *wi;
672
44.4k
    struct wipkt *wip;
673
44.4k
    struct ice_lite_agent_cfg *ila_c;
674
675
44.4k
    ila_c = (struct ice_lite_agent_cfg *)pktx->auxp;
676
44.4k
    if (ila_c == NULL)
677
38.9k
        return (PPROC_ACT_DROP);
678
5.50k
    wi = rtpp_wi_malloc_udata((void **)&wip, sizeof(struct wipkt));
679
5.50k
    if (wi == NULL)
680
0
        return (PPROC_ACT_DROP);
681
5.50k
    wip->pkt = pktx->pktp;
682
5.50k
    RTPP_OBJ_BORROW(wi, ila_c);
683
5.50k
    wip->ila_c = ila_c;
684
5.50k
    RTPP_OBJ_BORROW(wi, pktx->strmp_in);
685
5.50k
    wip->strmp_in = pktx->strmp_in;
686
5.50k
    if (rtpp_queue_put_item(wi, ila_c->mself->wthr.mod_q) != 0) {
687
0
        RTPP_OBJ_DECREF(wi);
688
0
        return (PPROC_ACT_DROP);
689
0
    }
690
5.50k
    return (PPROC_ACT_TAKE);
691
5.50k
}
692
693
static struct pproc_act
694
rtpp_ice_lite_rtcp_dmx(const struct pkt_proc_ctx *pktx)
695
0
{
696
0
    struct mux_demux_ctx *ctx = pktx->pproc->arg;
697
0
    struct pkt_proc_ctx opktx = {.strmp_in = ctx->strmp_in, .strmp_out = ctx->strmp_out,
698
0
      .pktp = pktx->pktp, .flags = pktx->flags};
699
0
    return CALL_SMETHOD(opktx.strmp_in->pproc_manager, handleat, &opktx, PPROC_ORD_CT_RECV);
700
0
}
701
702
static struct pproc_act
703
rtpp_ice_lite_rtcp_mx(const struct pkt_proc_ctx *pktx)
704
0
{
705
0
    struct mux_demux_ctx *ctx = pktx->pproc->arg;
706
0
    struct pkt_proc_ctx opktx = {.strmp_in = ctx->strmp_in, .strmp_out = ctx->strmp_out,
707
0
      .pktp = pktx->pktp, .flags = pktx->flags};
708
0
    return CALL_SMETHOD(opktx.strmp_out->pproc_manager->reverse, handleat, &opktx, PPROC_ORD_CT_SEND);
709
0
}
710
711
static struct rtpp_module_priv *
712
rtpp_ice_lite_ctor(const struct rtpp_cfg *cfsp, struct rtpp_minfo *mself)
713
4
{
714
4
    struct rtpp_module_priv *pvt;
715
716
4
    pvt = mod_zmalloc(sizeof(struct rtpp_module_priv));
717
4
    if (pvt == NULL) {
718
0
        goto e0;
719
0
    }
720
#ifdef RTPP_CHECK_LEAKS
721
    _libre_memdeb = *mself->memdeb_p;
722
#endif
723
4
    pvt->mself = mself;
724
4
    return (pvt);
725
726
0
e0:
727
0
    return (NULL);
728
4
}
729
730
static void
731
rtpp_ice_lite_dtor(struct rtpp_module_priv *pvt)
732
4
{
733
734
4
    mod_free(pvt);
735
4
    return;
736
4
}