OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include <algorithm> | 11 #include <algorithm> |
12 | 12 |
13 #include "webrtc/base/array_view.h" | 13 #include "webrtc/base/array_view.h" |
| 14 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" |
14 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" | 15 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" |
15 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" | 16 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" |
16 #include "webrtc/voice_engine/transport_feedback_packet_loss_tracker.h" | 17 #include "webrtc/voice_engine/transport_feedback_packet_loss_tracker.h" |
17 | 18 |
18 namespace webrtc { | 19 namespace webrtc { |
19 | 20 |
20 namespace { | 21 namespace { |
21 | 22 |
22 template <typename T> | 23 template <typename T> |
23 T FuzzInput(const uint8_t** data, size_t* size) { | 24 T FuzzInput(const uint8_t** data, size_t* size) { |
(...skipping 16 matching lines...) Expand all Loading... |
40 const size_t offset = (static_cast<float>(fuzzed) / 0x10000) * (range + 1); | 41 const size_t offset = (static_cast<float>(fuzzed) / 0x10000) * (range + 1); |
41 RTC_CHECK_LE(offset, range); // (fuzzed <= 0xffff) -> (offset < range + 1) | 42 RTC_CHECK_LE(offset, range); // (fuzzed <= 0xffff) -> (offset < range + 1) |
42 return lower + offset; | 43 return lower + offset; |
43 } | 44 } |
44 | 45 |
45 class TransportFeedbackGenerator { | 46 class TransportFeedbackGenerator { |
46 public: | 47 public: |
47 explicit TransportFeedbackGenerator(const uint8_t** data, size_t* size) | 48 explicit TransportFeedbackGenerator(const uint8_t** data, size_t* size) |
48 : data_(data), size_(size) {} | 49 : data_(data), size_(size) {} |
49 | 50 |
50 bool GetNextTransportFeedback(rtcp::TransportFeedback* feedback) { | 51 bool GetNextTransportFeedbackVector( |
51 uint16_t base_seq_num = 0; | 52 std::vector<PacketFeedback>* feedback_vector) { |
52 if (!ReadData<uint16_t>(&base_seq_num)) { | 53 RTC_CHECK(feedback_vector->empty()); |
| 54 |
| 55 uint16_t remaining_packets = 0; |
| 56 if (!ReadData<uint16_t>(&remaining_packets)) { |
53 return false; | 57 return false; |
54 } | 58 } |
55 constexpr int64_t kBaseTimeUs = 1234; // Irrelevant to this test. | |
56 feedback->SetBase(base_seq_num, kBaseTimeUs); | |
57 | 59 |
58 uint16_t remaining_packets = 0; | 60 if (remaining_packets == 0) { |
59 if (!ReadData<uint16_t>(&remaining_packets)) | 61 return true; |
| 62 } |
| 63 |
| 64 uint16_t seq_num; |
| 65 if (!ReadData<uint16_t>(&seq_num)) { // Fuzz base sequence number. |
60 return false; | 66 return false; |
61 // Range is [0x00001 : 0x10000], but we keep it 0x0000 to 0xffff for now, | 67 } |
62 // and add the last status as RECEIVED. That is because of a limitation | |
63 // that says that the last status cannot be LOST. | |
64 | 68 |
65 uint16_t seq_num = base_seq_num; | |
66 while (remaining_packets > 0) { | 69 while (remaining_packets > 0) { |
67 uint8_t status_byte = 0; | 70 uint8_t status_byte = 0; |
68 if (!ReadData<uint8_t>(&status_byte)) { | 71 if (!ReadData<uint8_t>(&status_byte)) { |
69 return false; | 72 return false; |
70 } | 73 } |
71 // Each status byte contains 8 statuses. | 74 // Each status byte contains 8 statuses. |
72 for (size_t i = 0; i < 8 && remaining_packets > 0; ++i) { | 75 for (size_t i = 0; i < 8 && remaining_packets > 0; ++i) { |
| 76 // Any positive integer signals reception. kNotReceived signals loss. |
| 77 // Other values are just illegal. |
| 78 constexpr int64_t kArrivalTimeMs = 1234; |
| 79 |
73 const bool received = (status_byte & (0x01 << i)); | 80 const bool received = (status_byte & (0x01 << i)); |
74 if (received) { | 81 feedback_vector->emplace_back(PacketFeedback( |
75 feedback->AddReceivedPacket(seq_num, kBaseTimeUs); | 82 received ? kArrivalTimeMs : PacketFeedback::kNotReceived, |
76 } | 83 seq_num++)); |
77 ++seq_num; | |
78 --remaining_packets; | 84 --remaining_packets; |
79 } | 85 } |
80 } | 86 } |
81 | 87 |
82 // As mentioned above, all feedbacks must report with a received packet. | |
83 feedback->AddReceivedPacket(seq_num, kBaseTimeUs); | |
84 | |
85 return true; | 88 return true; |
86 } | 89 } |
87 | 90 |
88 private: | 91 private: |
89 template <typename T> | 92 template <typename T> |
90 bool ReadData(T* value) { | 93 bool ReadData(T* value) { |
91 if (*size_ < sizeof(T)) { | 94 if (*size_ < sizeof(T)) { |
92 return false; | 95 return false; |
93 } else { | 96 } else { |
94 *value = FuzzInput<T>(data_, size_); | 97 *value = FuzzInput<T>(data_, size_); |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 // be meaningless - we'd go straight back to fuzzing another packet | 232 // be meaningless - we'd go straight back to fuzzing another packet |
230 // transmission block. | 233 // transmission block. |
231 if (*size < sizeof(uint8_t)) { | 234 if (*size < sizeof(uint8_t)) { |
232 return false; | 235 return false; |
233 } | 236 } |
234 | 237 |
235 size_t feedbacks_num = 1 + (FuzzInput<uint8_t>(data, size) & 0x3f); | 238 size_t feedbacks_num = 1 + (FuzzInput<uint8_t>(data, size) & 0x3f); |
236 TransportFeedbackGenerator feedback_generator(data, size); | 239 TransportFeedbackGenerator feedback_generator(data, size); |
237 | 240 |
238 for (size_t i = 0; i < feedbacks_num; i++) { | 241 for (size_t i = 0; i < feedbacks_num; i++) { |
239 rtcp::TransportFeedback feedback; | 242 std::vector<PacketFeedback> feedback_vector; |
240 bool may_continue = feedback_generator.GetNextTransportFeedback(&feedback); | 243 bool may_continue = |
| 244 feedback_generator.GetNextTransportFeedbackVector(&feedback_vector); |
241 if (!may_continue) { | 245 if (!may_continue) { |
242 return false; | 246 return false; |
243 } | 247 } |
244 tracker->OnReceivedTransportFeedback(feedback); | 248 tracker->OnNewTransportFeedbacks(feedback_vector); |
245 tracker->Validate(); | 249 tracker->Validate(); |
246 } | 250 } |
247 | 251 |
248 return true; | 252 return true; |
249 } | 253 } |
250 | 254 |
251 } // namespace | 255 } // namespace |
252 | 256 |
253 void FuzzOneInput(const uint8_t* data, size_t size) { | 257 void FuzzOneInput(const uint8_t* data, size_t size) { |
254 std::unique_ptr<TransportFeedbackPacketLossTracker> tracker; | 258 std::unique_ptr<TransportFeedbackPacketLossTracker> tracker; |
(...skipping 11 matching lines...) Expand all Loading... |
266 while (may_continue) { | 270 while (may_continue) { |
267 may_continue = FuzzPacketSendBlock(tracker, &data, &size, &time_ms); | 271 may_continue = FuzzPacketSendBlock(tracker, &data, &size, &time_ms); |
268 if (!may_continue) { | 272 if (!may_continue) { |
269 return; | 273 return; |
270 } | 274 } |
271 may_continue = FuzzTransportFeedbackBlock(tracker, &data, &size); | 275 may_continue = FuzzTransportFeedbackBlock(tracker, &data, &size); |
272 } | 276 } |
273 } | 277 } |
274 | 278 |
275 } // namespace webrtc | 279 } // namespace webrtc |
OLD | NEW |