Commit Diff
Diff:
437140e30abc8e0567763b34594c87b70cbefe50
3553d5f311ff8d924ddbff45b28310969a69917b
Commit:
3553d5f311ff8d924ddbff45b28310969a69917b
Tree:
b1af681e29aaba0171a68fd20a75e749063d6534
Author:
pbug <pbug@delphinusdns.org>
Committer:
pbug <pbug@delphinusdns.org>
Date:
Sun Sep 26 11:08:37 2010 UTC
Message:
* parse ptr responses * expire recurses struct that has lived for more than 10 seconds * catch errors on close() * make query NONBLOCKing now this may catch a problem where we block in recvfrom() possibly * close descriptor if it exists in netlookup() this cleans "zombie" descriptors that haven't seen an answer unfortunately..clobber clobber tested and compiles on OpenBSD
blob - b72280a4d5997d560692cc190a7f0f620203191f
blob + f399b21c518248bcf75986dbd5b8064f4e3075a1
--- recurse.c
+++ recurse.c
@@ -54,6 +54,7 @@ extern void reply_a(struct sreply *, DB *);
extern void reply_aaaa(struct sreply *, DB *);
extern void reply_ns(struct sreply *, DB *);
extern void reply_nxdomain(struct sreply *);
+extern void reply_ptr(struct sreply *);
extern int memcasecmp(u_char *, u_char *, int);
extern int get_soa(DB *, struct question *, struct domain *, int);
extern void reply_noerror(struct sreply *);
@@ -71,7 +72,7 @@ struct recurseentry {
} *rn1, *rn2, *rnp;
-static const char rcsid[] = "$Id: recurse.c,v 1.21 2010/09/25 19:57:56 pbug Exp $";
+static const char rcsid[] = "$Id: recurse.c,v 1.22 2010/09/26 11:08:37 pbug Exp $";
/*
* INIT_RECURSE - initialize the recurse singly linked list
@@ -245,6 +246,23 @@ recurseloop(int sp, int *raw, DB *db)
free(sr1);
}
}
+
+ /*
+ * while we're going through the list to look for
+ * fakesr launches we may as well expire recurses
+ * that have timed out (> 10 seconds)
+ */
+ if (difftime(time(NULL), sr1->received) >= 10) {
+ syslog(LOG_DEBUG, "removing recurses struct");
+ SLIST_REMOVE(&recurseshead, sr1, recurses, entries);
+ if (sr1->so != -1) {
+ if (close(sr1->so) < 0)
+ syslog(LOG_ERR, "close: %m");
+ }
+
+ free_question(sr1->question);
+ free(sr1);
+ }
}
FD_ZERO(&rset);
@@ -356,7 +374,8 @@ recurseloop(int sp, int *raw, DB *db)
*/
if ((len = recvfrom(sr1->so, buf, sizeof(buf), 0, (struct sockaddr *)&sin, &slen)) < 0) {
- syslog(LOG_ERR, "recvfrom: %m");
+ if (errno != EWOULDBLOCK)
+ syslog(LOG_ERR, "recvfrom: %m");
continue;
}
@@ -389,7 +408,9 @@ recurseloop(int sp, int *raw, DB *db)
/* XXX */
- close(sr1->so);
+ if (close(sr1->so) < 0)
+ syslog(LOG_ERR, "close: %m");
+
sr1->so = -1;
if (ntohs(dh->query) & DNS_NAMEERR) {
@@ -1218,8 +1239,29 @@ again:
goto end;
}
-
- if (ntohs(a->type) == DNS_TYPE_NS) {
+ if (ntohs(a->type) == DNS_TYPE_PTR) {
+
+ sdomain.ptr = malloc(cn_len[i]);
+ if (sdomain.ptr == NULL) {
+ syslog(LOG_ERR, "malloc: %m");
+ return (-1);
+ }
+
+ memcpy(sdomain.ptr, converted_name[i], cn_len[i]);
+ sdomain.ptrlen = cn_len[i];
+
+ sdomain.flags |= DOMAIN_HAVE_PTR;
+ sdomain.flags &= ~(DOMAIN_NEGATIVE_CACHE);
+ sdomain.created = time(NULL);
+ sdomain.ttl = ntohl(a->ttl);
+
+ if (! (sdomain.flags & DOMAIN_STATIC_ZONE)) {
+ update_db(db, &sdomain);
+#if 1
+ syslog(LOG_DEBUG, "updateing zone %s with PTR name %s ttl= %u\n", converted_name[i - 1], converted_name[i], sdomain.ttl);
+#endif
+ }
+ } else if (ntohs(a->type) == DNS_TYPE_NS) {
update = 1;
for (j = 0; j < sdomain.ns_count; j++) {
#if 0
@@ -1386,10 +1428,16 @@ netlookup(DB *db, struct recurses *sr)
struct dns_header *dh;
char buf[2048];
+ int flag;
/* do the network stuff then */
/* XXX should be IPv6 ready */
+ if (sr->so != -1) {
+ if (close(sr->so) < 0)
+ syslog(LOG_ERR, "close: %m");
+ }
+
sr->so = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sr->so < 0) {
syslog(LOG_ERR, "socket: %m");
@@ -1414,14 +1462,30 @@ netlookup(DB *db, struct recurses *sr)
if (bind(sr->so, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
syslog(LOG_ERR, "bind: %m");
- close(sr->so);
+ if (close(sr->so) < 0) {
+ syslog(LOG_ERR, "close: %m");
+ }
sr->so = -1;
return (-1);
}
+ /*
+ * make this socket nonblocking
+ */
+
+ if ((flag = fcntl(sr->so, F_GETFL)) < 0) {
+ syslog(LOG_INFO, "fcntl 3: %m");
+ }
+ flag |= O_NONBLOCK;
+ if (fcntl(sr->so, F_SETFL, flag) < 0) {
+ syslog(LOG_INFO, "fcntl 4: %m");
+ }
+
if (lookup_ns(db, sr) <= 0) {
syslog(LOG_ERR, "can't establish any servers to reach for zone \"%s\"", sr->question->converted_name);
- close(sr->so);
+ if (close(sr->so) < 0) {
+ syslog(LOG_ERR, "close: %m");
+ }
sr->so = -1;
return (-1);
}
@@ -1449,7 +1513,9 @@ netlookup(DB *db, struct recurses *sr)
if (sendto(sr->so, buf, sr->len, 0, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
syslog(LOG_ERR, "sendto: %m");
- close(sr->so);
+ if (close(sr->so) < 0) {
+ syslog(LOG_ERR, "close: %m");
+ }
sr->so = -1;
return (-1);
}
@@ -1589,6 +1655,9 @@ reply_raw(DB *db, struct recurses *sr, struct domain *
break;
case DNS_TYPE_NS:
reply_ns(&sreply, db);
+ break;
+ case DNS_TYPE_PTR:
+ reply_ptr(&sreply);
break;
default:
syslog(LOG_ERR, "other types have not been implemented yet");
blob - 01ba91f9c8b4ffc1ddc27e724850614a3b007553
blob + f75e329a8257142b6fca4b7e8f9e398562c84156
--- reply.c
+++ reply.c
@@ -75,7 +75,7 @@ struct collects {
} *cn1, *cn2, *cnp;
-static const char rcsid[] = "$Id: reply.c,v 1.32 2010/09/25 19:31:55 pbug Exp $";
+static const char rcsid[] = "$Id: reply.c,v 1.33 2010/09/26 11:08:37 pbug Exp $";
/*
* REPLY_A() - replies a DNS question (*q) on socket (so)
@@ -1020,7 +1020,10 @@ reply_ptr(struct sreply *sreply)
outlen += (q->hdr->namelen + 4);
SET_DNS_REPLY(odh);
- SET_DNS_AUTHORITATIVE(odh);
+ if (sreply->sr == NULL)
+ SET_DNS_AUTHORITATIVE(odh);
+ else
+ SET_DNS_RECURSION_AVAIL(odh);
HTONS(odh->query);
@@ -1036,7 +1039,10 @@ reply_ptr(struct sreply *sreply)
answer->name[1] = 0x0c;
answer->type = q->hdr->qtype;
answer->class = q->hdr->qclass;
- answer->ttl = htonl(sd->ttl);
+ if (sreply->sr != NULL)
+ answer->ttl = htonl(sd->ttl - (time(NULL) - sd->created));
+ else
+ answer->ttl = htonl(sd->ttl);
outlen += 12; /* up to rdata length */
@@ -1068,26 +1074,30 @@ reply_ptr(struct sreply *sreply)
answer->rdlength = htons(&reply[outlen] - &answer->rdata);
- if (istcp) {
- char *tmpbuf;
- u_int16_t *plen;
+ if (sreply->sr != NULL) {
+ reply_raw2(so, reply, outlen, sreply->sr);
+ } else {
+ if (istcp) {
+ char *tmpbuf;
+ u_int16_t *plen;
- tmpbuf = malloc(outlen + 2);
- if (tmpbuf == NULL) {
- syslog(LOG_INFO, "malloc: %m");
- }
- plen = (u_int16_t *)tmpbuf;
- *plen = htons(outlen);
-
- memcpy(&tmpbuf[2], reply, outlen);
+ tmpbuf = malloc(outlen + 2);
+ if (tmpbuf == NULL) {
+ syslog(LOG_INFO, "malloc: %m");
+ }
+ plen = (u_int16_t *)tmpbuf;
+ *plen = htons(outlen);
+
+ memcpy(&tmpbuf[2], reply, outlen);
- if (send(so, tmpbuf, outlen + 2, 0) < 0) {
- syslog(LOG_INFO, "send: %m");
- }
- free(tmpbuf);
- } else {
- if (sendto(so, reply, outlen, 0, sa, salen) < 0) {
- syslog(LOG_INFO, "sendto: %m");
+ if (send(so, tmpbuf, outlen + 2, 0) < 0) {
+ syslog(LOG_INFO, "send: %m");
+ }
+ free(tmpbuf);
+ } else {
+ if (sendto(so, reply, outlen, 0, sa, salen) < 0) {
+ syslog(LOG_INFO, "sendto: %m");
+ }
}
}
repomaster@centroid.eu