Coverage Report

Created: 2026-09-14 07:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/rtpproxy/libre/rtpp_re_icesdp.c
Line
Count
Source
1
#include <errno.h>
2
#include <stdbool.h>
3
#include <stdint.h>
4
#include <stdlib.h>
5
#include <string.h>
6
7
0
#define DEBUG_MODULE "icesdp"
8
#define DEBUG_LEVEL 5
9
10
struct stun_msg;
11
12
#include "re_dbg.h"
13
#include "re_fmt.h"
14
#include "re_sa.h"
15
#include "re_list.h"
16
#include "re_ice.h"
17
#include "re_tmr.h"
18
#include "ice/ice.h"
19
20
#include "rtpp_types.h"
21
#include "rtpp_log.h"
22
#include "rtpp_log_obj.h"
23
#include "rtpp_command_args.h"
24
25
277k
#define A2PL(a, i) S2PL(&(a)->v[i])
26
277k
#define S2PL(sp) (struct pl){.p=(sp)->s, .l=(sp)->len}
27
303
#define PL4P(pl) ((int)(pl).l), (pl).p
28
29
static enum ice_transp transp_resolve(const struct pl *transp)
30
21.9k
{
31
21.9k
        if (!pl_strcasecmp(transp, "UDP"))
32
21.8k
                return ICE_TRANSP_UDP;
33
34
101
        return ICE_TRANSP_NONE;
35
21.9k
}
36
37
int
38
rtpp_cand_decode(struct icem *icem, const struct rtpp_command_argsp *args,
39
  struct rtpp_log *log)
40
22.1k
{
41
22.1k
    static const char rel_addr_str[] = "raddr";
42
22.1k
    static const char rel_port_str[] = "rport";
43
22.1k
    struct pl foundation, compid, transp, prio, addr, port, cand_type;
44
22.1k
    struct sa caddr, rel_addr;
45
22.1k
    char type[8];
46
22.1k
    uint8_t cid;
47
22.1k
    int err;
48
49
22.1k
    if (args->c < 8 || pl_strcasecmp(&A2PL(args, 6), "typ") != 0)
50
202
        return EINVAL;
51
52
21.9k
    foundation = A2PL(args, 0);
53
21.9k
    compid = A2PL(args, 1);
54
21.9k
    transp = A2PL(args, 2);
55
21.9k
    prio = A2PL(args, 3);
56
21.9k
    addr = A2PL(args, 4);
57
21.9k
    port = A2PL(args, 5);
58
21.9k
    cand_type = A2PL(args, 7);
59
21.9k
    struct rtpp_command_argsp extra = {.c = args->c - 8, .v = args->v + 8};
60
61
21.9k
    if (ICE_TRANSP_NONE == transp_resolve(&transp)) {
62
101
        if (log == NULL) {
63
0
            DEBUG_NOTICE("<%s> ignoring candidate with"
64
0
              " unknown transport=%r (%r:%r)\n",
65
0
              icem->name, &transp, &cand_type, &addr);
66
101
        } else {
67
101
            RTPP_LOG(log, RTPP_LOG_WARN, "<%s> ignoring candidate with"
68
202
              " unknown transport=%.*s (%.*s:%.*s)",
69
202
              icem->name, PL4P(transp), PL4P(cand_type), PL4P(addr));
70
101
        }
71
101
        return EINVAL;
72
101
    }
73
    /* "When parsing this field, an agent can differentiate an IPv4
74
        address and an IPv6 address by presence of a colon in its value -
75
        the presence of a colon indicates IPv6." */
76
21.8k
    if (memchr(addr.p, ':', addr.l)) {
77
2.40k
        sa_init(&rel_addr, AF_INET6);
78
19.4k
    } else {
79
19.4k
        sa_init(&rel_addr, AF_INET);
80
19.4k
    }
81
82
    /* Loop through " SP attr SP value" pairs */
83
72.4k
    while (extra.c >= 2) {
84
50.6k
        struct pl name, value;
85
50.6k
        name = A2PL(&extra, 0);
86
50.6k
        value = A2PL(&extra, 1);
87
50.6k
        extra.c -= 2;
88
50.6k
        extra.v += 2;
89
90
50.6k
        if (0 == pl_strcasecmp(&name, rel_addr_str)) {
91
5.26k
            err = sa_set(&rel_addr, &value,
92
5.26k
                        sa_port(&rel_addr));
93
5.26k
            if (err)
94
30
                return (err);
95
5.26k
        }
96
45.3k
        else if (0 == pl_strcasecmp(&name, rel_port_str)) {
97
5.11k
            sa_set_port(&rel_addr, pl_u32(&value));
98
5.11k
        }
99
50.6k
    }
100
101
21.8k
    err = sa_set(&caddr, &addr, pl_u32(&port));
102
21.8k
    if (err)
103
89
        return err;
104
105
21.7k
    cid = pl_u32(&compid);
106
107
    /* add only if not exist */
108
21.7k
    if (icem_cand_find(&icem->rcandl, cid, &caddr))
109
1.11k
        return 0;
110
111
20.6k
    (void)pl_strcpy(&cand_type, type, sizeof(type));
112
113
20.6k
    return icem_rcand_add(icem, ice_cand_name2type(type), cid,
114
20.6k
      pl_u32(&prio), &caddr, &rel_addr, &foundation);
115
21.7k
}