Commit Diff
Diff:
c8a9dee0e821a85320109a74c60bfc71e3a23eb1
2289373656246b96b5fa24d736fa083e6b5fa7cb
Commit:
2289373656246b96b5fa24d736fa083e6b5fa7cb
Tree:
96914a7bf76650d3ece1624a51596d13d65248e3
Author:
pbug <pbug@delphinusdns.org>
Committer:
pbug <pbug@delphinusdns.org>
Date:
Sun Sep 19 11:39:38 2010 UTC
Message:
* shuffle some functions around to make it easier to reply to a raw socket
blob - d127bf26deeddbe13e9cd6821e3e143c538f83b3
blob + 9edb4c575b8d4f7d01e65e490fb33454e9021877
--- db.h
+++ db.h
@@ -116,6 +116,7 @@ struct sreply {
u_int8_t region; /* region of question */
int istcp; /* when set it's tcp */
int wildcard; /* wildcarding boolean */
+ struct recurses *sr; /* recurses struct for raw sockets */
};
struct srecurseheader {
@@ -126,6 +127,46 @@ struct srecurseheader {
int len; /* length of question */
char buf[512]; /* question buffer */
};
+
+
+SLIST_HEAD(listhead2, recurses) recurseshead;
+
+struct recurses {
+ char query[512]; /* the query we received */
+ int len; /* length of query */
+
+ int isfake; /* received or faked */
+ int replied; /* we replied to this question */
+ int af; /* address family */
+ int proto; /* protocol UDP/TCP */
+ struct sockaddr_storage source; /* source + port */
+ struct sockaddr_storage dest; /* dest + port */
+
+ time_t received; /* received request time */
+ time_t sent_last_query; /* the last time we did a lookup */
+
+ char upperlower[32]; /* uppercase / lowercase bitmap */
+ int so; /* the socket we did a lookup with */
+ u_short port; /* port used on outgoing */
+ u_int16_t id; /* last id used */
+
+ /* the below get loaded from the database upon each lookup */
+ in_addr_t a[RECORD_COUNT]; /* IPv4 addresses of nameservers */
+ int a_count; /* IPv4 address count */
+ int a_ptr; /* pointer to last used address */
+ struct in6_addr aaaa[RECORD_COUNT]; /* IPv6 addresses of nameservers */
+ int aaaa_count; /* IPv6 address count */
+ int aaaa_ptr; /* pointer to last used IPv6 address */
+
+ /* the below is our indicator which part of the lookup we're at */
+
+ int indicator; /* indicator of ns lookup */
+ int hascallback; /* some request has callback don't remove */
+
+ struct question *question; /* question struct */
+ SLIST_ENTRY(recurses) entries;
+ struct recurses *callback; /* callback */
+} *sr, *sr1;
int parse_file(DB *db, char *);
blob - 549579a0fb7128c7a3fd6755d760b6f0d7453a19
blob + 23214233a687b24f0d7f3918ad9e3ae5bc30ba3c
--- main.c
+++ main.c
@@ -62,7 +62,7 @@ char * dns_label(char *, int *);
int compress_label(u_char *, u_int16_t, int);
int memcasecmp(u_char *, u_char *, int);
char * get_dns_type(int dnstype);
-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);
+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);
void recurseheader(struct srecurseheader *, int, struct sockaddr_storage *, struct sockaddr_storage *, int);
/* aliases */
@@ -112,7 +112,7 @@ struct tcps {
} *tn1, *tn2, *tnp;
-static const char rcsid[] = "$Id: main.c,v 1.54 2010/08/27 19:35:31 pbug Exp $";
+static const char rcsid[] = "$Id: main.c,v 1.55 2010/09/19 11:39:38 pbug Exp $";
/*
* MAIN - set up arguments, set up database, set up sockets, call mainloop
@@ -1803,7 +1803,7 @@ mainloop(int *udp, int *tcp, int sockcount, char **ide
/* format error */
build_reply( &sreply, tnp->so, pbuf, len, NULL,
from, fromlen, NULL, NULL, tnp->region,
- istcp, tnp->wildcard);
+ istcp, tnp->wildcard, NULL);
reply_fmterror(&sreply);
syslog(LOG_INFO, "TCP question on descriptor %d interface \"%s\" from %s, did not have question of 1 replying format error", tnp->so, tnp->ident, tnp->address);
@@ -1848,7 +1848,7 @@ mainloop(int *udp, int *tcp, int sockcount, char **ide
build_reply( &sreply, tnp->so, pbuf, len,
question, from, fromlen,
&sd0, NULL, tnp->region, istcp,
- tnp->wildcard);
+ tnp->wildcard, NULL);
reply_noerror(&sreply);
goto tcpout;
@@ -1874,7 +1874,7 @@ tcpnxdomain:
build_reply( &sreply, tnp->so, pbuf, len, question,
from, fromlen, &sd0, NULL,
- tnp->region, istcp, tnp->wildcard);
+ tnp->region, istcp, tnp->wildcard, NULL);
reply_nxdomain(&sreply);
goto tcpout;
@@ -1908,7 +1908,7 @@ tcpnxdomain:
default:
build_reply( &sreply, tnp->so, pbuf, len, question,
from, fromlen, NULL, NULL, tnp->region,
- istcp, tnp->wildcard);
+ istcp, tnp->wildcard, NULL);
reply_notimpl(&sreply);
snprintf(replystring, DNS_MAXNAME, "NOTIMPL");
@@ -1920,19 +1920,19 @@ tcpnxdomain:
if (type0 == DNS_TYPE_CNAME) {
build_reply(&sreply, tnp->so, pbuf, len, question, from, \
fromlen, &sd0, ((type1 > 0) ? &sd1 : NULL), \
- tnp->region, istcp, tnp->wildcard);
+ tnp->region, istcp, tnp->wildcard, NULL);
reply_cname(&sreply);
} else if (type0 == DNS_TYPE_NS) {
build_reply(&sreply, tnp->so, pbuf, len, question,
from, fromlen, &sd0, NULL,
- tnp->region, istcp, tnp->wildcard);
+ tnp->region, istcp, tnp->wildcard, NULL);
reply_ns(&sreply, db);
break;
} else if (type0 == DNS_TYPE_A) {
build_reply(&sreply, tnp->so, pbuf, len, question, from, \
- fromlen, &sd0, NULL, tnp->region, istcp, tnp->wildcard);
+ fromlen, &sd0, NULL, tnp->region, istcp, tnp->wildcard, NULL);
reply_a(&sreply, db);
break; /* must break here */
}
@@ -1943,16 +1943,16 @@ tcpnxdomain:
if (type0 == DNS_TYPE_CNAME) {
build_reply(&sreply, tnp->so, pbuf, len, question, from, \
fromlen, &sd0, ((type1 > 0) ? &sd1 : NULL), \
- tnp->region, istcp, tnp->wildcard);
+ tnp->region, istcp, tnp->wildcard, NULL);
reply_cname(&sreply);
} else if (type0 == DNS_TYPE_NS) {
build_reply(&sreply, tnp->so, pbuf, len, question, from, \
- fromlen, &sd0, NULL, tnp->region, istcp, tnp->wildcard);
+ fromlen, &sd0, NULL, tnp->region, istcp, tnp->wildcard, NULL);
reply_ns(&sreply, db);
break;
} else if (type0 == DNS_TYPE_AAAA) {
build_reply(&sreply, tnp->so, pbuf, len, question, from,
- fromlen, &sd0, NULL, tnp->region, istcp, tnp->wildcard);
+ fromlen, &sd0, NULL, tnp->region, istcp, tnp->wildcard, NULL);
reply_aaaa(&sreply, db);
break; /* must break here */
}
@@ -1963,16 +1963,16 @@ tcpnxdomain:
if (type0 == DNS_TYPE_CNAME) {
build_reply(&sreply, tnp->so, pbuf, len, question, from, \
fromlen, &sd0, ((type1 > 0) ? &sd1 : NULL), \
- tnp->region, istcp, tnp->wildcard);
+ tnp->region, istcp, tnp->wildcard, NULL);
reply_cname(&sreply);
} else if (type0 == DNS_TYPE_NS) {
build_reply(&sreply, tnp->so, pbuf, len, question, from, \
- fromlen, &sd0, NULL, tnp->region, istcp, tnp->wildcard);
+ fromlen, &sd0, NULL, tnp->region, istcp, tnp->wildcard, NULL);
reply_ns(&sreply, db);
break;
} else if (type0 == DNS_TYPE_MX) {
build_reply(&sreply, tnp->so, pbuf, len, question, from, \
- fromlen, &sd0, NULL, tnp->region, istcp, tnp->wildcard);
+ fromlen, &sd0, NULL, tnp->region, istcp, tnp->wildcard, NULL);
reply_mx(&sreply, db);
break; /* must break here */
}
@@ -1981,11 +1981,11 @@ tcpnxdomain:
case DNS_TYPE_SOA:
if (type0 == DNS_TYPE_SOA) {
build_reply(&sreply, tnp->so, pbuf, len, question, from, \
- fromlen, &sd0, NULL, tnp->region, istcp, tnp->wildcard);
+ fromlen, &sd0, NULL, tnp->region, istcp, tnp->wildcard, NULL);
reply_soa(&sreply);
} else if (type0 == DNS_TYPE_NS) {
build_reply(&sreply, tnp->so, pbuf, len, question, from, \
- fromlen, &sd0, NULL, tnp->region, istcp, tnp->wildcard);
+ fromlen, &sd0, NULL, tnp->region, istcp, tnp->wildcard, NULL);
reply_ns(&sreply, db);
break;
}
@@ -1993,7 +1993,7 @@ tcpnxdomain:
case DNS_TYPE_NS:
if (type0 == DNS_TYPE_NS) {
build_reply(&sreply, tnp->so, pbuf, len, question, from, \
- fromlen, &sd0, NULL, tnp->region, istcp, tnp->wildcard);
+ fromlen, &sd0, NULL, tnp->region, istcp, tnp->wildcard, NULL);
reply_ns(&sreply, db);
}
break;
@@ -2002,11 +2002,11 @@ tcpnxdomain:
case DNS_TYPE_CNAME:
if (type0 == DNS_TYPE_CNAME) {
build_reply(&sreply, tnp->so, pbuf, len, question, from, \
- fromlen, &sd0, NULL, tnp->region, istcp, tnp->wildcard);
+ fromlen, &sd0, NULL, tnp->region, istcp, tnp->wildcard, NULL);
reply_cname(&sreply);
} else if (type0 == DNS_TYPE_NS) {
build_reply(&sreply, tnp->so, pbuf, len, question, from, \
- fromlen, &sd0, NULL, tnp->region, istcp, tnp->wildcard);
+ fromlen, &sd0, NULL, tnp->region, istcp, tnp->wildcard, NULL);
reply_ns(&sreply, db);
break;
}
@@ -2016,16 +2016,16 @@ tcpnxdomain:
if (type0 == DNS_TYPE_CNAME) {
build_reply(&sreply, tnp->so, pbuf, len, question, from, \
fromlen, &sd0, ((type1 > 0) ? &sd1 : NULL) \
- , tnp->region, istcp, tnp->wildcard);
+ , tnp->region, istcp, tnp->wildcard, NULL);
reply_cname(&sreply);
} else if (type0 == DNS_TYPE_NS) {
build_reply(&sreply, tnp->so, pbuf, len, question, from, \
- fromlen, &sd0, NULL, tnp->region, istcp, tnp->wildcard);
+ fromlen, &sd0, NULL, tnp->region, istcp, tnp->wildcard, NULL);
reply_ns(&sreply, db);
break;
} else if (type0 == DNS_TYPE_PTR) {
build_reply(&sreply, tnp->so, pbuf, len, question, from,
- fromlen, &sd0, NULL, tnp->region, istcp, tnp->wildcard);
+ fromlen, &sd0, NULL, tnp->region, istcp, tnp->wildcard, NULL);
reply_ptr(&sreply);
break; /* must break here */
}
@@ -2034,7 +2034,7 @@ tcpnxdomain:
case DNS_TYPE_TXT:
if (type0 == DNS_TYPE_TXT) {
build_reply(&sreply, tnp->so, pbuf, len, question, from, \
- fromlen, &sd0, NULL, tnp->region, istcp, tnp->wildcard);
+ fromlen, &sd0, NULL, tnp->region, istcp, tnp->wildcard, NULL);
reply_txt(&sreply);
}
break;
@@ -2051,12 +2051,12 @@ tcpnxdomain:
if (type0 == DNS_TYPE_NS) {
build_reply(&sreply, tnp->so, pbuf, len, question, from, \
- fromlen, &sd0, NULL, aregion, istcp, tnp->wildcard);
+ fromlen, &sd0, NULL, aregion, istcp, tnp->wildcard, NULL);
reply_ns(&sreply, db);
} else {
build_reply(&sreply, tnp->so, pbuf, len, question, from, \
- fromlen, NULL, NULL, tnp->region, istcp, tnp->wildcard);
+ fromlen, NULL, NULL, tnp->region, istcp, tnp->wildcard, NULL);
reply_notimpl(&sreply);
snprintf(replystring, DNS_MAXNAME, "NOTIMPL");
@@ -2196,7 +2196,7 @@ tcpnxdomain:
syslog(LOG_INFO, "on descriptor %u interface \"%s\" header from %s has no question, drop", so, ident[i], address);
/* format error */
- build_reply(&sreply, so, buf, len, NULL, from, fromlen, NULL, NULL, aregion, istcp, wildcard);
+ build_reply(&sreply, so, buf, len, NULL, from, fromlen, NULL, NULL, aregion, istcp, wildcard, NULL);
reply_fmterror(&sreply);
syslog(LOG_INFO, "question on descriptor %d interface \"%s\" from %s, did not have question of 1 replying format error", so, ident[i], address);
goto drop;
@@ -2249,7 +2249,7 @@ tcpnxdomain:
(void)get_soa(db, question, &sd0, wildcard);
build_reply(&sreply, so, buf, len, question, from, \
- fromlen, &sd0, NULL, aregion, istcp, wildcard);
+ fromlen, &sd0, NULL, aregion, istcp, wildcard, NULL);
reply_noerror(&sreply);
goto udpout;
@@ -2283,7 +2283,7 @@ udpnxdomain:
(void)get_soa(db, question, &sd0, wildcard);
build_reply(&sreply, so, buf, len, question, from, \
- fromlen, &sd0, NULL, aregion, istcp, wildcard);
+ fromlen, &sd0, NULL, aregion, istcp, wildcard, NULL);
reply_nxdomain(&sreply);
goto udpout;
} /* else rflag */
@@ -2316,7 +2316,7 @@ udpnxdomain:
break;
default:
build_reply(&sreply, so, buf, len, question, from, \
- fromlen, NULL, NULL, aregion, istcp, wildcard);
+ fromlen, NULL, NULL, aregion, istcp, wildcard, NULL);
reply_notimpl(&sreply);
snprintf(replystring, DNS_MAXNAME, "NOTIMPL");
goto udpout;
@@ -2327,16 +2327,16 @@ udpnxdomain:
if (type0 == DNS_TYPE_CNAME) {
build_reply(&sreply, so, buf, len, question, from, \
fromlen, &sd0, ((type1 > 0) ? &sd1 : NULL), \
- aregion, istcp, wildcard);
+ aregion, istcp, wildcard, NULL);
reply_cname(&sreply);
} else if (type0 == DNS_TYPE_NS) {
build_reply(&sreply, so, buf, len, question, from, \
- fromlen, &sd0, NULL, aregion, istcp, wildcard);
+ fromlen, &sd0, NULL, aregion, istcp, wildcard, NULL);
reply_ns(&sreply, db);
break;
} else if (type0 == DNS_TYPE_A) {
build_reply(&sreply, so, buf, len, question, from, \
- fromlen, &sd0, NULL, aregion, istcp, wildcard);
+ fromlen, &sd0, NULL, aregion, istcp, wildcard, NULL);
reply_a(&sreply, db);
break; /* must break here */
}
@@ -2347,16 +2347,16 @@ udpnxdomain:
if (type0 == DNS_TYPE_CNAME) {
build_reply(&sreply, so, buf, len, question, from, \
fromlen, &sd0, ((type1 > 0) ? &sd1 : NULL), \
- aregion, istcp, wildcard);
+ aregion, istcp, wildcard, NULL);
reply_cname(&sreply);
} else if (type0 == DNS_TYPE_NS) {
build_reply(&sreply, so, buf, len, question, from, \
- fromlen, &sd0, NULL, aregion, istcp, wildcard);
+ fromlen, &sd0, NULL, aregion, istcp, wildcard, NULL);
reply_ns(&sreply, db);
break;
} else if (type0 == DNS_TYPE_AAAA) {
build_reply(&sreply, so, buf, len, question, from,
- fromlen, &sd0, NULL, aregion, istcp, wildcard);
+ fromlen, &sd0, NULL, aregion, istcp, wildcard, NULL);
reply_aaaa(&sreply, db);
break; /* must break here */
}
@@ -2367,16 +2367,16 @@ udpnxdomain:
if (type0 == DNS_TYPE_CNAME) {
build_reply(&sreply, so, buf, len, question, from, \
fromlen, &sd0, ((type1 > 0) ? &sd1 : NULL), \
- aregion, istcp, wildcard);
+ aregion, istcp, wildcard, NULL);
reply_cname(&sreply);
} else if (type0 == DNS_TYPE_NS) {
build_reply(&sreply, so, buf, len, question, from, \
- fromlen, &sd0, NULL, aregion, istcp, wildcard);
+ fromlen, &sd0, NULL, aregion, istcp, wildcard, NULL);
reply_ns(&sreply, db);
break;
} else if (type0 == DNS_TYPE_MX) {
build_reply(&sreply, so, buf, len, question, from, \
- fromlen, &sd0, NULL, aregion, istcp, wildcard);
+ fromlen, &sd0, NULL, aregion, istcp, wildcard, NULL);
reply_mx(&sreply, db);
break; /* must break here */
}
@@ -2385,11 +2385,11 @@ udpnxdomain:
case DNS_TYPE_SOA:
if (type0 == DNS_TYPE_SOA) {
build_reply(&sreply, so, buf, len, question, from, \
- fromlen, &sd0, NULL, aregion, istcp, wildcard);
+ fromlen, &sd0, NULL, aregion, istcp, wildcard, NULL);
reply_soa(&sreply);
} else if (type0 == DNS_TYPE_NS) {
build_reply(&sreply, so, buf, len, question, from, \
- fromlen, &sd0, NULL, aregion, istcp, wildcard);
+ fromlen, &sd0, NULL, aregion, istcp, wildcard, NULL);
reply_ns(&sreply, db);
break;
}
@@ -2397,7 +2397,7 @@ udpnxdomain:
case DNS_TYPE_NS:
if (type0 == DNS_TYPE_NS) {
build_reply(&sreply, so, buf, len, question, from, \
- fromlen, &sd0, NULL, aregion, istcp, wildcard);
+ fromlen, &sd0, NULL, aregion, istcp, wildcard, NULL);
reply_ns(&sreply, db);
}
break;
@@ -2406,11 +2406,11 @@ udpnxdomain:
case DNS_TYPE_CNAME:
if (type0 == DNS_TYPE_CNAME) {
build_reply(&sreply, so, buf, len, question, from, \
- fromlen, &sd0, NULL, aregion, istcp, wildcard);
+ fromlen, &sd0, NULL, aregion, istcp, wildcard, NULL);
reply_cname(&sreply);
} else if (type0 == DNS_TYPE_NS) {
build_reply(&sreply, so, buf, len, question, from, \
- fromlen, &sd0, NULL, aregion, istcp, wildcard);
+ fromlen, &sd0, NULL, aregion, istcp, wildcard, NULL);
reply_ns(&sreply, db);
break;
}
@@ -2420,16 +2420,16 @@ udpnxdomain:
if (type0 == DNS_TYPE_CNAME) {
build_reply(&sreply, so, buf, len, question, from, \
fromlen, &sd0, ((type1 > 0) ? &sd1 : NULL) \
- , aregion, istcp, wildcard);
+ , aregion, istcp, wildcard, NULL);
reply_cname(&sreply);
} else if (type0 == DNS_TYPE_NS) {
build_reply(&sreply, so, buf, len, question, from, \
- fromlen, &sd0, NULL, aregion, istcp, wildcard);
+ fromlen, &sd0, NULL, aregion, istcp, wildcard, NULL);
reply_ns(&sreply, db);
break;
} else if (type0 == DNS_TYPE_PTR) {
build_reply(&sreply, so, buf, len, question, from,
- fromlen, &sd0, NULL, aregion, istcp, wildcard);
+ fromlen, &sd0, NULL, aregion, istcp, wildcard, NULL);
reply_ptr(&sreply);
break; /* must break here */
}
@@ -2437,7 +2437,7 @@ udpnxdomain:
case DNS_TYPE_TXT:
if (type0 == DNS_TYPE_TXT) {
build_reply(&sreply, so, buf, len, question, from, \
- fromlen, &sd0, NULL, aregion, istcp, wildcard);
+ fromlen, &sd0, NULL, aregion, istcp, wildcard, NULL);
reply_txt(&sreply);
}
break;
@@ -2452,13 +2452,13 @@ udpnxdomain:
if (type0 == DNS_TYPE_NS) {
build_reply(&sreply, so, buf, len, question, from, \
- fromlen, &sd0, NULL, aregion, istcp, wildcard);
+ fromlen, &sd0, NULL, aregion, istcp, wildcard, NULL);
reply_ns(&sreply, db);
} else {
build_reply(&sreply, so, buf, len, question, from, \
- fromlen, NULL, NULL, aregion, istcp, wildcard);
+ fromlen, NULL, NULL, aregion, istcp, wildcard, NULL);
reply_notimpl(&sreply);
snprintf(replystring, DNS_MAXNAME, "NOTIMPL");
}
@@ -2495,7 +2495,7 @@ udpnxdomain:
*/
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)
+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)
{
reply->so = so;
reply->buf = buf;
@@ -2508,6 +2508,7 @@ build_reply(struct sreply *reply, int so, char *buf, i
reply->region = region;
reply->istcp = istcp;
reply->wildcard = wildcard;
+ reply->sr = sr;
return;
}
blob - d1d64d9157118d0c9b1274a44ba9be0872e719ce
blob + 6831259ed16ed37c02d64bba1fd02e52b0252a96
--- recurse.c
+++ recurse.c
@@ -40,8 +40,16 @@ extern struct question * build_question(char *buf, int
extern struct question * build_fake_question(char *, int, u_int16_t);
extern int free_question(struct question *);
extern int lookup_zone(DB *db, struct question *question, struct domain *sd, int *lzerrno, char *replystring, int wildcard);
+int lookup_ns(DB *, struct recurses *);
+int lookup_a(DB *, struct recurses *, struct ns *);
+int recurse_parse(DB *db, struct recurses *sr, u_char *buf, u_int16_t offset);
+int negative_cache(DB *db, struct recurses *sr);
+int netlookup(DB *db, struct recurses *sr);
+int fakerecurse(DB *db, struct recurses *sr, struct ns *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 *);
-
SLIST_HEAD(listhead, recurseentry) recursehead;
struct recurseentry {
@@ -53,52 +61,9 @@ struct recurseentry {
SLIST_ENTRY(recurseentry) entries;
} *rn1, *rn2, *rnp;
-SLIST_HEAD(listhead2, recurses) recurseshead;
-struct recurses {
- char query[512]; /* the query we received */
- int len; /* length of query */
+static const char rcsid[] = "$Id: recurse.c,v 1.10 2010/09/19 11:39:38 pbug Exp $";
- int isfake; /* received or faked */
- int af; /* address family */
- int proto; /* protocol UDP/TCP */
- struct sockaddr_storage source; /* source + port */
- struct sockaddr_storage dest; /* dest + port */
-
- time_t received; /* received request time */
- time_t sent_last_query; /* the last time we did a lookup */
-
- char upperlower[32]; /* uppercase / lowercase bitmap */
- int so; /* the socket we did a lookup with */
- u_short port; /* port used on outgoing */
- u_int16_t id; /* last id used */
-
- /* the below get loaded from the database upon each lookup */
- in_addr_t a[RECORD_COUNT]; /* IPv4 addresses of nameservers */
- int a_count; /* IPv4 address count */
- int a_ptr; /* pointer to last used address */
- struct in6_addr aaaa[RECORD_COUNT]; /* IPv6 addresses of nameservers */
- int aaaa_count; /* IPv6 address count */
- int aaaa_ptr; /* pointer to last used IPv6 address */
-
- /* the below is our indicator which part of the lookup we're at */
-
- int indicator; /* indicator of ns lookup */
-
- struct question *question; /* question struct */
- SLIST_ENTRY(recurses) entries;
- struct recurses *callback; /* callback */
-} *sr, *sr1;
-
-int lookup_ns(DB *, struct recurses *);
-int lookup_a(DB *, struct recurses *, struct ns *);
-int recurse_parse(DB *db, struct recurses *sr, u_char *buf, u_int16_t offset);
-int negative_cache(DB *db, struct recurses *sr);
-int netlookup(DB *db, struct recurses *sr);
-int fakerecurse(DB *db, struct recurses *sr, struct ns *ns);
-
-static const char rcsid[] = "$Id: recurse.c,v 1.9 2010/09/18 19:51:06 pbug Exp $";
-
/*
* INIT_RECURSE - initialize the recurse singly linked list
*/
@@ -261,10 +226,12 @@ recurseloop(int sp, int *raw, DB *db)
/* XXX remember recurseshead is for struct recurses */
SLIST_FOREACH(sr1, &recurseshead, entries) {
- if (maxso < sr1->so)
- maxso = sr1->so;
+ if (sr1->so != -1) {
+ if (maxso < sr1->so)
+ maxso = sr1->so;
- FD_SET(sr1->so, &rset);
+ FD_SET(sr1->so, &rset);
+ }
}
tv.tv_sec = 1;
@@ -299,6 +266,7 @@ recurseloop(int sp, int *raw, DB *db)
sr->proto = rh.proto;
sr->so = -1;
sr->callback = NULL;
+ sr->hascallback = 0;
sr->isfake = 0;
memcpy(&sr->source, &rh.source, sizeof(struct sockaddr_storage));
memcpy(&sr->dest, &rh.dest, sizeof(struct sockaddr_storage));
@@ -316,20 +284,21 @@ recurseloop(int sp, int *raw, DB *db)
if (netlookup(db, sr) < 0)
continue;
+ syslog(LOG_DEBUG, "adding sr %lx to list\n", (void*)sr);
SLIST_INSERT_HEAD(&recurseshead, sr, entries);
} else {
syslog(LOG_DEBUG, "we had the record in our cache, reply action");
-#if 0
- reply_raw(sr);
- free(sr);
+
+ reply_raw(db, sr, &sd, raw);
+ free_question(sr->question);
+ free(sr);
continue;
-#endif
}
} /* FD_ISSET(sp) */
SLIST_FOREACH(sr1, &recurseshead, entries) {
- if (FD_ISSET(sr1->so, &rset)) {
+ if (sr1->so != -1 && FD_ISSET(sr1->so, &rset)) {
/*
* we got a reply from the nameserver we
* queried, now we must parse the input
@@ -383,11 +352,13 @@ recurseloop(int sp, int *raw, DB *db)
type = lookup_zone(db, sr1->question, &sd, &lzerrno, (char *)fakereplystring, wildcard);
if (type < 0) {
+ syslog(LOG_DEBUG, "lookup_zone failed, doing netlookup");
if (netlookup(db, sr1) < 0) {
syslog(LOG_DEBUG, "subsequent netlookup failed");
- /* continue; XXX */
}
+
+ continue;
} else {
/* we've found the record we're looking
* for do something with it..
@@ -395,18 +366,33 @@ recurseloop(int sp, int *raw, DB *db)
if (sr1->isfake) {
/* do another netlookup with the callback */
+ syslog(LOG_DEBUG, "sr is fake, doing netlookup on the callback");
if (netlookup(db, sr1->callback) < 0) {
syslog(LOG_DEBUG, "callback netlookup failed");
}
- } else
+ sr1->callback->hascallback--;
+ /* XXX continue; */
+
+
+ } else {
+ reply_raw(db, sr1, &sd, raw);
+#if 0
syslog(LOG_DEBUG, "record found but no action");
+#endif
+ }
}
remove:
- SLIST_REMOVE(&recurseshead, sr1, recurses, entries);
- free_question(sr1->question);
- free(sr1);
+ /* only remove if we don't have any callbacks
+ * outstanding...
+ */
+ if (! sr1->hascallback) {
+ syslog(LOG_DEBUG, "removing sr %lx from list\n", sr1);
+ SLIST_REMOVE(&recurseshead, sr1, recurses, entries);
+ free_question(sr1->question);
+ free(sr1);
+ }
} /* FD_ISSET(sr1->so */
} /* SLIST_FOREACH(sr... */
@@ -698,7 +684,7 @@ int
recurse_parse(DB *db, struct recurses *sr, u_char *buf, u_int16_t offset)
{
u_char *label[256]; /* should be enough */
- u_char converted_name[256][256];
+ static u_char converted_name[256][256];
u_int8_t cn_len[256];
u_char *end = &buf[offset];
int update;
@@ -1026,7 +1012,9 @@ again:
update = 1;
for (j = 0; j < sdomain.a_count; j++) {
if (memcmp(&sdomain.a[j], p, sizeof(in_addr_t)) == 0) {
+#if 0
syslog(LOG_INFO, "record exists already");
+#endif
update = 0;
}
}
@@ -1088,7 +1076,9 @@ again:
syslog(LOG_DEBUG, "nameserver record %s", sdomain.ns[j]->nsserver);
#endif
if (memcmp(sdomain.ns[j]->nsserver, converted_name[i], cn_len[i]) == 0) {
+#if 0
syslog(LOG_INFO, "record exists already");
+#endif
update = 0;
}
}
@@ -1203,6 +1193,7 @@ netlookup(DB *db, struct recurses *sr)
sr->so = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sr->so < 0) {
syslog(LOG_ERR, "socket: %m");
+ sr->so = -1;
return (-1);
}
@@ -1224,12 +1215,14 @@ netlookup(DB *db, struct recurses *sr)
if (bind(sr->so, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
syslog(LOG_ERR, "bind: %m");
close(sr->so);
+ sr->so = -1;
return (-1);
}
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);
+ sr->so = -1;
return (-1);
}
@@ -1257,6 +1250,7 @@ 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);
+ sr->so = -1;
return (-1);
}
@@ -1277,11 +1271,16 @@ 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 *type, *class;
+ u_int16_t *qtype, *qclass;
+ int type, lzerrno, wildcard = 0;
+
/* place request on struct recurses linked list */
fakesr = calloc(sizeof(struct recurses), 1);
@@ -1295,6 +1294,8 @@ fakerecurse(DB *db, struct recurses *sr, struct ns *ns
fakesr->proto = sr->proto;
fakesr->so = -1;
fakesr->callback = sr;
+ sr->hascallback++;
+ fakesr->hascallback = 0;
fakesr->isfake = 1;
fakesr->received = time(NULL);
@@ -1320,19 +1321,63 @@ fakerecurse(DB *db, struct recurses *sr, struct ns *ns
p = (char *)&fakesr->query[len];
memcpy(p, ns->nsserver, ns->nslen);
len += ns->nslen;
- type = (u_int16_t *)&fakesr->query[len];
- *type = fakesr->question->hdr->qtype;
+ qtype = (u_int16_t *)&fakesr->query[len];
+ *qtype = fakesr->question->hdr->qtype;
len += sizeof(u_int16_t);
- class = (u_int16_t *)&fakesr->query[len];
- *class = fakesr->question->hdr->qclass;
+ qclass = (u_int16_t *)&fakesr->query[len];
+ *qclass = fakesr->question->hdr->qclass;
len += sizeof(u_int16_t);
fakesr->len = len;
- if (netlookup(db, fakesr) < 0)
- return (-1);
+ 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);
+ }
+ syslog(LOG_DEBUG, "adding fake sr %lx to list", fakesr);
SLIST_INSERT_HEAD(&recurseshead, fakesr, entries);
return (0);
+}
+
+void
+reply_raw(DB *db, struct recurses *sr, struct domain *sd, int *raw)
+{
+ char buf[2048];
+ int so;
+ struct sreply sreply;
+
+ syslog(LOG_DEBUG, "reply_raw called");
+
+ switch (sr->af) {
+ case AF_INET:
+ so = raw[0];
+ break;
+ case AF_INET6:
+ so = raw[1];
+ break;
+ default:
+ syslog(LOG_ERR, "reply_raw(): unknown address family in struct recurses");
+ return;
+ }
+
+ build_reply(&sreply, so, sr->query, sr->len, sr->question, NULL, 0, sd, NULL, 0xff, 0, 0, sr);
+
+ switch (ntohs(sr->question->hdr->qtype)) {
+ case DNS_TYPE_A:
+ reply_a(&sreply, db);
+ break;
+ default:
+ syslog(LOG_ERR, "other types have not been implemented yet");
+ break;
+ }
+
+ return;
}
blob - 4f84b2cfbcc0a05bea5f947bf6e7a793fd04030a
blob + 2655129ed1189037840d04b59f80066af54c6044
--- reply.c
+++ reply.c
@@ -67,7 +67,7 @@ struct collects {
} *cn1, *cn2, *cnp;
-static const char rcsid[] = "$Id: reply.c,v 1.24 2010/07/27 07:19:05 pbug Exp $";
+static const char rcsid[] = "$Id: reply.c,v 1.25 2010/09/19 11:39:38 pbug Exp $";
/*
* REPLY_A() - replies a DNS question (*q) on socket (so)
@@ -120,8 +120,11 @@ reply_a(struct sreply *sreply, DB *db)
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);
odh->question = htons(1);
@@ -187,29 +190,33 @@ reply_a(struct sreply *sreply, DB *db)
}
out:
- if (istcp) {
- char *tmpbuf;
- u_int16_t *plen;
+ if (sreply->sr != NULL) {
+ syslog(LOG_DEBUG, "raw replying has not been implemented yet");
+ } 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");
+ 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");
+ }
}
- free(tmpbuf);
- } else {
- if (sendto(so, reply, outlen, 0, sa, salen) < 0) {
- syslog(LOG_INFO, "sendto: %m");
- }
- }
+ } /* if (->sr) */
/*
* update a_ptr setting
*/
repomaster@centroid.eu