Commit Diff
Diff:
df41eab0f4452ddb1203cbd167ab64355fb314d7
00c899138bf0acbaa7093b128ad7bdada83cadbe
Commit:
00c899138bf0acbaa7093b128ad7bdada83cadbe
Tree:
95377f51cf6f868c9603716af9e303a71b29575d
Author:
pbug <pbug@delphinusdns.org>
Committer:
pbug <pbug@delphinusdns.org>
Date:
Mon Oct 11 19:47:58 2010 UTC
Message:
* when we receive an IPv6 reply, do check it as well whether it is from the right address, otherwise we may have just gotten lucky that it went through the IPv4 check. tested on OpenBSD
blob - b4fcb42b7d34ab48c564e53d83717d9f1536a843
blob + e89b9e0b437f82c9c84dc65df16d72d9a4876c8c
--- recurse.c
+++ recurse.c
@@ -85,7 +85,7 @@ struct recurseentry {
} *rn1, *rn2, *rnp;
-static const char rcsid[] = "$Id: recurse.c,v 1.29 2010/10/06 10:42:54 pbug Exp $";
+static const char rcsid[] = "$Id: recurse.c,v 1.30 2010/10/11 19:47:58 pbug Exp $";
/*
* INIT_RECURSE - initialize the recurse singly linked list
@@ -225,20 +225,20 @@ recurseloop(int sp, int *raw, DB *db)
{
int sel, ret;
int maxso, len;
- socklen_t slen = sizeof(struct sockaddr);
+ socklen_t slen = sizeof(struct sockaddr_storage);
fd_set rset;
struct timeval tv;
struct srecurseheader rh;
struct domain sd;
struct dns_header *dh;
- struct sockaddr_in sin;
+ struct sockaddr_storage ssin;
+ struct sockaddr_in *sin;
+ struct sockaddr_in6 *sin6;
int type, lzerrno, wildcard = 0;
char fakereplystring[DNS_MAXNAME + 1];
char buf[2048];
-
-
SLIST_INIT(&recurseshead);
@@ -401,7 +401,8 @@ recurseloop(int sp, int *raw, DB *db)
* queried, now we must parse the input
*/
- if ((len = recvfrom(sr1->so, buf, sizeof(buf), 0, (struct sockaddr *)&sin, &slen)) < 0) {
+ slen = sizeof(struct sockaddr_storage);
+ if ((len = recvfrom(sr1->so, buf, sizeof(buf), 0, (struct sockaddr *)&ssin, &slen)) < 0) {
if (errno != EWOULDBLOCK)
syslog(LOG_ERR, "recvfrom: %m");
continue;
@@ -409,9 +410,21 @@ recurseloop(int sp, int *raw, DB *db)
#if 1
/* XXX do some checking of expected IP address */
- if (sin.sin_addr.s_addr != sr1->a[0]) {
- syslog(LOG_ERR, "return address is not from right nameserver");
- continue;
+
+ switch (ssin.ss_family) {
+ case AF_INET:
+ sin = (struct sockaddr_in *)&ssin;
+ if (sin->sin_addr.s_addr != sr1->a[0]) {
+ syslog(LOG_ERR, "return address is not from right nameserver");
+ continue;
+ }
+ case AF_INET6:
+ sin6 = (struct sockaddr_in6*)&ssin;
+ if (memcmp((char *)&sin6->sin6_addr, (char *)&sr1->aaaa[0], sizeof(struct in6_addr)) != 0) {
+
+ syslog(LOG_ERR, "return IPv6 address is not from right nameserver");
+ continue;
+ }
}
#endif
repomaster@centroid.eu