| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/quic/quic_fec_group.h" | 5 #include "net/quic/quic_fec_group.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 | 11 |
| 12 using base::StringPiece; | 12 using base::StringPiece; |
| 13 using std::numeric_limits; | 13 using std::numeric_limits; |
| 14 using std::set; | 14 using std::set; |
| 15 | 15 |
| 16 namespace net { | 16 namespace net { |
| 17 | 17 |
| 18 namespace { | 18 namespace { |
| 19 const QuicPacketSequenceNumber kNoSequenceNumber = kuint64max; | 19 const QuicPacketSequenceNumber kNoSequenceNumber = kuint64max; |
| 20 } // namespace | 20 } // namespace |
| 21 | 21 |
| 22 QuicFecGroup::QuicFecGroup() | 22 QuicFecGroup::QuicFecGroup() |
| 23 : min_protected_packet_(kNoSequenceNumber), | 23 : min_protected_packet_(kNoSequenceNumber), |
| 24 max_protected_packet_(kNoSequenceNumber), | 24 max_protected_packet_(kNoSequenceNumber), |
| 25 payload_parity_len_(0) { | 25 payload_parity_len_(0) { |
| 26 } | 26 } |
| 27 | 27 |
| 28 QuicFecGroup::~QuicFecGroup() {} | 28 QuicFecGroup::~QuicFecGroup() { |
| 29 } |
| 29 | 30 |
| 30 bool QuicFecGroup::Update(const QuicPacketHeader& header, | 31 bool QuicFecGroup::Update(const QuicPacketHeader& header, |
| 31 StringPiece decrypted_payload) { | 32 StringPiece decrypted_payload) { |
| 32 if (received_packets_.count(header.packet_sequence_number) != 0) { | 33 if (received_packets_.count(header.packet_sequence_number) != 0) { |
| 33 return false; | 34 return false; |
| 34 } | 35 } |
| 35 if (min_protected_packet_ != kNoSequenceNumber && | 36 if (min_protected_packet_ != kNoSequenceNumber && |
| 36 max_protected_packet_ != kNoSequenceNumber && | 37 max_protected_packet_ != kNoSequenceNumber && |
| 37 (header.packet_sequence_number < min_protected_packet_ || | 38 (header.packet_sequence_number < min_protected_packet_ || |
| 38 header.packet_sequence_number > max_protected_packet_)) { | 39 header.packet_sequence_number > max_protected_packet_)) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 size_t QuicFecGroup::Revive(QuicPacketHeader* header, | 83 size_t QuicFecGroup::Revive(QuicPacketHeader* header, |
| 83 char* decrypted_payload, | 84 char* decrypted_payload, |
| 84 size_t decrypted_payload_len) { | 85 size_t decrypted_payload_len) { |
| 85 if (!CanRevive()) { | 86 if (!CanRevive()) { |
| 86 return 0; | 87 return 0; |
| 87 } | 88 } |
| 88 | 89 |
| 89 // Identify the packet sequence number to be resurrected. | 90 // Identify the packet sequence number to be resurrected. |
| 90 QuicPacketSequenceNumber missing = kNoSequenceNumber; | 91 QuicPacketSequenceNumber missing = kNoSequenceNumber; |
| 91 for (QuicPacketSequenceNumber i = min_protected_packet_; | 92 for (QuicPacketSequenceNumber i = min_protected_packet_; |
| 92 i <= max_protected_packet_; ++i) { | 93 i <= max_protected_packet_; |
| 94 ++i) { |
| 93 // Is this packet missing? | 95 // Is this packet missing? |
| 94 if (received_packets_.count(i) == 0) { | 96 if (received_packets_.count(i) == 0) { |
| 95 missing = i; | 97 missing = i; |
| 96 break; | 98 break; |
| 97 } | 99 } |
| 98 } | 100 } |
| 99 DCHECK_NE(kNoSequenceNumber, missing); | 101 DCHECK_NE(kNoSequenceNumber, missing); |
| 100 | 102 |
| 101 DCHECK_LE(payload_parity_len_, decrypted_payload_len); | 103 DCHECK_LE(payload_parity_len_, decrypted_payload_len); |
| 102 if (payload_parity_len_ > decrypted_payload_len) { | 104 if (payload_parity_len_ > decrypted_payload_len) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 125 bool QuicFecGroup::UpdateParity(StringPiece payload) { | 127 bool QuicFecGroup::UpdateParity(StringPiece payload) { |
| 126 DCHECK_LE(payload.size(), kMaxPacketSize); | 128 DCHECK_LE(payload.size(), kMaxPacketSize); |
| 127 if (payload.size() > kMaxPacketSize) { | 129 if (payload.size() > kMaxPacketSize) { |
| 128 DLOG(ERROR) << "Illegal payload size: " << payload.size(); | 130 DLOG(ERROR) << "Illegal payload size: " << payload.size(); |
| 129 return false; | 131 return false; |
| 130 } | 132 } |
| 131 if (payload_parity_len_ < payload.size()) { | 133 if (payload_parity_len_ < payload.size()) { |
| 132 payload_parity_len_ = payload.size(); | 134 payload_parity_len_ = payload.size(); |
| 133 } | 135 } |
| 134 DCHECK_LE(payload.size(), kMaxPacketSize); | 136 DCHECK_LE(payload.size(), kMaxPacketSize); |
| 135 if (received_packets_.empty() && | 137 if (received_packets_.empty() && min_protected_packet_ == kNoSequenceNumber) { |
| 136 min_protected_packet_ == kNoSequenceNumber) { | |
| 137 // Initialize the parity to the value of this payload | 138 // Initialize the parity to the value of this payload |
| 138 memcpy(payload_parity_, payload.data(), payload.size()); | 139 memcpy(payload_parity_, payload.data(), payload.size()); |
| 139 if (payload.size() < kMaxPacketSize) { | 140 if (payload.size() < kMaxPacketSize) { |
| 140 // TODO(rch): expand as needed. | 141 // TODO(rch): expand as needed. |
| 141 memset(payload_parity_ + payload.size(), 0, | 142 memset( |
| 142 kMaxPacketSize - payload.size()); | 143 payload_parity_ + payload.size(), 0, kMaxPacketSize - payload.size()); |
| 143 } | 144 } |
| 144 return true; | 145 return true; |
| 145 } | 146 } |
| 146 // Update the parity by XORing in the data (padding with 0s if necessary). | 147 // Update the parity by XORing in the data (padding with 0s if necessary). |
| 147 for (size_t i = 0; i < kMaxPacketSize; ++i) { | 148 for (size_t i = 0; i < kMaxPacketSize; ++i) { |
| 148 uint8 byte = i < payload.size() ? payload[i] : 0x00; | 149 uint8 byte = i < payload.size() ? payload[i] : 0x00; |
| 149 payload_parity_[i] ^= byte; | 150 payload_parity_[i] ^= byte; |
| 150 } | 151 } |
| 151 return true; | 152 return true; |
| 152 } | 153 } |
| 153 | 154 |
| 154 size_t QuicFecGroup::NumMissingPackets() const { | 155 size_t QuicFecGroup::NumMissingPackets() const { |
| 155 if (min_protected_packet_ == kNoSequenceNumber) | 156 if (min_protected_packet_ == kNoSequenceNumber) |
| 156 return numeric_limits<size_t>::max(); | 157 return numeric_limits<size_t>::max(); |
| 157 return (max_protected_packet_ - min_protected_packet_ + 1) - | 158 return (max_protected_packet_ - min_protected_packet_ + 1) - |
| 158 received_packets_.size(); | 159 received_packets_.size(); |
| 159 } | 160 } |
| 160 | 161 |
| 161 } // namespace net | 162 } // namespace net |
| OLD | NEW |