Coverage Report

Created: 2026-03-21 06:16

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 "rtpp_bindaddr.h"
75
#include "advanced/packet_processor.h"
76
#include "advanced/pproc_manager.h"
77
78
#include "rtpp_re.h"
79
#include "re_types.h"
80
#include "re_fmt.h"
81
#include "re_sa.h"
82
#include "re_ice.h"
83
#include "re_udp.h"
84
#include "re_mem.h"
85
#include "re_list.h"
86
#include "re_tmr.h"
87
#include "re_mbuf.h"
88
#include "re_stun.h"
89
#include "ice/ice.h"
90
91
struct rtpp_module_priv {
92
    struct rtpp_minfo *mself;
93
};
94
95
struct ila_sock {
96
    struct sa laddr;
97
    struct rtpp_netaddr *raddr;
98
    struct sthread_args *sender;
99
    struct rtpp_stream *strmp_in;
100
    udp_helper_recv_h *rh;
101
    void *rh_arg;
102
};
103
104
struct mux_demux_ctx {
105
    struct rtpp_stream *strmp_in;
106
    struct rtpp_stream *strmp_out;
107
    struct pproc_manager *unreg;
108
};
109
110
struct ice_lite_agent_cfg {
111
    struct rtpp_refcnt *rcnt;
112
    pthread_mutex_t state_lock;
113
    struct icem *icem;
114
    struct ila_sock *sock;
115
    struct mbuf *mb;
116
    _Atomic(bool) completed;
117
    struct mux_demux_ctx rtcp_dmx_ctx;
118
    struct mux_demux_ctx rtcp_mx_ctx;
119
    struct rtpp_minfo *mself;
120
};
121
122
static struct rtpp_module_priv *rtpp_ice_lite_ctor(const struct rtpp_cfg *,
123
  struct rtpp_minfo *);
124
static void rtpp_ice_lite_dtor(struct rtpp_module_priv *);
125
static void rtpp_ice_lite_worker(const struct rtpp_wthrdata *);
126
static int rtpp_ice_lite_handle_command(struct rtpp_module_priv *,
127
  const struct rtpp_subc_ctx *);
128
static struct pproc_act rtpp_ice_lite_rtcp_dmx(const struct pkt_proc_ctx *);
129
static struct pproc_act rtpp_ice_lite_rtcp_mx(const struct pkt_proc_ctx *);
130
static struct pproc_act rtpp_ice_lite_enqueue(const struct pkt_proc_ctx *);
131
static int ril_ice_taste(struct pkt_proc_ctx *);
132
133
#ifdef RTPP_CHECK_LEAKS
134
#include "rtpp_memdeb_internal.h"
135
void *_libre_memdeb;
136
RTPP_MEMDEB_APP_STATIC;
137
#endif
138
139
const struct rtpp_minfo RTPP_MOD_SELF = {
140
    .descr.name = "ice_lite",
141
    .descr.ver = MI_VER_INIT(),
142
    .descr.module_id = 5,
143
    .proc.ctor = rtpp_ice_lite_ctor,
144
    .proc.dtor = rtpp_ice_lite_dtor,
145
    .wapi = &(const struct rtpp_wthr_handlers){
146
        .main_thread = rtpp_ice_lite_worker,
147
        .queue_size = RTPQ_MEDIUM_CB_LEN,
148
     },
149
    .capi = &(const struct rtpp_cplane_handlers){.ul_subc_handle = rtpp_ice_lite_handle_command},
150
    .fn = &(struct rtpp_minfo_fset){0},
151
#ifdef RTPP_CHECK_LEAKS
152
    .memdeb_p = &MEMDEB_SYM
153
#endif
154
};
155
#if defined(LIBRTPPROXY)
156
DATA_SET(rtpp_modules, RTPP_MOD_SELF);
157
#endif
158
159
struct wipkt {
160
    struct rtp_packet *pkt;
161
    struct ice_lite_agent_cfg *ila_c;
162
    struct rtpp_stream *strmp_in;
163
};
164
165
void
166
re_dbg_printf(int level, const char *buf, int len)
167
511
{
168
#if defined(RTPP_DEBUG)
169
    fprintf(stderr, "%.*s", len, buf);
170
#endif
171
511
}
172
173
int
174
udp_register_helper(struct udp_helper **uhp, struct udp_sock *us, int layer,
175
  udp_helper_send_h *sh, udp_helper_recv_h *rh, void *arg)
