diff --git a/deps/libuv b/deps/libuv index 4ca78e98..165685b2 160000 --- a/deps/libuv +++ b/deps/libuv @@ -1 +1 @@ -Subproject commit 4ca78e989062a1099dc4b9ad182a98e8374134b1 +Subproject commit 165685b2a9a42cf96501d79cd6d48a18aaa16e3b diff --git a/src/dns.c b/src/dns.c index 446342e3..54ca18da 100644 --- a/src/dns.c +++ b/src/dns.c @@ -22,12 +22,47 @@ #include #endif -static void luv_getaddrinfo_cb(uv_getaddrinfo_t* req, int status, struct addrinfo* res) { - lua_State* L = luv_state(req->loop); - struct addrinfo* curr = res; +static void luv_pushaddrinfo(lua_State* L, struct addrinfo* res) { char ip[INET6_ADDRSTRLEN]; + int port, i = 0; const char *addr; - int port, nargs, i = 0; + struct addrinfo* curr = res; + lua_newtable(L); + for (curr = res; curr; curr = curr->ai_next) { + if (curr->ai_family == AF_INET || curr->ai_family == AF_INET6) { + lua_newtable(L); + if (curr->ai_family == AF_INET) { + addr = (char*) &((struct sockaddr_in*) curr->ai_addr)->sin_addr; + port = ((struct sockaddr_in*) curr->ai_addr)->sin_port; + } else { + addr = (char*) &((struct sockaddr_in6*) curr->ai_addr)->sin6_addr; + port = ((struct sockaddr_in6*) curr->ai_addr)->sin6_port; + } + lua_pushstring(L, luv_af_num_to_string(curr->ai_family)); + lua_setfield(L, -2, "family"); + uv_inet_ntop(curr->ai_family, addr, ip, INET6_ADDRSTRLEN); + lua_pushstring(L, ip); + lua_setfield(L, -2, "addr"); + if (ntohs(port)) { + lua_pushinteger(L, ntohs(port)); + lua_setfield(L, -2, "port"); + } + lua_pushstring(L, luv_sock_num_to_string(curr->ai_socktype)); + lua_setfield(L, -2, "socktype"); + lua_pushstring(L, luv_af_num_to_string(curr->ai_protocol)); + lua_setfield(L, -2, "protocol"); + if (curr->ai_canonname) { + lua_pushstring(L, curr->ai_canonname); + lua_setfield(L, -2, "canonname"); + } + lua_rawseti(L, -2, ++i); + } + } +} + +static void luv_getaddrinfo_cb(uv_getaddrinfo_t* req, int status, struct addrinfo* res) { + lua_State* L = luv_state(req->loop); + int nargs; if (status < 0) { luv_status(L, status); @@ -35,38 +70,8 @@ static void luv_getaddrinfo_cb(uv_getaddrinfo_t* req, int status, struct addrinf } else { lua_pushnil(L); - lua_newtable(L); + luv_pushaddrinfo(L, res); nargs = 2; - for (curr = res; curr; curr = curr->ai_next) { - if (curr->ai_family == AF_INET || curr->ai_family == AF_INET6) { - lua_newtable(L); - if (curr->ai_family == AF_INET) { - addr = (char*) &((struct sockaddr_in*) curr->ai_addr)->sin_addr; - port = ((struct sockaddr_in*) curr->ai_addr)->sin_port; - } else { - addr = (char*) &((struct sockaddr_in6*) curr->ai_addr)->sin6_addr; - port = ((struct sockaddr_in6*) curr->ai_addr)->sin6_port; - } - lua_pushstring(L, luv_af_num_to_string(curr->ai_family)); - lua_setfield(L, -2, "family"); - uv_inet_ntop(curr->ai_family, addr, ip, INET6_ADDRSTRLEN); - lua_pushstring(L, ip); - lua_setfield(L, -2, "addr"); - if (ntohs(port)) { - lua_pushinteger(L, ntohs(port)); - lua_setfield(L, -2, "port"); - } - lua_pushstring(L, luv_sock_num_to_string(curr->ai_socktype)); - lua_setfield(L, -2, "socktype"); - lua_pushstring(L, luv_af_num_to_string(curr->ai_protocol)); - lua_setfield(L, -2, "protocol"); - if (curr->ai_canonname) { - lua_pushstring(L, curr->ai_canonname); - lua_setfield(L, -2, "canonname"); - } - lua_rawseti(L, -2, ++i); - } - } } luv_fulfill_req(L, req->data, nargs); luv_cleanup_req(L, req->data); @@ -82,14 +87,13 @@ static int luv_getaddrinfo(lua_State* L) { struct addrinfo hints_s; struct addrinfo* hints = &hints_s; int ret, ref; - if (lua_isnil(L, 1)) node = NULL; + if (lua_isnoneornil(L, 1)) node = NULL; else node = luaL_checkstring(L, 1); - if (lua_isnil(L, 2)) service = NULL; + if (lua_isnoneornil(L, 2)) service = NULL; else service = luaL_checkstring(L, 2); - if (!lua_isnil(L, 3)) luaL_checktype(L, 3, LUA_TTABLE); + if (!lua_isnoneornil(L, 3)) luaL_checktype(L, 3, LUA_TTABLE); else hints = NULL; - luaL_checktype(L, 4, LUA_TFUNCTION); - ref = luv_check_continuation(L, 4); + ref = lua_isnoneornil(L, 4) ? LUA_NOREF : luv_check_continuation(L, 4); if (hints) { // Initialize the hints memset(hints, 0, sizeof(*hints)); @@ -181,11 +185,18 @@ static int luv_getaddrinfo(lua_State* L) { req = lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); - ret = uv_getaddrinfo(luv_loop(L), req, luv_getaddrinfo_cb, node, service, hints); + ret = uv_getaddrinfo(luv_loop(L), req, ref == LUA_NOREF ? NULL : luv_getaddrinfo_cb, node, service, hints); if (ret < 0) { lua_pop(L, 1); return luv_error(L, ret); } + if (ref == LUA_NOREF) { + + lua_pop(L, 1); + luv_pushaddrinfo(L, req->addrinfo); + uv_freeaddrinfo(req->addrinfo); + luv_cleanup_req(L, req->data); + } return 1; } @@ -214,7 +225,7 @@ static int luv_getnameinfo(lua_State* L) { uv_getnameinfo_t* req; struct sockaddr_storage addr; const char* ip = NULL; - int flags = 0; + int flags = 0, sync; int ret, ref, port = 0; luaL_checktype(L, 1, LUA_TTABLE); @@ -263,17 +274,23 @@ static int luv_getnameinfo(lua_State* L) { } lua_pop(L, 1); - luaL_checktype(L, 2, LUA_TFUNCTION); - ref = luv_check_continuation(L, 2); + ref = lua_isnoneornil(L, 2) ? LUA_NOREF : luv_check_continuation(L, 2); req = lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); - ret = uv_getnameinfo(luv_loop(L), req, luv_getnameinfo_cb, (struct sockaddr*)&addr, flags); + ret = uv_getnameinfo(luv_loop(L), req, ref == LUA_NOREF ? NULL : luv_getnameinfo_cb, (struct sockaddr*)&addr, flags); if (ret < 0) { lua_pop(L, 1); return luv_error(L, ret); } + if (ref == LUA_NOREF) { + lua_pop(L, 1); + lua_pushstring(L, req->host); + lua_pushstring(L, req->service); + luv_cleanup_req(L, req->data); + return 2; + } return 1; } diff --git a/src/luv.c b/src/luv.c index f2572f42..5fd5b93a 100644 --- a/src/luv.c +++ b/src/luv.c @@ -144,6 +144,7 @@ static const luaL_Reg luv_functions[] = { {"pipe_bind", luv_pipe_bind}, {"pipe_connect", luv_pipe_connect}, {"pipe_getsockname", luv_pipe_getsockname}, + {"pipe_getsocknamepeername", luv_pipe_getpeername}, {"pipe_pending_instances", luv_pipe_pending_instances}, {"pipe_pending_count", luv_pipe_pending_count}, {"pipe_pending_type", luv_pipe_pending_type}, @@ -302,6 +303,7 @@ static const luaL_Reg luv_pipe_methods[] = { {"bind", luv_pipe_bind}, {"connect", luv_pipe_connect}, {"getsockname", luv_pipe_getsockname}, + {"getpeername", luv_pipe_getpeername}, {"pending_instances", luv_pipe_pending_instances}, {"pending_count", luv_pipe_pending_count}, {"pending_type", luv_pipe_pending_type}, diff --git a/src/pipe.c b/src/pipe.c index 6c438d8b..117bacd6 100644 --- a/src/pipe.c +++ b/src/pipe.c @@ -75,6 +75,16 @@ static int luv_pipe_getsockname(lua_State* L) { return 1; } +static int luv_pipe_getpeername(lua_State* L) { + uv_pipe_t* handle = luv_check_pipe(L, 1); + size_t len = 2*PATH_MAX; + char buf[2*PATH_MAX]; + int ret = uv_pipe_getpeername(handle, buf, &len); + if (ret < 0) return luv_error(L, ret); + lua_pushlstring(L, buf, len); + return 1; +} + static int luv_pipe_pending_instances(lua_State* L) { uv_pipe_t* handle = luv_check_pipe(L, 1); int count = luaL_checkinteger(L, 2); diff --git a/tests/test-dns.lua b/tests/test-dns.lua index 2fb9ce92..095f920c 100644 --- a/tests/test-dns.lua +++ b/tests/test-dns.lua @@ -8,6 +8,12 @@ return require('lib/tap')(function (test) end))) end) + test("Get all local http addresses sync", function (print, p, expect, uv) + local res = assert(uv.getaddrinfo(nil, "http")) + p(res, #res) + assert(res[1].port == 80) + end) + test("Get only ipv4 tcp adresses for luvit.io", function (print, p, expect, uv) assert(uv.getaddrinfo("luvit.io", nil, { socktype = "stream", @@ -61,6 +67,15 @@ return require('lib/tap')(function (test) end))) end) + test("Lookup local ipv4 address sync", function (print, p, expect, uv) + local hostname, service = assert(uv.getnameinfo({ + family = "inet", + })) + p{hostname=hostname,service=service} + assert(hostname) + assert(service) + end) + test("Lookup local 127.0.0.1 ipv4 address", function (print, p, expect, uv) assert(uv.getnameinfo({ ip = "127.0.0.1",