18 static char secretkey[32];
19 static char publickey[32];
26 for (k = 0; k < 32; ++k)
32 static int flagforwardonly = 0;
39 static void cachegeneric(
const char type[2],
const char *d,
const char *
data,
unsigned int datalen,uint32 ttl)
45 if (
len > 255)
return;
47 byte_copy(key,2,
type);
48 byte_copy(key + 2,
len,d);
49 case_lowerb(key + 2,
len);
54 static char save_buf[8192];
55 static unsigned int save_len;
56 static unsigned int save_ok;
58 static void save_start(
void)
64 static void save_data(
const char *
buf,
unsigned int len)
67 if (
len > (
sizeof(save_buf)) - save_len) { save_ok = 0;
return; }
68 byte_copy(save_buf + save_len,
len,
buf);
72 static void save_finish(
const char type[2],
const char *d,uint32 ttl)
75 cachegeneric(
type,d,save_buf,save_len,ttl);
78 static int typematch(
const char rtype[2],
const char qtype[2])
80 return byte_equal(qtype,2,rtype) || byte_equal(qtype,2,
DNS_T_ANY);
83 static uint32 ttlget(
char buf[4])
87 uint32_unpack_big(
buf,&ttl);
88 if (ttl > 1000000000)
return 0;
89 if (ttl > 604800)
return 604800;
93 static void cleanup(
struct query *
z)
108 static int move_name_to_alias(
struct query *
z,uint32 ttl)
114 z->alias[j] =
z->alias[j - 1];
116 z->aliasttl[j] =
z->aliasttl[j - 1];
117 z->alias[0] =
z->name[0];
118 z->aliasttl[0] = ttl;
123 static int rqa(
struct query *
z)
142 static int globalip(
char *d,
char ip[16])
149 byte_copy(
ip,12,V4mappedprefix);
156 if (
dd4(d,
"",
ip) == 4)
return 1;
163 static char *owner = 0;
164 static char *referral = 0;
165 static unsigned int *records = 0;
167 static int smaller(
char *
buf,
unsigned int len,
unsigned int pos1,
unsigned int pos2)
180 r = byte_diff(header1,4,header2);
186 if (len1 < len2)
return 1;
187 if (len1 > len2)
return 0;
189 r = case_diffb(t1,len1,t2);
193 if (pos1 < pos2)
return 1;
201 unsigned int cachedlen;
204 const char *whichserver;
213 unsigned int posanswers;
215 unsigned int posauthority;
217 unsigned int posglue;
240 if (state == 1)
goto HAVEPACKET;
249 d =
z->name[
z->level];
253 if (globalip(d,misc)) {
259 if (!rqa(
z))
goto DIE;
260 if (typematch(
DNS_T_A,dtype)) {
278 if (
z->level)
goto LOWERLEVEL;
279 if (!rqa(
z))
goto DIE;
280 if (typematch(
DNS_T_A,dtype)) {
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;
346 if (
z->level)
goto LOWERLEVEL;
347 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;
407 if (
z->level)
goto LOWERLEVEL;
408 if (!rqa(
z))
goto DIE;
421 if (
z->level)
goto LOWERLEVEL;
422 if (!rqa(
z))
goto DIE;
433 if (
z->level)
goto LOWERLEVEL;
434 if (!rqa(
z))
goto DIE;
446 if (
z->level)
goto LOWERLEVEL;
447 if (!rqa(
z))
goto DIE;
448 if (typematch(
DNS_T_A,dtype)) {
459 if (
z->level)
goto LOWERLEVEL;
460 if (!rqa(
z))
goto DIE;
461 if (typematch(
DNS_T_A,dtype)) {
474 byte_copy(key + 2,
dlen,d);
475 case_lowerb(key + 2,
dlen);
485 if (cached && cachedlen) {
488 if (!rqa(
z))
goto DIE;
495 if (!move_name_to_alias(
z,ttl))
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);
737 if (
cns_transmit_start(&
z->dt,
z->servers[
z->level],flagforwardonly,
z->name[
z->level],dtype,
z->localip,cnskey,publickey,control) < 0)
goto DIE;
753 len =
z->dt.packetlen;
755 whichserver =
z->dt.servers + 16 *
z->dt.curserver;
756 control =
z->control[
z->level];
757 d =
z->name[
z->level];
766 uint16_unpack_big(header + 6,&numanswers);
767 uint16_unpack_big(header + 8,&numauthority);
768 uint16_unpack_big(header + 10,&numglue);
770 rcode = header[3] & 15;
771 if (rcode && (rcode != 3))
goto DIE;
785 for (j = 0; j < numanswers; ++j) {
790 if (byte_equal(header + 2,2,
DNS_C_IN)) {
791 if (typematch(header,dtype))
798 uint16_unpack_big(header + 8,&datalen);
804 for (j = 0; j < numauthority; ++j) {
810 soattl = ttlget(header + 4);
811 if (soattl > 3600) soattl = 3600;
813 else if (typematch(header,
DNS_T_NS)) {
818 uint16_unpack_big(header + 8,&datalen);
824 if (flagsoa && (pos <=
len)) {
825 cachettl = ttlget(
buf + pos - 4);
826 if (soattl < cachettl) cachettl = soattl;
830 if (records) { alloc_free(records); records = 0; }
832 k = numanswers + numauthority + numglue;
833 records = (
unsigned int *) alloc(k *
sizeof(
unsigned int));
834 if (!records)
goto DIE;
837 for (j = 0; j < k; ++j) {
841 uint16_unpack_big(header + 8,&datalen);
847 if (i > 1) { --i; pos = records[i - 1]; }
848 else { pos = records[j - 1]; records[j - 1] = records[i - 1]; --j; }
851 while ((
p = q * 2) < j) {
852 if (!smaller(
buf,
len,records[
p],records[
p - 1])) ++
p;
853 records[q - 1] = records[
p - 1]; q =
p;
856 records[q - 1] = records[
p - 1]; q =
p;
858 while ((q > i) && smaller(
buf,
len,records[(
p = q/2) - 1],pos)) {
859 records[q - 1] = records[
p - 1]; q =
p;
861 records[q - 1] = pos;
870 ttl = ttlget(header + 4);
872 byte_copy(
type,2,header);
873 if (byte_diff(header + 2,2,
DNS_C_IN)) { ++i;
continue; }
875 for (j = i + 1; j < k; ++j) {
879 if (byte_diff(header,2,
type))
break;
880 if (byte_diff(header + 2,2,
DNS_C_IN))
break;
884 if (!
roots_same(t1,control)) { i = j;
continue; }
896 if (records[i] < posauthority)
897 log_rrsoa(whichserver,t1,t2,t3,misc,ttl);
935 log_rrmx(whichserver,t1,t2,misc,ttl);
947 if (byte_equal(header + 8,2,
"\0\4")) {
961 if (byte_equal(header + 8,2,
"\0\20")) {
963 save_data(header,16);
975 uint16_unpack_big(header + 8,&datalen);
976 if (datalen >
len - pos)
goto DIE;
977 save_data(header + 8,2);
978 save_data(
buf + pos,datalen);
982 save_finish(
type,t1,ttl);
988 alloc_free(records); records = 0;
997 for (j = 0; j < numanswers; ++j) {
1003 if (byte_equal(header + 2,2,
DNS_C_IN)) {
1005 ttl = ttlget(header + 4);
1007 if (!move_name_to_alias(
z,ttl))
goto DIE ;
1009 d =
z->name[
z->level];
1014 uint16_unpack_big(header + 8,&datalen);
1023 cachegeneric(
DNS_T_ANY,d,
"",0,cachettl);
1026 if (
z->level)
goto LOWERLEVEL;
1027 if (!rqa(
z))
goto DIE;
1043 if (!rcode && !flagout && flagreferral && !flagsoa)
1045 log_lame(whichserver,control,referral);
1046 byte_zero(whichserver,16);
1052 if (!flagout && flagsoa)
1056 save_finish(dtype,d,soattl);
1058 if (
z->level && !byte_diff(
DNS_T_A,2,dtype)) {
1059 d =
z->name[
z->level];
1060 z->ipv6[
z->level] = 1;
1067 if (flagout || flagsoa || !flagreferral) {
1071 for (j = 0; j < numanswers; ++j) {
1074 uint16_unpack_big(header + 8,&datalen);
1076 if (typematch(header,
DNS_T_A))
1077 if (byte_equal(header + 2,2,
DNS_C_IN))
1080 byte_copy(addr,12,V4mappedprefix);
1081 byte_copy(addr+12,4,misc);
1082 flagns =
cns_addns(
z,addr,flaghaskey,pubkey);
1086 if (byte_equal(header + 2,2,
DNS_C_IN))
1087 if (datalen == 16) {
1089 flagns =
cns_addns(
z,misc,flaghaskey,pubkey);
1098 if (!rqa(
z))
goto DIE;
1101 for (j = 0; j < numanswers; ++j) {
1104 ttl = ttlget(header + 4);
1105 uint16_unpack_big(header + 8,&datalen);
1107 if (byte_equal(header + 2,2,
DNS_C_IN))
1108 if (typematch(header,dtype)) {
1115 else if (typematch(header,
DNS_T_MX)) {
1130 if (pos + datalen >
len)
goto DIE;
1151 if (flagforwardonly) {
1153 byte_zero(whichserver,16);
1158 z->control[
z->level] = control;
1159 z->byzg = numauthority*100 + numglue;
1160 z->flagnskeys[
z->level] = 0;
1167 for (j = 0; j < numauthority; ++j) {
1170 uint16_unpack_big(header + 8,&datalen);
1173 if (byte_equal(header + 2,2,
DNS_C_IN))
1183 if (
z->level)
goto LOWERLEVEL;
1184 if (!rqa(
z))
goto DIE;
1192 if (records) { alloc_free(records); records = 0; }
1206 byte_copy(
z->type,2,
type);
1207 byte_copy(
z->class,2,
class);
1208 byte_copy(
z->localip,16,localip);
1209 z->scope_id = scope_id;
1220 case -1:
case -2:
case -3:
unsigned int doit(char *buf, unsigned int len, unsigned int pos)
void cache_set(const char *key, unsigned int keylen, const char *data, unsigned int datalen, uint32 ttl)
char * cache_get(const char *key, unsigned int keylen, unsigned int *datalen, uint32 *ttl)
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)
#define crypto_box_beforenm
#define crypto_scalarmult_base
int dd4(const char *q, const char *base, char ip[4])
void dns_transmit_free(struct dns_transmit *)
void dns_transmit_io(struct dns_transmit *, iopause_fd *, struct taia *)
unsigned int dns_packet_copy(const char *, unsigned int, unsigned int, char *, unsigned int)
int dns_domain_equal(const char *, const char *)
unsigned int dns_random(unsigned int)
int dns_domain_copy(char **, const char *)
int dns_domain_suffix(const char *, const char *)
unsigned int dns_packet_skipname(const char *, unsigned int, unsigned int)
void dns_domain_free(char **)
unsigned int dns_domain_length(const char *)
unsigned int dns_domain_suffixpos(const char *, const char *)
unsigned int dns_packet_getname(const char *, unsigned int, unsigned int, char **)
int dns_transmit_get(struct dns_transmit *, const iopause_fd *, const struct taia *)
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_rrmx(const char server[16], const char *q, const char *mx, const char pref[2], unsigned int ttl)
void log_rrcname(const char server[16], const char *q, const char *data, unsigned int ttl)
void log_servflag(const char server[16], int flag)
void log_servfail(const char *dn)
void log_tx(const char *q, const char qtype[2], const char *control, const char servers[512], int flagkey, unsigned int gluelessness)
void log_cachedanswer(const char *q, const char type[2])
void log_nxdomain(const char server[16], const char *q, unsigned int ttl)
void log_cachednxdomain(const char *dn)
void log_nodata(const char server[16], const char *q, const char qtype[2], unsigned int ttl)
void log_rrptr(const char server[16], const char *q, const char *data, unsigned int ttl)
void log_ignore_referral(const char server[16], const char *control, const char *referral)
void log_lame(const char server[16], const char *control, const char *referral)
void log_cachedcname(const char *dn, const char *dn2)
void log_rrsoa(const char server[16], const char *q, const char *n1, const char *n2, const char misc[20], unsigned int ttl)
void log_rrns(const char server[16], const char *q, const char *data, unsigned int ttl)
void log_cachedns(const char *control, const char *ns)
void log_rr(const char server[16], const char *q, const char type[2], const char *buf, unsigned int len, unsigned int ttl)
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_addbytes(const char *buf, unsigned int len)
int response_addname(const char *d)
int response_cname(const char *c, const char *d, uint32 ttl)
void response_rfinish(int x)
int response_query(const char *q, const char qtype[2], const char qclass[2])
void response_nxdomain(void)
void response_servfail(void)
int response_rstart(const char *d, const char type[2], uint32 ttl)
int roots_same(char *q, char *q2)
int roots(char servers[QUERY_MAXIPLEN], char *q)