aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorosy <osy86@users.noreply.github.com>2020-03-31 15:59:19 -0700
committerosy <osy86@users.noreply.github.com>2020-10-12 16:39:25 -0700
commit9f82a47b81f2864422b82c1e40e51a2ed9c6ac32 (patch)
tree17e6f54a649963fea930e3191dda4b103d9203c5
parent2fc963326df7d39a83ea768416329a27b9fd6e1c (diff)
downloadslirp-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.build10
-rw-r--r--src/slirp.c101
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,