diff options
author | osy <osy86@users.noreply.github.com> | 2020-03-31 15:59:19 -0700 |
---|---|---|
committer | osy <osy86@users.noreply.github.com> | 2020-10-12 16:39:25 -0700 |
commit | 9f82a47b81f2864422b82c1e40e51a2ed9c6ac32 (patch) | |
tree | 17e6f54a649963fea930e3191dda4b103d9203c5 | |
parent | 2fc963326df7d39a83ea768416329a27b9fd6e1c (diff) | |
download | slirp-9f82a47b81f2864422b82c1e40e51a2ed9c6ac32.zip slirp-9f82a47b81f2864422b82c1e40e51a2ed9c6ac32.tar.gz slirp-9f82a47b81f2864422b82c1e40e51a2ed9c6ac32.tar.bz2 |
Add DNS resolving for iOS
iOS does not support reading /etc/resolv.conf so we have to use libresolv
Also modified build script to support building on Darwin systems.
-rw-r--r-- | meson.build | 10 | ||||
-rw-r--r-- | src/slirp.c | 101 |
2 files changed, 108 insertions, 3 deletions
diff --git a/meson.build b/meson.build index 922d602..2d67ae1 100644 --- a/meson.build +++ b/meson.build @@ -54,6 +54,10 @@ if host_system == 'windows' cc.find_library('ws2_32'), cc.find_library('iphlpapi') ] +elif host_system == 'darwin' + platform_deps += [ + cc.find_library('resolv') + ] endif cargs = [ @@ -95,7 +99,11 @@ sources = [ ] mapfile = 'src/libslirp.map' -vflag = '-Wl,--version-script,@0@/@1@'.format(meson.current_source_dir(), mapfile) +vflag = [] +vflag_test = '-Wl,--version-script,@0@/@1@'.format(meson.current_source_dir(), mapfile) +if cc.has_link_argument(vflag_test) + vflag += vflag_test +endif configure_file( input : 'src/libslirp-version.h.in', diff --git a/src/slirp.c b/src/slirp.c index 021324c..9bead0c 100644 --- a/src/slirp.c +++ b/src/slirp.c @@ -64,7 +64,7 @@ static unsigned dns6_addr_time; /* for the aging of certain requests like DNS */ #define TIMEOUT_DEFAULT 1000 /* milliseconds */ -#ifdef _WIN32 +#if defined(_WIN32) int get_dns_addr(struct in_addr *pdns_addr) { @@ -121,7 +121,104 @@ static void winsock_cleanup(void) WSACleanup(); } -#else +#elif defined(__APPLE__) + +#include <resolv.h> + +static int get_dns_addr_cached(void *pdns_addr, void *cached_addr, + socklen_t addrlen, unsigned *cached_time) +{ + struct stat old_stat; + if (curtime - *cached_time < TIMEOUT_DEFAULT) { + memcpy(pdns_addr, cached_addr, addrlen); + return 0; + } + return 1; +} + +static int get_dns_addr_libresolv(int af, void *pdns_addr, void *cached_addr, + socklen_t addrlen, uint32_t *scope_id, + unsigned *cached_time) +{ + char buff[512]; + struct __res_state state; + union res_sockaddr_union servers[NI_MAXSERV]; + int count; + int found; + + if (res_ninit(&state) != 0) { + return -1; + } + + count = res_getservers(&state, servers, NI_MAXSERV); + found = 0; + DEBUG_MISC("IP address of your DNS(s):"); + for (int i = 0; i < count; i++) { + if (af == servers[i].sin.sin_family) { + found++; + } + + // we use the first found entry + if (found == 1) { + memcpy(pdns_addr, &servers[i].sin.sin_addr, addrlen); + memcpy(cached_addr, &servers[i].sin.sin_addr, addrlen); + if (scope_id) { + *scope_id = 0; + } + *cached_time = curtime; + } + + if (found > 3) { + DEBUG_MISC(" (more)"); + break; + } else if (slirp_debug & DBG_MISC) { + char s[INET6_ADDRSTRLEN]; + const char *res = inet_ntop(servers[i].sin.sin_family, + &servers[i].sin.sin_addr, + s, + sizeof(s)); + if (!res) { + res = " (string conversion error)"; + } + DEBUG_MISC(" %s", res); + } + } + + res_nclose(&state); + if (!found) + return -1; + return 0; +} + +int get_dns_addr(struct in_addr *pdns_addr) +{ + if (dns_addr.s_addr != 0) { + int ret; + ret = get_dns_addr_cached(pdns_addr, &dns_addr, sizeof(dns_addr), + &dns_addr_time); + if (ret <= 0) { + return ret; + } + } + return get_dns_addr_libresolv(AF_INET, pdns_addr, &dns_addr, + sizeof(dns_addr), NULL, &dns_addr_time); +} + +int get_dns6_addr(struct in6_addr *pdns6_addr, uint32_t *scope_id) +{ + if (!in6_zero(&dns6_addr)) { + int ret; + ret = get_dns_addr_cached(pdns6_addr, &dns6_addr, sizeof(dns6_addr), + &dns6_addr_time); + if (ret <= 0) { + return ret; + } + } + return get_dns_addr_libresolv(AF_INET6, pdns6_addr, &dns6_addr, + sizeof(dns6_addr), scope_id, &dns6_addr_time); +} + +#else // !defined(_WIN32) && !defined(__APPLE__) static int get_dns_addr_cached(void *pdns_addr, void *cached_addr, socklen_t addrlen, struct stat *cached_stat, |