#include <u.h>
#include <libc.h>
#include <ip.h>
#include <bio.h>
#include <ndb.h>
#include <ctype.h>
#include "dat.h"

/*
 *  format of a binding entry:
 *	char ipaddr[32];
 *	char id[32];
 *	char hwa[32];
 *	char otime[10];
 */
Binding *bcache;
uchar bfirst[IPaddrlen];
char *binddir = nil;
char *xbinddir = "#9/ndb/dhcp";

/*
 *  convert a byte array to hex
 */
static char
hex(int x)
{
	if(x < 10)
		return x + '0';
	return x - 10 + 'a';
}
extern char*
tohex(char *hdr, uchar *p, int len)
{
	char *s, *sp;
	int hlen;

	hlen = strlen(hdr);
	s = malloc(hlen + 2*len + 1);
	sp = s;
	strcpy(sp, hdr);
	sp += hlen;
	for(; len > 0; len--){
		*sp++ = hex(*p>>4);
		*sp++ = hex(*p & 0xf);
		p++;
	}
	*sp = 0;
	return s;
}

/*
 *  convert a client id to a string.  If it's already
 *  ascii, leave it be.  Otherwise, convert it to hex.
 */
extern char*
toid(uchar *p, int n)
{
	int i;
	char *s;

	for(i = 0; i < n; i++)
		if(!isprint(p[i]))
			return tohex("id", p, n);
	s = malloc(n + 1);
	memmove(s, p, n);
	s[n] = 0;
	return s;
}

/*
 *  increment an ip address
 */
static void
incip(uchar *ip)
{
	int i, x;

	for(i = IPaddrlen-1; i >= 0; i--){
		x = ip[i];
		x++;
		ip[i] = x;
		if((x & 0x100) == 0)
			break;
	}
}

/*
 *  find a binding for an id or hardware address
 */
static int
lockopen(char *file)
{
	char err[ERRMAX];
	int fd, tries;

	for(tries = 0; tries < 5; tries++){
		fd = open(file, OLOCK|ORDWR);
		if(fd >= 0)
			return fd;
		errstr(err, sizeof err);
		if(strstr(err, "lock")){
			/* wait for other process to let go of lock */
			sleep(250);

			/* try again */
			continue;
		}
		if(strstr(err, "exist") || strstr(err, "No such")){
			/* no file, create an exclusive access file */
			fd = create(file, ORDWR, DMEXCL|0666);
			chmod(file, 0666);
			if(fd >= 0)
				return fd;
		}
	}
	return -1;
}

void
setbinding(Binding *b, char *id, long t)
{
	if(b->boundto)
		free(b->boundto);

	b->boundto = strdup(id);
	b->lease = t;
}

static void
parsebinding(Binding *b, char *buf)
{
	long t;
	char *id, *p;

	/* parse */
	t = atoi(buf);
	id = strchr(buf, '\n');
	if(id){
		*id++ = 0;
		p = strchr(id, '\n');
		if(p)
			*p = 0;
	} else
		id = "";

	/* replace any past info */
	setbinding(b, id, t);
}

static int
writebinding(int fd, Binding *b)
{
	Dir *d;

	seek(fd, 0, 0);
	if(fprint(fd, "%ld\n%s\n", b->lease, b->boundto) < 0)
		return -1;
	d = dirfstat(fd);
	if(d == nil)
		return -1;
	b->q.type = d->qid.type;
	b->q.path = d->qid.path;
	b->q.vers = d->qid.vers;
	free(d);
	return 0;
}

/*
 *  synchronize cached binding with file.  the file always wins.
 */
int
syncbinding(Binding *b, int returnfd)
{
	char buf[512];
	int i, fd;
	Dir *d;

	if(binddir == nil)
		binddir = unsharp(xbinddir);

	snprint(buf, sizeof(buf), "%s/%I", binddir, b->ip);
	fd = lockopen(buf);
	if(fd < 0){
		/* assume someone else is using it */
		b->lease = time(0) + OfferTimeout;
		return -1;
	}

	/* reread if changed */
	d = dirfstat(fd);
	if(d != nil)	/* BUG? */
	if(d->qid.type != b->q.type || d->qid.path != b->q.path || d->qid.vers != b->q.vers){
		i = read(fd, buf, sizeof(buf)-1);
		if(i < 0)
			i = 0;
		buf[i] = 0;
		parsebinding(b, buf);
		b->lasttouched = d->mtime;
		b->q.path = d->qid.path;
		b->q.vers = d->qid.vers;
	}

	free(d);

	if(returnfd)
		return fd;

	close(fd);
	return 0;
}

extern int
samenet(uchar *ip, Info *iip)
{
	uchar x[IPaddrlen];

	maskip(iip->ipmask, ip, x);
	return ipcmp(x, iip->ipnet) == 0;
}

/*
 *  create a record for each binding
 */
extern void
initbinding(uchar *first, int n)
{
	while(n-- > 0){
		iptobinding(first, 1);
		incip(first);
	}
}

/*
 *  find a binding for a specific ip address
 */
