|
|
|
@ -434,10 +434,14 @@ static void read_udp_packets(ares_channel channel, fd_set *read_fds, |
|
|
|
|
unsigned char buf[PACKETSZ + 1]; |
|
|
|
|
#ifdef HAVE_RECVFROM |
|
|
|
|
ares_socklen_t fromlen; |
|
|
|
|
#ifdef HAVE_STRUCT_SOCKADDR_STORAGE |
|
|
|
|
struct sockaddr_storage from; |
|
|
|
|
#else |
|
|
|
|
union { |
|
|
|
|
struct sockaddr_in sa4; |
|
|
|
|
struct sockaddr_in6 sa6; |
|
|
|
|
} from; |
|
|
|
|
#endif |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
if(!read_fds && (read_fd == ARES_SOCKET_BAD)) |
|
|
|
@ -473,10 +477,7 @@ static void read_udp_packets(ares_channel channel, fd_set *read_fds, |
|
|
|
|
* packets as we can. */ |
|
|
|
|
do { |
|
|
|
|
#ifdef HAVE_RECVFROM |
|
|
|
|
if (server->addr.family == AF_INET) |
|
|
|
|
fromlen = sizeof(from.sa4); |
|
|
|
|
else |
|
|
|
|
fromlen = sizeof(from.sa6); |
|
|
|
|
fromlen = sizeof(from); /* doesn't matter if it's larger than needed */ |
|
|
|
|
count = (ssize_t)recvfrom(server->udp_socket, (void *)buf, sizeof(buf), |
|
|
|
|
0, (struct sockaddr *)&from, &fromlen); |
|
|
|
|
#else |
|
|
|
@ -487,7 +488,15 @@ static void read_udp_packets(ares_channel channel, fd_set *read_fds, |
|
|
|
|
else if (count <= 0) |
|
|
|
|
handle_error(channel, i, now); |
|
|
|
|
#ifdef HAVE_RECVFROM |
|
|
|
|
else if (!same_address((struct sockaddr *)&from, &server->addr)) |
|
|
|
|
#ifdef HAVE_STRUCT_SOCKADDR_STORAGE |
|
|
|
|
/* This family hack works around compiler warnings about
|
|
|
|
|
* aliases. |
|
|
|
|
*/ |
|
|
|
|
else if (!((from.ss_family == server->addr.family) && |
|
|
|
|
same_address((struct sockaddr *)&from, &server->addr))) |
|
|
|
|
#else |
|
|
|
|
else if (!same_address((struct sockaddr *)&from, &server->addr))) |
|
|
|
|
#endif |
|
|
|
|
/* The address the response comes from does not match
|
|
|
|
|
* the address we sent the request to. Someone may be |
|
|
|
|
* attempting to perform a cache poisoning attack. */ |
|
|
|
@ -1177,8 +1186,10 @@ static int same_address(struct sockaddr *sa, struct ares_addr *aa) |
|
|
|
|
void *addr1; |
|
|
|
|
void *addr2; |
|
|
|
|
|
|
|
|
|
#ifndef HAVE_STRUCT_SOCKADDR_STORAGE |
|
|
|
|
if (sa->sa_family == aa->family) |
|
|
|
|
{ |
|
|
|
|
#endif |
|
|
|
|
switch (aa->family) |
|
|
|
|
{ |
|
|
|
|
case AF_INET: |
|
|
|
@ -1196,7 +1207,9 @@ static int same_address(struct sockaddr *sa, struct ares_addr *aa) |
|
|
|
|
default: |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
#ifndef HAVE_STRUCT_SOCKADDR_STORAGE |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
return 0; /* different */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|