diff options
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(); |