diff options
Diffstat (limited to 'src/slirp.c')
-rw-r--r-- | src/slirp.c | 47 |
1 files changed, 36 insertions, 11 deletions
diff --git a/src/slirp.c b/src/slirp.c index 62a018a..a84d6e4 100644 --- a/src/slirp.c +++ b/src/slirp.c @@ -87,6 +87,8 @@ unsigned curtime; static struct in_addr dns_addr; static struct in6_addr dns6_addr; +static uint16_t dns_port; +static uint16_t dns6_port; static uint32_t dns6_scope_id; static unsigned dns_addr_time; static unsigned dns6_addr_time; @@ -98,7 +100,7 @@ static unsigned dns6_addr_time; #if defined(_WIN32) -int get_dns_addr(struct in_addr *pdns_addr) +int get_dns_addr(struct in_addr *pdns_addr, uint16_t *pdns_port) { FIXED_INFO *FixedInfo = NULL; ULONG BufLen; @@ -134,6 +136,7 @@ int get_dns_addr(struct in_addr *pdns_addr) pIPAddr = &(FixedInfo->DnsServerList); inet_aton(pIPAddr->IpAddress.String, &tmp_addr); *pdns_addr = tmp_addr; + *pdns_port = dns_port = htons(53); // TODO: honor custom port dns_addr = tmp_addr; dns_addr_time = curtime; if (FixedInfo) { @@ -230,16 +233,19 @@ failure: return -1; } -int get_dns6_addr(struct in6_addr *pdns6_addr, uint32_t *scope_id) +int get_dns6_addr(struct in6_addr *pdns6_addr, uint16_t *pdns6_port, + uint32_t *scope_id) { if (!in6_zero(&dns6_addr) && (curtime - dns6_addr_time) < TIMEOUT_DEFAULT) { *pdns6_addr = dns6_addr; + *pdns6_port = dns6_port; *scope_id = dns6_scope_id; return 0; } if (get_ipv6_dns_server(pdns6_addr, scope_id) == 0) { dns6_addr = *pdns6_addr; + *pdns6_port = dns6_port = htons(53); // TODO: honor custom port dns6_addr_time = curtime; dns6_scope_id = *scope_id; return 0; @@ -258,10 +264,13 @@ static void winsock_cleanup(void) #include <resolv.h> static int get_dns_addr_cached(void *pdns_addr, void *cached_addr, - socklen_t addrlen, unsigned *cached_time) + socklen_t addrlen, + uint16_t *pdns_port, uint16_t cached_port, + unsigned *cached_time) { if (curtime - *cached_time < TIMEOUT_DEFAULT) { memcpy(pdns_addr, cached_addr, addrlen); + *pdns_port = cached_port; return 0; } return 1; @@ -269,6 +278,7 @@ static int get_dns_addr_cached(void *pdns_addr, void *cached_addr, static int get_dns_addr_libresolv(int af, void *pdns_addr, void *cached_addr, socklen_t addrlen, + uint16_t *pdns_port, uint16_t *cached_port, uint32_t *scope_id, uint32_t *cached_scope_id, unsigned *cached_time) { @@ -277,6 +287,7 @@ static int get_dns_addr_libresolv(int af, void *pdns_addr, void *cached_addr, int count; int found; void *addr; + uint16_t port; // we only support IPv4 and IPv4, we assume it's one or the other assert(af == AF_INET || af == AF_INET6); @@ -297,14 +308,17 @@ static int get_dns_addr_libresolv(int af, void *pdns_addr, void *cached_addr, if (af == AF_INET) { addr = &servers[i].sin.sin_addr; + port = servers[i].sin.sin_port; } else { // af == AF_INET6 addr = &servers[i].sin6.sin6_addr; + port = servers[i].sin6.sin6_port; } // we use the first found entry if (found == 1) { memcpy(pdns_addr, addr, addrlen); memcpy(cached_addr, addr, addrlen); + *pdns_port = *cached_port = port; if (scope_id) { *scope_id = 0; } @@ -323,7 +337,7 @@ static int get_dns_addr_libresolv(int af, void *pdns_addr, void *cached_addr, if (!res) { res = " (string conversion error)"; } - DEBUG_MISC(" %s", res); + DEBUG_MISC(" %s, port %d", res, ntohs(port)); } } @@ -333,26 +347,29 @@ static int get_dns_addr_libresolv(int af, void *pdns_addr, void *cached_addr, return 0; } -int get_dns_addr(struct in_addr *pdns_addr) +int get_dns_addr(struct in_addr *pdns_addr, uint16_t *pdns_port) { if (dns_addr.s_addr != 0) { int ret; ret = get_dns_addr_cached(pdns_addr, &dns_addr, sizeof(dns_addr), - &dns_addr_time); + pdns_port, dns_port, &dns_addr_time); if (ret <= 0) { return ret; } } return get_dns_addr_libresolv(AF_INET, pdns_addr, &dns_addr, - sizeof(dns_addr), NULL, NULL, &dns_addr_time); + sizeof(dns_addr), + pdns_port, &dns_port, + NULL, NULL, &dns_addr_time); } -int get_dns6_addr(struct in6_addr *pdns6_addr, uint32_t *scope_id) +int get_dns6_addr(struct in6_addr *pdns6_addr, uint16_t *pdns6_port, + 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); + pdns6_port, dns6_port, &dns6_addr_time); if (ret == 0) { *scope_id = dns6_scope_id; } @@ -362,6 +379,7 @@ int get_dns6_addr(struct in6_addr *pdns6_addr, uint32_t *scope_id) } return get_dns_addr_libresolv(AF_INET6, pdns6_addr, &dns6_addr, sizeof(dns6_addr), + pdns6_port, &dns6_port, scope_id, &dns6_scope_id, &dns6_addr_time); } @@ -440,6 +458,7 @@ static bool try_and_setdns_server(int af, unsigned found, unsigned if_index, static int get_dns_addr_resolv_conf(int af, void *pdns_addr, void *cached_addr, socklen_t addrlen, + uint16_t *pdns_port, uint16_t *cached_port, uint32_t *scope_id, uint32_t *cached_scope_id, unsigned *cached_time) { @@ -488,10 +507,13 @@ static int get_dns_addr_resolv_conf(int af, void *pdns_addr, void *cached_addr, cached_scope_id, cached_time); } + if (found) + *pdns_port = *cached_port = htons(53); // TODO: honor custom port + return found ? 0 : -1; } -int get_dns_addr(struct in_addr *pdns_addr) +int get_dns_addr(struct in_addr *pdns_addr, uint16_t *pdns_port) { static struct stat dns_addr_stat; @@ -505,10 +527,12 @@ int get_dns_addr(struct in_addr *pdns_addr) } return get_dns_addr_resolv_conf(AF_INET, pdns_addr, &dns_addr, sizeof(dns_addr), + pdns_port, &dns_port, NULL, NULL, &dns_addr_time); } -int get_dns6_addr(struct in6_addr *pdns6_addr, uint32_t *scope_id) +int get_dns6_addr(struct in6_addr *pdns6_addr, uint16_t *pdns6_port, + uint32_t *scope_id) { static struct stat dns6_addr_stat; @@ -525,6 +549,7 @@ int get_dns6_addr(struct in6_addr *pdns6_addr, uint32_t *scope_id) } return get_dns_addr_resolv_conf(AF_INET6, pdns6_addr, &dns6_addr, sizeof(dns6_addr), + pdns6_port, &dns6_port, scope_id, &dns6_scope_id, &dns6_addr_time); } |