176
8.02k
{
177
8.02k
    struct ila_sock *sock = (struct ila_sock *)us;
178
8.02k
    assert(sock->rh == NULL && sock->rh_arg == NULL);
179
8.02k
    sock->rh = rh;
180
8.02k
    sock->rh_arg = arg;
181
8.02k
    return (0);
182
8.02k
}
183
184
static void
185
rtpp2re_sa(struct sa *sad, const struct sockaddr *sas)
186
7.54k
{
187
188
7.54k
    memcpy(&sad->u.sa, sas, SA_LEN(sas));
189
7.54k
    sad->len = SA_LEN(sas);
190
7.54k
}
191
192
int
193
udp_send(struct udp_sock *us, const struct sa *dst, struct mbuf *mb)
194
{
195
    struct ila_sock *sock = (struct ila_sock *)us;
196
    struct rtp_packet *packet;
197
198
    packet = rtp_packet_alloc();
199
    if (packet == NULL)
200
        return (ENOMEM);
201
    memcpy(packet->data.buf, mb->buf, mb->end);
202
    packet->size = mb->end;
203
    CALL_SMETHOD(sock->raddr, set, &dst->u.sa, dst->len);
204
    CALL_SMETHOD(sock->strmp_in, send_pkt_to, sock->sender, packet, sock->raddr);
205
    return (0);
206
}
207
208
static bool
209
iscompleted(const struct icem *icem)
210
7.54k
{
211
7.54k
    struct le *le;
212
7.54k
    bool rval = false;
213
214
7.54k
    for (le = icem->validl.head; le; le = le->next) {
215
0
        const struct ice_candpair *cp = le->data;
216
0
        if (!icem_candpair_iscompleted(cp))
217
0
            return false;
218
0
        rval = true;
219
0
    }
220
221
7.54k
    return rval;
222
7.54k
}
223
224
static bool
225
ila_iscompleted(struct ice_lite_agent_cfg *ila_c)
226
45.7k
{
227
45.7k
    return atomic_load_explicit(&ila_c->completed, memory_order_relaxed);
228
45.7k
}
229
230
static void
231
rtpp_ice_lite_worker(const struct rtpp_wthrdata *wp)
232
4
{
233
4
    struct rtpp_wi *wi;
234
4
    struct wipkt *wip;
235
4
    struct rtp_packet *pkt;
236
4
    struct mbuf *mb;
237
4
    struct ice_lite_agent_cfg *ila_c;
238
239
7.54k
    for (;;) {
240
7.54k
        wi = rtpp_queue_get_item(wp->mod_q, 0);
241
7.54k
        if (wi == wp->sigterm) {
242
4
            RTPP_OBJ_DECREF(wi);
243
4
            break;
244
4
        }
245
7.54k
        wip = rtpp_wi_data_get_ptr(wi, sizeof(*wip), sizeof(*wip));
246
7.54k
        pkt = wip->pkt;
247
7.54k
        ila_c = wip->ila_c;
248
7.54k
        pthread_mutex_lock(&ila_c->state_lock);
249
7.54k
        mb = ila_c->mb;
250
7.54k
        assert(pkt->size <= mb->size);
251
7.54k
        memcpy(mb->buf, pkt->data.buf, pkt->size);
252
7.54k
        mb->end = pkt->size;
253
7.54k
        struct sa raddr = {0};
254
7.54k
        rtpp2re_sa(&raddr, sstosa(&pkt->raddr));
255
7.54k
        ila_c->sock->strmp_in = wip->strmp_in;
256
7.54k
        if (ila_c->sock->rh == NULL)
257
0
            goto out;
258
7.54k
        ila_c->sock->rh(&raddr, mb, ila_c->sock->rh_arg);
259
7.54k
        bool completed = iscompleted(ila_c->icem);
260
7.54k
        if (!ila_iscompleted(ila_c) && completed) {
261
0
            RTPP_LOG(ila_c->sock->strmp_in->log, RTPP_LOG_INFO, "ICE completed");
262
0
            CALL_SMETHOD(ila_c->sock->strmp_in, latch_setmode, RTPLM_FORCE_ON);
263
0
            CALL_SMETHOD(ila_c->sock->strmp_in, latch, pkt);
264
0
            atomic_store_explicit(&ila_c->completed, true, memory_order_relaxed);
265
0
        }
266
7.54k
out:
267
7.54k
        pthread_mutex_unlock(&ila_c->state_lock);
268
7.54k
        RTPP_OBJ_DECREF(pkt);
269
7.54k
        RTPP_OBJ_DECREF(wi);
270
7.54k
    }
271
4
}
272
273
static void
274
ice_lite_data_dtor(struct ice_lite_agent_cfg *pvt)
275
9.08k
{
276
277
9.08k
    pthread_mutex_destroy(&pvt->state_lock);
278
9.08k
    RTPP_OBJ_DECREF(pvt->sock->raddr);
279
9.08k
    mem_deref(pvt->mb->buf);
280
9.08k
    mem_deref(pvt->mb);
281
9.08k
    mem_deref(pvt->sock);
282
9.08k
    mem_deref(pvt->icem);
283
9.08k
    RC_DECREF(pvt->mself->super_rcnt);
284
9.08k
}
285
286
int
287
udp_local_get(const struct udp_sock *us, struct sa *local)
288
8.02k
{
289
8.02k
    struct ila_sock *sock = (struct ila_sock *)us;
290
8.02k
    *local = sock->laddr;
291
8.02k
    return (0);
292
8.02k
}
293
294
static struct ice_lite_agent_cfg *
295
ice_lite_data_ctor(int lufrag_len, int lpwd_len, struct rtpp_minfo *mself)
296
9.59k
{
297
9.59k
    struct ice_lite_agent_cfg *ila_c;
298
9.59k
    rtpp_str_mutble_t lufrag, lpwd;
299
9.59k
    uint64_t tiebrk = 1;
300
301
9.59k
    ila_c = mod_rzmalloc(sizeof(*ila_c), offsetof(typeof(*ila_c), rcnt));
302
9.59k
    if (ila_c == NULL)
303
0
        goto e0;
304
9.59k
    atomic_init(&ila_c->completed, false);
305
9.59k
    lufrag.s = alloca(lufrag_len + 1);
306
9.59k
    lpwd.s = alloca(lpwd_len + 1);
307
9.59k
    if (lufrag.s == NULL || lpwd.s == NULL)
308
0
        goto e1;
309
9.59k
    lufrag.len = lufrag_len;
310
9.59k
    generate_random_string(lufrag.s, lufrag.len);
311
9.59k
    lpwd.len = lpwd_len;
312
9.59k
    generate_random_string(lpwd.s, lpwd.len);
313
9.59k
    if (icem_alloc(&ila_c->icem, ICE_MODE_LITE, ICE_ROLE_CONTROLLED, IPPROTO_UDP, 0,
314
9.59k
      tiebrk, lufrag.s, lpwd.s, NULL, NULL) != 0)
315
511
        goto e1;
316
9.08k
    ila_c->sock = mem_zalloc(sizeof(*ila_c->sock), NULL);
317
9.08k
    if (ila_c->sock == NULL)
318
0
        goto e2;
319
9.08k
    ila_c->mb = mem_zalloc(sizeof(*ila_c->mb), NULL);
320
9.08k
    if (ila_c->mb == NULL)
321
0
        goto e3;
322
9.08k
    ila_c->mb->buf = mem_zalloc(MAX_RPKT_LEN, NULL);
323
9.08k
    if (ila_c->mb->buf == NULL)
324
0
        goto e4;
325
9.08k
    ila_c->mb->size = MAX_RPKT_LEN;
326
9.08k
    ila_c->sock->raddr = rtpp_netaddr_ctor();
327
9.08k
    if (ila_c->sock->raddr == NULL)
328
0
        goto e5;
329
9.08k
    if (pthread_mutex_init(&ila_c->state_lock, NULL) != 0)
330
0
        goto e6;
331
9.08k
    RC_INCREF(mself->super_rcnt);
332
9.08k
    ila_c->mself = mself;
333
9.08k
    RTPP_OBJ_DTOR_ATTACH_s(ila_c, (rtpp_refcnt_dtor_t)ice_lite_data_dtor, ila_c);
334
9.08k
    return (ila_c);
335
0
e6:
336
0
    RTPP_OBJ_DECREF(ila_c->sock->raddr);
337
0
e5:
338
0
    mem_deref(ila_c->mb->buf);
339
0
e4:
340
0
    mem_deref(ila_c->mb);
341
0
e3:
342
0
    mem_deref(ila_c->sock);
343
0
e2:
344
0
    mem_deref(ila_c->icem);
345
511
e1:
346
511
    mod_free(ila_c);
347
511
e0:
348
511
    return (NULL);
349
511
}
350
351
static int
352
ila_set_rauth(struct ice_lite_agent_cfg *ila_c, const rtpp_str_t *ice_rufrag,
353
  const rtpp_str_t *ice_rpwd)
