Blame


1 87a52e04 2005-12-26 devnull #include <u.h>
2 87a52e04 2005-12-26 devnull #include <libc.h>
3 87a52e04 2005-12-26 devnull #include <ip.h>
4 87a52e04 2005-12-26 devnull #include <bio.h>
5 87a52e04 2005-12-26 devnull #include <ndb.h>
6 87a52e04 2005-12-26 devnull #include <ctype.h>
7 87a52e04 2005-12-26 devnull #include "dat.h"
8 87a52e04 2005-12-26 devnull
9 87a52e04 2005-12-26 devnull /*
10 87a52e04 2005-12-26 devnull * format of a binding entry:
11 87a52e04 2005-12-26 devnull * char ipaddr[32];
12 87a52e04 2005-12-26 devnull * char id[32];
13 87a52e04 2005-12-26 devnull * char hwa[32];
14 87a52e04 2005-12-26 devnull * char otime[10];
15 87a52e04 2005-12-26 devnull */
16 87a52e04 2005-12-26 devnull Binding *bcache;
17 87a52e04 2005-12-26 devnull uchar bfirst[IPaddrlen];
18 87a52e04 2005-12-26 devnull char *binddir = nil;
19 87a52e04 2005-12-26 devnull char *xbinddir = "#9/ndb/dhcp";
20 87a52e04 2005-12-26 devnull
21 87a52e04 2005-12-26 devnull /*
22 87a52e04 2005-12-26 devnull * convert a byte array to hex
23 87a52e04 2005-12-26 devnull */
24 87a52e04 2005-12-26 devnull static char
25 87a52e04 2005-12-26 devnull hex(int x)
26 87a52e04 2005-12-26 devnull {
27 87a52e04 2005-12-26 devnull if(x < 10)
28 87a52e04 2005-12-26 devnull return x + '0';
29 87a52e04 2005-12-26 devnull return x - 10 + 'a';
30 87a52e04 2005-12-26 devnull }
31 87a52e04 2005-12-26 devnull extern char*
32 87a52e04 2005-12-26 devnull tohex(char *hdr, uchar *p, int len)
33 87a52e04 2005-12-26 devnull {
34 87a52e04 2005-12-26 devnull char *s, *sp;
35 87a52e04 2005-12-26 devnull int hlen;
36 87a52e04 2005-12-26 devnull
37 87a52e04 2005-12-26 devnull hlen = strlen(hdr);
38 87a52e04 2005-12-26 devnull s = malloc(hlen + 2*len + 1);
39 87a52e04 2005-12-26 devnull sp = s;
40 87a52e04 2005-12-26 devnull strcpy(sp, hdr);
41 87a52e04 2005-12-26 devnull sp += hlen;
42 87a52e04 2005-12-26 devnull for(; len > 0; len--){
43 87a52e04 2005-12-26 devnull *sp++ = hex(*p>>4);
44 87a52e04 2005-12-26 devnull *sp++ = hex(*p & 0xf);
45 87a52e04 2005-12-26 devnull p++;
46 87a52e04 2005-12-26 devnull }
47 87a52e04 2005-12-26 devnull *sp = 0;
48 87a52e04 2005-12-26 devnull return s;
49 87a52e04 2005-12-26 devnull }
50 87a52e04 2005-12-26 devnull
51 87a52e04 2005-12-26 devnull /*
52 87a52e04 2005-12-26 devnull * convert a client id to a string. If it's already
53 87a52e04 2005-12-26 devnull * ascii, leave it be. Otherwise, convert it to hex.
54 87a52e04 2005-12-26 devnull */
55 87a52e04 2005-12-26 devnull extern char*
56 87a52e04 2005-12-26 devnull toid(uchar *p, int n)
57 87a52e04 2005-12-26 devnull {
58 87a52e04 2005-12-26 devnull int i;
59 87a52e04 2005-12-26 devnull char *s;
60 87a52e04 2005-12-26 devnull
61 87a52e04 2005-12-26 devnull for(i = 0; i < n; i++)
62 87a52e04 2005-12-26 devnull if(!isprint(p[i]))
63 87a52e04 2005-12-26 devnull return tohex("id", p, n);
64 87a52e04 2005-12-26 devnull s = malloc(n + 1);
65 87a52e04 2005-12-26 devnull memmove(s, p, n);
66 87a52e04 2005-12-26 devnull s[n] = 0;
67 87a52e04 2005-12-26 devnull return s;
68 87a52e04 2005-12-26 devnull }
69 87a52e04 2005-12-26 devnull
70 87a52e04 2005-12-26 devnull /*
71 87a52e04 2005-12-26 devnull * increment an ip address
72 87a52e04 2005-12-26 devnull */
73 87a52e04 2005-12-26 devnull static void
74 87a52e04 2005-12-26 devnull incip(uchar *ip)
75 87a52e04 2005-12-26 devnull {
76 87a52e04 2005-12-26 devnull int i, x;
77 87a52e04 2005-12-26 devnull
78 87a52e04 2005-12-26 devnull for(i = IPaddrlen-1; i >= 0; i--){
79 87a52e04 2005-12-26 devnull x = ip[i];
80 87a52e04 2005-12-26 devnull x++;
81 87a52e04 2005-12-26 devnull ip[i] = x;
82 87a52e04 2005-12-26 devnull if((x & 0x100) == 0)
83 87a52e04 2005-12-26 devnull break;
84 87a52e04 2005-12-26 devnull }
85 87a52e04 2005-12-26 devnull }
86 87a52e04 2005-12-26 devnull
87 87a52e04 2005-12-26 devnull /*
88 87a52e04 2005-12-26 devnull * find a binding for an id or hardware address
89 87a52e04 2005-12-26 devnull */
90 87a52e04 2005-12-26 devnull static int
91 87a52e04 2005-12-26 devnull lockopen(char *file)
92 87a52e04 2005-12-26 devnull {
93 87a52e04 2005-12-26 devnull char err[ERRMAX];
94 87a52e04 2005-12-26 devnull int fd, tries;
95 87a52e04 2005-12-26 devnull
96 87a52e04 2005-12-26 devnull for(tries = 0; tries < 5; tries++){
97 87a52e04 2005-12-26 devnull fd = open(file, OLOCK|ORDWR);
98 87a52e04 2005-12-26 devnull if(fd >= 0)
99 87a52e04 2005-12-26 devnull return fd;
100 87a52e04 2005-12-26 devnull print("open %s: %r\n", file);
101 87a52e04 2005-12-26 devnull errstr(err, sizeof err);
102 87a52e04 2005-12-26 devnull if(strstr(err, "lock")){
103 87a52e04 2005-12-26 devnull /* wait for other process to let go of lock */
104 87a52e04 2005-12-26 devnull sleep(250);
105 87a52e04 2005-12-26 devnull
106 87a52e04 2005-12-26 devnull /* try again */
107 87a52e04 2005-12-26 devnull continue;
108 87a52e04 2005-12-26 devnull }
109 87a52e04 2005-12-26 devnull if(strstr(err, "exist") || strstr(err, "No such")){
110 87a52e04 2005-12-26 devnull /* no file, create an exclusive access file */
111 87a52e04 2005-12-26 devnull fd = create(file, ORDWR, DMEXCL|0666);
112 87a52e04 2005-12-26 devnull chmod(file, 0666);
113 87a52e04 2005-12-26 devnull if(fd >= 0)
114 87a52e04 2005-12-26 devnull return fd;
115 87a52e04 2005-12-26 devnull }
116 87a52e04 2005-12-26 devnull }
117 87a52e04 2005-12-26 devnull return -1;
118 87a52e04 2005-12-26 devnull }
119 87a52e04 2005-12-26 devnull
120 87a52e04 2005-12-26 devnull void
121 87a52e04 2005-12-26 devnull setbinding(Binding *b, char *id, long t)
122 87a52e04 2005-12-26 devnull {
123 87a52e04 2005-12-26 devnull if(b->boundto)
124 87a52e04 2005-12-26 devnull free(b->boundto);
125 87a52e04 2005-12-26 devnull
126 87a52e04 2005-12-26 devnull b->boundto = strdup(id);
127 87a52e04 2005-12-26 devnull b->lease = t;
128 87a52e04 2005-12-26 devnull }
129 87a52e04 2005-12-26 devnull
130 87a52e04 2005-12-26 devnull static void
131 87a52e04 2005-12-26 devnull parsebinding(Binding *b, char *buf)
132 87a52e04 2005-12-26 devnull {
133 87a52e04 2005-12-26 devnull long t;
134 87a52e04 2005-12-26 devnull char *id, *p;
135 87a52e04 2005-12-26 devnull
136 87a52e04 2005-12-26 devnull /* parse */
137 87a52e04 2005-12-26 devnull t = atoi(buf);
138 87a52e04 2005-12-26 devnull id = strchr(buf, '\n');
139 87a52e04 2005-12-26 devnull if(id){
140 87a52e04 2005-12-26 devnull *id++ = 0;
141 87a52e04 2005-12-26 devnull p = strchr(id, '\n');
142 87a52e04 2005-12-26 devnull if(p)
143 87a52e04 2005-12-26 devnull *p = 0;
144 87a52e04 2005-12-26 devnull } else
145 87a52e04 2005-12-26 devnull id = "";
146 87a52e04 2005-12-26 devnull
147 87a52e04 2005-12-26 devnull /* replace any past info */
148 87a52e04 2005-12-26 devnull setbinding(b, id, t);
149 87a52e04 2005-12-26 devnull }
150 87a52e04 2005-12-26 devnull
151 87a52e04 2005-12-26 devnull static int
152 87a52e04 2005-12-26 devnull writebinding(int fd, Binding *b)
153 87a52e04 2005-12-26 devnull {
154 87a52e04 2005-12-26 devnull Dir *d;
155 87a52e04 2005-12-26 devnull
156 87a52e04 2005-12-26 devnull seek(fd, 0, 0);
157 87a52e04 2005-12-26 devnull if(fprint(fd, "%ld\n%s\n", b->lease, b->boundto) < 0)
158 87a52e04 2005-12-26 devnull return -1;
159 87a52e04 2005-12-26 devnull d = dirfstat(fd);
160 87a52e04 2005-12-26 devnull if(d == nil)
161 87a52e04 2005-12-26 devnull return -1;
162 87a52e04 2005-12-26 devnull b->q.type = d->qid.type;
163 87a52e04 2005-12-26 devnull b->q.path = d->qid.path;
164 87a52e04 2005-12-26 devnull b->q.vers = d->qid.vers;
165 87a52e04 2005-12-26 devnull free(d);
166 87a52e04 2005-12-26 devnull return 0;
167 87a52e04 2005-12-26 devnull }
168 87a52e04 2005-12-26 devnull
169 87a52e04 2005-12-26 devnull /*
170 87a52e04 2005-12-26 devnull * synchronize cached binding with file. the file always wins.
171 87a52e04 2005-12-26 devnull */
172 87a52e04 2005-12-26 devnull int
173 87a52e04 2005-12-26 devnull syncbinding(Binding *b, int returnfd)
174 87a52e04 2005-12-26 devnull {
175 87a52e04 2005-12-26 devnull char buf[512];
176 87a52e04 2005-12-26 devnull int i, fd;
177 87a52e04 2005-12-26 devnull Dir *d;
178 87a52e04 2005-12-26 devnull
179 87a52e04 2005-12-26 devnull if(binddir == nil)
180 87a52e04 2005-12-26 devnull binddir = unsharp(xbinddir);
181 87a52e04 2005-12-26 devnull
182 87a52e04 2005-12-26 devnull snprint(buf, sizeof(buf), "%s/%I", binddir, b->ip);
183 87a52e04 2005-12-26 devnull fd = lockopen(buf);
184 87a52e04 2005-12-26 devnull if(fd < 0){
185 87a52e04 2005-12-26 devnull /* assume someone else is using it */
186 87a52e04 2005-12-26 devnull b->lease = time(0) + OfferTimeout;
187 87a52e04 2005-12-26 devnull return -1;
188 87a52e04 2005-12-26 devnull }
189 87a52e04 2005-12-26 devnull
190 87a52e04 2005-12-26 devnull /* reread if changed */
191 87a52e04 2005-12-26 devnull d = dirfstat(fd);
192 87a52e04 2005-12-26 devnull if(d != nil) /* BUG? */
193 87a52e04 2005-12-26 devnull if(d->qid.type != b->q.type || d->qid.path != b->q.path || d->qid.vers != b->q.vers){
194 87a52e04 2005-12-26 devnull i = read(fd, buf, sizeof(buf)-1);
195 87a52e04 2005-12-26 devnull if(i < 0)
196 87a52e04 2005-12-26 devnull i = 0;
197 87a52e04 2005-12-26 devnull buf[i] = 0;
198 87a52e04 2005-12-26 devnull parsebinding(b, buf);
199 87a52e04 2005-12-26 devnull b->lasttouched = d->mtime;
200 87a52e04 2005-12-26 devnull b->q.path = d->qid.path;
201 87a52e04 2005-12-26 devnull b->q.vers = d->qid.vers;
202 87a52e04 2005-12-26 devnull }
203 87a52e04 2005-12-26 devnull
204 87a52e04 2005-12-26 devnull free(d);
205 87a52e04 2005-12-26 devnull
206 87a52e04 2005-12-26 devnull if(returnfd)
207 87a52e04 2005-12-26 devnull return fd;
208 87a52e04 2005-12-26 devnull
209 87a52e04 2005-12-26 devnull close(fd);
210 87a52e04 2005-12-26 devnull return 0;
211 87a52e04 2005-12-26 devnull }
212 87a52e04 2005-12-26 devnull
213 87a52e04 2005-12-26 devnull extern int
214 87a52e04 2005-12-26 devnull samenet(uchar *ip, Info *iip)
215 87a52e04 2005-12-26 devnull {
216 87a52e04 2005-12-26 devnull uchar x[IPaddrlen];
217 87a52e04 2005-12-26 devnull
218 87a52e04 2005-12-26 devnull maskip(iip->ipmask, ip, x);
219 87a52e04 2005-12-26 devnull return ipcmp(x, iip->ipnet) == 0;
220 87a52e04 2005-12-26 devnull }
221 87a52e04 2005-12-26 devnull
222 87a52e04 2005-12-26 devnull /*
223 87a52e04 2005-12-26 devnull * create a record for each binding
224 87a52e04 2005-12-26 devnull */
225 87a52e04 2005-12-26 devnull extern void
226 87a52e04 2005-12-26 devnull initbinding(uchar *first, int n)
227 87a52e04 2005-12-26 devnull {
228 87a52e04 2005-12-26 devnull while(n-- > 0){
229 87a52e04 2005-12-26 devnull iptobinding(first, 1);
230 87a52e04 2005-12-26 devnull incip(first);
231 87a52e04 2005-12-26 devnull }
232 87a52e04 2005-12-26 devnull }
233 87a52e04 2005-12-26 devnull
234 87a52e04 2005-12-26 devnull /*
235 87a52e04 2005-12-26 devnull * find a binding for a specific ip address
236 87a52e04 2005-12-26 devnull */
237 87a52e04 2005-12-26 devnull extern Binding*
238 87a52e04 2005-12-26 devnull iptobinding(uchar *ip, int mk)
239 87a52e04 2005-12-26 devnull {
240 87a52e04 2005-12-26 devnull Binding *b;
241 87a52e04 2005-12-26 devnull
242 87a52e04 2005-12-26 devnull for(b = bcache; b; b = b->next){
243 87a52e04 2005-12-26 devnull if(ipcmp(b->ip, ip) == 0){
244 87a52e04 2005-12-26 devnull syncbinding(b, 0);
245 87a52e04 2005-12-26 devnull return b;
246 87a52e04 2005-12-26 devnull }
247 87a52e04 2005-12-26 devnull }
248 87a52e04 2005-12-26 devnull
249 87a52e04 2005-12-26 devnull if(mk == 0)
250 87a52e04 2005-12-26 devnull return 0;
251 87a52e04 2005-12-26 devnull b = malloc(sizeof(*b));
252 87a52e04 2005-12-26 devnull memset(b, 0, sizeof(*b));
253 87a52e04 2005-12-26 devnull ipmove(b->ip, ip);
254 87a52e04 2005-12-26 devnull b->next = bcache;
255 87a52e04 2005-12-26 devnull bcache = b;
256 87a52e04 2005-12-26 devnull syncbinding(b, 0);
257 87a52e04 2005-12-26 devnull return b;
258 87a52e04 2005-12-26 devnull }
259 87a52e04 2005-12-26 devnull
260 87a52e04 2005-12-26 devnull static void
261 87a52e04 2005-12-26 devnull lognolease(Binding *b)
262 87a52e04 2005-12-26 devnull {
263 87a52e04 2005-12-26 devnull /* renew the old binding, and hope it eventually goes away */
264 87a52e04 2005-12-26 devnull b->offer = 5*60;
265 87a52e04 2005-12-26 devnull commitbinding(b);
266 87a52e04 2005-12-26 devnull
267 87a52e04 2005-12-26 devnull /* complain if we haven't in the last 5 minutes */
268 87a52e04 2005-12-26 devnull if(now - b->lastcomplained < 5*60)
269 87a52e04 2005-12-26 devnull return;
270 87a52e04 2005-12-26 devnull syslog(0, blog, "dhcp: lease for %I to %s ended at %ld but still in use\n",
271 87a52e04 2005-12-26 devnull b->ip, b->boundto != nil ? b->boundto : "?", b->lease);
272 87a52e04 2005-12-26 devnull b->lastcomplained = now;
273 87a52e04 2005-12-26 devnull }
274 87a52e04 2005-12-26 devnull
275 87a52e04 2005-12-26 devnull /*
276 87a52e04 2005-12-26 devnull * find a free binding for a hw addr or id on the same network as iip
277 87a52e04 2005-12-26 devnull */
278 87a52e04 2005-12-26 devnull extern Binding*
279 87a52e04 2005-12-26 devnull idtobinding(char *id, Info *iip, int ping)
280 87a52e04 2005-12-26 devnull {
281 87a52e04 2005-12-26 devnull Binding *b, *oldest;
282 87a52e04 2005-12-26 devnull int oldesttime;
283 87a52e04 2005-12-26 devnull
284 87a52e04 2005-12-26 devnull /*
285 87a52e04 2005-12-26 devnull * first look for an old binding that matches. that way
286 87a52e04 2005-12-26 devnull * clients will tend to keep the same ip addresses.
287 87a52e04 2005-12-26 devnull */
288 87a52e04 2005-12-26 devnull for(b = bcache; b; b = b->next){
289 87a52e04 2005-12-26 devnull if(b->boundto && strcmp(b->boundto, id) == 0){
290 87a52e04 2005-12-26 devnull if(!samenet(b->ip, iip))
291 87a52e04 2005-12-26 devnull continue;
292 87a52e04 2005-12-26 devnull
293 87a52e04 2005-12-26 devnull /* check with the other servers */
294 87a52e04 2005-12-26 devnull syncbinding(b, 0);
295 87a52e04 2005-12-26 devnull if(strcmp(b->boundto, id) == 0)
296 87a52e04 2005-12-26 devnull return b;
297 87a52e04 2005-12-26 devnull }
298 87a52e04 2005-12-26 devnull }
299 87a52e04 2005-12-26 devnull
300 87a52e04 2005-12-26 devnull print("looking for old for %I\n", iip->ipnet);
301 87a52e04 2005-12-26 devnull
302 87a52e04 2005-12-26 devnull /*
303 87a52e04 2005-12-26 devnull * look for oldest binding that we think is unused
304 87a52e04 2005-12-26 devnull */
305 87a52e04 2005-12-26 devnull for(;;){
306 87a52e04 2005-12-26 devnull oldest = nil;
307 87a52e04 2005-12-26 devnull oldesttime = 0;
308 87a52e04 2005-12-26 devnull for(b = bcache; b; b = b->next){
309 87a52e04 2005-12-26 devnull print("tried %d now %d lease %d exp %d %I\n", b->tried, now, b->lease, b->expoffer, b->ip);
310 87a52e04 2005-12-26 devnull if(b->tried != now)
311 87a52e04 2005-12-26 devnull if(b->lease < now && b->expoffer < now && samenet(b->ip, iip))
312 87a52e04 2005-12-26 devnull if(oldest == nil || b->lasttouched < oldesttime){
313 87a52e04 2005-12-26 devnull /* sync and check again */
314 87a52e04 2005-12-26 devnull syncbinding(b, 0);
315 87a52e04 2005-12-26 devnull if(b->lease < now && b->expoffer < now && samenet(b->ip, iip))
316 87a52e04 2005-12-26 devnull if(oldest == nil || b->lasttouched < oldesttime){
317 87a52e04 2005-12-26 devnull oldest = b;
318 87a52e04 2005-12-26 devnull print("have oldest\n");
319 87a52e04 2005-12-26 devnull oldesttime = b->lasttouched;
320 87a52e04 2005-12-26 devnull }
321 87a52e04 2005-12-26 devnull }
322 87a52e04 2005-12-26 devnull }
323 87a52e04 2005-12-26 devnull if(oldest == nil)
324 87a52e04 2005-12-26 devnull break;
325 87a52e04 2005-12-26 devnull
326 87a52e04 2005-12-26 devnull /* make sure noone is still using it */
327 87a52e04 2005-12-26 devnull oldest->tried = now;
328 87a52e04 2005-12-26 devnull print("return oldest\n");
329 87a52e04 2005-12-26 devnull if(ping == 0 || icmpecho(oldest->ip) == 0)
330 87a52e04 2005-12-26 devnull return oldest;
331 87a52e04 2005-12-26 devnull
332 87a52e04 2005-12-26 devnull lognolease(oldest); /* sets lastcomplained */
333 87a52e04 2005-12-26 devnull }
334 87a52e04 2005-12-26 devnull
335 87a52e04 2005-12-26 devnull /* try all bindings */
336 87a52e04 2005-12-26 devnull for(b = bcache; b; b = b->next){
337 87a52e04 2005-12-26 devnull syncbinding(b, 0);
338 87a52e04 2005-12-26 devnull if(b->tried != now)
339 87a52e04 2005-12-26 devnull if(b->lease < now && b->expoffer < now && samenet(b->ip, iip)){
340 87a52e04 2005-12-26 devnull b->tried = now;
341 87a52e04 2005-12-26 devnull if(ping == 0 || icmpecho(b->ip) == 0)
342 87a52e04 2005-12-26 devnull return b;
343 87a52e04 2005-12-26 devnull
344 87a52e04 2005-12-26 devnull lognolease(b);
345 87a52e04 2005-12-26 devnull }
346 87a52e04 2005-12-26 devnull }
347 87a52e04 2005-12-26 devnull
348 87a52e04 2005-12-26 devnull /* nothing worked, give up */
349 87a52e04 2005-12-26 devnull return 0;
350 87a52e04 2005-12-26 devnull }
351 87a52e04 2005-12-26 devnull
352 87a52e04 2005-12-26 devnull /*
353 87a52e04 2005-12-26 devnull * create an offer
354 87a52e04 2005-12-26 devnull */
355 87a52e04 2005-12-26 devnull extern void
356 87a52e04 2005-12-26 devnull mkoffer(Binding *b, char *id, long leasetime)
357 87a52e04 2005-12-26 devnull {
358 87a52e04 2005-12-26 devnull if(leasetime <= 0){
359 87a52e04 2005-12-26 devnull if(b->lease > now + minlease)
360 87a52e04 2005-12-26 devnull leasetime = b->lease - now;
361 87a52e04 2005-12-26 devnull else
362 87a52e04 2005-12-26 devnull leasetime = minlease;
363 87a52e04 2005-12-26 devnull }
364 87a52e04 2005-12-26 devnull if(b->offeredto)
365 87a52e04 2005-12-26 devnull free(b->offeredto);
366 87a52e04 2005-12-26 devnull b->offeredto = strdup(id);
367 87a52e04 2005-12-26 devnull b->offer = leasetime;
368 87a52e04 2005-12-26 devnull b->expoffer = now + OfferTimeout;
369 87a52e04 2005-12-26 devnull }
370 87a52e04 2005-12-26 devnull
371 87a52e04 2005-12-26 devnull /*
372 87a52e04 2005-12-26 devnull * find an offer for this id
373 87a52e04 2005-12-26 devnull */
374 87a52e04 2005-12-26 devnull extern Binding*
375 87a52e04 2005-12-26 devnull idtooffer(char *id, Info *iip)
376 87a52e04 2005-12-26 devnull {
377 87a52e04 2005-12-26 devnull Binding *b;
378 87a52e04 2005-12-26 devnull
379 87a52e04 2005-12-26 devnull /* look for an offer to this id */
380 87a52e04 2005-12-26 devnull for(b = bcache; b; b = b->next){
381 87a52e04 2005-12-26 devnull print("%I %I ? offeredto %s id %s\n", b->ip, iip->ipnet, b->offeredto, id);
382 87a52e04 2005-12-26 devnull if(b->offeredto && strcmp(b->offeredto, id) == 0 && samenet(b->ip, iip)){
383 87a52e04 2005-12-26 devnull /* make sure some other system hasn't stolen it */
384 87a52e04 2005-12-26 devnull syncbinding(b, 0);
385 87a52e04 2005-12-26 devnull print("b->lease %d now %d boundto %s offered %s\n", b->lease, now, b->boundto, b->offeredto);
386 87a52e04 2005-12-26 devnull if(b->lease < now
387 87a52e04 2005-12-26 devnull || (b->boundto && strcmp(b->boundto, b->offeredto) == 0))
388 87a52e04 2005-12-26 devnull return b;
389 87a52e04 2005-12-26 devnull }
390 87a52e04 2005-12-26 devnull }
391 87a52e04 2005-12-26 devnull return 0;
392 87a52e04 2005-12-26 devnull }
393 87a52e04 2005-12-26 devnull
394 87a52e04 2005-12-26 devnull /*
395 87a52e04 2005-12-26 devnull * commit a lease, this could fail
396 87a52e04 2005-12-26 devnull */
397 87a52e04 2005-12-26 devnull extern int
398 87a52e04 2005-12-26 devnull commitbinding(Binding *b)
399 87a52e04 2005-12-26 devnull {
400 87a52e04 2005-12-26 devnull int fd;
401 87a52e04 2005-12-26 devnull long now;
402 87a52e04 2005-12-26 devnull
403 87a52e04 2005-12-26 devnull now = time(0);
404 87a52e04 2005-12-26 devnull
405 87a52e04 2005-12-26 devnull if(b->offeredto == 0)
406 87a52e04 2005-12-26 devnull return -1;
407 87a52e04 2005-12-26 devnull fd = syncbinding(b, 1);
408 87a52e04 2005-12-26 devnull if(fd < 0)
409 87a52e04 2005-12-26 devnull return -1;
410 87a52e04 2005-12-26 devnull if(b->lease > now && b->boundto && strcmp(b->boundto, b->offeredto) != 0){
411 87a52e04 2005-12-26 devnull close(fd);
412 87a52e04 2005-12-26 devnull return -1;
413 87a52e04 2005-12-26 devnull }
414 87a52e04 2005-12-26 devnull setbinding(b, b->offeredto, now + b->offer);
415 87a52e04 2005-12-26 devnull b->lasttouched = now;
416 87a52e04 2005-12-26 devnull
417 87a52e04 2005-12-26 devnull if(writebinding(fd, b) < 0){
418 87a52e04 2005-12-26 devnull close(fd);
419 87a52e04 2005-12-26 devnull return -1;
420 87a52e04 2005-12-26 devnull }
421 87a52e04 2005-12-26 devnull close(fd);
422 87a52e04 2005-12-26 devnull return 0;
423 87a52e04 2005-12-26 devnull }
424 87a52e04 2005-12-26 devnull
425 87a52e04 2005-12-26 devnull /*
426 87a52e04 2005-12-26 devnull * commit a lease, this could fail
427 87a52e04 2005-12-26 devnull */
428 87a52e04 2005-12-26 devnull extern int
429 87a52e04 2005-12-26 devnull releasebinding(Binding *b, char *id)
430 87a52e04 2005-12-26 devnull {
431 87a52e04 2005-12-26 devnull int fd;
432 87a52e04 2005-12-26 devnull long now;
433 87a52e04 2005-12-26 devnull
434 87a52e04 2005-12-26 devnull now = time(0);
435 87a52e04 2005-12-26 devnull
436 87a52e04 2005-12-26 devnull fd = syncbinding(b, 1);
437 87a52e04 2005-12-26 devnull if(fd < 0)
438 87a52e04 2005-12-26 devnull return -1;
439 87a52e04 2005-12-26 devnull if(b->lease > now && b->boundto && strcmp(b->boundto, id) != 0){
440 87a52e04 2005-12-26 devnull close(fd);
441 87a52e04 2005-12-26 devnull return -1;
442 87a52e04 2005-12-26 devnull }
443 87a52e04 2005-12-26 devnull b->lease = 0;
444 87a52e04 2005-12-26 devnull b->expoffer = 0;
445 87a52e04 2005-12-26 devnull
446 87a52e04 2005-12-26 devnull if(writebinding(fd, b) < 0){
447 87a52e04 2005-12-26 devnull close(fd);
448 87a52e04 2005-12-26 devnull return -1;
449 87a52e04 2005-12-26 devnull }
450 87a52e04 2005-12-26 devnull close(fd);
451 87a52e04 2005-12-26 devnull return 0;
452 87a52e04 2005-12-26 devnull }