djbdnscurve6  38
djbdnscurve6
query.c
Go to the documentation of this file.
1 #include "error.h"
2 #include "roots.h"
3 #include "log.h"
4 #include "case.h"
5 #include "cache.h"
6 #include "byte.h"
7 #include "dns.h"
8 #include "uint_t.h"
9 #include "dd.h"
10 #include "alloc.h"
11 #include "response.h"
12 #include "query.h"
13 #include "ip.h"
14 #include "curvedns.h"
15 
16 extern int flagusetxtformat;
17 
18 static char secretkey[32];
19 static char publickey[32];
20 
21 void query_init(void)
22 {
23  int k;
24 
25  /* called after droproot(), can't use crypto_box_keypair (depends on /dev/urandom) */
26  for (k = 0; k < 32; ++k)
27  secretkey[k] = dns_random(256);
28  crypto_scalarmult_base((unsigned char *) publickey,(unsigned char *) secretkey);
29 
30 }
31 
32 static int flagforwardonly = 0;
33 
35 {
36  flagforwardonly = 1;
37 }
38 
39 static void cachegeneric(const char type[2],const char *d,const char *data,unsigned int datalen,uint32 ttl)
40 {
41  unsigned int len;
42  char key[257];
43 
45  if (len > 255) return;
46 
47  byte_copy(key,2,type);
48  byte_copy(key + 2,len,d);
49  case_lowerb(key + 2,len);
50 
51  cache_set(key,len + 2,data,datalen,ttl);
52 }
53 
54 static char save_buf[8192];
55 static unsigned int save_len;
56 static unsigned int save_ok;
57 
58 static void save_start(void)
59 {
60  save_len = 0;
61  save_ok = 1;
62 }
63 
64 static void save_data(const char *buf,unsigned int len)
65 {
66  if (!save_ok) return;
67  if (len > (sizeof(save_buf)) - save_len) { save_ok = 0; return; }
68  byte_copy(save_buf + save_len,len,buf);
69  save_len += len;
70 }
71 
72 static void save_finish(const char type[2],const char *d,uint32 ttl)
73 {
74  if (!save_ok) return;
75  cachegeneric(type,d,save_buf,save_len,ttl);
76 }
77 
78 static int typematch(const char rtype[2],const char qtype[2])
79 {
80  return byte_equal(qtype,2,rtype) || byte_equal(qtype,2,DNS_T_ANY);
81 }
82 
83 static uint32 ttlget(char buf[4])
84 {
85  uint32 ttl;
86 
87  uint32_unpack_big(buf,&ttl);
88  if (ttl > 1000000000) return 0;
89  if (ttl > 604800) return 604800;
90  return ttl;
91 }
92 
93 static void cleanup(struct query *z)
94 {
95  int j;
96  int k;
97 
98  dns_transmit_free(&z->dt);
99  for (j = 0; j < QUERY_MAXALIAS; ++j)
100  dns_domain_free(&z->alias[j]);
101  for (j = 0; j < QUERY_MAXLEVEL; ++j) {
102  dns_domain_free(&z->name[j]);
103  for (k = 0; k < QUERY_MAXNS; ++k)
104  dns_domain_free(&z->ns[j][k]);
105  }
106 }
107 
108 static int move_name_to_alias(struct query *z,uint32 ttl)
109 {
110  int j ;
111 
112  if (z->alias[QUERY_MAXALIAS - 1]) return 0;
113  for (j = QUERY_MAXALIAS - 1; j > 0 ;--j)
114  z->alias[j] = z->alias[j - 1];
115  for (j = QUERY_MAXALIAS - 1; j > 0; --j)
116  z->aliasttl[j] = z->aliasttl[j - 1];
117  z->alias[0] = z->name[0];
118  z->aliasttl[0] = ttl;
119  z->name[0] = 0;
120  return 1;
121 }
122 
123 static int rqa(struct query *z)
124 {
125  int i;
126 
127  for (i = QUERY_MAXALIAS - 1; i >= 0; --i)
128  if (z->alias[i]) {
129  if (!response_query(z->alias[i],z->type,z->class)) return 0;
130  while (i > 0) {
131  if (!response_cname(z->alias[i],z->alias[i - 1],z->aliasttl[i])) return 0;
132  --i;
133  }
134  if (!response_cname(z->alias[0],z->name[0],z->aliasttl[0])) return 0;
135  return 1;
136  }
137 
138  if (!response_query(z->name[0],z->type,z->class)) return 0;
139  return 1;
140 }
141 
142 static int globalip(char *d,char ip[16])
143 {
144  if (dns_domain_equal(d,"\014ip6-loopback\0")) {
145  byte_copy(ip,16,IP6_LOOPBACK_OCTAL);
146  return 1;
147  }
148  if (dns_domain_equal(d,"\014ip4-loopback\0")) {
149  byte_copy(ip,12,V4mappedprefix);
150  byte_copy(ip + 12,4,IP4_LOOPBACK_OCTAL);
151  return 1;
152  }
153 
154  /* Domain names may look like IPv4 addresses: 1.2.3.com; not like IPv6 */
155 
156  if (dd4(d,"",ip) == 4) return 1;
157  return 0;
158 }
159 
160 static char *t1 = 0;
161 static char *t2 = 0;
162 static char *t3 = 0;
163 static char *owner = 0;
164 static char *referral = 0;
165 static unsigned int *records = 0;
166 
167 static int smaller(char *buf,unsigned int len,unsigned int pos1,unsigned int pos2)
168 {
169  char header1[12];
170  char header2[12];
171  int r;
172  unsigned int len1;
173  unsigned int len2;
174 
175  pos1 = dns_packet_getname(buf,len,pos1,&t1);
176  dns_packet_copy(buf,len,pos1,header1,10);
177  pos2 = dns_packet_getname(buf,len,pos2,&t2);
178  dns_packet_copy(buf,len,pos2,header2,10);
179 
180  r = byte_diff(header1,4,header2);
181  if (r < 0) return 1;
182  if (r > 0) return 0;
183 
184  len1 = dns_domain_length(t1);
185  len2 = dns_domain_length(t2);
186  if (len1 < len2) return 1;
187  if (len1 > len2) return 0;
188 
189  r = case_diffb(t1,len1,t2);
190  if (r < 0) return 1;
191  if (r > 0) return 0;
192 
193  if (pos1 < pos2) return 1;
194  return 0;
195 }
196 
197 static int doit(struct query *z,int state)
198 {
199  char key[257];
200  char *cached;
201  unsigned int cachedlen;
202  char *buf;
203  unsigned int len;
204  const char *whichserver;
205  char *whichkey;
206  char header[24];
207  char addr[16];
208  char misc[20];
209  char pubkey[32];
210  int flaghaskey;
211  int flagns;
212  unsigned int rcode;
213  unsigned int posanswers;
214  uint16 numanswers;
215  unsigned int posauthority;
216  uint16 numauthority;
217  unsigned int posglue;
218  uint16 numglue;
219  unsigned int pos;
220  unsigned int pos2;
221  uint16 datalen;
222  char *control;
223  char *d;
224  const char *dtype;
225  unsigned int dlen;
226  int flagout;
227  int flagreferral;
228  int flagsoa;
229  const char *cnskey;
230  uint32 ttl;
231  uint32 soattl;
232  uint32 cachettl;
233  int i;
234  int j;
235  int k;
236  int p;
237  int q;
238 
239  errno = EIO;
240  if (state == 1) goto HAVEPACKET;
241  if (state == -1) {
242  log_servfail(z->name[z->level]);
243  goto SERVFAIL;
244  }
245 
246 
247  NEWNAME:
248  if (++z->loop == QUERY_MAXLOOP) goto DIE;
249  d = z->name[z->level];
250  dtype = z->level ? (z->ipv6[z->level] ? DNS_T_AAAA : DNS_T_A) : z->type;
251  dlen = dns_domain_length(d);
252 
253  if (globalip(d,misc)) {
254  if (z->level) {
255  flagns = cns_addns(z,misc,0,0); /* new; ok */
256  if (flagns) log_servflag(addr,flagns);
257  goto LOWERLEVEL;
258  }
259  if (!rqa(z)) goto DIE;
260  if (typematch(DNS_T_A,dtype)) {
261  if (!response_rstart(d,DNS_T_A,655360)) goto DIE;
262  if (!response_addbytes(misc,4)) goto DIE;
264  }
265  if (typematch(DNS_T_AAAA,dtype)) {
266  if (!response_rstart(d,DNS_T_AAAA,655360)) goto DIE;
267  if (!response_addbytes(misc,16)) goto DIE;
269  }
270  cleanup(z);
271  return 1;
272  }
273 
274  /* common localhost and loopback handling (query.h) */
275 
276  if (dns_domain_equal(d,"\011localhost\0") ||
277  dns_domain_equal(d,"\010loopback\0")) {
278  if (z->level) goto LOWERLEVEL;
279  if (!rqa(z)) goto DIE;
280  if (typematch(DNS_T_A,dtype)) {
281  if (!response_rstart(d,DNS_T_A,655360)) goto DIE;
282  if (!response_addbytes(IP4_LOOPBACK_OCTAL,4)) goto DIE;
284  }
285  if (typematch(DNS_T_AAAA,dtype)) {
286  if (!response_rstart(d,DNS_T_AAAA,655360)) goto DIE;
287  if (!response_addbytes(IP6_LOOPBACK_OCTAL,16)) goto DIE;
289  }
290  cleanup(z);
291  return 1;
292  }
293 
294  /* IPv6 well-known names (query.h) RFC 4291 */
295 
298  if (z->level) goto LOWERLEVEL;
299  if (!rqa(z)) goto DIE;
300  if (typematch(DNS_T_PTR,dtype)) {
301  if (!response_rstart(d,DNS_T_PTR,655360)) goto DIE;
302  if (!response_addname("\014ip4-loopback\0")) goto DIE;
304  }
305  cleanup(z);
306  return 1;
307  }
308 
309  if (dns_domain_equal(d,IP6_LOCALNET_ARPA)) { /* unspecified IPv6 */
310  if (z->level) goto LOWERLEVEL;
311  if (!rqa(z)) goto DIE;
312  if (typematch(DNS_T_PTR,dtype)) {
313  if (!response_rstart(d,DNS_T_PTR,655360)) goto DIE;
314  if (!response_addname("\014ip6-localnet\0")) goto DIE;
316  }
317  cleanup(z);
318  return 1;
319  }
320 
322  if (z->level) goto LOWERLEVEL;
323  if (!rqa(z)) goto DIE;
324  if (typematch(DNS_T_PTR,dtype)) {
325  if (!response_rstart(d,DNS_T_PTR,655360)) goto DIE;
326  if (!response_addname("\017ip6-mcastprefix\0")) goto DIE;
328  }
329  cleanup(z);
330  return 1;
331  }
332 
334  if (z->level) goto LOWERLEVEL;
335  if (!rqa(z)) goto DIE;
336  if (typematch(DNS_T_PTR,dtype)) {
337  if (!response_rstart(d,DNS_T_PTR,655360)) goto DIE;
338  if (!response_addname("\016ip6-allnodes\0")) goto DIE;
340  }
341  cleanup(z);
342  return 1;
343  }
344 
346  if (z->level) goto LOWERLEVEL;
347  if (!rqa(z)) goto DIE;
348  if (typematch(DNS_T_PTR,dtype)) {
349  if (!response_rstart(d,DNS_T_PTR,655360)) goto DIE;
350  if (!response_addname("\016ip6-allrouters\0")) goto DIE;
352  }
353  cleanup(z);
354  return 1;
355  }
356 
357  if (dns_domain_equal(d,"\015ip6-localhost\0") ||
358  dns_domain_equal(d,"\014ip6-loopback\0")) {
359  if (z->level) goto LOWERLEVEL;
360  if (!rqa(z)) goto DIE;
361  if (typematch(DNS_T_AAAA,dtype)) {
362  if (!response_rstart(d,DNS_T_AAAA,655360)) goto DIE;
363  if (!response_addbytes(IP6_LOOPBACK_OCTAL,16)) goto DIE;
365  }
366  cleanup(z);
367  return 1;
368  }
369 
370  if (dns_domain_equal(d,"\014ip6-localnet\0")) {
371  if (z->level) goto LOWERLEVEL;
372  if (!rqa(z)) goto DIE;
373  if (typematch(DNS_T_AAAA,dtype)) {
374  if (!response_rstart(d,DNS_T_AAAA,655360)) goto DIE;
375  if (!response_addbytes(IP6_LOCALNET,16)) goto DIE;
377  }
378  cleanup(z);
379  return 1;
380  }
381 
382  if (dns_domain_equal(d,"\017ip6-mcastprefix\0")) {
383  if (z->level) goto LOWERLEVEL;
384  if (!rqa(z)) goto DIE;
385  if (typematch(DNS_T_AAAA,dtype)) {
386  if (!response_rstart(d,DNS_T_AAAA,655360)) goto DIE;
387  if (!response_addbytes(IP6_MULTICASTPFX_OCTAL,16)) goto DIE;
389  }
390  cleanup(z);
391  return 1;
392  }
393 
394  if (dns_domain_equal(d,"\14ip6-allnodes\0")) {
395  if (z->level) goto LOWERLEVEL;
396  if (!rqa(z)) goto DIE;
397  if (typematch(DNS_T_AAAA,dtype)) {
398  if (!response_rstart(d,DNS_T_AAAA,655360)) goto DIE;
399  if (!response_addbytes(IP6_ALLNODES_OCTAL,16)) goto DIE;
401  }
402  cleanup(z);
403  return 1;
404  }
405 
406  if (dns_domain_equal(d,"\16ip6-allrouters\0")) {
407  if (z->level) goto LOWERLEVEL;
408  if (!rqa(z)) goto DIE;
409  if (typematch(DNS_T_AAAA,dtype)) {
410  if (!response_rstart(d,DNS_T_AAAA,655360)) goto DIE;
411  if (!response_addbytes(IP6_ALLROUTERS_OCTAL,16)) goto DIE;
413  }
414  cleanup(z);
415  return 1;
416  }
417 
418  /* IPv4 well-known names (query.h) */
419 
421  if (z->level) goto LOWERLEVEL;
422  if (!rqa(z)) goto DIE;
423  if (typematch(DNS_T_PTR,dtype)) {
424  if (!response_rstart(d,DNS_T_PTR,655360)) goto DIE;
425  if (!response_addname("\014ip4-loopback\0")) goto DIE;
427  }
428  cleanup(z);
429  return 1;
430  }
431 
433  if (z->level) goto LOWERLEVEL;
434  if (!rqa(z)) goto DIE;
435  if (typematch(DNS_T_PTR,dtype)) {
436  if (!response_rstart(d,DNS_T_PTR,655360)) goto DIE;
437  if (!response_addname("\015ip4-localhost\0")) goto DIE;
439  }
440  cleanup(z);
441  log_stats();
442  return 1;
443  }
444 
445  if (dns_domain_equal(d,"\014ip4-localnet\0")) {
446  if (z->level) goto LOWERLEVEL;
447  if (!rqa(z)) goto DIE;
448  if (typematch(DNS_T_A,dtype)) {
449  if (!response_rstart(d,DNS_T_A,655360)) goto DIE;
450  if (!response_addbytes(IP4_LOCALNET,4)) goto DIE;
452  }
453  cleanup(z);
454  return 1;
455  }
456 
457  if (dns_domain_equal(d,"\015ip4-localhost\0") ||
458  dns_domain_equal(d,"\014ip4-loopback\0")) {
459  if (z->level) goto LOWERLEVEL;
460  if (!rqa(z)) goto DIE;
461  if (typematch(DNS_T_A,dtype)) {
462  if (!response_rstart(d,DNS_T_A,655360)) goto DIE;
463  if (!response_addbytes(IP4_LOOPBACK_OCTAL,4)) goto DIE;
465  }
466  cleanup(z);
467  return 1;
468  }
469 
470  /* special names done */
471 
472  if (dlen <= 255) {
473  byte_copy(key,2,DNS_T_ANY);
474  byte_copy(key + 2,dlen,d);
475  case_lowerb(key + 2,dlen);
476  cached = cache_get(key,dlen + 2,&cachedlen,&ttl);
477  if (cached) {
479  goto NXDOMAIN;
480  }
481 
482  byte_copy(key,2,DNS_T_CNAME);
483  cached = cache_get(key,dlen + 2,&cachedlen,&ttl);
484 
485  if (cached && cachedlen) {
486  if (typematch(DNS_T_CNAME,dtype)) {
488  if (!rqa(z)) goto DIE;
489  if (!response_cname(z->name[0],cached,ttl)) goto DIE;
490  cleanup(z);
491  return 1;
492  }
493  log_cachedcname(d,cached);
494  if (!z->level)
495  if (!move_name_to_alias(z,ttl)) goto DIE ;
496  if (!dns_domain_copy(&z->name[z->level],cached)) goto DIE;
497  goto NEWNAME;
498  }
499 
500  if (typematch(DNS_T_NS,dtype)) {
501  byte_copy(key,2,DNS_T_NS);
502  cached = cache_get(key,dlen + 2,&cachedlen,&ttl);
503  if (cached && (cachedlen || byte_diff(dtype,2,DNS_T_ANY))) {
504  if (z->level) {
505  flaghaskey = cns_pubkey(d,pubkey);
506  flagns = cns_addns(z,cached,flaghaskey,pubkey); /* ok */
507  if (flagns) log_servflag(addr,flagns);
508  else log_cachedanswer(d,DNS_T_NS);
509  }
510  if (!rqa(z)) goto DIE;
511  pos = 0;
512  while ((pos = dns_packet_getname(cached,cachedlen,pos,&t2))) {
513  if (!response_rstart(d,DNS_T_NS,ttl)) goto DIE;
514  if (!response_addname(t2)) goto DIE;
516  }
517  cleanup(z);
518  return 1;
519  }
520  }
521 
522  if (typematch(DNS_T_PTR,dtype)) {
523  byte_copy(key,2,DNS_T_PTR);
524  cached = cache_get(key,dlen + 2,&cachedlen,&ttl);
525  if (cached && (cachedlen || byte_diff(dtype,2,DNS_T_ANY))) {
527  if (!rqa(z)) goto DIE;
528  pos = 0;
529  while ((pos = dns_packet_getname(cached,cachedlen,pos,&t2))) {
530  if (!response_rstart(d,DNS_T_PTR,ttl)) goto DIE;
531  if (!response_addname(t2)) goto DIE;
533  }
534  cleanup(z);
535  return 1;
536  }
537  }
538 
539  if (typematch(DNS_T_MX,dtype)) {
540  byte_copy(key,2,DNS_T_MX);
541  cached = cache_get(key,dlen + 2,&cachedlen,&ttl);
542  if (cached && (cachedlen || byte_diff(dtype,2,DNS_T_ANY))) {
544  if (!rqa(z)) goto DIE;
545  pos = 0;
546  while ((pos = dns_packet_copy(cached,cachedlen,pos,misc,2))) {
547  pos = dns_packet_getname(cached,cachedlen,pos,&t2);
548  if (!pos) break;
549  if (!response_rstart(d,DNS_T_MX,ttl)) goto DIE;
550  if (!response_addbytes(misc,2)) goto DIE;
551  if (!response_addname(t2)) goto DIE;
553  }
554  cleanup(z);
555  return 1;
556  }
557  }
558 
559  if (typematch(DNS_T_A,dtype)) {
560  byte_copy(key,2,DNS_T_A);
561  cached = cache_get(key,dlen + 2,&cachedlen,&ttl);
562  /* if we were looking the A record up to find an NS, try IPv6 too */
563  if (cached && !cachedlen && z->level) {
564  z->ipv6[z->level] = 1;
565  goto NEWNAME;
566  }
567  if (cached && (cachedlen || byte_diff(dtype,2,DNS_T_ANY))) {
568  if (z->level) {
569  flaghaskey = cns_pubkey(d,pubkey);
571  while (cachedlen >= 4) {
572  for (k = 0; k < QUERY_MAXIPLEN; k += 16)
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);
576  break;
577  }
578  byte_copy(addr,12,V4mappedprefix);
579  byte_copy(addr+12,4,cached);
580  flagns = cns_addns(z,addr,flaghaskey,pubkey);
581  if (flagns) log_servflag(addr,flagns);
582  cached += 4;
583  cachedlen -= 4;
584  }
585  goto LOWERLEVEL;
586  }
587 
589  if (!rqa(z)) goto DIE;
590  while (cachedlen >= 4) {
591  if (!response_rstart(d,DNS_T_A,ttl)) goto DIE;
592  if (!response_addbytes(cached,4)) goto DIE;
594  cached += 4;
595  cachedlen -= 4;
596  }
597  cleanup(z);
598  return 1;
599  }
600  }
601 
602  if (typematch(DNS_T_AAAA,dtype)) {
603  byte_copy(key,2,DNS_T_AAAA);
604  cached = cache_get(key,dlen + 2,&cachedlen,&ttl);
605  if (cached && (cachedlen || byte_diff(dtype,2,DNS_T_ANY))) {
606  if (z->level) {
607  flaghaskey = cns_pubkey(d,pubkey);
609  while (cachedlen >= 16) {
610  flagns = cns_addns(z,cached,flaghaskey,pubkey);
611  if (flagns) log_servflag(addr,flagns);
612  cached += 16;
613  cachedlen -= 16;
614  }
615  goto LOWERLEVEL;
616  }
617 
619  if (!rqa(z)) goto DIE;
620  while (cachedlen >= 16) {
621  if (!response_rstart(d,DNS_T_AAAA,ttl)) goto DIE;
622  if (!response_addbytes(cached,16)) goto DIE;
624  cached += 16;
625  cachedlen -= 16;
626  }
627  cleanup(z);
628  return 1;
629  }
630  }
631 
632  if (!typematch(DNS_T_ANY,dtype) && !typematch(DNS_T_AXFR,dtype) &&
633  !typematch(DNS_T_NS,dtype) && !typematch(DNS_T_PTR,dtype) &&
634  !typematch(DNS_T_A,dtype) && !typematch(DNS_T_AAAA,dtype) &&
635  !typematch(DNS_T_MX,dtype)) {
636  byte_copy(key,2,dtype);
637  cached = cache_get(key,dlen + 2,&cachedlen,&ttl);
638  if (cached && (cachedlen || byte_diff(dtype,2,DNS_T_ANY))) {
639  log_cachedanswer(d,dtype);
640  if (!rqa(z)) goto DIE;
641  while (cachedlen >= 2) {
642  uint16_unpack_big(cached,&datalen);
643  cached += 2;
644  cachedlen -= 2;
645  if (datalen > cachedlen) goto DIE;
646  if (!response_rstart(d,dtype,ttl)) goto DIE;
647  if (!response_addbytes(cached,datalen)) goto DIE;
649  cached += datalen;
650  cachedlen -= datalen;
651  }
652  cleanup(z);
653  return 1;
654  }
655  }
656  } /* end of dlen if */
657 
658  for (;;) {
659  /* XXX: allow roots() to provide keys */
660  if (roots(z->servers[z->level],d)) {
661  z->flagnskeys[z->level] = 0;
662  for (j = 0; j < QUERY_MAXNS; ++j)
663  dns_domain_free(&z->ns[z->level][j]);
664  z->control[z->level] = d;
665  break;
666  }
667 
668  if (!flagforwardonly && (z->level < 2))
669  if (dlen < 255) {
670  byte_copy(key,2,DNS_T_NS);
671  byte_copy(key + 2,dlen,d);
672  case_lowerb(key + 2,dlen);
673  cached = cache_get(key,dlen + 2,&cachedlen,&ttl);
674  if (cached && cachedlen) {
675  z->control[z->level] = d;
676  byte_zero(z->servers[z->level],QUERY_MAXIPLEN);
677  z->flagnskeys[z->level] = 0; /* XXX */
678  for (j = 0; j < QUERY_MAXNS; ++j)
679  dns_domain_free(&z->ns[z->level][j]);
680  pos = 0;
681  j = 0;
682  while ((pos = dns_packet_getname(cached,cachedlen,pos,&t1))) {
683  log_cachedns(d,t1);
684  if (j < QUERY_MAXNS)
685  if (!dns_domain_copy(&z->ns[z->level][j++],t1)) goto DIE;
686  }
687  break;
688  }
689  }
690 
691  if (!*d) goto DIE;
692  j = 1 + (unsigned int) (unsigned char) *d;
693  dlen -= j;
694  d += j;
695  }
696 
697 
698  HAVENS:
699  for (j = 0; j < QUERY_MAXNS; ++j)
700  if (z->ns[z->level][j]) {
701  if (z->level + 1 < QUERY_MAXLEVEL) {
702  if (!dns_domain_copy(&z->name[z->level + 1],z->ns[z->level][j])) goto DIE;
703  dns_domain_free(&z->ns[z->level][j]);
704  ++z->level;
705  z->ipv6[z->level] = 0;
706  goto NEWNAME;
707  }
708  dns_domain_free(&z->ns[z->level][j]);
709  }
710 
711  for (j = 0; j < QUERY_MAXIPLEN; j += 16)
712  if (byte_diff(z->servers[z->level] + j,16,V6localnet)) break;
713  if (j == QUERY_MAXIPLEN) goto SERVFAIL;
714 
715  if (z->flagnskeys[z->level]) {
716  byte_copy(key,2,DNS_T_AXFR);
717  for (j = 0; j < QUERY_MAXIPLEN; j += 16)
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);
724  continue;
725  }
726  crypto_box_beforenm((unsigned char *) whichkey,(const unsigned char *) whichkey,(const unsigned char *) secretkey);
727  cache_set(key,34,whichkey,32,655360);
728  }
729  }
730 
731  cns_sortns(z->servers[z->level],z->keys[z->level],QUERY_MAXNS);
732  dtype = z->level ? DNS_T_A : z->type;
733  control = flagusetxtformat ? z->control[z->level] : 0;
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);
736 
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;
738 
739  return 0;
740 
741 
742  LOWERLEVEL:
743  dns_domain_free(&z->name[z->level]);
744  for (j = 0; j < QUERY_MAXNS; ++j)
745  dns_domain_free(&z->ns[z->level][j]);
746  --z->level;
747  goto HAVENS;
748 
749 
750  HAVEPACKET:
751  if (++z->loop == QUERY_MAXLOOP) goto DIE;
752  buf = z->dt.packet;
753  len = z->dt.packetlen;
754 
755  whichserver = z->dt.servers + 16 * z->dt.curserver;
756  control = z->control[z->level];
757  d = z->name[z->level];
758  /* dtype = z->level ? DNS_T_A : z->type; */
759  dtype = z->level ? (z->ipv6[z->level] ? DNS_T_AAAA : DNS_T_A) : z->type;
760 
761  pos = dns_packet_copy(buf,len,0,header,12); if (!pos) goto DIE;
762  pos = dns_packet_skipname(buf,len,pos); if (!pos) goto DIE;
763  pos += 4;
764  posanswers = pos;
765 
766  uint16_unpack_big(header + 6,&numanswers);
767  uint16_unpack_big(header + 8,&numauthority);
768  uint16_unpack_big(header + 10,&numglue);
769 
770  rcode = header[3] & 15;
771  if (rcode && (rcode != 3)) goto DIE; /* impossible; see irrelevant() */
772 
773  flagout = 0;
774  flagreferral = 0;
775  flagsoa = 0;
776  soattl = 0;
777  cachettl = 0;
778 
779  if (!dns_domain_copy(&owner,d)) goto DIE;
780  /* This code assumes that the CNAME chain is presented in the correct order.
781  ** The example algorithm in RFC 1034 will actually result in this
782  ** being the case, but the words do not require it to be so.
783  */
784 
785  for (j = 0; j < numanswers; ++j) {
786  pos = dns_packet_getname(buf,len,pos,&t1); if (!pos) goto DIE;
787  pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE;
788 
789  if (dns_domain_equal(t1,owner))
790  if (byte_equal(header + 2,2,DNS_C_IN)) { /* should always be true */
791  if (typematch(header,dtype))
792  flagout = 1;
793  else if (typematch(header,DNS_T_CNAME)) {
794  if (!dns_packet_getname(buf,len,pos,&owner)) goto DIE;
795  }
796  }
797 
798  uint16_unpack_big(header + 8,&datalen);
799  pos += datalen;
800  }
801  dns_domain_free(&owner);
802  posauthority = pos;
803 
804  for (j = 0; j < numauthority; ++j) {
805  pos = dns_packet_getname(buf,len,pos,&t1); if (!pos) goto DIE;
806  pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE;
807 
808  if (typematch(header,DNS_T_SOA)) {
809  flagsoa = 1;
810  soattl = ttlget(header + 4);
811  if (soattl > 3600) soattl = 3600;
812  }
813  else if (typematch(header,DNS_T_NS)) {
814  flagreferral = 1;
815  if (!dns_domain_copy(&referral,t1)) goto DIE;
816  }
817 
818  uint16_unpack_big(header + 8,&datalen);
819  pos += datalen;
820  }
821 
822  /* JBP Negative cache patch and record in log */
823 
824  if (flagsoa && (pos <= len)) {
825  cachettl = ttlget(buf + pos - 4);
826  if (soattl < cachettl) cachettl = soattl;
827  }
828  posglue = pos; /* XXX ?? this is never used; posauthority? */
829 
830  if (records) { alloc_free(records); records = 0; }
831 
832  k = numanswers + numauthority + numglue;
833  records = (unsigned int *) alloc(k * sizeof(unsigned int));
834  if (!records) goto DIE;
835 
836  pos = posanswers;
837  for (j = 0; j < k; ++j) {
838  records[j] = pos;
839  pos = dns_packet_getname(buf,len,pos,&t1); if (!pos) goto DIE;
840  pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE;
841  uint16_unpack_big(header + 8,&datalen);
842  pos += datalen;
843  }
844 
845  i = j = k;
846  while (j > 1) {
847  if (i > 1) { --i; pos = records[i - 1]; }
848  else { pos = records[j - 1]; records[j - 1] = records[i - 1]; --j; }
849 
850  q = i;
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;
854  }
855  if (p == j) {
856  records[q - 1] = records[p - 1]; q = p;
857  }
858  while ((q > i) && smaller(buf,len,records[(p = q/2) - 1],pos)) {
859  records[q - 1] = records[p - 1]; q = p;
860  }
861  records[q - 1] = pos;
862  }
863 
864  i = 0;
865  while (i < k) {
866  char type[2];
867 
868  pos = dns_packet_getname(buf,len,records[i],&t1); if (!pos) goto DIE;
869  pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE;
870  ttl = ttlget(header + 4);
871 
872  byte_copy(type,2,header);
873  if (byte_diff(header + 2,2,DNS_C_IN)) { ++i; continue; }
874 
875  for (j = i + 1; j < k; ++j) {
876  pos = dns_packet_getname(buf,len,records[j],&t2); if (!pos) goto DIE;
877  pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE;
878  if (!dns_domain_equal(t1,t2)) break;
879  if (byte_diff(header,2,type)) break;
880  if (byte_diff(header + 2,2,DNS_C_IN)) break;
881  }
882 
883  if (!dns_domain_suffix(t1,control)) { i = j; continue; }
884  if (!roots_same(t1,control)) { i = j; continue; }
885 
886  if (byte_equal(type,2,DNS_T_ANY))
887  ;
888  else if (byte_equal(type,2,DNS_T_AXFR))
889  ;
890  else if (byte_equal(type,2,DNS_T_SOA)) {
891  while (i < j) {
892  pos = dns_packet_skipname(buf,len,records[i]); if (!pos) goto DIE;
893  pos = dns_packet_getname(buf,len,pos + 10,&t2); if (!pos) goto DIE;
894  pos = dns_packet_getname(buf,len,pos,&t3); if (!pos) goto DIE;
895  pos = dns_packet_copy(buf,len,pos,misc,20); if (!pos) goto DIE;
896  if (records[i] < posauthority)
897  log_rrsoa(whichserver,t1,t2,t3,misc,ttl);
898  ++i;
899  }
900  }
901  else if (byte_equal(type,2,DNS_T_CNAME)) {
902  pos = dns_packet_skipname(buf,len,records[j - 1]); if (!pos) goto DIE;
903  pos = dns_packet_getname(buf,len,pos + 10,&t2); if (!pos) goto DIE;
904  log_rrcname(whichserver,t1,t2,ttl);
905  cachegeneric(DNS_T_CNAME,t1,t2,dns_domain_length(t2),ttl);
906  }
907  else if (byte_equal(type,2,DNS_T_PTR)) {
908  save_start();
909  while (i < j) {
910  pos = dns_packet_skipname(buf,len,records[i]); if (!pos) goto DIE;
911  pos = dns_packet_getname(buf,len,pos + 10,&t2); if (!pos) goto DIE;
912  log_rrptr(whichserver,t1,t2,ttl);
913  save_data(t2,dns_domain_length(t2));
914  ++i;
915  }
916  save_finish(DNS_T_PTR,t1,ttl);
917  }
918  else if (byte_equal(type,2,DNS_T_NS)) {
919  save_start();
920  while (i < j) {
921  pos = dns_packet_skipname(buf,len,records[i]); if (!pos) goto DIE;
922  pos = dns_packet_getname(buf,len,pos + 10,&t2); if (!pos) goto DIE;
923  log_rrns(whichserver,t1,t2,ttl);
924  save_data(t2,dns_domain_length(t2));
925  ++i;
926  }
927  save_finish(DNS_T_NS,t1,ttl);
928  }
929  else if (byte_equal(type,2,DNS_T_MX)) {
930  save_start();
931  while (i < j) {
932  pos = dns_packet_skipname(buf,len,records[i]); if (!pos) goto DIE;
933  pos = dns_packet_copy(buf,len,pos + 10,misc,2); if (!pos) goto DIE;
934  pos = dns_packet_getname(buf,len,pos,&t2); if (!pos) goto DIE;
935  log_rrmx(whichserver,t1,t2,misc,ttl);
936  save_data(misc,2);
937  save_data(t2,dns_domain_length(t2));
938  ++i;
939  }
940  save_finish(DNS_T_MX,t1,ttl);
941  }
942  else if (byte_equal(type,2,DNS_T_A)) {
943  save_start();
944  while (i < j) {
945  pos = dns_packet_skipname(buf,len,records[i]); if (!pos) goto DIE;
946  pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE;
947  if (byte_equal(header + 8,2,"\0\4")) {
948  pos = dns_packet_copy(buf,len,pos,header,4); if (!pos) goto DIE;
949  save_data(header,4);
950  log_rr(whichserver,t1,DNS_T_A,header,4,ttl);
951  }
952  ++i;
953  }
954  save_finish(DNS_T_A,t1,ttl);
955  }
956  else if (byte_equal(type,2,DNS_T_AAAA)) {
957  save_start();
958  while (i < j) {
959  pos = dns_packet_skipname(buf,len,records[i]); if (!pos) goto DIE;
960  pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE;
961  if (byte_equal(header + 8,2,"\0\20")) {
962  pos = dns_packet_copy(buf,len,pos,header,16); if (!pos) goto DIE;
963  save_data(header,16);
964  log_rr(whichserver,t1,DNS_T_AAAA,header,16,ttl);
965  }
966  ++i;
967  }
968  save_finish(DNS_T_AAAA,t1,ttl);
969  }
970  else {
971  save_start();
972  while (i < j) {
973  pos = dns_packet_skipname(buf,len,records[i]); if (!pos) goto DIE;
974  pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE;
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);
979  log_rr(whichserver,t1,type,buf + pos,datalen,ttl);
980  ++i;
981  }
982  save_finish(type,t1,ttl);
983  }
984 
985  i = j;
986  }
987 
988  alloc_free(records); records = 0;
989 
990  /* This code assumes that the CNAME chain is presented in the correct
991  ** order. The example algorithm in RFC 1034 will actually result in this
992  ** being the case, but the words do not require it to be so.
993  */
994 
995  if (byte_diff(DNS_T_CNAME,2,dtype)) {
996  pos = posanswers;
997  for (j = 0; j < numanswers; ++j) {
998  pos = dns_packet_getname(buf,len,pos,&t1); if (!pos) goto DIE;
999  pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE;
1000 
1001 /* XXX */
1002  if (dns_domain_equal(t1,d))
1003  if (byte_equal(header + 2,2,DNS_C_IN)) { /* should always be true */
1004  if (typematch(header,DNS_T_CNAME)) {
1005  ttl = ttlget(header + 4);
1006  if (z->level == 0)
1007  if (!move_name_to_alias(z,ttl)) goto DIE ;
1008  if (!dns_packet_getname(buf,len,pos,&z->name[z->level])) goto DIE;
1009  d = z->name[z->level];
1010  if (!dns_domain_suffix(d,control) || !roots_same(d,control))
1011  goto NEWNAME ; /* Cannot trust the chain further - restart using current name */
1012  }
1013  }
1014  uint16_unpack_big(header + 8,&datalen);
1015  pos += datalen;
1016  }
1017  }
1018 
1019  /* A "no such name" error applies to the end of any CNAME chain, not to the start. */
1020 
1021  if (rcode == 3) {
1022  log_nxdomain(whichserver,d,cachettl);
1023  cachegeneric(DNS_T_ANY,d,"",0,cachettl);
1024 
1025  NXDOMAIN:
1026  if (z->level) goto LOWERLEVEL;
1027  if (!rqa(z)) goto DIE;
1029  cleanup(z);
1030  return 1;
1031  }
1032 
1033  /* We check for a lame server _after_ we have cached any records that it
1034  ** might have returned to us. This copes better with the incorrect
1035  ** behaviour of one content DNS server software that doesn't return
1036  ** complete CNAME chains but instead returns only the first link in a
1037  ** chain followed by a lame delegation to the same server.
1038  ** Also: We check for a lame server _after_ following the CNAME chain. The
1039  ** delegation in a referral answer applies to the _end_ of the chain, not
1040  ** to the beginning.
1041  */
1042 
1043  if (!rcode && !flagout && flagreferral && !flagsoa)
1044  if (dns_domain_equal(referral,control) || !dns_domain_suffix(referral,control)) {
1045  log_lame(whichserver,control,referral);
1046  byte_zero(whichserver,16);
1047  goto HAVENS;
1048  }
1049 
1050  /* Don't save empty RRSets for those types that we use as special markers. */
1051 
1052  if (!flagout && flagsoa)
1053  if (byte_diff(DNS_T_ANY,2,dtype))
1054  if (byte_diff(DNS_T_AXFR,2,dtype)) {
1055  save_start();
1056  save_finish(dtype,d,soattl);
1057  log_nodata(whichserver,d,dtype,soattl);
1058  if (z->level && !byte_diff(DNS_T_A,2,dtype)) {
1059  d = z->name[z->level];
1060  z->ipv6[z->level] = 1;
1061  goto NEWNAME; /* retry, will ask for AAAA next */
1062  }
1063  }
1064 
1065  log_stats();
1066 
1067  if (flagout || flagsoa || !flagreferral) {
1068  if (z->level) {
1069  flaghaskey = cns_pubkey(d,pubkey);
1070  pos = posanswers;
1071  for (j = 0; j < numanswers; ++j) {
1072  pos = dns_packet_getname(buf,len,pos,&t1); if (!pos) goto DIE;
1073  pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE;
1074  uint16_unpack_big(header + 8,&datalen);
1075  if (dns_domain_equal(t1,d)) {
1076  if (typematch(header,DNS_T_A))
1077  if (byte_equal(header + 2,2,DNS_C_IN)) /* should always be true */
1078  if (datalen == 4) {
1079  if (!dns_packet_copy(buf,len,pos,misc,4)) goto DIE;
1080  byte_copy(addr,12,V4mappedprefix);
1081  byte_copy(addr+12,4,misc);
1082  flagns = cns_addns(z,addr,flaghaskey,pubkey);
1083  if (flagns) log_servflag(addr,flagns);
1084  }
1085  if (typematch(header,DNS_T_AAAA))
1086  if (byte_equal(header + 2,2,DNS_C_IN)) /* should always be true */
1087  if (datalen == 16) {
1088  if (!dns_packet_copy(buf,len,pos,misc,16)) goto DIE;
1089  flagns = cns_addns(z,misc,flaghaskey,pubkey);
1090  if (flagns) log_servflag(addr,flagns);
1091  }
1092  }
1093  pos += datalen;
1094  }
1095  goto LOWERLEVEL;
1096  }
1097 
1098  if (!rqa(z)) goto DIE;
1099 
1100  pos = posanswers;
1101  for (j = 0; j < numanswers; ++j) {
1102  pos = dns_packet_getname(buf,len,pos,&t1); if (!pos) goto DIE;
1103  pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE;
1104  ttl = ttlget(header + 4);
1105  uint16_unpack_big(header + 8,&datalen);
1106  if (dns_domain_equal(t1,d))
1107  if (byte_equal(header + 2,2,DNS_C_IN)) /* should always be true */
1108  if (typematch(header,dtype)) {
1109  if (!response_rstart(t1,header,ttl)) goto DIE;
1110 
1111  if (typematch(header,DNS_T_NS) || typematch(header,DNS_T_CNAME) || typematch(header,DNS_T_PTR)) {
1112  if (!dns_packet_getname(buf,len,pos,&t2)) goto DIE;
1113  if (!response_addname(t2)) goto DIE;
1114  }
1115  else if (typematch(header,DNS_T_MX)) {
1116  pos2 = dns_packet_copy(buf,len,pos,misc,2); if (!pos2) goto DIE;
1117  if (!response_addbytes(misc,2)) goto DIE;
1118  if (!dns_packet_getname(buf,len,pos2,&t2)) goto DIE;
1119  if (!response_addname(t2)) goto DIE;
1120  }
1121  else if (typematch(header,DNS_T_SOA)) {
1122  pos2 = dns_packet_getname(buf,len,pos,&t2); if (!pos2) goto DIE;
1123  if (!response_addname(t2)) goto DIE;
1124  pos2 = dns_packet_getname(buf,len,pos2,&t3); if (!pos2) goto DIE;
1125  if (!response_addname(t3)) goto DIE;
1126  pos2 = dns_packet_copy(buf,len,pos2,misc,20); if (!pos2) goto DIE;
1127  if (!response_addbytes(misc,20)) goto DIE;
1128  }
1129  else {
1130  if (pos + datalen > len) goto DIE;
1131  if (!response_addbytes(buf + pos,datalen)) goto DIE;
1132  }
1133 
1135  }
1136  pos += datalen;
1137  }
1138 
1139  cleanup(z);
1140  return 1;
1141  }
1142 
1143 
1144  if (!dns_domain_suffix(d,referral)) goto DIE;
1145 
1146  /* In strict "forwardonly" mode, we don't, as the manual states,
1147  ** contact a chain of servers according to "NS" resource records.
1148  ** We don't obey any referral responses, therefore. Instead, we
1149  ** eliminate the server from the list and try the next one.
1150  */
1151  if (flagforwardonly) {
1152  log_ignore_referral(whichserver,control,referral);
1153  byte_zero(whichserver,16);
1154  goto HAVENS;
1155  }
1156 
1157  control = d + dns_domain_suffixpos(d,referral);
1158  z->control[z->level] = control;
1159  z->byzg = numauthority*100 + numglue;
1160  z->flagnskeys[z->level] = 0; /* XXX */
1161  byte_zero(z->servers[z->level],QUERY_MAXIPLEN);
1162  for (j = 0; j < QUERY_MAXNS; ++j)
1163  dns_domain_free(&z->ns[z->level][j]);
1164  k = 0;
1165 
1166  pos = posauthority;
1167  for (j = 0; j < numauthority; ++j) {
1168  pos = dns_packet_getname(buf,len,pos,&t1); if (!pos) goto DIE;
1169  pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE;
1170  uint16_unpack_big(header + 8,&datalen);
1171  if (dns_domain_equal(referral,t1)) /* should always be true */
1172  if (typematch(header,DNS_T_NS)) /* should always be true */
1173  if (byte_equal(header + 2,2,DNS_C_IN)) /* should always be true */
1174  if (k < QUERY_MAXNS)
1175  if (!dns_packet_getname(buf,len,pos,&z->ns[z->level][k++])) goto DIE;
1176  pos += datalen;
1177  }
1178 
1179  goto HAVENS;
1180 
1181 
1182  SERVFAIL:
1183  if (z->level) goto LOWERLEVEL;
1184  if (!rqa(z)) goto DIE;
1186  cleanup(z);
1187  return 1;
1188 
1189 
1190  DIE:
1191  cleanup(z);
1192  if (records) { alloc_free(records); records = 0; }
1193  dns_domain_free(&owner);
1194  return DNS_ERR;
1195 }
1196 
1197 int query_start(struct query *z,char *dn,char type[2],char class[2],char localip[16],uint32 scope_id)
1198 {
1199  if (byte_equal(type,2,DNS_T_AXFR)) { errno = EPERM; return DNS_ERR; }
1200 
1201  cleanup(z);
1202  z->level = 0;
1203  z->loop = 0;
1204 
1205  if (!dns_domain_copy(&z->name[0],dn)) return DNS_ERR;
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;
1210  z->ipv6[0] = 0;
1211 
1212  return doit(z,0);
1213 }
1214 
1215 int query_get(struct query *z,iopause_fd *x,struct taia *stamp)
1216 {
1217  switch (dns_transmit_get(&z->dt,x,stamp)) {
1218  case 1:
1219  return doit(z,1);
1220  case -1: case -2: case -3:
1221  return doit(z,-1);
1222  }
1223  return 0;
1224 }
1225 
1226 void query_io(struct query *z,iopause_fd *x,struct taia *deadline)
1227 {
1228  dns_transmit_io(&z->dt,x,deadline);
1229 }
unsigned int doit(char *buf, unsigned int len, unsigned int pos)
Definition: axfr-get.c:131
char data[32767]
Definition: axfrdns.c:131
char ip[16]
Definition: axfrdns.c:126
uint16 len
Definition: axfrdns.c:302
char buf[MSGSIZE]
Definition: axfrdns.c:301
uint32 dlen
Definition: axfrdns.c:132
void cache_set(const char *key, unsigned int keylen, const char *data, unsigned int datalen, uint32 ttl)
Definition: cache.c:127
char * cache_get(const char *key, unsigned int keylen, unsigned int *datalen, uint32 *ttl)
Definition: cache.c:80
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)
Definition: curvedns.c:256
void cns_sortns(char *s, char *t, unsigned int n)
Definition: curvedns.c:201
int cns_pubkey(const char *dn, char key[32])
Definition: curvedns.c:188
int cns_addns(struct query *z, const char *addr, int flagnskey, const char *key)
Definition: curvedns.c:221
#define crypto_box_beforenm
Definition: curvedns.h:21
#define crypto_scalarmult_base
Definition: curvedns.h:20
int dd4(const char *q, const char *base, char ip[4])
Definition: dd.c:7
void dns_transmit_free(struct dns_transmit *)
Definition: dns_transmit.c:96
void dns_transmit_io(struct dns_transmit *, iopause_fd *, struct taia *)
Definition: dns_transmit.c:284
unsigned int dns_packet_copy(const char *, unsigned int, unsigned int, char *, unsigned int)
Definition: dns_packet.c:8
#define DNS_ERR
Definition: dns.h:22
#define DNS_T_A
Definition: dns.h:37
#define QUERY_MAXIPLEN
Definition: dns.h:30
int dns_domain_equal(const char *, const char *)
Definition: dns_domain.c:39
unsigned int dns_random(unsigned int)
Definition: dns_random.c:52
#define DNS_T_AXFR
Definition: dns.h:65
#define DNS_C_IN
Definition: dns.h:34
#define DNS_T_ANY
Definition: dns.h:66
int dns_domain_copy(char **, const char *)
Definition: dns_domain.c:25
int dns_domain_suffix(const char *, const char *)
Definition: dns_domain.c:50
unsigned int dns_packet_skipname(const char *, unsigned int, unsigned int)
Definition: dns_packet.c:18
void dns_domain_free(char **)
Definition: dns_domain.c:17
unsigned int dns_domain_length(const char *)
Definition: dns_domain.c:6
#define DNS_T_PTR
Definition: dns.h:41
#define DNS_T_SOA
Definition: dns.h:40
unsigned int dns_domain_suffixpos(const char *, const char *)
Definition: dns_domain.c:62
#define DNS_T_NS
Definition: dns.h:38
#define QUERY_MAXNS
Definition: dns.h:29
#define DNS_T_CNAME
Definition: dns.h:39
#define DNS_T_AAAA
Definition: dns.h:48
unsigned int dns_packet_getname(const char *, unsigned int, unsigned int, char **)
Definition: dns_packet.c:35
#define DNS_T_MX
Definition: dns.h:43
int dns_transmit_get(struct dns_transmit *, const iopause_fd *, const struct taia *)
Definition: dns_transmit.c:301
char * p
Definition: dnscache.c:38
struct line * x
char type[2]
Definition: dnsq.c:56
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)
Definition: install.c:103
void log_rrmx(const char server[16], const char *q, const char *mx, const char pref[2], unsigned int ttl)
Definition: log.c:284
void log_rrcname(const char server[16], const char *q, const char *data, unsigned int ttl)
Definition: log.c:268
void log_servflag(const char server[16], int flag)
Definition: log.c:226
void log_servfail(const char *dn)
Definition: log.c:235
void log_tx(const char *q, const char qtype[2], const char *control, const char servers[512], int flagkey, unsigned int gluelessness)
Definition: log.c:158
void log_cachedanswer(const char *q, const char type[2])
Definition: log.c:180
void log_nxdomain(const char server[16], const char *q, unsigned int ttl)
Definition: log.c:205
void log_cachednxdomain(const char *dn)
Definition: log.c:199
void log_nodata(const char server[16], const char *q, const char qtype[2], unsigned int ttl)
Definition: log.c:212
void log_rrptr(const char server[16], const char *q, const char *data, unsigned int ttl)
Definition: log.c:276
void log_ignore_referral(const char server[16], const char *control, const char *referral)
Definition: log.c:135
void log_lame(const char server[16], const char *control, const char *referral)
Definition: log.c:219
void log_stats(void)
Definition: log.c:310
void log_cachedcname(const char *dn, const char *dn2)
Definition: log.c:187
void log_rrsoa(const char server[16], const char *q, const char *n1, const char *n2, const char misc[20], unsigned int ttl)
Definition: log.c:295
void log_rrns(const char server[16], const char *q, const char *data, unsigned int ttl)
Definition: log.c:261
void log_cachedns(const char *control, const char *ns)
Definition: log.c:193
void log_rr(const char server[16], const char *q, const char type[2], const char *buf, unsigned int len, unsigned int ttl)
Definition: log.c:244
void query_init(void)
Definition: query.c:21
void query_io(struct query *z, iopause_fd *x, struct taia *deadline)
Definition: query.c:1226
int query_get(struct query *z, iopause_fd *x, struct taia *stamp)
Definition: query.c:1215
int flagusetxtformat
Definition: dnscache.c:35
void query_forwardonly(void)
Definition: query.c:34
int query_start(struct query *z, char *dn, char type[2], char class[2], char localip[16], uint32 scope_id)
Definition: query.c:1197
#define QUERY_MAXALIAS
Definition: query.h:10
#define IP6_LOOPBACK_OCTAL
Definition: query.h:29
#define IP6_ALLROUTERS_OCTAL
Definition: query.h:37
#define IP6_MULTICASTPFX_OCTAL
Definition: query.h:33
#define IP6_MULTICAST_ARPA
Definition: query.h:22
#define QUERY_MAXLEVEL
Definition: query.h:9
#define IP6_ALLNODESMULTICAST_ARPA
Definition: query.h:24
#define QUERY_MAXLOOP
Definition: query.h:11
#define IP4_LOOPBACK_ARPA
Definition: query.h:42
#define IP4_LOCALHOST_ARPA
Definition: query.h:40
#define IP6_LOCALHOST_ARPA
Definition: query.h:54
#define IP6_LOOPBACK_ARPA
Definition: query.h:18
#define IP6_LOCALNET
Definition: query.h:52
#define IP4_LOOPBACK_OCTAL
Definition: query.h:45
#define IP6_ALLROUTERSMULTICAST_ARPA
Definition: query.h:26
#define IP6_LOCALNET_ARPA
Definition: query.h:20
#define IP4_LOCALNET
Definition: query.h:51
#define IP6_ALLNODES_OCTAL
Definition: query.h:35
int response_addbytes(const char *buf, unsigned int len)
Definition: response.c:17
int response_addname(const char *d)
Definition: response.c:25
int response_cname(const char *c, const char *d, uint32 ttl)
Definition: response.c:95
void response_rfinish(int x)
Definition: response.c:89
int response_query(const char *q, const char qtype[2], const char qclass[2])
Definition: response.c:54
void response_nxdomain(void)
Definition: response.c:103
void response_servfail(void)
Definition: response.c:109
int response_rstart(const char *d, const char type[2], uint32 ttl)
Definition: response.c:75
#define RESPONSE_ANSWER
Definition: response.h:23
int roots_same(char *q, char *q2)
Definition: roots.c:55
int roots(char servers[QUERY_MAXIPLEN], char *q)
Definition: roots.c:46
Definition: query.h:56