Blame


1 3e0d8fb3 2005-12-27 devnull #include <u.h>
2 3e0d8fb3 2005-12-27 devnull #include <libc.h>
3 3e0d8fb3 2005-12-27 devnull #include <ip.h>
4 3e0d8fb3 2005-12-27 devnull #include <bio.h>
5 3e0d8fb3 2005-12-27 devnull #include <ndb.h>
6 5c9f76b5 2006-02-14 devnull #include <thread.h>
7 3e0d8fb3 2005-12-27 devnull #include "dns.h"
8 3e0d8fb3 2005-12-27 devnull
9 3e0d8fb3 2005-12-27 devnull static int udpannounce(char*);
10 3e0d8fb3 2005-12-27 devnull static void reply(int, uchar*, DNSmsg*, Request*);
11 3e0d8fb3 2005-12-27 devnull
12 3e0d8fb3 2005-12-27 devnull extern char *logfile;
13 3e0d8fb3 2005-12-27 devnull
14 3e0d8fb3 2005-12-27 devnull typedef struct Inprogress Inprogress;
15 3e0d8fb3 2005-12-27 devnull struct Inprogress
16 3e0d8fb3 2005-12-27 devnull {
17 3e0d8fb3 2005-12-27 devnull int inuse;
18 5c9f76b5 2006-02-14 devnull Udphdr uh;
19 3e0d8fb3 2005-12-27 devnull DN *owner;
20 3e0d8fb3 2005-12-27 devnull int type;
21 3e0d8fb3 2005-12-27 devnull int id;
22 3e0d8fb3 2005-12-27 devnull };
23 3e0d8fb3 2005-12-27 devnull Inprogress inprog[Maxactive+2];
24 b65f95f6 2006-02-17 devnull QLock inproglk;
25 3e0d8fb3 2005-12-27 devnull
26 3e0d8fb3 2005-12-27 devnull /*
27 3e0d8fb3 2005-12-27 devnull * record client id and ignore retransmissions.
28 3e0d8fb3 2005-12-27 devnull */
29 3e0d8fb3 2005-12-27 devnull static Inprogress*
30 3e0d8fb3 2005-12-27 devnull clientrxmit(DNSmsg *req, uchar *buf)
31 3e0d8fb3 2005-12-27 devnull {
32 3e0d8fb3 2005-12-27 devnull Inprogress *p, *empty;
33 5c9f76b5 2006-02-14 devnull Udphdr *uh;
34 3e0d8fb3 2005-12-27 devnull
35 b65f95f6 2006-02-17 devnull qlock(&inproglk);
36 5c9f76b5 2006-02-14 devnull uh = (Udphdr *)buf;
37 3e0d8fb3 2005-12-27 devnull empty = 0;
38 3e0d8fb3 2005-12-27 devnull for(p = inprog; p < &inprog[Maxactive]; p++){
39 3e0d8fb3 2005-12-27 devnull if(p->inuse == 0){
40 3e0d8fb3 2005-12-27 devnull if(empty == 0)
41 3e0d8fb3 2005-12-27 devnull empty = p;
42 3e0d8fb3 2005-12-27 devnull continue;
43 3e0d8fb3 2005-12-27 devnull }
44 3e0d8fb3 2005-12-27 devnull if(req->id == p->id)
45 3e0d8fb3 2005-12-27 devnull if(req->qd->owner == p->owner)
46 3e0d8fb3 2005-12-27 devnull if(req->qd->type == p->type)
47 b65f95f6 2006-02-17 devnull if(memcmp(uh, &p->uh, Udphdrsize) == 0){
48 b65f95f6 2006-02-17 devnull qunlock(&inproglk);
49 3e0d8fb3 2005-12-27 devnull return 0;
50 b65f95f6 2006-02-17 devnull }
51 3e0d8fb3 2005-12-27 devnull }
52 b65f95f6 2006-02-17 devnull if(empty == 0){
53 b65f95f6 2006-02-17 devnull qunlock(&inproglk);
54 3e0d8fb3 2005-12-27 devnull return 0; /* shouldn't happen - see slave() and definition of Maxactive */
55 b65f95f6 2006-02-17 devnull }
56 3e0d8fb3 2005-12-27 devnull
57 3e0d8fb3 2005-12-27 devnull empty->id = req->id;
58 3e0d8fb3 2005-12-27 devnull empty->owner = req->qd->owner;
59 3e0d8fb3 2005-12-27 devnull empty->type = req->qd->type;
60 5c9f76b5 2006-02-14 devnull memmove(&empty->uh, uh, Udphdrsize);
61 3e0d8fb3 2005-12-27 devnull empty->inuse = 1;
62 b65f95f6 2006-02-17 devnull qunlock(&inproglk);
63 3e0d8fb3 2005-12-27 devnull return empty;
64 3e0d8fb3 2005-12-27 devnull }
65 3e0d8fb3 2005-12-27 devnull
66 3e0d8fb3 2005-12-27 devnull /*
67 3e0d8fb3 2005-12-27 devnull * a process to act as a dns server for outside reqeusts
68 3e0d8fb3 2005-12-27 devnull */
69 5c9f76b5 2006-02-14 devnull static void
70 5c9f76b5 2006-02-14 devnull udpproc(void *v)
71 3e0d8fb3 2005-12-27 devnull {
72 3e0d8fb3 2005-12-27 devnull int fd, len, op;
73 3e0d8fb3 2005-12-27 devnull Request req;
74 3e0d8fb3 2005-12-27 devnull DNSmsg reqmsg, repmsg;
75 5c9f76b5 2006-02-14 devnull uchar buf[Udphdrsize + Maxudp + 1024];
76 3e0d8fb3 2005-12-27 devnull char *err;
77 3e0d8fb3 2005-12-27 devnull Inprogress *p;
78 3e0d8fb3 2005-12-27 devnull char tname[32];
79 5c9f76b5 2006-02-14 devnull Udphdr *uh;
80 3e0d8fb3 2005-12-27 devnull
81 19256e0d 2006-02-17 devnull fd = (uintptr)v;
82 3e0d8fb3 2005-12-27 devnull
83 3e0d8fb3 2005-12-27 devnull /* loop on requests */
84 3e0d8fb3 2005-12-27 devnull for(;; putactivity()){
85 3e0d8fb3 2005-12-27 devnull memset(&repmsg, 0, sizeof(repmsg));
86 3e0d8fb3 2005-12-27 devnull memset(&reqmsg, 0, sizeof(reqmsg));
87 5c9f76b5 2006-02-14 devnull len = udpread(fd, (Udphdr*)buf, buf+Udphdrsize, sizeof(buf)-Udphdrsize);
88 3e0d8fb3 2005-12-27 devnull if(len <= 0)
89 5c9f76b5 2006-02-14 devnull continue;
90 5c9f76b5 2006-02-14 devnull uh = (Udphdr*)buf;
91 3e0d8fb3 2005-12-27 devnull getactivity(&req);
92 3e0d8fb3 2005-12-27 devnull req.aborttime = now + 30; /* don't spend more than 30 seconds */
93 5c9f76b5 2006-02-14 devnull err = convM2DNS(&buf[Udphdrsize], len, &reqmsg);
94 3e0d8fb3 2005-12-27 devnull if(err){
95 3e0d8fb3 2005-12-27 devnull syslog(0, logfile, "server: input error: %s from %I", err, buf);
96 3e0d8fb3 2005-12-27 devnull continue;
97 3e0d8fb3 2005-12-27 devnull }
98 3e0d8fb3 2005-12-27 devnull if(reqmsg.qdcount < 1){
99 3e0d8fb3 2005-12-27 devnull syslog(0, logfile, "server: no questions from %I", buf);
100 3e0d8fb3 2005-12-27 devnull goto freereq;
101 3e0d8fb3 2005-12-27 devnull }
102 3e0d8fb3 2005-12-27 devnull if(reqmsg.flags & Fresp){
103 3e0d8fb3 2005-12-27 devnull syslog(0, logfile, "server: reply not request from %I", buf);
104 3e0d8fb3 2005-12-27 devnull goto freereq;
105 3e0d8fb3 2005-12-27 devnull }
106 3e0d8fb3 2005-12-27 devnull op = reqmsg.flags & Omask;
107 3e0d8fb3 2005-12-27 devnull if(op != Oquery && op != Onotify){
108 3e0d8fb3 2005-12-27 devnull syslog(0, logfile, "server: op %d from %I", reqmsg.flags & Omask, buf);
109 3e0d8fb3 2005-12-27 devnull goto freereq;
110 3e0d8fb3 2005-12-27 devnull }
111 3e0d8fb3 2005-12-27 devnull
112 3e0d8fb3 2005-12-27 devnull if(debug || (trace && subsume(trace, reqmsg.qd->owner->name))){
113 3e0d8fb3 2005-12-27 devnull syslog(0, logfile, "%d: serve (%I/%d) %d %s %s",
114 3e0d8fb3 2005-12-27 devnull req.id, buf, ((uh->rport[0])<<8)+uh->rport[1],
115 3e0d8fb3 2005-12-27 devnull reqmsg.id,
116 3e0d8fb3 2005-12-27 devnull reqmsg.qd->owner->name,
117 3e0d8fb3 2005-12-27 devnull rrname(reqmsg.qd->type, tname, sizeof tname));
118 3e0d8fb3 2005-12-27 devnull }
119 3e0d8fb3 2005-12-27 devnull
120 3e0d8fb3 2005-12-27 devnull p = clientrxmit(&reqmsg, buf);
121 3e0d8fb3 2005-12-27 devnull if(p == 0){
122 3e0d8fb3 2005-12-27 devnull if(debug)
123 3e0d8fb3 2005-12-27 devnull syslog(0, logfile, "%d: duplicate", req.id);
124 3e0d8fb3 2005-12-27 devnull goto freereq;
125 3e0d8fb3 2005-12-27 devnull }
126 3e0d8fb3 2005-12-27 devnull
127 3e0d8fb3 2005-12-27 devnull /* loop through each question */
128 3e0d8fb3 2005-12-27 devnull while(reqmsg.qd){
129 3e0d8fb3 2005-12-27 devnull memset(&repmsg, 0, sizeof(repmsg));
130 3e0d8fb3 2005-12-27 devnull switch(op){
131 3e0d8fb3 2005-12-27 devnull case Oquery:
132 3e0d8fb3 2005-12-27 devnull dnserver(&reqmsg, &repmsg, &req);
133 3e0d8fb3 2005-12-27 devnull break;
134 3e0d8fb3 2005-12-27 devnull case Onotify:
135 3e0d8fb3 2005-12-27 devnull dnnotify(&reqmsg, &repmsg, &req);
136 3e0d8fb3 2005-12-27 devnull break;
137 3e0d8fb3 2005-12-27 devnull }
138 3e0d8fb3 2005-12-27 devnull reply(fd, buf, &repmsg, &req);
139 3e0d8fb3 2005-12-27 devnull rrfreelist(repmsg.qd);
140 3e0d8fb3 2005-12-27 devnull rrfreelist(repmsg.an);
141 3e0d8fb3 2005-12-27 devnull rrfreelist(repmsg.ns);
142 3e0d8fb3 2005-12-27 devnull rrfreelist(repmsg.ar);
143 3e0d8fb3 2005-12-27 devnull }
144 3e0d8fb3 2005-12-27 devnull
145 3e0d8fb3 2005-12-27 devnull p->inuse = 0;
146 3e0d8fb3 2005-12-27 devnull
147 3e0d8fb3 2005-12-27 devnull freereq:
148 3e0d8fb3 2005-12-27 devnull rrfreelist(reqmsg.qd);
149 3e0d8fb3 2005-12-27 devnull rrfreelist(reqmsg.an);
150 3e0d8fb3 2005-12-27 devnull rrfreelist(reqmsg.ns);
151 3e0d8fb3 2005-12-27 devnull rrfreelist(reqmsg.ar);
152 3e0d8fb3 2005-12-27 devnull }
153 3e0d8fb3 2005-12-27 devnull }
154 3e0d8fb3 2005-12-27 devnull
155 3e0d8fb3 2005-12-27 devnull /*
156 3e0d8fb3 2005-12-27 devnull * announce on udp port
157 3e0d8fb3 2005-12-27 devnull */
158 3e0d8fb3 2005-12-27 devnull static int
159 3e0d8fb3 2005-12-27 devnull udpannounce(char *mntpt)
160 3e0d8fb3 2005-12-27 devnull {
161 3e0d8fb3 2005-12-27 devnull int fd;
162 3e0d8fb3 2005-12-27 devnull char buf[40];
163 3e0d8fb3 2005-12-27 devnull USED(mntpt);
164 5c9f76b5 2006-02-14 devnull
165 49a1496c 2006-02-20 devnull if((fd=announce(udpaddr, buf)) < 0)
166 19256e0d 2006-02-17 devnull warning("announce %s: %r", buf);
167 3e0d8fb3 2005-12-27 devnull return fd;
168 3e0d8fb3 2005-12-27 devnull }
169 3e0d8fb3 2005-12-27 devnull
170 3e0d8fb3 2005-12-27 devnull static void
171 3e0d8fb3 2005-12-27 devnull reply(int fd, uchar *buf, DNSmsg *rep, Request *reqp)
172 3e0d8fb3 2005-12-27 devnull {
173 3e0d8fb3 2005-12-27 devnull int len;
174 3e0d8fb3 2005-12-27 devnull char tname[32];
175 3e0d8fb3 2005-12-27 devnull RR *rp;
176 3e0d8fb3 2005-12-27 devnull
177 3e0d8fb3 2005-12-27 devnull if(debug || (trace && subsume(trace, rep->qd->owner->name)))
178 3e0d8fb3 2005-12-27 devnull syslog(0, logfile, "%d: reply (%I/%d) %d %s %s an %R ns %R ar %R",
179 3e0d8fb3 2005-12-27 devnull reqp->id, buf, ((buf[4])<<8)+buf[5],
180 3e0d8fb3 2005-12-27 devnull rep->id, rep->qd->owner->name,
181 3e0d8fb3 2005-12-27 devnull rrname(rep->qd->type, tname, sizeof tname), rep->an, rep->ns, rep->ar);
182 3e0d8fb3 2005-12-27 devnull
183 5c9f76b5 2006-02-14 devnull len = convDNS2M(rep, &buf[Udphdrsize], Maxudp);
184 3e0d8fb3 2005-12-27 devnull if(len <= 0){
185 3e0d8fb3 2005-12-27 devnull syslog(0, logfile, "error converting reply: %s %d", rep->qd->owner->name,
186 3e0d8fb3 2005-12-27 devnull rep->qd->type);
187 3e0d8fb3 2005-12-27 devnull for(rp = rep->an; rp; rp = rp->next)
188 3e0d8fb3 2005-12-27 devnull syslog(0, logfile, "an %R", rp);
189 3e0d8fb3 2005-12-27 devnull for(rp = rep->ns; rp; rp = rp->next)
190 3e0d8fb3 2005-12-27 devnull syslog(0, logfile, "ns %R", rp);
191 3e0d8fb3 2005-12-27 devnull for(rp = rep->ar; rp; rp = rp->next)
192 3e0d8fb3 2005-12-27 devnull syslog(0, logfile, "ar %R", rp);
193 3e0d8fb3 2005-12-27 devnull return;
194 3e0d8fb3 2005-12-27 devnull }
195 5c9f76b5 2006-02-14 devnull if(udpwrite(fd, (Udphdr*)buf, buf+Udphdrsize, len) != len)
196 3e0d8fb3 2005-12-27 devnull syslog(0, logfile, "error sending reply: %r");
197 3e0d8fb3 2005-12-27 devnull }
198 5c9f76b5 2006-02-14 devnull
199 5c9f76b5 2006-02-14 devnull void
200 5c9f76b5 2006-02-14 devnull dnudpserver(void *v)
201 5c9f76b5 2006-02-14 devnull {
202 5c9f76b5 2006-02-14 devnull int i, fd;
203 5c9f76b5 2006-02-14 devnull
204 5c9f76b5 2006-02-14 devnull while((fd = udpannounce(v)) < 0)
205 5c9f76b5 2006-02-14 devnull sleep(5*1000);
206 5c9f76b5 2006-02-14 devnull for(i=0; i<Maxactive; i++)
207 19256e0d 2006-02-17 devnull proccreate(udpproc, (void*)(uintptr)fd, STACK);
208 5c9f76b5 2006-02-14 devnull }
209 5c9f76b5 2006-02-14 devnull