summaryrefslogtreecommitdiffstats
path: root/net/socket/tcp_client_socket_libevent.cc
diff options
context:
space:
mode:
Diffstat (limited to 'net/socket/tcp_client_socket_libevent.cc')
-rw-r--r--net/socket/tcp_client_socket_libevent.cc82
1 files changed, 62 insertions, 20 deletions
diff --git a/net/socket/tcp_client_socket_libevent.cc b/net/socket/tcp_client_socket_libevent.cc
index 92d2560..1aaf3e3 100644
--- a/net/socket/tcp_client_socket_libevent.cc
+++ b/net/socket/tcp_client_socket_libevent.cc
@@ -18,9 +18,11 @@
#include "base/message_loop.h"
#include "base/string_util.h"
#include "base/trace_event.h"
+#include "base/values.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/base/net_log.h"
+#include "net/base/net_util.h"
#if defined(USE_SYSTEM_LIBEVENT)
#include <event.h>
#else
@@ -31,16 +33,31 @@ namespace net {
namespace {
-const int kInvalidSocket = -1;
+// TODO(eroman): Move this to shared location, so it can be used by
+// TCPClientSocketWin.
+class AddressListNetLogParam : public NetLog::EventParameters {
+ public:
+ explicit AddressListNetLogParam(const AddressList& addresses)
+ : addresses_(addresses) {}
-// Return 0 on success, -1 on failure.
-// Too small a function to bother putting in a library?
-int SetNonBlocking(int fd) {
- int flags = fcntl(fd, F_GETFL, 0);
- if (-1 == flags)
- return flags;
- return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
-}
+ virtual Value* ToValue() const {
+ DictionaryValue* dict = new DictionaryValue();
+ ListValue* list = new ListValue();
+
+ for (const addrinfo* head = addresses_.head();
+ head != NULL ; head = head->ai_next) {
+ list->Append(Value::CreateStringValue(NetAddressToString(head)));
+ }
+
+ dict->Set(L"addresses", list);
+ return dict;
+ }
+
+ private:
+ AddressList addresses_;
+};
+
+const int kInvalidSocket = -1;
// DisableNagle turns off buffering in the kernel. By default, TCP sockets will
// wait up to 200ms for more data to complete a packet before transmitting.
@@ -116,6 +133,7 @@ TCPClientSocketLibevent::TCPClientSocketLibevent(const AddressList& addresses,
read_callback_(NULL),
write_callback_(NULL),
next_connect_state_(CONNECT_STATE_NONE),
+ connect_os_error_(0),
net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) {
}
@@ -133,7 +151,8 @@ int TCPClientSocketLibevent::Connect(CompletionCallback* callback) {
DCHECK(!waiting_connect());
- net_log_.BeginEvent(NetLog::TYPE_TCP_CONNECT, NULL);
+ net_log_.BeginEvent(NetLog::TYPE_TCP_CONNECT,
+ new AddressListNetLogParam(addresses_));
// We will try to connect to each address in addresses_. Start with the
// first one in the list.
@@ -146,7 +165,7 @@ int TCPClientSocketLibevent::Connect(CompletionCallback* callback) {
DCHECK(callback);
write_callback_ = callback;
} else {
- net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT, NULL);
+ LogConnectCompletion(rv);
}
return rv;
@@ -180,12 +199,18 @@ int TCPClientSocketLibevent::DoConnectLoop(int result) {
int TCPClientSocketLibevent::DoConnect() {
DCHECK(current_ai_);
+ DCHECK_EQ(0, connect_os_error_);
+
+ net_log_.BeginEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT,
+ new NetLogStringParameter(
+ "address", NetAddressToString(current_ai_)));
+
next_connect_state_ = CONNECT_STATE_CONNECT_COMPLETE;
// Create a non-blocking socket.
- int os_error = CreateSocket(current_ai_);
- if (os_error)
- return MapPosixError(os_error);
+ connect_os_error_ = CreateSocket(current_ai_);
+ if (connect_os_error_)
+ return MapPosixError(connect_os_error_);
// Connect the socket.
if (!HANDLE_EINTR(connect(socket_, current_ai_->ai_addr,
@@ -195,23 +220,32 @@ int TCPClientSocketLibevent::DoConnect() {
}
// Check if the connect() failed synchronously.
- os_error = errno;
- if (os_error != EINPROGRESS)
- return MapPosixError(os_error);
+ connect_os_error_ = errno;
+ if (connect_os_error_ != EINPROGRESS)
+ return MapPosixError(connect_os_error_);
// Otherwise the connect() is going to complete asynchronously, so watch
// for its completion.
if (!MessageLoopForIO::current()->WatchFileDescriptor(
socket_, true, MessageLoopForIO::WATCH_WRITE, &write_socket_watcher_,
&write_watcher_)) {
- DLOG(INFO) << "WatchFileDescriptor failed: " << errno;
- return MapPosixError(errno);
+ connect_os_error_ = errno;
+ DLOG(INFO) << "WatchFileDescriptor failed: " << connect_os_error_;
+ return MapPosixError(connect_os_error_);
}
return ERR_IO_PENDING;
}
int TCPClientSocketLibevent::DoConnectComplete(int result) {
+ int os_error = connect_os_error_;
+ connect_os_error_ = 0;
+
+ scoped_refptr<NetLog::EventParameters> params;
+ if (result != OK)
+ params = new NetLogIntegerParameter("os_error", os_error);
+ net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, params);
+
write_socket_watcher_.StopWatchingFileDescriptor();
if (result == OK)
@@ -395,6 +429,13 @@ int TCPClientSocketLibevent::CreateSocket(const addrinfo* ai) {
return 0;
}
+void TCPClientSocketLibevent::LogConnectCompletion(int net_error) {
+ scoped_refptr<NetLog::EventParameters> params;
+ if (net_error != OK)
+ params = new NetLogIntegerParameter("net_error", net_error);
+ net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT, params);
+}
+
void TCPClientSocketLibevent::DoReadCallback(int rv) {
DCHECK_NE(rv, ERR_IO_PENDING);
DCHECK(read_callback_);
@@ -430,9 +471,10 @@ void TCPClientSocketLibevent::DidCompleteConnect() {
return;
}
+ connect_os_error_ = os_error;
int rv = DoConnectLoop(MapConnectError(os_error));
if (rv != ERR_IO_PENDING) {
- net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT, NULL);
+ LogConnectCompletion(rv);
DoWriteCallback(rv);
}
}