ext/libuv/src/win/tcp.c in libuv-0.10.2 vs ext/libuv/src/win/tcp.c in libuv-0.10.3

- old
+ new

@@ -233,19 +233,18 @@ loop->active_tcp_streams--; } } -static int uv__bind(uv_tcp_t* handle, - int family, - struct sockaddr* addr, - int addrsize) { +static int uv_tcp_try_bind(uv_tcp_t* handle, + const struct sockaddr* addr, + unsigned int addrlen) { DWORD err; int r; if (handle->socket == INVALID_SOCKET) { - SOCKET sock = socket(family, SOCK_STREAM, 0); + SOCKET sock = socket(addr->sa_family, SOCK_STREAM, 0); if (sock == INVALID_SOCKET) { return WSAGetLastError(); } /* Make the socket non-inheritable */ @@ -253,18 +252,18 @@ err = GetLastError(); closesocket(sock); return err; } - err = uv_tcp_set_socket(handle->loop, handle, sock, family, 0); + err = uv_tcp_set_socket(handle->loop, handle, sock, addr->sa_family, 0); if (err) { closesocket(sock); return err; } } - r = bind(handle->socket, addr, addrsize); + r = bind(handle->socket, addr, addrlen); if (r == SOCKET_ERROR) { err = WSAGetLastError(); if (err == WSAEADDRINUSE) { /* Some errors are not to be reported until connect() or listen() */ @@ -279,22 +278,10 @@ return 0; } -int uv__tcp_bind(uv_tcp_t* handle, struct sockaddr_in addr) { - return uv_translate_sys_error( - uv__bind(handle, AF_INET, (struct sockaddr*) &addr, sizeof(addr))); -} - - -int uv__tcp_bind6(uv_tcp_t* handle, struct sockaddr_in6 addr) { - return uv_translate_sys_error( - uv__bind(handle, AF_INET6, (struct sockaddr*) &addr, sizeof(addr))); -} - - static void CALLBACK post_completion(void* context, BOOLEAN timed_out) { uv_req_t* req; uv_tcp_t* handle; req = (uv_req_t*) context; @@ -432,13 +419,13 @@ * Preallocate a read buffer if the number of active streams is below * the threshold. */ if (loop->active_tcp_streams < uv_active_tcp_streams_threshold) { handle->flags &= ~UV_HANDLE_ZERO_READ; - handle->read_buffer = handle->alloc_cb((uv_handle_t*) handle, 65536); + handle->alloc_cb((uv_handle_t*) handle, 65536, &handle->read_buffer); if (handle->read_buffer.len == 0) { - handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, handle->read_buffer); + handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &handle->read_buffer); return; } assert(handle->read_buffer.base != NULL); buf = handle->read_buffer; } else { @@ -509,11 +496,13 @@ if (handle->flags & UV_HANDLE_BIND_ERROR) { return handle->bind_error; } if (!(handle->flags & UV_HANDLE_BOUND)) { - err = uv_tcp_bind(handle, uv_addr_ip4_any_); + err = uv_tcp_try_bind(handle, + (const struct sockaddr*) &uv_addr_ip4_any_, + sizeof(uv_addr_ip4_any_)); if (err) return err; } if (!handle->func_acceptex) { @@ -671,26 +660,34 @@ return 0; } -int uv__tcp_connect(uv_connect_t* req, - uv_tcp_t* handle, - struct sockaddr_in address, - uv_connect_cb cb) { +static int uv_tcp_try_connect(uv_connect_t* req, + uv_tcp_t* handle, + const struct sockaddr* addr, + unsigned int addrlen, + uv_connect_cb cb) { uv_loop_t* loop = handle->loop; - int addrsize = sizeof(struct sockaddr_in); + const struct sockaddr* bind_addr; BOOL success; DWORD bytes; int err; if (handle->flags & UV_HANDLE_BIND_ERROR) { return handle->bind_error; } if (!(handle->flags & UV_HANDLE_BOUND)) { - err = uv_tcp_bind(handle, uv_addr_ip4_any_); + if (addrlen == sizeof(uv_addr_ip4_any_)) { + bind_addr = (const struct sockaddr*) &uv_addr_ip4_any_; + } else if (addrlen == sizeof(uv_addr_ip6_any_)) { + bind_addr = (const struct sockaddr*) &uv_addr_ip6_any_; + } else { + abort(); + } + err = uv_tcp_try_bind(handle, bind_addr, addrlen); if (err) return err; } if (!handle->func_connectex) { @@ -704,12 +701,12 @@ req->handle = (uv_stream_t*) handle; req->cb = cb; memset(&req->overlapped, 0, sizeof(req->overlapped)); success = handle->func_connectex(handle->socket, - (struct sockaddr*) &address, - addrsize, + addr, + addrlen, NULL, 0, &bytes, &req->overlapped); @@ -728,65 +725,10 @@ return 0; } -int uv__tcp_connect6(uv_connect_t* req, - uv_tcp_t* handle, - struct sockaddr_in6 address, - uv_connect_cb cb) { - uv_loop_t* loop = handle->loop; - int addrsize = sizeof(struct sockaddr_in6); - BOOL success; - DWORD bytes; - int err; - - if (handle->flags & UV_HANDLE_BIND_ERROR) { - return handle->bind_error; - } - - if (!(handle->flags & UV_HANDLE_BOUND)) { - err = uv_tcp_bind6(handle, uv_addr_ip6_any_); - if (err) - return err; - } - - if (!handle->func_connectex) { - if (!uv_get_connectex_function(handle->socket, &handle->func_connectex)) { - return WSAEAFNOSUPPORT; - } - } - - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_CONNECT; - req->handle = (uv_stream_t*) handle; - req->cb = cb; - memset(&req->overlapped, 0, sizeof(req->overlapped)); - - success = handle->func_connectex(handle->socket, - (struct sockaddr*) &address, - addrsize, - NULL, - 0, - &bytes, - &req->overlapped); - - if (UV_SUCCEEDED_WITHOUT_IOCP(success)) { - handle->reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); - uv_insert_pending_req(loop, (uv_req_t*)req); - } else if (UV_SUCCEEDED_WITH_IOCP(success)) { - handle->reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); - } else { - return WSAGetLastError(); - } - - return 0; -} - - int uv_tcp_getsockname(uv_tcp_t* handle, struct sockaddr* name, int* namelen) { int result; if (!(handle->flags & UV_HANDLE_BOUND)) { @@ -825,12 +767,16 @@ return 0; } -int uv_tcp_write(uv_loop_t* loop, uv_write_t* req, uv_tcp_t* handle, - uv_buf_t bufs[], int bufcnt, uv_write_cb cb) { +int uv_tcp_write(uv_loop_t* loop, + uv_write_t* req, + uv_tcp_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs, + uv_write_cb cb) { int result; DWORD bytes; uv_req_init(loop, (uv_req_t*) req); req->type = UV_WRITE; @@ -848,12 +794,12 @@ req->overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1); req->wait_handle = INVALID_HANDLE_VALUE; } result = WSASend(handle->socket, - (WSABUF*)bufs, - bufcnt, + (WSABUF*) bufs, + nbufs, &bytes, 0, &req->overlapped, NULL); @@ -864,11 +810,11 @@ handle->write_reqs_pending++; REGISTER_HANDLE_REQ(loop, handle, req); uv_insert_pending_req(loop, (uv_req_t*) req); } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { /* Request queued by the kernel. */ - req->queued_bytes = uv_count_bufs(bufs, bufcnt); + req->queued_bytes = uv_count_bufs(bufs, nbufs); handle->reqs_pending++; handle->write_reqs_pending++; REGISTER_HANDLE_REQ(loop, handle, req); handle->write_queue_size += req->queued_bytes; if (handle->flags & UV_HANDLE_EMULATE_IOCP && @@ -914,20 +860,20 @@ err = WSAECONNRESET; } handle->read_cb((uv_stream_t*)handle, uv_translate_sys_error(err), - buf); + &buf); } } else { if (!(handle->flags & UV_HANDLE_ZERO_READ)) { /* The read was done with a non-zero buffer length. */ if (req->overlapped.InternalHigh > 0) { /* Successful read */ handle->read_cb((uv_stream_t*)handle, req->overlapped.InternalHigh, - handle->read_buffer); + &handle->read_buffer); /* Read again only if bytes == buf.len */ if (req->overlapped.InternalHigh < handle->read_buffer.len) { goto done; } } else { @@ -938,20 +884,20 @@ } handle->flags &= ~UV_HANDLE_READABLE; buf.base = 0; buf.len = 0; - handle->read_cb((uv_stream_t*)handle, UV_EOF, handle->read_buffer); + handle->read_cb((uv_stream_t*)handle, UV_EOF, &handle->read_buffer); goto done; } } /* Do nonblocking reads until the buffer is empty */ while (handle->flags & UV_HANDLE_READING) { - buf = handle->alloc_cb((uv_handle_t*) handle, 65536); + handle->alloc_cb((uv_handle_t*) handle, 65536, &buf); if (buf.len == 0) { - handle->read_cb(handle, UV_ENOBUFS, buf); + handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &buf); break; } assert(buf.base != NULL); flags = 0; @@ -962,28 +908,28 @@ &flags, NULL, NULL) != SOCKET_ERROR) { if (bytes > 0) { /* Successful read */ - handle->read_cb((uv_stream_t*)handle, bytes, buf); + handle->read_cb((uv_stream_t*)handle, bytes, &buf); /* Read again only if bytes == buf.len */ if (bytes < buf.len) { break; } } else { /* Connection closed */ handle->flags &= ~(UV_HANDLE_READING | UV_HANDLE_READABLE); DECREASE_ACTIVE_COUNT(loop, handle); - handle->read_cb((uv_stream_t*)handle, UV_EOF, buf); + handle->read_cb((uv_stream_t*)handle, UV_EOF, &buf); break; } } else { err = WSAGetLastError(); if (err == WSAEWOULDBLOCK) { /* Read buffer was completely empty, report a 0-byte read. */ - handle->read_cb((uv_stream_t*)handle, 0, buf); + handle->read_cb((uv_stream_t*)handle, 0, &buf); } else { /* Ouch! serious error. */ handle->flags &= ~UV_HANDLE_READING; DECREASE_ACTIVE_COUNT(loop, handle); @@ -993,11 +939,11 @@ err = WSAECONNRESET; } handle->read_cb((uv_stream_t*)handle, uv_translate_sys_error(err), - buf); + &buf); } break; } } @@ -1082,11 +1028,11 @@ if (handle->connection_cb) { handle->connection_cb((uv_stream_t*)handle, 0); } } else { /* Error related to accepted socket is ignored because the server */ - /* socket may still be healthy. If the server socket is broken + /* socket may still be healthy. If the server socket is broken */ /* uv_queue_accept will detect it. */ closesocket(req->accept_socket); req->accept_socket = INVALID_SOCKET; if (handle->flags & UV_HANDLE_LISTENING) { uv_tcp_queue_accept(handle, req); @@ -1408,8 +1354,42 @@ protocol_info.iAddressFamily, 1); if (err) { return uv_translate_sys_error(err); } + + return 0; +} + + +/* This function is an egress point, i.e. it returns libuv errors rather than + * system errors. + */ +int uv__tcp_bind(uv_tcp_t* handle, + const struct sockaddr* addr, + unsigned int addrlen) { + int err; + + err = uv_tcp_try_bind(handle, addr, addrlen); + if (err) + return uv_translate_sys_error(err); + + return 0; +} + + +/* This function is an egress point, i.e. it returns libuv errors rather than + * system errors. + */ +int uv__tcp_connect(uv_connect_t* req, + uv_tcp_t* handle, + const struct sockaddr* addr, + unsigned int addrlen, + uv_connect_cb cb) { + int err; + + err = uv_tcp_try_connect(req, handle, addr, addrlen, cb); + if (err) + return uv_translate_sys_error(err); return 0; }