33static int flagforwardonly = 0;
40static void cachegeneric(
const char type[2],
const char *d,
const char *
data,
unsigned int datalen,uint32 ttl)
48 byte_copy(key,2,
type);
49 byte_copy(key + 2,
len,d);
50 case_lowerb(key + 2,
len);
55static char save_buf[8192];
56static unsigned int save_len;
57static unsigned int save_ok;
59static void save_start(
void)
65static void save_data(
const char *
buf,
unsigned int len)
68 if (
len > (
sizeof(save_buf)) - save_len) { save_ok = 0;
return; }
69 byte_copy(save_buf + save_len,
len,
buf);
73static void save_finish(
const char type[2],
const char *d,uint32 ttl)
76 cachegeneric(
type,d,save_buf,save_len,ttl);
79static int typematch(
const char rtype[2],
const char qtype[2])
81 return byte_equal(qtype,2,rtype) || byte_equal(qtype,2,
DNS_T_ANY);
84static uint32 ttlget(
char buf[4])
88 uint32_unpack_big(
buf,&ttl);
89 if (ttl > 1000000000)
return 0;
90 if (ttl > 604800)
return 604800;
94static void cleanup(
struct query *
z)
109static int rqa(
struct query *
z)
128static int globalip(
char *d,
char ip[16])
135 byte_copy(
ip,12,V4mappedprefix);
142 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;
201 unsigned int posanswers;
203 unsigned int posauthority;
230 if (state == 1)
goto HAVEPACKET;
239 d =
z->name[
z->level];
243 if (globalip(d,misc)) {
249 if (!rqa(
z))
goto DIE;
250 if (typematch(
DNS_T_A,dtype)) {
268 if (
z->level)
goto LOWERLEVEL;
269 if (!rqa(
z))
goto DIE;
270 if (typematch(
DNS_T_A,dtype)) {
288 if (
z->level)
goto LOWERLEVEL;
289 if (!rqa(
z))
goto DIE;
300 if (
z->level)
goto LOWERLEVEL;
301 if (!rqa(
z))
goto DIE;
312 if (
z->level)
goto LOWERLEVEL;
313 if (!rqa(
z))
goto DIE;
324 if (
z->level)
goto LOWERLEVEL;
325 if (!rqa(
z))
goto DIE;
336 if (
z->level)
goto LOWERLEVEL;
337 if (!rqa(
z))
goto DIE;
349 if (
z->level)
goto LOWERLEVEL;
350 if (!rqa(
z))
goto DIE;
361 if (
z->level)
goto LOWERLEVEL;
362 if (!rqa(
z))
goto DIE;
373 if (
z->level)
goto LOWERLEVEL;
374 if (!rqa(
z))
goto DIE;
385 if (
z->level)
goto LOWERLEVEL;
386 if (!rqa(
z))
goto DIE;
397 if (
z->level)
goto LOWERLEVEL;
398 if (!rqa(
z))
goto DIE;
411 if (
z->level)
goto LOWERLEVEL;
412 if (!rqa(
z))
goto DIE;
423 if (
z->level)
goto LOWERLEVEL;
424 if (!rqa(
z))
goto DIE;
436 if (
z->level)
goto LOWERLEVEL;
437 if (!rqa(
z))
goto DIE;
438 if (typematch(
DNS_T_A,dtype)) {
449 if (
z->level)
goto LOWERLEVEL;
450 if (!rqa(
z))
goto DIE;
451 if (typematch(
DNS_T_A,dtype)) {
477 byte_copy(key + 2,
dlen,d);
478 case_lowerb(key + 2,
dlen);
488 if (cached && cachedlen) {
491 if (!rqa(
z))
goto DIE;
505 if (cached && (cachedlen || byte_diff(dtype,2,
DNS_T_ANY))) {
508 flagns =
cns_addns(
z,cached,flaghaskey,pubkey);
512 if (!rqa(
z))
goto DIE;
527 if (cached && (cachedlen || byte_diff(dtype,2,
DNS_T_ANY))) {
529 if (!rqa(
z))
goto DIE;
544 if (cached && (cachedlen || byte_diff(dtype,2,
DNS_T_ANY))) {
546 if (!rqa(
z))
goto DIE;
561 if (typematch(
DNS_T_A,dtype)) {
565 if (cached && !cachedlen &&
z->level) {
566 z->ipv6[
z->level] = 1;
569 if (cached && (cachedlen || byte_diff(dtype,2,
DNS_T_ANY))) {
573 while (cachedlen >= 4) {
575 if (byte_equal(
z->servers[
z->level - 1] + k,16,V6localnet)) {
576 byte_copy(
z->servers[
z->level - 1] + k,12,V4mappedprefix);
577 byte_copy(
z->servers[
z->level - 1] + k + 12,4,cached);
580 byte_copy(addr,12,V4mappedprefix);
581 byte_copy(addr + 12,4,cached);
591 if (!rqa(
z))
goto DIE;
592 while (cachedlen >= 4) {
607 if (cached && (cachedlen || byte_diff(dtype,2,
DNS_T_ANY))) {
611 while (cachedlen >= 16) {
612 flagns =
cns_addns(
z,cached,flaghaskey,pubkey);
621 if (!rqa(
z))
goto DIE;
622 while (cachedlen >= 16) {
638 byte_copy(key,2,dtype);
640 if (cached && (cachedlen || byte_diff(dtype,2,
DNS_T_ANY))) {
642 if (!rqa(
z))
goto DIE;
643 while (cachedlen >= 2) {
644 uint16_unpack_big(cached,&datalen);
647 if (datalen > cachedlen)
goto DIE;
652 cachedlen -= datalen;
662 if (
roots(
z->servers[
z->level],d)) {
663 z->flagnskeys[
z->level] = 0;
666 z->control[
z->level] =
d;
670 if (!flagforwardonly && (
z->level < 2))
673 byte_copy(key + 2,
dlen,d);
674 case_lowerb(key + 2,
dlen);
676 if (cached && cachedlen) {
677 z->control[
z->level] =
d;
679 z->flagnskeys[
z->level] = 0;
694 j = 1 + (
unsigned int) (
unsigned char) *
d;
702 if (
z->ns[
z->level][j]) {
707 z->ipv6[
z->level] = 0;
714 if (byte_diff(
z->servers[
z->level] + j,16,V6localnet))
break;
719 if (
z->flagnskeys[
z->level]) {
722 if (byte_diff(
z->servers[
z->level] + j,16,V6localnet)) {
723 whichkey =
z->keys[
z->level] + 2 * j;
724 byte_copy(key + 2,
KEY_LEN,whichkey);
726 if (cached && (cachedlen ==
KEY_LEN)) {
727 byte_copy(whichkey,
KEY_LEN,cached);
730 crypto_box_beforenm((
unsigned char *)whichkey,(
const unsigned char *)whichkey,(
const unsigned char *)secretkey);
738 cnskey =
z->flagnskeys[
z->level] ?
z->keys[
z->level] : 0;
744 if (
z->ctx[
z->level][i] ==
'd') { flagedns = 0;
break; }
749 if (cnskey) { flagtx = 3;
if (control) flagtx = 4; }
750 log_tx(
z->name[
z->level],dtype,
z->control[
z->level],
z->servers[
z->level],flagtx,
z->level);
754 const char qflags[2] = { flagforwardonly, flagedns };
756 dtype,
z->localip,cnskey,publickey,control) < 0)
goto DIE;
772 len =
z->dt.packetlen;
774 whichserver =
z->dt.servers + 16 *
z->dt.curserver;
775 control =
z->control[
z->level];
776 d =
z->name[
z->level];
785 uint16_unpack_big(header + 6,&numanswers);
786 uint16_unpack_big(header + 8,&numauthority);
787 uint16_unpack_big(header + 10,&numglue);
789 rcode = header[3] & 15;
790 if (rcode && (rcode != 3))
goto DIE;
800 for (j = 0; j < numanswers; ++j) {
805 if (byte_equal(header + 2,2,
DNS_C_IN)) {
806 if (typematch(header,dtype))
811 cnamettl = ttlget(header + 4);
815 uint16_unpack_big(header + 8,&datalen);
820 for (j = 0; j < numauthority; ++j) {
826 soattl = ttlget(header + 4);
827 if (soattl > 3600) soattl = 3600;
829 else if (typematch(header,
DNS_T_NS)) {
834 uint16_unpack_big(header + 8,&datalen);
840 if (flagsoa && (pos <=
len)) {
841 cachettl = ttlget(
buf + pos - 4);
842 if (soattl < cachettl) cachettl = soattl;
845 if (!flagcname && !rcode && !flagout && flagreferral && !flagsoa)
847 log_lame(whichserver,control,referral);
848 byte_zero((
char *)whichserver,4);
852 if (records) { alloc_free(records); records = 0; }
855 k = numanswers + numauthority + numglue;
856 records = (
unsigned int *)alloc(k *
sizeof(
unsigned int));
857 if (!records)
goto DIE;
860 for (j = 0; j < k; ++j) {
864 uint16_unpack_big(header + 8,&datalen);
870 if (i > 1) { --i; pos = records[i - 1]; }
871 else { pos = records[j - 1]; records[j - 1] = records[i - 1]; --j; }
874 while ((
p = q * 2) < j) {
875 if (!smaller(
buf,
len,records[
p],records[
p - 1])) ++
p;
876 records[q - 1] = records[
p - 1]; q =
p;
879 records[q - 1] = records[
p - 1]; q =
p;
881 while ((q > i) && smaller(
buf,
len,records[(
p = q/2) - 1],pos)) {
882 records[q - 1] = records[
p - 1]; q =
p;
884 records[q - 1] = pos;
893 ttl = ttlget(header + 4);
895 byte_copy(
type,2,header);
896 if (byte_diff(header + 2,2,
DNS_C_IN)) { ++i;
continue; }
898 for (j = i + 1; j < k; ++j) {
902 if (byte_diff(header,2,
type))
break;
903 if (byte_diff(header + 2,2,
DNS_C_IN))
break;
907 if (!
roots_same(t1,control)) { i = j;
continue; }
919 if (records[i] < posauthority)
920 log_rrsoa(whichserver,t1,t2,t3,misc,ttl);
958 log_rrmx(whichserver,t1,t2,misc,ttl);
970 if (byte_equal(header + 8,2,
"\0\4")) {
984 if (byte_equal(header + 8,2,
"\0\20")) {
986 save_data(header,16);
998 uint16_unpack_big(header + 8,&datalen);
999 if (datalen >
len - pos)
goto DIE;
1000 save_data(header + 8,2);
1001 save_data(
buf + pos,datalen);
1005 save_finish(
type,t1,ttl);
1011 alloc_free(records); records = 0;
1022 z->alias[j] =
z->alias[j - 1];
1025 z->aliasttl[j] =
z->aliasttl[j - 1];
1027 z->alias[0] =
z->name[0];
1028 z->aliasttl[0] = ttl;
1037 cachegeneric(
DNS_T_ANY,d,
"",0,cachettl);
1040 if (
z->level)
goto LOWERLEVEL;
1041 if (!rqa(
z))
goto DIE;
1049 if (!flagout && flagsoa)
1053 save_finish(dtype,d,soattl);
1055 if (
z->level && !byte_diff(
DNS_T_A,2,dtype)) {
1056 d =
z->name[
z->level];
1057 z->ipv6[
z->level] = 1;
1064 if (flagout || flagsoa || !flagreferral) {
1068 for (j = 0; j < numanswers; ++j) {
1071 uint16_unpack_big(header + 8,&datalen);
1073 if (typematch(header,
DNS_T_A))
1074 if (byte_equal(header + 2,2,
DNS_C_IN))
1077 byte_copy(addr,12,V4mappedprefix);
1078 byte_copy(addr + 12,4,misc);
1079 flagns =
cns_addns(
z,addr,flaghaskey,pubkey);
1083 if (byte_equal(header + 2,2,
DNS_C_IN))
1084 if (datalen == 16) {
1086 flagns =
cns_addns(
z,misc,flaghaskey,pubkey);
1095 if (!rqa(
z))
goto DIE;
1098 for (j = 0; j < numanswers; ++j) {
1101 ttl = ttlget(header + 4);
1102 uint16_unpack_big(header + 8,&datalen);
1104 if (byte_equal(header + 2,2,
DNS_C_IN))
1105 if (typematch(header,dtype)) {
1112 else if (typematch(header,
DNS_T_MX)) {
1127 if (pos + datalen >
len)
goto DIE;
1148 if (flagforwardonly) {
1150 byte_zero((
char *)whichserver,16);
1155 z->control[
z->level] = control;
1156 z->byzg = numauthority*100 + numglue;
1157 z->flagnskeys[
z->level] = 0;
1164 for (j = 0; j < numauthority; ++j) {
1167 uint16_unpack_big(header + 8,&datalen);
1170 if (byte_equal(header + 2,2,
DNS_C_IN))
1180 if (
z->level)
goto LOWERLEVEL;
1181 if (!rqa(
z))
goto DIE;
1189 if (records) { alloc_free(records); records = 0; }
1202 byte_copy(
z->type,2,
type);
1203 byte_copy(
z->class,2,
class);
1204 byte_copy(
z->localip,16,localip);
1205 z->scope_id = scope_id;
1216 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], char qflags[2], const char *q, const char qtype[2], const char localip[16], const char keys[QUERY_MAXNS *KEY_LEN], const char pubkey[KEY_LEN], 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 p(char *home, char *fifo, 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 *, 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)