354
6.97k
{
355
356
6.97k
    pthread_mutex_lock(&ila_c->state_lock);
357
6.97k
    if (icem_sdp_decode(ila_c->icem, "ice-ufrag", ice_rufrag->s) != 0)
358
0
        goto e0;
359
6.97k
    if (icem_sdp_decode(ila_c->icem, "ice-pwd", ice_rpwd->s) != 0)
360
0
        goto e0;
361
6.97k
    pthread_mutex_unlock(&ila_c->state_lock);
362
6.97k
    return 0;
363
0
e0:
364
0
    pthread_mutex_unlock(&ila_c->state_lock);
365
0
    return -1;
366
6.97k
}
367
368
enum ril_cmd {RIL_CMD_A, RIL_CMD_C, RIL_CMD_S, RIL_CMD_D, RIL_CMD_U};
369
16.0k
#define ICE_COMPID_RTP  1
370
#define ICE_COMPID_RTCP 2
371
372
2.92k
#define ICE_LUFRAG_LEN 4
373
2.92k
#define ICE_LPWD_LEN 24
374
375
static int
376
ice_lite_candidate(struct ice_lite_agent_cfg *ila_c, int c, const rtpp_str_t *v)
377
23.6k
{
378
23.6k
    struct rtpp_command_argsp args = {.c = c, .v = v};
379
23.6k
    pthread_mutex_lock(&ila_c->state_lock);
380
23.6k
    int err = rtpp_cand_decode(ila_c->icem, &args, ila_c->mself->log);
381
23.6k
    pthread_mutex_unlock(&ila_c->state_lock);
382
23.6k
    return (err);
383
23.6k
}
384
385
static int
386
cand_printf_handler(const char *p, size_t size, void *arg)
387
162k
{
388
162k
    rtpp_str_mutble_t *resp = (rtpp_str_mutble_t *)arg;
389
162k
    if (size + 1 > resp->len)
390
883
        return (ENOMEM);
391
161k
    int len = url_quote(p, resp->s, size, resp->len);
392
161k
    if (len < 0)
393
195
        return (ENOMEM);
394
161k
    resp->s += len;
395
161k
    resp->len -= len;
396
161k
    return (0);
397
161k
}
398
399
52.6k
#define APPEND(bs, ss) ({size_t len = strlcpy(bs->s, ss, bs->len); \
400
52.6k
  int err = (len > bs->len); bs->len -= (err) ? 0:len, bs->s += (err) ? 0:len; err;})