extern Binding*
iptobinding(uchar *ip, int mk)
{
	Binding *b;

	for(b = bcache; b; b = b->next){
		if(ipcmp(b->ip, ip) == 0){
			syncbinding(b, 0);
			return b;
		}
	}

	if(mk == 0)
		return 0;
	b = malloc(sizeof(*b));
	memset(b, 0, sizeof(*b));
	ipmove(b->ip, ip);
	b->next = bcache;
	bcache = b;
	syncbinding(b, 0);
	return b;
}

static void
lognolease(Binding *b)
{
	/* renew the old binding, and hope it eventually goes away */
	b->offer = 5*60;
	commitbinding(b);

	/* complain if we haven't in the last 5 minutes */
	if(now - b->lastcomplained < 5*60)
		return;
	syslog(0, blog, "dhcp: lease for %I to %s ended at %ld but still in use\n",
		b->ip, b->boundto != nil ? b->boundto : "?", b->lease);
	b->lastcomplained = now;
}

/*
 *  find a free binding for a hw addr or id on the same network as iip
 */
extern Binding*
idtobinding(char *id, Info *iip, int ping)
{
	Binding *b, *oldest;
	int oldesttime;

	/*
	 *  first look for an old binding that matches.  that way
	 *  clients will tend to keep the same ip addresses.
	 */
	for(b = bcache; b; b = b->next){
		if(b->boundto && strcmp(b->boundto, id) == 0){
			if(!samenet(b->ip, iip))
				continue;

			/* check with the other servers */
			syncbinding(b, 0);
			if(strcmp(b->boundto, id) == 0)
				return b;
		}
	}

	/*
	 *  look for oldest binding that we think is unused
	 */
	for(;;){
		oldest = nil;
		oldesttime = 0;
		for(b = bcache; b; b = b->next){
			if(b->tried != now)
			if(b->lease < now && b->expoffer < now && samenet(b->ip, iip))
			if(oldest == nil || b->lasttouched < oldesttime){
				/* sync and check again */
				syncbinding(b, 0);
				if(b->lease < now && b->expoffer < now && samenet(b->ip, iip))
				if(oldest == nil || b->lasttouched < oldesttime){
					oldest = b;
					oldesttime = b->lasttouched;
				}
			}
		}
		if(oldest == nil)
			break;

		/* make sure noone is still using it */
		oldest->tried = now;
		if(ping == 0 || icmpecho(oldest->ip) == 0)
			return oldest;

		lognolease(oldest);	/* sets lastcomplained */
	}

	/* try all bindings */
	for(b = bcache; b; b = b->next){
		syncbinding(b, 0);
		if(b->tried != now)
		if(b->lease < now && b->expoffer < now && samenet(b->ip, iip)){
			b->tried = now;
			if(ping == 0 || icmpecho(b->ip) == 0)
				return b;

			lognolease(b);
		}
	}

	/* nothing worked, give up */
	return 0;
}

/*
 *  create an offer
 */
extern void
mkoffer(Binding *b, char *id, long leasetime)
{
	if(leasetime <= 0){
		if(b->lease > now + minlease)
			leasetime = b->lease - now;
		else
			leasetime = minlease;
	}
	if(b->offeredto)
		free(b->offeredto);
	b->offeredto = strdup(id);
	b->offer = leasetime;
	b->expoffer = now + OfferTimeout;
}

/*
 *  find an offer for this id
 */
extern Binding*
idtooffer(char *id, Info *iip)
{
	Binding *b;

	/* look for an offer to this id */
	for(b = bcache; b; b = b->next){
		if(b->offeredto && strcmp(b->offeredto, id) == 0 && samenet(b->ip, iip)){
			/* make sure some other system hasn't stolen it */
			syncbinding(b, 0);
			if(b->lease < now
			|| (b->boundto && strcmp(b->boundto, b->offeredto) == 0))
				return b;
		}
	}
	return 0;
}

/*
 *  commit a lease, this could fail
 */
extern int
commitbinding(Binding *b)
{
	int fd;
	long now;

	now = time(0);

	if(b->offeredto == 0)
		return -1;
	fd = syncbinding(b, 1);
	if(fd < 0)
		return -1;
	if(b->lease > now && b->boundto && strcmp(b->boundto, b->offeredto) != 0){
		close(fd);
		return -1;
	}
	setbinding(b, b->offeredto, now + b->offer);
	b->lasttouched = now;
	
	if(writebinding(fd, b) < 0){
		close(fd);
		return -1;
	}
	close(fd);
	return 0;
}

/*
 *  commit a lease, this could fail
 */
extern int
releasebinding(Binding *b, char *id)
{
	int fd;
	long now;

	now = time(0);

	fd = syncbinding(b, 1);
	if(fd < 0)
		return -1;
	if(b->lease > now && b->boundto && strcmp(b->boundto, id) != 0){
		close(fd);
		return -1;
	}
	b->lease = 0;
	b->expoffer = 0;
	
	if(writebinding(fd, b) < 0){
		close(fd);
		return -1;
	}
	close(fd);
	return 0;
}
