diff options
author | wtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-05 03:06:08 +0000 |
---|---|---|
committer | wtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-05 03:06:08 +0000 |
commit | d3d828560fe1a18f6b790a470272844e794a7cb4 (patch) | |
tree | 697685d9ea9c729066236e4d1bda1e37a7e3fd04 /net/socket/tcp_client_socket_win.cc | |
parent | d406b29c71cc11328fe5c1f12063c3782fbbb3c8 (diff) | |
download | chromium_src-d3d828560fe1a18f6b790a470272844e794a7cb4.zip chromium_src-d3d828560fe1a18f6b790a470272844e794a7cb4.tar.gz chromium_src-d3d828560fe1a18f6b790a470272844e794a7cb4.tar.bz2 |
Map WSAEACCES (which is reported by connect if Windows Firewall
blocks the connection) to ERR_ACCESS_DENIED. We are already
mapping EACCES to ERR_ACCESS_DENIED on Linux and Mac.
Use ERR_CONNECTION_FAILED instead of ERR_FAILED as the default
error code for Connect.
Create the ShouldTryNextAddress function for Windows to match
the Linux and Mac code.
WSAGetLastError returns int rather than DWORD.
R=eroman
BUG=21548
TEST=none
Review URL: http://codereview.chromium.org/361015
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@31064 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/socket/tcp_client_socket_win.cc')
-rw-r--r-- | net/socket/tcp_client_socket_win.cc | 44 |
1 files changed, 32 insertions, 12 deletions
diff --git a/net/socket/tcp_client_socket_win.cc b/net/socket/tcp_client_socket_win.cc index 407ea44..199dccd 100644 --- a/net/socket/tcp_client_socket_win.cc +++ b/net/socket/tcp_client_socket_win.cc @@ -42,10 +42,14 @@ bool ResetEventIfSignaled(WSAEVENT hEvent) { //----------------------------------------------------------------------------- -int MapWinsockError(DWORD err) { +int MapWinsockError(int err) { // There are numerous Winsock error codes, but these are the ones we thus far // find interesting. switch (err) { + // connect fails with WSAEACCES when Windows Firewall blocks the + // connection. + case WSAEACCES: + return ERR_ACCESS_DENIED; case WSAENETDOWN: return ERR_INTERNET_DISCONNECTED; case WSAETIMEDOUT: @@ -79,12 +83,34 @@ int MapWinsockError(DWORD err) { } } -int MapConnectError(DWORD err) { +int MapConnectError(int err) { switch (err) { case WSAETIMEDOUT: return ERR_CONNECTION_TIMED_OUT; + default: { + int net_error = MapWinsockError(err); + if (net_error == ERR_FAILED) + return ERR_CONNECTION_FAILED; // More specific than ERR_FAILED. + return net_error; + } + } +} + +// Given err, a WSAGetLastError() error code from a connect() attempt, returns +// true if connect() should be retried with another address. +bool ShouldTryNextAddress(int err) { + switch (err) { + case WSAEADDRNOTAVAIL: + case WSAEAFNOSUPPORT: + case WSAECONNREFUSED: + case WSAEACCES: + case WSAENETUNREACH: + case WSAEHOSTUNREACH: + case WSAENETDOWN: + case WSAETIMEDOUT: + return true; default: - return MapWinsockError(err); + return false; } } @@ -339,7 +365,7 @@ int TCPClientSocketWin::DoConnect() { if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) return OK; } else { - DWORD err = WSAGetLastError(); + int err = WSAGetLastError(); if (err != WSAEWOULDBLOCK) { LOG(ERROR) << "connect failed: " << err; return MapConnectError(err); @@ -524,7 +550,7 @@ int TCPClientSocketWin::CreateSocket(const struct addrinfo* ai) { socket_ = WSASocket(ai->ai_family, ai->ai_socktype, ai->ai_protocol, NULL, 0, WSA_FLAG_OVERLAPPED); if (socket_ == INVALID_SOCKET) { - DWORD err = WSAGetLastError(); + int err = WSAGetLastError(); LOG(ERROR) << "WSASocket failed: " << err; return MapWinsockError(err); } @@ -618,13 +644,7 @@ void TCPClientSocketWin::DidCompleteConnect() { result = MapWinsockError(WSAGetLastError()); } else if (events.lNetworkEvents & FD_CONNECT) { DWORD error_code = static_cast<DWORD>(events.iErrorCode[FD_CONNECT_BIT]); - if (current_ai_->ai_next && ( - error_code == WSAEADDRNOTAVAIL || - error_code == WSAEAFNOSUPPORT || - error_code == WSAECONNREFUSED || - error_code == WSAENETUNREACH || - error_code == WSAEHOSTUNREACH || - error_code == WSAETIMEDOUT)) { + if (current_ai_->ai_next && ShouldTryNextAddress(error_code)) { // Try using the next address. const struct addrinfo* next = current_ai_->ai_next; Disconnect(); |