summaryrefslogtreecommitdiffstats
path: root/libc/netbsd/net/getaddrinfo.c
diff options
context:
space:
mode:
Diffstat (limited to 'libc/netbsd/net/getaddrinfo.c')
-rw-r--r--libc/netbsd/net/getaddrinfo.c42
1 files changed, 27 insertions, 15 deletions
diff --git a/libc/netbsd/net/getaddrinfo.c b/libc/netbsd/net/getaddrinfo.c
index 401bc6e..937c423 100644
--- a/libc/netbsd/net/getaddrinfo.c
+++ b/libc/netbsd/net/getaddrinfo.c
@@ -93,6 +93,7 @@
#include <errno.h>
#include <netdb.h>
#include "resolv_private.h"
+#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
@@ -214,7 +215,7 @@ struct res_target {
static int str2number(const char *);
static int explore_fqdn(const struct addrinfo *, const char *,
- const char *, struct addrinfo **, const char *iface);
+ const char *, struct addrinfo **, const char *iface, int mark);
static int explore_null(const struct addrinfo *,
const char *, struct addrinfo **);
static int explore_numeric(const struct addrinfo *, const char *,
@@ -577,12 +578,12 @@ int
getaddrinfo(const char *hostname, const char *servname,
const struct addrinfo *hints, struct addrinfo **res)
{
- return android_getaddrinfoforiface(hostname, servname, hints, NULL, res);
+ return android_getaddrinfoforiface(hostname, servname, hints, NULL, 0, res);
}
int
android_getaddrinfoforiface(const char *hostname, const char *servname,
- const struct addrinfo *hints, const char *iface, struct addrinfo **res)
+ const struct addrinfo *hints, const char *iface, int mark, struct addrinfo **res)
{
struct addrinfo sentinel;
struct addrinfo *cur;
@@ -761,7 +762,7 @@ android_getaddrinfoforiface(const char *hostname, const char *servname,
pai->ai_protocol = ex->e_protocol;
error = explore_fqdn(pai, hostname, servname,
- &cur->ai_next, iface);
+ &cur->ai_next, iface, mark);
while (cur && cur->ai_next)
cur = cur->ai_next;
@@ -794,7 +795,7 @@ android_getaddrinfoforiface(const char *hostname, const char *servname,
*/
static int
explore_fqdn(const struct addrinfo *pai, const char *hostname,
- const char *servname, struct addrinfo **res, const char *iface)
+ const char *servname, struct addrinfo **res, const char *iface, int mark)
{
struct addrinfo *result;
struct addrinfo *cur;
@@ -820,7 +821,7 @@ explore_fqdn(const struct addrinfo *pai, const char *hostname,
return 0;
switch (nsdispatch(&result, dtab, NSDB_HOSTS, "getaddrinfo",
- default_dns_files, hostname, pai, iface)) {
+ default_dns_files, hostname, pai, iface, mark)) {
case NS_TRYAGAIN:
error = EAI_AGAIN;
goto free;
@@ -1864,17 +1865,19 @@ error:
free(elems);
}
-static int _using_alt_dns()
+static bool _using_default_dns(const char *iface)
{
- char propname[PROP_NAME_MAX];
- char propvalue[PROP_VALUE_MAX];
+ char buf[IF_NAMESIZE+1];
+ size_t if_len;
- propvalue[0] = 0;
- snprintf(propname, sizeof(propname), "net.dns1.%d", getpid());
- if (__system_property_get(propname, propvalue) > 0 ) {
- return 1;
+ // common case
+ if (iface == NULL || *iface == '\0') return true;
+
+ if_len = _resolv_get_default_iface(buf, sizeof(buf));
+ if (if_len != 0 && if_len + 1 <= sizeof(buf)) {
+ if (strcmp(buf, iface) == 0) return true;
}
- return 0;
+ return false;
}
/*ARGSUSED*/
@@ -1889,10 +1892,12 @@ _dns_getaddrinfo(void *rv, void *cb_data, va_list ap)
struct res_target q, q2;
res_state res;
const char* iface;
+ int mark;
name = va_arg(ap, char *);
pai = va_arg(ap, const struct addrinfo *);
iface = va_arg(ap, char *);
+ mark = va_arg(ap, int);
//fprintf(stderr, "_dns_getaddrinfo() name = '%s'\n", name);
memset(&q, 0, sizeof(q));
@@ -1924,7 +1929,7 @@ _dns_getaddrinfo(void *rv, void *cb_data, va_list ap)
// Only implement AI_ADDRCONFIG if the application is not
// using its own DNS servers, since our implementation
// only works on the default connection.
- if (!_using_alt_dns()) {
+ if (_using_default_dns(iface)) {
query_ipv6 = _have_ipv6();
query_ipv4 = _have_ipv4();
}
@@ -1980,6 +1985,7 @@ _dns_getaddrinfo(void *rv, void *cb_data, va_list ap)
* and have a cache hit that would be wasted, so we do the rest there on miss
*/
res_setiface(res, iface);
+ res_setmark(res, mark);
if (res_searchN(name, &q, res) < 0) {
__res_put_state(res);
free(buf);
@@ -2310,6 +2316,12 @@ res_searchN(const char *name, struct res_target *target, res_state res)
(dots && !trailing_dot && (res->options & RES_DNSRCH))) {
int done = 0;
+ /* Unfortunately we need to set stuff up before
+ * the domain stuff is tried. Will have a better
+ * fix after thread pools are used.
+ */
+ _resolv_populate_res_for_iface(res);
+
for (domain = (const char * const *)res->dnsrch;
*domain && !done;
domain++) {