From 525c58314549aafd39038122b61e39658193d102 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Witold=20Kr=C4=99cicki?= Date: Wed, 15 Jan 2020 12:29:41 +0100 Subject: [PATCH] netmgr: - isc__netievent_storage_t was to small to contain isc__netievent__socket_streaminfo_t on Windows - handle isc_uv_export and isc_uv_import errors properly - rewrite isc_uv_export and isc_uv_import on Windows --- lib/isc/netmgr/netmgr-int.h | 9 ++++---- lib/isc/netmgr/tcp.c | 20 +++++++++++++++-- lib/isc/netmgr/uv-compat.c | 44 ++++++++++++++++++++++++++++--------- 3 files changed, 57 insertions(+), 16 deletions(-) diff --git a/lib/isc/netmgr/netmgr-int.h b/lib/isc/netmgr/netmgr-int.h index 1930927a5e..cf9478f171 100644 --- a/lib/isc/netmgr/netmgr-int.h +++ b/lib/isc/netmgr/netmgr-int.h @@ -245,10 +245,11 @@ typedef isc__netievent_t isc__netievent_shutdown_t; typedef isc__netievent_t isc__netievent_stop_t; typedef union { - isc__netievent_t ni; - isc__netievent__socket_t nis; - isc__netievent__socket_req_t nisr; - isc__netievent_udpsend_t nius; + isc__netievent_t ni; + isc__netievent__socket_t nis; + isc__netievent__socket_req_t nisr; + isc__netievent_udpsend_t nius; + isc__netievent__socket_streaminfo_t niss; } isc__netievent_storage_t; /* diff --git a/lib/isc/netmgr/tcp.c b/lib/isc/netmgr/tcp.c index b884772e7b..17a97cda38 100644 --- a/lib/isc/netmgr/tcp.c +++ b/lib/isc/netmgr/tcp.c @@ -295,7 +295,16 @@ isc__nm_async_tcplisten(isc__networker_t *worker, isc__netievent_t *ev0) { event = isc__nm_get_ievent(csock->mgr, netievent_tcpchildlisten); - isc_uv_export(&sock->uv_handle.stream, &event->streaminfo); + r = isc_uv_export(&sock->uv_handle.stream, + &event->streaminfo); + if (r != 0) { + isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, + ISC_LOGMODULE_NETMGR, ISC_LOG_ERROR, + "uv_export failed: %s", + isc_result_totext(isc__nm_uverr2result(r))); + isc__nm_put_ievent(sock->mgr, event); + continue; + } event->sock = csock; if (csock->tid == isc_nm_tid()) { isc__nm_async_tcpchildlisten(&sock->mgr->workers[i], @@ -334,7 +343,14 @@ isc__nm_async_tcpchildlisten(isc__networker_t *worker, isc__netievent_t *ev0) { uv_tcp_init(&worker->loop, (uv_tcp_t *) &sock->uv_handle.tcp); uv_handle_set_data(&sock->uv_handle.handle, sock); - isc_uv_import(&sock->uv_handle.stream, &ievent->streaminfo); + r = isc_uv_import(&sock->uv_handle.stream, &ievent->streaminfo); + if (r != 0) { + isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, + ISC_LOGMODULE_NETMGR, ISC_LOG_ERROR, + "uv_import failed: %s", + isc_result_totext(isc__nm_uverr2result(r))); + return; + } r = uv_listen((uv_stream_t *) &sock->uv_handle.tcp, sock->backlog, tcp_connection_cb); diff --git a/lib/isc/netmgr/uv-compat.c b/lib/isc/netmgr/uv-compat.c index 101c3c7201..9e45fff108 100644 --- a/lib/isc/netmgr/uv-compat.c +++ b/lib/isc/netmgr/uv-compat.c @@ -10,6 +10,7 @@ */ #include +#include #include "uv-compat.h" /* @@ -21,6 +22,7 @@ #ifdef WIN32 /* This code is adapted from libuv/src/win/internal.h */ + typedef enum { UV__IPC_SOCKET_XFER_NONE = 0, UV__IPC_SOCKET_XFER_TCP_CONNECTION, @@ -32,38 +34,60 @@ typedef struct { uint32_t delayed_error; } uv__ipc_socket_xfer_info_t; +/* + * Needed to make sure that the internal structure that we pulled out of + * libuv hasn't changed. + */ + int uv__tcp_xfer_import(uv_tcp_t *tcp, uv__ipc_socket_xfer_type_t xfer_type, uv__ipc_socket_xfer_info_t *xfer_info); + int -uv__tcp_xfer_export(uv_tcp_t *handle, int pid, - uv__ipc_socket_xfer_info_t *xfer_info); +uv__tcp_xfer_export(uv_tcp_t* handle, + int target_pid, + uv__ipc_socket_xfer_type_t* xfer_type, + uv__ipc_socket_xfer_info_t* xfer_info); int isc_uv_export(uv_stream_t *stream, isc_uv_stream_info_t *info) { + uv__ipc_socket_xfer_info_t xfer_info; + uv__ipc_socket_xfer_type_t xfer_type = UV__IPC_SOCKET_XFER_NONE; + + /* + * Needed to make sure that the internal structure that we pulled + * out of libuv hasn't changed. + */ + RUNTIME_CHECK(sizeof(uv__ipc_socket_xfer_info_t) == 632); + if (stream->type != UV_TCP) { return (-1); } - if (uv__tcp_xfer_export((uv_tcp_t *) stream, GetCurrentProcessId(), - &info->socket_info) == -1) { - return (-1); + int r = uv__tcp_xfer_export((uv_tcp_t *) stream, + GetCurrentProcessId(), + &xfer_type, &xfer_info); + if (r != 0) { + return (r); + } + if (xfer_info.delayed_error != 0) { + return (xfer_info.delayed_error); } - info->type = UV_TCP; + info->socket_info = xfer_info.socket_info; + return (0); } int isc_uv_import(uv_stream_t *stream, isc_uv_stream_info_t *info) { - uv__ipc_socket_xfer_info_t xfer_info; - if (stream->type != UV_TCP || info->type != UV_TCP) { return (-1); } - xfer_info.socket_info = info->socket_info; return (uv__tcp_xfer_import((uv_tcp_t *) stream, UV__IPC_SOCKET_XFER_TCP_SERVER, - &xfer_info)); + &(uv__ipc_socket_xfer_info_t){ + .socket_info = info->socket_info + })); } #else /* WIN32 */ /* Adapted from libuv/src/unix/internal.h */