Commit cdf8d836 authored by Simon Morlat's avatar Simon Morlat

dns.c: add v6only disablement for windows

parent 98409c0b
commit 9dd52e29fbaa42fb751e0e542fe435792a93d0f6
Author: Simon Morlat <simon.morlat@linphone.org>
Date: Fri Jan 3 12:04:11 2014 +0100
improve DNS resolver:
- supports IPv6 DNS servers
- supports nameserver lists with both IPv4 and IPv6 servers
diff --git a/src/dns.c b/src/dns.c
index cb5fcfa..167c114 100644
--- a/src/dns.c
+++ b/src/dns.c
@@ -5790,7 +5792,17 @@ int dns_so_submit(struct dns_socket *so, struct dns_packet *Q, struct sockaddr *
if ((error = dns_so_newanswer(so, DNS_SO_MINBUF)))
goto syerr;
- memcpy(&so->remote, host, dns_sa_len(host));
+ if (so->local.ss_family==AF_INET6 && host->sa_family==AF_INET){
+ uint32_t *addr=(uint32_t*)dns_sa_addr(AF_INET6,&so->remote);
+ /* add v4mapping*/
+ so->remote.ss_family=AF_INET6;
+ addr[0]=0;
+ addr[1]=0;
+ addr[2]=ntohl(0xffff);
+ addr[3]=((struct sockaddr_in*)host)->sin_addr.s_addr;
+ *dns_sa_port(AF_INET6,&so->remote)=((struct sockaddr_in*)host)->sin_port;
+
+ }else memcpy(&so->remote, host, dns_sa_len(host));
so->query = Q;
so->qout = 0;
@@ -5916,31 +5928,47 @@ static int dns_so_tcp_recv(struct dns_socket *so) {
#pragma clang diagnostic pop
#endif
+#define USE_CONNECT 0
int dns_so_check(struct dns_socket *so) {
int error;
long n;
+#if !USE_CONNECT
+ struct sockaddr_storage saddr;
+ socklen_t slen=sizeof(saddr);
+#endif
retry:
switch (so->state) {
case DNS_SO_UDP_INIT:
so->state++;
case DNS_SO_UDP_CONN:
+#if USE_CONNECT
if (0 != connect(so->udp, (struct sockaddr *)&so->remote, dns_sa_len(&so->remote)))
goto soerr;
-
+#endif
so->state++;
case DNS_SO_UDP_SEND:
+#if USE_CONNECT
if (0 > (n = send(so->udp, (void *)so->query->data, so->query->end, 0)))
goto soerr;
-
+#else
+ if (0 > (n = sendto(so->udp, (void *)so->query->data, so->query->end, 0, (struct sockaddr *)&so->remote, dns_sa_len(&so->remote))))
+ goto soerr;
+#endif
so->stat.udp.sent.bytes += n;
so->stat.udp.sent.count++;
so->state++;
case DNS_SO_UDP_RECV:
+#if USE_CONNECT
if (0 > (n = recv(so->udp, (void *)so->answer->data, so->answer->size, 0)))
goto soerr;
+#else
+ if (0 > (n = recvfrom(so->udp, (void *)so->answer->data, so->answer->size, 0, (struct sockaddr*)&saddr,&slen)))
+ goto soerr;
+ /*TODO check if saddr matches one of the DNS server we previously sent a question, for security*/
+#endif
so->stat.udp.rcvd.bytes += n;
so->stat.udp.rcvd.count++;
@@ -6609,7 +6637,7 @@ static int dns_res_exec(struct dns_resolver *R) {
char host[DNS_D_MAXNAME + 1];
size_t len;
struct dns_rr rr;
- struct sockaddr_in sin;
+ struct sockaddr_storage saddr={0};
int error;
struct dns_rr_i dns_rr_it;
int dns_grep_error;
@@ -6882,7 +6910,7 @@ exec:
goto error;
F->hints_j.name = host;
- F->hints_j.type = DNS_T_A;
+ F->hints_j.type = DNS_T_ALL;
F->hints_j.section = DNS_S_ALL & ~DNS_S_QD;
if (!dns_rr_grep(&rr, 1, &F->hints_j, F->hints, &error)) {
@@ -6892,23 +6920,28 @@ exec:
goto(R->sp, DNS_R_FOREACH_NS);
}
- sin.sin_family = AF_INET;
+ saddr.ss_family = rr.type==DNS_T_AAAA ? AF_INET6 : AF_INET;
- if ((error = dns_a_parse((struct dns_a *)&sin.sin_addr, &rr, F->hints)))
- goto error;
+ if (saddr.ss_family==AF_INET){
+ if ((error = dns_a_parse((struct dns_a *)dns_sa_addr(saddr.ss_family, &saddr), &rr, F->hints)))
+ goto error;
+ }else{
+ if ((error = dns_aaaa_parse((struct dns_aaaa *)dns_sa_addr(saddr.ss_family, &saddr), &rr, F->hints)))
+ goto error;
+ }
- if (R->sp == 0)
- sin.sin_port = dns_hints_port(R->hints, AF_INET, (struct sockaddr *)&sin.sin_addr);
- else
- sin.sin_port = htons(53);
+ *dns_sa_port(saddr.ss_family, &saddr) = (R->sp == 0) ? dns_hints_port(R->hints, saddr.ss_family, (struct sockaddr *)&saddr) : htons(53);
+
if (DNS_DEBUG) {
char addr[INET_ADDRSTRLEN + 1];
- dns_a_print(addr, sizeof addr, (struct dns_a *)&sin.sin_addr);
+ if (saddr.ss_family==AF_INET)
+ dns_a_print(addr, sizeof addr, (struct dns_a *)dns_sa_addr(saddr.ss_family, &saddr));
+ else dns_aaaa_print(addr, sizeof addr, (struct dns_aaaa *)dns_sa_addr(saddr.ss_family, &saddr));
DNS_SHOW(F->query, "ASKING: %s/%s @ DEPTH: %u)", host, addr, R->sp);
}
- if ((error = dns_so_submit(&R->so, F->query, (struct sockaddr *)&sin)))
+ if ((error = dns_so_submit(&R->so, F->query, (struct sockaddr *)&saddr)))
goto error;
F->state++;
commit 6ac8aa90db64a37e6c783da005ba513c6077c23d
Author: Simon Morlat <simon.morlat@linphone.org>
Date: Fri Jan 30 10:08:45 2015 +0100
fix ipv6 resolver test on windows
diff --git a/src/dns.c b/src/dns.c
index 317e8e0..b778aa4 100644
--- a/src/dns.c
+++ b/src/dns.c
@@ -79,6 +79,11 @@
#include <iphlpapi.h>
#pragma comment(lib, "IPHLPAPI.lib")
#endif
+
+#ifndef IPV6_V6ONLY
+#define IPV6_V6ONLY 27
+#endif
+
#else
#include <sys/types.h> /* FD_SETSIZE socklen_t */
#include <sys/select.h> /* FD_ZERO FD_SET fd_set select(2) */
@@ -5709,7 +5714,8 @@ static void dns_so_destroy(struct dns_socket *);
static struct dns_socket *dns_so_init(struct dns_socket *so, const struct sockaddr *local, int type, const struct dns_options *opts, int *error) {
static struct dns_socket so_initializer;
static DNSBool initialized = 0;
-
+ int value=0;
+
if (!initialized) {
memset(&so_initializer, 0, sizeof so_initializer);
so_initializer.opts.closefd.arg = 0;
@@ -5731,7 +5737,8 @@ static struct dns_socket *dns_so_init(struct dns_socket *so, const struct sockad
if (-1 == (so->udp = dns_socket((struct sockaddr *)&so->local, SOCK_DGRAM, error)))
goto error;
-
+ value=0;
+ setsockopt(so->udp, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&value, sizeof(value));
dns_k_permutor_init(&so->qids, 1, 65535);
return so;
commit 978db14caa4c7b5a3ca2db64a7aceb2bdd251773
Author: Simon Morlat <simon.morlat@linphone.org>
Date: Tue May 17 16:04:32 2016 +0200
allow to iterate through the dns server list in case of network error while dialoging with one server.
diff --git a/src/dns.c b/src/dns.c
index 6dba2c2..634e00b 100644
--- a/src/dns.c
+++ b/src/dns.c
@@ -278,6 +278,8 @@ int dns_v_api(void) {
#define DNS_EALREADY WSAEALREADY
#define DNS_EAGAIN EAGAIN
#define DNS_ETIMEDOUT WSAETIMEDOUT
+#define DNS_ECONNREFUSED WSAECONNREFUSED
+#define DNS_ENETUNREACH WSAENETUNREACH
#define dns_syerr() ((int)GetLastError())
#define dns_soerr() ((int)WSAGetLastError())
@@ -291,6 +293,8 @@ int dns_v_api(void) {
#define DNS_EALREADY EALREADY
#define DNS_EAGAIN EAGAIN
#define DNS_ETIMEDOUT ETIMEDOUT
+#define DNS_ECONNREFUSED ECONNREFUSED
+#define DNS_ENETUNREACH ENETUNREACH
#define dns_syerr() errno
#define dns_soerr() errno
@@ -5595,6 +5599,10 @@ static int dns_socket(struct sockaddr *local, int type, int *error_) {
goto soerr;
}
#endif
+ if (local->sa_family == AF_INET6){
+ int value=0;
+ setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&value, sizeof(value));
+ }
if (local->sa_family != AF_INET && local->sa_family != AF_INET6)
return fd;
@@ -5746,7 +5754,6 @@ static void dns_so_destroy(struct dns_socket *);
static struct dns_socket *dns_so_init(struct dns_socket *so, const struct sockaddr *local, int type, const struct dns_options *opts, int *error) {
static struct dns_socket so_initializer;
static DNSBool initialized = 0;
- int value=0;
if (!initialized) {
memset(&so_initializer, 0, sizeof so_initializer);
@@ -5769,8 +5776,7 @@ static struct dns_socket *dns_so_init(struct dns_socket *so, const struct sockad
if (-1 == (so->udp = dns_socket((struct sockaddr *)&so->local, SOCK_DGRAM, error)))
goto error;
- value=0;
- setsockopt(so->udp, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&value, sizeof(value));
+
dns_k_permutor_init(&so->qids, 1, 65535);
return so;
@@ -7026,8 +7032,11 @@ exec:
if (dns_so_elapsed(&R->so) >= (time_t)R->resconf->options.timeout)
goto(R->sp, DNS_R_FOREACH_A);
- if ((error = dns_so_check(&R->so)))
- goto error;
+ if ((error = dns_so_check(&R->so))){
+ if (error == DNS_ENETUNREACH || error == DNS_ECONNREFUSED){
+ goto(R->sp, DNS_R_FOREACH_A);
+ }else goto error;
+ }
free(F->answer);
......@@ -6249,6 +6249,11 @@ static int dns_socket(struct sockaddr *local, int type, int *error_) {
#endif
if (-1 == (fd = socket(local->sa_family, type|flags, 0)))
goto soerr;
if (local->sa_family == AF_INET6){
int value=0;
setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&value, sizeof(value));
}
#if defined F_SETFD && !HAVE_SOCK_CLOEXEC
if (-1 == fcntl(fd, F_SETFD, 1))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment