From f367ee5260f2af27989c470f77fd812089e76efc Mon Sep 17 00:00:00 2001 From: Oldes Date: Sun, 24 May 2020 10:52:25 +0200 Subject: [PATCH] FEAT: it's again possible to `read dns://` to resolve a hostname ``` >> read dns:// == "Oldes-Aero" ``` It also fixes a bug introduce in https://github.com/rebol/rebol/pull/66, that resolving domain name from ip was not possible at all. Now it's again working properly: ``` >> read dns://rebol.com == 162.216.18.225 >> read dns://162.216.18.225 == "rebol.com" ``` Related to: https://github.com/Oldes/Rebol-issues/issues/1935 --- src/core/p-dns.c | 17 +++++++++++++---- src/os/dev-dns.c | 34 +++++++++++++++++++++++++++------- src/tests/units/port-test.r3 | 11 +++++++++++ 3 files changed, 51 insertions(+), 11 deletions(-) diff --git a/src/core/p-dns.c b/src/core/p-dns.c index 1231de68bc..584dc06d69 100644 --- a/src/core/p-dns.c +++ b/src/core/p-dns.c @@ -65,13 +65,22 @@ } arg = Obj_Value(spec, STD_PORT_SPEC_NET_HOST); - - if (IS_TUPLE(arg) && Scan_Tuple(VAL_BIN(arg), (REBCNT)LEN_BYTES(VAL_BIN(arg)), &tmp)) { + if (IS_NONE(arg)) { + // case: read dns:// + sock->data = NULL; + } + else if (IS_TUPLE(arg)) { SET_FLAG(sock->modes, RST_REVERSE); - memcpy(&sock->net.remote_ip, VAL_TUPLE(&tmp), 4); + memcpy(&sock->net.remote_ip, VAL_TUPLE(arg), 4); } else if (IS_STRING(arg)) { - sock->data = VAL_BIN(arg); + if (Scan_Tuple(VAL_BIN(arg), (REBCNT)LEN_BYTES(VAL_BIN(arg)), &tmp)) { + SET_FLAG(sock->modes, RST_REVERSE); + memcpy(&sock->net.remote_ip, VAL_TUPLE(&tmp), 4); + } + else { + sock->data = VAL_BIN(arg); + } } else Trap_Port(RE_INVALID_SPEC, port, -10); diff --git a/src/os/dev-dns.c b/src/os/dev-dns.c index 50a64d9407..b5c9fd0a85 100644 --- a/src/os/dev-dns.c +++ b/src/os/dev-dns.c @@ -106,11 +106,24 @@ extern HWND Event_Handle; #endif host = OS_Make(MAXGETHOSTSTRUCT); // be sure to free it + sock->net.host_info = host; // stores allocated buffer, deallocated on close or on error #ifdef HAS_ASYNC_DNS - if (!GET_FLAG(sock->modes, RST_REVERSE)) // hostname lookup - handle = WSAAsyncGetHostByName(Event_Handle, WM_DNS, sock->data, host, MAXGETHOSTSTRUCT); - else + // WINDOWS version + if (!GET_FLAG(sock->modes, RST_REVERSE)) {// hostname lookup + if (sock->data == NULL) { + DWORD dwSize = MAXGETHOSTSTRUCT; + if (GetComputerNameExA(ComputerNameDnsFullyQualified, host, &dwSize)) { + ((REBYTE*)host)[dwSize] = 0; + sock->data = host; + SET_FLAG(sock->modes, RST_REVERSE); + SET_FLAG(sock->flags, RRF_DONE); + return DR_DONE; + } + goto error; + } + handle = WSAAsyncGetHostByName(Event_Handle, WM_DNS, cs_cast(sock->data), host, MAXGETHOSTSTRUCT); + } else handle = WSAAsyncGetHostByAddr(Event_Handle, WM_DNS, (char*)&(sock->net.remote_ip), 4, AF_INET, host, MAXGETHOSTSTRUCT); if (handle != 0) { @@ -119,27 +132,34 @@ extern HWND Event_Handle; return DR_PEND; // keep it on pending list } #else + // POSIX version // Use old-style blocking DNS (mainly for testing purposes): if (GET_FLAG(sock->modes, RST_REVERSE)) { he = gethostbyaddr((char*)&sock->net.remote_ip, 4, AF_INET); if (he) { - sock->net.host_info = host; //??? sock->data = he->h_name; SET_FLAG(sock->flags, RRF_DONE); return DR_DONE; } } + else if (sock->data == NULL) { + if(0 == gethostname(host, MAXGETHOSTSTRUCT)) { + sock->data = host; + SET_FLAG(sock->modes, RST_REVERSE); + SET_FLAG(sock->flags, RRF_DONE); + return DR_DONE; + } + } else { he = gethostbyname(sock->data); if (he) { - sock->net.host_info = host; // ?? who deallocs? COPY_MEM((char*)&(sock->net.remote_ip), (char *)(*he->h_addr_list), 4); //he->h_length); SET_FLAG(sock->flags, RRF_DONE); return DR_DONE; } } #endif - +error: OS_Free(host); sock->net.host_info = 0; @@ -178,7 +198,7 @@ extern HWND Event_Handle; if (!req->error) { // success! host = (HOSTENT*)req->net.host_info; if (GET_FLAG(req->modes, RST_REVERSE)) - req->data = host->h_name; + req->data = (REBYTE*)host->h_name; else COPY_MEM((char*)&(req->net.remote_ip), (char *)(*host->h_addr_list), 4); //he->h_length); Signal_Device(req, EVT_READ); diff --git a/src/tests/units/port-test.r3 b/src/tests/units/port-test.r3 index f1968f4837..f7b8255e08 100644 --- a/src/tests/units/port-test.r3 +++ b/src/tests/units/port-test.r3 @@ -130,4 +130,15 @@ if "true" <> get-env "CONTINUOUS_INTEGRATION" [ ===end-group=== ] + +===start-group=== "DNS" +;@@ https://github.com/Oldes/Rebol-issues/issues/1935 + --test-- "read dns://" + --assert string? try [probe read dns://] ;- no crash! + --test-- "read dns://8.8.8.8" + --assert "dns.google" = try [probe read dns://8.8.8.8] + --test-- "read dns://google.com" + --assert tuple? try [read dns://google.com] +===end-group=== + ~~~end-file~~~ \ No newline at end of file