401
402
static int
403
ice_lite_start(struct ice_lite_agent_cfg *ila_c, struct rtpp_stream *isp,
404
  rtpp_str_mutble_t *resp)
405
13.1k
{
406
13.1k
    int err;
407
13.1k
    struct sa *laddr;
408
409
13.1k
    pthread_mutex_lock(&ila_c->state_lock);
410
13.1k
    laddr = &ila_c->sock->laddr;
411
13.1k
    if (laddr->len == 0) {
412
8.02k
        const struct sockaddr *s_laddr = isp->laddr->addr;
413
8.02k
        memcpy(&laddr->u.sa, s_laddr, SA_LEN(s_laddr));
414
8.02k
        laddr->len = SA_LEN(s_laddr);
415
8.02k
        sa_set_port(laddr, isp->port);
416
417
8.02k
        err = icem_comp_add(ila_c->icem, ICE_COMPID_RTP, ila_c->sock);
418
8.02k
        if (err != 0)
419
0
            goto e0;
420
8.02k
        err = icem_cand_add(ila_c->icem, ICE_COMPID_RTP, 0, NULL, laddr);
421
8.02k
        if (err != 0)
422
0
            goto e0;
423
8.02k
    }
424
13.1k
    if (APPEND(resp, ila_c->icem->lufrag) < 0)
425
0
        goto e0;
426
13.1k
    if (APPEND(resp, " ") < 0)
427
0
        goto e0;
428
13.1k
    if (APPEND(resp, ila_c->icem->lpwd) < 0)
429
0
        goto e0;
430
13.1k
    struct re_printf pt = {.vph = cand_printf_handler, .arg = resp};
431
13.1k
    struct list *canlist = icem_lcandl(ila_c->icem);
432
25.2k
    for(struct le *le = canlist->head; le; le = le->next) {
433
13.1k
        if (APPEND(resp, " c:") < 0)
434
0
            goto e0;
435
13.1k
        err = ice_cand_encode(&pt, (struct ice_cand *)le->data);
436
13.1k
        if (err  != 0)
437
1.07k
            goto e0;
438
13.1k
    }
439
12.0k
    pthread_mutex_unlock(&ila_c->state_lock);
440
12.0k
    return (0);
441
1.07k
e0:
442
1.07k
    pthread_mutex_unlock(&ila_c->state_lock);
443
1.07k
    return (-1);
444
13.1k
}
445
446
static struct ice_lite_agent_cfg *
447
ice_lite_activate(struct rtpp_module_priv *pvt, const struct rtpp_subc_ctx *ctxp,
448
  struct rtpp_stream *ice_strmp, int lufrag_len, int lpwd_len)
