|
@@ -550,108 +550,6 @@ compute_num_cpus(void)
|
|
|
return num_cpus;
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * On Windows, WSAEWOULDBLOCK is not always correct: when you see it,
|
|
|
- * you need to ask the socket for its actual errno. Also, you need to
|
|
|
- * get your errors from WSAGetLastError, not errno. (If you supply a
|
|
|
- * socket of -1, we check WSAGetLastError, but don't correct
|
|
|
- * WSAEWOULDBLOCKs.)
|
|
|
- *
|
|
|
- * The upshot of all of this is that when a socket call fails, you
|
|
|
- * should call tor_socket_errno <em>at most once</em> on the failing
|
|
|
- * socket to get the error.
|
|
|
- */
|
|
|
-#if defined(_WIN32)
|
|
|
-int
|
|
|
-tor_socket_errno(tor_socket_t sock)
|
|
|
-{
|
|
|
- int optval, optvallen=sizeof(optval);
|
|
|
- int err = WSAGetLastError();
|
|
|
- if (err == WSAEWOULDBLOCK && SOCKET_OK(sock)) {
|
|
|
- if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)&optval, &optvallen))
|
|
|
- return err;
|
|
|
- if (optval)
|
|
|
- return optval;
|
|
|
- }
|
|
|
- return err;
|
|
|
-}
|
|
|
-#endif /* defined(_WIN32) */
|
|
|
-
|
|
|
-#if defined(_WIN32)
|
|
|
-#define E(code, s) { code, (s " [" #code " ]") }
|
|
|
-struct { int code; const char *msg; } windows_socket_errors[] = {
|
|
|
- E(WSAEINTR, "Interrupted function call"),
|
|
|
- E(WSAEACCES, "Permission denied"),
|
|
|
- E(WSAEFAULT, "Bad address"),
|
|
|
- E(WSAEINVAL, "Invalid argument"),
|
|
|
- E(WSAEMFILE, "Too many open files"),
|
|
|
- E(WSAEWOULDBLOCK, "Resource temporarily unavailable"),
|
|
|
- E(WSAEINPROGRESS, "Operation now in progress"),
|
|
|
- E(WSAEALREADY, "Operation already in progress"),
|
|
|
- E(WSAENOTSOCK, "Socket operation on nonsocket"),
|
|
|
- E(WSAEDESTADDRREQ, "Destination address required"),
|
|
|
- E(WSAEMSGSIZE, "Message too long"),
|
|
|
- E(WSAEPROTOTYPE, "Protocol wrong for socket"),
|
|
|
- E(WSAENOPROTOOPT, "Bad protocol option"),
|
|
|
- E(WSAEPROTONOSUPPORT, "Protocol not supported"),
|
|
|
- E(WSAESOCKTNOSUPPORT, "Socket type not supported"),
|
|
|
- /* What's the difference between NOTSUPP and NOSUPPORT? :) */
|
|
|
- E(WSAEOPNOTSUPP, "Operation not supported"),
|
|
|
- E(WSAEPFNOSUPPORT, "Protocol family not supported"),
|
|
|
- E(WSAEAFNOSUPPORT, "Address family not supported by protocol family"),
|
|
|
- E(WSAEADDRINUSE, "Address already in use"),
|
|
|
- E(WSAEADDRNOTAVAIL, "Cannot assign requested address"),
|
|
|
- E(WSAENETDOWN, "Network is down"),
|
|
|
- E(WSAENETUNREACH, "Network is unreachable"),
|
|
|
- E(WSAENETRESET, "Network dropped connection on reset"),
|
|
|
- E(WSAECONNABORTED, "Software caused connection abort"),
|
|
|
- E(WSAECONNRESET, "Connection reset by peer"),
|
|
|
- E(WSAENOBUFS, "No buffer space available"),
|
|
|
- E(WSAEISCONN, "Socket is already connected"),
|
|
|
- E(WSAENOTCONN, "Socket is not connected"),
|
|
|
- E(WSAESHUTDOWN, "Cannot send after socket shutdown"),
|
|
|
- E(WSAETIMEDOUT, "Connection timed out"),
|
|
|
- E(WSAECONNREFUSED, "Connection refused"),
|
|
|
- E(WSAEHOSTDOWN, "Host is down"),
|
|
|
- E(WSAEHOSTUNREACH, "No route to host"),
|
|
|
- E(WSAEPROCLIM, "Too many processes"),
|
|
|
- /* Yes, some of these start with WSA, not WSAE. No, I don't know why. */
|
|
|
- E(WSASYSNOTREADY, "Network subsystem is unavailable"),
|
|
|
- E(WSAVERNOTSUPPORTED, "Winsock.dll out of range"),
|
|
|
- E(WSANOTINITIALISED, "Successful WSAStartup not yet performed"),
|
|
|
- E(WSAEDISCON, "Graceful shutdown now in progress"),
|
|
|
-#ifdef WSATYPE_NOT_FOUND
|
|
|
- E(WSATYPE_NOT_FOUND, "Class type not found"),
|
|
|
-#endif
|
|
|
- E(WSAHOST_NOT_FOUND, "Host not found"),
|
|
|
- E(WSATRY_AGAIN, "Nonauthoritative host not found"),
|
|
|
- E(WSANO_RECOVERY, "This is a nonrecoverable error"),
|
|
|
- E(WSANO_DATA, "Valid name, no data record of requested type)"),
|
|
|
-
|
|
|
- /* There are some more error codes whose numeric values are marked
|
|
|
- * <b>OS dependent</b>. They start with WSA_, apparently for the same
|
|
|
- * reason that practitioners of some craft traditions deliberately
|
|
|
- * introduce imperfections into their baskets and rugs "to allow the
|
|
|
- * evil spirits to escape." If we catch them, then our binaries
|
|
|
- * might not report consistent results across versions of Windows.
|
|
|
- * Thus, I'm going to let them all fall through.
|
|
|
- */
|
|
|
- { -1, NULL },
|
|
|
-};
|
|
|
-/** There does not seem to be a strerror equivalent for Winsock errors.
|
|
|
- * Naturally, we have to roll our own.
|
|
|
- */
|
|
|
-const char *
|
|
|
-tor_socket_strerror(int e)
|
|
|
-{
|
|
|
- int i;
|
|
|
- for (i=0; windows_socket_errors[i].code >= 0; ++i) {
|
|
|
- if (e == windows_socket_errors[i].code)
|
|
|
- return windows_socket_errors[i].msg;
|
|
|
- }
|
|
|
- return strerror(e);
|
|
|
-}
|
|
|
-#endif /* defined(_WIN32) */
|
|
|
|
|
|
/** Called before we make any calls to network-related functions.
|
|
|
* (Some operating systems require their network libraries to be
|