Showing with 175 additions and 138 deletions.
  1. +39 −36 src/win/error.c
  2. +0 −3 src/win/internal.h
  3. +55 −29 src/win/tcp.c
  4. +50 −42 src/win/udp.c
  5. +31 −28 src/win/winsock.c
@@ -66,31 +66,6 @@ void uv_fatal_error(const int errorno, const char* syscall) {
uv_err_code uv_translate_sys_error(int sys_errno) {
switch (sys_errno) {
case ERROR_SUCCESS: return UV_OK;
case ERROR_BEGINNING_OF_MEDIA: return UV_EIO;
case ERROR_BUS_RESET: return UV_EIO;
case ERROR_CRC: return UV_EIO;
case ERROR_DEVICE_DOOR_OPEN: return UV_EIO;
case ERROR_DEVICE_REQUIRES_CLEANING: return UV_EIO;
case ERROR_DISK_CORRUPT: return UV_EIO;
case ERROR_EOM_OVERFLOW: return UV_EIO;
case ERROR_FILEMARK_DETECTED: return UV_EIO;
case ERROR_GEN_FAILURE: return UV_EIO;
case ERROR_INVALID_BLOCK_LENGTH: return UV_EIO;
case ERROR_IO_DEVICE: return UV_EIO;
case ERROR_NO_DATA_DETECTED: return UV_EIO;
case ERROR_NO_SIGNAL_SENT: return UV_EIO;
case ERROR_OPEN_FAILED: return UV_EIO;
case ERROR_SETMARK_DETECTED: return UV_EIO;
case ERROR_SIGNAL_REFUSED: return UV_EIO;
case ERROR_DIRECTORY: return UV_ENOENT;
case ERROR_FILE_NOT_FOUND: return UV_ENOENT;
case ERROR_INVALID_NAME: return UV_ENOENT;
case ERROR_INVALID_REPARSE_DATA: return UV_ENOENT;
case ERROR_MOD_NOT_FOUND: return UV_ENOENT;
case ERROR_PATH_NOT_FOUND: return UV_ENOENT;
case WSANO_DATA: return UV_ENOENT;
case ERROR_ACCESS_DENIED: return UV_EPERM;
case ERROR_PRIVILEGE_NOT_HELD: return UV_EPERM;
case ERROR_NOACCESS: return UV_EACCES;
case WSAEACCES: return UV_EACCES;
case ERROR_ADDRESS_ALREADY_ASSOCIATED: return UV_EADDRINUSE;
@@ -99,8 +74,14 @@ uv_err_code uv_translate_sys_error(int sys_errno) {
case WSAEAFNOSUPPORT: return UV_EAFNOSUPPORT;
case WSAEWOULDBLOCK: return UV_EAGAIN;
case WSAEALREADY: return UV_EALREADY;
case ERROR_INVALID_FLAGS: return UV_EBADF;
case ERROR_INVALID_HANDLE: return UV_EBADF;
case ERROR_LOCK_VIOLATION: return UV_EBUSY;
case ERROR_PIPE_BUSY: return UV_EBUSY;
case ERROR_SHARING_VIOLATION: return UV_EBUSY;
case ERROR_OPERATION_ABORTED: return UV_ECANCELED;
case WSAEINTR: return UV_ECANCELED;
case ERROR_NO_UNICODE_TRANSLATION: return UV_ECHARSET;
case ERROR_CONNECTION_ABORTED: return UV_ECONNABORTED;
case WSAECONNABORTED: return UV_ECONNABORTED;
case ERROR_CONNECTION_REFUSED: return UV_ECONNREFUSED;
@@ -113,11 +94,29 @@ uv_err_code uv_translate_sys_error(int sys_errno) {
case WSAEFAULT: return UV_EFAULT;
case ERROR_HOST_UNREACHABLE: return UV_EHOSTUNREACH;
case WSAEHOSTUNREACH: return UV_EHOSTUNREACH;
case ERROR_OPERATION_ABORTED: return UV_ECANCELED;
case WSAEINTR: return UV_ECANCELED;
case ERROR_INSUFFICIENT_BUFFER: return UV_EINVAL;
case ERROR_INVALID_DATA: return UV_EINVAL;
case ERROR_INVALID_PARAMETER: return UV_EINVAL;
case ERROR_SYMLINK_NOT_SUPPORTED: return UV_EINVAL;
case WSAEINVAL: return UV_EINVAL;
case WSAEPFNOSUPPORT: return UV_EINVAL;
case WSAESOCKTNOSUPPORT: return UV_EINVAL;
case ERROR_BEGINNING_OF_MEDIA: return UV_EIO;
case ERROR_BUS_RESET: return UV_EIO;
case ERROR_CRC: return UV_EIO;
case ERROR_DEVICE_DOOR_OPEN: return UV_EIO;
case ERROR_DEVICE_REQUIRES_CLEANING: return UV_EIO;
case ERROR_DISK_CORRUPT: return UV_EIO;
case ERROR_EOM_OVERFLOW: return UV_EIO;
case ERROR_FILEMARK_DETECTED: return UV_EIO;
case ERROR_GEN_FAILURE: return UV_EIO;
case ERROR_INVALID_BLOCK_LENGTH: return UV_EIO;
case ERROR_IO_DEVICE: return UV_EIO;
case ERROR_NO_DATA_DETECTED: return UV_EIO;
case ERROR_NO_SIGNAL_SENT: return UV_EIO;
case ERROR_OPEN_FAILED: return UV_EIO;
case ERROR_SETMARK_DETECTED: return UV_EIO;
case ERROR_SIGNAL_REFUSED: return UV_EIO;
case ERROR_CANT_RESOLVE_FILENAME: return UV_ELOOP;
case ERROR_TOO_MANY_OPEN_FILES: return UV_EMFILE;
case WSAEMFILE: return UV_EMFILE;
@@ -126,33 +125,37 @@ uv_err_code uv_translate_sys_error(int sys_errno) {
case ERROR_NETWORK_UNREACHABLE: return UV_ENETUNREACH;
case WSAENETUNREACH: return UV_ENETUNREACH;
case WSAENOBUFS: return UV_ENOBUFS;
case ERROR_DIRECTORY: return UV_ENOENT;
case ERROR_FILE_NOT_FOUND: return UV_ENOENT;
case ERROR_INVALID_NAME: return UV_ENOENT;
case ERROR_INVALID_REPARSE_DATA: return UV_ENOENT;
case ERROR_MOD_NOT_FOUND: return UV_ENOENT;
case ERROR_PATH_NOT_FOUND: return UV_ENOENT;
case WSAHOST_NOT_FOUND: return UV_ENOENT;
case WSANO_DATA: return UV_ENOENT;
case ERROR_NOT_ENOUGH_MEMORY: return UV_ENOMEM;
case ERROR_OUTOFMEMORY: return UV_ENOMEM;
case ERROR_CANNOT_MAKE: return UV_ENOSPC;
case ERROR_DISK_FULL: return UV_ENOSPC;
case ERROR_EA_TABLE_FULL: return UV_ENOSPC;
case ERROR_END_OF_MEDIA: return UV_ENOSPC;
case ERROR_HANDLE_DISK_FULL: return UV_ENOSPC;
case ERROR_WRITE_PROTECT: return UV_EROFS;
case ERROR_NOT_CONNECTED: return UV_ENOTCONN;
case WSAENOTCONN: return UV_ENOTCONN;
case ERROR_DIR_NOT_EMPTY: return UV_ENOTEMPTY;
case WSAENOTSOCK: return UV_ENOTSOCK;
case ERROR_NOT_SUPPORTED: return UV_ENOTSUP;
case ERROR_INSUFFICIENT_BUFFER: return UV_EINVAL;
case ERROR_INVALID_FLAGS: return UV_EBADF;
case ERROR_INVALID_HANDLE: return UV_EBADF;
case ERROR_INVALID_PARAMETER: return UV_EINVAL;
case ERROR_NO_UNICODE_TRANSLATION: return UV_ECHARSET;
case ERROR_BROKEN_PIPE: return UV_EOF;
case ERROR_ACCESS_DENIED: return UV_EPERM;
case ERROR_PRIVILEGE_NOT_HELD: return UV_EPERM;
case ERROR_BAD_PIPE: return UV_EPIPE;
case ERROR_NO_DATA: return UV_EPIPE;
case ERROR_PIPE_NOT_CONNECTED: return UV_EPIPE;
case WSAESHUTDOWN: return UV_EPIPE;
case ERROR_PIPE_BUSY: return UV_EBUSY;
case WSAEPROTONOSUPPORT: return UV_EPROTONOSUPPORT;
case ERROR_WRITE_PROTECT: return UV_EROFS;
case ERROR_SEM_TIMEOUT: return UV_ETIMEDOUT;
case WSAETIMEDOUT: return UV_ETIMEDOUT;
case WSAHOST_NOT_FOUND: return UV_ENOENT;
case WSAENOTSOCK: return UV_ENOTSOCK;
case ERROR_NOT_SAME_DEVICE: return UV_EXDEV;
default: return UV_UNKNOWN;
}
@@ -335,9 +335,6 @@ int WSAAPI uv_wsarecvfrom_workaround(SOCKET socket, WSABUF* buffers,
int WSAAPI uv_msafd_poll(SOCKET socket, AFD_POLL_INFO* info,
OVERLAPPED* overlapped);

/* Whether ipv6 is supported */
extern int uv_allow_ipv6;

/* Whether there are any non-IFS LSPs stacked on TCP */
extern int uv_tcp_non_ifs_lsp_ipv4;
extern int uv_tcp_non_ifs_lsp_ipv6;
@@ -81,7 +81,7 @@ static int uv__tcp_keepalive(uv_tcp_t* handle, SOCKET socket, int enable, unsign


static int uv_tcp_set_socket(uv_loop_t* loop, uv_tcp_t* handle,
SOCKET socket, int imported) {
SOCKET socket, int family, int imported) {
DWORD yes = 1;
int non_ifs_lsp;

@@ -107,8 +107,11 @@ static int uv_tcp_set_socket(uv_loop_t* loop, uv_tcp_t* handle,
}
}

non_ifs_lsp = (handle->flags & UV_HANDLE_IPV6) ? uv_tcp_non_ifs_lsp_ipv6 :
uv_tcp_non_ifs_lsp_ipv4;
if (family == AF_INET6) {
non_ifs_lsp = uv_tcp_non_ifs_lsp_ipv6;
} else {
non_ifs_lsp = uv_tcp_non_ifs_lsp_ipv4;
}

if (pSetFileCompletionNotificationModes && !non_ifs_lsp) {
if (pSetFileCompletionNotificationModes((HANDLE) socket,
@@ -134,6 +137,12 @@ static int uv_tcp_set_socket(uv_loop_t* loop, uv_tcp_t* handle,

handle->socket = socket;

if (family == AF_INET6) {
handle->flags |= UV_HANDLE_IPV6;
} else {
assert(!(handle->flags & UV_HANDLE_IPV6));
}

return 0;
}

@@ -230,14 +239,14 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {


static int uv__bind(uv_tcp_t* handle,
int domain,
int family,
struct sockaddr* addr,
int addrsize) {
DWORD err;
int r;

if (handle->socket == INVALID_SOCKET) {
SOCKET sock = socket(domain, SOCK_STREAM, 0);
SOCKET sock = socket(family, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET) {
uv__set_sys_error(handle->loop, WSAGetLastError());
return -1;
@@ -250,7 +259,7 @@ static int uv__bind(uv_tcp_t* handle,
return -1;
}

if (uv_tcp_set_socket(handle->loop, handle, sock, 0) == -1) {
if (uv_tcp_set_socket(handle->loop, handle, sock, family, 0) < 0) {
closesocket(sock);
return -1;
}
@@ -285,17 +294,10 @@ int uv__tcp_bind(uv_tcp_t* handle, struct sockaddr_in addr) {


int uv__tcp_bind6(uv_tcp_t* handle, struct sockaddr_in6 addr) {
if (uv_allow_ipv6) {
handle->flags |= UV_HANDLE_IPV6;
return uv__bind(handle,
AF_INET6,
(struct sockaddr*)&addr,
sizeof(struct sockaddr_in6));

} else {
uv__set_sys_error(handle->loop, WSAEAFNOSUPPORT);
return -1;
}
return uv__bind(handle,
AF_INET6,
(struct sockaddr*)&addr,
sizeof(struct sockaddr_in6));
}


@@ -584,6 +586,7 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client) {
uv_loop_t* loop = server->loop;
int rv = 0;
int family;

uv_tcp_accept_t* req = server->pending_accepts;

@@ -598,7 +601,17 @@ int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client) {
return -1;
}

if (uv_tcp_set_socket(client->loop, client, req->accept_socket, 0) == -1) {
if (server->flags & UV_HANDLE_IPV6) {
family = AF_INET6;
} else {
family = AF_INET;
}

if (uv_tcp_set_socket(client->loop,
client,
req->accept_socket,
family,
0) < 0) {
closesocket(req->accept_socket);
rv = -1;
} else {
@@ -733,11 +746,6 @@ int uv__tcp_connect6(uv_connect_t* req,
BOOL success;
DWORD bytes;

if (!uv_allow_ipv6) {
uv__set_sys_error(loop, WSAEAFNOSUPPORT);
return -1;
}

if (handle->flags & UV_HANDLE_BIND_ERROR) {
uv__set_sys_error(loop, handle->bind_error);
return -1;
@@ -1148,7 +1156,11 @@ int uv_tcp_import(uv_tcp_t* tcp, WSAPROTOCOL_INFOW* socket_protocol_info,
return -1;
}

if (uv_tcp_set_socket(tcp->loop, tcp, socket, 1) != 0) {
if (uv_tcp_set_socket(tcp->loop,
tcp,
socket,
socket_protocol_info->iAddressFamily,
1) < 0) {
closesocket(socket);
return -1;
}
@@ -1161,10 +1173,6 @@ int uv_tcp_import(uv_tcp_t* tcp, WSAPROTOCOL_INFOW* socket_protocol_info,
tcp->flags |= UV_HANDLE_BOUND;
tcp->flags |= UV_HANDLE_SHARED_TCP_SOCKET;

if (socket_protocol_info->iAddressFamily == AF_INET6) {
tcp->flags |= UV_HANDLE_IPV6;
}

tcp->loop->active_tcp_streams++;
return 0;
}
@@ -1381,13 +1389,31 @@ void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp) {


int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) {
WSAPROTOCOL_INFOW protocol_info;
int opt_len;

/* Detect the address family of the socket. */
opt_len = (int) sizeof protocol_info;
if (getsockopt(sock,
SOL_SOCKET,
SO_PROTOCOL_INFOW,
(char*) &protocol_info,
&opt_len) == SOCKET_ERROR) {
uv__set_sys_error(handle->loop, GetLastError());
return -1;
}

/* Make the socket non-inheritable */
if (!SetHandleInformation((HANDLE) sock, HANDLE_FLAG_INHERIT, 0)) {
uv__set_sys_error(handle->loop, GetLastError());
return -1;
}

if (uv_tcp_set_socket(handle->loop, handle, sock, 0) == -1) {
if (uv_tcp_set_socket(handle->loop,
handle,
sock,
protocol_info.iAddressFamily,
1) < 0) {
return -1;
}