449
9.59k
{
450
9.59k
    struct ice_lite_agent_cfg *ila_c;
451
9.59k
    struct packet_processor_if stun_poi;
452
453
9.59k
    ila_c = ice_lite_data_ctor(lufrag_len, lpwd_len, pvt->mself);
454
9.59k
    if (ila_c == NULL) {
455
511
        goto e0;
456
511
    }
457
9.08k
    stun_poi = (struct packet_processor_if) {
458
9.08k
        .descr = "stun/ice",
459
9.08k
        .taste = ril_ice_taste,
460
9.08k
        .enqueue = rtpp_ice_lite_enqueue,
461
9.08k
        .key = pvt,
462
9.08k
        .arg = ila_c,
463
9.08k
        .rcnt = ila_c->rcnt
464
9.08k
    };
465
9.08k
    if (CALL_SMETHOD(ice_strmp->pproc_manager, reg, PPROC_ORD_RECV,
466
9.08k
      &stun_poi) < 0)
467
0
        goto e1;
468
9.08k
    struct rtpp_stream_pair rtcp = get_rtcp_pair(ctxp->env->sessp, ice_strmp);
469
9.08k
    if (rtcp.ret != 0) {
470
0
        goto e2;
471
0
    }
472
9.08k
    if (rtcp.in != NULL) {
473
9.08k
        struct packet_processor_if rtcp_dmx_poi = {
474
9.08k
            .descr = "rtcp demux",
475
9.08k
            .taste = rtpp_is_rtcp_tst,
476
9.08k
            .enqueue = rtpp_ice_lite_rtcp_dmx,
477
9.08k
            .key = pvt + 1,
478
9.08k
            .arg = &ila_c->rtcp_dmx_ctx,
479
9.08k
            .rcnt = ila_c->rcnt
480
9.08k
        };
481
9.08k
        ila_c->rtcp_dmx_ctx = (struct mux_demux_ctx) {
482
9.08k
            .strmp_in = rtcp.in,
483
9.08k
            .strmp_out = rtcp.out,
484
9.08k
        };
485
9.08k
        if (CALL_SMETHOD(ice_strmp->pproc_manager, reg, PPROC_ORD_CT_RECV,
486
9.08k
            &rtcp_dmx_poi) < 0)
487
0
            goto e2;
488
9.08k
        struct packet_processor_if rtcp_mx_poi = {
489
9.08k
            .descr = "rtcp mux",
490
9.08k
            .taste = rtpp_is_rtcp_tst,
491
9.08k
            .enqueue = rtpp_ice_lite_rtcp_mx,
492
9.08k
            .key = pvt + 2,
493
9.08k
            .arg = &ila_c->rtcp_mx_ctx,
494
9.08k
            .rcnt = ila_c->rcnt
495
9.08k
        };
496
9.08k
        ila_c->rtcp_mx_ctx = (struct mux_demux_ctx) {
497
9.08k
            .strmp_in = rtcp.out,
498
9.08k
            .strmp_out = ice_strmp,
499
9.08k
            .unreg = rtcp.in->pproc_manager->reverse,
500
9.08k
        };
501
9.08k
        if (CALL_SMETHOD(rtcp.in->pproc_manager->reverse, reg, PPROC_ORD_CT_SEND,
502
9.08k
            &rtcp_mx_poi) < 0)
503
0
            goto e3;
504
9.08k
    }
505
9.08k
    CALL_SMETHOD(ice_strmp, latch_setmode, RTPLM_FORCE_OFF);
506
9.08k
    return (ila_c);
507
0
e3:
508
0
    CALL_SMETHOD(ice_strmp->pproc_manager, unreg, pvt + 1);
509
0
e2:
510
0
    CALL_SMETHOD(ice_strmp->pproc_manager, unreg, pvt);
511
0
e1:
512
0
    RTPP_OBJ_DECREF(ila_c);
513
511
e0:
514
511
    return (NULL);
515
0
}
516
517
static int
518
rtpp_ice_lite_handle_command(struct rtpp_module_priv *pvt,
519
  const struct rtpp_subc_ctx *ctxp)
