Home | History | Annotate | Download | only in quic
      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
      3 // found in the LICENSE file.
      4 
      5 #include "net/quic/quic_protocol.h"
      6 
      7 #include "base/stl_util.h"
      8 #include "net/quic/quic_utils.h"
      9 
     10 using base::StringPiece;
     11 using std::map;
     12 using std::numeric_limits;
     13 using std::ostream;
     14 using std::string;
     15 
     16 namespace net {
     17 
     18 size_t GetPacketHeaderSize(QuicPacketHeader header) {
     19   return GetPacketHeaderSize(header.public_header.guid_length,
     20                              header.public_header.version_flag,
     21                              header.public_header.sequence_number_length,
     22                              header.is_in_fec_group);
     23 }
     24 
     25 size_t GetPacketHeaderSize(QuicGuidLength guid_length,
     26                            bool include_version,
     27                            QuicSequenceNumberLength sequence_number_length,
     28                            InFecGroup is_in_fec_group) {
     29   return kPublicFlagsSize + guid_length +
     30       (include_version ? kQuicVersionSize : 0) + sequence_number_length +
     31       kPrivateFlagsSize + (is_in_fec_group == IN_FEC_GROUP ? kFecGroupSize : 0);
     32 }
     33 
     34 size_t GetPublicResetPacketSize() {
     35   return kPublicFlagsSize + PACKET_8BYTE_GUID + kPublicResetNonceSize +
     36       PACKET_6BYTE_SEQUENCE_NUMBER;
     37 }
     38 
     39 size_t GetStartOfFecProtectedData(
     40     QuicGuidLength guid_length,
     41     bool include_version,
     42     QuicSequenceNumberLength sequence_number_length) {
     43   return GetPacketHeaderSize(
     44       guid_length, include_version, sequence_number_length, IN_FEC_GROUP);
     45 }
     46 
     47 size_t GetStartOfEncryptedData(
     48     QuicGuidLength guid_length,
     49     bool include_version,
     50     QuicSequenceNumberLength sequence_number_length) {
     51   // Don't include the fec size, since encryption starts before private flags.
     52   return GetPacketHeaderSize(
     53       guid_length, include_version, sequence_number_length, NOT_IN_FEC_GROUP) -
     54       kPrivateFlagsSize;
     55 }
     56 
     57 QuicPacketPublicHeader::QuicPacketPublicHeader()
     58     : guid(0),
     59       guid_length(PACKET_8BYTE_GUID),
     60       reset_flag(false),
     61       version_flag(false),
     62       sequence_number_length(PACKET_6BYTE_SEQUENCE_NUMBER) {
     63 }
     64 
     65 QuicPacketPublicHeader::QuicPacketPublicHeader(
     66     const QuicPacketPublicHeader& other)
     67     : guid(other.guid),
     68       guid_length(other.guid_length),
     69       reset_flag(other.reset_flag),
     70       version_flag(other.version_flag),
     71       sequence_number_length(other.sequence_number_length),
     72       versions(other.versions) {
     73 }
     74 
     75 QuicPacketPublicHeader::~QuicPacketPublicHeader() {}
     76 
     77 QuicPacketHeader::QuicPacketHeader()
     78     : fec_flag(false),
     79       entropy_flag(false),
     80       entropy_hash(0),
     81       packet_sequence_number(0),
     82       is_in_fec_group(NOT_IN_FEC_GROUP),
     83       fec_group(0) {
     84 }
     85 
     86 QuicPacketHeader::QuicPacketHeader(const QuicPacketPublicHeader& header)
     87     : public_header(header),
     88       fec_flag(false),
     89       entropy_flag(false),
     90       entropy_hash(0),
     91       packet_sequence_number(0),
     92       is_in_fec_group(NOT_IN_FEC_GROUP),
     93       fec_group(0) {
     94 }
     95 
     96 QuicStreamFrame::QuicStreamFrame() {}
     97 
     98 QuicStreamFrame::QuicStreamFrame(const QuicStreamFrame& frame)
     99     : stream_id(frame.stream_id),
    100       fin(frame.fin),
    101       offset(frame.offset),
    102       data(frame.data),
    103       notifier(frame.notifier) {
    104 }
    105 
    106 QuicStreamFrame::QuicStreamFrame(QuicStreamId stream_id,
    107                                  bool fin,
    108                                  QuicStreamOffset offset,
    109                                  IOVector data)
    110     : stream_id(stream_id),
    111       fin(fin),
    112       offset(offset),
    113       data(data),
    114       notifier(NULL) {
    115 }
    116 
    117 string* QuicStreamFrame::GetDataAsString() const {
    118   string* data_string = new string();
    119   data_string->reserve(data.TotalBufferSize());
    120   for (size_t i = 0; i < data.Size(); ++i) {
    121     data_string->append(static_cast<char*>(data.iovec()[i].iov_base),
    122                         data.iovec()[i].iov_len);
    123   }
    124   DCHECK_EQ(data_string->size(), data.TotalBufferSize());
    125   return data_string;
    126 }
    127 
    128 uint32 MakeQuicTag(char a, char b, char c, char d) {
    129   return static_cast<uint32>(a) |
    130          static_cast<uint32>(b) << 8 |
    131          static_cast<uint32>(c) << 16 |
    132          static_cast<uint32>(d) << 24;
    133 }
    134 
    135 QuicVersionVector QuicSupportedVersions() {
    136   QuicVersionVector supported_versions;
    137   for (size_t i = 0; i < arraysize(kSupportedQuicVersions); ++i) {
    138     supported_versions.push_back(kSupportedQuicVersions[i]);
    139   }
    140   return supported_versions;
    141 }
    142 
    143 QuicTag QuicVersionToQuicTag(const QuicVersion version) {
    144   switch (version) {
    145     case QUIC_VERSION_12:
    146       return MakeQuicTag('Q', '0', '1', '2');
    147     default:
    148       // This shold be an ERROR because we should never attempt to convert an
    149       // invalid QuicVersion to be written to the wire.
    150       LOG(ERROR) << "Unsupported QuicVersion: " << version;
    151       return 0;
    152   }
    153 }
    154 
    155 QuicVersion QuicTagToQuicVersion(const QuicTag version_tag) {
    156   for (size_t i = 0; i < arraysize(kSupportedQuicVersions); ++i) {
    157     if (version_tag == QuicVersionToQuicTag(kSupportedQuicVersions[i])) {
    158       return kSupportedQuicVersions[i];
    159     }
    160   }
    161   // Reading from the client so this should not be considered an ERROR.
    162   DVLOG(1) << "Unsupported QuicTag version: "
    163              << QuicUtils::TagToString(version_tag);
    164   return QUIC_VERSION_UNSUPPORTED;
    165 }
    166 
    167 #define RETURN_STRING_LITERAL(x) \
    168 case x: \
    169 return #x
    170 
    171 string QuicVersionToString(const QuicVersion version) {
    172   switch (version) {
    173     RETURN_STRING_LITERAL(QUIC_VERSION_12);
    174     default:
    175       return "QUIC_VERSION_UNSUPPORTED";
    176   }
    177 }
    178 
    179 string QuicVersionVectorToString(const QuicVersionVector& versions) {
    180   string result = "";
    181   for (size_t i = 0; i < versions.size(); ++i) {
    182     if (i != 0) {
    183       result.append(",");
    184     }
    185     result.append(QuicVersionToString(versions[i]));
    186   }
    187   return result;
    188 }
    189 
    190 ostream& operator<<(ostream& os, const QuicPacketHeader& header) {
    191   os << "{ guid: " << header.public_header.guid
    192      << ", guid_length:" << header.public_header.guid_length
    193      << ", sequence_number_length:"
    194      << header.public_header.sequence_number_length
    195      << ", reset_flag: " << header.public_header.reset_flag
    196      << ", version_flag: " << header.public_header.version_flag;
    197   if (header.public_header.version_flag) {
    198     os << " version: ";
    199     for (size_t i = 0; i < header.public_header.versions.size(); ++i) {
    200       os << header.public_header.versions[0] << " ";
    201     }
    202   }
    203   os << ", fec_flag: " << header.fec_flag
    204      << ", entropy_flag: " << header.entropy_flag
    205      << ", entropy hash: " << static_cast<int>(header.entropy_hash)
    206      << ", sequence_number: " << header.packet_sequence_number
    207      << ", is_in_fec_group:" << header.is_in_fec_group
    208      << ", fec_group: " << header.fec_group<< "}\n";
    209   return os;
    210 }
    211 
    212 ReceivedPacketInfo::ReceivedPacketInfo()
    213     : largest_observed(0),
    214       delta_time_largest_observed(QuicTime::Delta::Infinite()),
    215       is_truncated(false) {
    216 }
    217 
    218 ReceivedPacketInfo::~ReceivedPacketInfo() {}
    219 
    220 bool IsAwaitingPacket(const ReceivedPacketInfo& received_info,
    221                       QuicPacketSequenceNumber sequence_number) {
    222   return sequence_number > received_info.largest_observed ||
    223       ContainsKey(received_info.missing_packets, sequence_number);
    224 }
    225 
    226 void InsertMissingPacketsBetween(ReceivedPacketInfo* received_info,
    227                                  QuicPacketSequenceNumber lower,
    228                                  QuicPacketSequenceNumber higher) {
    229   for (QuicPacketSequenceNumber i = lower; i < higher; ++i) {
    230     received_info->missing_packets.insert(i);
    231   }
    232 }
    233 
    234 SentPacketInfo::SentPacketInfo() {}
    235 
    236 SentPacketInfo::~SentPacketInfo() {}
    237 
    238 // Testing convenience method.
    239 QuicAckFrame::QuicAckFrame(QuicPacketSequenceNumber largest_observed,
    240                            QuicTime largest_observed_receive_time,
    241                            QuicPacketSequenceNumber least_unacked) {
    242   received_info.largest_observed = largest_observed;
    243   received_info.entropy_hash = 0;
    244   sent_info.least_unacked = least_unacked;
    245   sent_info.entropy_hash = 0;
    246 }
    247 
    248 ostream& operator<<(ostream& os, const SentPacketInfo& sent_info) {
    249   os << "entropy_hash: " << static_cast<int>(sent_info.entropy_hash)
    250      << " least_unacked: " << sent_info.least_unacked;
    251   return os;
    252 }
    253 
    254 ostream& operator<<(ostream& os, const ReceivedPacketInfo& received_info) {
    255   os << "entropy_hash: " << static_cast<int>(received_info.entropy_hash)
    256      << " largest_observed: " << received_info.largest_observed
    257      << " missing_packets: [ ";
    258   for (SequenceNumberSet::const_iterator it =
    259            received_info.missing_packets.begin();
    260        it != received_info.missing_packets.end(); ++it) {
    261     os << *it << " ";
    262   }
    263   os << " ] ";
    264   return os;
    265 }
    266 
    267 QuicCongestionFeedbackFrame::QuicCongestionFeedbackFrame() {
    268 }
    269 
    270 QuicCongestionFeedbackFrame::~QuicCongestionFeedbackFrame() {
    271 }
    272 
    273 ostream& operator<<(ostream& os,
    274                     const QuicCongestionFeedbackFrame& congestion_frame) {
    275   os << "type: " << congestion_frame.type;
    276   switch (congestion_frame.type) {
    277     case kInterArrival: {
    278       const CongestionFeedbackMessageInterArrival& inter_arrival =
    279           congestion_frame.inter_arrival;
    280       os << " accumulated_number_of_lost_packets: "
    281          << inter_arrival.accumulated_number_of_lost_packets;
    282       os << " received packets: [ ";
    283       for (TimeMap::const_iterator it =
    284                inter_arrival.received_packet_times.begin();
    285            it != inter_arrival.received_packet_times.end(); ++it) {
    286         os << it->first << "@" << it->second.ToDebuggingValue() << " ";
    287       }
    288       os << "]";
    289       break;
    290     }
    291     case kFixRate: {
    292       os << " bitrate_in_bytes_per_second: "
    293          << congestion_frame.fix_rate.bitrate.ToBytesPerSecond();
    294       break;
    295     }
    296     case kTCP: {
    297       const CongestionFeedbackMessageTCP& tcp = congestion_frame.tcp;
    298       os << " accumulated_number_of_lost_packets: "
    299          << congestion_frame.tcp.accumulated_number_of_lost_packets;
    300       os << " receive_window: " << tcp.receive_window;
    301       break;
    302     }
    303   }
    304   return os;
    305 }
    306 
    307 ostream& operator<<(ostream& os, const QuicAckFrame& ack_frame) {
    308   os << "sent info { " << ack_frame.sent_info << " } "
    309      << "received info { " << ack_frame.received_info << " }\n";
    310   return os;
    311 }
    312 
    313 CongestionFeedbackMessageFixRate::CongestionFeedbackMessageFixRate()
    314     : bitrate(QuicBandwidth::Zero()) {
    315 }
    316 
    317 CongestionFeedbackMessageInterArrival::
    318 CongestionFeedbackMessageInterArrival() {}
    319 
    320 CongestionFeedbackMessageInterArrival::
    321 ~CongestionFeedbackMessageInterArrival() {}
    322 
    323 QuicGoAwayFrame::QuicGoAwayFrame(QuicErrorCode error_code,
    324                                  QuicStreamId last_good_stream_id,
    325                                  const string& reason)
    326     : error_code(error_code),
    327       last_good_stream_id(last_good_stream_id),
    328       reason_phrase(reason) {
    329   DCHECK_LE(error_code, numeric_limits<uint8>::max());
    330 }
    331 
    332 QuicFecData::QuicFecData() {}
    333 
    334 QuicData::~QuicData() {
    335   if (owns_buffer_) {
    336     delete [] const_cast<char*>(buffer_);
    337   }
    338 }
    339 
    340 StringPiece QuicPacket::FecProtectedData() const {
    341   const size_t start_of_fec = GetStartOfFecProtectedData(
    342       guid_length_, includes_version_, sequence_number_length_);
    343   return StringPiece(data() + start_of_fec, length() - start_of_fec);
    344 }
    345 
    346 StringPiece QuicPacket::AssociatedData() const {
    347   return StringPiece(
    348       data() + kStartOfHashData,
    349       GetStartOfEncryptedData(
    350           guid_length_, includes_version_, sequence_number_length_) -
    351       kStartOfHashData);
    352 }
    353 
    354 StringPiece QuicPacket::BeforePlaintext() const {
    355   return StringPiece(data(), GetStartOfEncryptedData(guid_length_,
    356                                                      includes_version_,
    357                                                      sequence_number_length_));
    358 }
    359 
    360 StringPiece QuicPacket::Plaintext() const {
    361   const size_t start_of_encrypted_data =
    362       GetStartOfEncryptedData(
    363           guid_length_, includes_version_, sequence_number_length_);
    364   return StringPiece(data() + start_of_encrypted_data,
    365                      length() - start_of_encrypted_data);
    366 }
    367 
    368 RetransmittableFrames::RetransmittableFrames()
    369     : encryption_level_(NUM_ENCRYPTION_LEVELS) {
    370 }
    371 
    372 RetransmittableFrames::~RetransmittableFrames() {
    373   for (QuicFrames::iterator it = frames_.begin(); it != frames_.end(); ++it) {
    374     switch (it->type) {
    375       case PADDING_FRAME:
    376         delete it->padding_frame;
    377         break;
    378       case STREAM_FRAME:
    379         delete it->stream_frame;
    380         break;
    381       case ACK_FRAME:
    382         delete it->ack_frame;
    383         break;
    384       case CONGESTION_FEEDBACK_FRAME:
    385         delete it->congestion_feedback_frame;
    386         break;
    387       case RST_STREAM_FRAME:
    388         delete it->rst_stream_frame;
    389         break;
    390       case CONNECTION_CLOSE_FRAME:
    391         delete it->connection_close_frame;
    392         break;
    393       case GOAWAY_FRAME:
    394         delete it->goaway_frame;
    395         break;
    396       case NUM_FRAME_TYPES:
    397         DCHECK(false) << "Cannot delete type: " << it->type;
    398     }
    399   }
    400   STLDeleteElements(&stream_data_);
    401 }
    402 
    403 const QuicFrame& RetransmittableFrames::AddStreamFrame(
    404     QuicStreamFrame* stream_frame) {
    405   // Make an owned copy of the stream frame's data.
    406   stream_data_.push_back(stream_frame->GetDataAsString());
    407   // Ensure the stream frame's IOVector points to the owned copy of the data.
    408   stream_frame->data.Clear();
    409   stream_frame->data.Append(const_cast<char*>(stream_data_.back()->data()),
    410                             stream_data_.back()->size());
    411   frames_.push_back(QuicFrame(stream_frame));
    412   return frames_.back();
    413 }
    414 
    415 const QuicFrame& RetransmittableFrames::AddNonStreamFrame(
    416     const QuicFrame& frame) {
    417   DCHECK_NE(frame.type, STREAM_FRAME);
    418   frames_.push_back(frame);
    419   return frames_.back();
    420 }
    421 
    422 void RetransmittableFrames::set_encryption_level(EncryptionLevel level) {
    423   encryption_level_ = level;
    424 }
    425 
    426 SerializedPacket::SerializedPacket(
    427     QuicPacketSequenceNumber sequence_number,
    428     QuicSequenceNumberLength sequence_number_length,
    429     QuicPacket* packet,
    430     QuicPacketEntropyHash entropy_hash,
    431     RetransmittableFrames* retransmittable_frames)
    432     : sequence_number(sequence_number),
    433       sequence_number_length(sequence_number_length),
    434       packet(packet),
    435       entropy_hash(entropy_hash),
    436       retransmittable_frames(retransmittable_frames) {
    437 }
    438 
    439 SerializedPacket::~SerializedPacket() {}
    440 
    441 QuicEncryptedPacket* QuicEncryptedPacket::Clone() const {
    442   char* buffer = new char[this->length()];
    443   memcpy(buffer, this->data(), this->length());
    444   return new QuicEncryptedPacket(buffer, this->length(), true);
    445 }
    446 
    447 ostream& operator<<(ostream& os, const QuicEncryptedPacket& s) {
    448   os << s.length() << "-byte data";
    449   return os;
    450 }
    451 
    452 ostream& operator<<(ostream& os, const QuicConsumedData& s) {
    453   os << "bytes_consumed: " << s.bytes_consumed
    454      << " fin_consumed: " << s.fin_consumed;
    455   return os;
    456 }
    457 
    458 }  // namespace net
    459