Skip to content

Commit 5ac1766

Browse files
author
osy
committed
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.
1 parent 126c04a commit 5ac1766

2 files changed

Lines changed: 108 additions & 3 deletions

File tree

meson.build

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ if host_system == 'windows'
5050
cc.find_library('ws2_32'),
5151
cc.find_library('iphlpapi')
5252
]
53+
elif host_system == 'darwin'
54+
platform_deps += [
55+
cc.find_library('resolv')
56+
]
5357
endif
5458

5559
cargs = [
@@ -91,7 +95,11 @@ sources = [
9195
]
9296

9397
mapfile = 'src/libslirp.map'
94-
vflag = '-Wl,--version-script,@0@/@1@'.format(meson.current_source_dir(), mapfile)
98+
vflag = []
99+
vflag_test = '-Wl,--version-script,@0@/@1@'.format(meson.current_source_dir(), mapfile)
100+
if cc.has_link_argument(vflag_test)
101+
vflag += vflag_test
102+
endif
95103

96104
configure_file(
97105
input : 'src/libslirp-version.h.in',

src/slirp.c

Lines changed: 99 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ static unsigned dns6_addr_time;
5959
/* for the aging of certain requests like DNS */
6060
#define TIMEOUT_DEFAULT 1000 /* milliseconds */
6161

62-
#ifdef _WIN32
62+
#if defined(_WIN32)
6363

6464
int get_dns_addr(struct in_addr *pdns_addr)
6565
{
@@ -116,7 +116,104 @@ static void winsock_cleanup(void)
116116
WSACleanup();
117117
}
118118

119-
#else
119+
#elif defined(__APPLE__)
120+
121+
#include <resolv.h>
122+
123+
static int get_dns_addr_cached(void *pdns_addr, void *cached_addr,
124+
socklen_t addrlen, unsigned *cached_time)
125+
{
126+
struct stat old_stat;
127+
if (curtime - *cached_time < TIMEOUT_DEFAULT) {
128+
memcpy(pdns_addr, cached_addr, addrlen);
129+
return 0;
130+
}
131+
return 1;
132+
}
133+
134+
static int get_dns_addr_libresolv(int af, void *pdns_addr, void *cached_addr,
135+
socklen_t addrlen, uint32_t *scope_id,
136+
unsigned *cached_time)
137+
{
138+
char buff[512];
139+
struct __res_state state;
140+
union res_sockaddr_union servers[NI_MAXSERV];
141+
int count;
142+
int found;
143+
144+
if (res_ninit(&state) != 0) {
145+
return -1;
146+
}
147+
148+
count = res_getservers(&state, servers, NI_MAXSERV);
149+
found = 0;
150+
DEBUG_MISC("IP address of your DNS(s):");
151+
for (int i = 0; i < count; i++) {
152+
if (af == servers[i].sin.sin_family) {
153+
found++;
154+
}
155+
156+
// we use the first found entry
157+
if (found == 1) {
158+
memcpy(pdns_addr, &servers[i].sin.sin_addr, addrlen);
159+
memcpy(cached_addr, &servers[i].sin.sin_addr, addrlen);
160+
if (scope_id) {
161+
*scope_id = 0;
162+
}
163+
*cached_time = curtime;
164+
}
165+
166+
if (found > 3) {
167+
DEBUG_MISC(" (more)");
168+
break;
169+
} else if (slirp_debug & DBG_MISC) {
170+
char s[INET6_ADDRSTRLEN];
171+
const char *res = inet_ntop(servers[i].sin.sin_family,
172+
&servers[i].sin.sin_addr,
173+
s,
174+
sizeof(s));
175+
if (!res) {
176+
res = " (string conversion error)";
177+
}
178+
DEBUG_MISC(" %s", res);
179+
}
180+
}
181+
182+
res_nclose(&state);
183+
if (!found)
184+
return -1;
185+
return 0;
186+
}
187+
188+
int get_dns_addr(struct in_addr *pdns_addr)
189+
{
190+
if (dns_addr.s_addr != 0) {
191+
int ret;
192+
ret = get_dns_addr_cached(pdns_addr, &dns_addr, sizeof(dns_addr),
193+
&dns_addr_time);
194+
if (ret <= 0) {
195+
return ret;
196+
}
197+
}
198+
return get_dns_addr_libresolv(AF_INET, pdns_addr, &dns_addr,
199+
sizeof(dns_addr), NULL, &dns_addr_time);
200+
}
201+
202+
int get_dns6_addr(struct in6_addr *pdns6_addr, uint32_t *scope_id)
203+
{
204+
if (!in6_zero(&dns6_addr)) {
205+
int ret;
206+
ret = get_dns_addr_cached(pdns6_addr, &dns6_addr, sizeof(dns6_addr),
207+
&dns6_addr_time);
208+
if (ret <= 0) {
209+
return ret;
210+
}
211+
}
212+
return get_dns_addr_libresolv(AF_INET6, pdns6_addr, &dns6_addr,
213+
sizeof(dns6_addr), scope_id, &dns6_addr_time);
214+
}
215+
216+
#else // !defined(_WIN32) && !defined(__APPLE__)
120217

121218
static int get_dns_addr_cached(void *pdns_addr, void *cached_addr,
122219
socklen_t addrlen, struct stat *cached_stat,

0 commit comments

Comments
 (0)