From 467c6a09964df702e5a09ed4112c2475fc9048ea Mon Sep 17 00:00:00 2001 From: Steven Dwy Date: Mon, 16 Mar 2020 05:04:40 -0700 Subject: [PATCH] resolveHost: Check expected address family on returned address The code as is never checks the requested address family when doing a DNS query, so resolving an IPv6 only host with AddressFamily.INET would still return an IPv6. --- source/vibe/core/net.d | 12 ++++-- .../pull-218-resolvehost-dns-address-family.d | 39 +++++++++++++++++++ 2 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 tests/pull-218-resolvehost-dns-address-family.d diff --git a/source/vibe/core/net.d b/source/vibe/core/net.d index c8b2727..8295a0f 100644 --- a/source/vibe/core/net.d +++ b/source/vibe/core/net.d @@ -58,10 +58,14 @@ NetworkAddress resolveHost(string host, ushort address_family, bool use_dns = tr cb => eventDriver.dns.lookupHost(host, cb), (cb, id) => eventDriver.dns.cancelLookup(id), (DNSLookupID, DNSStatus status, scope RefAddress[] addrs) { - if (status == DNSStatus.ok && addrs.length > 0) { - try res = NetworkAddress(addrs[0]); - catch (Exception e) { logDiagnostic("Failed to store address from DNS lookup: %s", e.msg); } - success = true; + if (status == DNSStatus.ok) { + foreach (addr; addrs) { + if (address_family != AddressFamily.UNSPEC && addr.addressFamily != address_family) continue; + try res = NetworkAddress(addr); + catch (Exception e) { logDiagnostic("Failed to store address from DNS lookup: %s", e.msg); } + success = true; + break; + } } } ); diff --git a/tests/pull-218-resolvehost-dns-address-family.d b/tests/pull-218-resolvehost-dns-address-family.d new file mode 100644 index 0000000..7d978fb --- /dev/null +++ b/tests/pull-218-resolvehost-dns-address-family.d @@ -0,0 +1,39 @@ +/+ dub.sdl: + name "test" + dependency "vibe-core" path=".." ++/ +module test; + +import std.socket: AddressFamily; + +import vibe.core.core; +import vibe.core.net; + +void main() +{ + runTask({ + scope(exit) exitEventLoop(); + + auto addr = resolveHost("ip6.me", AddressFamily.INET); + assert(addr.family == AddressFamily.INET); + + addr = resolveHost("ip6.me", AddressFamily.INET6); + assert(addr.family == AddressFamily.INET6); + + try + { + resolveHost("ip4only.me", AddressFamily.INET6); + assert(false); + } + catch(Exception) {} + + try + { + resolveHost("ip6only.me", AddressFamily.INET); + assert(false); + } + catch(Exception) {} + }); + + runEventLoop(); +}