summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorsergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-11 22:15:09 +0000
committersergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-11 22:15:09 +0000
commit33cdc9b854044864f7494c23a21f78733a961236 (patch)
tree5cff7b26780bc68451fb3917baea18bdb9f1c95a /net
parenta7fb410b943d13c9f4aed11fe8d2774f990b3220 (diff)
downloadchromium_src-33cdc9b854044864f7494c23a21f78733a961236.zip
chromium_src-33cdc9b854044864f7494c23a21f78733a961236.tar.gz
chromium_src-33cdc9b854044864f7494c23a21f78733a961236.tar.bz2
Revert 77870 - UDP sockets implementation for windows.
BUG=None TEST=Unittests Review URL: http://codereview.chromium.org/6658027 TBR=sergeyu@chromium.org Review URL: http://codereview.chromium.org/6681014 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@77872 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r--net/base/winsock_util.cc96
-rw-r--r--net/base/winsock_util.h31
-rw-r--r--net/net.gyp40
-rw-r--r--net/socket/tcp_client_socket_win.cc87
-rw-r--r--net/udp/datagram_server_socket.h2
-rw-r--r--net/udp/udp_socket.h19
-rw-r--r--net/udp/udp_socket_libevent.cc42
-rw-r--r--net/udp/udp_socket_libevent.h24
-rw-r--r--net/udp/udp_socket_unittest.cc62
-rw-r--r--net/udp/udp_socket_win.cc366
-rw-r--r--net/udp/udp_socket_win.h178
11 files changed, 160 insertions, 787 deletions
diff --git a/net/base/winsock_util.cc b/net/base/winsock_util.cc
deleted file mode 100644
index dac38be..0000000
--- a/net/base/winsock_util.cc
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/base/winsock_util.h"
-
-#include "base/logging.h"
-#include "net/base/net_errors.h"
-
-namespace net {
-
-namespace {
-
-// Prevent the compiler from optimizing away the arguments so they appear
-// nicely on the stack in crash dumps.
-#pragma warning (disable: 4748)
-#pragma optimize( "", off )
-
-// Pass the important values as function arguments so that they are available
-// in crash dumps.
-void CheckEventWait(WSAEVENT hEvent, DWORD wait_rv, DWORD expected) {
- if (wait_rv != expected) {
- DWORD err = ERROR_SUCCESS;
- if (wait_rv == WAIT_FAILED)
- err = GetLastError();
- CHECK(false); // Crash.
- }
-}
-
-#pragma optimize( "", on )
-#pragma warning (default: 4748)
-
-} // namespace
-
-void AssertEventNotSignaled(WSAEVENT hEvent) {
- DWORD wait_rv = WaitForSingleObject(hEvent, 0);
- CheckEventWait(hEvent, wait_rv, WAIT_TIMEOUT);
-}
-
-bool ResetEventIfSignaled(WSAEVENT hEvent) {
- // TODO(wtc): Remove the CHECKs after enough testing.
- DWORD wait_rv = WaitForSingleObject(hEvent, 0);
- if (wait_rv == WAIT_TIMEOUT)
- return false; // The event object is not signaled.
- CheckEventWait(hEvent, wait_rv, WAIT_OBJECT_0);
- BOOL ok = WSAResetEvent(hEvent);
- CHECK(ok);
- return true;
-}
-
-// Map winsock error to Chromium error.
-int MapWinsockError(int os_error) {
- // There are numerous Winsock error codes, but these are the ones we thus far
- // find interesting.
- switch (os_error) {
- case WSAEACCES:
- return ERR_ACCESS_DENIED;
- case WSAENETDOWN:
- return ERR_INTERNET_DISCONNECTED;
- case WSAETIMEDOUT:
- return ERR_TIMED_OUT;
- case WSAECONNRESET:
- case WSAENETRESET: // Related to keep-alive
- return ERR_CONNECTION_RESET;
- case WSAECONNABORTED:
- return ERR_CONNECTION_ABORTED;
- case WSAECONNREFUSED:
- return ERR_CONNECTION_REFUSED;
- case WSA_IO_INCOMPLETE:
- case WSAEDISCON:
- // WSAEDISCON is returned by WSARecv or WSARecvFrom for message-oriented
- // sockets (where a return value of zero means a zero-byte message) to
- // indicate graceful connection shutdown. We should not ever see this
- // error code for TCP sockets, which are byte stream oriented.
- LOG(DFATAL) << "Unexpected error " << os_error
- << " mapped to net::ERR_UNEXPECTED";
- return ERR_UNEXPECTED;
- case WSAEHOSTUNREACH:
- case WSAENETUNREACH:
- return ERR_ADDRESS_UNREACHABLE;
- case WSAEADDRNOTAVAIL:
- return ERR_ADDRESS_INVALID;
- case WSAENOTCONN:
- return ERR_SOCKET_NOT_CONNECTED;
- case WSAEAFNOSUUPORT:
- return ERR_ADDRESS_UNREACHABLE;
- case ERROR_SUCCESS:
- return OK;
- default:
- LOG(WARNING) << "Unknown error " << os_error
- << " mapped to net::ERR_FAILED";
- return ERR_FAILED;
- }
-}
-
-} // namespace net
diff --git a/net/base/winsock_util.h b/net/base/winsock_util.h
deleted file mode 100644
index c26e63f..0000000
--- a/net/base/winsock_util.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef NET_BASE_WINSOCK_UTIL_H_
-#define NET_BASE_WINSOCK_UTIL_H_
-#pragma once
-
-#include <winsock2.h>
-
-namespace net {
-
-// Assert that the (manual-reset) event object is not signaled.
-void AssertEventNotSignaled(WSAEVENT hEvent);
-
-// If the (manual-reset) event object is signaled, resets it and returns true.
-// Otherwise, does nothing and returns false. Called after a Winsock function
-// succeeds synchronously
-//
-// Our testing shows that except in rare cases (when running inside QEMU),
-// the event object is already signaled at this point, so we call this method
-// to avoid a context switch in common cases. This is just a performance
-// optimization. The code still works if this function simply returns false.
-bool ResetEventIfSignaled(WSAEVENT hEvent);
-
-// Map winsock error to Chromium error.
-int MapWinsockError(int os_error);
-
-} // namespace net
-
-#endif // NET_BASE_WINSOCK_UTIL_H_
diff --git a/net/net.gyp b/net/net.gyp
index 7fa024a..12b2a95 100644
--- a/net/net.gyp
+++ b/net/net.gyp
@@ -199,8 +199,6 @@
'base/upload_data_stream.h',
'base/winsock_init.cc',
'base/winsock_init.h',
- 'base/winsock_util.cc',
- 'base/winsock_util.h',
'base/x509_certificate.cc',
'base/x509_certificate.h',
'base/x509_certificate_mac.cc',
@@ -327,7 +325,6 @@
],
'sources!': [
'base/winsock_init.cc',
- 'base/winsock_util.cc',
],
},
],
@@ -677,18 +674,6 @@
'spdy/spdy_settings_storage.h',
'spdy/spdy_stream.cc',
'spdy/spdy_stream.h',
- 'udp/datagram_client_socket.h',
- 'udp/datagram_server_socket.h',
- 'udp/datagram_socket.h',
- 'udp/udp_client_socket.cc',
- 'udp/udp_client_socket.h',
- 'udp/udp_server_socket.cc',
- 'udp/udp_server_socket.h',
- 'udp/udp_socket.h',
- 'udp/udp_socket_libevent.cc',
- 'udp/udp_socket_libevent.h',
- 'udp/udp_socket_win.cc',
- 'udp/udp_socket_win.h',
'url_request/https_prober.h',
'url_request/https_prober.cc',
'url_request/url_request.cc',
@@ -823,7 +808,6 @@
'sources!': [
'http/http_auth_handler_ntlm_portable.cc',
'socket/tcp_client_socket_libevent.cc',
- 'udp/udp_socket_libevent.cc',
],
'dependencies': [
'../third_party/nss/nss.gyp:nss',
@@ -1009,7 +993,6 @@
'tools/dump_cache/url_utilities.h',
'tools/dump_cache/url_utilities.cc',
'tools/dump_cache/url_utilities_unittest.cc',
- 'udp/udp_socket_unittest.cc',
'url_request/url_request_job_tracker_unittest.cc',
'url_request/url_request_throttler_unittest.cc',
'url_request/url_request_unittest.cc',
@@ -1448,6 +1431,29 @@
},
],
}],
+ ['OS=="linux"', {
+ 'targets': [
+ {
+ 'target_name': 'udp_socket_unittest',
+ 'type': 'executable',
+ 'dependencies': [
+ 'net',
+ 'net_test_support',
+ '../base/base.gyp:base',
+ '../base/base.gyp:base_i18n',
+ '../testing/gmock.gyp:gmock',
+ '../testing/gtest.gyp:gtest',
+ '../third_party/zlib/zlib.gyp:zlib',
+ ],
+ 'sources': [
+ 'udp/udp_client_socket.cc',
+ 'udp/udp_server_socket.cc',
+ 'udp/udp_socket_libevent.cc',
+ 'udp/udp_socket_unittest.cc',
+ ]
+ },
+ ],
+ }],
['OS=="win"', {
'targets': [
{
diff --git a/net/socket/tcp_client_socket_win.cc b/net/socket/tcp_client_socket_win.cc
index 6d733fa..9e93bf0 100644
--- a/net/socket/tcp_client_socket_win.cc
+++ b/net/socket/tcp_client_socket_win.cc
@@ -22,12 +22,97 @@
#include "net/base/network_change_notifier.h"
#include "net/base/sys_addrinfo.h"
#include "net/base/winsock_init.h"
-#include "net/base/winsock_util.h"
namespace net {
namespace {
+// Prevent the compiler from optimizing away the arguments so they appear
+// nicely on the stack in crash dumps.
+#pragma warning (disable: 4748)
+#pragma optimize( "", off )
+
+// Pass the important values as function arguments so that they are available
+// in crash dumps.
+void CheckEventWait(WSAEVENT hEvent, DWORD wait_rv, DWORD expected) {
+ if (wait_rv != expected) {
+ DWORD err = ERROR_SUCCESS;
+ if (wait_rv == WAIT_FAILED)
+ err = GetLastError();
+ CHECK(false); // Crash.
+ }
+}
+
+#pragma optimize( "", on )
+#pragma warning (default: 4748)
+
+// Assert that the (manual-reset) event object is not signaled.
+void AssertEventNotSignaled(WSAEVENT hEvent) {
+ DWORD wait_rv = WaitForSingleObject(hEvent, 0);
+ CheckEventWait(hEvent, wait_rv, WAIT_TIMEOUT);
+}
+
+// If the (manual-reset) event object is signaled, resets it and returns true.
+// Otherwise, does nothing and returns false. Called after a Winsock function
+// succeeds synchronously
+//
+// Our testing shows that except in rare cases (when running inside QEMU),
+// the event object is already signaled at this point, so we call this method
+// to avoid a context switch in common cases. This is just a performance
+// optimization. The code still works if this function simply returns false.
+bool ResetEventIfSignaled(WSAEVENT hEvent) {
+ // TODO(wtc): Remove the CHECKs after enough testing.
+ DWORD wait_rv = WaitForSingleObject(hEvent, 0);
+ if (wait_rv == WAIT_TIMEOUT)
+ return false; // The event object is not signaled.
+ CheckEventWait(hEvent, wait_rv, WAIT_OBJECT_0);
+ BOOL ok = WSAResetEvent(hEvent);
+ CHECK(ok);
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+
+int MapWinsockError(int os_error) {
+ // There are numerous Winsock error codes, but these are the ones we thus far
+ // find interesting.
+ switch (os_error) {
+ case WSAEACCES:
+ return ERR_ACCESS_DENIED;
+ case WSAENETDOWN:
+ return ERR_INTERNET_DISCONNECTED;
+ case WSAETIMEDOUT:
+ return ERR_TIMED_OUT;
+ case WSAECONNRESET:
+ case WSAENETRESET: // Related to keep-alive
+ return ERR_CONNECTION_RESET;
+ case WSAECONNABORTED:
+ return ERR_CONNECTION_ABORTED;
+ case WSAECONNREFUSED:
+ return ERR_CONNECTION_REFUSED;
+ case WSA_IO_INCOMPLETE:
+ case WSAEDISCON:
+ // WSAEDISCON is returned by WSARecv or WSARecvFrom for message-oriented
+ // sockets (where a return value of zero means a zero-byte message) to
+ // indicate graceful connection shutdown. We should not ever see this
+ // error code for TCP sockets, which are byte stream oriented.
+ LOG(DFATAL) << "Unexpected error " << os_error
+ << " mapped to net::ERR_UNEXPECTED";
+ return ERR_UNEXPECTED;
+ case WSAEHOSTUNREACH:
+ case WSAENETUNREACH:
+ return ERR_ADDRESS_UNREACHABLE;
+ case WSAEADDRNOTAVAIL:
+ return ERR_ADDRESS_INVALID;
+ case ERROR_SUCCESS:
+ return OK;
+ default:
+ LOG(WARNING) << "Unknown error " << os_error
+ << " mapped to net::ERR_FAILED";
+ return ERR_FAILED;
+ }
+}
+
int MapConnectError(int os_error) {
switch (os_error) {
// connect fails with WSAEACCES when Windows Firewall blocks the
diff --git a/net/udp/datagram_server_socket.h b/net/udp/datagram_server_socket.h
index 9841d53..30286e5 100644
--- a/net/udp/datagram_server_socket.h
+++ b/net/udp/datagram_server_socket.h
@@ -6,6 +6,8 @@
#define NET_UDP_DATAGRAM_SERVER_SOCKET_H_
#pragma once
+#include <sys/socket.h>
+
#include "net/base/completion_callback.h"
#include "net/udp/datagram_socket.h"
diff --git a/net/udp/udp_socket.h b/net/udp/udp_socket.h
index 15ba76c..9e5f826 100644
--- a/net/udp/udp_socket.h
+++ b/net/udp/udp_socket.h
@@ -16,24 +16,7 @@
namespace net {
-// UDPSocket
-// Accessor API for a UDP socket in either client or server form.
-//
-// Client form:
-// In this case, we're connecting to a specific server, so the client will
-// usually use:
-// Connect(address) // Connect to a UDP server
-// Read/Write // Reads/Writes all go to a single destination
-//
-// Server form:
-// In this case, we want to read/write to many clients which are connecting
-// to this server. First the server 'binds' to an addres, then we read from
-// clients and write responses to them.
-// Example:
-// Bind(address/port) // Binds to port for reading from clients
-// RecvFrom/SendTo // Each read can come from a different client
-// // Writes need to be directed to a specific
-// // address.
+// A client socket that uses UDP as the transport layer.
#if defined(OS_WIN)
typedef UDPSocketWin UDPSocket;
#elif defined(OS_POSIX)
diff --git a/net/udp/udp_socket_libevent.cc b/net/udp/udp_socket_libevent.cc
index de24253..7c75ce3 100644
--- a/net/udp/udp_socket_libevent.cc
+++ b/net/udp/udp_socket_libevent.cc
@@ -63,8 +63,6 @@ int MapPosixError(int os_error) {
return ERR_ADDRESS_INVALID;
case EMSGSIZE:
return ERR_MSG_TOO_BIG;
- case ENOTCONN:
- return ERR_SOCKET_NOT_CONNECTED;
case 0:
return OK;
default:
@@ -101,21 +99,9 @@ UDPSocketLibevent::~UDPSocketLibevent() {
}
void UDPSocketLibevent::Close() {
- DCHECK(CalledOnValidThread());
-
- if (read_callback_)
- DoReadCallback(ERR_ABORTED);
- if (write_callback_)
- DoReadCallback(ERR_ABORTED);
-
if (!is_connected())
return;
- bool ok = read_socket_watcher_.StopWatchingFileDescriptor();
- DCHECK(ok);
- ok = write_socket_watcher_.StopWatchingFileDescriptor();
- DCHECK(ok);
-
if (HANDLE_EINTR(close(socket_)) < 0)
PLOG(ERROR) << "close";
@@ -175,7 +161,10 @@ int UDPSocketLibevent::Read(IOBuffer* buf,
DCHECK(callback); // Synchronous operation not supported
DCHECK_GT(buf_len, 0);
- int nread = InternalRead(buf, buf_len);
+ read_buf_ = buf;
+ read_buf_len_ = buf_len;
+
+ int nread = InternalRead();
if (nread != ERR_IO_PENDING)
return nread;
@@ -186,8 +175,6 @@ int UDPSocketLibevent::Read(IOBuffer* buf,
return MapPosixError(errno);
}
- read_buf_ = buf;
- read_buf_len_ = buf_len;
read_callback_ = callback;
return ERR_IO_PENDING;
}
@@ -245,7 +232,7 @@ int UDPSocketLibevent::Connect(const IPEndPoint& address) {
DCHECK(!remote_address_.get());
int rv = CreateSocket(address);
if (rv < 0)
- return rv;
+ return MapPosixError(rv);
struct sockaddr_storage addr_storage;
size_t addr_len = sizeof(addr_storage);
@@ -255,7 +242,7 @@ int UDPSocketLibevent::Connect(const IPEndPoint& address) {
rv = HANDLE_EINTR(connect(socket_, addr, addr_len));
if (rv < 0)
- return MapPosixError(errno);
+ return MapPosixError(rv);
remote_address_.reset(new IPEndPoint(address));
return rv;
@@ -266,7 +253,7 @@ int UDPSocketLibevent::Bind(const IPEndPoint& address) {
DCHECK(!local_address_.get());
int rv = CreateSocket(address);
if (rv < 0)
- return rv;
+ return MapPosixError(rv);
struct sockaddr_storage addr_storage;
size_t addr_len = sizeof(addr_storage);
@@ -276,7 +263,7 @@ int UDPSocketLibevent::Bind(const IPEndPoint& address) {
rv = bind(socket_, addr, addr_len);
if (rv < 0)
- return MapPosixError(errno);
+ return MapPosixError(rv);
local_address_.reset(new IPEndPoint(address));
return rv;
@@ -305,7 +292,7 @@ void UDPSocketLibevent::DoWriteCallback(int rv) {
}
void UDPSocketLibevent::DidCompleteRead() {
- int result = InternalRead(read_buf_, read_buf_len_);
+ int result = InternalRead();
if (result != ERR_IO_PENDING) {
read_buf_ = NULL;
read_buf_len_ = 0;
@@ -318,9 +305,9 @@ void UDPSocketLibevent::DidCompleteRead() {
int UDPSocketLibevent::CreateSocket(const IPEndPoint& address) {
socket_ = socket(address.GetFamily(), SOCK_DGRAM, 0);
if (socket_ == kInvalidSocket)
- return MapPosixError(errno);
+ return errno;
if (SetNonBlocking(socket_)) {
- const int err = MapPosixError(errno);
+ const int err = errno;
Close();
return err;
}
@@ -344,7 +331,7 @@ void UDPSocketLibevent::DidCompleteWrite() {
}
}
-int UDPSocketLibevent::InternalRead(IOBuffer* buf, int buf_len) {
+int UDPSocketLibevent::InternalRead() {
int bytes_transferred;
int flags = 0;
@@ -354,8 +341,8 @@ int UDPSocketLibevent::InternalRead(IOBuffer* buf, int buf_len) {
bytes_transferred =
HANDLE_EINTR(recvfrom(socket_,
- buf->data(),
- buf_len,
+ read_buf_->data(),
+ read_buf_len_,
flags,
addr,
&addr_len));
@@ -373,7 +360,6 @@ int UDPSocketLibevent::InternalRead(IOBuffer* buf, int buf_len) {
}
return result;
}
-
int UDPSocketLibevent::InternalWrite(IOBuffer* buf, int buf_len) {
struct sockaddr_storage addr_storage;
size_t addr_len = sizeof(addr_storage);
diff --git a/net/udp/udp_socket_libevent.h b/net/udp/udp_socket_libevent.h
index 1a9fd6e..ebe01b2 100644
--- a/net/udp/udp_socket_libevent.h
+++ b/net/udp/udp_socket_libevent.h
@@ -6,6 +6,25 @@
#define NET_UDP_UDP_SOCKET_LIBEVENT_H_
#pragma once
+// UDPSocketLibevent
+// Accessor API for a UDP socket in either client or server form.
+//
+// Client form:
+// In this case, we're connecting to a specific server, so the client will
+// usually use:
+// Connect(address) // Connect to a UDP server
+// Read/Write // Reads/Writes all go to a single destination
+//
+// Server form:
+// In this case, we want to read/write to many clients which are connecting
+// to this server. First the server 'binds' to an addres, then we read from
+// clients and write responses to them.
+// Example:
+// Bind(address/port) // Binds to port for reading from clients
+// RecvFrom/SendTo // Each read can come from a different client
+// // Writes need to be directed to a specific
+// // address.
+
#include "base/message_loop.h"
#include "base/ref_counted.h"
#include "base/scoped_ptr.h"
@@ -14,6 +33,7 @@
#include "net/base/ip_endpoint.h"
#include "net/base/net_log.h"
#include "net/socket/client_socket.h"
+#include "net/udp/datagram_socket.h"
namespace net {
@@ -93,6 +113,8 @@ class UDPSocketLibevent : public base::NonThreadSafe {
// Returns true if the socket is already connected or bound.
bool is_connected() const { return socket_ != kInvalidSocket; }
+ IPEndPoint* local_address() { return local_address_.get(); }
+
private:
static const int kInvalidSocket = -1;
@@ -142,7 +164,7 @@ class UDPSocketLibevent : public base::NonThreadSafe {
// Returns the OS error code (or 0 on success).
int CreateSocket(const IPEndPoint& address);
- int InternalRead(IOBuffer* buf, int buf_len);
+ int InternalRead();
int InternalWrite(IOBuffer* buf, int buf_len);
int socket_;
diff --git a/net/udp/udp_socket_unittest.cc b/net/udp/udp_socket_unittest.cc
index 23caf22..ef43731 100644
--- a/net/udp/udp_socket_unittest.cc
+++ b/net/udp/udp_socket_unittest.cc
@@ -107,7 +107,7 @@ class UDPSocketTest : public PlatformTest {
return bytes_sent;
}
- protected:
+ private:
static const int kMaxRead = 1024;
scoped_refptr<IOBufferWithSize> buffer_;
IPEndPoint recv_from_address_;
@@ -223,7 +223,7 @@ TEST_F(UDPSocketTest, ClientGetLocalPeerAddresses) {
struct TestData {
std::string remote_address;
std::string local_address;
- bool may_fail;
+ bool is_ipv6;
} tests[] = {
{ "127.0.00.1", "127.0.0.1", false },
{ "192.168.1.1", "127.0.0.1", false },
@@ -231,9 +231,6 @@ TEST_F(UDPSocketTest, ClientGetLocalPeerAddresses) {
{ "2001:db8:0::42", "::1", true },
};
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); i++) {
- SCOPED_TRACE(std::string("Connecting from ") + tests[i].local_address +
- std::string(" to ") + tests[i].remote_address);
-
net::IPAddressNumber ip_number;
net::ParseIPLiteralToNumber(tests[i].remote_address, &ip_number);
net::IPEndPoint remote_address(ip_number, 80);
@@ -242,12 +239,6 @@ TEST_F(UDPSocketTest, ClientGetLocalPeerAddresses) {
UDPClientSocket client(NULL, NetLog::Source());
int rv = client.Connect(remote_address);
- if (tests[i].may_fail && rv == ERR_ADDRESS_UNREACHABLE) {
- // Connect() may return ERR_ADDRESS_UNREACHABLE for IPv6
- // addresses if IPv6 is not configured.
- continue;
- }
-
EXPECT_LE(ERR_IO_PENDING, rv);
IPEndPoint fetched_local_address;
@@ -269,52 +260,21 @@ TEST_F(UDPSocketTest, ClientGetLocalPeerAddresses) {
}
TEST_F(UDPSocketTest, ServerGetLocalAddress) {
- IPEndPoint bind_address;
- CreateUDPAddress("127.0.0.1", 0, &bind_address);
- UDPServerSocket server(NULL, NetLog::Source());
- int rv = server.Listen(bind_address);
- EXPECT_EQ(OK, rv);
-
- IPEndPoint local_address;
- rv = server.GetLocalAddress(&local_address);
- EXPECT_EQ(rv, 0);
-
- // Verify that port was allocated.
- EXPECT_GE(local_address.port(), 0);
- EXPECT_EQ(local_address.address(), bind_address.address());
+ // TODO(mbelshe): implement me
}
TEST_F(UDPSocketTest, ServerGetPeerAddress) {
- IPEndPoint bind_address;
- CreateUDPAddress("127.0.0.1", 0, &bind_address);
- UDPServerSocket server(NULL, NetLog::Source());
- int rv = server.Listen(bind_address);
- EXPECT_EQ(OK, rv);
-
- IPEndPoint peer_address;
- rv = server.GetPeerAddress(&peer_address);
- EXPECT_EQ(rv, ERR_SOCKET_NOT_CONNECTED);
+ // TODO(mbelshe): implement me
}
-// Close the socket while read is pending.
-TEST_F(UDPSocketTest, CloseWithPendingRead) {
- IPEndPoint bind_address;
- CreateUDPAddress("127.0.0.1", 0, &bind_address);
- UDPServerSocket server(NULL, NetLog::Source());
- int rv = server.Listen(bind_address);
- EXPECT_EQ(OK, rv);
+} // namespace
- TestCompletionCallback callback;
- IPEndPoint from;
- rv = server.RecvFrom(buffer_, kMaxRead, &from, &callback);
- EXPECT_EQ(rv, ERR_IO_PENDING);
+} // namespace net
- server.Close();
+int main(int argc, char** argv) {
+ // Record histograms, so we can get histograms data in tests.
+ base::StatisticsRecorder recorder;
+ NetTestSuite test_suite(argc, argv);
- EXPECT_TRUE(callback.have_result());
- EXPECT_EQ(callback.GetResult(rv), ERR_ABORTED);
+ return test_suite.Run();
}
-
-} // namespace
-
-} // namespace net
diff --git a/net/udp/udp_socket_win.cc b/net/udp/udp_socket_win.cc
deleted file mode 100644
index 8a180d2..0000000
--- a/net/udp/udp_socket_win.cc
+++ /dev/null
@@ -1,366 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/udp/udp_socket_win.h"
-
-#include <mstcpip.h>
-
-#include "base/eintr_wrapper.h"
-#include "base/logging.h"
-#include "base/message_loop.h"
-#include "base/memory_debug.h"
-#include "base/metrics/stats_counters.h"
-#include "net/base/io_buffer.h"
-#include "net/base/ip_endpoint.h"
-#include "net/base/net_errors.h"
-#include "net/base/net_log.h"
-#include "net/base/net_util.h"
-#include "net/base/winsock_init.h"
-#include "net/base/winsock_util.h"
-
-namespace net {
-
-void UDPSocketWin::ReadDelegate::OnObjectSignaled(HANDLE object) {
- DCHECK_EQ(object, socket_->read_overlapped_.hEvent);
- socket_->DidCompleteRead();
-}
-
-void UDPSocketWin::WriteDelegate::OnObjectSignaled(HANDLE object) {
- DCHECK_EQ(object, socket_->write_overlapped_.hEvent);
- socket_->DidCompleteWrite();
-}
-
-UDPSocketWin::UDPSocketWin(net::NetLog* net_log,
- const net::NetLog::Source& source)
- : socket_(INVALID_SOCKET),
- ALLOW_THIS_IN_INITIALIZER_LIST(read_delegate_(this)),
- ALLOW_THIS_IN_INITIALIZER_LIST(write_delegate_(this)),
- recv_from_address_(NULL),
- read_callback_(NULL),
- write_callback_(NULL),
- net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) {
- EnsureWinsockInit();
- scoped_refptr<NetLog::EventParameters> params;
- if (source.is_valid())
- params = new NetLogSourceParameter("source_dependency", source);
- net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params);
- memset(&read_overlapped_, 0, sizeof(read_overlapped_));
- read_overlapped_.hEvent = WSACreateEvent();
- memset(&write_overlapped_, 0, sizeof(write_overlapped_));
- write_overlapped_.hEvent = WSACreateEvent();
-}
-
-UDPSocketWin::~UDPSocketWin() {
- Close();
- net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE, NULL);
-}
-
-void UDPSocketWin::Close() {
- DCHECK(CalledOnValidThread());
-
- if (!is_connected())
- return;
-
- if (read_callback_)
- DoReadCallback(ERR_ABORTED);
- if (write_callback_)
- DoReadCallback(ERR_ABORTED);
-
- read_watcher_.StopWatching();
- write_watcher_.StopWatching();
-
- closesocket(socket_);
- socket_ = INVALID_SOCKET;
-}
-
-int UDPSocketWin::GetPeerAddress(IPEndPoint* address) const {
- DCHECK(CalledOnValidThread());
- DCHECK(address);
- if (!is_connected())
- return ERR_SOCKET_NOT_CONNECTED;
-
- if (!remote_address_.get()) {
- struct sockaddr_storage addr_storage;
- int addr_len = sizeof(addr_storage);
- struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage);
- if (getpeername(socket_, addr, &addr_len))
- return MapWinsockError(WSAGetLastError());
- scoped_ptr<IPEndPoint> address(new IPEndPoint());
- if (!address->FromSockAddr(addr, addr_len))
- return ERR_FAILED;
- remote_address_.reset(address.release());
- }
-
- *address = *remote_address_;
- return OK;
-}
-
-int UDPSocketWin::GetLocalAddress(IPEndPoint* address) const {
- DCHECK(CalledOnValidThread());
- DCHECK(address);
- if (!is_connected())
- return ERR_SOCKET_NOT_CONNECTED;
-
- if (!local_address_.get()) {
- struct sockaddr_storage addr_storage;
- socklen_t addr_len = sizeof(addr_storage);
- struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage);
- if (getsockname(socket_, addr, &addr_len))
- return MapWinsockError(WSAGetLastError());
- scoped_ptr<IPEndPoint> address(new IPEndPoint());
- if (!address->FromSockAddr(addr, addr_len))
- return ERR_FAILED;
- local_address_.reset(address.release());
- }
-
- *address = *local_address_;
- return OK;
-}
-
-int UDPSocketWin::RecvFrom(IOBuffer* buf,
- int buf_len,
- IPEndPoint* address,
- CompletionCallback* callback) {
- DCHECK(!recv_from_address_);
- recv_from_address_ = address;
- return Read(buf, buf_len, callback);
-}
-
-int UDPSocketWin::Read(IOBuffer* buf,
- int buf_len,
- CompletionCallback* callback) {
- DCHECK(CalledOnValidThread());
- DCHECK_NE(INVALID_SOCKET, socket_);
- DCHECK(!read_callback_);
- DCHECK(callback); // Synchronous operation not supported.
- DCHECK_GT(buf_len, 0);
-
- int nread = InternalRead(buf, buf_len);
- if (nread != ERR_IO_PENDING)
- return nread;
-
- read_iobuffer_ = buf;
- read_callback_ = callback;
- return ERR_IO_PENDING;
-}
-
-int UDPSocketWin::SendTo(IOBuffer* buf,
- int buf_len,
- const IPEndPoint& address,
- CompletionCallback* callback) {
- send_to_address_.reset(new IPEndPoint(address));
- return Write(buf, buf_len, callback);
-}
-
-int UDPSocketWin::Write(IOBuffer* buf,
- int buf_len,
- CompletionCallback* callback) {
- DCHECK(CalledOnValidThread());
- DCHECK_NE(INVALID_SOCKET, socket_);
- DCHECK(!write_callback_);
- DCHECK(callback); // Synchronous operation not supported.
- DCHECK_GT(buf_len, 0);
-
- int nwrite = InternalWrite(buf, buf_len);
- if (nwrite != ERR_IO_PENDING)
- return nwrite;
-
- write_iobuffer_ = buf;
- write_callback_ = callback;
- return ERR_IO_PENDING;
-}
-
-int UDPSocketWin::Connect(const IPEndPoint& address) {
- DCHECK(!is_connected());
- DCHECK(!remote_address_.get());
- int rv = CreateSocket(address);
- if (rv < 0)
- return rv;
-
- struct sockaddr_storage addr_storage;
- size_t addr_len = sizeof(addr_storage);
- struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage);
- if (!address.ToSockAddr(addr, &addr_len))
- return ERR_FAILED;
-
- rv = connect(socket_, addr, addr_len);
- if (rv < 0)
- return MapWinsockError(WSAGetLastError());
-
- remote_address_.reset(new IPEndPoint(address));
- return rv;
-}
-
-int UDPSocketWin::Bind(const IPEndPoint& address) {
- DCHECK(!is_connected());
- DCHECK(!local_address_.get());
- int rv = CreateSocket(address);
- if (rv < 0)
- return rv;
-
- struct sockaddr_storage addr_storage;
- size_t addr_len = sizeof(addr_storage);
- struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage);
- if (!address.ToSockAddr(addr, &addr_len))
- return ERR_FAILED;
-
- rv = bind(socket_, addr, addr_len);
- if (rv < 0)
- return MapWinsockError(WSAGetLastError());
-
- local_address_.reset(new IPEndPoint(address));
- return rv;
-}
-
-int UDPSocketWin::CreateSocket(const IPEndPoint& address) {
- socket_ = WSASocket(address.GetFamily(), SOCK_DGRAM, IPPROTO_UDP, NULL, 0,
- WSA_FLAG_OVERLAPPED);
- if (socket_ == INVALID_SOCKET)
- return MapWinsockError(WSAGetLastError());
- return OK;
-}
-
-void UDPSocketWin::DoReadCallback(int rv) {
- DCHECK_NE(rv, ERR_IO_PENDING);
- DCHECK(read_callback_);
-
- // since Run may result in Read being called, clear read_callback_ up front.
- CompletionCallback* c = read_callback_;
- read_callback_ = NULL;
- recv_from_address_ = NULL;
- c->Run(rv);
-}
-
-void UDPSocketWin::DoWriteCallback(int rv) {
- DCHECK_NE(rv, ERR_IO_PENDING);
- DCHECK(write_callback_);
-
- // since Run may result in Write being called, clear write_callback_ up front.
- CompletionCallback* c = write_callback_;
- write_callback_ = NULL;
- send_to_address_.reset();
- c->Run(rv);
-}
-
-void UDPSocketWin::DidCompleteRead() {
- DWORD num_bytes, flags;
- BOOL ok = WSAGetOverlappedResult(socket_, &read_overlapped_,
- &num_bytes, FALSE, &flags);
- WSAResetEvent(read_overlapped_.hEvent);
- int result = ok ? num_bytes : MapWinsockError(WSAGetLastError());
- if (ok) {
- if (!ProcessSuccessfulRead(num_bytes))
- result = ERR_FAILED;
- }
- read_iobuffer_ = NULL;
- DoReadCallback(result);
-}
-
-bool UDPSocketWin::ProcessSuccessfulRead(int num_bytes) {
- static base::StatsCounter read_bytes("udp.read_bytes");
- read_bytes.Add(num_bytes);
-
- // Convert address.
- if (recv_from_address_) {
- struct sockaddr* addr =
- reinterpret_cast<struct sockaddr*>(&recv_addr_storage_);
- if (!recv_from_address_->FromSockAddr(addr, recv_addr_len_))
- return false;
- }
-
- return true;
-}
-
-void UDPSocketWin::DidCompleteWrite() {
- DWORD num_bytes, flags;
- BOOL ok = WSAGetOverlappedResult(socket_, &write_overlapped_,
- &num_bytes, FALSE, &flags);
- WSAResetEvent(write_overlapped_.hEvent);
- int result = ok ? num_bytes : MapWinsockError(WSAGetLastError());
- if (ok)
- ProcessSuccessfulWrite(num_bytes);
- write_iobuffer_ = NULL;
- DoWriteCallback(result);
-}
-
-void UDPSocketWin::ProcessSuccessfulWrite(int num_bytes) {
- static base::StatsCounter write_bytes("udp.write_bytes");
- write_bytes.Add(num_bytes);
-}
-
-int UDPSocketWin::InternalRead(IOBuffer* buf, int buf_len) {
- recv_addr_len_ = sizeof(recv_addr_storage_);
- struct sockaddr* addr =
- reinterpret_cast<struct sockaddr*>(&recv_addr_storage_);
-
- WSABUF read_buffer;
- read_buffer.buf = buf->data();
- read_buffer.len = buf_len;
-
- DWORD flags = 0;
- DWORD num;
- AssertEventNotSignaled(read_overlapped_.hEvent);
- int rv = WSARecvFrom(socket_, &read_buffer, 1, &num, &flags, addr,
- &recv_addr_len_, &read_overlapped_, NULL);
- if (rv == 0) {
- if (ResetEventIfSignaled(read_overlapped_.hEvent)) {
- // Because of how WSARecv fills memory when used asynchronously, Purify
- // isn't able to detect that it's been initialized, so it scans for 0xcd
- // in the buffer and reports UMRs (uninitialized memory reads) for those
- // individual bytes. We override that in PURIFY builds to avoid the
- // false error reports.
- // See bug 5297.
- base::MemoryDebug::MarkAsInitialized(read_buffer.buf, num);
- if (!ProcessSuccessfulRead(num))
- return ERR_FAILED;
- return static_cast<int>(num);
- }
- } else {
- int os_error = WSAGetLastError();
- if (os_error != WSA_IO_PENDING)
- return MapWinsockError(os_error);
- }
- read_watcher_.StartWatching(read_overlapped_.hEvent, &read_delegate_);
- return ERR_IO_PENDING;
-}
-
-int UDPSocketWin::InternalWrite(IOBuffer* buf, int buf_len) {
- struct sockaddr_storage addr_storage;
- size_t addr_len = sizeof(addr_storage);
- struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage);
-
- // Convert address.
- if (!send_to_address_.get()) {
- addr = NULL;
- addr_len = 0;
- } else {
- if (!send_to_address_->ToSockAddr(addr, &addr_len))
- return ERR_FAILED;
- }
-
- WSABUF write_buffer;
- write_buffer.buf = buf->data();
- write_buffer.len = buf_len;
-
- DWORD flags = 0;
- DWORD num;
- AssertEventNotSignaled(write_overlapped_.hEvent);
- int rv = WSASendTo(socket_, &write_buffer, 1, &num, flags,
- addr, addr_len, &write_overlapped_, NULL);
- if (rv == 0) {
- if (ResetEventIfSignaled(write_overlapped_.hEvent)) {
- ProcessSuccessfulWrite(num);
- return static_cast<int>(num);
- }
- } else {
- int os_error = WSAGetLastError();
- if (os_error != WSA_IO_PENDING)
- return MapWinsockError(os_error);
- }
-
- write_watcher_.StartWatching(write_overlapped_.hEvent, &write_delegate_);
- return ERR_IO_PENDING;
-}
-
-} // namespace net
diff --git a/net/udp/udp_socket_win.h b/net/udp/udp_socket_win.h
deleted file mode 100644
index d9e1dee..0000000
--- a/net/udp/udp_socket_win.h
+++ /dev/null
@@ -1,178 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef NET_UDP_UDP_SOCKET_WIN_H_
-#define NET_UDP_UDP_SOCKET_WIN_H_
-#pragma once
-
-#include <winsock2.h>
-
-#include "base/ref_counted.h"
-#include "base/scoped_ptr.h"
-#include "base/threading/non_thread_safe.h"
-#include "base/win/object_watcher.h"
-#include "net/base/completion_callback.h"
-#include "net/base/ip_endpoint.h"
-#include "net/base/io_buffer.h"
-#include "net/base/net_log.h"
-
-namespace net {
-
-class BoundNetLog;
-
-class UDPSocketWin : public base::NonThreadSafe {
- public:
- UDPSocketWin(net::NetLog* net_log,
- const net::NetLog::Source& source);
- virtual ~UDPSocketWin();
-
- // Connect the socket to connect with a certain |address|.
- // Returns a net error code.
- int Connect(const IPEndPoint& address);
-
- // Bind the address/port for this socket to |address|. This is generally
- // only used on a server.
- // Returns a net error code.
- int Bind(const IPEndPoint& address);
-
- // Close the socket.
- void Close();
-
- // Copy the remote udp address into |address| and return a network error code.
- int GetPeerAddress(IPEndPoint* address) const;
-
- // Copy the local udp address into |address| and return a network error code.
- // (similar to getsockname)
- int GetLocalAddress(IPEndPoint* address) const;
-
- // IO:
- // Multiple outstanding read requests are not supported.
- // Full duplex mode (reading and writing at the same time) is supported
-
- // Read from the socket.
- // Only usable from the client-side of a UDP socket, after the socket
- // has been connected.
- int Read(IOBuffer* buf, int buf_len, CompletionCallback* callback);
-
- // Write to the socket.
- // Only usable from the client-side of a UDP socket, after the socket
- // has been connected.
- int Write(IOBuffer* buf, int buf_len, CompletionCallback* callback);
-
- // Read from a socket and receive sender address information.
- // |buf| is the buffer to read data into.
- // |buf_len| is the maximum amount of data to read.
- // |address| is a buffer provided by the caller for receiving the sender
- // address information about the received data. This buffer must be kept
- // alive by the caller until the callback is placed.
- // |address_length| is a ptr to the length of the |address| buffer. This
- // is an input parameter containing the maximum size |address| can hold
- // and also an output parameter for the size of |address| upon completion.
- // |callback| the callback on completion of the Recv.
- // Returns a net error code, or ERR_IO_PENDING if the IO is in progress.
- // If ERR_IO_PENDING is returned, the caller must keep |buf|, |address|,
- // and |address_length| alive until the callback is called.
- int RecvFrom(IOBuffer* buf,
- int buf_len,
- IPEndPoint* address,
- CompletionCallback* callback);
-
- // Send to a socket with a particular destination.
- // |buf| is the buffer to send
- // |buf_len| is the number of bytes to send
- // |address| is the recipient address.
- // |address_length| is the size of the recipient address
- // |callback| is the user callback function to call on complete.
- // Returns a net error code, or ERR_IO_PENDING if the IO is in progress.
- // If ERR_IO_PENDING is returned, the caller must keep |buf| and |address|
- // alive until the callback is called.
- int SendTo(IOBuffer* buf,
- int buf_len,
- const IPEndPoint& address,
- CompletionCallback* callback);
-
- // Returns true if the socket is already connected or bound.
- bool is_connected() const { return socket_ != INVALID_SOCKET; }
-
- private:
- class ReadDelegate : public base::win::ObjectWatcher::Delegate {
- public:
- explicit ReadDelegate(UDPSocketWin* socket) : socket_(socket) {}
- virtual ~ReadDelegate() {}
-
- // base::ObjectWatcher::Delegate methods:
- virtual void OnObjectSignaled(HANDLE object);
-
- private:
- UDPSocketWin* const socket_;
- };
-
- class WriteDelegate : public base::win::ObjectWatcher::Delegate {
- public:
- explicit WriteDelegate(UDPSocketWin* socket) : socket_(socket) {}
- virtual ~WriteDelegate() {}
-
- // base::ObjectWatcher::Delegate methods:
- virtual void OnObjectSignaled(HANDLE object);
-
- private:
- UDPSocketWin* const socket_;
- };
-
- void DoReadCallback(int rv);
- void DoWriteCallback(int rv);
- void DidCompleteRead();
- void DidCompleteWrite();
- bool ProcessSuccessfulRead(int num_bytes);
- void ProcessSuccessfulWrite(int num_bytes);
-
- // Returns the OS error code (or 0 on success).
- int CreateSocket(const IPEndPoint& address);
-
- int InternalRead(IOBuffer* buf, int buf_len);
- int InternalWrite(IOBuffer* buf, int buf_len);
-
- SOCKET socket_;
-
- // These are mutable since they're just cached copies to make
- // GetPeerAddress/GetLocalAddress smarter.
- mutable scoped_ptr<IPEndPoint> local_address_;
- mutable scoped_ptr<IPEndPoint> remote_address_;
-
- // The socket's win wrappers
- ReadDelegate read_delegate_;
- WriteDelegate write_delegate_;
-
- // Watchers to watch for events from Read() and Write().
- base::win::ObjectWatcher read_watcher_;
- base::win::ObjectWatcher write_watcher_;
-
- // OVERLAPPED for pending read and write operations.
- OVERLAPPED read_overlapped_;
- OVERLAPPED write_overlapped_;
-
- // The buffer used by InternalRead() to retry Read requests
- scoped_refptr<IOBuffer> read_iobuffer_;
- struct sockaddr_storage recv_addr_storage_;
- socklen_t recv_addr_len_;
- IPEndPoint* recv_from_address_;
-
- // The buffer used by InternalWrite() to retry Write requests
- scoped_refptr<IOBuffer> write_iobuffer_;
- scoped_ptr<IPEndPoint> send_to_address_;
-
- // External callback; called when read is complete.
- CompletionCallback* read_callback_;
-
- // External callback; called when write is complete.
- CompletionCallback* write_callback_;
-
- BoundNetLog net_log_;
-
- DISALLOW_COPY_AND_ASSIGN(UDPSocketWin);
-};
-
-} // namespace net
-
-#endif // NET_UDP_UDP_SOCKET_WIN_H_