1 /*
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include <memory>
12
13 #include "modules/include/module_common_types_public.h"
14 #include "modules/rtp_rtcp/source/byte_io.h"
15 #include "modules/rtp_rtcp/source/fec_test_helper.h"
16 #include "modules/rtp_rtcp/source/ulpfec_generator.h"
17 #include "rtc_base/checks.h"
18 #include "rtc_base/copy_on_write_buffer.h"
19 #include "system_wrappers/include/clock.h"
20
21 namespace webrtc {
22
23 namespace {
24 constexpr uint8_t kFecPayloadType = 96;
25 constexpr uint8_t kRedPayloadType = 97;
26 } // namespace
27
FuzzOneInput(const uint8_t * data,size_t size)28 void FuzzOneInput(const uint8_t* data, size_t size) {
29 SimulatedClock clock(1);
30 UlpfecGenerator generator(kRedPayloadType, kFecPayloadType, &clock);
31 size_t i = 0;
32 if (size < 4)
33 return;
34 FecProtectionParams params = {
35 data[i++] % 128, static_cast<int>(data[i++] % 10), kFecMaskBursty};
36 generator.SetProtectionParameters(params, params);
37 uint16_t seq_num = data[i++];
38 uint16_t prev_seq_num = 0;
39 while (i + 3 < size) {
40 size_t rtp_header_length = data[i++] % 10 + 12;
41 size_t payload_size = data[i++] % 10;
42 if (i + payload_size + rtp_header_length + 2 > size)
43 break;
44 rtc::CopyOnWriteBuffer packet(&data[i], payload_size + rtp_header_length);
45 packet.EnsureCapacity(IP_PACKET_SIZE);
46 // Write a valid parsable header (version = 2, no padding, no extensions,
47 // no CSRCs).
48 ByteWriter<uint8_t>::WriteBigEndian(packet.MutableData(), 2 << 6);
49 // Make sure sequence numbers are increasing.
50 ByteWriter<uint16_t>::WriteBigEndian(packet.MutableData() + 2, seq_num++);
51 i += payload_size + rtp_header_length;
52 const bool protect = data[i++] % 2 == 1;
53
54 // Check the sequence numbers are monotonic. In rare case the packets number
55 // may loop around and in the same FEC-protected group the packet sequence
56 // number became out of order.
57 if (protect && IsNewerSequenceNumber(seq_num, prev_seq_num) &&
58 seq_num < prev_seq_num + kUlpfecMaxMediaPackets) {
59 RtpPacketToSend rtp_packet(nullptr);
60 // Check that we actually have a parsable packet, we want to fuzz FEC
61 // logic, not RTP header parsing.
62 RTC_CHECK(rtp_packet.Parse(packet));
63 generator.AddPacketAndGenerateFec(rtp_packet);
64 prev_seq_num = seq_num;
65 }
66
67 generator.GetFecPackets();
68 }
69 }
70 } // namespace webrtc
71