djbdnscurve6  38
djbdnscurve6
dnsfilter.c
Go to the documentation of this file.
1 #include <unistd.h>
2 #include "buffer.h"
3 #include "stralloc.h"
4 #include "alloc.h"
5 #include "dns.h"
6 #include "ip.h"
7 #include "byte.h"
8 #include "scan.h"
9 #include "taia.h"
10 #include "getoptb.h"
11 #include "iopause.h"
12 #include "logmsg.h"
13 #include "exit.h"
14 #include "str.h"
15 
16 #define WHO "dnsfilter"
17 
18 void nomem(void)
19 {
20  logmsg(WHO,111,FATAL,"out of memory");
21 }
22 
23 struct line {
24  stralloc left;
25  stralloc middle;
26  stralloc right;
27  struct dns_transmit dt;
29  iopause_fd *io;
30 } *x;
31 
32 struct line tmp;
33 unsigned int xmax = 1000;
34 unsigned int xnum = 0;
35 unsigned int numactive = 0;
36 unsigned int maxactive = 10;
37 
38 static stralloc partial;
39 
40 char inbuf[1024];
41 int inbuflen = 0;
42 iopause_fd *inio;
43 int flag0 = 1;
44 
45 iopause_fd *io;
46 int iolen;
47 
50 char ip4[4];
51 char ip6[16];
53 
54 void errout(int i)
55 {
56  int j;
57 
58  if (!stralloc_copys(&x[i].middle,"?")) nomem();
59  if (!stralloc_cats(&x[i].middle,errstr(errno))) nomem();
60 
61  for (j = 0; j < x[i].middle.len; ++j)
62  if (x[i].middle.s[j] == ' ')
63  x[i].middle.s[j] = '-';
64 }
65 
66 int main(int argc,char **argv)
67 {
68  struct taia stamp;
69  struct taia deadline;
70  int opt;
71  unsigned long u;
72  int i;
73  int j;
74  int r;
75 
76  while ((opt = getopt(argc,argv,"c:l:")) != opteof)
77  switch(opt) {
78  case 'c':
79  scan_ulong(optarg,&u);
80  if (u < 1) u = 1;
81  if (u > 1000) u = 1000;
82  maxactive = u;
83  break;
84  case 'l':
85  scan_ulong(optarg,&u);
86  if (u < 1) u = 1;
87  if (u > 1000000) u = 1000000;
88  xmax = u;
89  break;
90  default:
91  logmsg(WHO,100,USAGE,"dnsfilter [ -c concurrency ] [ -l lines ]");
92  }
93 
94  x = (struct line *) alloc(xmax * sizeof(struct line));
95  if (!x) nomem();
96  byte_zero(x,xmax * sizeof(struct line));
97 
98  io = (iopause_fd *) alloc((xmax + 1) * sizeof(iopause_fd));
99  if (!io) nomem();
100 
101  if (!stralloc_copys(&partial,"")) nomem();
102 
103 
104  while (flag0 || inbuflen || partial.len || xnum) {
105  taia_now(&stamp);
106  taia_uint(&deadline,120);
107  taia_add(&deadline,&deadline,&stamp);
108 
109  iolen = 0;
110 
111  if (flag0)
112  if (inbuflen < sizeof(inbuf)) {
113  inio = io + iolen++;
114  inio->fd = 0;
115  inio->events = IOPAUSE_READ;
116  }
117 
118  for (i = 0; i < xnum; ++i)
119  if (x[i].flagactive) {
120  x[i].io = io + iolen++;
121  dns_transmit_io(&x[i].dt,x[i].io,&deadline);
122  }
123 
124  r = iopause(io,iolen,&deadline,&stamp);
125 // if (r < 0) return;
126 
127  if (flag0)
128  if (inbuflen < sizeof(inbuf))
129  if (inio->revents) {
130  r = read(0,inbuf + inbuflen,(sizeof(inbuf)) - inbuflen);
131  if (r <= 0)
132  flag0 = 0;
133  else
134  inbuflen += r;
135  }
136 
137  for (i = 0; i < xnum; ++i)
138  if (x[i].flagactive) {
139  r = dns_transmit_get(&x[i].dt,x[i].io,&stamp);
140  if (r < 0) {
141  errout(i);
142  x[i].flagactive = 0;
143  --numactive;
144  }
145  else if (r == 1) {
146  if (dns_name_packet(&x[i].middle,x[i].dt.packet,x[i].dt.packetlen) < 0)
147  errout(i);
148  if (x[i].middle.len)
149  if (!stralloc_cats(&x[i].left,"=")) nomem();
150  x[i].flagactive = 0;
151  --numactive;
152  }
153  }
154 
155  for (;;) {
156  if (xnum && !x[0].flagactive) {
157  buffer_put(buffer_1,x[0].left.s,x[0].left.len);
158  buffer_put(buffer_1,x[0].middle.s,x[0].middle.len);
159  buffer_put(buffer_1,x[0].right.s,x[0].right.len);
160  buffer_flush(buffer_1);
161  --xnum;
162  tmp = x[0];
163  for (i = 0;i < xnum;++i) x[i] = x[i + 1];
164  x[xnum] = tmp;
165  continue;
166  }
167 
168  if ((xnum < xmax) && (numactive < maxactive)) {
169  i = byte_chr(inbuf,inbuflen,'\n');
170  if (inbuflen && (i == inbuflen)) {
171  if (!stralloc_catb(&partial,inbuf,inbuflen)) nomem();
172  inbuflen = 0;
173  continue;
174  }
175 
176  if ((i < inbuflen) || (!flag0 && partial.len)) {
177  if (i < inbuflen) ++i;
178  if (!stralloc_catb(&partial,inbuf,i)) nomem();
179  inbuflen -= i;
180  for (j = 0; j < inbuflen; ++j) inbuf[j] = inbuf[j + i];
181 
182  if (partial.len) {
183  i = byte_chr(partial.s,partial.len,'\n');
184  i = byte_chr(partial.s,i,'\t');
185  i = byte_chr(partial.s,i,' ');
186 
187  if (!stralloc_copyb(&x[xnum].left,partial.s,i)) nomem();
188  if (!stralloc_copys(&x[xnum].middle,"")) nomem();
189  if (!stralloc_copyb(&x[xnum].right,partial.s + i,partial.len - i)) nomem();
190  x[xnum].flagactive = 0;
191 
192  partial.len = i;
193  if (!stralloc_0(&partial)) nomem();
194  if (str_chr(partial.s,':') == partial.len - 1) {
195  if (ip4_scan(partial.s,ip4)) dns_name4_domain(name,ip4);
196  } else {
197  if (ip6_scan(partial.s,ip6)) dns_name6_domain(name,ip6);
198  }
199 
201  logmsg(WHO,111,FATAL,"unable to read /etc/resolv.conf");
202 
203  if (dns_transmit_start6(&x[xnum].dt,servers,1,name,DNS_T_PTR,V6localnet,scopes) < 0)
204  errout(xnum);
205  else {
206  x[xnum].flagactive = 1;
207  ++numactive;
208  }
209  ++xnum;
210  }
211 
212  partial.len = 0;
213  continue;
214  }
215  }
216 
217  break;
218  }
219  }
220 
221  _exit(0);
222 }
void dns_transmit_io(struct dns_transmit *, iopause_fd *, struct taia *)
Definition: dns_transmit.c:284
int dns_resolvconfip(char *, uint32 *)
#define QUERY_MAXIPLEN
Definition: dns.h:30
int dns_name_packet(stralloc *, const char *, unsigned int)
Definition: dns_name.c:9
int dns_name4_domain(char *, const char *)
#define DNS_T_PTR
Definition: dns.h:41
int dns_name6_domain(char *, const char *)
#define QUERY_MAXNS
Definition: dns.h:29
int dns_transmit_start6(struct dns_transmit *, const char *, int, const char *, const char *, const char *, const uint32 *)
#define DNS_NAME6_DOMAIN
Definition: dns.h:157
int dns_transmit_get(struct dns_transmit *, const iopause_fd *, const struct taia *)
Definition: dns_transmit.c:301
int main(int argc, char **argv)
Definition: dnsfilter.c:66
char inbuf[1024]
Definition: dnsfilter.c:40
int iolen
Definition: dnsfilter.c:46
unsigned int numactive
Definition: dnsfilter.c:35
iopause_fd * inio
Definition: dnsfilter.c:42
char ip6[16]
Definition: dnsfilter.c:51
unsigned int maxactive
Definition: dnsfilter.c:36
iopause_fd * io
Definition: dnsfilter.c:45
int flag0
Definition: dnsfilter.c:43
int inbuflen
Definition: dnsfilter.c:41
char servers[QUERY_MAXIPLEN]
Definition: dnsfilter.c:48
struct line * x
unsigned int xmax
Definition: dnsfilter.c:33
void nomem(void)
Definition: dnsfilter.c:18
uint32 scopes[QUERY_MAXNS]
Definition: dnsfilter.c:49
unsigned int xnum
Definition: dnsfilter.c:34
char name[DNS_NAME6_DOMAIN]
Definition: dnsfilter.c:52
char ip4[4]
Definition: dnsfilter.c:50
struct line tmp
Definition: dnsfilter.c:32
void errout(int i)
Definition: dnsfilter.c:54
#define WHO
Definition: dnsfilter.c:16
unsigned long u
Definition: utime.c:10
unsigned int packetlen
Definition: dns.h:77
char * packet
Definition: dns.h:76
Definition: dnsfilter.c:23
iopause_fd * io
Definition: dnsfilter.c:29
stralloc left
Definition: dnsfilter.c:24
int flagactive
Definition: dnsfilter.c:28
stralloc middle
Definition: dnsfilter.c:25
stralloc right
Definition: dnsfilter.c:26
struct dns_transmit dt
Definition: dnsfilter.c:27