Coverage Report

Created: 2026-01-13 06:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/coturn/src/apps/common/stun_buffer.c
Line
Count
Source
1
/*
2
 * SPDX-License-Identifier: BSD-3-Clause
3
 *
4
 * https://opensource.org/license/bsd-3-clause
5
 *
6
 * Copyright (C) 2011, 2012, 2013 Citrix Systems
7
 *
8
 * All rights reserved.
9
 *
10
 * Redistribution and use in source and binary forms, with or without
11
 * modification, are permitted provided that the following conditions
12
 * are met:
13
 * 1. Redistributions of source code must retain the above copyright
14
 *    notice, this list of conditions and the following disclaimer.
15
 * 2. Redistributions in binary form must reproduce the above copyright
16
 *    notice, this list of conditions and the following disclaimer in the
17
 *    documentation and/or other materials provided with the distribution.
18
 * 3. Neither the name of the project nor the names of its contributors
19
 *    may be used to endorse or promote products derived from this software
20
 *    without specific prior written permission.
21
 *
22
 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
23
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
26
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32
 * SUCH DAMAGE.
33
 */
34
35
#include "stun_buffer.h"
36
37
#include <string.h> // for memset
38
39
////////////////////// BUFFERS ///////////////////////////
40
41
0
int stun_init_buffer(stun_buffer *buf) {
42
0
  if (!buf) {
43
0
    return -1;
44
0
  }
45
0
  memset(buf->buf, 0, sizeof(buf->buf));
46
0
  buf->len = 0;
47
0
  buf->offset = 0;
48
0
  buf->coffset = 0;
49
0
  return 0;
50
0
}
51
52
0
int stun_get_size(const stun_buffer *buf) {
53
0
  if (!buf) {
54
0
    return 0;
55
0
  }
56
0
  return sizeof(buf->buf);
57
0
}
58
59
////////////////////////////////////////////////////////////
60
61
0
void stun_tid_from_message(const stun_buffer *buf, stun_tid *id) {
62
0
  stun_tid_from_message_str(buf->buf, (size_t)(buf->len), id);
63
0
}
64
65
0
void stun_tid_generate_in_message(stun_buffer *buf, stun_tid *id) {
66
0
  if (buf) {
67
0
    stun_tid_generate_in_message_str(buf->buf, id);
68
0
  }
69
0
}
70
71
////////////////////////////////////////////////////////
72
73
0
static inline bool is_channel_msg(const stun_buffer *buf) {
74
0
  if (buf && buf->len > 0) {
75
0
    return is_channel_msg_str(buf->buf, (size_t)(buf->len));
76
0
  }
77
0
  return false;
78
0
}
79
80
206
bool stun_is_command_message(const stun_buffer *buf) {
81
206
  if (!buf || buf->len <= 0) {
82
0
    return false;
83
206
  } else {
84
206
    return stun_is_command_message_str(buf->buf, (size_t)(buf->len));
85
206
  }
86
206
}
87
88
0
bool stun_is_request(const stun_buffer *buf) { return stun_is_request_str(buf->buf, (size_t)buf->len); }
89
90
52
bool stun_is_success_response(const stun_buffer *buf) {
91
52
  return stun_is_success_response_str(buf->buf, (size_t)(buf->len));
92
52
}
93
94
0
bool stun_is_error_response(const stun_buffer *buf, int *err_code, uint8_t *err_msg, size_t err_msg_size) {
95
0
  return stun_is_error_response_str(buf->buf, (size_t)(buf->len), err_code, err_msg, err_msg_size);
96
0
}
97
98
60
bool stun_is_response(const stun_buffer *buf) { return stun_is_response_str(buf->buf, (size_t)(buf->len)); }
99
100
0
bool stun_is_indication(const stun_buffer *buf) {
101
0
  if (is_channel_msg(buf)) {
102
0
    return false;
103
0
  }
104
0
  return IS_STUN_INDICATION(stun_get_msg_type(buf));
105
0
}
106
107
0
uint16_t stun_get_method(const stun_buffer *buf) { return stun_get_method_str(buf->buf, (size_t)(buf->len)); }
108
109
0
uint16_t stun_get_msg_type(const stun_buffer *buf) {
110
0
  if (!buf) {
111
0
    return (uint16_t)-1;
112
0
  }
113
0
  return stun_get_msg_type_str(buf->buf, (size_t)buf->len);
114
0
}
115
116
////////////////////////////////////////////////////////////
117
118
0
static void stun_init_command(uint16_t message_type, stun_buffer *buf) {
119
0
  buf->len = stun_get_size(buf);
120
0
  stun_init_command_str(message_type, buf->buf, &(buf->len));
121
0
}
122
123
0
void stun_init_request(uint16_t method, stun_buffer *buf) { stun_init_command(stun_make_request(method), buf); }
124
125
0
void stun_init_indication(uint16_t method, stun_buffer *buf) { stun_init_command(stun_make_indication(method), buf); }
126
127
0
void stun_init_success_response(uint16_t method, stun_buffer *buf, stun_tid *id) {
128
0
  buf->len = stun_get_size(buf);
129
0
  stun_init_success_response_str(method, buf->buf, &(buf->len), id);
130
0
}
131
132
void stun_init_error_response(uint16_t method, stun_buffer *buf, uint16_t error_code, const uint8_t *reason,
133
0
                              stun_tid *id) {
134
0
  buf->len = stun_get_size(buf);
135
0
  stun_init_error_response_str(method, buf->buf, &(buf->len), error_code, reason, id);
136
0
}
137
138
///////////////////////////////////////////////////////////////////////////////
139
140
0
int stun_get_command_message_len(const stun_buffer *buf) {
141
0
  return stun_get_command_message_len_str(buf->buf, buf->len);
142
0
}
143
144
///////////////////////////////////////////////////////////////////////////////
145
146
0
bool stun_init_channel_message(uint16_t chnumber, stun_buffer *buf, int length, bool do_padding) {
147
0
  return stun_init_channel_message_str(chnumber, buf->buf, &(buf->len), length, do_padding);
148
0
}
149
150
0
bool stun_is_channel_message(stun_buffer *buf, uint16_t *chnumber, bool is_padding_mandatory) {
151
0
  if (!buf) {
152
0
    return false;
153
0
  }
154
0
  size_t blen = buf->len;
155
0
  const bool ret = stun_is_channel_message_str(buf->buf, &blen, chnumber, is_padding_mandatory);
156
0
  if (ret) {
157
0
    buf->len = blen;
158
0
  }
159
0
  return ret;
160
0
}
161
162
///////////////////////////////////////////////////////////////////////////////
163
164
bool stun_set_allocate_request(stun_buffer *buf, uint32_t lifetime, bool af4, bool af6, uint8_t transport, bool mobile,
165
0
                               const char *rt, int ep) {
166
0
  return stun_set_allocate_request_str(buf->buf, &(buf->len), lifetime, af4, af6, transport, mobile, rt, ep);
167
0
}
168
169
bool stun_set_allocate_response(stun_buffer *buf, stun_tid *tid, const ioa_addr *relayed_addr1,
170
                                const ioa_addr *relayed_addr2, const ioa_addr *reflexive_addr, uint32_t lifetime,
171
                                uint32_t max_lifetime, int error_code, const uint8_t *reason,
172
0
                                uint64_t reservation_token, char *mobile_id) {
173
174
0
  return stun_set_allocate_response_str(buf->buf, &(buf->len), tid, relayed_addr1, relayed_addr2, reflexive_addr,
175
0
                                        lifetime, max_lifetime, error_code, reason, reservation_token, mobile_id);
176
0
}
177
178
///////////////////////////////////////////////////////////////////////////////
179
180
0
uint16_t stun_set_channel_bind_request(stun_buffer *buf, const ioa_addr *peer_addr, uint16_t channel_number) {
181
182
0
  return stun_set_channel_bind_request_str(buf->buf, &(buf->len), peer_addr, channel_number);
183
0
}
184
185
0
void stun_set_channel_bind_response(stun_buffer *buf, stun_tid *tid, int error_code, const uint8_t *reason) {
186
0
  stun_set_channel_bind_response_str(buf->buf, &(buf->len), tid, error_code, reason);
187
0
}
188
189
////////////////////////////////////////////////////////////////
190
191
0
stun_attr_ref stun_attr_get_first(const stun_buffer *buf) { return stun_attr_get_first_str(buf->buf, buf->len); }
192
193
0
stun_attr_ref stun_attr_get_next(const stun_buffer *buf, stun_attr_ref prev) {
194
0
  return stun_attr_get_next_str(buf->buf, buf->len, prev);
195
0
}
196
197
0
bool stun_attr_add(stun_buffer *buf, uint16_t attr, const char *avalue, int alen) {
198
0
  return stun_attr_add_str(buf->buf, &(buf->len), attr, (const uint8_t *)avalue, alen);
199
0
}
200
201
0
bool stun_attr_add_channel_number(stun_buffer *buf, uint16_t chnumber) {
202
0
  return stun_attr_add_channel_number_str(buf->buf, &(buf->len), chnumber);
203
0
}
204
205
0
bool stun_attr_add_addr(stun_buffer *buf, uint16_t attr_type, const ioa_addr *ca) {
206
0
  return stun_attr_add_addr_str(buf->buf, &(buf->len), attr_type, ca);
207
0
}
208
209
0
bool stun_attr_get_addr(const stun_buffer *buf, stun_attr_ref attr, ioa_addr *ca, const ioa_addr *default_addr) {
210
0
  return stun_attr_get_addr_str(buf->buf, buf->len, attr, ca, default_addr);
211
0
}
212
213
0
bool stun_attr_get_first_addr(const stun_buffer *buf, uint16_t attr_type, ioa_addr *ca, const ioa_addr *default_addr) {
214
0
  return stun_attr_get_first_addr_str(buf->buf, buf->len, attr_type, ca, default_addr);
215
0
}
216
217
0
bool stun_attr_add_even_port(stun_buffer *buf, uint8_t value) {
218
0
  if (value) {
219
0
    value = 0x80;
220
0
  }
221
0
  return stun_attr_add(buf, STUN_ATTRIBUTE_EVEN_PORT, (const char *)&value, 1);
222
0
}
223
224
0
uint16_t stun_attr_get_first_channel_number(const stun_buffer *buf) {
225
0
  return stun_attr_get_first_channel_number_str(buf->buf, buf->len);
226
0
}
227
228
0
stun_attr_ref stun_attr_get_first_by_type(const stun_buffer *buf, uint16_t attr_type) {
229
0
  return stun_attr_get_first_by_type_str(buf->buf, buf->len, attr_type);
230
0
}
231
232
///////////////////////////////////////////////////////////////////////////////
233
234
0
void stun_set_binding_request(stun_buffer *buf) { stun_set_binding_request_str(buf->buf, (size_t *)(&(buf->len))); }
235
236
bool stun_set_binding_response(stun_buffer *buf, stun_tid *tid, const ioa_addr *reflexive_addr, int error_code,
237
0
                               const uint8_t *reason) {
238
0
  return stun_set_binding_response_str(buf->buf, &(buf->len), tid, reflexive_addr, error_code, reason, 0, false, true);
239
0
}
240
241
0
void stun_prepare_binding_request(stun_buffer *buf) { stun_set_binding_request_str(buf->buf, (size_t *)(&(buf->len))); }
242
243
40
bool stun_is_binding_response(const stun_buffer *buf) { return stun_is_binding_response_str(buf->buf, buf->len); }
244
245
///////////////////////////////////////////////////////