Coverage Report

Created: 2025-10-10 06:25

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
274k
#define A2PL(a, i) S2PL(&(a)->v[i])
26
274k
#define S2PL(sp) (struct pl){.p=(sp)->s, .l=(sp)->len}
27
222
#define PL4P(pl) ((int)(pl).l), (pl).p
28
29
static enum ice_transp transp_resolve(const struct pl *transp)
30
22.0k
{
31
22.0k
        if (!pl_strcasecmp(transp, "UDP"))
32
21.9k
                return ICE_TRANSP_UDP;
33
34
74
        return ICE_TRANSP_NONE;
35
22.0k
}
36
37
int
38
rtpp_cand_decode(struct icem *icem, const struct rtpp_command_argsp *args,
39
  struct rtpp_log *log)
40
22.2k
{
41
22.2k
    static const char rel_addr_str[] = "raddr";
42
22.2k
    static const char rel_port_str[] = "rport";
43
22.2k
    struct pl foundation, compid, transp, prio, addr, port, cand_type;
44
22.2k
    struct sa caddr, rel_addr;
45
22.2k
    char type[8];
46
22.2k
    uint8_t cid;
47
22.2k
    int err;
48
49
22.2k
    if (args->c < 8 || pl_strcasecmp(&A2PL(args, 6), "typ") != 0)
50
230
        return EINVAL;
51
52
22.0k
    foundation = A2PL(args, 0);
53
22.0k
    compid = A2PL(args, 1);
54
22.0k
    transp = A2PL(args, 2);
55
22.0k
    prio = A2PL(args, 3);
56
22.0k
    addr = A2PL(args, 4);
57
22.0k
    port = A2PL(args, 5);
58
22.0k
    cand_type = A2PL(args, 7);
59
22.0k
    struct rtpp_command_argsp extra = {.c = args->c - 8, .v = args->v + 8};
60
61
22.0k
    if (ICE_TRANSP_NONE == transp_resolve(&transp)) {
62
74
        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
74
        } else {
67
74
            RTPP_LOG(log, RTPP_LOG_WARN, "<%s> ignoring candidate with"
68
148
              " unknown transport=%.*s (%.*s:%.*s)",
69
148
              icem->name, PL4P(transp), PL4P(cand_type), PL4P(addr));
70
74
        }
71
74
        return EINVAL;
72
74
    }
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.9k
    if (memchr(addr.p, ':', addr.l)) {
77
3.05k
        sa_init(&rel_addr, AF_INET6);
78
18.8k
    } else {
79
18.8k
        sa_init(&rel_addr, AF_INET);
80
18.8k
    }
81
82
    /* Loop through " SP attr SP value" pairs */
83
71.1k
    while (extra.c >= 2) {
84
49.2k
        struct pl name, value;
85
49.2k
        name = A2PL(&extra, 0);
86
49.2k
        value = A2PL(&extra, 1);
87
49.2k
        extra.c -= 2;
88
49.2k
        extra.v += 2;
89
90
49.2k
        if (0 == pl_strcasecmp(&name, rel_addr_str)) {
91
5.29k
            err = sa_set(&rel_addr, &value,
92
5.29k
                        sa_port(&rel_addr));
93
5.29k
            if (err)
94
69
                return (err);
95
5.29k
        }
96
44.0k
        else if (0 == pl_strcasecmp(&name, rel_port_str)) {
97
5.15k
            sa_set_port(&rel_addr, pl_u32(&value));
98
5.15k
        }
99
49.2k
    }
100
101
21.8k
    err = sa_set(&caddr, &addr, pl_u32(&port));
102
21.8k
    if (err)
103
146
        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.40k
        return 0;
110
111
20.3k
    (void)pl_strcpy(&cand_type, type, sizeof(type));
112
113
20.3k
    return icem_rcand_add(icem, ice_cand_name2type(type), cid,
114
20.3k
      pl_u32(&prio), &caddr, &rel_addr, &foundation);
115
21.7k
}