Coverage Report

Created: 2026-09-04 06:46

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/coturn/fuzzing/FuzzStunClient.c
Line
Count
Source
1
/*
2
 * SPDX-License-Identifier: BSD-3-Clause
3
 *
4
 * https://opensource.org/license/bsd-3-clause
5
 *
6
 * Multi-harness libFuzzer entry point for client-side STUN parsing,
7
 * TCP framing, and address codec.
8
 *
9
 * Every iteration runs all sub-harnesses in sequence on the same input.
10
 * Keeping everything behind a single binary allows the upstream OSS-Fuzz
11
 * build recipe (which only copies FuzzStun and FuzzStunClient) to stay
12
 * unchanged.
13
 */
14
15
#include <stdbool.h>
16
#include <stdint.h>
17
#include <string.h>
18
19
#include "apputils.h"
20
#include "ns_turn_msg.h"
21
#include "ns_turn_msg_addr.h"
22
#include "ns_turn_msg_defs.h"
23
#include "ns_turn_utils.h"
24
#include "stun_buffer.h"
25
26
676k
static uint8_t fuzz_byte(const uint8_t *Data, size_t Size, size_t idx) { return Size ? Data[idx % Size] : 0; }
27
28
85.0k
static uint16_t fuzz_u16(const uint8_t *Data, size_t Size, size_t idx) {
29
85.0k
  return (uint16_t)(((uint16_t)fuzz_byte(Data, Size, idx) << 8) | (uint16_t)fuzz_byte(Data, Size, idx + 1));
30
85.0k
}
31
32
28.8k
static uint32_t fuzz_u32(const uint8_t *Data, size_t Size, size_t idx) {
33
28.8k
  return ((uint32_t)fuzz_u16(Data, Size, idx) << 16) | (uint32_t)fuzz_u16(Data, Size, idx + 2);
34
28.8k
}
35
36
3.28k
static uint64_t fuzz_u64(const uint8_t *Data, size_t Size, size_t idx) {
37
3.28k
  return ((uint64_t)fuzz_u32(Data, Size, idx) << 32) | (uint64_t)fuzz_u32(Data, Size, idx + 4);
38
3.28k
}
39
40
37.1k
static bool fuzz_flag(const uint8_t *Data, size_t Size, size_t idx) { return (fuzz_byte(Data, Size, idx) & 1u) != 0; }
41
42
9.84k
static void fuzz_string(const uint8_t *Data, size_t Size, size_t idx, char *out, size_t out_size) {
43
9.84k
  if (!out || !out_size) {
44
0
    return;
45
0
  }
46
47
9.84k
  const size_t max_len = out_size - 1;
48
9.84k
  const size_t len = max_len ? (size_t)(fuzz_byte(Data, Size, idx) % (max_len + 1)) : 0;
49
50
268k
  for (size_t i = 0; i < len; ++i) {
51
258k
    out[i] = (char)('A' + (fuzz_byte(Data, Size, idx + 1 + i) % 26));
52
258k
  }
53
54
9.84k
  out[len] = '\0';
55
9.84k
}
56
57
4.92k
static void fuzz_tid(const uint8_t *Data, size_t Size, size_t idx, stun_tid *tid) {
58
4.92k
  if (!tid) {
59
0
    return;
60
0
  }
61
62
4.92k
  memset(tid, 0, sizeof(*tid));
63
63.9k
  for (size_t i = 0; i < STUN_TID_SIZE; ++i) {
64
59.0k
    tid->tsx_id[i] = fuzz_byte(Data, Size, idx + i);
65
59.0k
  }
66
4.92k
}
67
68
20.7k
static void fuzz_addr(const uint8_t *Data, size_t Size, size_t idx, ioa_addr *addr) {
69
20.7k
  if (!addr) {
70
0
    return;
71
0
  }
72
73
20.7k
  memset(addr, 0, sizeof(*addr));
74
75
20.7k
  if (fuzz_flag(Data, Size, idx)) {
76
8.26k
    addr->s6.sin6_family = AF_INET6;
77
8.26k
    addr->s6.sin6_port = htons(fuzz_u16(Data, Size, idx + 1));
78
140k
    for (size_t i = 0; i < 16; ++i) {
79
132k
      addr->s6.sin6_addr.s6_addr[i] = fuzz_byte(Data, Size, idx + 3 + i);
80
132k
    }
81
8.26k
    if (!memcmp(addr->s6.sin6_addr.s6_addr, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16)) {
82
43
      addr->s6.sin6_addr.s6_addr[15] = 1;
83
43
    }
84
12.4k
  } else {
85
12.4k
    addr->s4.sin_family = AF_INET;
86
12.4k
    addr->s4.sin_port = htons(fuzz_u16(Data, Size, idx + 1));
87
12.4k
    addr->s4.sin_addr.s_addr = htonl(fuzz_u32(Data, Size, idx + 3) | 1u);
88
12.4k
  }
89
20.7k
}
90
91
41.0k
static void inspect_buffer_message(stun_buffer *msg, uint16_t addr_attr_type, const ioa_addr *default_addr) {
92
41.0k
  if (!msg) {
93
0
    return;
94
0
  }
95
96
41.0k
  (void)stun_get_command_message_len(msg);
97
41.0k
  (void)stun_is_command_message(msg);
98
41.0k
  (void)stun_is_request(msg);
99
41.0k
  (void)stun_is_response(msg);
100
41.0k
  (void)stun_is_success_response(msg);
101
41.0k
  (void)stun_is_binding_response(msg);
102
41.0k
  (void)stun_get_method(msg);
103
41.0k
  (void)stun_get_msg_type(msg);
104
105
41.0k
  {
106
41.0k
    int err_code = 0;
107
41.0k
    uint8_t err_msg[256] = {0};
108
41.0k
    (void)stun_is_error_response(msg, &err_code, err_msg, sizeof(err_msg));
109
41.0k
  }
110
111
41.0k
  {
112
41.0k
    ioa_addr parsed = {0};
113
41.0k
    (void)stun_attr_get_first_addr(msg, addr_attr_type, &parsed, default_addr);
114
41.0k
  }
115
116
41.0k
  {
117
41.0k
    stun_attr_ref attr = stun_attr_get_first(msg);
118
112k
    while (attr) {
119
71.7k
      (void)stun_attr_get_type(attr);
120
71.7k
      (void)stun_attr_get_len(attr);
121
71.7k
      if (stun_attr_is_addr(attr)) {
122
23.5k
        ioa_addr parsed = {0};
123
23.5k
        (void)stun_attr_get_addr(msg, attr, &parsed, default_addr);
124
23.5k
      }
125
71.7k
      attr = stun_attr_get_next(msg, attr);
126
71.7k
    }
127
41.0k
  }
128
129
41.0k
  (void)stun_attr_get_first_channel_number(msg);
130
41.0k
}
131
132
34.4k
static void inspect_raw_message(const uint8_t *buf, size_t len, uint16_t addr_attr_type, const ioa_addr *default_addr) {
133
34.4k
  if (!buf || !len) {
134
0
    return;
135
0
  }
136
137
34.4k
  (void)stun_is_command_message_str((uint8_t *)buf, len);
138
34.4k
  (void)stun_is_request_str(buf, len);
139
34.4k
  (void)stun_is_response_str(buf, len);
140
34.4k
  (void)stun_is_success_response_str(buf, len);
141
34.4k
  (void)stun_is_binding_response_str(buf, len);
142
34.4k
  (void)stun_get_method_str(buf, len);
143
34.4k
  (void)stun_get_msg_type_str(buf, len);
144
145
34.4k
  {
146
34.4k
    int err_code = 0;
147
34.4k
    uint8_t err_msg[256] = {0};
148
34.4k
    (void)stun_is_error_response_str(buf, len, &err_code, err_msg, sizeof(err_msg));
149
34.4k
  }
150
151
34.4k
  {
152
34.4k
    ioa_addr parsed = {0};
153
34.4k
    (void)stun_attr_get_first_addr_str(buf, len, addr_attr_type, &parsed, default_addr);
154
34.4k
  }
155
156
34.4k
  {
157
34.4k
    stun_attr_ref attr = stun_attr_get_first_str(buf, len);
158
91.1k
    while (attr) {
159
56.6k
      (void)stun_attr_get_type(attr);
160
56.6k
      (void)stun_attr_get_len(attr);
161
56.6k
      if (stun_attr_is_addr(attr)) {
162
26.5k
        ioa_addr parsed = {0};
163
26.5k
        (void)stun_attr_get_addr_str(buf, len, attr, &parsed, default_addr);
164
26.5k
      }
165
56.6k
      attr = stun_attr_get_next_str(buf, len, attr);
166
56.6k
    }
167
34.4k
  }
168
169
34.4k
  (void)stun_attr_get_first_channel_number_str(buf, len);
170
34.4k
}
171
172
/* ------------------------------------------------------------------ */
173
/* Raw-input coverage for stun_attr_get_first_addr.                   */
174
/*                                                                    */
175
/* The inspect_buffer_message() path only sees messages produced by   */
176
/* the project's own serializers, which are always well-formed. This  */
177
/* harness feeds arbitrary fuzzer input through the stun_buffer       */
178
/* wrapper (not just the _str variant) for every address attribute    */
179
/* type, with both NULL and a fuzzed default_addr fallback.           */
180
/* ------------------------------------------------------------------ */
181
static const uint16_t kFirstAddrAttrs[] = {
182
    STUN_ATTRIBUTE_MAPPED_ADDRESS,   STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS,  OLD_STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS,
183
    STUN_ATTRIBUTE_XOR_PEER_ADDRESS, STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS, STUN_ATTRIBUTE_ALTERNATE_SERVER,
184
    STUN_ATTRIBUTE_RESPONSE_ORIGIN,  STUN_ATTRIBUTE_OTHER_ADDRESS,
185
};
186
187
1.77k
static void harness_attr_get_first_addr(const uint8_t *Data, size_t Size) {
188
1.77k
  if (Size < STUN_HEADER_LENGTH || Size > 5120) {
189
722
    return;
190
722
  }
191
192
1.05k
  stun_buffer msg;
193
1.05k
  msg.len = Size;
194
1.05k
  memcpy(msg.buf, Data, Size);
195
196
1.05k
  ioa_addr default_addr = {0};
197
1.05k
  fuzz_addr(Data, Size, 0, &default_addr);
198
199
1.05k
  const size_t num_attrs = sizeof(kFirstAddrAttrs) / sizeof(kFirstAddrAttrs[0]);
200
9.45k
  for (size_t i = 0; i < num_attrs; ++i) {
201
8.40k
    ioa_addr parsed = {0};
202
8.40k
    (void)stun_attr_get_first_addr(&msg, kFirstAddrAttrs[i], &parsed, NULL);
203
204
8.40k
    memset(&parsed, 0, sizeof(parsed));
205
8.40k
    (void)stun_attr_get_first_addr(&msg, kFirstAddrAttrs[i], &parsed, &default_addr);
206
8.40k
  }
207
1.05k
}
208
209
/* ------------------------------------------------------------------ */
210
/* stun_buffer-based client message parsing (original FuzzStunClient). */
211
/* ------------------------------------------------------------------ */
212
1.77k
static void harness_stun_client(const uint8_t *Data, size_t Size) {
213
1.77k
  if (Size < 10 || Size > 5120) {
214
581
    return;
215
581
  }
216
217
1.19k
  stun_buffer buf;
218
1.19k
  buf.len = Size;
219
1.19k
  memcpy(buf.buf, Data, buf.len);
220
221
1.19k
  if (!stun_is_command_message(&buf)) {
222
1.04k
    return;
223
1.04k
  }
224
225
149
  (void)stun_get_method_str(buf.buf, buf.len);
226
149
  (void)stun_get_msg_type_str(buf.buf, buf.len);
227
228
149
  if (stun_is_response(&buf) && stun_is_success_response(&buf) && stun_is_binding_response(&buf)) {
229
9
    return;
230
9
  }
231
232
140
  stun_is_indication_str(buf.buf, buf.len);
233
234
140
  int err_code = 0;
235
140
  uint8_t err_msg[256] = {0};
236
140
  stun_is_error_response_str(buf.buf, buf.len, &err_code, err_msg, sizeof(err_msg));
237
140
}
238
239
/* ------------------------------------------------------------------ */
240
/* ChannelData / TCP framing (FuzzChannelData).                       */
241
/* ------------------------------------------------------------------ */
242
1.77k
static void harness_channel_data(const uint8_t *Data, size_t Size) {
243
1.77k
  if (Size < 4 || Size > 8192) {
244
351
    return;
245
351
  }
246
247
1.42k
  uint8_t buf[8192] = {0};
248
1.42k
  memcpy(buf, Data, Size);
249
250
1.42k
  size_t app_len_tcp = 0;
251
1.42k
  size_t app_len_udp = 0;
252
253
1.42k
  int mlen_tcp = stun_get_message_len_str(buf, Size, 1, &app_len_tcp);
254
1.42k
  int mlen_udp = stun_get_message_len_str(buf, Size, 0, &app_len_udp);
255
256
1.42k
  if (mlen_tcp > 0) {
257
549
    if (app_len_tcp > Size) {
258
0
      __builtin_trap();
259
0
    }
260
549
    if ((size_t)mlen_tcp > Size) {
261
0
      __builtin_trap();
262
0
    }
263
549
    if ((size_t)mlen_tcp < app_len_tcp) {
264
0
      __builtin_trap();
265
0
    }
266
549
  }
267
268
1.42k
  if (mlen_udp > 0) {
269
565
    if (app_len_udp > Size) {
270
0
      __builtin_trap();
271
0
    }
272
565
    if ((size_t)mlen_udp > Size) {
273
0
      __builtin_trap();
274
0
    }
275
565
  }
276
277
1.42k
  size_t blen_tcp = Size;
278
1.42k
  uint16_t chn_tcp = 0;
279
1.42k
  bool is_chan_tcp = stun_is_channel_message_str(buf, &blen_tcp, &chn_tcp, true);
280
281
1.42k
  size_t blen_udp = Size;
282
1.42k
  uint16_t chn_udp = 0;
283
1.42k
  bool is_chan_udp = stun_is_channel_message_str(buf, &blen_udp, &chn_udp, false);
284
285
1.42k
  if (is_chan_tcp && (blen_tcp < 4 || blen_tcp > Size)) {
286
0
    __builtin_trap();
287
0
  }
288
1.42k
  if (is_chan_udp && (blen_udp < 4 || blen_udp > Size)) {
289
0
    __builtin_trap();
290
0
  }
291
1.42k
}
292
293
/* ------------------------------------------------------------------ */
294
/* STUN address encode/decode (FuzzStunAddrCodec).                    */
295
/* ------------------------------------------------------------------ */
296
1.77k
static void harness_addr_codec(const uint8_t *Data, size_t Size) {
297
1.77k
  if (Size < 2 || Size > 64) {
298
575
    return;
299
575
  }
300
301
1.19k
  uint8_t tid[STUN_TID_SIZE] = {0};
302
1.19k
  size_t tid_bytes = Size > (STUN_TID_SIZE + 2) ? STUN_TID_SIZE : (Size > 2 ? Size - 2 : 0);
303
1.19k
  memcpy(tid, Data, tid_bytes);
304
1.19k
  const uint8_t *payload = Data + tid_bytes;
305
1.19k
  int payload_len = (int)(Size - tid_bytes);
306
307
1.19k
  ioa_addr addr = {0};
308
309
  /* XOR decode + round-trip */
310
1.19k
  if (stun_addr_decode(&addr, payload, payload_len, 1, STUN_MAGIC_COOKIE, tid) == 0) {
311
10
    uint8_t enc_buf[32] = {0};
312
10
    int enc_len = 0;
313
10
    if (stun_addr_encode(&addr, enc_buf, &enc_len, 1, STUN_MAGIC_COOKIE, tid) == 0) {
314
10
      ioa_addr addr2 = {0};
315
10
      stun_addr_decode(&addr2, enc_buf, enc_len, 1, STUN_MAGIC_COOKIE, tid);
316
10
    }
317
10
  }
318
319
  /* Plain decode + round-trip */
320
1.19k
  memset(&addr, 0, sizeof(addr));
321
1.19k
  if (stun_addr_decode(&addr, payload, payload_len, 0, 0, tid) == 0) {
322
10
    uint8_t enc_buf[32] = {0};
323
10
    int enc_len = 0;
324
10
    if (stun_addr_encode(&addr, enc_buf, &enc_len, 0, 0, tid) == 0) {
325
10
      ioa_addr addr2 = {0};
326
10
      stun_addr_decode(&addr2, enc_buf, enc_len, 0, 0, tid);
327
10
    }
328
10
  }
329
330
  /* Alternate magic cookie (old STUN) */
331
1.19k
  memset(&addr, 0, sizeof(addr));
332
1.19k
  uint32_t alt_cookie = 0;
333
1.19k
  if (Size >= 4) {
334
985
    memcpy(&alt_cookie, Data, 4);
335
985
  }
336
1.19k
  (void)stun_addr_decode(&addr, payload, payload_len, 1, alt_cookie, tid);
337
1.19k
}
338
339
/* ------------------------------------------------------------------ */
340
/* Message builders / wrappers / round-trip parsing.                  */
341
/* ------------------------------------------------------------------ */
342
1.77k
static void harness_message_builders(const uint8_t *Data, size_t Size) {
343
1.77k
  if (!Size || Size > 4096) {
344
132
    return;
345
132
  }
346
347
1.64k
  static const uint16_t kMethods[] = {
348
1.64k
      STUN_METHOD_ALLOCATE, STUN_METHOD_BINDING, STUN_METHOD_CHANNEL_BIND, STUN_METHOD_REFRESH, STUN_METHOD_CONNECT,
349
1.64k
  };
350
1.64k
  static const uint16_t kErrorCodes[] = {
351
1.64k
      300, 400, 401, 403, 420, 437, 438, 440, 441, 442, 443, 446, 447, 486, 487, 500, 508, 699,
352
1.64k
  };
353
354
1.64k
  stun_tid tid = {0};
355
1.64k
  ioa_addr relay1 = {0};
356
1.64k
  ioa_addr relay2 = {0};
357
1.64k
  ioa_addr reflexive = {0};
358
1.64k
  ioa_addr peer = {0};
359
1.64k
  ioa_addr default_addr = {0};
360
1.64k
  char reason[96] = {0};
361
1.64k
  char mobile_id[96] = {0};
362
1.64k
  uint8_t raw[MAX_STUN_MESSAGE_SIZE] = {0};
363
364
1.64k
  fuzz_tid(Data, Size, 0, &tid);
365
1.64k
  fuzz_addr(Data, Size, 16, &relay1);
366
1.64k
  fuzz_addr(Data, Size, 40, &relay2);
367
1.64k
  fuzz_addr(Data, Size, 64, &reflexive);
368
1.64k
  fuzz_addr(Data, Size, 88, &peer);
369
1.64k
  fuzz_addr(Data, Size, 112, &default_addr);
370
1.64k
  fuzz_string(Data, Size, 136, reason, sizeof(reason));
371
1.64k
  fuzz_string(Data, Size, 232, mobile_id, sizeof(mobile_id));
372
373
1.64k
  const uint16_t method = kMethods[fuzz_byte(Data, Size, 328) % (sizeof(kMethods) / sizeof(kMethods[0]))];
374
1.64k
  const uint16_t error_code = kErrorCodes[fuzz_byte(Data, Size, 329) % (sizeof(kErrorCodes) / sizeof(kErrorCodes[0]))];
375
1.64k
  const uint32_t lifetime = fuzz_u32(Data, Size, 330);
376
1.64k
  const uint32_t max_lifetime = fuzz_u32(Data, Size, 334);
377
1.64k
  const uint64_t reservation_token = fuzz_u64(Data, Size, 338);
378
1.64k
  const uint16_t channel_number = fuzz_u16(Data, Size, 346);
379
1.64k
  const bool include_reason = fuzz_flag(Data, Size, 348);
380
1.64k
  const bool old_stun = fuzz_flag(Data, Size, 349);
381
1.64k
  const bool stun_backward_compatibility = fuzz_flag(Data, Size, 350);
382
1.64k
  const uint32_t old_cookie = fuzz_u32(Data, Size, 351);
383
384
  /* Direct wrapper coverage for stun_init_error_response(). */
385
1.64k
  {
386
1.64k
    stun_buffer msg;
387
1.64k
    stun_init_buffer(&msg);
388
1.64k
    stun_init_error_response(method, &msg, error_code, reason[0] ? (const uint8_t *)reason : NULL, &tid,
389
1.64k
                             include_reason);
390
1.64k
    inspect_buffer_message(&msg, STUN_ATTRIBUTE_MAPPED_ADDRESS, &default_addr);
391
1.64k
  }
392
393
  /* Success allocate response covers addr extraction; error allocate response
394
   * forces the shared error builder path. */
395
1.64k
  {
396
1.64k
    stun_buffer msg;
397
1.64k
    stun_init_buffer(&msg);
398
1.64k
    (void)stun_set_allocate_response(&msg, &tid, &relay1, fuzz_flag(Data, Size, 355) ? &relay2 : NULL, &reflexive,
399
1.64k
                                     lifetime, max_lifetime, 0, (const uint8_t *)reason, reservation_token, mobile_id,
400
1.64k
                                     include_reason);
401
1.64k
    inspect_buffer_message(&msg, STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS, &default_addr);
402
403
1.64k
    size_t raw_len = sizeof(raw);
404
1.64k
    (void)stun_set_allocate_response_str(raw, &raw_len, &tid, &relay1, &relay2, &reflexive, lifetime, max_lifetime, 0,
405
1.64k
                                         (const uint8_t *)reason, reservation_token, mobile_id, include_reason);
406
1.64k
    inspect_raw_message(raw, raw_len, STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS, &default_addr);
407
408
1.64k
    stun_init_buffer(&msg);
409
1.64k
    (void)stun_set_allocate_response(&msg, &tid, NULL, NULL, NULL, lifetime, max_lifetime, error_code,
410
1.64k
                                     reason[0] ? (const uint8_t *)reason : NULL, reservation_token, mobile_id,
411
1.64k
                                     include_reason);
412
1.64k
    inspect_buffer_message(&msg, STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS, &default_addr);
413
414
1.64k
    raw_len = sizeof(raw);
415
1.64k
    (void)stun_set_allocate_response_str(raw, &raw_len, &tid, NULL, NULL, NULL, lifetime, max_lifetime, error_code,
416
1.64k
                                         reason[0] ? (const uint8_t *)reason : NULL, reservation_token, mobile_id,
417
1.64k
                                         include_reason);
418
1.64k
    inspect_raw_message(raw, raw_len, STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS, &default_addr);
419
1.64k
  }
420
421
1.64k
  {
422
1.64k
    stun_buffer msg;
423
1.64k
    stun_init_buffer(&msg);
424
1.64k
    (void)stun_set_binding_response(&msg, &tid, &reflexive, 0, (const uint8_t *)reason, include_reason);
425
1.64k
    inspect_buffer_message(&msg, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, &default_addr);
426
427
1.64k
    size_t raw_len = sizeof(raw);
428
1.64k
    (void)stun_set_binding_response_str(raw, &raw_len, &tid, &reflexive, 0, (const uint8_t *)reason, old_cookie,
429
1.64k
                                        old_stun, stun_backward_compatibility, include_reason);
430
1.64k
    inspect_raw_message(raw, raw_len, old_stun ? STUN_ATTRIBUTE_MAPPED_ADDRESS : STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS,
431
1.64k
                        &default_addr);
432
433
1.64k
    stun_init_buffer(&msg);
434
1.64k
    (void)stun_set_binding_response(&msg, &tid, NULL, error_code, reason[0] ? (const uint8_t *)reason : NULL,
435
1.64k
                                    include_reason);
436
1.64k
    inspect_buffer_message(&msg, STUN_ATTRIBUTE_MAPPED_ADDRESS, &default_addr);
437
438
1.64k
    raw_len = sizeof(raw);
439
1.64k
    (void)stun_set_binding_response_str(raw, &raw_len, &tid, NULL, error_code,
440
1.64k
                                        reason[0] ? (const uint8_t *)reason : NULL, old_cookie, old_stun,
441
1.64k
                                        stun_backward_compatibility, include_reason);
442
1.64k
    inspect_raw_message(raw, raw_len, STUN_ATTRIBUTE_MAPPED_ADDRESS, &default_addr);
443
1.64k
  }
444
445
1.64k
  {
446
1.64k
    stun_buffer msg;
447
1.64k
    stun_init_buffer(&msg);
448
1.64k
    (void)stun_set_channel_bind_request(&msg, fuzz_flag(Data, Size, 356) ? &peer : NULL, channel_number);
449
1.64k
    inspect_buffer_message(&msg, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &default_addr);
450
451
1.64k
    size_t raw_len = sizeof(raw);
452
1.64k
    (void)stun_set_channel_bind_request_str(raw, &raw_len, fuzz_flag(Data, Size, 357) ? &peer : NULL, channel_number);
453
1.64k
    inspect_raw_message(raw, raw_len, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &default_addr);
454
455
1.64k
    stun_init_buffer(&msg);
456
1.64k
    stun_set_channel_bind_response(&msg, &tid, 0, (const uint8_t *)reason, include_reason);
457
1.64k
    inspect_buffer_message(&msg, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &default_addr);
458
459
1.64k
    raw_len = sizeof(raw);
460
1.64k
    stun_set_channel_bind_response_str(raw, &raw_len, &tid, error_code, reason[0] ? (const uint8_t *)reason : NULL,
461
1.64k
                                       include_reason);
462
1.64k
    inspect_raw_message(raw, raw_len, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &default_addr);
463
1.64k
  }
464
1.64k
}
465
466
/* ------------------------------------------------------------------ */
467
/* Deterministic branch coverage for the response builders.          */
468
/*                                                                    */
469
/* harness_message_builders randomizes include_reason/old_stun/NULL- */
470
/* vs-present selectors from single input bytes, so any one iteration */
471
/* only visits a fraction of the branches inside these builders. This */
472
/* harness hits every branch point of each listed builder on every   */
473
/* iteration so coverage is not gated on libFuzzer finding the right  */
474
/* bytes. Inputs (tid / addrs / strings / numeric fields) are still   */
475
/* fuzz-derived to keep each call meaningfully distinct.              */
476
/* ------------------------------------------------------------------ */
477
1.77k
static void harness_response_matrix(const uint8_t *Data, size_t Size) {
478
1.77k
  if (!Size || Size > 4096) {
479
132
    return;
480
132
  }
481
482
1.64k
  stun_tid tid = {0};
483
1.64k
  ioa_addr relay1 = {0};
484
1.64k
  ioa_addr relay2 = {0};
485
1.64k
  ioa_addr reflexive = {0};
486
1.64k
  ioa_addr peer = {0};
487
1.64k
  ioa_addr default_addr = {0};
488
1.64k
  char reason[96] = {0};
489
1.64k
  char mobile_id[96] = {0};
490
1.64k
  uint8_t raw[MAX_STUN_MESSAGE_SIZE] = {0};
491
492
1.64k
  fuzz_tid(Data, Size, 0, &tid);
493
1.64k
  fuzz_addr(Data, Size, 16, &relay1);
494
1.64k
  fuzz_addr(Data, Size, 40, &relay2);
495
1.64k
  fuzz_addr(Data, Size, 64, &reflexive);
496
1.64k
  fuzz_addr(Data, Size, 88, &peer);
497
1.64k
  fuzz_addr(Data, Size, 112, &default_addr);
498
1.64k
  fuzz_string(Data, Size, 136, reason, sizeof(reason));
499
1.64k
  fuzz_string(Data, Size, 232, mobile_id, sizeof(mobile_id));
500
501
1.64k
  const uint32_t max_lifetime = fuzz_u32(Data, Size, 328) | 1u;
502
1.64k
  const uint64_t reservation_token = fuzz_u64(Data, Size, 332) | 1ull;
503
1.64k
  const uint16_t channel_number_valid = (uint16_t)(0x4000u + (fuzz_u16(Data, Size, 340) % (0x7FFFu - 0x4000u + 1u)));
504
1.64k
  const uint32_t old_cookie = fuzz_u32(Data, Size, 344);
505
506
  /* stun_init_error_response — cover (reason NULL vs set) × (include reason). */
507
1.64k
  {
508
1.64k
    stun_buffer msg;
509
1.64k
    stun_init_buffer(&msg);
510
1.64k
    stun_init_error_response(STUN_METHOD_ALLOCATE, &msg, 437, NULL, &tid, false);
511
1.64k
    inspect_buffer_message(&msg, STUN_ATTRIBUTE_MAPPED_ADDRESS, &default_addr);
512
513
1.64k
    stun_init_buffer(&msg);
514
1.64k
    stun_init_error_response(STUN_METHOD_BINDING, &msg, 400, (const uint8_t *)reason, &tid, true);
515
1.64k
    inspect_buffer_message(&msg, STUN_ATTRIBUTE_MAPPED_ADDRESS, &default_addr);
516
1.64k
  }
517
518
  /* stun_set_allocate_response / _str — cover every optional-field branch and
519
   * the error path independently of the fuzzer selectors. */
520
1.64k
  {
521
1.64k
    stun_buffer msg;
522
523
    /* Minimal success: relay1 only, no reflexive, no reservation, no mobile id,
524
     * lifetime 0 (triggers the <1 default branch). */
525
1.64k
    stun_init_buffer(&msg);
526
1.64k
    (void)stun_set_allocate_response(&msg, &tid, &relay1, NULL, NULL, 0, max_lifetime, 0, NULL, 0, NULL, false);
527
1.64k
    inspect_buffer_message(&msg, STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS, &default_addr);
528
529
1.64k
    size_t raw_len = sizeof(raw);
530
1.64k
    (void)stun_set_allocate_response_str(raw, &raw_len, &tid, &relay1, NULL, NULL, 0, max_lifetime, 0, NULL, 0, NULL,
531
1.64k
                                         false);
532
1.64k
    inspect_raw_message(raw, raw_len, STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS, &default_addr);
533
534
    /* Full success: both relays + reflexive + reservation + mobile id,
535
     * lifetime > max (triggers clamp branch). */
536
1.64k
    stun_init_buffer(&msg);
537
1.64k
    (void)stun_set_allocate_response(&msg, &tid, &relay1, &relay2, &reflexive, max_lifetime + 1, max_lifetime, 0,
538
1.64k
                                     (const uint8_t *)reason, reservation_token, mobile_id, true);
539
1.64k
    inspect_buffer_message(&msg, STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS, &default_addr);
540
541
1.64k
    raw_len = sizeof(raw);
542
1.64k
    (void)stun_set_allocate_response_str(raw, &raw_len, &tid, &relay1, &relay2, &reflexive, max_lifetime + 1,
543
1.64k
                                         max_lifetime, 0, (const uint8_t *)reason, reservation_token, mobile_id, true);
544
1.64k
    inspect_raw_message(raw, raw_len, STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS, &default_addr);
545
546
    /* Error path with and without a reason string. */
547
1.64k
    stun_init_buffer(&msg);
548
1.64k
    (void)stun_set_allocate_response(&msg, &tid, NULL, NULL, NULL, 0, max_lifetime, 441, NULL, 0, NULL, false);
549
1.64k
    inspect_buffer_message(&msg, STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS, &default_addr);
550
551
1.64k
    raw_len = sizeof(raw);
552
1.64k
    (void)stun_set_allocate_response_str(raw, &raw_len, &tid, NULL, NULL, NULL, 0, max_lifetime, 508,
553
1.64k
                                         (const uint8_t *)reason, 0, NULL, true);
554
1.64k
    inspect_raw_message(raw, raw_len, STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS, &default_addr);
555
1.64k
  }
556
557
  /* stun_set_binding_response / _str — cover success × error × old_stun. */
558
1.64k
  {
559
1.64k
    stun_buffer msg;
560
561
1.64k
    stun_init_buffer(&msg);
562
1.64k
    (void)stun_set_binding_response(&msg, &tid, &reflexive, 0, NULL, false);
563
1.64k
    inspect_buffer_message(&msg, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, &default_addr);
564
565
1.64k
    stun_init_buffer(&msg);
566
1.64k
    (void)stun_set_binding_response(&msg, &tid, NULL, 420, (const uint8_t *)reason, true);
567
1.64k
    inspect_buffer_message(&msg, STUN_ATTRIBUTE_MAPPED_ADDRESS, &default_addr);
568
569
1.64k
    const bool matrix_old_stun[] = {false, true};
570
1.64k
    const bool matrix_backcompat[] = {false, true};
571
4.92k
    for (size_t o = 0; o < sizeof(matrix_old_stun) / sizeof(matrix_old_stun[0]); ++o) {
572
9.84k
      for (size_t b = 0; b < sizeof(matrix_backcompat) / sizeof(matrix_backcompat[0]); ++b) {
573
6.56k
        size_t raw_len = sizeof(raw);
574
6.56k
        (void)stun_set_binding_response_str(raw, &raw_len, &tid, &reflexive, 0, NULL, old_cookie, matrix_old_stun[o],
575
6.56k
                                            matrix_backcompat[b], false);
576
6.56k
        inspect_raw_message(raw, raw_len,
577
6.56k
                            matrix_old_stun[o] ? STUN_ATTRIBUTE_MAPPED_ADDRESS : STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS,
578
6.56k
                            &default_addr);
579
580
6.56k
        raw_len = sizeof(raw);
581
6.56k
        (void)stun_set_binding_response_str(raw, &raw_len, &tid, NULL, 500, (const uint8_t *)reason, old_cookie,
582
6.56k
                                            matrix_old_stun[o], matrix_backcompat[b], true);
583
6.56k
        inspect_raw_message(raw, raw_len, STUN_ATTRIBUTE_MAPPED_ADDRESS, &default_addr);
584
6.56k
      }
585
3.28k
    }
586
1.64k
  }
587
588
  /* stun_set_channel_bind_request / _str — cover peer NULL vs set. */
589
1.64k
  {
590
1.64k
    stun_buffer msg;
591
592
1.64k
    stun_init_buffer(&msg);
593
1.64k
    (void)stun_set_channel_bind_request(&msg, NULL, channel_number_valid);
594
1.64k
    inspect_buffer_message(&msg, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &default_addr);
595
596
1.64k
    stun_init_buffer(&msg);
597
1.64k
    (void)stun_set_channel_bind_request(&msg, &peer, channel_number_valid);
598
1.64k
    inspect_buffer_message(&msg, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &default_addr);
599
600
1.64k
    size_t raw_len = sizeof(raw);
601
1.64k
    (void)stun_set_channel_bind_request_str(raw, &raw_len, NULL, channel_number_valid);
602
1.64k
    inspect_raw_message(raw, raw_len, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &default_addr);
603
604
1.64k
    raw_len = sizeof(raw);
605
1.64k
    (void)stun_set_channel_bind_request_str(raw, &raw_len, &peer, channel_number_valid);
606
1.64k
    inspect_raw_message(raw, raw_len, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &default_addr);
607
1.64k
  }
608
609
  /* stun_set_channel_bind_response / _str — cover success vs error. */
610
1.64k
  {
611
1.64k
    stun_buffer msg;
612
613
1.64k
    stun_init_buffer(&msg);
614
1.64k
    stun_set_channel_bind_response(&msg, &tid, 0, NULL, false);
615
1.64k
    inspect_buffer_message(&msg, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &default_addr);
616
617
1.64k
    stun_init_buffer(&msg);
618
1.64k
    stun_set_channel_bind_response(&msg, &tid, 438, (const uint8_t *)reason, true);
619
1.64k
    inspect_buffer_message(&msg, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &default_addr);
620
621
1.64k
    size_t raw_len = sizeof(raw);
622
1.64k
    stun_set_channel_bind_response_str(raw, &raw_len, &tid, 0, NULL, false);
623
1.64k
    inspect_raw_message(raw, raw_len, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &default_addr);
624
625
1.64k
    raw_len = sizeof(raw);
626
1.64k
    stun_set_channel_bind_response_str(raw, &raw_len, &tid, 486, (const uint8_t *)reason, true);
627
1.64k
    inspect_raw_message(raw, raw_len, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &default_addr);
628
1.64k
  }
629
1.64k
}
630
631
/* ------------------------------------------------------------------ */
632
/* stun_buffer.c wrapper coverage.                                    */
633
/*                                                                    */
634
/* Exercises every public wrapper in src/apps/common/stun_buffer.c    */
635
/* that is not already reached by the harnesses above:                */
636
/*  - stun_get_size NULL/non-NULL                                     */
637
/*  - stun_init_request / _indication / _success_response             */
638
/*  - stun_tid_from_message, stun_tid_generate_in_message             */
639
/*  - stun_is_indication wrapper (gates static is_channel_msg)        */
640
/*  - stun_attr_add, stun_attr_add_channel_number, stun_attr_add_addr */
641
/*  - stun_attr_add_even_port (zero + non-zero branches)              */
642
/*  - stun_attr_get_first_by_type                                     */
643
/*  - stun_set_allocate_request (rt NULL + non-NULL)                  */
644
/*  - stun_set_binding_request, stun_prepare_binding_request          */
645
/*  - stun_init_channel_message + stun_is_channel_message wrappers    */
646
/*                                                                    */
647
/* Each call is followed by inspect_buffer_message so the resulting   */
648
/* serialized message is also walked by the parser predicates.        */
649
/* The tail block also pumps raw fuzzer bytes through the predicate   */
650
/* wrappers to hit malformed-input branches the serializers cannot    */
651
/* produce.                                                           */
652
/* ------------------------------------------------------------------ */
653
1.77k
static void harness_stun_buffer_api(const uint8_t *Data, size_t Size) {
654
1.77k
  if (!Size || Size > 4096) {
655
132
    return;
656
132
  }
657
658
1.64k
  static const uint16_t kMethods[] = {
659
1.64k
      STUN_METHOD_ALLOCATE, STUN_METHOD_BINDING, STUN_METHOD_CHANNEL_BIND, STUN_METHOD_REFRESH, STUN_METHOD_CONNECT,
660
1.64k
  };
661
662
1.64k
  stun_tid tid = {0};
663
1.64k
  ioa_addr peer = {0};
664
1.64k
  ioa_addr default_addr = {0};
665
1.64k
  char attr_value[64] = {0};
666
1.64k
  char rt[8] = {0};
667
668
1.64k
  fuzz_tid(Data, Size, 0, &tid);
669
1.64k
  fuzz_addr(Data, Size, 16, &peer);
670
1.64k
  fuzz_addr(Data, Size, 40, &default_addr);
671
1.64k
  fuzz_string(Data, Size, 64, attr_value, sizeof(attr_value));
672
1.64k
  fuzz_string(Data, Size, 128, rt, sizeof(rt));
673
674
1.64k
  const uint16_t method = kMethods[fuzz_byte(Data, Size, 200) % (sizeof(kMethods) / sizeof(kMethods[0]))];
675
1.64k
  const uint32_t lifetime = fuzz_u32(Data, Size, 201);
676
1.64k
  const uint16_t channel_number = (uint16_t)(0x4000u + (fuzz_u16(Data, Size, 205) & 0x3FFFu));
677
1.64k
  const uint8_t transport = fuzz_byte(Data, Size, 207);
678
1.64k
  const uint8_t even_port_value = fuzz_byte(Data, Size, 208);
679
1.64k
  const bool af4 = fuzz_flag(Data, Size, 209);
680
1.64k
  const bool af6 = fuzz_flag(Data, Size, 210);
681
1.64k
  const bool mobile = fuzz_flag(Data, Size, 211);
682
1.64k
  const bool padding = fuzz_flag(Data, Size, 212);
683
1.64k
  const int chan_payload_len = (int)(fuzz_u16(Data, Size, 213) % 256);
684
1.64k
  const int ep = (int)(int8_t)fuzz_byte(Data, Size, 215);
685
686
  /* NULL-guard branches. */
687
1.64k
  (void)stun_get_size(NULL);
688
1.64k
  (void)stun_init_buffer(NULL);
689
1.64k
  (void)stun_get_msg_type(NULL);
690
1.64k
  {
691
1.64k
    stun_tid scratch = {0};
692
1.64k
    stun_tid_generate_in_message(NULL, &scratch);
693
1.64k
  }
694
695
  /* stun_init_request — also covers stun_get_size (non-NULL), the static
696
   * stun_init_command helper, and stun_attr_add* / stun_attr_get_first_by_type
697
   * over the freshly built message. */
698
1.64k
  {
699
1.64k
    stun_buffer msg;
700
1.64k
    stun_init_buffer(&msg);
701
1.64k
    stun_init_request(method, &msg);
702
703
1.64k
    stun_tid extracted = {0};
704
1.64k
    stun_tid_from_message(&msg, &extracted);
705
1.64k
    stun_tid_generate_in_message(&msg, &extracted);
706
707
1.64k
    const int alen = (int)strlen(attr_value);
708
1.64k
    (void)stun_attr_add(&msg, STUN_ATTRIBUTE_USERNAME, attr_value, alen);
709
1.64k
    (void)stun_attr_add_channel_number(&msg, channel_number);
710
1.64k
    (void)stun_attr_add_addr(&msg, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &peer);
711
1.64k
    (void)stun_attr_add_even_port(&msg, even_port_value);
712
1.64k
    (void)stun_attr_add_even_port(&msg, 0);
713
714
1.64k
    (void)stun_attr_get_first_by_type(&msg, STUN_ATTRIBUTE_USERNAME);
715
1.64k
    (void)stun_attr_get_first_by_type(&msg, STUN_ATTRIBUTE_CHANNEL_NUMBER);
716
1.64k
    (void)stun_attr_get_first_by_type(&msg, STUN_ATTRIBUTE_XOR_PEER_ADDRESS);
717
1.64k
    (void)stun_attr_get_first_by_type(&msg, STUN_ATTRIBUTE_EVEN_PORT);
718
719
1.64k
    (void)stun_is_indication(&msg);
720
1.64k
    inspect_buffer_message(&msg, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &default_addr);
721
1.64k
  }
722
723
  /* stun_init_indication — drives the IS_STUN_INDICATION branch of
724
   * stun_is_indication. */
725
1.64k
  {
726
1.64k
    stun_buffer msg;
727
1.64k
    stun_init_buffer(&msg);
728
1.64k
    stun_init_indication(method, &msg);
729
1.64k
    (void)stun_is_indication(&msg);
730
1.64k
    inspect_buffer_message(&msg, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &default_addr);
731
1.64k
  }
732
733
  /* stun_init_success_response. */
734
1.64k
  {
735
1.64k
    stun_buffer msg;
736
1.64k
    stun_init_buffer(&msg);
737
1.64k
    stun_init_success_response(method, &msg, &tid);
738
1.64k
    inspect_buffer_message(&msg, STUN_ATTRIBUTE_MAPPED_ADDRESS, &default_addr);
739
1.64k
  }
740
741
  /* stun_set_allocate_request — both rt NULL and rt non-NULL paths. */
742
1.64k
  {
743
1.64k
    stun_buffer msg;
744
1.64k
    stun_init_buffer(&msg);
745
1.64k
    (void)stun_set_allocate_request(&msg, lifetime, af4, af6, transport, mobile, rt[0] ? rt : NULL, ep);
746
1.64k
    inspect_buffer_message(&msg, STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS, &default_addr);
747
748
1.64k
    stun_init_buffer(&msg);
749
1.64k
    (void)stun_set_allocate_request(&msg, lifetime, !af4, !af6, transport, !mobile, NULL, ep);
750
1.64k
    inspect_buffer_message(&msg, STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS, &default_addr);
751
1.64k
  }
752
753
  /* stun_set_binding_request + stun_prepare_binding_request (both currently
754
   * delegate to stun_set_binding_request_str but exercise the wrappers). */
755
1.64k
  {
756
1.64k
    stun_buffer msg;
757
1.64k
    stun_init_buffer(&msg);
758
1.64k
    stun_set_binding_request(&msg);
759
1.64k
    inspect_buffer_message(&msg, STUN_ATTRIBUTE_MAPPED_ADDRESS, &default_addr);
760
761
1.64k
    stun_init_buffer(&msg);
762
1.64k
    stun_prepare_binding_request(&msg);
763
1.64k
    inspect_buffer_message(&msg, STUN_ATTRIBUTE_MAPPED_ADDRESS, &default_addr);
764
1.64k
  }
765
766
  /* stun_init_channel_message + stun_is_channel_message wrappers. */
767
1.64k
  {
768
1.64k
    stun_buffer msg;
769
1.64k
    stun_init_buffer(&msg);
770
1.64k
    if (stun_init_channel_message(channel_number, &msg, chan_payload_len, padding)) {
771
1.64k
      uint16_t parsed_chn = 0;
772
1.64k
      (void)stun_is_channel_message(&msg, &parsed_chn, true);
773
1.64k
      (void)stun_is_channel_message(&msg, &parsed_chn, false);
774
1.64k
    }
775
1.64k
    {
776
1.64k
      uint16_t chn = 0;
777
1.64k
      (void)stun_is_channel_message(NULL, &chn, false);
778
1.64k
    }
779
1.64k
  }
780
781
  /* Raw fuzzer bytes through the wrapper-form predicates so they see
782
   * malformed inputs the serializer paths above never produce. */
783
1.64k
  {
784
1.64k
    stun_buffer msg;
785
1.64k
    msg.len = Size > sizeof(msg.buf) ? sizeof(msg.buf) : Size;
786
1.64k
    memcpy(msg.buf, Data, msg.len);
787
788
1.64k
    (void)stun_is_indication(&msg);
789
790
1.64k
    stun_tid extracted = {0};
791
1.64k
    stun_tid_from_message(&msg, &extracted);
792
793
1.64k
    {
794
1.64k
      uint16_t chn = 0;
795
1.64k
      const size_t saved_len = msg.len;
796
1.64k
      (void)stun_is_channel_message(&msg, &chn, true);
797
1.64k
      msg.len = saved_len;
798
1.64k
      (void)stun_is_channel_message(&msg, &chn, false);
799
1.64k
    }
800
801
1.64k
    (void)stun_attr_get_first_by_type(&msg, STUN_ATTRIBUTE_USERNAME);
802
1.64k
    (void)stun_attr_get_first_by_type(&msg, STUN_ATTRIBUTE_XOR_PEER_ADDRESS);
803
1.64k
    (void)stun_attr_get_first_by_type(&msg, STUN_ATTRIBUTE_CHANNEL_NUMBER);
804
1.64k
  }
805
1.64k
}
806
807
/* ------------------------------------------------------------------ */
808
/* libFuzzer entry point — run every harness on each input.           */
809
/*                                                                    */
810
/* Note: OAuth token sub-harnesses are intentionally omitted here.    */
811
/* decode_oauth_token_gcm in src/client/ns_turn_msg.c leaks the       */
812
/* EVP_CIPHER_CTX on several early-return paths, which trips ASan     */
813
/* under CIFuzz. Those harnesses will be re-added once the library    */
814
/* leak is fixed in a separate PR.                                    */
815
/* ------------------------------------------------------------------ */
816
3.51k
extern int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
817
3.51k
  harness_stun_client(Data, Size);
818
3.51k
  harness_channel_data(Data, Size);
819
3.51k
  harness_addr_codec(Data, Size);
820
3.51k
  harness_message_builders(Data, Size);
821
3.51k
  harness_attr_get_first_addr(Data, Size);
822
3.51k
  harness_response_matrix(Data, Size);
823
3.51k
  harness_stun_buffer_api(Data, Size);
824
3.51k
  return 0;
825
3.51k
}