djbdnscurve6  38
djbdnscurve6
tdlookup.c
Go to the documentation of this file.
1 
2 #include <unistd.h>
3 #include "uint_t.h"
4 #include "open.h"
5 #include "tai.h"
6 #include "cdbread.h"
7 #include "byte.h"
8 #include "case.h"
9 #include "dns.h"
10 #include "seek.h"
11 #include "response.h"
12 #include "ip.h"
13 #include "clientloc.h"
14 
15 // unsigned int max_response_len = MSGSIZE;
16 
17 static int want(const char *owner,const char type[2])
18 {
19  unsigned int pos;
20  static char *d;
21  char x[10];
22  uint16 datalen;
23 
24  pos = dns_packet_skipname(response,response_len,12); if (!pos) return 0;
25  pos += 4;
26 
27  while (pos < response_len) {
28  pos = dns_packet_getname(response,response_len,pos,&d); if (!pos) return 0;
29  pos = dns_packet_copy(response,response_len,pos,x,10); if (!pos) return 0;
30  if (dns_domain_equal(d,owner))
31  if (byte_equal(type,2,x))
32  return 0;
33  uint16_unpack_big(x + 8,&datalen);
34  pos += datalen;
35  }
36  return 1;
37 }
38 
39 static char *d1;
40 
41 static char clientloc[2];
42 static struct tai now;
43 static struct cdb c;
44 
45 static char data[32767];
46 static uint32 dlen;
47 static unsigned int dpos;
48 static char type[2];
49 static uint32 ttl;
50 
51 static int find(char *d,int flagwild)
52 {
53  int r;
54  char ch;
55  struct tai cutoff;
56  char ttd[8];
57  char ttlstr[4];
58  char recordloc[2];
59  double newttl;
60 
61  for (;;) {
62  r = cdb_findnext(&c,d,dns_domain_length(d));
63  if (r <= 0) return r;
64  dlen = cdb_datalen(&c);
65  if (dlen > sizeof(data)) return DNS_ERR;
66  if (cdb_read(&c,data,dlen,cdb_datapos(&c)) == -1) return DNS_INT;
67  dpos = dns_packet_copy(data,dlen,0,type,2); if (!dpos) return DNS_ERR;
68  dpos = dns_packet_copy(data,dlen,dpos,&ch,1); if (!dpos) return DNS_ERR;
69  if ((ch == '=' + 1) || (ch == '*' + 1) || (ch == '6' + 1)) {
70  --ch;
71  dpos = dns_packet_copy(data,dlen,dpos,recordloc,2); if (!dpos) return DNS_ERR;
72  if (byte_diff(recordloc,2,clientloc)) continue;
73  }
74  if (flagwild != (ch == '*')) continue;
75  dpos = dns_packet_copy(data,dlen,dpos,ttlstr,4); if (!dpos) return DNS_ERR;
76  uint32_unpack_big(ttlstr,&ttl);
77  dpos = dns_packet_copy(data,dlen,dpos,ttd,8); if (!dpos) return DNS_ERR;
78  if (byte_diff(ttd,8,"\0\0\0\0\0\0\0\0")) {
79  tai_unpack(ttd,&cutoff);
80  if (ttl == 0) {
81  if (tai_less(&cutoff,&now)) continue;
82  tai_sub(&cutoff,&cutoff,&now);
83  newttl = tai_approx(&cutoff);
84  if (newttl <= 2.0) newttl = 2.0;
85  if (newttl >= 3600.0) newttl = 3600.0;
86  ttl = newttl;
87  }
88  else
89  if (!tai_less(&cutoff,&now)) continue;
90  }
91  return 1;
92  }
93 }
94 
95 static int dobytes(unsigned int len)
96 {
97  char buf[20];
98  if (len > 20) return 0;
100  if (!dpos) return 0;
101  return response_addbytes(buf,len);
102 }
103 
104 static int doname(void)
105 {
107  if (!dpos) return 0;
108  return response_addname(d1);
109 }
110 
111 static int doit(char *q,char qtype[2])
112 {
113  unsigned int bpos;
114  unsigned int anpos;
115  unsigned int aupos;
116  unsigned int arpos;
117  char *control;
118  char *wild;
119  int flaggavesoa;
120  int flagfound;
121  int r;
122  int flagns;
123  int flagauthoritative;
124  char x[20];
125  uint16 u16;
126  char addr[8][4];
127  char addr6[8][16];
128  int addrnum,addr6num;
129  uint32 addrttl,addr6ttl;
130  int i;
131 
132  anpos = response_len;
133 
134  control = q;
135  for (;;) {
136  flagns = 0;
137  flagauthoritative = 0;
138  cdb_findstart(&c);
139  while ((r = find(control,0))) {
140  if (r == -1) return 0;
141  if (byte_equal(type,2,DNS_T_SOA)) flagauthoritative = 1;
142  if (byte_equal(type,2,DNS_T_NS)) flagns = 1;
143  }
144  if (flagns) break;
145  if (!*control) return 0; /* q is not within our bailiwick */
146  control += *control;
147  control += 1;
148  }
149 
150  if (!flagauthoritative) {
151  response[2] &= ~4;
152  goto AUTHORITY; /* q is in a child zone */
153  }
154 
155 
156  flaggavesoa = 0;
157  flagfound = 0;
158  wild = q;
159 
160  for (;;) {
161  addrnum = addr6num = 0;
162  addrttl = addr6ttl = 0;
163  cdb_findstart(&c);
164  while ((r = find(wild,wild != q))) {
165  if (r == -1) return 0;
166  flagfound = 1;
167  if (flaggavesoa && byte_equal(type,2,DNS_T_SOA)) continue;
168  if (byte_diff(type,2,qtype) && byte_diff(qtype,2,DNS_T_ANY) && byte_diff(type,2,DNS_T_CNAME)) continue;
169  if (byte_equal(type,2,DNS_T_A) && (dlen - dpos == 4)) {
170  addrttl = ttl;
171  i = dns_random(addrnum + 1);
172  if (i < 8) {
173  if ((i < addrnum) && (addrnum < 8))
174  byte_copy(addr[addrnum],4,addr[i]);
175  byte_copy(addr[i],4,data + dpos);
176  }
177  if (addrnum < 1000000) ++addrnum;
178  continue;
179  }
180  if (byte_equal(type,2,DNS_T_AAAA) && (dlen - dpos == 16)) {
181  addr6ttl = ttl;
182  i = dns_random(addr6num + 1);
183  if (i < 8) {
184  if ((i < addr6num) && (addr6num < 8))
185  byte_copy(addr6[addr6num],16,addr6[i]);
186  byte_copy(addr6[i],16,data + dpos);
187  }
188  if (addr6num < 1000000) ++addr6num;
189  continue;
190  }
191  if (!response_rstart(q,type,ttl)) return 0;
192  if (byte_equal(type,2,DNS_T_NS) || byte_equal(type,2,DNS_T_CNAME) || byte_equal(type,2,DNS_T_PTR)) {
193  if (!doname()) return 0;
194  }
195  else if (byte_equal(type,2,DNS_T_MX)) {
196  if (!dobytes(2)) return 0;
197  if (!doname()) return 0;
198  }
199  else if (byte_equal(type,2,DNS_T_SOA)) {
200  if (!doname()) return 0;
201  if (!doname()) return 0;
202  if (!dobytes(20)) return 0;
203  flaggavesoa = 1;
204  }
205  else
206  if (!response_addbytes(data + dpos,dlen - dpos)) return 0;
208  }
209  for (i = 0; i < addrnum; ++i)
210  if (i < 8) {
211  if (!response_rstart(q,DNS_T_A,addrttl)) return 0;
212  if (!response_addbytes(addr[i],4)) return 0;
214  }
215  for (i = 0; i < addr6num; ++i)
216  if (i < 8) {
217  if (!response_rstart(q,DNS_T_AAAA,addr6ttl)) return 0;
218  if (!response_addbytes(addr6[i],16)) return 0;
220  }
221 
222  if (flagfound) break;
223  if (wild == control) break;
224  if (!*wild) break; /* impossible */
225  wild += *wild;
226  wild += 1;
227  }
228 
229  if (!flagfound)
231 
232 
233  AUTHORITY:
234  aupos = response_len;
235 
236  if (flagauthoritative && (aupos == anpos)) {
237  cdb_findstart(&c);
238  while ((r = find(control,0))) {
239  if (r == -1) return 0;
240  if (byte_equal(type,2,DNS_T_SOA)) {
241  if (!response_rstart(control,DNS_T_SOA,ttl)) return 0;
242  if (!doname()) return 0;
243  if (!doname()) return 0;
244  if (!dobytes(20)) return 0;
246  break;
247  }
248  }
249  }
250  else
251  if (want(control,DNS_T_NS)) {
252  cdb_findstart(&c);
253  while ((r = find(control,0))) {
254  if (r == -1) return 0;
255  if (byte_equal(type,2,DNS_T_NS)) {
256  if (!response_rstart(control,DNS_T_NS,ttl)) return 0;
257  if (!doname()) return 0;
259  }
260  }
261  }
262 
263  arpos = response_len;
264 
265  bpos = anpos;
266  while (bpos < arpos) {
267  bpos = dns_packet_skipname(response,arpos,bpos); if (!bpos) return 0;
268  bpos = dns_packet_copy(response,arpos,bpos,x,10); if (!bpos) return 0;
269  if (byte_equal(x,2,DNS_T_NS) || byte_equal(x,2,DNS_T_MX)) {
270  if (byte_equal(x,2,DNS_T_NS)) {
271  if (!dns_packet_getname(response,arpos,bpos,&d1)) return 0;
272  }
273  else if (!dns_packet_getname(response,arpos,bpos + 2,&d1)) return 0;
274  case_lowerb(d1,dns_domain_length(d1));
275  if (want(d1,DNS_T_A)) {
276  cdb_findstart(&c);
277  while ((r = find(d1,0))) {
278  if (r == -1) return 0;
279  if (byte_equal(type,2,DNS_T_A)) {
280  if (!response_rstart(d1,DNS_T_A,ttl)) return 0;
281  if (!dobytes(4)) return 0;
283  }
284  else if (byte_equal(type,2,DNS_T_AAAA)) {
285  if (!response_rstart(d1,DNS_T_AAAA,ttl)) return 0;
286  if (!dobytes(16)) return 0;
288  }
289  }
290  }
291  }
292  uint16_unpack_big(x + 8,&u16);
293  bpos += u16;
294  }
295 
296  if (flagauthoritative && (response_len > max_response_len)) {
297  byte_zero(response + RESPONSE_ADDITIONAL,2);
298  response_len = arpos;
299  if (response_len > MSGSIZE) {
300  byte_zero(response + RESPONSE_AUTHORITY,2);
301  response_len = aupos;
302  }
303  }
304 
305  return 1;
306 }
307 
308 int respond(char *q,char qtype[2],char ip[16])
309 {
310  int fd;
311  int r;
312 
314 
315  tai_now(&now);
316  fd = open_read("data.cdb");
317  if (fd == -1) return 0;
318  cdb_init(&c,fd);
319 
320  r = doit(q,qtype);
321 
322  cdb_free(&c);
323  close(fd);
324  return r;
325 }
int fd
Definition: axfr-get.c:103
unsigned int doit(char *buf, unsigned int len, unsigned int pos)
Definition: axfr-get.c:131
char data[32767]
Definition: axfrdns.c:131
struct tai now
Definition: axfrdns.c:130
char clientloc[2]
Definition: axfrdns.c:128
char ip[16]
Definition: axfrdns.c:126
uint16 len
Definition: axfrdns.c:302
char buf[MSGSIZE]
Definition: axfrdns.c:301
uint32 dpos
Definition: axfrdns.c:133
void doname(stralloc *sa)
Definition: axfrdns.c:141
uint32 dlen
Definition: axfrdns.c:132
int find_client_loc(char loc[2], const char ip[16])
Definition: clientloc.c:8
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
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_ANY
Definition: dns.h:66
#define MSGSIZE
Definition: dns.h:26
#define DNS_INT
Definition: dns.h:24
unsigned int dns_packet_skipname(const char *, unsigned int, unsigned int)
Definition: dns_packet.c:18
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
#define DNS_T_NS
Definition: dns.h:38
#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
struct line * x
char type[2]
Definition: dnsq.c:56
void d(const char *home, const char *subdir, int uid, int gid, int mode)
struct cdb_make cdb
Definition: rbldns-data.c:36
int response_addbytes(const char *buf, unsigned int len)
Definition: response.c:17
int response_addname(const char *d)
Definition: response.c:25
char response[65535]
Definition: response.c:6
unsigned int max_response_len
Definition: response.c:8
unsigned int response_len
Definition: response.c:7
void response_rfinish(int x)
Definition: response.c:89
void response_nxdomain(void)
Definition: response.c:103
int response_rstart(const char *d, const char type[2], uint32 ttl)
Definition: response.c:75
#define RESPONSE_AUTHORITY
Definition: response.h:24
#define RESPONSE_ANSWER
Definition: response.h:23
#define RESPONSE_ADDITIONAL
Definition: response.h:25
int respond(char *q, char qtype[2], char ip[16])
Definition: tdlookup.c:308