diff options
author | rch@chromium.org <rch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-23 18:57:38 +0000 |
---|---|---|
committer | rch@chromium.org <rch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-23 18:57:38 +0000 |
commit | eed749f90554fcb7f561c935bcee60b8e1235de2 (patch) | |
tree | 7a4d304ebcb722ecad33ae952da8ca6475d42aa8 /net/quic | |
parent | b7e14683a6986670c56106b743fa3bd6433a9362 (diff) | |
download | chromium_src-eed749f90554fcb7f561c935bcee60b8e1235de2.zip chromium_src-eed749f90554fcb7f561c935bcee60b8e1235de2.tar.gz chromium_src-eed749f90554fcb7f561c935bcee60b8e1235de2.tar.bz2 |
Implement connection pooling in QUIC.
Review URL: https://codereview.chromium.org/105873007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@242391 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/quic')
-rw-r--r-- | net/quic/quic_client_session.cc | 29 | ||||
-rw-r--r-- | net/quic/quic_client_session.h | 8 | ||||
-rw-r--r-- | net/quic/quic_crypto_client_stream.h | 2 | ||||
-rw-r--r-- | net/quic/quic_stream_factory.cc | 57 | ||||
-rw-r--r-- | net/quic/quic_stream_factory.h | 6 | ||||
-rw-r--r-- | net/quic/quic_stream_factory_test.cc | 212 | ||||
-rw-r--r-- | net/quic/test_tools/mock_crypto_client_stream.cc | 18 | ||||
-rw-r--r-- | net/quic/test_tools/mock_crypto_client_stream.h | 7 | ||||
-rw-r--r-- | net/quic/test_tools/mock_crypto_client_stream_factory.cc | 7 | ||||
-rw-r--r-- | net/quic/test_tools/mock_crypto_client_stream_factory.h | 5 |
10 files changed, 337 insertions, 14 deletions
diff --git a/net/quic/quic_client_session.cc b/net/quic/quic_client_session.cc index ab70e7f..60c57de 100644 --- a/net/quic/quic_client_session.cc +++ b/net/quic/quic_client_session.cc @@ -277,6 +277,21 @@ int QuicClientSession::GetNumSentClientHellos() const { return crypto_stream_->num_sent_client_hellos(); } +bool QuicClientSession::CanPool(const std::string& hostname) const { + // TODO(rch): When QUIC supports channel ID or client certificates, this + // logic will need to be revised. + DCHECK(connection()->connected()); + SSLInfo ssl_info; + bool unused = false; + DCHECK(crypto_stream_); + if (!crypto_stream_->GetSSLInfo(&ssl_info) || !ssl_info.cert) { + // We can always pool with insecure QUIC sessions. + return true; + } + // Only pool secure QUIC sessions if the cert matches the new hostname. + return ssl_info.cert->VerifyNameMatch(hostname, &unused); +} + QuicDataStream* QuicClientSession::CreateIncomingDataStream( QuicStreamId id) { DLOG(ERROR) << "Server push not supported"; @@ -451,15 +466,25 @@ void QuicClientSession::CloseAllObservers(int net_error) { } } -base::Value* QuicClientSession::GetInfoAsValue(const HostPortPair& pair) const { +base::Value* QuicClientSession::GetInfoAsValue( + const std::set<HostPortProxyPair>& aliases) const { base::DictionaryValue* dict = new base::DictionaryValue(); - dict->SetString("host_port_pair", pair.ToString()); + // TODO(rch): remove "host_port_pair" when Chrome 34 is stable. + dict->SetString("host_port_pair", aliases.begin()->first.ToString()); dict->SetString("version", QuicVersionToString(connection()->version())); dict->SetInteger("open_streams", GetNumOpenStreams()); dict->SetInteger("total_streams", num_total_streams_); dict->SetString("peer_address", peer_address().ToString()); dict->SetString("guid", base::Uint64ToString(guid())); dict->SetBoolean("connected", connection()->connected()); + + base::ListValue* alias_list = new base::ListValue(); + for (std::set<HostPortProxyPair>::const_iterator it = aliases.begin(); + it != aliases.end(); it++) { + alias_list->Append(new base::StringValue(it->first.ToString())); + } + dict->Set("aliases", alias_list); + return dict; } diff --git a/net/quic/quic_client_session.h b/net/quic/quic_client_session.h index 07da96a..943c206 100644 --- a/net/quic/quic_client_session.h +++ b/net/quic/quic_client_session.h @@ -15,6 +15,7 @@ #include "base/containers/hash_tables.h" #include "base/memory/scoped_ptr.h" #include "net/base/completion_callback.h" +#include "net/proxy/proxy_server.h" #include "net/quic/quic_connection_logger.h" #include "net/quic/quic_crypto_client_stream.h" #include "net/quic/quic_reliable_client_stream.h" @@ -143,7 +144,7 @@ class NET_EXPORT_PRIVATE QuicClientSession : public QuicSession { // that this session has been closed, which will delete the session. void CloseSessionOnError(int error); - base::Value* GetInfoAsValue(const HostPortPair& pair) const; + base::Value* GetInfoAsValue(const std::set<HostPortProxyPair>& aliases) const; const BoundNetLog& net_log() const { return net_log_; } @@ -154,6 +155,11 @@ class NET_EXPORT_PRIVATE QuicClientSession : public QuicSession { // than the number of round-trips needed for the handshake. int GetNumSentClientHellos() const; + // Returns true if |hostname| may be pooled onto this session. If this + // is a secure QUIC session, then |hostname| must match the certificate + // presented during the handshake. + bool CanPool(const std::string& hostname) const; + protected: // QuicSession methods: virtual QuicDataStream* CreateIncomingDataStream(QuicStreamId id) OVERRIDE; diff --git a/net/quic/quic_crypto_client_stream.h b/net/quic/quic_crypto_client_stream.h index ca2fea7..1ca423f 100644 --- a/net/quic/quic_crypto_client_stream.h +++ b/net/quic/quic_crypto_client_stream.h @@ -46,7 +46,7 @@ class NET_EXPORT_PRIVATE QuicCryptoClientStream : public QuicCryptoStream { int num_sent_client_hellos() const; // Gets the SSL connection information. - bool GetSSLInfo(SSLInfo* ssl_info); + virtual bool GetSSLInfo(SSLInfo* ssl_info); private: // ProofVerifierCallbackImpl is passed as the callback method to VerifyProof. diff --git a/net/quic/quic_stream_factory.cc b/net/quic/quic_stream_factory.cc index d68e80d..efa9fca 100644 --- a/net/quic/quic_stream_factory.cc +++ b/net/quic/quic_stream_factory.cc @@ -169,6 +169,13 @@ int QuicStreamFactory::Job::DoResolveHostComplete(int rv) { return rv; DCHECK(!factory_->HasActiveSession(host_port_proxy_pair_)); + + // Inform the factory of this resolution, which will set up + // a session alias, if possible. + if (factory_->OnResolution(host_port_proxy_pair_, address_list_)) { + return OK; + } + io_state_ = STATE_CONNECT; return OK; } @@ -189,6 +196,7 @@ int QuicStreamRequest::Request( const CompletionCallback& callback) { DCHECK(!stream_); DCHECK(callback_.is_null()); + DCHECK(factory_); int rv = factory_->Create(host_port_proxy_pair, is_https, cert_verifier, net_log, this); if (rv == ERR_IO_PENDING) { @@ -244,6 +252,15 @@ int QuicStreamFactory::Job::DoConnectComplete(int rv) { return rv; DCHECK(!factory_->HasActiveSession(host_port_proxy_pair_)); + // There may well now be an active session for this IP. If so, use the + // existing session instead. + AddressList address(session_->connection()->peer_address()); + if (factory_->OnResolution(host_port_proxy_pair_, address)) { + session_->connection()->SendConnectionClose(QUIC_NO_ERROR); + session_ = NULL; + return OK; + } + factory_->ActivateSession(host_port_proxy_pair_, session_); return OK; @@ -319,6 +336,29 @@ int QuicStreamFactory::Create(const HostPortProxyPair& host_port_proxy_pair, return rv; } +bool QuicStreamFactory::OnResolution( + const HostPortProxyPair& host_port_proxy_pair, + const AddressList& address_list) { + DCHECK(!HasActiveSession(host_port_proxy_pair)); + for (size_t i = 0; i < address_list.size(); ++i) { + const IPEndPoint& address = address_list[i]; + if (!ContainsKey(ip_aliases_, address)) + continue; + + const SessionSet& sessions = ip_aliases_[address]; + for (SessionSet::const_iterator i = sessions.begin(); + i != sessions.end(); ++i) { + QuicClientSession* session = *i; + if (!session->CanPool(host_port_proxy_pair.first.host())) + continue; + active_sessions_[host_port_proxy_pair] = session; + session_aliases_[session].insert(host_port_proxy_pair); + return true; + } + } + return false; +} + void QuicStreamFactory::OnJobComplete(Job* job, int rv) { if (rv == OK) { require_confirmation_ = false; @@ -381,6 +421,11 @@ void QuicStreamFactory::OnSessionGoingAway(QuicClientSession* session) { http_server_properties_->SetBrokenAlternateProtocol(it->first); } } + IPEndPoint peer_address = session->connection()->peer_address(); + ip_aliases_[peer_address].erase(session); + if (ip_aliases_[peer_address].empty()) { + ip_aliases_.erase(peer_address); + } session_aliases_.erase(session); } @@ -418,9 +463,12 @@ base::Value* QuicStreamFactory::QuicStreamFactoryInfoToValue() const { for (SessionMap::const_iterator it = active_sessions_.begin(); it != active_sessions_.end(); ++it) { const HostPortProxyPair& pair = it->first; - const QuicClientSession* session = it->second; - - list->Append(session->GetInfoAsValue(pair.first)); + QuicClientSession* session = it->second; + const AliasSet& aliases = session_aliases_.find(session)->second; + if (pair.first.Equals(aliases.begin()->first) && + pair.second == aliases.begin()->second) { + list->Append(session->GetInfoAsValue(aliases)); + } } return list; } @@ -528,6 +576,9 @@ void QuicStreamFactory::ActivateSession( DCHECK(!HasActiveSession(host_port_proxy_pair)); active_sessions_[host_port_proxy_pair] = session; session_aliases_[session].insert(host_port_proxy_pair); + DCHECK(!ContainsKey(ip_aliases_[session->connection()->peer_address()], + session)); + ip_aliases_[session->connection()->peer_address()].insert(session); } QuicCryptoClientConfig* QuicStreamFactory::GetOrCreateCryptoConfig( diff --git a/net/quic/quic_stream_factory.h b/net/quic/quic_stream_factory.h index 8a915b6..709cbb0 100644 --- a/net/quic/quic_stream_factory.h +++ b/net/quic/quic_stream_factory.h @@ -158,6 +158,7 @@ class NET_EXPORT_PRIVATE QuicStreamFactory typedef std::set<HostPortProxyPair> AliasSet; typedef std::map<QuicClientSession*, AliasSet> SessionAliasMap; typedef std::set<QuicClientSession*> SessionSet; + typedef std::map<IPEndPoint, SessionSet> IPAliasMap; typedef std::map<HostPortProxyPair, QuicCryptoClientConfig*> CryptoConfigMap; typedef std::map<HostPortPair, HostPortProxyPair> CanonicalHostMap; typedef std::map<HostPortProxyPair, Job*> JobMap; @@ -165,6 +166,8 @@ class NET_EXPORT_PRIVATE QuicStreamFactory typedef std::set<QuicStreamRequest*> RequestSet; typedef std::map<Job*, RequestSet> JobRequestsMap; + bool OnResolution(const HostPortProxyPair& host_port_proxy_pair, + const AddressList& address_list); void OnJobComplete(Job* job, int rv); bool HasActiveSession(const HostPortProxyPair& host_port_proxy_pair); bool HasActiveJob(const HostPortProxyPair& host_port_proxy_pair); @@ -205,7 +208,10 @@ class NET_EXPORT_PRIVATE QuicStreamFactory // Contains non-owning pointers to currently active session // (not going away session, once they're implemented). SessionMap active_sessions_; + // Map from session to set of aliases that this session is known by. SessionAliasMap session_aliases_; + // Map from IP address to sessions which are connected to this address. + IPAliasMap ip_aliases_; // Contains owning pointers to QuicCryptoClientConfig. QuicCryptoClientConfig // contains configuration and cached state about servers. diff --git a/net/quic/quic_stream_factory_test.cc b/net/quic/quic_stream_factory_test.cc index 4cdea8b18f..8f3bdde 100644 --- a/net/quic/quic_stream_factory_test.cc +++ b/net/quic/quic_stream_factory_test.cc @@ -6,6 +6,7 @@ #include "base/run_loop.h" #include "base/strings/string_util.h" +#include "net/base/test_data_directory.h" #include "net/cert/cert_verifier.h" #include "net/dns/mock_host_resolver.h" #include "net/http/http_response_headers.h" @@ -21,6 +22,7 @@ #include "net/quic/test_tools/quic_test_packet_maker.h" #include "net/quic/test_tools/quic_test_utils.h" #include "net/socket/socket_test_util.h" +#include "net/test/cert_test_util.h" #include "testing/gtest/include/gtest/gtest.h" using base::StringPiece; @@ -187,6 +189,216 @@ TEST_P(QuicStreamFactoryTest, Create) { EXPECT_TRUE(socket_data.at_write_eof()); } +TEST_P(QuicStreamFactoryTest, Pooling) { + MockRead reads[] = { + MockRead(ASYNC, OK, 0) // EOF + }; + DeterministicSocketData socket_data(reads, arraysize(reads), NULL, 0); + socket_factory_.AddSocketDataProvider(&socket_data); + socket_data.StopAfter(1); + + HostPortProxyPair server2 = HostPortProxyPair( + HostPortPair("mail.google.com", kDefaultServerPort), + host_port_proxy_pair_.second); + + host_resolver_.set_synchronous_mode(true); + host_resolver_.rules()->AddIPLiteralRule( + kDefaultServerHostName, "192.168.0.1", ""); + host_resolver_.rules()->AddIPLiteralRule( + "mail.google.com", "192.168.0.1", ""); + + QuicStreamRequest request(&factory_); + EXPECT_EQ(OK, request.Request(host_port_proxy_pair_, is_https_, + cert_verifier_.get(), net_log_, + callback_.callback())); + scoped_ptr<QuicHttpStream> stream = request.ReleaseStream(); + EXPECT_TRUE(stream.get()); + + TestCompletionCallback callback; + QuicStreamRequest request2(&factory_); + EXPECT_EQ(OK, request2.Request(server2, is_https_, + cert_verifier_.get(), net_log_, + callback.callback())); + scoped_ptr<QuicHttpStream> stream2 = request2.ReleaseStream(); + EXPECT_TRUE(stream2.get()); + + EXPECT_EQ( + QuicStreamFactoryPeer::GetActiveSession(&factory_, host_port_proxy_pair_), + QuicStreamFactoryPeer::GetActiveSession(&factory_, server2)); + + EXPECT_TRUE(socket_data.at_read_eof()); + EXPECT_TRUE(socket_data.at_write_eof()); +} + +TEST_P(QuicStreamFactoryTest, NoPoolingAfterGoAway) { + MockRead reads[] = { + MockRead(ASYNC, OK, 0) // EOF + }; + DeterministicSocketData socket_data1(reads, arraysize(reads), NULL, 0); + DeterministicSocketData socket_data2(reads, arraysize(reads), NULL, 0); + socket_factory_.AddSocketDataProvider(&socket_data1); + socket_factory_.AddSocketDataProvider(&socket_data2); + socket_data1.StopAfter(1); + socket_data2.StopAfter(1); + + HostPortProxyPair server2 = HostPortProxyPair( + HostPortPair("mail.google.com", kDefaultServerPort), + host_port_proxy_pair_.second); + + host_resolver_.set_synchronous_mode(true); + host_resolver_.rules()->AddIPLiteralRule( + kDefaultServerHostName, "192.168.0.1", ""); + host_resolver_.rules()->AddIPLiteralRule( + "mail.google.com", "192.168.0.1", ""); + + QuicStreamRequest request(&factory_); + EXPECT_EQ(OK, request.Request(host_port_proxy_pair_, is_https_, + cert_verifier_.get(), net_log_, + callback_.callback())); + scoped_ptr<QuicHttpStream> stream = request.ReleaseStream(); + EXPECT_TRUE(stream.get()); + + TestCompletionCallback callback; + QuicStreamRequest request2(&factory_); + EXPECT_EQ(OK, request2.Request(server2, is_https_, + cert_verifier_.get(), net_log_, + callback.callback())); + scoped_ptr<QuicHttpStream> stream2 = request2.ReleaseStream(); + EXPECT_TRUE(stream2.get()); + + factory_.OnSessionGoingAway( + QuicStreamFactoryPeer::GetActiveSession(&factory_, + host_port_proxy_pair_)); + EXPECT_FALSE(QuicStreamFactoryPeer::HasActiveSession(&factory_, + host_port_proxy_pair_)); + EXPECT_FALSE(QuicStreamFactoryPeer::HasActiveSession(&factory_, server2)); + + TestCompletionCallback callback3; + QuicStreamRequest request3(&factory_); + EXPECT_EQ(OK, request3.Request(server2, is_https_, + cert_verifier_.get(), net_log_, + callback3.callback())); + scoped_ptr<QuicHttpStream> stream3 = request3.ReleaseStream(); + EXPECT_TRUE(stream3.get()); + + EXPECT_TRUE(QuicStreamFactoryPeer::HasActiveSession(&factory_, server2)); + + EXPECT_TRUE(socket_data1.at_read_eof()); + EXPECT_TRUE(socket_data1.at_write_eof()); + EXPECT_TRUE(socket_data2.at_read_eof()); + EXPECT_TRUE(socket_data2.at_write_eof()); +} + +TEST_P(QuicStreamFactoryTest, HttpsPooling) { + MockRead reads[] = { + MockRead(ASYNC, OK, 0) // EOF + }; + DeterministicSocketData socket_data(reads, arraysize(reads), NULL, 0); + socket_factory_.AddSocketDataProvider(&socket_data); + socket_data.StopAfter(1); + + HostPortProxyPair server1(HostPortPair("www.example.org", 443), + ProxyServer::Direct()); + HostPortProxyPair server2(HostPortPair("mail.example.org", 443), + ProxyServer::Direct()); + + // Load a cert that is valid for: + // www.example.org (server1) + // mail.example.org (server2) + // www.example.com + base::FilePath certs_dir = GetTestCertsDirectory(); + scoped_refptr<X509Certificate> test_cert( + ImportCertFromFile(certs_dir, "spdy_pooling.pem")); + ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert); + SSLInfo ssl_info; + ssl_info.cert = test_cert.get(); + crypto_client_stream_factory_.set_ssl_info(&ssl_info); + + host_resolver_.set_synchronous_mode(true); + host_resolver_.rules()->AddIPLiteralRule( + server1.first.host(), "192.168.0.1", ""); + host_resolver_.rules()->AddIPLiteralRule( + server2.first.host(), "192.168.0.1", ""); + + QuicStreamRequest request(&factory_); + is_https_ = true; + EXPECT_EQ(OK, request.Request(server1, is_https_, cert_verifier_.get(), + net_log_, callback_.callback())); + scoped_ptr<QuicHttpStream> stream = request.ReleaseStream(); + EXPECT_TRUE(stream.get()); + + TestCompletionCallback callback; + QuicStreamRequest request2(&factory_); + EXPECT_EQ(OK, request2.Request(server2, is_https_, cert_verifier_.get(), + net_log_, callback_.callback())); + scoped_ptr<QuicHttpStream> stream2 = request2.ReleaseStream(); + EXPECT_TRUE(stream2.get()); + + EXPECT_EQ(QuicStreamFactoryPeer::GetActiveSession(&factory_, server1), + QuicStreamFactoryPeer::GetActiveSession(&factory_, server2)); + + EXPECT_TRUE(socket_data.at_read_eof()); + EXPECT_TRUE(socket_data.at_write_eof()); +} + +TEST_P(QuicStreamFactoryTest, NoHttpsPoolingWithCertMismatch) { + MockRead reads[] = { + MockRead(ASYNC, OK, 0) // EOF + }; + DeterministicSocketData socket_data1(reads, arraysize(reads), NULL, 0); + DeterministicSocketData socket_data2(reads, arraysize(reads), NULL, 0); + socket_factory_.AddSocketDataProvider(&socket_data1); + socket_factory_.AddSocketDataProvider(&socket_data2); + socket_data1.StopAfter(1); + socket_data2.StopAfter(1); + + HostPortProxyPair server1(HostPortPair("www.example.org", 443), + ProxyServer::Direct()); + HostPortProxyPair server2(HostPortPair("mail.google.com", 443), + ProxyServer::Direct()); + + // Load a cert that is valid for: + // www.example.org (server1) + // mail.example.org + // www.example.com + // But is not valid for mail.google.com (server2). + base::FilePath certs_dir = GetTestCertsDirectory(); + scoped_refptr<X509Certificate> test_cert( + ImportCertFromFile(certs_dir, "spdy_pooling.pem")); + ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert); + SSLInfo ssl_info; + ssl_info.cert = test_cert.get(); + crypto_client_stream_factory_.set_ssl_info(&ssl_info); + + host_resolver_.set_synchronous_mode(true); + host_resolver_.rules()->AddIPLiteralRule( + server1.first.host(), "192.168.0.1", ""); + host_resolver_.rules()->AddIPLiteralRule( + server2.first.host(), "192.168.0.1", ""); + + QuicStreamRequest request(&factory_); + is_https_ = true; + EXPECT_EQ(OK, request.Request(server1, is_https_, cert_verifier_.get(), + net_log_, callback_.callback())); + scoped_ptr<QuicHttpStream> stream = request.ReleaseStream(); + EXPECT_TRUE(stream.get()); + + TestCompletionCallback callback; + QuicStreamRequest request2(&factory_); + EXPECT_EQ(OK, request2.Request(server2, is_https_, cert_verifier_.get(), + net_log_, callback_.callback())); + scoped_ptr<QuicHttpStream> stream2 = request2.ReleaseStream(); + EXPECT_TRUE(stream2.get()); + + EXPECT_NE(QuicStreamFactoryPeer::GetActiveSession(&factory_, server1), + QuicStreamFactoryPeer::GetActiveSession(&factory_, server2)); + + EXPECT_TRUE(socket_data1.at_read_eof()); + EXPECT_TRUE(socket_data1.at_write_eof()); + EXPECT_TRUE(socket_data2.at_read_eof()); + EXPECT_TRUE(socket_data2.at_write_eof()); +} + TEST_P(QuicStreamFactoryTest, Goaway) { MockRead reads[] = { MockRead(ASYNC, OK, 0) // EOF diff --git a/net/quic/test_tools/mock_crypto_client_stream.cc b/net/quic/test_tools/mock_crypto_client_stream.cc index bfeb06f..7dd3ffe 100644 --- a/net/quic/test_tools/mock_crypto_client_stream.cc +++ b/net/quic/test_tools/mock_crypto_client_stream.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "net/quic/test_tools/mock_crypto_client_stream.h" +#include "net/ssl/ssl_info.h" #include "testing/gtest/include/gtest/gtest.h" namespace net { @@ -11,9 +12,11 @@ MockCryptoClientStream::MockCryptoClientStream( const string& server_hostname, QuicSession* session, QuicCryptoClientConfig* crypto_config, - HandshakeMode handshake_mode) - : QuicCryptoClientStream(server_hostname, session, crypto_config), - handshake_mode_(handshake_mode) { + HandshakeMode handshake_mode, + const SSLInfo* ssl_info) + : QuicCryptoClientStream(server_hostname, session, crypto_config), + handshake_mode_(handshake_mode), + ssl_info_(ssl_info) { } MockCryptoClientStream::~MockCryptoClientStream() { @@ -51,6 +54,15 @@ bool MockCryptoClientStream::CryptoConnect() { return true; } +bool MockCryptoClientStream::GetSSLInfo(SSLInfo* ssl_info) { + ssl_info->Reset(); + if (!ssl_info_) { + return false; + } + *ssl_info = *ssl_info_; + return true; +} + void MockCryptoClientStream::SendOnCryptoHandshakeEvent( QuicSession::CryptoHandshakeEvent event) { encryption_established_ = true; diff --git a/net/quic/test_tools/mock_crypto_client_stream.h b/net/quic/test_tools/mock_crypto_client_stream.h index ada1b68..ab393e8 100644 --- a/net/quic/test_tools/mock_crypto_client_stream.h +++ b/net/quic/test_tools/mock_crypto_client_stream.h @@ -37,7 +37,8 @@ class MockCryptoClientStream : public QuicCryptoClientStream { const string& server_hostname, QuicSession* session, QuicCryptoClientConfig* crypto_config, - HandshakeMode handshake_mode); + HandshakeMode handshake_mode, + const SSLInfo* ssl_info); virtual ~MockCryptoClientStream(); // CryptoFramerVisitorInterface implementation. @@ -47,6 +48,8 @@ class MockCryptoClientStream : public QuicCryptoClientStream { // QuicCryptoClientStream implementation. virtual bool CryptoConnect() OVERRIDE; + virtual bool GetSSLInfo(SSLInfo* ssl_info) OVERRIDE; + // Invokes the sessions's CryptoHandshakeEvent method with the specified // event. void SendOnCryptoHandshakeEvent(QuicSession::CryptoHandshakeEvent event); @@ -55,6 +58,8 @@ class MockCryptoClientStream : public QuicCryptoClientStream { private: void SetConfigNegotiated(); + + const SSLInfo* ssl_info_; }; } // namespace net diff --git a/net/quic/test_tools/mock_crypto_client_stream_factory.cc b/net/quic/test_tools/mock_crypto_client_stream_factory.cc index e54fb41..671a872 100644 --- a/net/quic/test_tools/mock_crypto_client_stream_factory.cc +++ b/net/quic/test_tools/mock_crypto_client_stream_factory.cc @@ -13,7 +13,8 @@ namespace net { MockCryptoClientStreamFactory::MockCryptoClientStreamFactory() : handshake_mode_(MockCryptoClientStream::CONFIRM_HANDSHAKE), - last_stream_(NULL) { + last_stream_(NULL), + ssl_info_(NULL) { } QuicCryptoClientStream* @@ -21,8 +22,8 @@ MockCryptoClientStreamFactory::CreateQuicCryptoClientStream( const string& server_hostname, QuicSession* session, QuicCryptoClientConfig* crypto_config) { - last_stream_ = new MockCryptoClientStream(server_hostname, session, - crypto_config, handshake_mode_); + last_stream_ = new MockCryptoClientStream( + server_hostname, session, crypto_config, handshake_mode_, ssl_info_); return last_stream_; } diff --git a/net/quic/test_tools/mock_crypto_client_stream_factory.h b/net/quic/test_tools/mock_crypto_client_stream_factory.h index 9d056cb..94feb0b 100644 --- a/net/quic/test_tools/mock_crypto_client_stream_factory.h +++ b/net/quic/test_tools/mock_crypto_client_stream_factory.h @@ -29,6 +29,10 @@ class MockCryptoClientStreamFactory : public QuicCryptoClientStreamFactory { handshake_mode_ = handshake_mode; } + void set_ssl_info(const SSLInfo* ssl_info) { + ssl_info_ = ssl_info; + } + MockCryptoClientStream* last_stream() const { return last_stream_; } @@ -36,6 +40,7 @@ class MockCryptoClientStreamFactory : public QuicCryptoClientStreamFactory { private: MockCryptoClientStream::HandshakeMode handshake_mode_; MockCryptoClientStream* last_stream_; + const SSLInfo* ssl_info_; }; } // namespace net |