| 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->OnNewTransportFeedbackVector(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 |