quic_test_packet_maker.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
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
14using std::make_pair;
15
16namespace net {
17namespace test {
18
19QuicTestPacketMaker::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
29QuicTestPacketMaker::~QuicTestPacketMaker() {
30}
31
32scoped_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
51scoped_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
102scoped_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
120scoped_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.
165scoped_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
177scoped_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
196scoped_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
214SpdyHeaderBlock 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
227SpdyHeaderBlock 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
236scoped_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
248void 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