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