Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(66)

Side by Side Diff: net/quic/quic_client_session_test.cc

Issue 11633030: Send the ClientHello handshake message. Fix a bug in (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/quic/quic_client_session.h" 5 #include "net/quic/quic_client_session.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/stl_util.h" 9 #include "base/stl_util.h"
10 #include "net/base/test_completion_callback.h" 10 #include "net/base/test_completion_callback.h"
11 #include "net/quic/crypto/crypto_protocol.h" 11 #include "net/quic/crypto/crypto_protocol.h"
12 #include "net/quic/test_tools/quic_test_utils.h" 12 #include "net/quic/test_tools/quic_test_utils.h"
13 13
14 using base::StringPiece;
15 using std::vector;
14 using testing::_; 16 using testing::_;
15 17
16 namespace net { 18 namespace net {
17 namespace test { 19 namespace test {
18 namespace { 20 namespace {
19 21
22 class TestEncrypter : public QuicEncrypter {
23 public:
24 virtual QuicData* Encrypt(StringPiece associated_data,
25 StringPiece plaintext) {
26 return new QuicData(plaintext.data(), plaintext.length());
27 }
28 virtual size_t GetMaxPlaintextSize(size_t ciphertext_size) {
29 return ciphertext_size;
30 }
31 virtual size_t GetCiphertextSize(size_t plaintext_size) {
32 return plaintext_size;
33 }
34 };
35
36 class TestDecrypter : public QuicDecrypter {
37 public:
38 virtual QuicData* Decrypt(StringPiece associated_data,
39 StringPiece ciphertext) {
40 return new QuicData(ciphertext.data(), ciphertext.length());
41 }
42 };
43
44 class TestQuicVisitor : public NoOpFramerVisitor {
45 public:
46 TestQuicVisitor() {}
47
48 // NoOpFramerVisitor
49 virtual void OnStreamFrame(const QuicStreamFrame& frame) {
50 frame_ = frame;
51 }
52
53 QuicStreamFrame* frame() { return &frame_; }
54
55 private:
56 QuicStreamFrame frame_;
57
58 DISALLOW_COPY_AND_ASSIGN(TestQuicVisitor);
59 };
60
61 class TestCryptoVisitor : public CryptoFramerVisitorInterface {
62 public:
63 TestCryptoVisitor()
64 : error_count_(0) {
65 }
66
67 virtual void OnError(CryptoFramer* framer) {
68 DLOG(ERROR) << "CryptoFramer Error: " << framer->error();
69 ++error_count_;
70 }
71
72 virtual void OnHandshakeMessage(const CryptoHandshakeMessage& message) {
73 messages_.push_back(message);
74 }
75
76 // Counters from the visitor callbacks.
77 int error_count_;
78
79 vector<CryptoHandshakeMessage> messages_;
80 };
81
20 class QuicClientSessionTest : public ::testing::Test { 82 class QuicClientSessionTest : public ::testing::Test {
21 protected: 83 protected:
22 QuicClientSessionTest() 84 QuicClientSessionTest()
23 : guid_(1), 85 : guid_(1),
24 connection_(new PacketSavingConnection(guid_, IPEndPoint())), 86 connection_(new PacketSavingConnection(guid_, IPEndPoint())),
25 session_(connection_, NULL, NULL) { 87 session_(connection_, NULL, NULL) {
26 } 88 }
27 89
28 protected: 90 // Checks whether |packet| is the default ClientHello packet.
91 void CheckClientHelloPacket(QuicPacket* packet);
92
29 QuicGuid guid_; 93 QuicGuid guid_;
30 PacketSavingConnection* connection_; 94 PacketSavingConnection* connection_;
31 QuicClientSession session_; 95 QuicClientSession session_;
32 QuicConnectionVisitorInterface* visitor_; 96 QuicConnectionVisitorInterface* visitor_;
33 TestCompletionCallback callback_; 97 TestCompletionCallback callback_;
34 }; 98 };
35 99
100 void QuicClientSessionTest::CheckClientHelloPacket(QuicPacket* packet) {
101 QuicFramer quic_framer(new TestDecrypter, new TestEncrypter);
102 TestQuicVisitor quic_visitor;
103 quic_framer.set_visitor(&quic_visitor);
104 QuicEncryptedPacket encrypted(packet->data(), packet->length());
105 ASSERT_TRUE(quic_framer.ProcessPacket(IPEndPoint(), IPEndPoint(),
106 encrypted));
107 EXPECT_EQ(kCryptoStreamId, quic_visitor.frame()->stream_id);
108 EXPECT_FALSE(quic_visitor.frame()->fin);
109 EXPECT_EQ(0u, quic_visitor.frame()->offset);
110
111 // Check quic_visitor.frame()->data.
112 test::TestCryptoVisitor crypto_visitor;
113 CryptoFramer crypto_framer;
114 crypto_framer.set_visitor(&crypto_visitor);
115 ASSERT_TRUE(crypto_framer.ProcessInput(quic_visitor.frame()->data));
116 ASSERT_EQ(0u, crypto_framer.InputBytesRemaining());
117 ASSERT_EQ(1u, crypto_visitor.messages_.size());
118 EXPECT_EQ(kCHLO, crypto_visitor.messages_[0].tag);
119
120 CryptoTagValueMap& tag_value_map =
121 crypto_visitor.messages_[0].tag_value_map;
122 ASSERT_EQ(7u, tag_value_map.size());
123
124 // kNONC
125 // TODO(wtc): check the nonce.
126 ASSERT_EQ(32u, tag_value_map[kNONC].size());
127
128 // kAEAD
129 ASSERT_EQ(8u, tag_value_map[kAEAD].size());
130 CryptoTag cipher[2];
131 memcpy(&cipher[0], &tag_value_map[kAEAD][0], 4);
132 memcpy(&cipher[1], &tag_value_map[kAEAD][4], 4);
133 EXPECT_EQ(kAESG, cipher[0]);
134 EXPECT_EQ(kAESH, cipher[1]);
135
136 // kICSL
137 ASSERT_EQ(4u, tag_value_map[kICSL].size());
138 uint32 idle_lifetime;
139 memcpy(&idle_lifetime, tag_value_map[kICSL].data(), 4);
140 EXPECT_EQ(300u, idle_lifetime);
141
142 // kKATO
143 ASSERT_EQ(4u, tag_value_map[kKATO].size());
144 uint32 keepalive_timeout;
145 memcpy(&keepalive_timeout, tag_value_map[kKATO].data(), 4);
146 EXPECT_EQ(0u, keepalive_timeout);
147
148 // kVERS
149 ASSERT_EQ(2u, tag_value_map[kVERS].size());
150 uint16 version;
151 memcpy(&version, tag_value_map[kVERS].data(), 2);
152 EXPECT_EQ(0u, version);
153
154 // kKEXS
155 ASSERT_EQ(8u, tag_value_map[kKEXS].size());
156 CryptoTag key_exchange[2];
157 memcpy(&key_exchange[0], &tag_value_map[kKEXS][0], 4);
158 memcpy(&key_exchange[1], &tag_value_map[kKEXS][4], 4);
159 EXPECT_EQ(kC255, key_exchange[0]);
160 EXPECT_EQ(kP256, key_exchange[1]);
161
162 // kCGST
163 ASSERT_EQ(8u, tag_value_map[kCGST].size());
164 CryptoTag congestion[2];
165 memcpy(&congestion[0], &tag_value_map[kCGST][0], 4);
166 memcpy(&congestion[1], &tag_value_map[kCGST][4], 4);
167 EXPECT_EQ(kQBIC, congestion[0]);
168 EXPECT_EQ(kINAR, congestion[1]);
169 }
170
36 TEST_F(QuicClientSessionTest, CryptoConnectSendsCorrectData) { 171 TEST_F(QuicClientSessionTest, CryptoConnectSendsCorrectData) {
37 EXPECT_EQ(ERR_IO_PENDING, session_.CryptoConnect(callback_.callback())); 172 EXPECT_EQ(ERR_IO_PENDING, session_.CryptoConnect(callback_.callback()));
38 ASSERT_EQ(1u, connection_->packets_.size()); 173 ASSERT_EQ(1u, connection_->packets_.size());
39 scoped_ptr<QuicPacket> chlo(ConstructHandshakePacket(guid_, kCHLO)); 174 CheckClientHelloPacket(connection_->packets_[0]);
40 CompareQuicDataWithHexError("CHLO", connection_->packets_[0], chlo.get());
41 } 175 }
42 176
43 TEST_F(QuicClientSessionTest, CryptoConnectSendsCompletesAfterSHLO) { 177 TEST_F(QuicClientSessionTest, CryptoConnectSendsCompletesAfterSHLO) {
44 ASSERT_EQ(ERR_IO_PENDING, session_.CryptoConnect(callback_.callback())); 178 ASSERT_EQ(ERR_IO_PENDING, session_.CryptoConnect(callback_.callback()));
wtc 2012/12/20 00:33:08 Do you want me to copy ASSERT_EQ(1u, connection_
Ryan Hamilton 2012/12/20 18:51:06 I think it's fine to rely on the earlier test.
45 // Send the SHLO message. 179 // Send the SHLO message.
46 CryptoHandshakeMessage server_message; 180 CryptoHandshakeMessage server_message;
47 server_message.tag = kSHLO; 181 server_message.tag = kSHLO;
48 session_.GetCryptoStream()->OnHandshakeMessage(server_message); 182 session_.GetCryptoStream()->OnHandshakeMessage(server_message);
49 EXPECT_EQ(OK, callback_.WaitForResult()); 183 EXPECT_EQ(OK, callback_.WaitForResult());
50 } 184 }
51 185
52 TEST_F(QuicClientSessionTest, MaxNumConnections) { 186 TEST_F(QuicClientSessionTest, MaxNumConnections) {
53 // Initialize crypto before the client session will create a stream. 187 // Initialize crypto before the client session will create a stream.
54 ASSERT_EQ(ERR_IO_PENDING, session_.CryptoConnect(callback_.callback())); 188 ASSERT_EQ(ERR_IO_PENDING, session_.CryptoConnect(callback_.callback()));
189 ASSERT_EQ(1u, connection_->packets_.size());
190 CheckClientHelloPacket(connection_->packets_[0]);
wtc 2012/12/20 00:33:08 Note that I copied these two lines to this test. N
Ryan Hamilton 2012/12/20 18:51:06 My vote goes for not duplicating the earlier test,
191 // Simulate the server crypto handshake.
55 CryptoHandshakeMessage server_message; 192 CryptoHandshakeMessage server_message;
56 server_message.tag = kSHLO; 193 server_message.tag = kSHLO;
57 session_.GetCryptoStream()->OnHandshakeMessage(server_message); 194 session_.GetCryptoStream()->OnHandshakeMessage(server_message);
58 callback_.WaitForResult(); 195 callback_.WaitForResult();
59 196
60 std::vector<QuicReliableClientStream*> streams; 197 std::vector<QuicReliableClientStream*> streams;
61 for (size_t i = 0; i < kDefaultMaxStreamsPerConnection; i++) { 198 for (size_t i = 0; i < kDefaultMaxStreamsPerConnection; i++) {
62 QuicReliableClientStream* stream = session_.CreateOutgoingReliableStream(); 199 QuicReliableClientStream* stream = session_.CreateOutgoingReliableStream();
63 EXPECT_TRUE(stream); 200 EXPECT_TRUE(stream);
64 streams.push_back(stream); 201 streams.push_back(stream);
65 } 202 }
66 EXPECT_FALSE(session_.CreateOutgoingReliableStream()); 203 EXPECT_FALSE(session_.CreateOutgoingReliableStream());
67 204
68 // Close a stream and ensure I can now open a new one. 205 // Close a stream and ensure I can now open a new one.
69 session_.CloseStream(streams[0]->id()); 206 session_.CloseStream(streams[0]->id());
70 EXPECT_TRUE(session_.CreateOutgoingReliableStream()); 207 EXPECT_TRUE(session_.CreateOutgoingReliableStream());
71 } 208 }
72 209
73 } // namespace 210 } // namespace
74 } // namespace test 211 } // namespace test
75 } // namespace net 212 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698