520
48.8k
{
521
48.8k
    struct ice_lite_agent_cfg *ila_c;
522
48.8k
    const rtpp_str_t *rufrag, *rpwd;
523
48.8k
    enum ril_cmd ril_cmd;
524
48.8k
    const rtpp_str_t *argv = rtpp_str_fix(&ctxp->subc_args->v[1]);
525
48.8k
    int argc = ctxp->subc_args->c - 1;
526
48.8k
    struct rtpp_stream *ice_strmp;
527
528
48.8k
    if (argc < 1) {
529
108
        RTPP_LOG(pvt->mself->log, RTPP_LOG_ERR,
530
108
          "expected at least 1 parameter: %d", argc);
531
108
        return (-1);
532
108
    }
533
48.7k
    {static int b=0; while (b);}
534
535
48.7k
    switch (argv[0].s[0] | argv[0].s[1]) {
536
472
    case 'a':
537
7.72k
    case 'A':
538
7.72k
        if (argc != 3)
539
233
            goto invalmode;
540
7.48k
        ril_cmd = RIL_CMD_A;
541
7.48k
        break;
542
543
3.18k
    case 'c':
544
23.8k
    case 'C':
545
23.8k
        if (argc < 9)
546
165
            goto invalmode;
547
23.6k
        ril_cmd = RIL_CMD_C;
548
23.6k
        break;
549
550
8.11k
    case 's':
551
13.8k
    case 'S':
552
13.8k
        if (argc != 1)
553
691
            goto invalmode;
554
13.1k
        ril_cmd = RIL_CMD_S;
555
13.1k
        break;
556
557
386
    case 'd':
558
584
    case 'D':
559
584
        if (argc != 1)
560
197
            goto invalmode;
561
387
        ril_cmd = RIL_CMD_D;
562
387
        break;
563
564
2.34k
    case 'u':
565
2.47k
    case 'U':
566
2.47k
        if (argc != 1)
567
136
            goto invalmode;
568
2.34k
        ril_cmd = RIL_CMD_U;
569
2.34k
        break;
570
571
294
    default:
572
294
        goto invalmode;
573
48.7k
    }
574
575
47.0k
    switch (ril_cmd) {
576
7.48k
    case RIL_CMD_A:
577
7.48k
        rufrag = rtpp_str_fix(&argv[1]);
578
7.48k
        rpwd = rtpp_str_fix(&argv[2]);
579
31.1k
    case RIL_CMD_C:
580
31.5k
    case RIL_CMD_D:
581
31.5k
        ice_strmp = ctxp->env->strmp_in;
582
31.5k
        break;
583
584
13.1k
    case RIL_CMD_S:
585
15.5k
    case RIL_CMD_U:
586
15.5k
        ice_strmp = ctxp->env->strmp_out;
587
15.5k
        break;
588
47.0k
    }
589
590
47.0k
    struct packet_processor_if stun_poi;
591
592
47.0k
    int lookup_res = CALL_SMETHOD(ice_strmp->pproc_manager, lookup, pvt, &stun_poi);
593
594
47.0k
    if (lookup_res != 0) {
595
36.9k
        ila_c = stun_poi.arg;
596
36.9k
    }
597
598
47.0k
    switch (ril_cmd) {
599
387
    case RIL_CMD_D:
600
2.73k
    case RIL_CMD_U:
601
2.73k
        if (lookup_res == 0)
602
406
            return (-1);
603
2.32k
        RTPP_OBJ_INCREF(ila_c); /* for the unlock */
604
2.32k
        pthread_mutex_lock(&ila_c->state_lock);
605
2.32k
        CALL_SMETHOD(ila_c->rtcp_mx_ctx.unreg, unreg, pvt + 2);
606
2.32k
        CALL_SMETHOD(ice_strmp->pproc_manager, unreg, pvt + 1);
607
2.32k
        CALL_SMETHOD(ice_strmp->pproc_manager, unreg, pvt);
608
2.32k
        CALL_SMETHOD(ice_strmp, latch_setmode, RTPLM_NORMAL);
609
2.32k
        pthread_mutex_unlock(&ila_c->state_lock);
610
2.32k
        RTPP_OBJ_DECREF(ila_c);
611
2.32k
        break;
612
613
23.6k
    case RIL_CMD_C:
614
23.6k
        if (lookup_res == 0)
615
72
            return (-1);
616
23.6k
        if (ice_lite_candidate(ila_c, argc - 1, argv + 1) != 0)
617
498
            goto e0;
618
23.1k
        break;
619
620
23.1k
   case RIL_CMD_S:
621
13.1k
        if (lookup_res == 0) {
622
2.92k
            ila_c = ice_lite_activate(pvt, ctxp, ice_strmp, ICE_LUFRAG_LEN, ICE_LPWD_LEN);
623
2.92k
            if (ila_c == NULL)
624
0
               return (-1);
625
2.92k
        }
626
13.1k
        rtpp_str_mutble_t resp = {.s = ctxp->resp->buf_t, .len = sizeof(ctxp->resp->buf_t)};
627
13.1k
        if (ice_lite_start(ila_c, ice_strmp, &resp) != 0) {
628
1.07k
            goto e0;
629
1.07k
        }
630
12.0k
        break;
631
632
12.0k
    case RIL_CMD_A:
633
7.48k
        if (lookup_res == 0) {
634
6.67k
            ila_c = ice_lite_activate(pvt, ctxp, ice_strmp, rufrag->len, rpwd->len);
635
6.67k
            if (ila_c == NULL)
636
511
                return (-1);
637
6.67k
        }
638
6.97k
        if (ila_set_rauth(ila_c, rufrag, rpwd) != 0)
639
0
            goto e0;
640
6.97k
        break;
641
47.0k
   }
642
643
44.5k
    RTPP_OBJ_DECREF(ila_c);
644
44.5k
    return (0);
645
646
1.71k
invalmode:
647
1.71k
    RTPP_LOG(pvt->mself->log, RTPP_LOG_ERR, "invalid mode: \"%s\"",
648
1.71k
      argv[0].s);
649
1.71k
    return (-1);
650
1.57k
e0:
651
1.57k
    RTPP_OBJ_DECREF(ila_c);
652
1.57k
    return (-1);
653
47.0k
}
654
655
static int
656
ril_ice_taste(struct pkt_proc_ctx *pktx)
657
45.7k
{
658
45.7k
    struct ice_lite_agent_cfg *ila_c;
659
660
45.7k
    ila_c = pktx->pproc->arg;
661
45.7k
    if (!rtpp_is_stun_tst(pktx)) {
662
38.1k
        if (!ila_iscompleted(ila_c)) {
663
38.1k
            pktx->auxp = NULL;
664
38.1k
            return (true);
665
38.1k
        }
666
0
        return (false);
667
38.1k
    }
668
7.54k
    pktx->auxp = ila_c;
669
7.54k
    return (true);
670
45.7k
}
671
672
static struct pproc_act
673
rtpp_ice_lite_enqueue(const struct pkt_proc_ctx *pktx)
674
45.7k
{
675
45.7k
    struct rtpp_wi *wi;
676
45.7k
    struct wipkt *wip;
677
45.7k
    struct ice_lite_agent_cfg *ila_c;
678
679
45.7k
    ila_c = (struct ice_lite_agent_cfg *)pktx->auxp;
680
45.7k
    if (ila_c == NULL)
681
38.1k
        return (PPROC_ACT_DROP);
682
7.54k
    wi = rtpp_wi_malloc_udata((void **)&wip, sizeof(struct wipkt));
683
7.54k
    if (wi == NULL)
684
0
        return (PPROC_ACT_DROP);
685
7.54k
    wip->pkt = pktx->pktp;
686
7.54k
    RTPP_OBJ_BORROW_s(wi, ila_c);
687
7.54k
    wip->ila_c = ila_c;
688
7.54k
    RTPP_OBJ_BORROW_s(wi, pktx->strmp_in);
689
7.54k
    wip->strmp_in = pktx->strmp_in;
690
7.54k
    if (rtpp_queue_put_item(wi, ila_c->mself->wthr.mod_q) != 0) {
691
0
        RTPP_OBJ_DECREF(wi);
692
0
        return (PPROC_ACT_DROP);
693
0
    }
694
7.54k
    return (PPROC_ACT_TAKE);
695
7.54k
}
696
697
static struct pproc_act
698
rtpp_ice_lite_rtcp_dmx(const struct pkt_proc_ctx *pktx)
699
0
{
700
0
    struct mux_demux_ctx *ctx = pktx->pproc->arg;
701
0
    struct pkt_proc_ctx opktx = {.strmp_in = ctx->strmp_in, .strmp_out = ctx->strmp_out,
702
0
      .pktp = pktx->pktp, .flags = pktx->flags};
703
0
    return CALL_SMETHOD(opktx.strmp_in->pproc_manager, handleat, &opktx, PPROC_ORD_CT_RECV);
704
0
}
705
706
static struct pproc_act
707
rtpp_ice_lite_rtcp_mx(const struct pkt_proc_ctx *pktx)
708
0
{
709
0
    struct mux_demux_ctx *ctx = pktx->pproc->arg;
710
0
    struct pkt_proc_ctx opktx = {.strmp_in = ctx->strmp_in, .strmp_out = ctx->strmp_out,
711
0
      .pktp = pktx->pktp, .flags = pktx->flags};
712
0
    return CALL_SMETHOD(opktx.strmp_out->pproc_manager->reverse, handleat, &opktx, PPROC_ORD_CT_SEND);
713
0
}
714
715
static struct rtpp_module_priv *
716
rtpp_ice_lite_ctor(const struct rtpp_cfg *cfsp, struct rtpp_minfo *mself)
717
4
{
718
4
    struct rtpp_module_priv *pvt;
719
720
4
    pvt = mod_zmalloc(sizeof(struct rtpp_module_priv));
721
4
    if (pvt == NULL) {
722
0
        goto e0;
723
0
    }
724
#ifdef RTPP_CHECK_LEAKS
725
    _libre_memdeb = *mself->memdeb_p;
726
#endif
727
4
    pvt->mself = mself;
728
4
    return (pvt);
729
730
0
e0:
731
0
    return (NULL);
732
4
}
733
734
static void
735
rtpp_ice_lite_dtor(struct rtpp_module_priv *pvt)
736
4
{
737
738
4
    mod_free(pvt);
739
4
    return;
740
4
}