quic_packet_creator.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/quic/quic_packet_creator.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/quic/quic_utils.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//#include "util/random/acmrandom.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::StringPiece;
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::make_pair;
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::min;
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::pair;
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::vector;
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)QuicPacketCreator::QuicPacketCreator(QuicGuid guid, QuicFramer* framer)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : guid_(guid),
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      framer_(framer),
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sequence_number_(0),
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      fec_group_number_(1) {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  framer_->set_fec_builder(this);
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)QuicPacketCreator::~QuicPacketCreator() {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuicPacketCreator::OnBuiltFecProtectedPayload(
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const QuicPacketHeader& header,
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StringPiece payload) {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (fec_group_.get()) {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fec_group_->Update(header, payload);
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuicPacketCreator::DataToStream(QuicStreamId id,
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     StringPiece data,
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     QuicStreamOffset offset,
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     bool fin,
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     vector<PacketPair>* packets) {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GT(options_.max_packet_length,
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            QuicUtils::StreamFramePacketOverhead(1));
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicPacketHeader header;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicPacket* packet = NULL;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicFrames frames;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicFecGroupNumber current_fec_group = 0;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicFecData fec_data;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (options_.use_fec) {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(!fec_group_.get());
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fec_group_.reset(new QuicFecGroup);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    current_fec_group = fec_group_number_;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fec_data.fec_group = current_fec_group;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fec_data.min_protected_packet_sequence_number = sequence_number_ + 1;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (data.size() != 0) {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t data_to_send = data.size();
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t max_frame_len = framer_->GetMaxPlaintextSize(
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        options_.max_packet_length -
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        QuicUtils::StreamFramePacketOverhead(1));
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK_GT(max_frame_len, 0u);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t frame_len = min<size_t>(max_frame_len, data_to_send);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (data_to_send > 0) {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bool set_fin = false;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (data_to_send <= frame_len) {  // last loop
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        frame_len = min(data_to_send, frame_len);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        set_fin = fin && !options_.separate_fin_packet;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      StringPiece data_frame(data.data() + data.size() - data_to_send,
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                frame_len);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      QuicStreamFrame frame(id, set_fin, offset, data_frame);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      frames.push_back(QuicFrame(&frame));
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FillPacketHeader(current_fec_group, PACKET_FLAGS_NONE, &header);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      offset += frame_len;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_to_send -= frame_len;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Produce the data packet (which might fin the stream).
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      framer_->ConstructFrameDataPacket(header, frames, &packet);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK_GE(options_.max_packet_length, packet->length());
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      packets->push_back(make_pair(header.packet_sequence_number, packet));
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      frames.clear();
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a new packet for the fin, if necessary.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (fin && (options_.separate_fin_packet || data.size() == 0)) {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FillPacketHeader(current_fec_group, PACKET_FLAGS_NONE, &header);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    QuicStreamFrame frame(id, true, offset, "");
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frames.push_back(QuicFrame(&frame));
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    framer_->ConstructFrameDataPacket(header, frames, &packet);
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    packets->push_back(make_pair(header.packet_sequence_number, packet));
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frames.clear();
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a new FEC packet, if necessary
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (current_fec_group != 0) {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FillPacketHeader(current_fec_group, PACKET_FLAGS_FEC, &header);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fec_data.redundancy = fec_group_->parity();
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    QuicPacket* fec_packet;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    framer_->ConstructFecPacket(header, fec_data, &fec_packet);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    packets->push_back(make_pair(header.packet_sequence_number, fec_packet));
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++fec_group_number_;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /*
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (options_.random_reorder) {
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32 seed = ACMRandom::HostnamePidTimeSeed();
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ACMRandom random(seed);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(INFO) << "Seed " << seed;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vector<PacketPair> tmp_store;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tmp_store.swap(*packets);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (tmp_store.size() != 0) {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int idx = random.Uniform(tmp_store.size());
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      packets->push_back(tmp_store[idx]);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tmp_store.erase(tmp_store.begin() + idx);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  */
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fec_group_.reset(NULL);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)QuicPacketCreator::PacketPair QuicPacketCreator::ResetStream(
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    QuicStreamId id,
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    QuicStreamOffset offset,
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    QuicErrorCode error) {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicPacketHeader header;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FillPacketHeader(0, PACKET_FLAGS_NONE, &header);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicRstStreamFrame close_frame(id, offset, error);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicPacket* packet;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicFrames frames;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  frames.push_back(QuicFrame(&close_frame));
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  framer_->ConstructFrameDataPacket(header, frames, &packet);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return make_pair(header.packet_sequence_number, packet);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)QuicPacketCreator::PacketPair QuicPacketCreator::CloseConnection(
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    QuicConnectionCloseFrame* close_frame) {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicPacketHeader header;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FillPacketHeader(0, PACKET_FLAGS_NONE, &header);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicPacket* packet;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicFrames frames;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  frames.push_back(QuicFrame(close_frame));
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  framer_->ConstructFrameDataPacket(header, frames, &packet);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return make_pair(header.packet_sequence_number, packet);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)QuicPacketCreator::PacketPair QuicPacketCreator::AckPacket(
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    QuicAckFrame* ack_frame) {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicPacketHeader header;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FillPacketHeader(0, PACKET_FLAGS_NONE, &header);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicPacket* packet;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicFrames frames;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  frames.push_back(QuicFrame(ack_frame));
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  framer_->ConstructFrameDataPacket(header, frames, &packet);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return make_pair(header.packet_sequence_number, packet);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)QuicPacketSequenceNumber QuicPacketCreator::SetNewSequenceNumber(
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    QuicPacket* packet) {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ++sequence_number_;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  framer_->WriteSequenceNumber(sequence_number_, packet);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return sequence_number_;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuicPacketCreator::FillPacketHeader(QuicFecGroupNumber fec_group,
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         QuicPacketFlags flags,
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         QuicPacketHeader* header) {
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  header->guid = guid_;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  header->flags = flags;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  header->packet_sequence_number = ++sequence_number_;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  header->fec_group = fec_group;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
188