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;
229 if (state == 1)
goto HAVEPACKET;
238 d =
z->name[
z->level];
242 if (globalip(d,misc)) {
248 if (!rqa(
z))
goto DIE;
249 if (typematch(
DNS_T_A,dtype)) {
267 if (
z->level)
goto LOWERLEVEL;
268 if (!rqa(
z))
goto DIE;
269 if (typematch(
DNS_T_A,dtype)) {
287 if (
z->level)
goto LOWERLEVEL;
288 if (!rqa(
z))
goto DIE;
299 if (
z->level)
goto LOWERLEVEL;
300 if (!rqa(
z))
goto DIE;
311 if (
z->level)
goto LOWERLEVEL;
312 if (!rqa(
z))
goto DIE;
323 if (
z->level)
goto LOWERLEVEL;
324 if (!rqa(
z))
goto DIE;
335 if (
z->level)
goto LOWERLEVEL;
336 if (!rqa(
z))
goto DIE;
348 if (
z->level)
goto LOWERLEVEL;
349 if (!rqa(
z))
goto DIE;
360 if (
z->level)
goto LOWERLEVEL;
361 if (!rqa(
z))
goto DIE;
372 if (
z->level)
goto LOWERLEVEL;
373 if (!rqa(
z))
goto DIE;
384 if (
z->level)
goto LOWERLEVEL;
385 if (!rqa(
z))
goto DIE;
396 if (
z->level)
goto LOWERLEVEL;
397 if (!rqa(
z))
goto DIE;
410 if (
z->level)
goto LOWERLEVEL;
411 if (!rqa(
z))
goto DIE;
422 if (
z->level)
goto LOWERLEVEL;
423 if (!rqa(
z))
goto DIE;
435 if (
z->level)
goto LOWERLEVEL;
436 if (!rqa(
z))
goto DIE;
437 if (typematch(
DNS_T_A,dtype)) {
448 if (
z->level)
goto LOWERLEVEL;
449 if (!rqa(
z))
goto DIE;
450 if (typematch(
DNS_T_A,dtype)) {
476 byte_copy(key + 2,
dlen,d);
477 case_lowerb(key + 2,
dlen);
487 if (cached && cachedlen) {
490 if (!rqa(
z))
goto DIE;
504 if (cached && (cachedlen || byte_diff(dtype,2,
DNS_T_ANY))) {
507 flagns =
cns_addns(
z,cached,flaghaskey,pubkey);
511 if (!rqa(
z))
goto DIE;
526 if (cached && (cachedlen || byte_diff(dtype,2,
DNS_T_ANY))) {
528 if (!rqa(
z))
goto DIE;
543 if (cached && (cachedlen || byte_diff(dtype,2,
DNS_T_ANY))) {
545 if (!rqa(
z))
goto DIE;
560 if (typematch(
DNS_T_A,dtype)) {
564 if (cached && !cachedlen &&
z->level) {
565 z->ipv6[
z->level] = 1;
568 if (cached && (cachedlen || byte_diff(dtype,2,
DNS_T_ANY))) {
572 while (cachedlen >= 4) {
574 if (byte_equal(
z->servers[
z->level - 1] + k,16,V6localnet)) {
575 byte_copy(
z->servers[
z->level - 1] + k,12,V4mappedprefix);
576 byte_copy(
z->servers[
z->level - 1] + k + 12,4,cached);
579 byte_copy(addr,12,V4mappedprefix);
580 byte_copy(addr+12,4,cached);
590 if (!rqa(
z))
goto DIE;
591 while (cachedlen >= 4) {
606 if (cached && (cachedlen || byte_diff(dtype,2,
DNS_T_ANY))) {
610 while (cachedlen >= 16) {
611 flagns =
cns_addns(
z,cached,flaghaskey,pubkey);
620 if (!rqa(
z))
goto DIE;
621 while (cachedlen >= 16) {
637 byte_copy(key,2,dtype);
639 if (cached && (cachedlen || byte_diff(dtype,2,
DNS_T_ANY))) {
641 if (!rqa(
z))
goto DIE;
642 while (cachedlen >= 2) {
643 uint16_unpack_big(cached,&datalen);
646 if (datalen > cachedlen)
goto DIE;
651 cachedlen -= datalen;
661 if (
roots(
z->servers[
z->level],d)) {
662 z->flagnskeys[
z->level] = 0;
665 z->control[
z->level] =
d;
669 if (!flagforwardonly && (
z->level < 2))
672 byte_copy(key + 2,
dlen,d);
673 case_lowerb(key + 2,
dlen);
675 if (cached && cachedlen) {
676 z->control[
z->level] =
d;
678 z->flagnskeys[
z->level] = 0;
693 j = 1 + (
unsigned int) (
unsigned char) *
d;
701 if (
z->ns[
z->level][j]) {
706 z->ipv6[
z->level] = 0;
713 if (byte_diff(
z->servers[
z->level] + j,16,V6localnet))
break;
716 if (
z->flagnskeys[
z->level]) {
719 if (byte_diff(
z->servers[
z->level] + j,16,V6localnet)) {
720 whichkey =
z->keys[
z->level] + 2 * j;
721 byte_copy(key + 2,32,whichkey);
722 cached =
cache_get(key,34,&cachedlen,&ttl);
723 if (cached && (cachedlen == 32)) {
724 byte_copy(whichkey,32,cached);
727 crypto_box_beforenm((
unsigned char *) whichkey,(
const unsigned char *) whichkey,(
const unsigned char *) secretkey);
735 cnskey =
z->flagnskeys[
z->level] ?
z->keys[
z->level] : 0;
736 log_tx(
z->name[
z->level],dtype,
z->control[
z->level],
z->servers[
z->level],
z->flagnskeys[
z->level],
z->level);
739 dtype,
z->localip,cnskey,publickey,control) < 0)
goto DIE;
755 len =
z->dt.packetlen;
757 whichserver =
z->dt.servers + 16 *
z->dt.curserver;
758 control =
z->control[
z->level];
759 d =
z->name[
z->level];
768 uint16_unpack_big(header + 6,&numanswers);
769 uint16_unpack_big(header + 8,&numauthority);
770 uint16_unpack_big(header + 10,&numglue);
772 rcode = header[3] & 15;
773 if (rcode && (rcode != 3))
goto DIE;
783 for (j = 0; j < numanswers; ++j) {
788 if (byte_equal(header + 2,2,
DNS_C_IN)) {
789 if (typematch(header,dtype))
794 cnamettl = ttlget(header + 4);
798 uint16_unpack_big(header + 8,&datalen);
803 for (j = 0; j < numauthority; ++j) {
809 soattl = ttlget(header + 4);
810 if (soattl > 3600) soattl = 3600;
812 else if (typematch(header,
DNS_T_NS)) {
817 uint16_unpack_big(header + 8,&datalen);
823 if (flagsoa && (pos <=
len)) {
824 cachettl = ttlget(
buf + pos - 4);
825 if (soattl < cachettl) cachettl = soattl;
828 if (!flagcname && !rcode && !flagout && flagreferral && !flagsoa)
830 log_lame(whichserver,control,referral);
831 byte_zero((
char *)whichserver,4);
835 if (records) { alloc_free(records); records = 0; }
837 k = numanswers + numauthority + numglue;
838 records = (
unsigned int *) alloc(k *
sizeof(
unsigned int));
839 if (!records)
goto DIE;
842 for (j = 0; j < k; ++j) {
846 uint16_unpack_big(header + 8,&datalen);
852 if (i > 1) { --i; pos = records[i - 1]; }
853 else { pos = records[j - 1]; records[j - 1] = records[i - 1]; --j; }
856 while ((
p = q * 2) < j) {
857 if (!smaller(
buf,
len,records[
p],records[
p - 1])) ++
p;
858 records[q - 1] = records[
p - 1]; q =
p;
861 records[q - 1] = records[
p - 1]; q =
p;
863 while ((q > i) && smaller(
buf,
len,records[(
p = q/2) - 1],pos)) {
864 records[q - 1] = records[
p - 1]; q =
p;
866 records[q - 1] = pos;
875 ttl = ttlget(header + 4);
877 byte_copy(
type,2,header);
878 if (byte_diff(header + 2,2,
DNS_C_IN)) { ++i;
continue; }
880 for (j = i + 1; j < k; ++j) {
884 if (byte_diff(header,2,
type))
break;
885 if (byte_diff(header + 2,2,
DNS_C_IN))
break;
889 if (!
roots_same(t1,control)) { i = j;
continue; }
901 if (records[i] < posauthority)
902 log_rrsoa(whichserver,t1,t2,t3,misc,ttl);
940 log_rrmx(whichserver,t1,t2,misc,ttl);
952 if (byte_equal(header + 8,2,
"\0\4")) {
966 if (byte_equal(header + 8,2,
"\0\20")) {
968 save_data(header,16);
980 uint16_unpack_big(header + 8,&datalen);
981 if (datalen >
len - pos)
goto DIE;
982 save_data(header + 8,2);
983 save_data(
buf + pos,datalen);
987 save_finish(
type,t1,ttl);
993 alloc_free(records); records = 0;
1004 z->alias[j] =
z->alias[j - 1];
1007 z->aliasttl[j] =
z->aliasttl[j - 1];
1009 z->alias[0] =
z->name[0];
1010 z->aliasttl[0] = ttl;
1019 cachegeneric(
DNS_T_ANY,d,
"",0,cachettl);
1022 if (
z->level)
goto LOWERLEVEL;
1023 if (!rqa(
z))
goto DIE;
1031 if (!flagout && flagsoa)
1035 save_finish(dtype,d,soattl);
1037 if (
z->level && !byte_diff(
DNS_T_A,2,dtype)) {
1038 d =
z->name[
z->level];
1039 z->ipv6[
z->level] = 1;
1046 if (flagout || flagsoa || !flagreferral) {
1050 for (j = 0; j < numanswers; ++j) {
1053 uint16_unpack_big(header + 8,&datalen);
1055 if (typematch(header,
DNS_T_A))
1056 if (byte_equal(header + 2,2,
DNS_C_IN))
1059 byte_copy(addr,12,V4mappedprefix);
1060 byte_copy(addr+12,4,misc);
1061 flagns =
cns_addns(
z,addr,flaghaskey,pubkey);
1065 if (byte_equal(header + 2,2,
DNS_C_IN))
1066 if (datalen == 16) {
1068 flagns =
cns_addns(
z,misc,flaghaskey,pubkey);
1077 if (!rqa(
z))
goto DIE;
1080 for (j = 0; j < numanswers; ++j) {
1083 ttl = ttlget(header + 4);
1084 uint16_unpack_big(header + 8,&datalen);
1086 if (byte_equal(header + 2,2,
DNS_C_IN))
1087 if (typematch(header,dtype)) {
1094 else if (typematch(header,
DNS_T_MX)) {
1109 if (pos + datalen >
len)
goto DIE;
1130 if (flagforwardonly) {
1132 byte_zero((
char *)whichserver,16);
1137 z->control[
z->level] = control;
1138 z->byzg = numauthority*100 + numglue;
1139 z->flagnskeys[
z->level] = 0;
1146 for (j = 0; j < numauthority; ++j) {
1149 uint16_unpack_big(header + 8,&datalen);
1152 if (byte_equal(header + 2,2,
DNS_C_IN))
1162 if (
z->level)
goto LOWERLEVEL;
1163 if (!rqa(
z))
goto DIE;
1171 if (records) { alloc_free(records); records = 0; }
1184 byte_copy(
z->type,2,
type);
1185 byte_copy(
z->class,2,
class);
1186 byte_copy(
z->localip,16,localip);
1187 z->scope_id = scope_id;
1198 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)
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_rrptr(const char[16], const char *, const char *, unsigned int)
void log_rr(const char[16], const char *, const char[2], const char *, unsigned int, unsigned int)
void log_lame(const char[16], const char *, const char *)
void log_tx(const char *, const char[2], const char *, const char[QUERY_MAXIPLEN], int, unsigned int)
void log_rrmx(const char[16], const char *, const char *, const char[2], unsigned int)
void log_ignore_referral(const char[16], const char *, const char *)
void log_servfail(const char *)
void log_servflag(const char[16], int)
void log_nxdomain(const char[16], const char *, unsigned int)
void log_nodata(const char[16], const char *, const char[2], unsigned int)
void log_rrns(const char[16], const char *, const char *, unsigned int)
void log_cachedcname(const char *, const char *)
void log_cachedanswer(const char *, const char[2])
void log_rrsoa(const char[16], const char *, const char *, const char *, const char[20], unsigned int)
void log_cachednxdomain(const char *)
void log_cachedns(const char *, const char *)
void log_rrcname(const char[16], const char *, const char *, 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_rstart(const char *, const char[2], uint32)
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_query(const char *, const char[2], const char[2])
void response_nxdomain(void)
void response_servfail(void)
int roots(char[QUERY_MAXIPLEN], 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)