Home | History | Annotate | Download | only in test_tools
      1 // Copyright 2013 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/test_tools/quic_test_packet_maker.h"
      6 
      7 #include <list>
      8 
      9 #include "net/quic/quic_framer.h"
     10 #include "net/quic/quic_http_utils.h"
     11 #include "net/quic/quic_utils.h"
     12 #include "net/quic/test_tools/quic_test_utils.h"
     13 
     14 using std::make_pair;
     15 
     16 namespace net {
     17 namespace test {
     18 
     19 QuicTestPacketMaker::QuicTestPacketMaker(QuicVersion version,
     20                                          QuicConnectionId connection_id,
     21                                          MockClock* clock)
     22     : version_(version),
     23       connection_id_(connection_id),
     24       clock_(clock),
     25       spdy_request_framer_(SPDY3),
     26       spdy_response_framer_(SPDY3) {
     27 }
     28 
     29 QuicTestPacketMaker::~QuicTestPacketMaker() {
     30 }
     31 
     32 scoped_ptr<QuicEncryptedPacket> QuicTestPacketMaker::MakeRstPacket(
     33     QuicPacketSequenceNumber num,
     34     bool include_version,
     35     QuicStreamId stream_id,
     36     QuicRstStreamErrorCode error_code) {
     37   QuicPacketHeader header;
     38   header.public_header.connection_id = connection_id_;
     39   header.public_header.reset_flag = false;
     40   header.public_header.version_flag = include_version;
     41   header.public_header.sequence_number_length = PACKET_1BYTE_SEQUENCE_NUMBER;
     42   header.packet_sequence_number = num;
     43   header.entropy_flag = false;
     44   header.fec_flag = false;
     45   header.fec_group = 0;
     46 
     47   QuicRstStreamFrame rst(stream_id, error_code, 0);
     48   return scoped_ptr<QuicEncryptedPacket>(MakePacket(header, QuicFrame(&rst)));
     49 }
     50 
     51 scoped_ptr<QuicEncryptedPacket> QuicTestPacketMaker::MakeAckAndRstPacket(
     52     QuicPacketSequenceNumber num,
     53     bool include_version,
     54     QuicStreamId stream_id,
     55     QuicRstStreamErrorCode error_code,
     56     QuicPacketSequenceNumber largest_received,
     57     QuicPacketSequenceNumber least_unacked,
     58     bool send_feedback) {
     59 
     60   QuicPacketHeader header;
     61   header.public_header.connection_id = connection_id_;
     62   header.public_header.reset_flag = false;
     63   header.public_header.version_flag = include_version;
     64   header.public_header.sequence_number_length = PACKET_1BYTE_SEQUENCE_NUMBER;
     65   header.packet_sequence_number = num;
     66   header.entropy_flag = false;
     67   header.fec_flag = false;
     68   header.fec_group = 0;
     69 
     70   QuicAckFrame ack(MakeAckFrame(largest_received));
     71   ack.delta_time_largest_observed = QuicTime::Delta::Zero();
     72   if (version_ > QUIC_VERSION_22) {
     73     for (QuicPacketSequenceNumber i = least_unacked; i <= largest_received;
     74          ++i) {
     75       ack.received_packet_times.push_back(make_pair(i, clock_->Now()));
     76     }
     77   }
     78   QuicFrames frames;
     79   frames.push_back(QuicFrame(&ack));
     80   QuicCongestionFeedbackFrame feedback;
     81   if (send_feedback && version_ <= QUIC_VERSION_22) {
     82     feedback.type = kTCP;
     83     feedback.tcp.receive_window = 256000;
     84 
     85     frames.push_back(QuicFrame(&feedback));
     86   }
     87 
     88   QuicStopWaitingFrame stop_waiting;
     89   stop_waiting.least_unacked = least_unacked;
     90   frames.push_back(QuicFrame(&stop_waiting));
     91 
     92   QuicRstStreamFrame rst(stream_id, error_code, 0);
     93   frames.push_back(QuicFrame(&rst));
     94 
     95   QuicFramer framer(SupportedVersions(version_), clock_->Now(), false);
     96   scoped_ptr<QuicPacket> packet(
     97       BuildUnsizedDataPacket(&framer, header, frames).packet);
     98   return scoped_ptr<QuicEncryptedPacket>(framer.EncryptPacket(
     99       ENCRYPTION_NONE, header.packet_sequence_number, *packet));
    100 }
    101 
    102 scoped_ptr<QuicEncryptedPacket> QuicTestPacketMaker::MakeConnectionClosePacket(
    103     QuicPacketSequenceNumber num) {
    104   QuicPacketHeader header;
    105   header.public_header.connection_id = connection_id_;
    106   header.public_header.reset_flag = false;
    107   header.public_header.version_flag = false;
    108   header.public_header.sequence_number_length = PACKET_1BYTE_SEQUENCE_NUMBER;
    109   header.packet_sequence_number = num;
    110   header.entropy_flag = false;
    111   header.fec_flag = false;
    112   header.fec_group = 0;
    113 
    114   QuicConnectionCloseFrame close;
    115   close.error_code = QUIC_CRYPTO_VERSION_NOT_SUPPORTED;
    116   close.error_details = "Time to panic!";
    117   return scoped_ptr<QuicEncryptedPacket>(MakePacket(header, QuicFrame(&close)));
    118 }
    119 
    120 scoped_ptr<QuicEncryptedPacket> QuicTestPacketMaker::MakeAckPacket(
    121     QuicPacketSequenceNumber sequence_number,
    122     QuicPacketSequenceNumber largest_received,
    123     QuicPacketSequenceNumber least_unacked,
    124     bool send_feedback) {
    125   QuicPacketHeader header;
    126   header.public_header.connection_id = connection_id_;
    127   header.public_header.reset_flag = false;
    128   header.public_header.version_flag = false;
    129   header.public_header.sequence_number_length = PACKET_1BYTE_SEQUENCE_NUMBER;
    130   header.packet_sequence_number = sequence_number;
    131   header.entropy_flag = false;
    132   header.fec_flag = false;
    133   header.fec_group = 0;
    134 
    135   QuicAckFrame ack(MakeAckFrame(largest_received));
    136   ack.delta_time_largest_observed = QuicTime::Delta::Zero();
    137   if (version_ > QUIC_VERSION_22) {
    138     for (QuicPacketSequenceNumber i = least_unacked; i <= largest_received;
    139          ++i) {
    140       ack.received_packet_times.push_back(make_pair(i, clock_->Now()));
    141     }
    142   }
    143 
    144   QuicFramer framer(SupportedVersions(version_), clock_->Now(), false);
    145   QuicFrames frames;
    146   frames.push_back(QuicFrame(&ack));
    147   QuicCongestionFeedbackFrame feedback;
    148   if (send_feedback && version_ <= QUIC_VERSION_22) {
    149     feedback.type = kTCP;
    150     feedback.tcp.receive_window = 256000;
    151     frames.push_back(QuicFrame(&feedback));
    152   }
    153 
    154   QuicStopWaitingFrame stop_waiting;
    155   stop_waiting.least_unacked = least_unacked;
    156   frames.push_back(QuicFrame(&stop_waiting));
    157 
    158   scoped_ptr<QuicPacket> packet(
    159       BuildUnsizedDataPacket(&framer, header, frames).packet);
    160   return scoped_ptr<QuicEncryptedPacket>(framer.EncryptPacket(
    161       ENCRYPTION_NONE, header.packet_sequence_number, *packet));
    162 }
    163 
    164 // Returns a newly created packet to send kData on stream 1.
    165 scoped_ptr<QuicEncryptedPacket> QuicTestPacketMaker::MakeDataPacket(
    166     QuicPacketSequenceNumber sequence_number,
    167     QuicStreamId stream_id,
    168     bool should_include_version,
    169     bool fin,
    170     QuicStreamOffset offset,
    171     base::StringPiece data) {
    172   InitializeHeader(sequence_number, should_include_version);
    173   QuicStreamFrame frame(stream_id, fin, offset, MakeIOVector(data));
    174   return MakePacket(header_, QuicFrame(&frame));
    175 }
    176 
    177 scoped_ptr<QuicEncryptedPacket> QuicTestPacketMaker::MakeRequestHeadersPacket(
    178     QuicPacketSequenceNumber sequence_number,
    179     QuicStreamId stream_id,
    180     bool should_include_version,
    181     bool fin,
    182     const SpdyHeaderBlock& headers) {
    183   InitializeHeader(sequence_number, should_include_version);
    184   SpdySynStreamIR syn_stream(stream_id);
    185   syn_stream.set_name_value_block(headers);
    186   syn_stream.set_fin(fin);
    187   syn_stream.set_priority(0);
    188   scoped_ptr<SpdySerializedFrame> spdy_frame(
    189       spdy_request_framer_.SerializeSynStream(syn_stream));
    190   QuicStreamFrame frame(kHeadersStreamId, false, 0,
    191                         MakeIOVector(base::StringPiece(spdy_frame->data(),
    192                                                        spdy_frame->size())));
    193   return MakePacket(header_, QuicFrame(&frame));
    194 }
    195 
    196 scoped_ptr<QuicEncryptedPacket> QuicTestPacketMaker::MakeResponseHeadersPacket(
    197     QuicPacketSequenceNumber sequence_number,
    198     QuicStreamId stream_id,
    199     bool should_include_version,
    200     bool fin,
    201     const SpdyHeaderBlock& headers) {
    202   InitializeHeader(sequence_number, should_include_version);
    203   SpdySynReplyIR syn_reply(stream_id);
    204   syn_reply.set_name_value_block(headers);
    205   syn_reply.set_fin(fin);
    206   scoped_ptr<SpdySerializedFrame> spdy_frame(
    207       spdy_response_framer_.SerializeSynReply(syn_reply));
    208   QuicStreamFrame frame(kHeadersStreamId, false, 0,
    209                         MakeIOVector(base::StringPiece(spdy_frame->data(),
    210                                                        spdy_frame->size())));
    211   return MakePacket(header_, QuicFrame(&frame));
    212 }
    213 
    214 SpdyHeaderBlock QuicTestPacketMaker::GetRequestHeaders(
    215     const std::string& method,
    216     const std::string& scheme,
    217     const std::string& path) {
    218   SpdyHeaderBlock headers;
    219   headers[":method"] = method;
    220   headers[":host"] = "www.google.com";
    221   headers[":path"] = path;
    222   headers[":scheme"] = scheme;
    223   headers[":version"] = "HTTP/1.1";
    224   return headers;
    225 }
    226 
    227 SpdyHeaderBlock QuicTestPacketMaker::GetResponseHeaders(
    228     const std::string& status) {
    229   SpdyHeaderBlock headers;
    230   headers[":status"] = status;
    231   headers[":version"] = "HTTP/1.1";
    232   headers["content-type"] = "text/plain";
    233   return headers;
    234 }
    235 
    236 scoped_ptr<QuicEncryptedPacket> QuicTestPacketMaker::MakePacket(
    237     const QuicPacketHeader& header,
    238     const QuicFrame& frame) {
    239   QuicFramer framer(SupportedVersions(version_), QuicTime::Zero(), false);
    240   QuicFrames frames;
    241   frames.push_back(frame);
    242   scoped_ptr<QuicPacket> packet(
    243       BuildUnsizedDataPacket(&framer, header, frames).packet);
    244   return scoped_ptr<QuicEncryptedPacket>(framer.EncryptPacket(
    245       ENCRYPTION_NONE, header.packet_sequence_number, *packet));
    246 }
    247 
    248 void QuicTestPacketMaker::InitializeHeader(
    249     QuicPacketSequenceNumber sequence_number,
    250     bool should_include_version) {
    251   header_.public_header.connection_id = connection_id_;
    252   header_.public_header.reset_flag = false;
    253   header_.public_header.version_flag = should_include_version;
    254   header_.public_header.sequence_number_length = PACKET_1BYTE_SEQUENCE_NUMBER;
    255   header_.packet_sequence_number = sequence_number;
    256   header_.fec_group = 0;
    257   header_.entropy_flag = false;
    258   header_.fec_flag = false;
    259 }
    260 
    261 }  // namespace test
    262 }  // namespace net
    263