djbdnscurve6 45
djbdnscurve6
Loading...
Searching...
No Matches
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
17static 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;
31 if (byte_equal(type,2,x)) return 0;
32 uint16_unpack_big(x + 8,&datalen);
33 pos += datalen;
34 }
35 return 1;
36}
37
38static char *d1;
39
40static char clientloc[2];
41static struct tai now;
42static struct cdb c;
43
44static char data[32767];
45static uint32 dlen;
46static unsigned int dpos;
47static char type[2];
48static uint32 ttl;
49
50static int find(char *d,int flagwild)
51{
52 int r;
53 char ch;
54 struct tai cutoff;
55 char ttd[8];
56 char ttlstr[4];
57 char recordloc[2];
58 double newttl;
59
60 for (;;) {
61 r = cdb_findnext(&c,d,dns_domain_length(d));
62 if (r <= 0) return r;
63 dlen = cdb_datalen(&c);
64 if (dlen > sizeof(data)) return DNS_ERR;
65 if (cdb_read(&c,data,dlen,cdb_datapos(&c)) == -1) return DNS_INT;
66 dpos = dns_packet_copy(data,dlen,0,type,2); if (!dpos) return DNS_ERR;
67 dpos = dns_packet_copy(data,dlen,dpos,&ch,1); if (!dpos) return DNS_ERR;
68 if ((ch == '=' + 1) || (ch == '*' + 1) || (ch == '6' + 1)) {
69 --ch;
70 dpos = dns_packet_copy(data,dlen,dpos,recordloc,2); if (!dpos) return DNS_ERR;
71 if (byte_diff(recordloc,2,clientloc)) continue;
72 }
73 if (flagwild != (ch == '*')) continue;
74 dpos = dns_packet_copy(data,dlen,dpos,ttlstr,4); if (!dpos) return DNS_ERR;
75 uint32_unpack_big(ttlstr,&ttl);
76 dpos = dns_packet_copy(data,dlen,dpos,ttd,8); if (!dpos) return DNS_ERR;
77 if (byte_diff(ttd,8,"\0\0\0\0\0\0\0\0")) {
78 tai_unpack(ttd,&cutoff);
79 if (ttl == 0) {
80 if (tai_less(&cutoff,&now)) continue;
81 tai_sub(&cutoff,&cutoff,&now);
82 newttl = tai_approx(&cutoff);
83 if (newttl <= 2.0) newttl = 2.0;
84 if (newttl >= 3600.0) newttl = 3600.0;
85 ttl = newttl;
86 }
87 else
88 if (!tai_less(&cutoff,&now)) continue;
89 }
90 return 1;
91 }
92}
93
94static int dobytes(unsigned int len)
95{
96 char buf[20];
97 if (len > 20) return 0;
99 if (!dpos) return 0;
100 return response_addbytes(buf,len);
101}
102
103static int doname(void)
104{
106 if (!dpos) return 0;
107 return response_addname(d1);
108}
109
110static int doit(char *q,char qtype[2])
111{
112 unsigned int bpos;
113 unsigned int anpos;
114 unsigned int aupos;
115 unsigned int arpos;
116 char *control;
117 char *wild;
118 int flaggavesoa;
119 int flagfound;
120 int r;
121 int flagns;
122 int flagauthoritative;
123 char x[20];
124 uint16 u16;
125 char addr[8][4];
126 char addr6[8][16];
127 int addrnum,addr6num;
128 uint32 addrttl;
129 uint32 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 } else if (want(control,DNS_T_NS)) {
250 cdb_findstart(&c);
251 while ((r = find(control,0))) {
252 if (r == -1) return 0;
253 if (byte_equal(type,2,DNS_T_NS)) {
254 if (!response_rstart(control,DNS_T_NS,ttl)) return 0;
255 if (!doname()) return 0;
257 }
258 }
259 }
260
261 arpos = response_len;
262
263 bpos = anpos;
264 while (bpos < arpos) {
265 bpos = dns_packet_skipname(response,arpos,bpos); if (!bpos) return 0;
266 bpos = dns_packet_copy(response,arpos,bpos,x,10); if (!bpos) return 0;
267 if (byte_equal(x,2,DNS_T_NS) || byte_equal(x,2,DNS_T_MX)) {
268 if (byte_equal(x,2,DNS_T_NS)) {
269 if (!dns_packet_getname(response,arpos,bpos,&d1)) return 0;
270 }
271 else if (!dns_packet_getname(response,arpos,bpos + 2,&d1)) return 0;
272 case_lowerb(d1,dns_domain_length(d1));
273 if (want(d1,DNS_T_A)) {
274 cdb_findstart(&c);
275 while ((r = find(d1,0))) {
276 if (r == -1) return 0;
277 if (byte_equal(type,2,DNS_T_A)) {
278 if (!response_rstart(d1,DNS_T_A,ttl)) return 0;
279 if (!dobytes(4)) return 0;
281 }
282 else if (byte_equal(type,2,DNS_T_AAAA)) {
283 if (!response_rstart(d1,DNS_T_AAAA,ttl)) return 0;
284 if (!dobytes(16)) return 0;
286 }
287 }
288 }
289 }
290 uint16_unpack_big(x + 8,&u16);
291 bpos += u16;
292 }
293
294 if (flagauthoritative && (response_len > max_response_len)) {
295 byte_zero(response + RESPONSE_ADDITIONAL,2);
296 response_len = arpos;
297 if (response_len > MSGSIZE) {
298 byte_zero(response + RESPONSE_AUTHORITY,2);
299 response_len = aupos;
300 }
301 }
302
303 return 1;
304}
305
306int respond(char *q,char qtype[2],char ip[16])
307{
308 int fd;
309 int r;
310
312
313 tai_now(&now);
314 fd = open_read("data.cdb");
315 if (fd == -1) return 0;
316 cdb_init(&c,fd);
317
318 r = doit(q,qtype);
319
320 cdb_free(&c);
321 close(fd);
322 return r;
323}
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:130
struct tai now
Definition: axfrdns.c:129
char clientloc[2]
Definition: axfrdns.c:127
char ip[16]
Definition: axfrdns.c:125
uint16 len
Definition: axfrdns.c:319
char buf[MSGSIZE]
Definition: axfrdns.c:318
uint32 dpos
Definition: axfrdns.c:132
void doname(stralloc *sa)
Definition: axfrdns.c:140
uint32 dlen
Definition: axfrdns.c:131
int find_clientloc(char clientloc[2], const char ip[16])
Definition: clientloc.c:8
#define DNS_ERR
Definition: dns.h:32
#define DNS_T_A
Definition: dns.h:56
#define DNS_T_ANY
Definition: dns.h:85
#define MSGSIZE
Definition: dns.h:38
#define DNS_INT
Definition: dns.h:34
#define DNS_T_PTR
Definition: dns.h:60
#define DNS_T_SOA
Definition: dns.h:59
#define DNS_T_NS
Definition: dns.h:57
#define DNS_T_CNAME
Definition: dns.h:58
#define DNS_T_AAAA
Definition: dns.h:67
#define DNS_T_MX
Definition: dns.h:62
int dns_domain_equal(const char *dn1, const char *dn2)
Definition: dns_domain.c:39
unsigned int dns_domain_length(const char *dn)
Definition: dns_domain.c:6
unsigned int dns_packet_getname(const char *buf, unsigned int len, unsigned int pos, char **d)
Definition: dns_packet.c:35
unsigned int dns_packet_copy(const char *buf, unsigned int len, unsigned int pos, char *out, unsigned int outlen)
Definition: dns_packet.c:8
unsigned int dns_packet_skipname(const char *buf, unsigned int len, unsigned int pos)
Definition: dns_packet.c:18
unsigned int dns_random(unsigned int n)
Definition: dns_random.c:56
struct line * x
char type[2]
Definition: dnsq.c:56
void owner(int uid, int gid)
Definition: generic-conf.c:76
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_addname(const char *)
Definition: response.c:25
void response_rfinish(int)
Definition: response.c:89
int response_addbytes(const char *, unsigned int)
Definition: response.c:17
char response[]
Definition: response.c:6
unsigned int max_response_len
Definition: response.c:8
unsigned int response_len
Definition: response.c:7
#define RESPONSE_AUTHORITY
Definition: response.h:24
int response_rstart(const char *, const char *, uint32)
#define RESPONSE_ANSWER
Definition: response.h:23
void response_nxdomain(void)
Definition: response.c:103
#define RESPONSE_ADDITIONAL
Definition: response.h:25
int respond(char *q, char qtype[2], char ip[16])
Definition: tdlookup.c:306