summaryrefslogtreecommitdiffstats
path: root/net/socket
diff options
context:
space:
mode:
Diffstat (limited to 'net/socket')
-rw-r--r--net/socket/client_socket.h4
-rw-r--r--net/socket/client_socket_pool_base_unittest.cc4
-rw-r--r--net/socket/socket_test_util.cc8
-rw-r--r--net/socket/socket_test_util.h8
-rw-r--r--net/socket/socks5_client_socket.cc20
-rw-r--r--net/socket/socks5_client_socket.h7
-rw-r--r--net/socket/socks5_client_socket_unittest.cc54
-rw-r--r--net/socket/socks_client_socket.cc20
-rw-r--r--net/socket/socks_client_socket.h7
-rw-r--r--net/socket/socks_client_socket_unittest.cc54
-rw-r--r--net/socket/ssl_client_socket_mac.cc214
-rw-r--r--net/socket/ssl_client_socket_mac.h8
-rw-r--r--net/socket/ssl_client_socket_nss.cc39
-rw-r--r--net/socket/ssl_client_socket_nss.h8
-rw-r--r--net/socket/ssl_client_socket_unittest.cc49
-rw-r--r--net/socket/ssl_client_socket_win.cc36
-rw-r--r--net/socket/ssl_client_socket_win.h8
-rw-r--r--net/socket/tcp_client_socket_libevent.cc42
-rw-r--r--net/socket/tcp_client_socket_libevent.h9
-rw-r--r--net/socket/tcp_client_socket_pool.cc4
-rw-r--r--net/socket/tcp_client_socket_pool_unittest.cc6
-rw-r--r--net/socket/tcp_client_socket_unittest.cc21
-rw-r--r--net/socket/tcp_client_socket_win.cc46
-rw-r--r--net/socket/tcp_client_socket_win.h9
-rw-r--r--net/socket/tcp_pinger.h2
25 files changed, 491 insertions, 196 deletions
diff --git a/net/socket/client_socket.h b/net/socket/client_socket.h
index 6594f33..ce0cf2a 100644
--- a/net/socket/client_socket.h
+++ b/net/socket/client_socket.h
@@ -15,6 +15,8 @@
namespace net {
+class LoadLog;
+
class ClientSocket : public Socket {
public:
// Called to establish a connection. Returns OK if the connection could be
@@ -31,7 +33,7 @@ class ClientSocket : public Socket {
//
// Connect may also be called again after a call to the Disconnect method.
//
- virtual int Connect(CompletionCallback* callback) = 0;
+ virtual int Connect(CompletionCallback* callback, LoadLog* load_log) = 0;
// Called to disconnect a socket. Does nothing if the socket is already
// disconnected. After calling Disconnect it is possible to call Connect
diff --git a/net/socket/client_socket_pool_base_unittest.cc b/net/socket/client_socket_pool_base_unittest.cc
index be502af..5f0695a 100644
--- a/net/socket/client_socket_pool_base_unittest.cc
+++ b/net/socket/client_socket_pool_base_unittest.cc
@@ -47,7 +47,7 @@ class MockClientSocket : public ClientSocket {
// ClientSocket methods:
- virtual int Connect(CompletionCallback* callback) {
+ virtual int Connect(CompletionCallback* callback, LoadLog* load_log) {
connected_ = true;
return OK;
}
@@ -197,7 +197,7 @@ class TestConnectJob : public ConnectJob {
int result = ERR_CONNECTION_FAILED;
if (succeed) {
result = OK;
- socket()->Connect(NULL);
+ socket()->Connect(NULL, NULL);
} else {
set_socket(NULL);
}
diff --git a/net/socket/socket_test_util.cc b/net/socket/socket_test_util.cc
index 60ef70c..5433a65 100644
--- a/net/socket/socket_test_util.cc
+++ b/net/socket/socket_test_util.cc
@@ -72,7 +72,8 @@ MockTCPClientSocket::MockTCPClientSocket(const net::AddressList& addresses,
data_->Reset();
}
-int MockTCPClientSocket::Connect(net::CompletionCallback* callback) {
+int MockTCPClientSocket::Connect(net::CompletionCallback* callback,
+ LoadLog* load_log) {
if (connected_)
return net::OK;
connected_ = true;
@@ -176,10 +177,11 @@ void MockSSLClientSocket::GetSSLInfo(net::SSLInfo* ssl_info) {
ssl_info->Reset();
}
-int MockSSLClientSocket::Connect(net::CompletionCallback* callback) {
+int MockSSLClientSocket::Connect(net::CompletionCallback* callback,
+ LoadLog* load_log) {
ConnectCallback* connect_callback = new ConnectCallback(
this, callback, data_->connect.result);
- int rv = transport_->Connect(connect_callback);
+ int rv = transport_->Connect(connect_callback, load_log);
if (rv == net::OK) {
delete connect_callback;
if (data_->connect.async) {
diff --git a/net/socket/socket_test_util.h b/net/socket/socket_test_util.h
index 23cadec..cfbdda8 100644
--- a/net/socket/socket_test_util.h
+++ b/net/socket/socket_test_util.h
@@ -26,6 +26,7 @@
namespace net {
class ClientSocket;
+class LoadLog;
class SSLClientSocket;
struct MockConnect {
@@ -232,7 +233,7 @@ class MockClientSocket : public net::SSLClientSocket {
MockClientSocket();
// ClientSocket methods:
- virtual int Connect(net::CompletionCallback* callback) = 0;
+ virtual int Connect(net::CompletionCallback* callback, LoadLog* load_log) = 0;
// SSLClientSocket methods:
virtual void GetSSLInfo(net::SSLInfo* ssl_info);
@@ -268,7 +269,8 @@ class MockTCPClientSocket : public MockClientSocket {
net::MockSocket* socket);
// ClientSocket methods:
- virtual int Connect(net::CompletionCallback* callback);
+ virtual int Connect(net::CompletionCallback* callback,
+ LoadLog* load_log);
// Socket methods:
virtual int Read(net::IOBuffer* buf, int buf_len,
@@ -298,7 +300,7 @@ class MockSSLClientSocket : public MockClientSocket {
virtual void GetSSLInfo(net::SSLInfo* ssl_info);
- virtual int Connect(net::CompletionCallback* callback);
+ virtual int Connect(net::CompletionCallback* callback, LoadLog* load_log);
virtual void Disconnect();
// Socket methods:
diff --git a/net/socket/socks5_client_socket.cc b/net/socket/socks5_client_socket.cc
index cc12a3c..ef3e9d0 100644
--- a/net/socket/socks5_client_socket.cc
+++ b/net/socket/socks5_client_socket.cc
@@ -14,6 +14,7 @@
#include "base/compiler_specific.h"
#include "base/trace_event.h"
#include "net/base/io_buffer.h"
+#include "net/base/load_log.h"
#include "net/base/net_util.h"
namespace net {
@@ -49,7 +50,8 @@ SOCKS5ClientSocket::~SOCKS5ClientSocket() {
Disconnect();
}
-int SOCKS5ClientSocket::Connect(CompletionCallback* callback) {
+int SOCKS5ClientSocket::Connect(CompletionCallback* callback,
+ LoadLog* load_log) {
DCHECK(transport_.get());
DCHECK(transport_->IsConnected());
DCHECK_EQ(STATE_NONE, next_state_);
@@ -60,10 +62,17 @@ int SOCKS5ClientSocket::Connect(CompletionCallback* callback) {
return OK;
next_state_ = STATE_RESOLVE_HOST;
+ load_log_ = load_log;
+
+ LoadLog::BeginEvent(load_log, LoadLog::TYPE_SOCKS5_CONNECT);
int rv = DoLoop(OK);
- if (rv == ERR_IO_PENDING)
+ if (rv == ERR_IO_PENDING) {
user_callback_ = callback;
+ } else {
+ LoadLog::EndEvent(load_log, LoadLog::TYPE_SOCKS5_CONNECT);
+ load_log_ = NULL;
+ }
return rv;
}
@@ -125,8 +134,11 @@ void SOCKS5ClientSocket::DoCallback(int result) {
void SOCKS5ClientSocket::OnIOComplete(int result) {
DCHECK_NE(STATE_NONE, next_state_);
int rv = DoLoop(result);
- if (rv != ERR_IO_PENDING)
+ if (rv != ERR_IO_PENDING) {
+ LoadLog::EndEvent(load_log_, LoadLog::TYPE_SOCKS5_CONNECT);
+ load_log_ = NULL;
DoCallback(rv);
+ }
}
int SOCKS5ClientSocket::DoLoop(int last_io_result) {
@@ -185,7 +197,7 @@ int SOCKS5ClientSocket::DoResolveHost() {
next_state_ = STATE_RESOLVE_HOST_COMPLETE;
return host_resolver_.Resolve(
- host_request_info_, &addresses_, &io_callback_, NULL);
+ host_request_info_, &addresses_, &io_callback_, load_log_);
}
int SOCKS5ClientSocket::DoResolveHostComplete(int result) {
diff --git a/net/socket/socks5_client_socket.h b/net/socket/socks5_client_socket.h
index 395d3e9..a5db645 100644
--- a/net/socket/socks5_client_socket.h
+++ b/net/socket/socks5_client_socket.h
@@ -20,6 +20,8 @@
namespace net {
+class LoadLog;
+
// This ClientSocket is used to setup a SOCKSv5 handshake with a socks proxy.
// Currently no SOCKSv5 authentication is supported.
class SOCKS5ClientSocket : public ClientSocket {
@@ -39,7 +41,7 @@ class SOCKS5ClientSocket : public ClientSocket {
// ClientSocket methods:
// Does the SOCKS handshake and completes the protocol.
- virtual int Connect(CompletionCallback* callback);
+ virtual int Connect(CompletionCallback* callback, LoadLog* load_log);
virtual void Disconnect();
virtual bool IsConnected() const;
virtual bool IsConnectedAndIdle() const;
@@ -145,10 +147,11 @@ class SOCKS5ClientSocket : public ClientSocket {
AddressList addresses_;
HostResolver::RequestInfo host_request_info_;
+ scoped_refptr<LoadLog> load_log_;
+
DISALLOW_COPY_AND_ASSIGN(SOCKS5ClientSocket);
};
} // namespace net
#endif // NET_SOCKET_SOCKS5_CLIENT_SOCKET_H_
-
diff --git a/net/socket/socks5_client_socket_unittest.cc b/net/socket/socks5_client_socket_unittest.cc
index 9dedc39..1b079e7 100644
--- a/net/socket/socks5_client_socket_unittest.cc
+++ b/net/socket/socks5_client_socket_unittest.cc
@@ -12,6 +12,8 @@
#include <netdb.h>
#endif
#include "net/base/address_list.h"
+#include "net/base/load_log.h"
+#include "net/base/load_log_unittest.h"
#include "net/base/mock_host_resolver.h"
#include "net/base/test_completion_callback.h"
#include "net/base/winsock_init.h"
@@ -73,7 +75,7 @@ SOCKS5ClientSocket* SOCKS5ClientSocketTest::BuildMockSocket(
mock_socket_.reset(new StaticMockSocket(reads, writes));
tcp_sock_ = new MockTCPClientSocket(address_list_, mock_socket_.get());
- int rv = tcp_sock_->Connect(&callback);
+ int rv = tcp_sock_->Connect(&callback, NULL);
EXPECT_EQ(ERR_IO_PENDING, rv);
rv = callback.WaitForResult();
EXPECT_EQ(OK, rv);
@@ -112,15 +114,21 @@ TEST_F(SOCKS5ClientSocketTest, CompleteHandshake) {
EXPECT_TRUE(tcp_sock_->IsConnected());
EXPECT_FALSE(user_sock_->IsConnected());
- int rv = user_sock_->Connect(&callback_);
+ scoped_refptr<LoadLog> log(new LoadLog);
+ int rv = user_sock_->Connect(&callback_, log);
EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_FALSE(user_sock_->IsConnected());
+ EXPECT_TRUE(
+ LogContains(*log, 0, LoadLog::TYPE_SOCKS5_CONNECT, LoadLog::PHASE_BEGIN));
+
rv = callback_.WaitForResult();
EXPECT_EQ(OK, rv);
EXPECT_TRUE(user_sock_->IsConnected());
EXPECT_EQ(SOCKS5ClientSocket::kEndPointResolvedIPv4,
user_sock_->address_type_);
+ EXPECT_TRUE(LogContains(
+ *log, -1, LoadLog::TYPE_SOCKS5_CONNECT, LoadLog::PHASE_END));
scoped_refptr<IOBuffer> buffer = new IOBuffer(payload_write.size());
memcpy(buffer->data(), payload_write.data(), payload_write.size());
@@ -163,13 +171,18 @@ TEST_F(SOCKS5ClientSocketTest, FailedDNS) {
user_sock_.reset(BuildMockSocket(data_reads, data_writes, hostname, 80));
- int rv = user_sock_->Connect(&callback_);
+ scoped_refptr<LoadLog> log(new LoadLog);
+ int rv = user_sock_->Connect(&callback_, log);
EXPECT_EQ(ERR_IO_PENDING, rv);
+ EXPECT_TRUE(LogContains(
+ *log, 0, LoadLog::TYPE_SOCKS5_CONNECT, LoadLog::PHASE_BEGIN));
rv = callback_.WaitForResult();
EXPECT_EQ(OK, rv);
EXPECT_TRUE(user_sock_->IsConnected());
EXPECT_EQ(SOCKS5ClientSocket::kEndPointFailedDomain,
user_sock_->address_type_);
+ EXPECT_TRUE(LogContains(
+ *log, -1, LoadLog::TYPE_SOCKS5_CONNECT, LoadLog::PHASE_END));
}
// Tries to connect to a domain that resolves to IPv6.
@@ -195,13 +208,18 @@ TEST_F(SOCKS5ClientSocketTest, IPv6Domain) {
user_sock_.reset(BuildMockSocket(data_reads, data_writes, hostname, 80));
- int rv = user_sock_->Connect(&callback_);
+ scoped_refptr<LoadLog> log(new LoadLog);
+ int rv = user_sock_->Connect(&callback_, log);
EXPECT_EQ(ERR_IO_PENDING, rv);
+ EXPECT_TRUE(LogContains(
+ *log, 0, LoadLog::TYPE_SOCKS5_CONNECT, LoadLog::PHASE_BEGIN));
rv = callback_.WaitForResult();
EXPECT_EQ(OK, rv);
EXPECT_TRUE(user_sock_->IsConnected());
EXPECT_EQ(SOCKS5ClientSocket::kEndPointResolvedIPv6,
user_sock_->address_type_);
+ EXPECT_TRUE(LogContains(
+ *log, -1, LoadLog::TYPE_SOCKS5_CONNECT, LoadLog::PHASE_END));
}
TEST_F(SOCKS5ClientSocketTest, PartialReadWrites) {
@@ -219,11 +237,16 @@ TEST_F(SOCKS5ClientSocketTest, PartialReadWrites) {
MockRead(true, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
MockRead(true, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)) };
user_sock_.reset(BuildMockSocket(data_reads, data_writes, hostname, 80));
- int rv = user_sock_->Connect(&callback_);
+ scoped_refptr<LoadLog> log(new LoadLog);
+ int rv = user_sock_->Connect(&callback_, log);
EXPECT_EQ(ERR_IO_PENDING, rv);
+ EXPECT_TRUE(LogContains(
+ *log, 0, LoadLog::TYPE_SOCKS5_CONNECT, LoadLog::PHASE_BEGIN));
rv = callback_.WaitForResult();
EXPECT_EQ(OK, rv);
EXPECT_TRUE(user_sock_->IsConnected());
+ EXPECT_TRUE(LogContains(
+ *log, -1, LoadLog::TYPE_SOCKS5_CONNECT, LoadLog::PHASE_END));
}
// Test for partial greet response read
@@ -238,11 +261,16 @@ TEST_F(SOCKS5ClientSocketTest, PartialReadWrites) {
MockRead(true, partial2, arraysize(partial2)),
MockRead(true, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)) };
user_sock_.reset(BuildMockSocket(data_reads, data_writes, hostname, 80));
- int rv = user_sock_->Connect(&callback_);
+ scoped_refptr<LoadLog> log(new LoadLog);
+ int rv = user_sock_->Connect(&callback_, log);
EXPECT_EQ(ERR_IO_PENDING, rv);
+ EXPECT_TRUE(LogContains(
+ *log, 0, LoadLog::TYPE_SOCKS5_CONNECT, LoadLog::PHASE_BEGIN));
rv = callback_.WaitForResult();
EXPECT_EQ(OK, rv);
EXPECT_TRUE(user_sock_->IsConnected());
+ EXPECT_TRUE(LogContains(
+ *log, -1, LoadLog::TYPE_SOCKS5_CONNECT, LoadLog::PHASE_END));
}
// Test for partial handshake request write
@@ -257,11 +285,16 @@ TEST_F(SOCKS5ClientSocketTest, PartialReadWrites) {
MockRead(true, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
MockRead(true, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)) };
user_sock_.reset(BuildMockSocket(data_reads, data_writes, hostname, 80));
- int rv = user_sock_->Connect(&callback_);
+ scoped_refptr<LoadLog> log(new LoadLog);
+ int rv = user_sock_->Connect(&callback_, log);
EXPECT_EQ(ERR_IO_PENDING, rv);
+ EXPECT_TRUE(LogContains(
+ *log, 0, LoadLog::TYPE_SOCKS5_CONNECT, LoadLog::PHASE_BEGIN));
rv = callback_.WaitForResult();
EXPECT_EQ(OK, rv);
EXPECT_TRUE(user_sock_->IsConnected());
+ EXPECT_TRUE(LogContains(
+ *log, -1, LoadLog::TYPE_SOCKS5_CONNECT, LoadLog::PHASE_END));
}
// Test for partial handshake response read
@@ -276,11 +309,16 @@ TEST_F(SOCKS5ClientSocketTest, PartialReadWrites) {
MockRead(true, partial1, arraysize(partial1)),
MockRead(true, partial2, arraysize(partial2)) };
user_sock_.reset(BuildMockSocket(data_reads, data_writes, hostname, 80));
- int rv = user_sock_->Connect(&callback_);
+ scoped_refptr<LoadLog> log(new LoadLog);
+ int rv = user_sock_->Connect(&callback_, log);
EXPECT_EQ(ERR_IO_PENDING, rv);
+ EXPECT_TRUE(LogContains(
+ *log, 0, LoadLog::TYPE_SOCKS5_CONNECT, LoadLog::PHASE_BEGIN));
rv = callback_.WaitForResult();
EXPECT_EQ(OK, rv);
EXPECT_TRUE(user_sock_->IsConnected());
+ EXPECT_TRUE(LogContains(
+ *log, -1, LoadLog::TYPE_SOCKS5_CONNECT, LoadLog::PHASE_END));
}
}
diff --git a/net/socket/socks_client_socket.cc b/net/socket/socks_client_socket.cc
index ace53d9..09c1dbd 100644
--- a/net/socket/socks_client_socket.cc
+++ b/net/socket/socks_client_socket.cc
@@ -14,6 +14,7 @@
#include "base/compiler_specific.h"
#include "base/trace_event.h"
#include "net/base/io_buffer.h"
+#include "net/base/load_log.h"
#include "net/base/net_util.h"
namespace net {
@@ -83,7 +84,8 @@ SOCKSClientSocket::~SOCKSClientSocket() {
Disconnect();
}
-int SOCKSClientSocket::Connect(CompletionCallback* callback) {
+int SOCKSClientSocket::Connect(CompletionCallback* callback,
+ LoadLog* load_log) {
DCHECK(transport_.get());
DCHECK(transport_->IsConnected());
DCHECK_EQ(STATE_NONE, next_state_);
@@ -94,10 +96,17 @@ int SOCKSClientSocket::Connect(CompletionCallback* callback) {
return OK;
next_state_ = STATE_RESOLVE_HOST;
+ load_log_ = load_log;
+
+ LoadLog::BeginEvent(load_log, LoadLog::TYPE_SOCKS_CONNECT);
int rv = DoLoop(OK);
- if (rv == ERR_IO_PENDING)
+ if (rv == ERR_IO_PENDING) {
user_callback_ = callback;
+ } else {
+ LoadLog::EndEvent(load_log, LoadLog::TYPE_SOCKS_CONNECT);
+ load_log_ = NULL;
+ }
return rv;
}
@@ -159,8 +168,11 @@ void SOCKSClientSocket::DoCallback(int result) {
void SOCKSClientSocket::OnIOComplete(int result) {
DCHECK_NE(STATE_NONE, next_state_);
int rv = DoLoop(result);
- if (rv != ERR_IO_PENDING)
+ if (rv != ERR_IO_PENDING) {
+ LoadLog::EndEvent(load_log_, LoadLog::TYPE_SOCKS_CONNECT);
+ load_log_ = NULL;
DoCallback(rv);
+ }
}
int SOCKSClientSocket::DoLoop(int last_io_result) {
@@ -205,7 +217,7 @@ int SOCKSClientSocket::DoResolveHost() {
next_state_ = STATE_RESOLVE_HOST_COMPLETE;
return host_resolver_.Resolve(
- host_request_info_, &addresses_, &io_callback_, NULL);
+ host_request_info_, &addresses_, &io_callback_, load_log_);
}
int SOCKSClientSocket::DoResolveHostComplete(int result) {
diff --git a/net/socket/socks_client_socket.h b/net/socket/socks_client_socket.h
index 9b53c11..c099c4c 100644
--- a/net/socket/socks_client_socket.h
+++ b/net/socket/socks_client_socket.h
@@ -20,6 +20,8 @@
namespace net {
+class LoadLog;
+
// The SOCKS client socket implementation
class SOCKSClientSocket : public ClientSocket {
public:
@@ -38,7 +40,7 @@ class SOCKSClientSocket : public ClientSocket {
// ClientSocket methods:
// Does the SOCKS handshake and completes the protocol.
- virtual int Connect(CompletionCallback* callback);
+ virtual int Connect(CompletionCallback* callback, LoadLog* load_log);
virtual void Disconnect();
virtual bool IsConnected() const;
virtual bool IsConnectedAndIdle() const;
@@ -126,10 +128,11 @@ class SOCKSClientSocket : public ClientSocket {
AddressList addresses_;
HostResolver::RequestInfo host_request_info_;
+ scoped_refptr<LoadLog> load_log_;
+
DISALLOW_COPY_AND_ASSIGN(SOCKSClientSocket);
};
} // namespace net
#endif // NET_SOCKET_SOCKS_CLIENT_SOCKET_H_
-
diff --git a/net/socket/socks_client_socket_unittest.cc b/net/socket/socks_client_socket_unittest.cc
index 7bb7ab7..56d84a8 100644
--- a/net/socket/socks_client_socket_unittest.cc
+++ b/net/socket/socks_client_socket_unittest.cc
@@ -5,6 +5,8 @@
#include "net/socket/socks_client_socket.h"
#include "net/base/address_list.h"
+#include "net/base/load_log.h"
+#include "net/base/load_log_unittest.h"
#include "net/base/mock_host_resolver.h"
#include "net/base/test_completion_callback.h"
#include "net/base/winsock_init.h"
@@ -62,7 +64,7 @@ SOCKSClientSocket* SOCKSClientSocketTest::BuildMockSocket(
mock_socket_.reset(new StaticMockSocket(reads, writes));
tcp_sock_ = new MockTCPClientSocket(address_list_, mock_socket_.get());
- int rv = tcp_sock_->Connect(&callback);
+ int rv = tcp_sock_->Connect(&callback, NULL);
EXPECT_EQ(ERR_IO_PENDING, rv);
rv = callback.WaitForResult();
EXPECT_EQ(OK, rv);
@@ -91,14 +93,19 @@ TEST_F(SOCKSClientSocketTest, CompleteHandshake) {
EXPECT_TRUE(tcp_sock_->IsConnected());
EXPECT_FALSE(user_sock_->IsConnected());
- int rv = user_sock_->Connect(&callback_);
+ scoped_refptr<LoadLog> log(new LoadLog);
+ int rv = user_sock_->Connect(&callback_, log);
EXPECT_EQ(ERR_IO_PENDING, rv);
+ EXPECT_TRUE(
+ LogContains(*log, 0, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_BEGIN));
EXPECT_FALSE(user_sock_->IsConnected());
rv = callback_.WaitForResult();
EXPECT_EQ(OK, rv);
EXPECT_TRUE(user_sock_->IsConnected());
EXPECT_EQ(SOCKSClientSocket::kSOCKS4, user_sock_->socks_version_);
+ EXPECT_TRUE(LogContains(
+ *log, -1, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_END));
scoped_refptr<IOBuffer> buffer = new IOBuffer(payload_write.size());
memcpy(buffer->data(), payload_write.data(), payload_write.size());
@@ -147,13 +154,18 @@ TEST_F(SOCKSClientSocketTest, HandshakeFailures) {
MockRead(false, tests[i].fail_reply, arraysize(tests[i].fail_reply)) };
user_sock_.reset(BuildMockSocket(data_reads, data_writes, "localhost", 80));
+ scoped_refptr<LoadLog> log(new LoadLog);
- int rv = user_sock_->Connect(&callback_);
+ int rv = user_sock_->Connect(&callback_, log);
EXPECT_EQ(ERR_IO_PENDING, rv);
+ EXPECT_TRUE(LogContains(
+ *log, 0, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_BEGIN));
rv = callback_.WaitForResult();
EXPECT_EQ(tests[i].fail_code, rv);
EXPECT_FALSE(user_sock_->IsConnected());
EXPECT_TRUE(tcp_sock_->IsConnected());
+ EXPECT_TRUE(LogContains(
+ *log, -1, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_END));
}
}
@@ -170,12 +182,17 @@ TEST_F(SOCKSClientSocketTest, PartialServerReads) {
MockRead(true, kSOCKSPartialReply2, arraysize(kSOCKSPartialReply2)) };
user_sock_.reset(BuildMockSocket(data_reads, data_writes, "localhost", 80));
+ scoped_refptr<LoadLog> log(new LoadLog);
- int rv = user_sock_->Connect(&callback_);
+ int rv = user_sock_->Connect(&callback_, log);
EXPECT_EQ(ERR_IO_PENDING, rv);
+ EXPECT_TRUE(LogContains(
+ *log, 0, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_BEGIN));
rv = callback_.WaitForResult();
EXPECT_EQ(OK, rv);
EXPECT_TRUE(user_sock_->IsConnected());
+ EXPECT_TRUE(LogContains(
+ *log, -1, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_END));
}
// Tests scenario when the client sends the handshake request in
@@ -195,12 +212,17 @@ TEST_F(SOCKSClientSocketTest, PartialClientWrites) {
MockRead(true, kSOCKSOkReply, arraysize(kSOCKSOkReply)) };
user_sock_.reset(BuildMockSocket(data_reads, data_writes, "localhost", 80));
+ scoped_refptr<LoadLog> log(new LoadLog);
- int rv = user_sock_->Connect(&callback_);
+ int rv = user_sock_->Connect(&callback_, log);
EXPECT_EQ(ERR_IO_PENDING, rv);
+ EXPECT_TRUE(LogContains(
+ *log, 0, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_BEGIN));
rv = callback_.WaitForResult();
EXPECT_EQ(OK, rv);
EXPECT_TRUE(user_sock_->IsConnected());
+ EXPECT_TRUE(LogContains(
+ *log, -1, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_END));
}
// Tests the case when the server sends a smaller sized handshake data
@@ -214,12 +236,17 @@ TEST_F(SOCKSClientSocketTest, FailedSocketRead) {
MockRead(false, 0) };
user_sock_.reset(BuildMockSocket(data_reads, data_writes, "localhost", 80));
+ scoped_refptr<LoadLog> log(new LoadLog);
- int rv = user_sock_->Connect(&callback_);
+ int rv = user_sock_->Connect(&callback_, log);
EXPECT_EQ(ERR_IO_PENDING, rv);
+ EXPECT_TRUE(LogContains(
+ *log, 0, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_BEGIN));
rv = callback_.WaitForResult();
EXPECT_EQ(ERR_CONNECTION_CLOSED, rv);
EXPECT_FALSE(user_sock_->IsConnected());
+ EXPECT_TRUE(LogContains(
+ *log, -1, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_END));
}
// Tries to connect to an unknown DNS and on failure should revert to SOCKS4A.
@@ -238,13 +265,18 @@ TEST_F(SOCKSClientSocketTest, SOCKS4AFailedDNS) {
MockRead(false, kSOCKSOkReply, arraysize(kSOCKSOkReply)) };
user_sock_.reset(BuildMockSocket(data_reads, data_writes, hostname, 80));
+ scoped_refptr<LoadLog> log(new LoadLog);
- int rv = user_sock_->Connect(&callback_);
+ int rv = user_sock_->Connect(&callback_, log);
EXPECT_EQ(ERR_IO_PENDING, rv);
+ EXPECT_TRUE(LogContains(
+ *log, 0, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_BEGIN));
rv = callback_.WaitForResult();
EXPECT_EQ(OK, rv);
EXPECT_TRUE(user_sock_->IsConnected());
EXPECT_EQ(SOCKSClientSocket::kSOCKS4a, user_sock_->socks_version_);
+ EXPECT_TRUE(LogContains(
+ *log, -1, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_END));
}
// Tries to connect to a domain that resolves to IPv6.
@@ -264,14 +296,18 @@ TEST_F(SOCKSClientSocketTest, SOCKS4AIfDomainInIPv6) {
MockRead(false, kSOCKSOkReply, arraysize(kSOCKSOkReply)) };
user_sock_.reset(BuildMockSocket(data_reads, data_writes, hostname, 80));
+ scoped_refptr<LoadLog> log(new LoadLog);
- int rv = user_sock_->Connect(&callback_);
+ int rv = user_sock_->Connect(&callback_, log);
EXPECT_EQ(ERR_IO_PENDING, rv);
+ EXPECT_TRUE(LogContains(
+ *log, 0, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_BEGIN));
rv = callback_.WaitForResult();
EXPECT_EQ(OK, rv);
EXPECT_TRUE(user_sock_->IsConnected());
EXPECT_EQ(SOCKSClientSocket::kSOCKS4a, user_sock_->socks_version_);
+ EXPECT_TRUE(LogContains(
+ *log, -1, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_END));
}
} // namespace net
-
diff --git a/net/socket/ssl_client_socket_mac.cc b/net/socket/ssl_client_socket_mac.cc
index 5e1cf76..1e9a96c 100644
--- a/net/socket/ssl_client_socket_mac.cc
+++ b/net/socket/ssl_client_socket_mac.cc
@@ -9,6 +9,7 @@
#include "base/string_util.h"
#include "net/base/cert_verifier.h"
#include "net/base/io_buffer.h"
+#include "net/base/load_log.h"
#include "net/base/net_errors.h"
#include "net/base/ssl_info.h"
@@ -326,108 +327,28 @@ SSLClientSocketMac::~SSLClientSocketMac() {
Disconnect();
}
-int SSLClientSocketMac::Connect(CompletionCallback* callback) {
+int SSLClientSocketMac::Connect(CompletionCallback* callback,
+ LoadLog* load_log) {
DCHECK(transport_.get());
DCHECK(next_handshake_state_ == STATE_NONE);
DCHECK(!user_connect_callback_);
- OSStatus status = noErr;
-
- status = SSLNewContext(false, &ssl_context_);
- if (status)
- return NetErrorFromOSStatus(status);
-
- status = SSLSetProtocolVersionEnabled(ssl_context_,
- kSSLProtocol2,
- ssl_config_.ssl2_enabled);
- if (status)
- return NetErrorFromOSStatus(status);
-
- status = SSLSetProtocolVersionEnabled(ssl_context_,
- kSSLProtocol3,
- ssl_config_.ssl3_enabled);
- if (status)
- return NetErrorFromOSStatus(status);
-
- status = SSLSetProtocolVersionEnabled(ssl_context_,
- kTLSProtocol1,
- ssl_config_.tls1_enabled);
- if (status)
- return NetErrorFromOSStatus(status);
-
- status = SSLSetIOFuncs(ssl_context_, SSLReadCallback, SSLWriteCallback);
- if (status)
- return NetErrorFromOSStatus(status);
-
- status = SSLSetConnection(ssl_context_, this);
- if (status)
- return NetErrorFromOSStatus(status);
-
- // Disable certificate verification within Secure Transport; we'll
- // be handling that ourselves.
- status = SSLSetEnableCertVerify(ssl_context_, false);
- if (status)
- return NetErrorFromOSStatus(status);
-
- // SSLSetSessionOption() was introduced in Mac OS X 10.5.7. It allows us
- // to perform certificate validation during the handshake, which is
- // required in order to properly enable session resumption.
- //
- // With the kSSLSessionOptionBreakOnServerAuth option set, SSLHandshake()
- // will return errSSLServerAuthCompleted after receiving the server's
- // Certificate during the handshake. That gives us an opportunity to verify
- // the server certificate and then re-enter that handshake (assuming the
- // certificate successfully validated).
- //
- // If SSLSetSessionOption() is not present, we do not enable session
- // resumption, because in that case we are verifying the server's certificate
- // after the handshake completes (but before any application data is
- // exchanged). If we were to enable session resumption in this situation,
- // the session would be cached before we verified the certificate, leaving
- // the potential for a session in which the certificate failed to validate
- // to still be able to be resumed.
- CFBundleRef bundle =
- CFBundleGetBundleWithIdentifier(CFSTR("com.apple.security"));
- if (bundle) {
- SSLSetSessionOptionFuncPtr ssl_set_session_options =
- reinterpret_cast<SSLSetSessionOptionFuncPtr>(
- CFBundleGetFunctionPointerForName(bundle,
- CFSTR("SSLSetSessionOption")));
- if (ssl_set_session_options) {
- status = ssl_set_session_options(ssl_context_,
- kSSLSessionOptionBreakOnServerAuthFlag,
- true);
- if (status)
- return NetErrorFromOSStatus(status);
-
- // Concatenate the hostname and peer address to use as the peer ID. To
- // resume a session, we must connect to the same server on the same port
- // using the same hostname (i.e., localhost and 127.0.0.1 are considered
- // different peers, which puts us through certificate validation again
- // and catches hostname/certificate name mismatches.
- struct sockaddr_storage addr;
- socklen_t addr_length = sizeof(struct sockaddr_storage);
- memset(&addr, 0, sizeof(addr));
- if (!transport_->GetPeerName(reinterpret_cast<struct sockaddr*>(&addr),
- &addr_length)) {
- // Assemble the socket hostname and address into a single buffer.
- std::vector<char> peer_id(hostname_.begin(), hostname_.end());
- peer_id.insert(peer_id.end(), reinterpret_cast<char*>(&addr),
- reinterpret_cast<char*>(&addr) + addr_length);
+ LoadLog::BeginEvent(load_log, LoadLog::TYPE_SSL_CONNECT);
- // SSLSetPeerID() treats peer_id as a binary blob, and makes its
- // own copy.
- status = SSLSetPeerID(ssl_context_, &peer_id[0], peer_id.size());
- if (status)
- return NetErrorFromOSStatus(status);
- }
- }
+ int rv = InitializeSSLContext();
+ if (rv != OK) {
+ LoadLog::EndEvent(load_log, LoadLog::TYPE_SSL_CONNECT);
+ return rv;
}
next_handshake_state_ = STATE_HANDSHAKE_START;
- int rv = DoHandshakeLoop(OK);
- if (rv == ERR_IO_PENDING)
+ rv = DoHandshakeLoop(OK);
+ if (rv == ERR_IO_PENDING) {
+ load_log_ = load_log;
user_connect_callback_ = callback;
+ } else {
+ LoadLog::EndEvent(load_log, LoadLog::TYPE_SSL_CONNECT);
+ }
return rv;
}
@@ -535,6 +456,103 @@ void SSLClientSocketMac::GetSSLCertRequestInfo(
// TODO(wtc): implement this.
}
+int SSLClientSocketMac::InitializeSSLContext() {
+ OSStatus status = noErr;
+
+ status = SSLNewContext(false, &ssl_context_);
+ if (status)
+ return NetErrorFromOSStatus(status);
+
+ status = SSLSetProtocolVersionEnabled(ssl_context_,
+ kSSLProtocol2,
+ ssl_config_.ssl2_enabled);
+ if (status)
+ return NetErrorFromOSStatus(status);
+
+ status = SSLSetProtocolVersionEnabled(ssl_context_,
+ kSSLProtocol3,
+ ssl_config_.ssl3_enabled);
+ if (status)
+ return NetErrorFromOSStatus(status);
+
+ status = SSLSetProtocolVersionEnabled(ssl_context_,
+ kTLSProtocol1,
+ ssl_config_.tls1_enabled);
+ if (status)
+ return NetErrorFromOSStatus(status);
+
+ status = SSLSetIOFuncs(ssl_context_, SSLReadCallback, SSLWriteCallback);
+ if (status)
+ return NetErrorFromOSStatus(status);
+
+ status = SSLSetConnection(ssl_context_, this);
+ if (status)
+ return NetErrorFromOSStatus(status);
+
+ // Disable certificate verification within Secure Transport; we'll
+ // be handling that ourselves.
+ status = SSLSetEnableCertVerify(ssl_context_, false);
+ if (status)
+ return NetErrorFromOSStatus(status);
+
+ // SSLSetSessionOption() was introduced in Mac OS X 10.5.7. It allows us
+ // to perform certificate validation during the handshake, which is
+ // required in order to properly enable session resumption.
+ //
+ // With the kSSLSessionOptionBreakOnServerAuth option set, SSLHandshake()
+ // will return errSSLServerAuthCompleted after receiving the server's
+ // Certificate during the handshake. That gives us an opportunity to verify
+ // the server certificate and then re-enter that handshake (assuming the
+ // certificate successfully validated).
+ //
+ // If SSLSetSessionOption() is not present, we do not enable session
+ // resumption, because in that case we are verifying the server's certificate
+ // after the handshake completes (but before any application data is
+ // exchanged). If we were to enable session resumption in this situation,
+ // the session would be cached before we verified the certificate, leaving
+ // the potential for a session in which the certificate failed to validate
+ // to still be able to be resumed.
+ CFBundleRef bundle =
+ CFBundleGetBundleWithIdentifier(CFSTR("com.apple.security"));
+ if (bundle) {
+ SSLSetSessionOptionFuncPtr ssl_set_session_options =
+ reinterpret_cast<SSLSetSessionOptionFuncPtr>(
+ CFBundleGetFunctionPointerForName(bundle,
+ CFSTR("SSLSetSessionOption")));
+ if (ssl_set_session_options) {
+ status = ssl_set_session_options(ssl_context_,
+ kSSLSessionOptionBreakOnServerAuthFlag,
+ true);
+ if (status)
+ return NetErrorFromOSStatus(status);
+
+ // Concatenate the hostname and peer address to use as the peer ID. To
+ // resume a session, we must connect to the same server on the same port
+ // using the same hostname (i.e., localhost and 127.0.0.1 are considered
+ // different peers, which puts us through certificate validation again
+ // and catches hostname/certificate name mismatches.
+ struct sockaddr_storage addr;
+ socklen_t addr_length = sizeof(struct sockaddr_storage);
+ memset(&addr, 0, sizeof(addr));
+ if (!transport_->GetPeerName(reinterpret_cast<struct sockaddr*>(&addr),
+ &addr_length)) {
+ // Assemble the socket hostname and address into a single buffer.
+ std::vector<char> peer_id(hostname_.begin(), hostname_.end());
+ peer_id.insert(peer_id.end(), reinterpret_cast<char*>(&addr),
+ reinterpret_cast<char*>(&addr) + addr_length);
+
+ // SSLSetPeerID() treats peer_id as a binary blob, and makes its
+ // own copy.
+ status = SSLSetPeerID(ssl_context_, &peer_id[0], peer_id.size());
+ if (status)
+ return NetErrorFromOSStatus(status);
+ }
+ }
+ }
+
+ return OK;
+}
+
void SSLClientSocketMac::DoConnectCallback(int rv) {
DCHECK(rv != ERR_IO_PENDING);
DCHECK(user_connect_callback_);
@@ -574,8 +592,11 @@ void SSLClientSocketMac::DoWriteCallback(int rv) {
void SSLClientSocketMac::OnHandshakeIOComplete(int result) {
DCHECK(next_handshake_state_ != STATE_NONE);
int rv = DoHandshakeLoop(result);
- if (rv != ERR_IO_PENDING)
+ if (rv != ERR_IO_PENDING) {
+ LoadLog::EndEvent(load_log_, LoadLog::TYPE_SSL_CONNECT);
+ load_log_ = NULL;
DoConnectCallback(rv);
+ }
}
void SSLClientSocketMac::OnTransportReadComplete(int result) {
@@ -589,8 +610,11 @@ void SSLClientSocketMac::OnTransportReadComplete(int result) {
if (next_handshake_state_ != STATE_NONE) {
int rv = DoHandshakeLoop(result);
- if (rv != ERR_IO_PENDING)
+ if (rv != ERR_IO_PENDING) {
+ LoadLog::EndEvent(load_log_, LoadLog::TYPE_SSL_CONNECT);
+ load_log_ = NULL;
DoConnectCallback(rv);
+ }
return;
}
if (user_read_buf_) {
diff --git a/net/socket/ssl_client_socket_mac.h b/net/socket/ssl_client_socket_mac.h
index 06bbdb5..c99ef8b 100644
--- a/net/socket/ssl_client_socket_mac.h
+++ b/net/socket/ssl_client_socket_mac.h
@@ -19,6 +19,7 @@
namespace net {
class CertVerifier;
+class LoadLog;
// An SSL client socket implemented with Secure Transport.
class SSLClientSocketMac : public SSLClientSocket {
@@ -37,7 +38,7 @@ class SSLClientSocketMac : public SSLClientSocket {
virtual void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info);
// ClientSocket methods:
- virtual int Connect(CompletionCallback* callback);
+ virtual int Connect(CompletionCallback* callback, LoadLog* load_log);
virtual void Disconnect();
virtual bool IsConnected() const;
virtual bool IsConnectedAndIdle() const;
@@ -49,6 +50,9 @@ class SSLClientSocketMac : public SSLClientSocket {
virtual bool SetSendBufferSize(int32 size);
private:
+ // Initializes the SSLContext. Returns a net error code.
+ int InitializeSSLContext();
+
void DoConnectCallback(int result);
void DoReadCallback(int result);
void DoWriteCallback(int result);
@@ -122,6 +126,8 @@ class SSLClientSocketMac : public SSLClientSocket {
// This buffer holds data for Read() operations on the underlying transport
// (ClientSocket::Read()).
scoped_refptr<IOBuffer> read_io_buf_;
+
+ scoped_refptr<LoadLog> load_log_;
};
} // namespace net
diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc
index 72c1bc3..ca523d5 100644
--- a/net/socket/ssl_client_socket_nss.cc
+++ b/net/socket/ssl_client_socket_nss.cc
@@ -69,6 +69,7 @@
#include "base/string_util.h"
#include "net/base/cert_verifier.h"
#include "net/base/io_buffer.h"
+#include "net/base/load_log.h"
#include "net/base/net_errors.h"
#include "net/base/ssl_cert_request_info.h"
#include "net/base/ssl_info.h"
@@ -236,7 +237,8 @@ int SSLClientSocketNSS::Init() {
return OK;
}
-int SSLClientSocketNSS::Connect(CompletionCallback* callback) {
+int SSLClientSocketNSS::Connect(CompletionCallback* callback,
+ LoadLog* load_log) {
EnterFunction("");
DCHECK(transport_.get());
DCHECK(next_handshake_state_ == STATE_NONE);
@@ -246,10 +248,32 @@ int SSLClientSocketNSS::Connect(CompletionCallback* callback) {
DCHECK(!user_read_buf_);
DCHECK(!user_write_buf_);
+ LoadLog::BeginEvent(load_log, LoadLog::TYPE_SSL_CONNECT);
+
if (Init() != OK) {
NOTREACHED() << "Couldn't initialize nss";
}
+ int rv = InitializeSSLOptions();
+ if (rv != OK) {
+ LoadLog::EndEvent(load_log, LoadLog::TYPE_SSL_CONNECT);
+ return rv;
+ }
+
+ GotoState(STATE_HANDSHAKE);
+ rv = DoHandshakeLoop(OK);
+ if (rv == ERR_IO_PENDING) {
+ user_connect_callback_ = callback;
+ load_log_ = load_log;
+ } else {
+ LoadLog::EndEvent(load_log, LoadLog::TYPE_SSL_CONNECT);
+ }
+
+ LeaveFunction("");
+ return rv > OK ? OK : rv;
+}
+
+int SSLClientSocketNSS::InitializeSSLOptions() {
// Transport connected, now hook it up to nss
// TODO(port): specify rx and tx buffer sizes separately
nss_fd_ = memio_CreateIOLayer(kRecvBufferSize);
@@ -337,13 +361,7 @@ int SSLClientSocketNSS::Connect(CompletionCallback* callback) {
// Tell SSL we're a client; needed if not letting NSPR do socket I/O
SSL_ResetHandshake(nss_fd_, 0);
- GotoState(STATE_HANDSHAKE);
- rv = DoHandshakeLoop(OK);
- if (rv == ERR_IO_PENDING)
- user_connect_callback_ = callback;
-
- LeaveFunction("");
- return rv > OK ? OK : rv;
+ return OK;
}
void SSLClientSocketNSS::InvalidateSessionIfBadCertificate() {
@@ -576,8 +594,11 @@ void SSLClientSocketNSS::DoConnectCallback(int rv) {
void SSLClientSocketNSS::OnHandshakeIOComplete(int result) {
EnterFunction(result);
int rv = DoHandshakeLoop(result);
- if (rv != ERR_IO_PENDING)
+ if (rv != ERR_IO_PENDING) {
+ LoadLog::EndEvent(load_log_, net::LoadLog::TYPE_SSL_CONNECT);
+ load_log_ = NULL;
DoConnectCallback(rv);
+ }
LeaveFunction("");
}
diff --git a/net/socket/ssl_client_socket_nss.h b/net/socket/ssl_client_socket_nss.h
index 5fd04c6..6e871b5 100644
--- a/net/socket/ssl_client_socket_nss.h
+++ b/net/socket/ssl_client_socket_nss.h
@@ -27,6 +27,7 @@
namespace net {
class CertVerifier;
+class LoadLog;
class X509Certificate;
// An SSL client socket implemented with Mozilla NSS.
@@ -46,7 +47,7 @@ class SSLClientSocketNSS : public SSLClientSocket {
virtual void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info);
// ClientSocket methods:
- virtual int Connect(CompletionCallback* callback);
+ virtual int Connect(CompletionCallback* callback, LoadLog* load_log);
virtual void Disconnect();
virtual bool IsConnected() const;
virtual bool IsConnectedAndIdle() const;
@@ -58,6 +59,9 @@ class SSLClientSocketNSS : public SSLClientSocket {
virtual bool SetSendBufferSize(int32 size);
private:
+ // Initializes NSS SSL options. Returns a net error code.
+ int InitializeSSLOptions();
+
void InvalidateSessionIfBadCertificate();
X509Certificate* UpdateServerCert();
void DoReadCallback(int result);
@@ -148,6 +152,8 @@ class SSLClientSocketNSS : public SSLClientSocket {
// Buffers for the network end of the SSL state machine
memio_Private* nss_bufs_;
+ scoped_refptr<LoadLog> load_log_;
+
static bool nss_options_initialized_;
};
diff --git a/net/socket/ssl_client_socket_unittest.cc b/net/socket/ssl_client_socket_unittest.cc
index aa94ff8..611a604 100644
--- a/net/socket/ssl_client_socket_unittest.cc
+++ b/net/socket/ssl_client_socket_unittest.cc
@@ -7,6 +7,8 @@
#include "net/base/address_list.h"
#include "net/base/host_resolver.h"
#include "net/base/io_buffer.h"
+#include "net/base/load_log.h"
+#include "net/base/load_log_unittest.h"
#include "net/base/net_errors.h"
#include "net/base/ssl_config_service.h"
#include "net/base/test_completion_callback.h"
@@ -67,7 +69,7 @@ TEST_F(SSLClientSocketTest, Connect) {
EXPECT_EQ(net::OK, rv);
net::ClientSocket *transport = new net::TCPClientSocket(addr);
- rv = transport->Connect(&callback);
+ rv = transport->Connect(&callback, NULL);
if (rv == net::ERR_IO_PENDING)
rv = callback.WaitForResult();
EXPECT_EQ(net::OK, rv);
@@ -78,16 +80,23 @@ TEST_F(SSLClientSocketTest, Connect) {
EXPECT_FALSE(sock->IsConnected());
- rv = sock->Connect(&callback);
+ scoped_refptr<net::LoadLog> log(new net::LoadLog);
+ rv = sock->Connect(&callback, log);
+ EXPECT_TRUE(net::LogContains(
+ *log, 0, net::LoadLog::TYPE_SSL_CONNECT, net::LoadLog::PHASE_BEGIN));
if (rv != net::OK) {
ASSERT_EQ(net::ERR_IO_PENDING, rv);
EXPECT_FALSE(sock->IsConnected());
+ EXPECT_FALSE(net::LogContains(
+ *log, -1, net::LoadLog::TYPE_SSL_CONNECT, net::LoadLog::PHASE_END));
rv = callback.WaitForResult();
EXPECT_EQ(net::OK, rv);
}
EXPECT_TRUE(sock->IsConnected());
+ EXPECT_TRUE(net::LogContains(
+ *log, -1, net::LoadLog::TYPE_SSL_CONNECT, net::LoadLog::PHASE_END));
sock->Disconnect();
EXPECT_FALSE(sock->IsConnected());
@@ -104,7 +113,7 @@ TEST_F(SSLClientSocketTest, ConnectExpired) {
EXPECT_EQ(net::OK, rv);
net::ClientSocket *transport = new net::TCPClientSocket(addr);
- rv = transport->Connect(&callback);
+ rv = transport->Connect(&callback, NULL);
if (rv == net::ERR_IO_PENDING)
rv = callback.WaitForResult();
EXPECT_EQ(net::OK, rv);
@@ -115,10 +124,15 @@ TEST_F(SSLClientSocketTest, ConnectExpired) {
EXPECT_FALSE(sock->IsConnected());
- rv = sock->Connect(&callback);
+ scoped_refptr<net::LoadLog> log(new net::LoadLog);
+ rv = sock->Connect(&callback, log);
+ EXPECT_TRUE(net::LogContains(
+ *log, 0, net::LoadLog::TYPE_SSL_CONNECT, net::LoadLog::PHASE_BEGIN));
if (rv != net::OK) {
ASSERT_EQ(net::ERR_IO_PENDING, rv);
EXPECT_FALSE(sock->IsConnected());
+ EXPECT_FALSE(net::LogContains(
+ *log, -1, net::LoadLog::TYPE_SSL_CONNECT, net::LoadLog::PHASE_END));
rv = callback.WaitForResult();
EXPECT_EQ(net::ERR_CERT_DATE_INVALID, rv);
@@ -127,6 +141,9 @@ TEST_F(SSLClientSocketTest, ConnectExpired) {
// We cannot test sock->IsConnected(), as the NSS implementation disconnects
// the socket when it encounters an error, whereas other implementations
// leave it connected.
+
+ EXPECT_TRUE(net::LogContains(
+ *log, -1, net::LoadLog::TYPE_SSL_CONNECT, net::LoadLog::PHASE_END));
}
TEST_F(SSLClientSocketTest, ConnectMismatched) {
@@ -141,7 +158,7 @@ TEST_F(SSLClientSocketTest, ConnectMismatched) {
EXPECT_EQ(net::OK, rv);
net::ClientSocket *transport = new net::TCPClientSocket(addr);
- rv = transport->Connect(&callback);
+ rv = transport->Connect(&callback, NULL);
if (rv == net::ERR_IO_PENDING)
rv = callback.WaitForResult();
EXPECT_EQ(net::OK, rv);
@@ -152,10 +169,15 @@ TEST_F(SSLClientSocketTest, ConnectMismatched) {
EXPECT_FALSE(sock->IsConnected());
- rv = sock->Connect(&callback);
+ scoped_refptr<net::LoadLog> log(new net::LoadLog);
+ rv = sock->Connect(&callback, log);
+ EXPECT_TRUE(net::LogContains(
+ *log, 0, net::LoadLog::TYPE_SSL_CONNECT, net::LoadLog::PHASE_BEGIN));
if (rv != net::ERR_CERT_COMMON_NAME_INVALID) {
ASSERT_EQ(net::ERR_IO_PENDING, rv);
EXPECT_FALSE(sock->IsConnected());
+ EXPECT_FALSE(net::LogContains(
+ *log, -1, net::LoadLog::TYPE_SSL_CONNECT, net::LoadLog::PHASE_END));
rv = callback.WaitForResult();
EXPECT_EQ(net::ERR_CERT_COMMON_NAME_INVALID, rv);
@@ -164,6 +186,9 @@ TEST_F(SSLClientSocketTest, ConnectMismatched) {
// We cannot test sock->IsConnected(), as the NSS implementation disconnects
// the socket when it encounters an error, whereas other implementations
// leave it connected.
+
+ EXPECT_TRUE(net::LogContains(
+ *log, -1, net::LoadLog::TYPE_SSL_CONNECT, net::LoadLog::PHASE_END));
}
// TODO(wtc): Add unit tests for IsConnectedAndIdle:
@@ -185,7 +210,7 @@ TEST_F(SSLClientSocketTest, Read) {
EXPECT_EQ(net::OK, rv);
net::ClientSocket *transport = new net::TCPClientSocket(addr);
- rv = transport->Connect(&callback);
+ rv = transport->Connect(&callback, NULL);
if (rv == net::ERR_IO_PENDING)
rv = callback.WaitForResult();
EXPECT_EQ(net::OK, rv);
@@ -195,7 +220,7 @@ TEST_F(SSLClientSocketTest, Read) {
server_.kHostName,
kDefaultSSLConfig));
- rv = sock->Connect(&callback);
+ rv = sock->Connect(&callback, NULL);
if (rv != net::OK) {
ASSERT_EQ(net::ERR_IO_PENDING, rv);
@@ -242,7 +267,7 @@ TEST_F(SSLClientSocketTest, Read_SmallChunks) {
EXPECT_EQ(net::OK, rv);
net::ClientSocket *transport = new net::TCPClientSocket(addr);
- rv = transport->Connect(&callback);
+ rv = transport->Connect(&callback, NULL);
if (rv == net::ERR_IO_PENDING)
rv = callback.WaitForResult();
EXPECT_EQ(net::OK, rv);
@@ -251,7 +276,7 @@ TEST_F(SSLClientSocketTest, Read_SmallChunks) {
socket_factory_->CreateSSLClientSocket(transport,
server_.kHostName, kDefaultSSLConfig));
- rv = sock->Connect(&callback);
+ rv = sock->Connect(&callback, NULL);
if (rv != net::OK) {
ASSERT_EQ(net::ERR_IO_PENDING, rv);
@@ -297,7 +322,7 @@ TEST_F(SSLClientSocketTest, Read_Interrupted) {
EXPECT_EQ(net::OK, rv);
net::ClientSocket *transport = new net::TCPClientSocket(addr);
- rv = transport->Connect(&callback);
+ rv = transport->Connect(&callback, NULL);
if (rv == net::ERR_IO_PENDING)
rv = callback.WaitForResult();
EXPECT_EQ(net::OK, rv);
@@ -306,7 +331,7 @@ TEST_F(SSLClientSocketTest, Read_Interrupted) {
socket_factory_->CreateSSLClientSocket(transport,
server_.kHostName, kDefaultSSLConfig));
- rv = sock->Connect(&callback);
+ rv = sock->Connect(&callback, NULL);
if (rv != net::OK) {
ASSERT_EQ(net::ERR_IO_PENDING, rv);
diff --git a/net/socket/ssl_client_socket_win.cc b/net/socket/ssl_client_socket_win.cc
index 03b8bfe..7212095 100644
--- a/net/socket/ssl_client_socket_win.cc
+++ b/net/socket/ssl_client_socket_win.cc
@@ -14,6 +14,7 @@
#include "net/base/cert_verifier.h"
#include "net/base/connection_type_histograms.h"
#include "net/base/io_buffer.h"
+#include "net/base/load_log.h"
#include "net/base/net_errors.h"
#include "net/base/ssl_cert_request_info.h"
#include "net/base/ssl_info.h"
@@ -426,11 +427,33 @@ void SSLClientSocketWin::GetSSLCertRequestInfo(
DCHECK(ok);
}
-int SSLClientSocketWin::Connect(CompletionCallback* callback) {
+int SSLClientSocketWin::Connect(CompletionCallback* callback,
+ LoadLog* load_log) {
DCHECK(transport_.get());
DCHECK(next_state_ == STATE_NONE);
DCHECK(!user_connect_callback_);
+ LoadLog::BeginEvent(load_log, LoadLog::TYPE_SSL_CONNECT);
+
+ int rv = InitializeSSLContext();
+ if (rv != OK) {
+ LoadLog::EndEvent(load_log, LoadLog::TYPE_SSL_CONNECT);
+ return rv;
+ }
+
+ writing_first_token_ = true;
+ next_state_ = STATE_HANDSHAKE_WRITE;
+ rv = DoLoop(OK);
+ if (rv == ERR_IO_PENDING) {
+ user_connect_callback_ = callback;
+ load_log_ = load_log;
+ } else {
+ LoadLog::EndEvent(load_log, LoadLog::TYPE_SSL_CONNECT);
+ }
+ return rv;
+}
+
+int SSLClientSocketWin::InitializeSSLContext() {
int ssl_version_mask = 0;
if (ssl_config_.ssl2_enabled)
ssl_version_mask |= SSL2;
@@ -487,14 +510,10 @@ int SSLClientSocketWin::Connect(CompletionCallback* callback) {
return MapSecurityError(status);
}
- writing_first_token_ = true;
- next_state_ = STATE_HANDSHAKE_WRITE;
- int rv = DoLoop(OK);
- if (rv == ERR_IO_PENDING)
- user_connect_callback_ = callback;
- return rv;
+ return OK;
}
+
void SSLClientSocketWin::Disconnect() {
// TODO(wtc): Send SSL close_notify alert.
next_state_ = STATE_NONE;
@@ -618,6 +637,9 @@ void SSLClientSocketWin::OnHandshakeIOComplete(int result) {
// The SSL handshake has some round trips. Any error, other than waiting
// for IO, means that we've failed and need to notify the caller.
if (rv != ERR_IO_PENDING) {
+ LoadLog::EndEvent(load_log_, LoadLog::TYPE_SSL_CONNECT);
+ load_log_ = NULL;
+
// If there is no connect callback available to call, it had better be
// because we are renegotiating (which occurs because we are in the middle
// of a Read when the renegotiation process starts). We need to inform the
diff --git a/net/socket/ssl_client_socket_win.h b/net/socket/ssl_client_socket_win.h
index 6b81001..2007844 100644
--- a/net/socket/ssl_client_socket_win.h
+++ b/net/socket/ssl_client_socket_win.h
@@ -22,6 +22,7 @@
namespace net {
class CertVerifier;
+class LoadLog;
// An SSL client socket implemented with the Windows Schannel.
class SSLClientSocketWin : public SSLClientSocket {
@@ -40,7 +41,7 @@ class SSLClientSocketWin : public SSLClientSocket {
virtual void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info);
// ClientSocket methods:
- virtual int Connect(CompletionCallback* callback);
+ virtual int Connect(CompletionCallback* callback, LoadLog* load_log);
virtual void Disconnect();
virtual bool IsConnected() const;
virtual bool IsConnectedAndIdle() const;
@@ -57,6 +58,9 @@ class SSLClientSocketWin : public SSLClientSocket {
return next_state_ == STATE_COMPLETED_HANDSHAKE;
}
+ // Initializes the SSL options and security context. Returns a net error code.
+ int InitializeSSLContext();
+
void OnHandshakeIOComplete(int result);
void OnReadComplete(int result);
void OnWriteComplete(int result);
@@ -176,6 +180,8 @@ class SSLClientSocketWin : public SSLClientSocket {
// True when the decrypter needs more data in order to decrypt.
bool need_more_data_;
+
+ scoped_refptr<LoadLog> load_log_;
};
} // namespace net
diff --git a/net/socket/tcp_client_socket_libevent.cc b/net/socket/tcp_client_socket_libevent.cc
index 165c4cd..abf66bc 100644
--- a/net/socket/tcp_client_socket_libevent.cc
+++ b/net/socket/tcp_client_socket_libevent.cc
@@ -14,6 +14,7 @@
#include "base/string_util.h"
#include "base/trace_event.h"
#include "net/base/io_buffer.h"
+#include "net/base/load_log.h"
#include "net/base/net_errors.h"
#include "third_party/libevent/event.h"
@@ -117,15 +118,37 @@ TCPClientSocketLibevent::~TCPClientSocketLibevent() {
Disconnect();
}
-int TCPClientSocketLibevent::Connect(CompletionCallback* callback) {
+int TCPClientSocketLibevent::Connect(CompletionCallback* callback,
+ LoadLog* load_log) {
// If already connected, then just return OK.
if (socket_ != kInvalidSocket)
return OK;
DCHECK(!waiting_connect_);
+ DCHECK(!load_log_);
TRACE_EVENT_BEGIN("socket.connect", this, "");
+ LoadLog::BeginEvent(load_log, LoadLog::TYPE_TCP_CONNECT);
+
+ int rv = DoConnect();
+
+ if (rv == ERR_IO_PENDING) {
+ // Synchronous operation not supported.
+ DCHECK(callback);
+
+ load_log_ = load_log;
+ waiting_connect_ = true;
+ write_callback_ = callback;
+ } else {
+ TRACE_EVENT_END("socket.connect", this, "");
+ LoadLog::EndEvent(load_log, LoadLog::TYPE_TCP_CONNECT);
+ }
+
+ return rv;
+}
+
+int TCPClientSocketLibevent::DoConnect() {
while (true) {
DCHECK(current_ai_);
@@ -135,7 +158,6 @@ int TCPClientSocketLibevent::Connect(CompletionCallback* callback) {
if (!HANDLE_EINTR(connect(socket_, current_ai_->ai_addr,
static_cast<int>(current_ai_->ai_addrlen)))) {
- TRACE_EVENT_END("socket.connect", this, "");
// Connected without waiting!
return OK;
}
@@ -158,9 +180,6 @@ int TCPClientSocketLibevent::Connect(CompletionCallback* callback) {
}
}
- // Synchronous operation not supported
- DCHECK(callback);
-
// Initialize write_socket_watcher_ and link it to our MessagePump.
// POLLOUT is set if the connection is established.
// POLLIN is set if the connection fails.
@@ -173,8 +192,6 @@ int TCPClientSocketLibevent::Connect(CompletionCallback* callback) {
return MapPosixError(errno);
}
- waiting_connect_ = true;
- write_callback_ = callback;
return ERR_IO_PENDING;
}
@@ -345,8 +362,6 @@ void TCPClientSocketLibevent::DoWriteCallback(int rv) {
void TCPClientSocketLibevent::DidCompleteConnect() {
int result = ERR_UNEXPECTED;
- TRACE_EVENT_END("socket.connect", this, "");
-
// Check to see if connect succeeded
int error_code = 0;
socklen_t len = sizeof(error_code);
@@ -361,12 +376,19 @@ void TCPClientSocketLibevent::DidCompleteConnect() {
const addrinfo* next = current_ai_->ai_next;
Disconnect();
current_ai_ = next;
- result = Connect(write_callback_);
+ scoped_refptr<LoadLog> load_log;
+ load_log.swap(load_log_);
+ TRACE_EVENT_END("socket.connect", this, "");
+ LoadLog::EndEvent(load_log, LoadLog::TYPE_TCP_CONNECT);
+ result = Connect(write_callback_, load_log);
} else {
result = MapConnectError(error_code);
bool ok = write_socket_watcher_.StopWatchingFileDescriptor();
DCHECK(ok);
waiting_connect_ = false;
+ TRACE_EVENT_END("socket.connect", this, "");
+ LoadLog::EndEvent(load_log_, LoadLog::TYPE_TCP_CONNECT);
+ load_log_ = NULL;
}
if (result != ERR_IO_PENDING) {
diff --git a/net/socket/tcp_client_socket_libevent.h b/net/socket/tcp_client_socket_libevent.h
index bfb5767..10b1c31 100644
--- a/net/socket/tcp_client_socket_libevent.h
+++ b/net/socket/tcp_client_socket_libevent.h
@@ -18,6 +18,8 @@ struct event; // From libevent
namespace net {
+class LoadLog;
+
// A client socket that uses TCP as the transport layer.
class TCPClientSocketLibevent : public ClientSocket {
public:
@@ -29,7 +31,7 @@ class TCPClientSocketLibevent : public ClientSocket {
virtual ~TCPClientSocketLibevent();
// ClientSocket methods:
- virtual int Connect(CompletionCallback* callback);
+ virtual int Connect(CompletionCallback* callback, LoadLog* load_log);
virtual void Disconnect();
virtual bool IsConnected() const;
virtual bool IsConnectedAndIdle() const;
@@ -85,6 +87,9 @@ class TCPClientSocketLibevent : public ClientSocket {
DISALLOW_COPY_AND_ASSIGN(WriteWatcher);
};
+ // Performs the actual connect(). Returns a net error code.
+ int DoConnect();
+
void DoReadCallback(int rv);
void DoWriteCallback(int rv);
void DidCompleteRead();
@@ -126,6 +131,8 @@ class TCPClientSocketLibevent : public ClientSocket {
// External callback; called when write is complete.
CompletionCallback* write_callback_;
+ scoped_refptr<LoadLog> load_log_;
+
DISALLOW_COPY_AND_ASSIGN(TCPClientSocketLibevent);
};
diff --git a/net/socket/tcp_client_socket_pool.cc b/net/socket/tcp_client_socket_pool.cc
index ca92073..37d2d8c 100644
--- a/net/socket/tcp_client_socket_pool.cc
+++ b/net/socket/tcp_client_socket_pool.cc
@@ -8,6 +8,7 @@
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/time.h"
+#include "net/base/load_log.h"
#include "net/base/net_errors.h"
#include "net/socket/client_socket_factory.h"
#include "net/socket/client_socket_handle.h"
@@ -123,8 +124,7 @@ int TCPConnectJob::DoTCPConnect() {
next_state_ = kStateTCPConnectComplete;
set_socket(client_socket_factory_->CreateTCPClientSocket(addresses_));
connect_start_time_ = base::TimeTicks::Now();
- // TODO(eroman): Socket::Connect() should take a LoadLog.
- return socket()->Connect(&callback_);
+ return socket()->Connect(&callback_, load_log());
}
int TCPConnectJob::DoTCPConnectComplete(int result) {
diff --git a/net/socket/tcp_client_socket_pool_unittest.cc b/net/socket/tcp_client_socket_pool_unittest.cc
index 5e1b0eeb1..e73b7d3 100644
--- a/net/socket/tcp_client_socket_pool_unittest.cc
+++ b/net/socket/tcp_client_socket_pool_unittest.cc
@@ -28,7 +28,7 @@ class MockClientSocket : public ClientSocket {
MockClientSocket() : connected_(false) {}
// ClientSocket methods:
- virtual int Connect(CompletionCallback* callback) {
+ virtual int Connect(CompletionCallback* callback, LoadLog* /* load_log */) {
connected_ = true;
return OK;
}
@@ -63,7 +63,7 @@ class MockFailingClientSocket : public ClientSocket {
MockFailingClientSocket() {}
// ClientSocket methods:
- virtual int Connect(CompletionCallback* callback) {
+ virtual int Connect(CompletionCallback* callback, LoadLog* /* load_log */) {
return ERR_CONNECTION_FAILED;
}
@@ -98,7 +98,7 @@ class MockPendingClientSocket : public ClientSocket {
is_connected_(false) {}
// ClientSocket methods:
- virtual int Connect(CompletionCallback* callback) {
+ virtual int Connect(CompletionCallback* callback, LoadLog* /* load_log */) {
MessageLoop::current()->PostTask(
FROM_HERE,
method_factory_.NewRunnableMethod(
diff --git a/net/socket/tcp_client_socket_unittest.cc b/net/socket/tcp_client_socket_unittest.cc
index 14d2305..80b0496 100644
--- a/net/socket/tcp_client_socket_unittest.cc
+++ b/net/socket/tcp_client_socket_unittest.cc
@@ -9,6 +9,8 @@
#include "net/base/host_resolver.h"
#include "net/base/io_buffer.h"
#include "net/base/listen_socket.h"
+#include "net/base/load_log.h"
+#include "net/base/load_log_unittest.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "net/base/winsock_init.h"
@@ -97,15 +99,22 @@ TEST_F(TCPClientSocketTest, Connect) {
TestCompletionCallback callback;
EXPECT_FALSE(sock_->IsConnected());
- int rv = sock_->Connect(&callback);
+ scoped_refptr<LoadLog> log(new LoadLog);
+ int rv = sock_->Connect(&callback, log);
+ EXPECT_TRUE(net::LogContains(
+ *log, 0, net::LoadLog::TYPE_TCP_CONNECT, net::LoadLog::PHASE_BEGIN));
if (rv != OK) {
ASSERT_EQ(rv, ERR_IO_PENDING);
+ EXPECT_FALSE(net::LogContains(
+ *log, -1, net::LoadLog::TYPE_TCP_CONNECT, net::LoadLog::PHASE_END));
rv = callback.WaitForResult();
EXPECT_EQ(rv, OK);
}
EXPECT_TRUE(sock_->IsConnected());
+ EXPECT_TRUE(net::LogContains(
+ *log, -1, net::LoadLog::TYPE_TCP_CONNECT, net::LoadLog::PHASE_END));
sock_->Disconnect();
EXPECT_FALSE(sock_->IsConnected());
@@ -117,7 +126,7 @@ TEST_F(TCPClientSocketTest, Connect) {
TEST_F(TCPClientSocketTest, Read) {
TestCompletionCallback callback;
- int rv = sock_->Connect(&callback);
+ int rv = sock_->Connect(&callback, NULL);
if (rv != OK) {
ASSERT_EQ(rv, ERR_IO_PENDING);
@@ -162,7 +171,7 @@ TEST_F(TCPClientSocketTest, Read) {
TEST_F(TCPClientSocketTest, Read_SmallChunks) {
TestCompletionCallback callback;
- int rv = sock_->Connect(&callback);
+ int rv = sock_->Connect(&callback, NULL);
if (rv != OK) {
ASSERT_EQ(rv, ERR_IO_PENDING);
@@ -207,7 +216,7 @@ TEST_F(TCPClientSocketTest, Read_SmallChunks) {
TEST_F(TCPClientSocketTest, Read_Interrupted) {
TestCompletionCallback callback;
- int rv = sock_->Connect(&callback);
+ int rv = sock_->Connect(&callback, NULL);
if (rv != OK) {
ASSERT_EQ(ERR_IO_PENDING, rv);
@@ -241,7 +250,7 @@ TEST_F(TCPClientSocketTest, Read_Interrupted) {
TEST_F(TCPClientSocketTest, DISABLED_FullDuplex_ReadFirst) {
TestCompletionCallback callback;
- int rv = sock_->Connect(&callback);
+ int rv = sock_->Connect(&callback, NULL);
if (rv != OK) {
ASSERT_EQ(rv, ERR_IO_PENDING);
@@ -283,7 +292,7 @@ TEST_F(TCPClientSocketTest, DISABLED_FullDuplex_ReadFirst) {
TEST_F(TCPClientSocketTest, DISABLED_FullDuplex_WriteFirst) {
TestCompletionCallback callback;
- int rv = sock_->Connect(&callback);
+ int rv = sock_->Connect(&callback, NULL);
if (rv != OK) {
ASSERT_EQ(ERR_IO_PENDING, rv);
diff --git a/net/socket/tcp_client_socket_win.cc b/net/socket/tcp_client_socket_win.cc
index 600c8ee..407ea44 100644
--- a/net/socket/tcp_client_socket_win.cc
+++ b/net/socket/tcp_client_socket_win.cc
@@ -13,6 +13,7 @@
#include "base/sys_info.h"
#include "base/trace_event.h"
#include "net/base/io_buffer.h"
+#include "net/base/load_log.h"
#include "net/base/net_errors.h"
#include "net/base/winsock_init.h"
@@ -271,15 +272,39 @@ TCPClientSocketWin::~TCPClientSocketWin() {
Disconnect();
}
-int TCPClientSocketWin::Connect(CompletionCallback* callback) {
+int TCPClientSocketWin::Connect(CompletionCallback* callback,
+ LoadLog* load_log) {
// If already connected, then just return OK.
if (socket_ != INVALID_SOCKET)
return OK;
+ DCHECK(!load_log_);
+
static StatsCounter connects("tcp.connect");
connects.Increment();
TRACE_EVENT_BEGIN("socket.connect", this, "");
+
+ LoadLog::BeginEvent(load_log, LoadLog::TYPE_TCP_CONNECT);
+
+ int rv = DoConnect();
+
+ if (rv == ERR_IO_PENDING) {
+ // Synchronous operation not supported.
+ DCHECK(callback);
+
+ load_log_ = load_log;
+ waiting_connect_ = true;
+ read_callback_ = callback;
+ } else {
+ TRACE_EVENT_END("socket.connect", this, "");
+ LoadLog::EndEvent(load_log, LoadLog::TYPE_TCP_CONNECT);
+ }
+
+ return rv;
+}
+
+int TCPClientSocketWin::DoConnect() {
const struct addrinfo* ai = current_ai_;
DCHECK(ai);
@@ -311,10 +336,8 @@ int TCPClientSocketWin::Connect(CompletionCallback* callback) {
// and we don't know if it's correct.
NOTREACHED();
- if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) {
- TRACE_EVENT_END("socket.connect", this, "");
+ if (ResetEventIfSignaled(core_->read_overlapped_.hEvent))
return OK;
- }
} else {
DWORD err = WSAGetLastError();
if (err != WSAEWOULDBLOCK) {
@@ -324,8 +347,6 @@ int TCPClientSocketWin::Connect(CompletionCallback* callback) {
}
core_->WatchForRead();
- waiting_connect_ = true;
- read_callback_ = callback;
return ERR_IO_PENDING;
}
@@ -587,7 +608,6 @@ void TCPClientSocketWin::DidCompleteConnect() {
DCHECK(waiting_connect_);
int result;
- TRACE_EVENT_END("socket.connect", this, "");
waiting_connect_ = false;
WSANETWORKEVENTS events;
@@ -609,13 +629,23 @@ void TCPClientSocketWin::DidCompleteConnect() {
const struct addrinfo* next = current_ai_->ai_next;
Disconnect();
current_ai_ = next;
- result = Connect(read_callback_);
+ scoped_refptr<LoadLog> load_log;
+ load_log.swap(load_log_);
+ TRACE_EVENT_END("socket.connect", this, "");
+ LoadLog::EndEvent(load_log, LoadLog::TYPE_TCP_CONNECT);
+ result = Connect(read_callback_, load_log);
} else {
result = MapConnectError(error_code);
+ TRACE_EVENT_END("socket.connect", this, "");
+ LoadLog::EndEvent(load_log_, LoadLog::TYPE_TCP_CONNECT);
+ load_log_ = NULL;
}
} else {
NOTREACHED();
result = ERR_UNEXPECTED;
+ TRACE_EVENT_END("socket.connect", this, "");
+ LoadLog::EndEvent(load_log_, LoadLog::TYPE_TCP_CONNECT);
+ load_log_ = NULL;
}
if (result != ERR_IO_PENDING)
diff --git a/net/socket/tcp_client_socket_win.h b/net/socket/tcp_client_socket_win.h
index 6bc63fc..032f1a6 100644
--- a/net/socket/tcp_client_socket_win.h
+++ b/net/socket/tcp_client_socket_win.h
@@ -14,6 +14,8 @@
namespace net {
+class LoadLog;
+
class TCPClientSocketWin : public ClientSocket {
public:
// The IP address(es) and port number to connect to. The TCP socket will try
@@ -24,7 +26,7 @@ class TCPClientSocketWin : public ClientSocket {
~TCPClientSocketWin();
// ClientSocket methods:
- virtual int Connect(CompletionCallback* callback);
+ virtual int Connect(CompletionCallback* callback, LoadLog* load_log);
virtual void Disconnect();
virtual bool IsConnected() const;
virtual bool IsConnectedAndIdle() const;
@@ -41,6 +43,9 @@ class TCPClientSocketWin : public ClientSocket {
private:
class Core;
+ // Performs the actual connect(). Returns a net error code.
+ int DoConnect();
+
int CreateSocket(const struct addrinfo* ai);
void DoReadCallback(int rv);
void DoWriteCallback(int rv);
@@ -72,6 +77,8 @@ class TCPClientSocketWin : public ClientSocket {
// External callback; called when write is complete.
CompletionCallback* write_callback_;
+ scoped_refptr<LoadLog> load_log_;
+
DISALLOW_COPY_AND_ASSIGN(TCPClientSocketWin);
};
diff --git a/net/socket/tcp_pinger.h b/net/socket/tcp_pinger.h
index 0b0bd9b..af9dc84 100644
--- a/net/socket/tcp_pinger.h
+++ b/net/socket/tcp_pinger.h
@@ -86,7 +86,7 @@ class TCPPinger {
void DoConnect() {
sock_.reset(new TCPClientSocket(addr_));
- int rv = sock_->Connect(&connect_callback_);
+ int rv = sock_->Connect(&connect_callback_, NULL);
// Regardless of success or failure, if we're done now,
// signal the customer.
if (rv != ERR_IO_PENDING)