/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 | } |