20static char secretkey[32];
21static char publickey[32];
28 for (k = 0; k < 32; ++k)
34static int flagforwardonly = 0;
41static void cachegeneric(
const char type[2],
const char *d,
const char *
data,
unsigned int datalen,uint32 ttl)
49 byte_copy(key,2,
type);
50 byte_copy(key + 2,
len,d);
51 case_lowerb(key + 2,
len);
56static char save_buf[8192];
57static unsigned int save_len;
58static unsigned int save_ok;
60static void save_start(
void)
66static void save_data(
const char *
buf,
unsigned int len)
69 if (
len > (
sizeof(save_buf)) - save_len) { save_ok = 0;
return; }
70 byte_copy(save_buf + save_len,
len,
buf);
74static void save_finish(
const char type[2],
const char *d,uint32 ttl)
77 cachegeneric(
type,d,save_buf,save_len,ttl);
80static int typematch(
const char rtype[2],
const char qtype[2])
82 return byte_equal(qtype,2,rtype) || byte_equal(qtype,2,
DNS_T_ANY);
85static uint32 ttlget(
char buf[4])
89 uint32_unpack_big(
buf,&ttl);
90 if (ttl > 1000000000)
return 0;
91 if (ttl > 604800)
return 604800;
95static void cleanup(
struct query *
z)
110static int rqa(
struct query *
z)
129static int globalip(
char *d,
char ip[16])
136 byte_copy(
ip,12,V4mappedprefix);
143 if (
dd4(d,
"",
ip) == 4)
return 1;
150static char *cname = 0;
151static char *referral = 0;
152static unsigned int *records = 0;
154static int smaller(
char *
buf,
unsigned int len,
unsigned int pos1,
unsigned int pos2)
167 r = byte_diff(header1,4,header2);
173 if (len1 < len2)
return 1;
174 if (len1 > len2)
return 0;
176 r = case_diffb(t1,len1,t2);
180 if (pos1 < pos2)
return 1;
188 unsigned int cachedlen;
191 const char *whichserver;
200 unsigned int posanswers;
202 unsigned int posauthority;
228 if (state == 1)
goto HAVEPACKET;
237 d =
z->name[
z->level];
241 if (globalip(d,misc)) {
247 if (!rqa(
z))
goto DIE;
248 if (typematch(
DNS_T_A,dtype)) {
266 if (
z->level)
goto LOWERLEVEL;
267 if (!rqa(
z))
goto DIE;
268 if (typematch(
DNS_T_A,dtype)) {
286 if (
z->level)
goto LOWERLEVEL;
287 if (!rqa(
z))
goto DIE;
298 if (
z->level)
goto LOWERLEVEL;
299 if (!rqa(
z))
goto DIE;
310 if (
z->level)
goto LOWERLEVEL;
311 if (!rqa(
z))
goto DIE;
322 if (
z->level)
goto LOWERLEVEL;
323 if (!rqa(
z))
goto DIE;
334 if (
z->level)
goto LOWERLEVEL;
335 if (!rqa(
z))
goto DIE;
347 if (
z->level)
goto LOWERLEVEL;
348 if (!rqa(
z))
goto DIE;
359 if (
z->level)
goto LOWERLEVEL;
360 if (!rqa(
z))
goto DIE;
371 if (
z->level)
goto LOWERLEVEL;
372 if (!rqa(
z))
goto DIE;
383 if (
z->level)
goto LOWERLEVEL;
384 if (!rqa(
z))
goto DIE;
395 if (
z->level)
goto LOWERLEVEL;
396 if (!rqa(
z))
goto DIE;
409 if (
z->level)
goto LOWERLEVEL;
410 if (!rqa(
z))
goto DIE;
421 if (
z->level)
goto LOWERLEVEL;
422 if (!rqa(
z))
goto DIE;
434 if (
z->level)
goto LOWERLEVEL;
435 if (!rqa(
z))
goto DIE;
436 if (typematch(
DNS_T_A,dtype)) {
447 if (
z->level)
goto LOWERLEVEL;
448 if (!rqa(
z))
goto DIE;
449 if (typematch(
DNS_T_A,dtype)) {
475 byte_copy(key + 2,
dlen,d);
476 case_lowerb(key + 2,
dlen);
486 if (cached && cachedlen) {
489 if (!rqa(
z))
goto DIE;
503 if (cached && (cachedlen || byte_diff(dtype,2,
DNS_T_ANY))) {
506 flagns =
cns_addns(
z,cached,flaghaskey,pubkey);
510 if (!rqa(
z))
goto DIE;
525 if (cached && (cachedlen || byte_diff(dtype,2,
DNS_T_ANY))) {
527 if (!rqa(
z))
goto DIE;
542 if (cached && (cachedlen || byte_diff(dtype,2,
DNS_T_ANY))) {
544 if (!rqa(
z))
goto DIE;
559 if (typematch(
DNS_T_A,dtype)) {
563 if (cached && !cachedlen &&
z->level) {
564 z->ipv6[
z->level] = 1;
567 if (cached && (cachedlen || byte_diff(dtype,2,
DNS_T_ANY))) {
571 while (cachedlen >= 4) {
573 if (byte_equal(
z->servers[
z->level - 1] + k,16,V6localnet)) {
574 byte_copy(
z->servers[
z->level - 1] + k,12,V4mappedprefix);
575 byte_copy(
z->servers[
z->level - 1] + k + 12,4,cached);
578 byte_copy(addr,12,V4mappedprefix);
579 byte_copy(addr+12,4,cached);
589 if (!rqa(
z))
goto DIE;
590 while (cachedlen >= 4) {
605 if (cached && (cachedlen || byte_diff(dtype,2,
DNS_T_ANY))) {
609 while (cachedlen >= 16) {
610 flagns =
cns_addns(
z,cached,flaghaskey,pubkey);
619 if (!rqa(
z))
goto DIE;
620 while (cachedlen >= 16) {
636 byte_copy(key,2,dtype);
638 if (cached && (cachedlen || byte_diff(dtype,2,
DNS_T_ANY))) {
640 if (!rqa(
z))
goto DIE;
641 while (cachedlen >= 2) {
642 uint16_unpack_big(cached,&datalen);
645 if (datalen > cachedlen)
goto DIE;
650 cachedlen -= datalen;
660 if (
roots(
z->servers[
z->level],d)) {
661 z->flagnskeys[
z->level] = 0;
664 z->control[
z->level] =
d;
668 if (!flagforwardonly && (
z->level < 2))
671 byte_copy(key + 2,
dlen,d);
672 case_lowerb(key + 2,
dlen);
674 if (cached && cachedlen) {
675 z->control[
z->level] =
d;
677 z->flagnskeys[
z->level] = 0;
692 j = 1 + (
unsigned int) (
unsigned char) *
d;
700 if (
z->ns[
z->level][j]) {
705 z->ipv6[
z->level] = 0;
712 if (byte_diff(
z->servers[
z->level] + j,16,V6localnet))
break;
715 if (
z->flagnskeys[
z->level]) {
718 if (byte_diff(
z->servers[
z->level] + j,16,V6localnet)) {
719 whichkey =
z->keys[
z->level] + 2 * j;
720 byte_copy(key + 2,32,whichkey);
721 cached =
cache_get(key,34,&cachedlen,&ttl);
722 if (cached && (cachedlen == 32)) {
723 byte_copy(whichkey,32,cached);
726 crypto_box_beforenm((
unsigned char *) whichkey,(
const unsigned char *) whichkey,(
const unsigned char *) secretkey);
734 cnskey =
z->flagnskeys[
z->level] ?
z->keys[
z->level] : 0;
735 log_tx(
z->name[
z->level],dtype,
z->control[
z->level],
z->servers[
z->level],
z->flagnskeys[
z->level],
z->level);
738 dtype,
z->localip,cnskey,publickey,control) < 0)
goto DIE;
754 len =
z->dt.packetlen;
756 whichserver =
z->dt.servers + 16 *
z->dt.curserver;
757 control =
z->control[
z->level];
758 d =
z->name[
z->level];
767 uint16_unpack_big(header + 6,&numanswers);
768 uint16_unpack_big(header + 8,&numauthority);
769 uint16_unpack_big(header + 10,&numglue);
771 rcode = header[3] & 15;
772 if (rcode && (rcode != 3))
goto DIE;
782 for (j = 0; j < numanswers; ++j) {
787 if (byte_equal(header + 2,2,
DNS_C_IN)) {
788 if (typematch(header,dtype))
793 cnamettl = ttlget(header + 4);
797 uint16_unpack_big(header + 8,&datalen);
802 for (j = 0; j < numauthority; ++j) {
808 soattl = ttlget(header + 4);
809 if (soattl > 3600) soattl = 3600;
811 else if (typematch(header,
DNS_T_NS)) {
816 uint16_unpack_big(header + 8,&datalen);
822 if (flagsoa && (pos <=
len)) {
823 cachettl = ttlget(
buf + pos - 4);
824 if (soattl < cachettl) cachettl = soattl;
827 if (!flagcname && !rcode && !flagout && flagreferral && !flagsoa)
829 log_lame(whichserver,control,referral);
830 byte_zero(whichserver,4);
834 if (records) { alloc_free(records); records = 0; }
836 k = numanswers + numauthority + numglue;
837 records = (
unsigned int *) alloc(k *
sizeof(
unsigned int));
838 if (!records)
goto DIE;
841 for (j = 0; j < k; ++j) {
845 uint16_unpack_big(header + 8,&datalen);
851 if (i > 1) { --i; pos = records[i - 1]; }
852 else { pos = records[j - 1]; records[j - 1] = records[i - 1]; --j; }
855 while ((
p = q * 2) < j) {
856 if (!smaller(
buf,
len,records[
p],records[
p - 1])) ++
p;
857 records[q - 1] = records[
p - 1]; q =
p;
860 records[q - 1] = records[
p - 1]; q =
p;
862 while ((q > i) && smaller(
buf,
len,records[(
p = q/2) - 1],pos)) {
863 records[q - 1] = records[
p - 1]; q =
p;
865 records[q - 1] = pos;
874 ttl = ttlget(header + 4);
876 byte_copy(
type,2,header);
877 if (byte_diff(header + 2,2,
DNS_C_IN)) { ++i;
continue; }
879 for (j = i + 1; j < k; ++j) {
883 if (byte_diff(header,2,
type))
break;
884 if (byte_diff(header + 2,2,
DNS_C_IN))
break;
888 if (!
roots_same(t1,control)) { i = j;
continue; }
900 if (records[i] < posauthority)
901 log_rrsoa(whichserver,t1,t2,t3,misc,ttl);
939 log_rrmx(whichserver,t1,t2,misc,ttl);
951 if (byte_equal(header + 8,2,
"\0\4")) {
965 if (byte_equal(header + 8,2,
"\0\20")) {
967 save_data(header,16);
979 uint16_unpack_big(header + 8,&datalen);
980 if (datalen >
len - pos)
goto DIE;
981 save_data(header + 8,2);
982 save_data(
buf + pos,datalen);
986 save_finish(
type,t1,ttl);
992 alloc_free(records); records = 0;
1003 z->alias[j] =
z->alias[j - 1];
1006 z->aliasttl[j] =
z->aliasttl[j - 1];
1008 z->alias[0] =
z->name[0];
1009 z->aliasttl[0] = ttl;
1018 cachegeneric(
DNS_T_ANY,d,
"",0,cachettl);
1021 if (
z->level)
goto LOWERLEVEL;
1022 if (!rqa(
z))
goto DIE;
1030 if (!flagout && flagsoa)
1034 save_finish(dtype,d,soattl);
1036 if (
z->level && !byte_diff(
DNS_T_A,2,dtype)) {
1037 d =
z->name[
z->level];
1038 z->ipv6[
z->level] = 1;
1045 if (flagout || flagsoa || !flagreferral) {
1049 for (j = 0; j < numanswers; ++j) {
1052 uint16_unpack_big(header + 8,&datalen);
1054 if (typematch(header,
DNS_T_A))
1055 if (byte_equal(header + 2,2,
DNS_C_IN))
1058 byte_copy(addr,12,V4mappedprefix);
1059 byte_copy(addr+12,4,misc);
1060 flagns =
cns_addns(
z,addr,flaghaskey,pubkey);
1064 if (byte_equal(header + 2,2,
DNS_C_IN))
1065 if (datalen == 16) {
1067 flagns =
cns_addns(
z,misc,flaghaskey,pubkey);
1076 if (!rqa(
z))
goto DIE;
1079 for (j = 0; j < numanswers; ++j) {
1082 ttl = ttlget(header + 4);
1083 uint16_unpack_big(header + 8,&datalen);
1085 if (byte_equal(header + 2,2,
DNS_C_IN))
1086 if (typematch(header,dtype)) {
1093 else if (typematch(header,
DNS_T_MX)) {
1108 if (pos + datalen >
len)
goto DIE;
1129 if (flagforwardonly) {
1131 byte_zero(whichserver,16);
1136 z->control[
z->level] = control;
1137 z->byzg = numauthority*100 + numglue;
1138 z->flagnskeys[
z->level] = 0;
1145 for (j = 0; j < numauthority; ++j) {
1148 uint16_unpack_big(header + 8,&datalen);
1151 if (byte_equal(header + 2,2,
DNS_C_IN))
1161 if (
z->level)
goto LOWERLEVEL;
1162 if (!rqa(
z))
goto DIE;
1170 if (records) { alloc_free(records); records = 0; }
1183 byte_copy(
z->type,2,
type);
1184 byte_copy(
z->class,2,
class);
1185 byte_copy(
z->localip,16,localip);
1186 z->scope_id = scope_id;
1197 case -1:
case -2:
case -3:
unsigned int doit(char *buf, unsigned int len, unsigned int pos)
#define crypto_box_beforenm
#define crypto_scalarmult_base
int cns_transmit_start(struct dns_transmit *d, const char servers[QUERY_MAXIPLEN], int flagrecursive, const char *q, const char qtype[2], const char localip[16], const char keys[1024], const char pubkey[32], const char *suffix)
void cns_sortns(char *s, char *t, unsigned int n)
int cns_pubkey(const char *dn, char key[32])
int cns_addns(struct query *z, const char *addr, int flagnskey, const char *key)
int dd4(const char *q, const char *base, char ip[4])
int dns_domain_equal(const char *dn1, const char *dn2)
unsigned int dns_domain_length(const char *dn)
int dns_domain_copy(char **out, const char *in)
int dns_domain_suffix(const char *big, const char *little)
void dns_domain_free(char **out)
unsigned int dns_domain_suffixpos(const char *big, const char *little)
unsigned int dns_packet_getname(const char *buf, unsigned int len, unsigned int pos, char **d)
unsigned int dns_packet_copy(const char *buf, unsigned int len, unsigned int pos, char *out, unsigned int outlen)
unsigned int dns_packet_skipname(const char *buf, unsigned int len, unsigned int pos)
unsigned int dns_random(unsigned int n)
void dns_transmit_io(struct dns_transmit *d, iopause_fd *x, struct taia *deadline)
void dns_transmit_free(struct dns_transmit *d)
int dns_transmit_get(struct dns_transmit *d, const iopause_fd *x, const struct taia *when)
void d(const char *home, const char *subdir, int uid, int gid, int mode)
void z(char *home, char *subdir, char *file, int len, int uid, int gid, int mode)
void log_nxdomain(const char *, const char *, unsigned int)
void log_rrptr(const char *, const char *, const char *, unsigned int)
void log_ignore_referral(const char *, const char *, const char *)
void log_cachedanswer(const char *, const char *)
void log_rrns(const char *, const char *, const char *, unsigned int)
void log_lame(const char *, const char *, const char *)
void log_rr(const char *, const char *, const char *, const char *, unsigned int, unsigned int)
void log_servfail(const char *)
void log_nodata(const char *, const char *, const char *, unsigned int)
void log_rrsoa(const char *, const char *, const char *, const char *, const char *, unsigned int)
void log_rrcname(const char *, const char *, const char *, unsigned int)
void log_rrmx(const char *, const char *, const char *, const char *, unsigned int)
void log_servflag(const char *, int)
void log_cachedcname(const char *, const char *)
void log_cachednxdomain(const char *)
void log_cachedns(const char *, const char *)
void log_tx(const char *, const char *, const char *, const char *, int, unsigned int)
void query_io(struct query *z, iopause_fd *x, struct taia *deadline)
int query_get(struct query *z, iopause_fd *x, struct taia *stamp)
void query_forwardonly(void)
int query_start(struct query *z, char *dn, char type[2], char class[2], char localip[16], uint32 scope_id)
#define IP6_LOOPBACK_OCTAL
#define IP6_ALLROUTERS_OCTAL
#define IP6_MULTICASTPFX_OCTAL
#define IP6_MULTICAST_ARPA
#define IP6_ALLNODESMULTICAST_ARPA
#define IP4_LOOPBACK_ARPA
#define IP4_LOCALHOST_ARPA
#define IP6_LOCALHOST_ARPA
#define IP6_LOOPBACK_ARPA
#define IP4_LOOPBACK_OCTAL
#define IP6_ALLROUTERSMULTICAST_ARPA
#define IP6_LOCALNET_ARPA
#define IP6_ALLNODES_OCTAL
int response_addname(const char *)
void response_rfinish(int)
int response_addbytes(const char *, unsigned int)
int response_cname(const char *, const char *, uint32)
int response_rstart(const char *, const char *, uint32)
int response_query(const char *, const char *, const char *)
void response_nxdomain(void)
void response_servfail(void)
int roots(char *, char *)
int roots_same(char *, char *)
char * cache_get(const char *, unsigned int, unsigned int *, uint32 *)
void cache_set(const char *, unsigned int, const char *, unsigned int, uint32)