Commit Diff
Diff:
fe3d3220bb9078aa22b0b439a6770036643baf96
5528a18e8f06ca7c0c89b23b2e2d57778e70f263
Commit:
5528a18e8f06ca7c0c89b23b2e2d57778e70f263
Tree:
04dbe6dfa4c97be773ed89876a2490c5e07d7515
Author:
pbug <pbug@delphinusdns.org>
Committer:
pbug <pbug@delphinusdns.org>
Date:
Tue Sep 21 19:04:43 2010 UTC
Message:
* FreeBSD compatibility in recurse code * fakerecurse() now checks to see if there is other fakerecurse requests for the same name and returns if there is so * when a record is cached do some math to show the remaining cache ttl * fix a divide by zero bug (which btw saved gtld-servers.net from a flood for a few minutes, which should be fixed with this commit) Compiles on FreeBSD and OpenBSD, tested on FreeBSD
blob - 9edb4c575b8d4f7d01e65e490fb33454e9021877
blob + c753a37514181072494e7dca0f99034f1be1214c
--- db.h
+++ db.h
@@ -136,6 +136,7 @@ struct recurses {
int len; /* length of query */
int isfake; /* received or faked */
+ int launched; /* is launched */
int replied; /* we replied to this question */
int af; /* address family */
int proto; /* protocol UDP/TCP */
@@ -166,7 +167,7 @@ struct recurses {
struct question *question; /* question struct */
SLIST_ENTRY(recurses) entries;
struct recurses *callback; /* callback */
-} *sr, *sr1;
+} *sr, *sr1, *sr2;
int parse_file(DB *db, char *);
blob - ec2a2521adf94315bb1ef9dd1c6561a3d042f3fd
blob + 16e9ae6df35a19d37b7dcee316927be9ac4cf3bb
--- recurse.c
+++ recurse.c
@@ -49,6 +49,7 @@ int fakerecurse(DB *db, struct recurses *sr, struct ns
void reply_raw(DB *db, struct recurses *sr, struct domain *sd, int *raw);
extern void build_reply(struct sreply *reply, int so, char *buf, int len, struct question *q, struct sockaddr *sa, socklen_t slen, struct domain *sd1, struct domain *sd2, u_int8_t region, int istcp, int wildcard, struct recurses *sr);
extern void reply_a(struct sreply *, DB *);
+extern int memcasecmp(u_char *, u_char *, int);
void remove_zone(DB *db, struct domain *sd);
SLIST_HEAD(listhead, recurseentry) recursehead;
@@ -63,7 +64,7 @@ struct recurseentry {
} *rn1, *rn2, *rnp;
-static const char rcsid[] = "$Id: recurse.c,v 1.12 2010/09/21 18:58:06 pbug Exp $";
+static const char rcsid[] = "$Id: recurse.c,v 1.13 2010/09/21 19:04:43 pbug Exp $";
/*
* INIT_RECURSE - initialize the recurse singly linked list
@@ -220,6 +221,23 @@ recurseloop(int sp, int *raw, DB *db)
SLIST_INIT(&recurseshead);
for (;;) {
+ /*
+ * launch all fakesr requests
+ */
+ SLIST_FOREACH(sr1, &recurseshead, entries) {
+ if (sr1->isfake && !sr1->launched) {
+ syslog(LOG_DEBUG, "launching question (fakesr) for %s", sr1->question->hdr->name);
+ sr1->launched = 1;
+ type = lookup_zone(db, sr1->question, &sd, &lzerrno, (char *)fakereplystring, wildcard);
+ if (type < 0) {
+ netlookup(db, sr1);
+ } else {
+ sr1->callback->hascallback--;
+ free_question(sr1->question);
+ free(sr1);
+ }
+ }
+ }
FD_ZERO(&rset);
maxso = sp;
@@ -561,7 +579,11 @@ again:
sr->a_count++;
}
- sd->ns_ptr = (sd->ns_ptr + 1) % sd->ns_count;
+ if (sd->ns_count)
+ sd->ns_ptr = (sd->ns_ptr + 1) % sd->ns_count;
+ else
+ sd->ns_ptr = 0;
+
update_db(db, sd);
break;
@@ -570,7 +592,7 @@ again:
} while (*p != 0 && ret != 0);
#if 1
- syslog(LOG_DEBUG, "got %d addresses for %s, indicator %d\n", sr->a_count, sr->question->converted_name, sr->indicator);
+ syslog(LOG_DEBUG, "got %d addresses for %s, indicator %d\n", sr->a_count, sr->question->hdr->name, sr->indicator);
#endif
@@ -632,6 +654,7 @@ lookup_a(DB *db, struct recurses *sr, struct ns *ns)
}
if (! found) {
+ syslog(LOG_DEBUG, "calling fakerecurse, sleeping 1 second for debug");
fakerecurse(db, sr, ns);
return (-1);
}
@@ -1284,16 +1307,22 @@ fakerecurse(DB *db, struct recurses *sr, struct ns *ns
{
struct recurses *fakesr;
struct dns_header *dh;
- struct domain sd;
char *p;
- char fakereplystring[DNS_MAXNAME + 1];
int len;
u_int16_t *qtype, *qclass;
- int type, lzerrno, wildcard = 0;
+ /* check if we have already started a fakerecurse on the same name */
+ SLIST_FOREACH(sr2, &recurseshead, entries) {
+ if (memcasecmp((u_char *)ns->nsserver, (u_char *)sr2->question->hdr->name, ns->nslen) == 0) {
+ syslog(LOG_INFO, "already have a fakerecurse structure with name %s, drop\n", ns->nsserver);
+ return (-1);
+ }
+ }
+
+
/* place request on struct recurses linked list */
fakesr = calloc(sizeof(struct recurses), 1);
@@ -1310,6 +1339,7 @@ fakerecurse(DB *db, struct recurses *sr, struct ns *ns
sr->hascallback++;
fakesr->hascallback = 0;
fakesr->isfake = 1;
+ fakesr->launched = 0;
fakesr->received = time(NULL);
fakesr->question = build_fake_question(ns->nsserver, ns->nslen, htons(DNS_TYPE_A));
@@ -1342,17 +1372,6 @@ fakerecurse(DB *db, struct recurses *sr, struct ns *ns
len += sizeof(u_int16_t);
fakesr->len = len;
-
- type = lookup_zone(db, fakesr->question, &sd, &lzerrno, (char *)fakereplystring, wildcard);
- if (type < 0) {
- if (netlookup(db, fakesr) < 0)
- return (-1);
- } else {
- sr->hascallback--;
- free_question(fakesr->question);
- free(fakesr);
- return (0);
- }
SLIST_INSERT_HEAD(&recurseshead, fakesr, entries);
blob - 32d282454c1bbc198be674e7b6dfa42d5863bd9f
blob + 95fe9622fd57234347979f0ce5f95b9b7282f98a
--- reply.c
+++ reply.c
@@ -70,7 +70,7 @@ struct collects {
} *cn1, *cn2, *cnp;
-static const char rcsid[] = "$Id: reply.c,v 1.26 2010/09/19 17:53:52 pbug Exp $";
+static const char rcsid[] = "$Id: reply.c,v 1.27 2010/09/21 19:04:43 pbug Exp $";
/*
* REPLY_A() - replies a DNS question (*q) on socket (so)
@@ -165,7 +165,10 @@ reply_a(struct sreply *sreply, DB *db)
answer->name[1] = 0x0c; /* 2 bytes */
answer->type = q->hdr->qtype; /* 4 bytes */
answer->class = q->hdr->qclass; /* 6 bytes */
- answer->ttl = htonl(sd->ttl); /* 10 bytes */
+ if (sreply->sr != NULL)
+ answer->ttl = htonl(sd->ttl - (time(NULL) - sd->created));
+ else
+ answer->ttl = htonl(sd->ttl); /* 10 bytes */
answer->rdlength = htons(sizeof(in_addr_t)); /* 12 bytes */
@@ -194,7 +197,6 @@ reply_a(struct sreply *sreply, DB *db)
out:
if (sreply->sr != NULL) {
- syslog(LOG_DEBUG, "raw replying has not been implemented yet");
reply_raw2(so, reply, outlen, sreply->sr);
} else {
if (istcp) {
@@ -2098,11 +2100,19 @@ reply_raw2(int so, char *reply, int outlen, struct rec
ip->ip_tos = 0;
+#ifdef __OpenBSD__
ip->ip_len = htons(udplen + sizeof(struct ip));
+#else
+ ip->ip_len = udplen + sizeof(struct ip);
+#endif
ip->ip_id = arc4random();
+#ifdef __OpenBSD__
ip->ip_off = htons(IP_DF);
+#else
+ ip->ip_off = IP_DF;
+#endif
ip->ip_ttl = 64;
ip->ip_p = IPPROTO_UDP;
repomaster@centroid.eu