From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTP id 3DEA630DC2 for ; Sat, 15 Jun 2019 12:58:33 -0400 (EDT) Received: from turing.freelists.org ([127.0.0.1]) by localhost (turing.freelists.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id qFy20Rhp95Gb for ; Sat, 15 Jun 2019 12:58:33 -0400 (EDT) Received: from smtpng3.m.smailru.net (smtpng3.m.smailru.net [94.100.177.149]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTPS id 6292A30DAC for ; Sat, 15 Jun 2019 12:58:32 -0400 (EDT) From: Roman Khabibov Subject: [tarantool-patches] [PATCH] lua: return getaddrinfo() errors Date: Sat, 15 Jun 2019 19:58:29 +0300 Message-Id: <20190615165829.11888-1-roman.habibov@tarantool.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: tarantool-patches-bounce@freelists.org Errors-to: tarantool-patches-bounce@freelists.org Reply-To: tarantool-patches@freelists.org List-Help: List-Unsubscribe: List-software: Ecartis version 1.0.0 List-Id: tarantool-patches List-Subscribe: List-Owner: List-post: List-Archive: To: tarantool-patches@freelists.org Cc: alexander.turenko@tarantool.org Before this patch, branch when coio_getaddrinfo() returns getaddrinfo() errors has never reached. Add this errors into the socket and thenet.box modules. Closes #4138 --- Branch: https://github.com/tarantool/tarantool/tree/romanhabibov/gh-4138-getaddrinfo Issue: https://github.com/tarantool/tarantool/issues/4138 src/box/lua/net_box.lua | 7 +++++-- src/lib/core/coio_task.c | 2 +- src/lua/socket.c | 6 ++++++ src/lua/socket.lua | 35 ++++++++++++++++++++++------------- test/app/socket.result | 31 ++++++++++++++++++++++++++++--- test/app/socket.test.lua | 19 ++++++++++++++++++- test/box/net.box.result | 21 ++++++++++++++++++++- test/box/net.box.test.lua | 15 +++++++++++++++ 8 files changed, 115 insertions(+), 21 deletions(-) diff --git a/src/box/lua/net_box.lua b/src/box/lua/net_box.lua index 251ad407a..4e3497ed9 100644 --- a/src/box/lua/net_box.lua +++ b/src/box/lua/net_box.lua @@ -142,9 +142,12 @@ local function next_id(id) return band(id + 1, 0x7FFFFFFF) end local function establish_connection(host, port, timeout) local timeout = timeout or DEFAULT_CONNECT_TIMEOUT local begin = fiber.clock() - local s = socket.tcp_connect(host, port, timeout) + local s, err = socket.tcp_connect(host, port, timeout) if not s then - return nil, errno.strerror(errno()) + if not err then + return nil, errno.strerror(errno()) + end + return nil, err end local msg = s:read({chunk = IPROTO_GREETING_SIZE}, timeout - (fiber.clock() - begin)) diff --git a/src/lib/core/coio_task.c b/src/lib/core/coio_task.c index 908b336ed..83f669d05 100644 --- a/src/lib/core/coio_task.c +++ b/src/lib/core/coio_task.c @@ -413,7 +413,7 @@ coio_getaddrinfo(const char *host, const char *port, return -1; /* timed out or cancelled */ /* Task finished */ - if (task->rc < 0) { + if (task->rc != 0) { /* getaddrinfo() failed */ errno = EIO; diag_set(SystemError, "getaddrinfo: %s", diff --git a/src/lua/socket.c b/src/lua/socket.c index 130378caf..5a8469ddf 100644 --- a/src/lua/socket.c +++ b/src/lua/socket.c @@ -54,6 +54,7 @@ #include #include "lua/utils.h" #include "lua/fiber.h" +#include "reflection.h" extern int coio_wait(int fd, int event, double timeout); @@ -816,6 +817,11 @@ lbox_socket_getaddrinfo(struct lua_State *L) if (dns_res != 0) { lua_pushnil(L); + struct error *err = diag_get()->last; + if (strcmp(err->type->name, "SystemError") == 0) { + lua_pushstring(L, err->errmsg); + return 2; + } return 1; } diff --git a/src/lua/socket.lua b/src/lua/socket.lua index 2dba0a8d2..f0b432925 100644 --- a/src/lua/socket.lua +++ b/src/lua/socket.lua @@ -1028,11 +1028,14 @@ local function tcp_connect(host, port, timeout) end local timeout = timeout or TIMEOUT_INFINITY local stop = fiber.clock() + timeout - local dns = getaddrinfo(host, port, timeout, { type = 'SOCK_STREAM', + local dns, err = getaddrinfo(host, port, timeout, { type = 'SOCK_STREAM', protocol = 'tcp' }) if dns == nil or #dns == 0 then - boxerrno(boxerrno.EINVAL) - return nil + if not err then + boxerrno(boxerrno.EINVAL) + return nil + end + return nil, err end for i, remote in pairs(dns) do timeout = stop - fiber.clock() @@ -1147,15 +1150,15 @@ end local function tcp_server_bind(host, port, prepare, timeout) timeout = timeout and tonumber(timeout) or TIMEOUT_INFINITY - local dns + local dns, err if host == 'unix/' then dns = {{host = host, port = port, family = 'AF_UNIX', protocol = 0, type = 'SOCK_STREAM' }} else - dns = getaddrinfo(host, port, timeout, { type = 'SOCK_STREAM', + dns, err = getaddrinfo(host, port, timeout, { type = 'SOCK_STREAM', flags = 'AI_PASSIVE'}) if dns == nil then - return nil + return nil, err end end @@ -1347,10 +1350,10 @@ local function lsocket_tcp_connect(self, host, port) -- This function is broken by design local ga_opts = { family = 'AF_INET', type = 'SOCK_STREAM' } local timeout = deadline - fiber.clock() - local dns = getaddrinfo(host, port, timeout, ga_opts) + local dns, err = getaddrinfo(host, port, timeout, ga_opts) if dns == nil or #dns == 0 then - self._errno = boxerrno.EINVAL - return nil, socket_error(self) + self._errno = boxerrno.EINVAL + return nil, err end for _, remote in ipairs(dns) do timeout = deadline - fiber.clock() @@ -1534,9 +1537,12 @@ local function lsocket_connect(host, port) if host == nil or port == nil then error("Usage: luasocket.connect(host, port)") end - local s = tcp_connect(host, port) + local s, err = tcp_connect(host, port) if not s then - return nil, boxerrno.strerror() + if not err then + return nil, boxerrno.strerror() + end + return nil, err end setmetatable(s, lsocket_tcp_client_mt) return s @@ -1547,9 +1553,12 @@ local function lsocket_bind(host, port, backlog) error("Usage: luasocket.bind(host, port [, backlog])") end local function prepare(s) return backlog end - local s = tcp_server_bind(host, port, prepare) + local s, err = tcp_server_bind(host, port, prepare) if not s then - return nil, boxerrno.strerror() + if not err then + return nil, boxerrno.strerror() + end + return nil, err end return setmetatable(s, lsocket_tcp_server_mt) end diff --git a/test/app/socket.result b/test/app/socket.result index 0d029039a..6a78b92a4 100644 --- a/test/app/socket.result +++ b/test/app/socket.result @@ -942,7 +942,7 @@ sc:close() ... -- tcp_connect -- test timeout -socket.tcp_connect('127.0.0.1', 80, 0.00000000001) +socket.tcp_connect('127.0.0.1', 80, 0.00000000000001) --- - null ... @@ -1664,7 +1664,7 @@ fio.stat(path) == nil { socket.tcp_connect('abrakadabra#123') == nil, errno.strerror() } --- - - true - - Invalid argument + - Input/output error ... -- wrong options for getaddrinfo socket.getaddrinfo('host', 'port', { type = 'WRONG' }) == nil and errno() == errno.EINVAL @@ -2870,7 +2870,32 @@ server:close() --- - true ... -test_run:cmd("clear filter") +--gh-4138 Check getaddrinfo() error. +test_run:cmd("setopt delimiter ';'") +--- +- true +... +function check_err(err) + if err == 'getaddrinfo: nodename nor servname provided, or not known' or + err == 'getaddrinfo: Servname not supported for ai_socktype' or + err == 'getaddrinfo: Name or service not known' then + return true + end + return false +end; +--- +... +s, err = socket:connect('hostname:3301'); +--- +... +check_err(err); +--- +- true +... +s, err = socket:bind('hostname:3301'); +--- +... +check_err(err); --- - true ... diff --git a/test/app/socket.test.lua b/test/app/socket.test.lua index dab168f90..140baf22f 100644 --- a/test/app/socket.test.lua +++ b/test/app/socket.test.lua @@ -301,7 +301,7 @@ sc:close() -- tcp_connect -- test timeout -socket.tcp_connect('127.0.0.1', 80, 0.00000000001) +socket.tcp_connect('127.0.0.1', 80, 0.00000000000001) -- AF_INET s = socket('AF_INET', 'SOCK_STREAM', 'tcp') @@ -982,4 +982,21 @@ fiber.cancel(echo_fiber) client:read(1, 5) == '' server:close() +--gh-4138 Check getaddrinfo() error. + +test_run:cmd("setopt delimiter ';'") +function check_err(err) + if err == 'getaddrinfo: nodename nor servname provided, or not known' or + err == 'getaddrinfo: Servname not supported for ai_socktype' or + err == 'getaddrinfo: Name or service not known' then + return true + end + return false +end; + +s, err = socket:connect('hostname:3301'); +check_err(err); +s, err = socket:bind('hostname:3301'); +check_err(err); + test_run:cmd("clear filter") diff --git a/test/box/net.box.result b/test/box/net.box.result index 474297af3..8a9b26411 100644 --- a/test/box/net.box.result +++ b/test/box/net.box.result @@ -3796,6 +3796,25 @@ test_run:grep_log('default', '00000040:.*') --- - null ... -box.cfg{log_level=log_level} +--gh-4138 Check getaddrinfo() error. +test_run:cmd("setopt delimiter ';'") +--- +- true +... +function check_err(err) + if err == 'getaddrinfo: nodename nor servname provided, or not known' or + err == 'getaddrinfo: Servname not supported for ai_socktype' or + err == 'getaddrinfo: Name or service not known' then + return true + end + return false +end; --- ... +s = remote.connect('hostname:3301'); +--- +... +check_err(s['error']); +--- +- true +... diff --git a/test/box/net.box.test.lua b/test/box/net.box.test.lua index bea43002d..13ed4e200 100644 --- a/test/box/net.box.test.lua +++ b/test/box/net.box.test.lua @@ -1538,4 +1538,19 @@ test_run:grep_log('default', '00000020:.*') test_run:grep_log('default', '00000030:.*') test_run:grep_log('default', '00000040:.*') +--gh-4138 Check getaddrinfo() error. +test_run:cmd("setopt delimiter ';'") + +function check_err(err) + if err == 'getaddrinfo: nodename nor servname provided, or not known' or + err == 'getaddrinfo: Servname not supported for ai_socktype' or + err == 'getaddrinfo: Name or service not known' then + return true + end + return false +end; + +s = remote.connect('hostname:3301'); +check_err(s['error']); + box.cfg{log_level=log_level} -- 2.20.1 (Apple Git-117)