From b9decf4304d2204173a8d8a706e003cdde2b1bf7 Mon Sep 17 00:00:00 2001 From: Laurent Ghigonis Date: Thu, 29 Nov 2012 10:58:30 +0100 Subject: move glougloud to old --- glougloud/BUGS.txt | 10 - glougloud/Makefile | 12 - glougloud/README.txt | 51 --- glougloud/external/README.txt | 8 - glougloud/external/imsg-buffer.c | 305 --------------- glougloud/external/imsg.c | 301 --------------- glougloud/external/imsg.h | 118 ------ glougloud/external/imsgev.c | 170 --------- glougloud/external/imsgev.h | 49 --- glougloud/external/queue.h | 568 --------------------------- glougloud/glougloud.c | 487 ----------------------- glougloud/glougloud.h | 79 ---- glougloud/server.c | 238 ------------ glougloud/user.c | 806 --------------------------------------- glougloud/util.c | 192 ---------- 15 files changed, 3394 deletions(-) delete mode 100644 glougloud/BUGS.txt delete mode 100644 glougloud/Makefile delete mode 100644 glougloud/README.txt delete mode 100644 glougloud/external/README.txt delete mode 100644 glougloud/external/imsg-buffer.c delete mode 100644 glougloud/external/imsg.c delete mode 100644 glougloud/external/imsg.h delete mode 100644 glougloud/external/imsgev.c delete mode 100644 glougloud/external/imsgev.h delete mode 100644 glougloud/external/queue.h delete mode 100644 glougloud/glougloud.c delete mode 100644 glougloud/glougloud.h delete mode 100644 glougloud/server.c delete mode 100644 glougloud/user.c delete mode 100644 glougloud/util.c (limited to 'glougloud') diff --git a/glougloud/BUGS.txt b/glougloud/BUGS.txt deleted file mode 100644 index 8380e70..0000000 --- a/glougloud/BUGS.txt +++ /dev/null @@ -1,10 +0,0 @@ -#0000 TITLE -DESCRIPTION - -=== TODO === - -#0001 fatal() messages should be printed on stderr -see util.c fatal() - - -=== DONE === diff --git a/glougloud/Makefile b/glougloud/Makefile deleted file mode 100644 index d37dde2..0000000 --- a/glougloud/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -PROG = glougloud -OBJS = glougloud.o server.o user.o util.o external/imsgev.o external/imsg-buffer.o external/imsg.o -CFLAGS+=-Wall -g -LDFLAGS=-lpcap -levent -lutil - -all: - make $(OBJS) - $(CC) $(OBJS) -o $(PROG) $(LDFLAGS) - -clean: - rm -f $(PROG) *~ *.o external/*.o - diff --git a/glougloud/README.txt b/glougloud/README.txt deleted file mode 100644 index 8a8c702..0000000 --- a/glougloud/README.txt +++ /dev/null @@ -1,51 +0,0 @@ -glougloud - glouglou daemon, for network traffic visualisation in real time - - -=== Requirements === - -* libglouglou - -Known to work on OpenBSD 5.1 and Linux 3.4 - - -=== Installation === - -git clone git@meg:glouglou - -sudo useradd -d /var/empty/ -s /sbin/nologin _glougloud - - -=== Usage === - -* Run the daemon - -cd glouglou/glougloud/ -sudo ./glougloud - -It logs to /var/log/glougloud. -For the moment it monitors lo0 interface. - -* Connect to the daemon - -nc -vvv -u 127.0.0.1 4430 |hexdump -C - -You get informations of traffic flowing on the monitored interface. - - -=== Notes on architecture and security === - -glougloud is architectured in 3 processes: - * main process, runs as root, opens the capture interfaces with -libpcap and resolves DNS names - * server process, runs as _glougloud user and chrooted in _glougloud -home, listens and accepts or refuses clients connections - * user process, runs as _glougloud user and chrooted in _glougloud -home, parses the captured network traffic and sends a summary to the -connected clients - -The 3 processes exchanges messages througt messages, with OpenBSD imsg -framework. - -Note that glougloud activates extra protections on pcap capture only -on OpenBSD by reimplementing some of libpcap functions, see -glougloud.c my_pcap_open_live() diff --git a/glougloud/external/README.txt b/glougloud/external/README.txt deleted file mode 100644 index 7e7509f..0000000 --- a/glougloud/external/README.txt +++ /dev/null @@ -1,8 +0,0 @@ -- imsg framework, and IPC mechanism from OpenBSD - -imsg-buffer.c -imsg.c -imsg.h -imsgev.c -imsgev.h -- queue implementation, from OpenBSD - -queue.h diff --git a/glougloud/external/imsg-buffer.c b/glougloud/external/imsg-buffer.c deleted file mode 100644 index 9f04757..0000000 --- a/glougloud/external/imsg-buffer.c +++ /dev/null @@ -1,305 +0,0 @@ -/* $OpenBSD: imsg-buffer.c,v 1.2 2012/06/02 21:46:53 gilles Exp $ */ - -/* - * Copyright (c) 2003, 2004 Henning Brauer - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "imsg.h" - -int ibuf_realloc(struct ibuf *, size_t); -void ibuf_enqueue(struct msgbuf *, struct ibuf *); -void ibuf_dequeue(struct msgbuf *, struct ibuf *); - -struct ibuf * -ibuf_open(size_t len) -{ - struct ibuf *buf; - - if ((buf = calloc(1, sizeof(struct ibuf))) == NULL) - return (NULL); - if ((buf->buf = malloc(len)) == NULL) { - free(buf); - return (NULL); - } - buf->size = buf->max = len; - buf->fd = -1; - - return (buf); -} - -struct ibuf * -ibuf_dynamic(size_t len, size_t max) -{ - struct ibuf *buf; - - if (max < len) - return (NULL); - - if ((buf = ibuf_open(len)) == NULL) - return (NULL); - - if (max > 0) - buf->max = max; - - return (buf); -} - -int -ibuf_realloc(struct ibuf *buf, size_t len) -{ - u_char *b; - - /* on static buffers max is eq size and so the following fails */ - if (buf->wpos + len > buf->max) { - errno = ENOMEM; - return (-1); - } - - b = realloc(buf->buf, buf->wpos + len); - if (b == NULL) - return (-1); - buf->buf = b; - buf->size = buf->wpos + len; - - return (0); -} - -int -ibuf_add(struct ibuf *buf, const void *data, size_t len) -{ - if (buf->wpos + len > buf->size) - if (ibuf_realloc(buf, len) == -1) - return (-1); - - memcpy(buf->buf + buf->wpos, data, len); - buf->wpos += len; - return (0); -} - -void * -ibuf_reserve(struct ibuf *buf, size_t len) -{ - void *b; - - if (buf->wpos + len > buf->size) - if (ibuf_realloc(buf, len) == -1) - return (NULL); - - b = buf->buf + buf->wpos; - buf->wpos += len; - return (b); -} - -void * -ibuf_seek(struct ibuf *buf, size_t pos, size_t len) -{ - /* only allowed to seek in already written parts */ - if (pos + len > buf->wpos) - return (NULL); - - return (buf->buf + pos); -} - -size_t -ibuf_size(struct ibuf *buf) -{ - return (buf->wpos); -} - -size_t -ibuf_left(struct ibuf *buf) -{ - return (buf->max - buf->wpos); -} - -void -ibuf_close(struct msgbuf *msgbuf, struct ibuf *buf) -{ - ibuf_enqueue(msgbuf, buf); -} - -int -ibuf_write(struct msgbuf *msgbuf) -{ - struct iovec iov[IOV_MAX]; - struct ibuf *buf; - unsigned int i = 0; - ssize_t n; - - bzero(&iov, sizeof(iov)); - TAILQ_FOREACH(buf, &msgbuf->bufs, entry) { - if (i >= IOV_MAX) - break; - iov[i].iov_base = buf->buf + buf->rpos; - iov[i].iov_len = buf->wpos - buf->rpos; - i++; - } - -again: - if ((n = writev(msgbuf->fd, iov, i)) == -1) { - if (errno == EAGAIN || errno == EINTR) - goto again; - if (errno == ENOBUFS) - errno = EAGAIN; - return (-1); - } - - if (n == 0) { /* connection closed */ - errno = 0; - return (0); - } - - msgbuf_drain(msgbuf, n); - - return (1); -} - -void -ibuf_free(struct ibuf *buf) -{ - free(buf->buf); - free(buf); -} - -void -msgbuf_init(struct msgbuf *msgbuf) -{ - msgbuf->queued = 0; - msgbuf->fd = -1; - TAILQ_INIT(&msgbuf->bufs); -} - -void -msgbuf_drain(struct msgbuf *msgbuf, size_t n) -{ - struct ibuf *buf, *next; - - for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0; - buf = next) { - next = TAILQ_NEXT(buf, entry); - if (buf->rpos + n >= buf->wpos) { - n -= buf->wpos - buf->rpos; - ibuf_dequeue(msgbuf, buf); - } else { - buf->rpos += n; - n = 0; - } - } -} - -void -msgbuf_clear(struct msgbuf *msgbuf) -{ - struct ibuf *buf; - - while ((buf = TAILQ_FIRST(&msgbuf->bufs)) != NULL) - ibuf_dequeue(msgbuf, buf); -} - -int -msgbuf_write(struct msgbuf *msgbuf) -{ - struct iovec iov[IOV_MAX]; - struct ibuf *buf; - unsigned int i = 0; - ssize_t n; - struct msghdr msg; - struct cmsghdr *cmsg; - union { - struct cmsghdr hdr; - char buf[CMSG_SPACE(sizeof(int))]; - } cmsgbuf; - - bzero(&iov, sizeof(iov)); - bzero(&msg, sizeof(msg)); - TAILQ_FOREACH(buf, &msgbuf->bufs, entry) { - if (i >= IOV_MAX) - break; - iov[i].iov_base = buf->buf + buf->rpos; - iov[i].iov_len = buf->wpos - buf->rpos; - i++; - if (buf->fd != -1) - break; - } - - msg.msg_iov = iov; - msg.msg_iovlen = i; - - if (buf != NULL && buf->fd != -1) { - msg.msg_control = (caddr_t)&cmsgbuf.buf; - msg.msg_controllen = sizeof(cmsgbuf.buf); - cmsg = CMSG_FIRSTHDR(&msg); - cmsg->cmsg_len = CMSG_LEN(sizeof(int)); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - *(int *)CMSG_DATA(cmsg) = buf->fd; - } - -again: - if ((n = sendmsg(msgbuf->fd, &msg, 0)) == -1) { - if (errno == EAGAIN || errno == EINTR) - goto again; - if (errno == ENOBUFS) - errno = EAGAIN; - return (-1); - } - - if (n == 0) { /* connection closed */ - errno = 0; - return (0); - } - - /* - * assumption: fd got sent if sendmsg sent anything - * this works because fds are passed one at a time - */ - if (buf != NULL && buf->fd != -1) { - close(buf->fd); - buf->fd = -1; - } - - msgbuf_drain(msgbuf, n); - - return (1); -} - -void -ibuf_enqueue(struct msgbuf *msgbuf, struct ibuf *buf) -{ - TAILQ_INSERT_TAIL(&msgbuf->bufs, buf, entry); - msgbuf->queued++; -} - -void -ibuf_dequeue(struct msgbuf *msgbuf, struct ibuf *buf) -{ - TAILQ_REMOVE(&msgbuf->bufs, buf, entry); - - if (buf->fd != -1) - close(buf->fd); - - msgbuf->queued--; - ibuf_free(buf); -} diff --git a/glougloud/external/imsg.c b/glougloud/external/imsg.c deleted file mode 100644 index 05e57c7..0000000 --- a/glougloud/external/imsg.c +++ /dev/null @@ -1,301 +0,0 @@ -/* $OpenBSD: imsg.c,v 1.2 2012/06/02 21:46:53 gilles Exp $ */ - -/* - * Copyright (c) 2003, 2004 Henning Brauer - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "imsg.h" - -int imsg_fd_overhead = 0; - -int imsg_get_fd(struct imsgbuf *); - -void -imsg_init(struct imsgbuf *ibuf, int fd) -{ - msgbuf_init(&ibuf->w); - bzero(&ibuf->r, sizeof(ibuf->r)); - ibuf->fd = fd; - ibuf->w.fd = fd; - ibuf->pid = getpid(); - TAILQ_INIT(&ibuf->fds); -} - -ssize_t -imsg_read(struct imsgbuf *ibuf) -{ - struct msghdr msg; - struct cmsghdr *cmsg; - union { - struct cmsghdr hdr; - char buf[CMSG_SPACE(sizeof(int) * 1)]; - } cmsgbuf; - struct iovec iov; - ssize_t n = -1; - int fd; - struct imsg_fd *ifd; - - bzero(&msg, sizeof(msg)); - - iov.iov_base = ibuf->r.buf + ibuf->r.wpos; - iov.iov_len = sizeof(ibuf->r.buf) - ibuf->r.wpos; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_control = &cmsgbuf.buf; - msg.msg_controllen = sizeof(cmsgbuf.buf); - - if ((ifd = calloc(1, sizeof(struct imsg_fd))) == NULL) - return (-1); - -again: - if (getdtablecount() + imsg_fd_overhead + - (CMSG_SPACE(sizeof(int))-CMSG_SPACE(0))/sizeof(int) - >= getdtablesize()) { - errno = EAGAIN; - return (-1); - } - - if ((n = recvmsg(ibuf->fd, &msg, 0)) == -1) { - if (errno == EMSGSIZE) - goto fail; - if (errno != EINTR && errno != EAGAIN) - goto fail; - goto again; - } - - ibuf->r.wpos += n; - - for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) { - if (cmsg->cmsg_level == SOL_SOCKET && - cmsg->cmsg_type == SCM_RIGHTS) { - int i; - int j; - - /* - * We only accept one file descriptor. Due to C - * padding rules, our control buffer might contain - * more than one fd, and we must close them. - */ - j = ((char *)cmsg + cmsg->cmsg_len - - (char *)CMSG_DATA(cmsg)) / sizeof(int); - for (i = 0; i < j; i++) { - fd = ((int *)CMSG_DATA(cmsg))[i]; - if (i == 0) { - ifd->fd = fd; - TAILQ_INSERT_TAIL(&ibuf->fds, ifd, - entry); - ifd = NULL; - } else - close(fd); - } - } - /* we do not handle other ctl data level */ - } - -fail: - if (ifd) - free(ifd); - return (n); -} - -ssize_t -imsg_get(struct imsgbuf *ibuf, struct imsg *imsg) -{ - size_t av, left, datalen; - - av = ibuf->r.wpos; - - if (IMSG_HEADER_SIZE > av) - return (0); - - memcpy(&imsg->hdr, ibuf->r.buf, sizeof(imsg->hdr)); - if (imsg->hdr.len < IMSG_HEADER_SIZE || - imsg->hdr.len > MAX_IMSGSIZE) { - errno = ERANGE; - return (-1); - } - if (imsg->hdr.len > av) - return (0); - datalen = imsg->hdr.len - IMSG_HEADER_SIZE; - ibuf->r.rptr = ibuf->r.buf + IMSG_HEADER_SIZE; - if ((imsg->data = malloc(datalen)) == NULL) - return (-1); - - if (imsg->hdr.flags & IMSGF_HASFD) - imsg->fd = imsg_get_fd(ibuf); - else - imsg->fd = -1; - - memcpy(imsg->data, ibuf->r.rptr, datalen); - - if (imsg->hdr.len < av) { - left = av - imsg->hdr.len; - memmove(&ibuf->r.buf, ibuf->r.buf + imsg->hdr.len, left); - ibuf->r.wpos = left; - } else - ibuf->r.wpos = 0; - - return (datalen + IMSG_HEADER_SIZE); -} - -int -imsg_compose(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid, - pid_t pid, int fd, void *data, u_int16_t datalen) -{ - struct ibuf *wbuf; - - if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL) - return (-1); - - if (imsg_add(wbuf, data, datalen) == -1) - return (-1); - - wbuf->fd = fd; - - imsg_close(ibuf, wbuf); - - return (1); -} - -int -imsg_composev(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid, - pid_t pid, int fd, const struct iovec *iov, int iovcnt) -{ - struct ibuf *wbuf; - int i, datalen = 0; - - for (i = 0; i < iovcnt; i++) - datalen += iov[i].iov_len; - - if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL) - return (-1); - - for (i = 0; i < iovcnt; i++) - if (imsg_add(wbuf, iov[i].iov_base, iov[i].iov_len) == -1) - return (-1); - - wbuf->fd = fd; - - imsg_close(ibuf, wbuf); - - return (1); -} - -/* ARGSUSED */ -struct ibuf * -imsg_create(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid, - pid_t pid, u_int16_t datalen) -{ - struct ibuf *wbuf; - struct imsg_hdr hdr; - - datalen += IMSG_HEADER_SIZE; - if (datalen > MAX_IMSGSIZE) { - errno = ERANGE; - return (NULL); - } - - hdr.type = type; - hdr.flags = 0; - hdr.peerid = peerid; - if ((hdr.pid = pid) == 0) - hdr.pid = ibuf->pid; - if ((wbuf = ibuf_dynamic(datalen, MAX_IMSGSIZE)) == NULL) { - return (NULL); - } - if (imsg_add(wbuf, &hdr, sizeof(hdr)) == -1) - return (NULL); - - return (wbuf); -} - -int -imsg_add(struct ibuf *msg, void *data, u_int16_t datalen) -{ - if (datalen) - if (ibuf_add(msg, data, datalen) == -1) { - ibuf_free(msg); - return (-1); - } - return (datalen); -} - -void -imsg_close(struct imsgbuf *ibuf, struct ibuf *msg) -{ - struct imsg_hdr *hdr; - - hdr = (struct imsg_hdr *)msg->buf; - - hdr->flags &= ~IMSGF_HASFD; - if (msg->fd != -1) - hdr->flags |= IMSGF_HASFD; - - hdr->len = (u_int16_t)msg->wpos; - - ibuf_close(&ibuf->w, msg); -} - -void -imsg_free(struct imsg *imsg) -{ - free(imsg->data); -} - -int -imsg_get_fd(struct imsgbuf *ibuf) -{ - int fd; - struct imsg_fd *ifd; - - if ((ifd = TAILQ_FIRST(&ibuf->fds)) == NULL) - return (-1); - - fd = ifd->fd; - TAILQ_REMOVE(&ibuf->fds, ifd, entry); - free(ifd); - - return (fd); -} - -int -imsg_flush(struct imsgbuf *ibuf) -{ - while (ibuf->w.queued) - if (msgbuf_write(&ibuf->w) < 0) - return (-1); - return (0); -} - -void -imsg_clear(struct imsgbuf *ibuf) -{ - int fd; - - msgbuf_clear(&ibuf->w); - while ((fd = imsg_get_fd(ibuf)) != -1) - close(fd); -} diff --git a/glougloud/external/imsg.h b/glougloud/external/imsg.h deleted file mode 100644 index 25cc2c4..0000000 --- a/glougloud/external/imsg.h +++ /dev/null @@ -1,118 +0,0 @@ -/* $OpenBSD: imsg.h,v 1.2 2010/06/23 07:53:55 nicm Exp $ */ - -/* - * Copyright (c) 2006, 2007 Pierre-Yves Ritschard - * Copyright (c) 2006, 2007, 2008 Reyk Floeter - * Copyright (c) 2003, 2004 Henning Brauer - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _IMSG_H_ -#define _IMSG_H_ - -/* compat hacks added by laurent */ -#if !defined(__OpenBSD__) -#define IOV_MAX 1024 -#define getdtablecount(x) 3 -#endif - -#define IBUF_READ_SIZE 65535 -#define IMSG_HEADER_SIZE sizeof(struct imsg_hdr) -#define MAX_IMSGSIZE 16384 - -struct ibuf { - TAILQ_ENTRY(ibuf) entry; - u_char *buf; - size_t size; - size_t max; - size_t wpos; - size_t rpos; - int fd; -}; - -struct msgbuf { - TAILQ_HEAD(, ibuf) bufs; - u_int32_t queued; - int fd; -}; - -struct ibuf_read { - u_char buf[IBUF_READ_SIZE]; - u_char *rptr; - size_t wpos; -}; - -struct imsg_fd { - TAILQ_ENTRY(imsg_fd) entry; - int fd; -}; - -struct imsgbuf { - TAILQ_HEAD(, imsg_fd) fds; - struct ibuf_read r; - struct msgbuf w; - int fd; - pid_t pid; -}; - -#define IMSGF_HASFD 1 - -struct imsg_hdr { - u_int32_t type; - u_int16_t len; - u_int16_t flags; - u_int32_t peerid; - u_int32_t pid; -}; - -struct imsg { - struct imsg_hdr hdr; - int fd; - void *data; -}; - - -/* buffer.c */ -struct ibuf *ibuf_open(size_t); -struct ibuf *ibuf_dynamic(size_t, size_t); -int ibuf_add(struct ibuf *, const void *, size_t); -void *ibuf_reserve(struct ibuf *, size_t); -void *ibuf_seek(struct ibuf *, size_t, size_t); -size_t ibuf_size(struct ibuf *); -size_t ibuf_left(struct ibuf *); -void ibuf_close(struct msgbuf *, struct ibuf *); -int ibuf_write(struct msgbuf *); -void ibuf_free(struct ibuf *); -void msgbuf_init(struct msgbuf *); -void msgbuf_clear(struct msgbuf *); -int msgbuf_write(struct msgbuf *); -void msgbuf_drain(struct msgbuf *, size_t); - -/* imsg.c */ -void imsg_init(struct imsgbuf *, int); -ssize_t imsg_read(struct imsgbuf *); -ssize_t imsg_get(struct imsgbuf *, struct imsg *); -int imsg_compose(struct imsgbuf *, u_int32_t, u_int32_t, pid_t, - int, void *, u_int16_t); -int imsg_composev(struct imsgbuf *, u_int32_t, u_int32_t, pid_t, - int, const struct iovec *, int); -struct ibuf *imsg_create(struct imsgbuf *, u_int32_t, u_int32_t, pid_t, - u_int16_t); -int imsg_add(struct ibuf *, void *, u_int16_t); -void imsg_close(struct imsgbuf *, struct ibuf *); -void imsg_free(struct imsg *); -int imsg_flush(struct imsgbuf *); -void imsg_clear(struct imsgbuf *); - -#endif diff --git a/glougloud/external/imsgev.c b/glougloud/external/imsgev.c deleted file mode 100644 index 6b92d79..0000000 --- a/glougloud/external/imsgev.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (c) 2009 Eric Faurot - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "imsgev.h" - -void imsgev_add(struct imsgev *); -void imsgev_dispatch(int, short, void *); -void imsgev_disconnect(struct imsgev *, int); - -void -imsgev_init(struct imsgev *iev, int fd, void *data, - void (*callback)(struct imsgev *, int, struct imsg *), - void (*needfd)(struct imsgev *)) -{ - imsg_init(&iev->ibuf, fd); - iev->terminate = 0; - - iev->data = data; - iev->handler = imsgev_dispatch; - iev->callback = callback; - iev->needfd = needfd; - - iev->events = EV_READ; - event_set(&iev->ev, iev->ibuf.fd, iev->events, iev->handler, iev); - event_add(&iev->ev, NULL); -} - -int -imsgev_compose(struct imsgev *iev, u_int16_t type, u_int32_t peerid, - uint32_t pid, int fd, void *data, u_int16_t datalen) -{ - int r; - - r = imsg_compose(&iev->ibuf, type, peerid, pid, fd, data, datalen); - if (r != -1) - imsgev_add(iev); - - return (r); -} - -void -imsgev_close(struct imsgev *iev) -{ - iev->terminate = 1; - imsgev_add(iev); -} - -void -imsgev_clear(struct imsgev *iev) -{ - event_del(&iev->ev); - msgbuf_clear(&iev->ibuf.w); - close(iev->ibuf.fd); -} - -void -imsgev_add(struct imsgev *iev) -{ - short events = 0; - - if (!iev->terminate) - events = EV_READ; - if (iev->ibuf.w.queued || iev->terminate) - events |= EV_WRITE; - - /* optimization: skip event_{del/set/add} if already set */ - if (events == iev->events) - return; - - iev->events = events; - event_del(&iev->ev); - event_set(&iev->ev, iev->ibuf.fd, iev->events, iev->handler, iev); - event_add(&iev->ev, NULL); -} - -void -imsgev_dispatch(int fd, short ev, void *humppa) -{ - struct imsgev *iev = humppa; - struct imsgbuf *ibuf = &iev->ibuf; - struct imsg imsg; - ssize_t n; - - iev->events = 0; - - if (ev & EV_READ) { - if ((n = imsg_read(ibuf)) == -1) { - /* if we don't have enough fds, free one up and retry */ - if (errno == EAGAIN) { - iev->needfd(iev); - n = imsg_read(ibuf); - } - - if (n == -1) { - imsgev_disconnect(iev, IMSGEV_EREAD); - return; - } - } - if (n == 0) { - /* - * Connection is closed for reading, and we assume - * it is also closed for writing, so we error out - * if write data is pending. - */ - imsgev_disconnect(iev, - (iev->ibuf.w.queued) ? IMSGEV_EWRITE : IMSGEV_DONE); - return; - } - } - - if (ev & EV_WRITE) { - /* - * We wanted to write data out but the connection is either - * closed, or some error occured. Both case are not recoverable - * from the imsg perspective, so we treat it as a WRITE error. - */ - if ((n = msgbuf_write(&ibuf->w)) != 1) { - imsgev_disconnect(iev, IMSGEV_EWRITE); - return; - } - } - - while (iev->terminate == 0) { - if ((n = imsg_get(ibuf, &imsg)) == -1) { - imsgev_disconnect(iev, IMSGEV_EIMSG); - return; - } - if (n == 0) - break; - iev->callback(iev, IMSGEV_IMSG, &imsg); - imsg_free(&imsg); - } - - if (iev->terminate && iev->ibuf.w.queued == 0) { - imsgev_disconnect(iev, IMSGEV_DONE); - return; - } - - imsgev_add(iev); -} - -void -imsgev_disconnect(struct imsgev *iev, int code) -{ - iev->callback(iev, code, NULL); -} diff --git a/glougloud/external/imsgev.h b/glougloud/external/imsgev.h deleted file mode 100644 index a0d0947..0000000 --- a/glougloud/external/imsgev.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2009 Eric Faurot - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef __IMSGEV_H__ -#define __IMSGEV_H__ - -#include -#include "imsg.h" - -#define IMSG_LEN(m) ((m)->hdr.len - IMSG_HEADER_SIZE) - -struct imsgev { - struct imsgbuf ibuf; - void (*handler)(int, short, void *); - struct event ev; - void *data; - short events; - int terminate; - void (*callback)(struct imsgev *, int, struct imsg *); - void (*needfd)(struct imsgev *); -}; - -#define IMSGEV_IMSG 0 -#define IMSGEV_DONE 1 -#define IMSGEV_EREAD 2 -#define IMSGEV_EWRITE 3 -#define IMSGEV_EIMSG 4 - -void imsgev_init(struct imsgev *, int, void *, void (*)(struct imsgev *, - int, struct imsg *), void (*)(struct imsgev *)); -int imsgev_compose(struct imsgev *, u_int16_t, u_int32_t, u_int32_t, int, - void *, u_int16_t); -void imsgev_close(struct imsgev *); -void imsgev_clear(struct imsgev *); - -#endif /* __IMSGEV_H__ */ diff --git a/glougloud/external/queue.h b/glougloud/external/queue.h deleted file mode 100644 index 622301d..0000000 --- a/glougloud/external/queue.h +++ /dev/null @@ -1,568 +0,0 @@ -/* $OpenBSD: queue.h,v 1.36 2012/04/11 13:29:14 naddy Exp $ */ -/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */ - -/* - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)queue.h 8.5 (Berkeley) 8/20/94 - */ - -#ifndef _SYS_QUEUE_H_ -#define _SYS_QUEUE_H_ - -/* - * This file defines five types of data structures: singly-linked lists, - * lists, simple queues, tail queues, and circular queues. - * - * - * A singly-linked list is headed by a single forward pointer. The elements - * are singly linked for minimum space and pointer manipulation overhead at - * the expense of O(n) removal for arbitrary elements. New elements can be - * added to the list after an existing element or at the head of the list. - * Elements being removed from the head of the list should use the explicit - * macro for this purpose for optimum efficiency. A singly-linked list may - * only be traversed in the forward direction. Singly-linked lists are ideal - * for applications with large datasets and few or no removals or for - * implementing a LIFO queue. - * - * A list is headed by a single forward pointer (or an array of forward - * pointers for a hash table header). The elements are doubly linked - * so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before - * or after an existing element or at the head of the list. A list - * may only be traversed in the forward direction. - * - * A simple queue is headed by a pair of pointers, one the head of the - * list and the other to the tail of the list. The elements are singly - * linked to save space, so elements can only be removed from the - * head of the list. New elements can be added to the list before or after - * an existing element, at the head of the list, or at the end of the - * list. A simple queue may only be traversed in the forward direction. - * - * A tail queue is headed by a pair of pointers, one to the head of the - * list and the other to the tail of the list. The elements are doubly - * linked so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before or - * after an existing element, at the head of the list, or at the end of - * the list. A tail queue may be traversed in either direction. - * - * A circle queue is headed by a pair of pointers, one to the head of the - * list and the other to the tail of the list. The elements are doubly - * linked so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before or after - * an existing element, at the head of the list, or at the end of the list. - * A circle queue may be traversed in either direction, but has a more - * complex end of list detection. - * - * For details on the use of these macros, see the queue(3) manual page. - */ - -#if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC)) -#define _Q_INVALIDATE(a) (a) = ((void *)-1) -#else -#define _Q_INVALIDATE(a) -#endif - -/* - * Singly-linked List definitions. - */ -#define SLIST_HEAD(name, type) \ -struct name { \ - struct type *slh_first; /* first element */ \ -} - -#define SLIST_HEAD_INITIALIZER(head) \ - { NULL } - -#define SLIST_ENTRY(type) \ -struct { \ - struct type *sle_next; /* next element */ \ -} - -/* - * Singly-linked List access methods. - */ -#define SLIST_FIRST(head) ((head)->slh_first) -#define SLIST_END(head) NULL -#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head)) -#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) - -#define SLIST_FOREACH(var, head, field) \ - for((var) = SLIST_FIRST(head); \ - (var) != SLIST_END(head); \ - (var) = SLIST_NEXT(var, field)) - -#define SLIST_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = SLIST_FIRST(head); \ - (var) && ((tvar) = SLIST_NEXT(var, field), 1); \ - (var) = (tvar)) - -/* - * Singly-linked List functions. - */ -#define SLIST_INIT(head) { \ - SLIST_FIRST(head) = SLIST_END(head); \ -} - -#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ - (elm)->field.sle_next = (slistelm)->field.sle_next; \ - (slistelm)->field.sle_next = (elm); \ -} while (0) - -#define SLIST_INSERT_HEAD(head, elm, field) do { \ - (elm)->field.sle_next = (head)->slh_first; \ - (head)->slh_first = (elm); \ -} while (0) - -#define SLIST_REMOVE_AFTER(elm, field) do { \ - (elm)->field.sle_next = (elm)->field.sle_next->field.sle_next; \ -} while (0) - -#define SLIST_REMOVE_HEAD(head, field) do { \ - (head)->slh_first = (head)->slh_first->field.sle_next; \ -} while (0) - -#define SLIST_REMOVE(head, elm, type, field) do { \ - if ((head)->slh_first == (elm)) { \ - SLIST_REMOVE_HEAD((head), field); \ - } else { \ - struct type *curelm = (head)->slh_first; \ - \ - while (curelm->field.sle_next != (elm)) \ - curelm = curelm->field.sle_next; \ - curelm->field.sle_next = \ - curelm->field.sle_next->field.sle_next; \ - _Q_INVALIDATE((elm)->field.sle_next); \ - } \ -} while (0) - -/* - * List definitions. - */ -#define LIST_HEAD(name, type) \ -struct name { \ - struct type *lh_first; /* first element */ \ -} - -#define LIST_HEAD_INITIALIZER(head) \ - { NULL } - -#define LIST_ENTRY(type) \ -struct { \ - struct type *le_next; /* next element */ \ - struct type **le_prev; /* address of previous next element */ \ -} - -/* - * List access methods - */ -#define LIST_FIRST(head) ((head)->lh_first) -#define LIST_END(head) NULL -#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head)) -#define LIST_NEXT(elm, field) ((elm)->field.le_next) - -#define LIST_FOREACH(var, head, field) \ - for((var) = LIST_FIRST(head); \ - (var)!= LIST_END(head); \ - (var) = LIST_NEXT(var, field)) - -#define LIST_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = LIST_FIRST(head); \ - (var) && ((tvar) = LIST_NEXT(var, field), 1); \ - (var) = (tvar)) - -/* - * List functions. - */ -#define LIST_INIT(head) do { \ - LIST_FIRST(head) = LIST_END(head); \ -} while (0) - -#define LIST_INSERT_AFTER(listelm, elm, field) do { \ - if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \ - (listelm)->field.le_next->field.le_prev = \ - &(elm)->field.le_next; \ - (listelm)->field.le_next = (elm); \ - (elm)->field.le_prev = &(listelm)->field.le_next; \ -} while (0) - -#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ - (elm)->field.le_prev = (listelm)->field.le_prev; \ - (elm)->field.le_next = (listelm); \ - *(listelm)->field.le_prev = (elm); \ - (listelm)->field.le_prev = &(elm)->field.le_next; \ -} while (0) - -#define LIST_INSERT_HEAD(head, elm, field) do { \ - if (((elm)->field.le_next = (head)->lh_first) != NULL) \ - (head)->lh_first->field.le_prev = &(elm)->field.le_next;\ - (head)->lh_first = (elm); \ - (elm)->field.le_prev = &(head)->lh_first; \ -} while (0) - -#define LIST_REMOVE(elm, field) do { \ - if ((elm)->field.le_next != NULL) \ - (elm)->field.le_next->field.le_prev = \ - (elm)->field.le_prev; \ - *(elm)->field.le_prev = (elm)->field.le_next; \ - _Q_INVALIDATE((elm)->field.le_prev); \ - _Q_INVALIDATE((elm)->field.le_next); \ -} while (0) - -#define LIST_REPLACE(elm, elm2, field) do { \ - if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \ - (elm2)->field.le_next->field.le_prev = \ - &(elm2)->field.le_next; \ - (elm2)->field.le_prev = (elm)->field.le_prev; \ - *(elm2)->field.le_prev = (elm2); \ - _Q_INVALIDATE((elm)->field.le_prev); \ - _Q_INVALIDATE((elm)->field.le_next); \ -} while (0) - -/* - * Simple queue definitions. - */ -#define SIMPLEQ_HEAD(name, type) \ -struct name { \ - struct type *sqh_first; /* first element */ \ - struct type **sqh_last; /* addr of last next element */ \ -} - -#define SIMPLEQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).sqh_first } - -#define SIMPLEQ_ENTRY(type) \ -struct { \ - struct type *sqe_next; /* next element */ \ -} - -/* - * Simple queue access methods. - */ -#define SIMPLEQ_FIRST(head) ((head)->sqh_first) -#define SIMPLEQ_END(head) NULL -#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head)) -#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next) - -#define SIMPLEQ_FOREACH(var, head, field) \ - for((var) = SIMPLEQ_FIRST(head); \ - (var) != SIMPLEQ_END(head); \ - (var) = SIMPLEQ_NEXT(var, field)) - -#define SIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = SIMPLEQ_FIRST(head); \ - (var) && ((tvar) = SIMPLEQ_NEXT(var, field), 1); \ - (var) = (tvar)) - -/* - * Simple queue functions. - */ -#define SIMPLEQ_INIT(head) do { \ - (head)->sqh_first = NULL; \ - (head)->sqh_last = &(head)->sqh_first; \ -} while (0) - -#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \ - if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \ - (head)->sqh_last = &(elm)->field.sqe_next; \ - (head)->sqh_first = (elm); \ -} while (0) - -#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \ - (elm)->field.sqe_next = NULL; \ - *(head)->sqh_last = (elm); \ - (head)->sqh_last = &(elm)->field.sqe_next; \ -} while (0) - -#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ - if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\ - (head)->sqh_last = &(elm)->field.sqe_next; \ - (listelm)->field.sqe_next = (elm); \ -} while (0) - -#define SIMPLEQ_REMOVE_HEAD(head, field) do { \ - if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \ - (head)->sqh_last = &(head)->sqh_first; \ -} while (0) - -#define SIMPLEQ_REMOVE_AFTER(head, elm, field) do { \ - if (((elm)->field.sqe_next = (elm)->field.sqe_next->field.sqe_next) \ - == NULL) \ - (head)->sqh_last = &(elm)->field.sqe_next; \ -} while (0) - -/* - * Tail queue definitions. - */ -#define TAILQ_HEAD(name, type) \ -struct name { \ - struct type *tqh_first; /* first element */ \ - struct type **tqh_last; /* addr of last next element */ \ -} - -#define TAILQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).tqh_first } - -#define TAILQ_ENTRY(type) \ -struct { \ - struct type *tqe_next; /* next element */ \ - struct type **tqe_prev; /* address of previous next element */ \ -} - -/* - * tail queue access methods - */ -#define TAILQ_FIRST(head) ((head)->tqh_first) -#define TAILQ_END(head) NULL -#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) -#define TAILQ_LAST(head, headname) \ - (*(((struct headname *)((head)->tqh_last))->tqh_last)) -/* XXX */ -#define TAILQ_PREV(elm, headname, field) \ - (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) -#define TAILQ_EMPTY(head) \ - (TAILQ_FIRST(head) == TAILQ_END(head)) - -#define TAILQ_FOREACH(var, head, field) \ - for((var) = TAILQ_FIRST(head); \ - (var) != TAILQ_END(head); \ - (var) = TAILQ_NEXT(var, field)) - -#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = TAILQ_FIRST(head); \ - (var) != TAILQ_END(head) && \ - ((tvar) = TAILQ_NEXT(var, field), 1); \ - (var) = (tvar)) - - -#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ - for((var) = TAILQ_LAST(head, headname); \ - (var) != TAILQ_END(head); \ - (var) = TAILQ_PREV(var, headname, field)) - -#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \ - for ((var) = TAILQ_LAST(head, headname); \ - (var) != TAILQ_END(head) && \ - ((tvar) = TAILQ_PREV(var, headname, field), 1); \ - (var) = (tvar)) - -/* - * Tail queue functions. - */ -#define TAILQ_INIT(head) do { \ - (head)->tqh_first = NULL; \ - (head)->tqh_last = &(head)->tqh_first; \ -} while (0) - -#define TAILQ_INSERT_HEAD(head, elm, field) do { \ - if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ - (head)->tqh_first->field.tqe_prev = \ - &(elm)->field.tqe_next; \ - else \ - (head)->tqh_last = &(elm)->field.tqe_next; \ - (head)->tqh_first = (elm); \ - (elm)->field.tqe_prev = &(head)->tqh_first; \ -} while (0) - -#define TAILQ_INSERT_TAIL(head, elm, field) do { \ - (elm)->field.tqe_next = NULL; \ - (elm)->field.tqe_prev = (head)->tqh_last; \ - *(head)->tqh_last = (elm); \ - (head)->tqh_last = &(elm)->field.tqe_next; \ -} while (0) - -#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ - if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\ - (elm)->field.tqe_next->field.tqe_prev = \ - &(elm)->field.tqe_next; \ - else \ - (head)->tqh_last = &(elm)->field.tqe_next; \ - (listelm)->field.tqe_next = (elm); \ - (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \ -} while (0) - -#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ - (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ - (elm)->field.tqe_next = (listelm); \ - *(listelm)->field.tqe_prev = (elm); \ - (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ -} while (0) - -#define TAILQ_REMOVE(head, elm, field) do { \ - if (((elm)->field.tqe_next) != NULL) \ - (elm)->field.tqe_next->field.tqe_prev = \ - (elm)->field.tqe_prev; \ - else \ - (head)->tqh_last = (elm)->field.tqe_prev; \ - *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ - _Q_INVALIDATE((elm)->field.tqe_prev); \ - _Q_INVALIDATE((elm)->field.tqe_next); \ -} while (0) - -#define TAILQ_REPLACE(head, elm, elm2, field) do { \ - if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \ - (elm2)->field.tqe_next->field.tqe_prev = \ - &(elm2)->field.tqe_next; \ - else \ - (head)->tqh_last = &(elm2)->field.tqe_next; \ - (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \ - *(elm2)->field.tqe_prev = (elm2); \ - _Q_INVALIDATE((elm)->field.tqe_prev); \ - _Q_INVALIDATE((elm)->field.tqe_next); \ -} while (0) - -/* - * Circular queue definitions. - */ -#define CIRCLEQ_HEAD(name, type) \ -struct name { \ - struct type *cqh_first; /* first element */ \ - struct type *cqh_last; /* last element */ \ -} - -#define CIRCLEQ_HEAD_INITIALIZER(head) \ - { CIRCLEQ_END(&head), CIRCLEQ_END(&head) } - -#define CIRCLEQ_ENTRY(type) \ -struct { \ - struct type *cqe_next; /* next element */ \ - struct type *cqe_prev; /* previous element */ \ -} - -/* - * Circular queue access methods - */ -#define CIRCLEQ_FIRST(head) ((head)->cqh_first) -#define CIRCLEQ_LAST(head) ((head)->cqh_last) -#define CIRCLEQ_END(head) ((void *)(head)) -#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next) -#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev) -#define CIRCLEQ_EMPTY(head) \ - (CIRCLEQ_FIRST(head) == CIRCLEQ_END(head)) - -#define CIRCLEQ_FOREACH(var, head, field) \ - for((var) = CIRCLEQ_FIRST(head); \ - (var) != CIRCLEQ_END(head); \ - (var) = CIRCLEQ_NEXT(var, field)) - -#define CIRCLEQ_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = CIRCLEQ_FIRST(head); \ - (var) != CIRCLEQ_END(head) && \ - ((tvar) = CIRCLEQ_NEXT(var, field), 1); \ - (var) = (tvar)) - -#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \ - for((var) = CIRCLEQ_LAST(head); \ - (var) != CIRCLEQ_END(head); \ - (var) = CIRCLEQ_PREV(var, field)) - -#define CIRCLEQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \ - for ((var) = CIRCLEQ_LAST(head, headname); \ - (var) != CIRCLEQ_END(head) && \ - ((tvar) = CIRCLEQ_PREV(var, headname, field), 1); \ - (var) = (tvar)) - -/* - * Circular queue functions. - */ -#define CIRCLEQ_INIT(head) do { \ - (head)->cqh_first = CIRCLEQ_END(head); \ - (head)->cqh_last = CIRCLEQ_END(head); \ -} while (0) - -#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ - (elm)->field.cqe_next = (listelm)->field.cqe_next; \ - (elm)->field.cqe_prev = (listelm); \ - if ((listelm)->field.cqe_next == CIRCLEQ_END(head)) \ - (head)->cqh_last = (elm); \ - else \ - (listelm)->field.cqe_next->field.cqe_prev = (elm); \ - (listelm)->field.cqe_next = (elm); \ -} while (0) - -#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \ - (elm)->field.cqe_next = (listelm); \ - (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \ - if ((listelm)->field.cqe_prev == CIRCLEQ_END(head)) \ - (head)->cqh_first = (elm); \ - else \ - (listelm)->field.cqe_prev->field.cqe_next = (elm); \ - (listelm)->field.cqe_prev = (elm); \ -} while (0) - -#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \ - (elm)->field.cqe_next = (head)->cqh_first; \ - (elm)->field.cqe_prev = CIRCLEQ_END(head); \ - if ((head)->cqh_last == CIRCLEQ_END(head)) \ - (head)->cqh_last = (elm); \ - else \ - (head)->cqh_first->field.cqe_prev = (elm); \ - (head)->cqh_first = (elm); \ -} while (0) - -#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \ - (elm)->field.cqe_next = CIRCLEQ_END(head); \ - (elm)->field.cqe_prev = (head)->cqh_last; \ - if ((head)->cqh_first == CIRCLEQ_END(head)) \ - (head)->cqh_first = (elm); \ - else \ - (head)->cqh_last->field.cqe_next = (elm); \ - (head)->cqh_last = (elm); \ -} while (0) - -#define CIRCLEQ_REMOVE(head, elm, field) do { \ - if ((elm)->field.cqe_next == CIRCLEQ_END(head)) \ - (head)->cqh_last = (elm)->field.cqe_prev; \ - else \ - (elm)->field.cqe_next->field.cqe_prev = \ - (elm)->field.cqe_prev; \ - if ((elm)->field.cqe_prev == CIRCLEQ_END(head)) \ - (head)->cqh_first = (elm)->field.cqe_next; \ - else \ - (elm)->field.cqe_prev->field.cqe_next = \ - (elm)->field.cqe_next; \ - _Q_INVALIDATE((elm)->field.cqe_prev); \ - _Q_INVALIDATE((elm)->field.cqe_next); \ -} while (0) - -#define CIRCLEQ_REPLACE(head, elm, elm2, field) do { \ - if (((elm2)->field.cqe_next = (elm)->field.cqe_next) == \ - CIRCLEQ_END(head)) \ - (head).cqh_last = (elm2); \ - else \ - (elm2)->field.cqe_next->field.cqe_prev = (elm2); \ - if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) == \ - CIRCLEQ_END(head)) \ - (head).cqh_first = (elm2); \ - else \ - (elm2)->field.cqe_prev->field.cqe_next = (elm2); \ - _Q_INVALIDATE((elm)->field.cqe_prev); \ - _Q_INVALIDATE((elm)->field.cqe_next); \ -} while (0) - -#endif /* !_SYS_QUEUE_H_ */ diff --git a/glougloud/glougloud.c b/glougloud/glougloud.c deleted file mode 100644 index 49a1608..0000000 --- a/glougloud/glougloud.c +++ /dev/null @@ -1,487 +0,0 @@ -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "glougloud.h" -#include "external/imsgev.h" -#if defined(__OpenBSD__) -#include "pcap-int.h" -#endif - -struct server_proc { - pid_t pid; - int fd[2]; - struct imsgev iev; -}; -struct user_proc { - pid_t pid; - int fd[2]; - struct imsgev iev; -}; -enum user_status { - USER_REQUESTED, - USER_ACCEPTED -}; -struct user { - LIST_ENTRY(user) entry; - struct sockaddr_in addr; - enum user_status status; -}; - -// XXX CONF -#define PCAP_INTERFACE "lo" -#define PCAP_SNAPLEN 100 -#define PCAP_FILTER "not port 4430 and not port 53" - -static void imsgev_server(struct imsgev *, int, struct imsg *); -static void imsgev_user(struct imsgev *, int, struct imsg *); -static void imsgev_server_needfd(struct imsgev *); -static void imsgev_user_needfd(struct imsgev *); - -struct server_proc *srv_proc; -struct user_proc *usr_proc; -LIST_HEAD(, user) usr_list; -int net_socket; - -#if defined(__OPENBSD__) -void __dead -#else -void -#endif -usage(void) -{ - extern char *__progname; - - fprintf(stderr, "usage: %s [-vi]", - __progname); - exit(1); -} - -static void -sig_handler(int sig, short why, void *data) -{ - log_info("got signal %d", sig); - if (sig == SIGINT || sig == SIGTERM) - event_loopexit(NULL); -} - -/* - * reimplement pcap_open_live with more restrictions on the bpf fd : - * - open device read only - * - lock the fd - * based on OpenBSD tcpdump, privsep_pcap.c v1.16 - */ - -static pcap_t * -my_pcap_open_live(const char *dev, int slen, int promisc, int to_ms, - char *ebuf, u_int dlt, u_int dirfilt) -{ -#if defined(__OpenBSD__) - struct bpf_version bv; - u_int v; - pcap_t *p; - char bpf[sizeof "/dev/bpf0000000000"]; - int fd, n = 0; - struct ifreq ifr; - - p = xmalloc(sizeof(*p)); - bzero(p, sizeof(*p)); - - /* priv part */ - - do { - snprintf(bpf, sizeof(bpf), "/dev/bpf%d", n++); - fd = open(bpf, O_RDONLY); - } while (fd < 0 && errno == EBUSY); - if (fd < 0) - return NULL; - - v = 32768; /* XXX this should be a user-accessible hook */ - ioctl(fd, BIOCSBLEN, &v); - - strlcpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)); - if (ioctl(fd, BIOCSETIF, &ifr) < 0) - return NULL; - - if (dlt != (u_int) -1 && ioctl(fd, BIOCSDLT, &dlt)) - return NULL; - - if (promisc) - /* this is allowed to fail */ - ioctl(fd, BIOCPROMISC, NULL); - if (ioctl(fd, BIOCSDIRFILT, &dirfilt) < 0) - return NULL; - - /* lock the descriptor */ - if (ioctl(fd, BIOCLOCK, NULL) < 0) - return NULL; - - /* end of priv part */ - - /* fd is locked, can only use 'safe' ioctls */ - if (ioctl(fd, BIOCVERSION, &bv) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCVERSION: %s", - pcap_strerror(errno)); - return NULL; - } - - if (bv.bv_major != BPF_MAJOR_VERSION || - bv.bv_minor < BPF_MINOR_VERSION) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "kernel bpf filter out of date"); - return NULL; - } - - p->fd = fd; - p->snapshot = slen; - - /* Get the data link layer type. */ - if (ioctl(fd, BIOCGDLT, &v) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCGDLT: %s", - pcap_strerror(errno)); - return NULL; - } -#if _BSDI_VERSION - 0 >= 199510 - /* The SLIP and PPP link layer header changed in BSD/OS 2.1 */ - switch (v) { - - case DLT_SLIP: - v = DLT_SLIP_BSDOS; - break; - - case DLT_PPP: - v = DLT_PPP_BSDOS; - break; - } -#endif - p->linktype = v; - - /* XXX hack from tcpdump */ - if (p->linktype == DLT_PFLOG && p->snapshot < 160) - p->snapshot = 160; - - /* set timeout */ - if (to_ms != 0) { - struct timeval to; - to.tv_sec = to_ms / 1000; - to.tv_usec = (to_ms * 1000) % 1000000; - if (ioctl(p->fd, BIOCSRTIMEOUT, &to) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCSRTIMEOUT: %s", - pcap_strerror(errno)); - return NULL; - } - } - - if (ioctl(fd, BIOCGBLEN, &v) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCGBLEN: %s", - pcap_strerror(errno)); - return NULL; - } - p->bufsize = v; - p->buffer = (u_char *)malloc(p->bufsize); - if (p->buffer == NULL) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", - pcap_strerror(errno)); - return NULL; - } - return p; -#else /* defined(__OpenBSD__) */ - return pcap_open_live(dev, slen, promisc, to_ms, ebuf); -#endif -} - -int -main(int argc, char **argv) -{ - struct sockaddr_in sock_addr; - struct event ev_sigint, ev_sigterm, ev_sigchld, ev_sighup; - char errbuf[PCAP_ERRBUF_SIZE]; - struct bpf_program bprog; - pcap_t *pcap; - int loglevel = 0, logpinvalid = 0; - int op; - int sock_on = 1; - - if (geteuid() != 0) - errx(1, "need root privileges"); - - while ((op = getopt(argc, argv, "hvi")) != -1) { - switch (op) { - case 'h': - usage(); - /* NOTREACHED */ - case 'v': - loglevel++; - break; - case 'i': - logpinvalid = 1; - break; - default: - usage(); - /* NOTREACHED */ - } - } - - log_init(loglevel, logpinvalid); - event_init(); - - net_socket = socket(AF_INET, SOCK_DGRAM, 0); - if (net_socket < 0) - fatal("server: socket failed"); - setsockopt(net_socket, SOL_SOCKET, SO_REUSEADDR, - &sock_on, sizeof(sock_on)); - memset(&sock_addr, 0, sizeof(sock_addr)); - sock_addr.sin_family = AF_INET; - sock_addr.sin_addr.s_addr = htonl(INADDR_ANY); - sock_addr.sin_port = htons(4430); - if (bind(net_socket, (struct sockaddr *)&sock_addr, - sizeof(sock_addr)) != 0) - fatal("server: socket bind failed, %s", strerror(errno)); - fd_nonblock(net_socket); - - srv_proc = xmalloc(sizeof(struct server_proc)); - socketpair_prepare(srv_proc->fd); - srv_proc->pid = server_init(srv_proc->fd); - close(srv_proc->fd[1]); - imsgev_init(&srv_proc->iev, srv_proc->fd[0], NULL, imsgev_server, imsgev_server_needfd); - - pcap = my_pcap_open_live(PCAP_INTERFACE, PCAP_SNAPLEN, 1, PCAP_TO, errbuf, -1, 0); - if (pcap == NULL) - fatal("capture: pcap_open_live failed on interface %s\n" - "with snaplen %d : %s", - PCAP_INTERFACE, PCAP_SNAPLEN, errbuf); - if (pcap_compile(pcap, &bprog, PCAP_FILTER, 0, 0) < 0) - fatal("capture: pcap_compile failed with filter %s : %s", - PCAP_FILTER, pcap_geterr(pcap)); - if (pcap_setfilter(pcap, &bprog) < 0) - fatal("capture: pcap_setfilter failed : %s", - pcap_geterr(pcap)); - - usr_proc = xmalloc(sizeof(struct user_proc)); - socketpair_prepare(usr_proc->fd); - usr_proc->pid = user_init(usr_proc->fd, pcap); - close(usr_proc->fd[1]); - imsgev_init(&usr_proc->iev, usr_proc->fd[0], NULL, imsgev_user, imsgev_user_needfd); - - signal_set(&ev_sigint, SIGINT, sig_handler, NULL); - signal_set(&ev_sigterm, SIGTERM, sig_handler, NULL); - signal_set(&ev_sigchld, SIGCHLD, sig_handler, NULL); - signal_set(&ev_sighup, SIGHUP, sig_handler, NULL); - signal_add(&ev_sigint, NULL); - signal_add(&ev_sigterm, NULL); - signal_add(&ev_sigchld, NULL); - signal_add(&ev_sighup, NULL); - signal(SIGPIPE, SIG_IGN); - - log_info("entering event loop"); - event_dispatch(); - - log_info("exiting"); - exit(0); -} - -static struct user * -finduser(struct sockaddr_in *remote) { - struct user *usr; - struct sockaddr_in *u; - - LIST_FOREACH(usr, &usr_list, entry) { - u = &usr->addr; - if (u->sin_addr.s_addr == remote->sin_addr.s_addr && - u->sin_port == remote->sin_port) - return usr; - } - return NULL; -} - -static void -srvconn(struct imsgev *iev, struct imsg *imsg) -{ - struct imsg_srvconn *req; - struct imsg_srvconn res; - struct imsg_usrconn req2; - struct user *usr; - - req = imsg->data; - - if (req->deco) { - log_tmp("srvconn deco"); - usr = finduser(&req->addr); - if (!usr) - fatal("trying to deco an inexistant user !"); - - addrcpy(&req2.addr, &usr->addr); - req2.deco = 1; - imsgev_compose(&usr_proc->iev, IMSG_USRCONN_REQ, 0, 0, -1, - &req2, sizeof(req2)); - - LIST_REMOVE(usr, entry); - free(usr); - - return; - } - - if (req->addr.sin_addr.s_addr == htonl(INADDR_LOOPBACK)) { - log_tmp("srvconn accepted"); - - usr = xmalloc(sizeof(struct user)); - addrcpy(&usr->addr, &req->addr); - usr->status = USER_REQUESTED; - LIST_INSERT_HEAD(&usr_list, usr, entry); - - addrcpy(&req2.addr, &req->addr); - req2.deco = 0; - imsgev_compose(&usr_proc->iev, IMSG_USRCONN_REQ, 0, 0, -1, - &req2, sizeof(req2)); - } - else - { - log_tmp("srvconn refused"); - res.ok = 0; - addrcpy(&res.addr, &req->addr); - imsgev_compose(iev, IMSG_SRVCONN_RES, 0, 0, -1, - &res, sizeof(res)); - } - -} - -static void -imsgev_server(struct imsgev *iev, int code, struct imsg *imsg) -{ - switch (code) { - case IMSGEV_IMSG: - log_debug("%s, got imsg %i on fd %i", - __func__, imsg->hdr.type, iev->ibuf.fd); - switch (imsg->hdr.type) { - case IMSG_SRVCONN_REQ: - srvconn(iev, imsg); - break; - default: - fatal("%s, unexpected imsg %d", - __func__, imsg->hdr.type); - } - break; - case IMSGEV_EREAD: - case IMSGEV_EWRITE: - case IMSGEV_EIMSG: - fatal("imsgev server read/write error"); - /* NOTREACHED */ - break; - case IMSGEV_DONE: - event_loopexit(NULL); - break; - } -} - -static void -usrconn(struct imsgev *iev, struct imsg *imsg) -{ - struct user *usr; - struct imsg_usrconn *res; - struct imsg_srvconn res2; - - res = imsg->data; - - usr = finduser(&res->addr); - if (!usr || usr->status != USER_REQUESTED) - fatal("received usrconn result that wasn't initiated !"); - usr->status = USER_ACCEPTED; - - addrcpy(&res2.addr, &res->addr); - res2.ok = 1; - imsgev_compose(&srv_proc->iev, IMSG_SRVCONN_RES, 0, 0, -1, - &res2, sizeof(res2)); -} - -/* XXX drop imsg when msgbuf->queued is too high ? */ -/* XXX review that func for correctness and security */ -static void -usrdns(struct imsgev *iev, struct imsg *imsg) -{ - struct imsg_usrdns_req *req; - struct imsg_usrdns_res res; - struct hostent *ent; - int len; - char *name; - extern int h_errno; - struct in_addr addr; - - req = imsg->data; - - res.addr.s_addr = req->addr.s_addr; - addr.s_addr = htonl(req->addr.s_addr); - ent = gethostbyaddr(&addr, sizeof(addr), AF_INET); - if (ent) { - len = strlen(ent->h_name); - if (len > DNSNAME_MAX) - name = ent->h_name - DNSNAME_MAX; /* keep right part */ - else - name = ent->h_name; - strncpy(res.name, name, sizeof(res.name)); - } else { - log_debug("usrdns failed for %x : %s", - addr, hstrerror(h_errno)); - res.name[0] = '\0'; - } - - imsgev_compose(&usr_proc->iev, IMSG_USRDNS_RES, 0, 0, -1, - &res, sizeof(res)); -} - -static void -imsgev_user(struct imsgev *iev, int code, struct imsg *imsg) -{ - switch (code) { - case IMSGEV_IMSG: - log_debug("%s, got imsg %i on fd %i", - __func__, imsg->hdr.type, iev->ibuf.fd); - switch (imsg->hdr.type) { - case IMSG_USRCONN_RES: - usrconn(iev, imsg); - break; - case IMSG_USRDNS_REQ: - usrdns(iev, imsg); - break; - default: - fatal("%s, unexpected imsg %d", - __func__, imsg->hdr.type); - } - break; - case IMSGEV_EREAD: - case IMSGEV_EWRITE: - case IMSGEV_EIMSG: - fatal("imsgev user read/write error"); - /* NOTREACHED */ - break; - case IMSGEV_DONE: - event_loopexit(NULL); - break; - } -} - -static void -imsgev_server_needfd(struct imsgev *iev) -{ - fatal("imsgev_server_needfd"); -} - -static void -imsgev_user_needfd(struct imsgev *iev) -{ - fatal("imsgev_user_needfd"); -} diff --git a/glougloud/glougloud.h b/glougloud/glougloud.h deleted file mode 100644 index c4f0a4a..0000000 --- a/glougloud/glougloud.h +++ /dev/null @@ -1,79 +0,0 @@ -#include - -#include - -#include -#include - -#include - -#include "external/queue.h" - -#if !defined(__OpenBSD__) -#define setproctitle(x) {} -#endif - -#define GLOUGLOUD_USER "_glougloud" -#define PCAP_COUNT 20 -#define PCAP_TO 300 - -/* ipc */ - -enum imsg_type { - IMSG_SRVCONN_REQ, - IMSG_SRVCONN_RES, - IMSG_USRCONN_REQ, - IMSG_USRCONN_RES, - IMSG_USRDNS_REQ, - IMSG_USRDNS_RES -}; - -/* XXX restore the _req _res structs, so that we have less bytes going on - * the pipe */ -struct imsg_srvconn { - struct sockaddr_in addr; - u_short ok; - u_short deco; -}; -struct imsg_usrconn { - struct sockaddr_in addr; - u_short ok; - u_short deco; -}; -struct imsg_usrdns_req { - struct in_addr addr; -}; -struct imsg_usrdns_res { - struct in_addr addr; - char name[DNSNAME_MAX]; -}; - -/* glougloud.c */ - -extern int net_socket; - -/* server.c */ - -int server_init(int *); - -/* user.c */ - -int user_init(int *, pcap_t *pcap); - -/* util.c */ - -void log_init(int, int); -void log_pinvalid(const char *, ...); -void log_tmp(const char *, ...); -void log_debug(const char *, ...); -void log_info(const char *, ...); -void log_warn(const char *, ...); -void fatal(const char *, ...); - -void *xmalloc(size_t); -void *xcalloc(size_t, size_t); -void fd_nonblock(int); -void droppriv(); -void addrcpy(struct sockaddr_in *, struct sockaddr_in *); -void socketpair_prepare(int *); - diff --git a/glougloud/server.c b/glougloud/server.c deleted file mode 100644 index 4fb0be6..0000000 --- a/glougloud/server.c +++ /dev/null @@ -1,238 +0,0 @@ -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "glougloud.h" -#include "external/imsgev.h" - -#define USER_TIMEOUT 300 -#define USERTIMER 10 - -struct server { - struct imsgev iev; - struct event ev; - - struct event usrtimer_ev; - struct timeval usrtimer_tv; - time_t time; -}; -enum user_status { - USER_REQUESTED, - USER_ACCEPTED, - USER_REFUSED -}; -struct user { - LIST_ENTRY(user) entry; - struct sockaddr_in addr; - enum user_status status; - time_t lastseen; -}; - -static void imsgev_main(struct imsgev *, int, struct imsg *); -static void imsgev_main_needfd(struct imsgev *); -static void receive(int, short, void *); -static void ev_usrtimer(int, short, void *); - -struct server *srv; -LIST_HEAD(, user) usr_list; - -static void -sig_handler(int sig, short why, void *data) -{ - log_info("server: got signal %d", sig); - if (sig == SIGINT || sig == SIGTERM) - event_loopexit(NULL); -} - -int -server_init(int fd[2]) -{ - struct event ev_sigint, ev_sigterm, ev_sigchld, ev_sighup; - int pid; - - pid = fork(); - if (pid < 0) - fatal("server fork"); - if (pid > 0) - return pid; - - setproctitle("server"); - event_init(); - close(fd[0]); - - signal_set(&ev_sigint, SIGINT, sig_handler, NULL); - signal_set(&ev_sigterm, SIGTERM, sig_handler, NULL); - signal_set(&ev_sigchld, SIGCHLD, sig_handler, NULL); - signal_set(&ev_sighup, SIGHUP, sig_handler, NULL); - signal_add(&ev_sigint, NULL); - signal_add(&ev_sigterm, NULL); - signal_add(&ev_sigchld, NULL); - signal_add(&ev_sighup, NULL); - signal(SIGPIPE, SIG_IGN); - - srv = xmalloc(sizeof(struct server)); - imsgev_init(&srv->iev, fd[1], NULL, imsgev_main, imsgev_main_needfd); - srv->time = time(NULL); - - event_set(&srv->ev, net_socket, EV_READ|EV_PERSIST, receive, NULL); - event_add(&srv->ev, NULL); - - srv->usrtimer_tv.tv_sec = USERTIMER; - srv->usrtimer_tv.tv_usec = 0; - evtimer_set(&srv->usrtimer_ev, ev_usrtimer, NULL); - if (event_add(&srv->usrtimer_ev, &srv->usrtimer_tv) == -1) - fatal("server: event_add usrtimr failed: %s", strerror(errno)); - - droppriv(); - - log_info("server: entering event loop"); - event_dispatch(); - - log_info("server: exiting"); - exit(0); -} - -static struct user * -finduser(struct sockaddr_in *remote) { - struct user *usr; - struct sockaddr_in *u; - - LIST_FOREACH(usr, &usr_list, entry) { - u = &usr->addr; - if (u->sin_addr.s_addr == remote->sin_addr.s_addr && - u->sin_port == remote->sin_port) - return usr; - } - return NULL; -} - -static void -srvconn(struct imsgev *iev, struct imsg *imsg) -{ - struct imsg_srvconn *res; - struct user *usr; - - res = imsg->data; - usr = finduser(&res->addr); - if (!usr || usr->status != USER_REQUESTED) - fatal("server: received srvconn response for inexistant connection"); - if (res->ok) { - usr->status = USER_ACCEPTED; - } else { - usr->status = USER_REFUSED; - } -} - -static void -imsgev_main(struct imsgev *iev, int code, struct imsg *imsg) -{ - switch (code) { - case IMSGEV_IMSG: - log_debug("server: %s got imsg %i on fd %i", - __func__, imsg->hdr.type, iev->ibuf.fd); - switch (imsg->hdr.type) { - case IMSG_SRVCONN_RES: - srvconn(iev, imsg); - break; - default: - fatal("%s, unexpected imsg %d", - __func__, imsg->hdr.type); - } - break; - case IMSGEV_EREAD: - case IMSGEV_EWRITE: - case IMSGEV_EIMSG: - fatal("server: imsgev read/write error (%d)", code); - /* NOTREACHED */ - break; - case IMSGEV_DONE: - event_loopexit(NULL); - /* NOTREACHED */ - break; - } -} - -static void -imsgev_main_needfd(struct imsgev *iev) -{ - fatal("server: imsgev_main_needfd"); -} - -static void -receive(int fd, short why, void *data) -{ - struct sockaddr_in remote; - struct imsg_srvconn req; - socklen_t len; - char buf[16384]; - struct user *usr; - int rv; - - len = sizeof(remote); - rv = recvfrom(fd, buf, sizeof(buf), 0, - (struct sockaddr *)&remote, &len); - if (rv < 0) { - log_warn("server: recvfrom failed"); - return; - } - usr = finduser(&remote); - if (usr) { - switch (usr->status) { - case USER_ACCEPTED: - log_tmp("server: data for existing user"); - break; - case USER_REQUESTED: - log_warn("server: data for not yet accepted user"); - break; - case USER_REFUSED: - log_warn("server: data for banned user !"); - break; - } - } else { - log_debug("server: new user request"); - - usr = xmalloc(sizeof(struct user)); - addrcpy(&usr->addr, &remote); - usr->status = USER_REQUESTED; - usr->lastseen = srv->time; - LIST_INSERT_HEAD(&usr_list, usr, entry); - - addrcpy(&req.addr, &remote); - req.deco = 0; - imsgev_compose(&srv->iev, IMSG_SRVCONN_REQ, 0, 0, -1, - &req, sizeof(req)); - } -} - -static void -ev_usrtimer(int fd, short why, void *data) -{ - struct user *usr, *usrtmp; - struct imsg_srvconn req; - - srv->time = time(NULL); - - LIST_FOREACH_SAFE(usr, &usr_list, entry, usrtmp) { - if (srv->time > usr->lastseen + USER_TIMEOUT) { - addrcpy(&req.addr, &usr->addr); - req.deco = 1; - imsgev_compose(&srv->iev, IMSG_SRVCONN_REQ, 0, 0, -1, - &req, sizeof(req)); - - LIST_REMOVE(usr, entry); - free(usr); - } - } - - if (event_add(&srv->usrtimer_ev, &srv->usrtimer_tv) == -1) - fatal("server: event_add usrtimer failed : %s", strerror(errno)); -} diff --git a/glougloud/user.c b/glougloud/user.c deleted file mode 100644 index ae9734f..0000000 --- a/glougloud/user.c +++ /dev/null @@ -1,806 +0,0 @@ -#include -#include -#include -#include - -#if !defined(__OpenBSD__) -#define __FAVOR_BSD -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "glougloud.h" -#include "external/imsgev.h" - -/* XXX a user process should be able to have multiple clients, so that we - * can send the same data to multiple machines with almost no overhead */ - -#define NULL_HDRLEN 4 // XXX portable ? -#define NODE_MAX_WITHOUT_TIMEOUT 1000 -#define NODE_TIMEOUT 300 // XXX conf ? -#define CONN_TIMEOUT 300 // XXX conf ? -#define CONN_TIMEOUT_UDP 20 // XXX conf ? -#define CONN_TIMEOUT_ICMP 10 // XXX conf ? -#define CONN_FREEIDS_COUNT 65536 /* 2^16 as long as freeids are u_int16_t */ -#define CONNTIMER 5 // XXX conf ? - -struct node { - LIST_ENTRY(node) entry; - struct in_addr addr; - time_t lastseen; - int used; - short namelen; -#define NODENAME_WAITING -1 -#define NODENAME_FAILED -2 - char *name; -}; - -enum connstate { - CONNSTATE_ESTABLISHED, - CONNSTATE_TCPFIN, - CONNSTATE_TCPFIN2 -}; - -struct conn { - LIST_ENTRY(conn) entry; - u_int id; - enum connstate state; - struct node *src; - u_int src_port; - struct node *dst; - u_int dst_port; - u_int proto; - u_int size; - time_t lastseen; -}; - -struct user { - LIST_ENTRY(user) entry; - struct sockaddr_in addr; -}; - -struct capture { - int fd; - struct imsgev iev; - - pcap_t *pcap; - struct event pcap_ev; - struct timeval pcap_tv; - pcap_handler pcap_handler; - - LIST_HEAD(, conn) conn_list; - LIST_HEAD(, node) node_list; - int node_count; - u_int16_t conn_freeids[CONN_FREEIDS_COUNT]; - int conn_freeids_ptr; - struct event conntimer_ev; - struct timeval conntimer_tv; - time_t time; - - int pinvalid; - int ptruncated; -}; - -struct phandler { - pcap_handler f; - int type; -}; - -static void ip_handle(struct ip *, const u_char *, u_int); -static void sendto_all(struct packet *, int); -static struct node *node_add(struct in_addr *); -static void node_del(struct node *); -static struct node *node_find(struct in_addr *); -static void conn_add(struct in_addr *, int, struct in_addr *, int, int, int); -static void conn_data(struct conn *, int, int); -static void conn_del(struct conn *); -static pcap_handler lookup_phandler(int); -static struct user *finduser(struct sockaddr_in *); - -static void phandler_ether(u_char *, - const struct pcap_pkthdr *, const u_char *); -static void phandler_loop(u_char *, - const struct pcap_pkthdr *, const u_char *); -static void ev_pcap(int, short, void *); -static void ev_timer(int, short, void *); - -static void usrconn(struct imsgev *, struct imsg *); -static void imsgev_main(struct imsgev *, int, struct imsg *); -static void imsgev_main_needfd(struct imsgev *); - -static struct phandler phandlers[] = { - { phandler_ether, DLT_EN10MB }, - { phandler_ether, DLT_IEEE802 }, - { phandler_loop, DLT_LOOP }, - { NULL, 0 }, -}; -struct capture *cap; -LIST_HEAD(, user) usr_list; -int usr_count = 0; - -static void -sig_handler(int sig, short why, void *data) -{ - log_info("user: got signal %d", sig); - if (sig == SIGINT || sig == SIGTERM) - event_loopexit(NULL); -} - -int -user_init(int fd[2], pcap_t *pcap) -{ - struct event ev_sigint, ev_sigterm, ev_sigchld, ev_sighup; - int pid, i; - - pid = fork(); - if (pid < 0) - fatal("user fork"); - if (pid > 0) - return pid; - - setproctitle("user"); - event_init(); - close(fd[0]); - - signal_set(&ev_sigint, SIGINT, sig_handler, NULL); - signal_set(&ev_sigterm, SIGTERM, sig_handler, NULL); - signal_set(&ev_sigchld, SIGCHLD, sig_handler, NULL); - signal_set(&ev_sighup, SIGHUP, sig_handler, NULL); - signal_add(&ev_sigint, NULL); - signal_add(&ev_sigterm, NULL); - signal_add(&ev_sigchld, NULL); - signal_add(&ev_sighup, NULL); - signal(SIGPIPE, SIG_IGN); - - cap = xcalloc(1, sizeof(struct capture)); - cap->fd = fd[1]; - imsgev_init(&cap->iev, cap->fd, NULL, imsgev_main, imsgev_main_needfd); - for (i=0; iconn_freeids[i] = i; - cap->time = time(NULL); - - cap->pcap = pcap; - cap->pcap_handler = lookup_phandler(pcap_datalink(pcap)); - cap->pcap_tv.tv_sec = 0; - cap->pcap_tv.tv_usec = PCAP_TO; - event_set(&cap->pcap_ev, pcap_fileno(cap->pcap), - EV_READ, ev_pcap, NULL); - - cap->conntimer_tv.tv_sec = CONNTIMER; - cap->conntimer_tv.tv_usec = 0; - evtimer_set(&cap->conntimer_ev, ev_timer, NULL); - if (event_add(&cap->conntimer_ev, &cap->conntimer_tv) == -1) - fatal("user: event_add conntimer failed: %s", strerror(errno)); - - droppriv(); - - log_info("user: entering event loop"); - event_dispatch(); - - log_info("user: exiting"); - exit(0); -} - -/* - * Parse an IP packet and descide what to do with it. - * 'ip' is a pointer the the captured IP packet - * 'pend' is a pointer to the end of the captured IP packet - * 'wirelen' is the size of the IP packet off the wire - */ -#define NOTCAPTURED(v) ((u_char *)v > (u_char *)pend - sizeof(*v)) -#define NOTRECEIVED(v) (wirelen < sizeof(v)) -static void -ip_handle(struct ip *ip, const u_char *pend, u_int wirelen) -{ - u_int len, ip_hlen, off; - const u_char *cp; - struct tcphdr *tcph; - struct udphdr *udph; - struct icmp *icmp; - struct in_addr src, dst; - u_int src_port, dst_port; - u_int size, proto, close, response; - struct conn *c, *conn; - - if (NOTCAPTURED(ip)) { - log_pinvalid("user: ip truncated (ip %x pend %x sizeof(ip) %d", - ip, pend, sizeof(ip)); - cap->ptruncated++; - return; - } - - if (ip->ip_v != IPVERSION) { - log_pinvalid("user: invalid ip version"); - cap->pinvalid++; - return; - } - - len = ntohs(ip->ip_len); - if (wirelen < len) { - log_pinvalid("user: ip too small"); - cap->pinvalid++; - len = wirelen; - } - - ip_hlen = ip->ip_hl * 4; - if (ip_hlen < sizeof(struct ip) || ip_hlen > len) { - log_pinvalid("user: ip_hlen invalid, %d", ip_hlen); - cap->pinvalid++; - return; - } - len -= ip_hlen; - - src.s_addr = ntohl(ip->ip_src.s_addr); - dst.s_addr = ntohl(ip->ip_dst.s_addr); - src_port = 0; - dst_port = 0; - proto = IPPROTO_IP; - size = len; - close = 0; - - off = ntohs(ip->ip_off); - if ((off & IP_OFFMASK) == 0) { - cp = (const u_char *)ip + ip_hlen; - switch (ip->ip_p) { - - case IPPROTO_TCP: - tcph = (struct tcphdr *)cp; - if (NOTCAPTURED(&tcph->th_flags)) { - log_pinvalid("user: tcp truncated"); - cap->ptruncated++; - return; - } - if (NOTRECEIVED(*tcph)) { - log_pinvalid("user: tcp too small"); - cap->pinvalid++; - return; - } - src_port = ntohs(tcph->th_sport); - dst_port = ntohs(tcph->th_dport); - proto = IPPROTO_TCP; - size = len - sizeof(*tcph); - if ((tcph->th_flags & TH_FIN) && - (tcph->th_flags & TH_ACK)) - close = 1; - break; - - case IPPROTO_UDP: - udph = (struct udphdr *)cp; - if (NOTCAPTURED(&udph->uh_dport)) { - log_pinvalid("user: udp truncated, " - "ip %x, udph %x, uh_port %x, pend %x, ip_hlen %d", - ip, udph, &udph->uh_dport, pend, ip_hlen); - cap->ptruncated++; - return; - } - if (NOTRECEIVED(*udph)) { - log_pinvalid("user: udp too small"); - cap->pinvalid++; - return; - } - src_port = ntohs(udph->uh_sport); - dst_port = ntohs(udph->uh_dport); - proto = IPPROTO_UDP; - size = len - sizeof(*udph); - break; - - case IPPROTO_ICMP: - icmp = (struct icmp *)cp; - if (NOTRECEIVED(*icmp)) { - log_pinvalid("user: icmp too small"); - cap->pinvalid++; - return; - } - proto = IPPROTO_ICMP; - size = len - sizeof(*icmp); - break; - - default: - log_warn("user: unknown ip protocol !"); - break; - } - } else { - /* - * if this isn't the first frag, we're missing the - * next level protocol header. - */ - log_tmp("user: got a fragmented ip packet !"); - } - - conn = NULL; - LIST_FOREACH(c, &cap->conn_list, entry) { - if (((c->src->addr.s_addr == src.s_addr && - c->src_port == src_port && - c->dst->addr.s_addr == dst.s_addr && - c->dst_port == dst_port) || - (c->src->addr.s_addr == dst.s_addr && - c->src_port == dst_port && - c->dst->addr.s_addr == src.s_addr && - c->dst_port == src_port)) && - c->proto == proto) { - conn = c; - if (c->src->addr.s_addr == src.s_addr) - response = 0; - else - response = 1; - break; - } - } - - if (conn) { - if (!close) { - conn_data(conn, size, response); - } else { - conn_del(conn); - } - } else { - if (!close) { - conn_add(&src, src_port, &dst, dst_port, proto, size); - } else { - log_warn("user: captured connection close w/o open !"); - } - } -} - -/* XXX all the packets must have data htos */ -static void -sendto_all(struct packet *p, int size) -{ - struct user *usr; - - log_debug("SEND PACKET (size %.2d): %x %x", size, p->ver, p->type); - - LIST_FOREACH(usr, &usr_list, entry) { - if (sendto(net_socket, p, size, 0, - (struct sockaddr *)&usr->addr, sizeof(usr->addr)) == -1) - log_warn("send_to failed: %s", strerror(errno)); - } -} - -static struct node * -node_add(struct in_addr *addr) -{ - struct node *n; - struct imsg_usrdns_req req; - - log_debug("user: node_add"); - - n = xcalloc(1, sizeof(struct node)); - n->addr.s_addr = addr->s_addr; - n->namelen = NODENAME_WAITING; - n->lastseen = cap->time; - LIST_INSERT_HEAD(&cap->node_list, n, entry); - cap->node_count++; - - req.addr.s_addr = addr->s_addr; - imsgev_compose(&cap->iev, IMSG_USRDNS_REQ, 0, 0, -1, - &req, sizeof(req)); - - return n; -} - -static void -node_del(struct node *n) -{ - if (n->used) - fatal("user: trying to remove a used node !"); - log_debug("user: node_del"); - - LIST_REMOVE(n, entry); - free(n->name); - free(n); - cap->node_count--; -} - -static struct node * -node_find(struct in_addr *remote) -{ - struct node *n; - - LIST_FOREACH(n, &cap->node_list, entry) - if (n->addr.s_addr == remote->s_addr) - return n; - return NULL; -} - -static void -conn_add(struct in_addr *src, int src_port, struct in_addr *dst, int dst_port, int proto, int size) -{ - struct packet p; - struct conn *c; - struct node *srcnode; - struct node *dstnode; - int id; - - log_debug("user: conn_add, %x:%d->%x:%d %d [%d]", - src->s_addr, src_port, dst->s_addr, dst_port, proto, size); - if (cap->conn_freeids_ptr == CONN_FREEIDS_COUNT) { - log_warn("user: out of connection identifiers !"); - return; - } - - id = cap->conn_freeids[cap->conn_freeids_ptr]; - cap->conn_freeids_ptr++; - - srcnode = node_find(src); - if (!srcnode) - srcnode = node_add(src); - srcnode->used++; - dstnode = node_find(dst); - if (!dstnode) - dstnode = node_add(dst); - dstnode->used++; - - c = xmalloc(sizeof(struct conn)); - c->id = id; - c->state = CONNSTATE_ESTABLISHED; - c->src = srcnode; - c->src_port = src_port; - c->dst = dstnode; - c->dst_port = dst_port; - c->proto = proto; - c->size = size; - c->lastseen = cap->time; - LIST_INSERT_HEAD(&cap->conn_list, c, entry); - - bzero(&p, sizeof(p)); - p.ver = PACKET_VERSION; - p.type = PACKET_NEWCONN; - p.newconn_id = id; - p.newconn_src = htonl(src->s_addr); - p.newconn_dst = htonl(dst->s_addr); - p.newconn_proto = proto; - p.newconn_size = htons(size << 8); - sendto_all(&p, PACKET_NEWCONN_SIZE); -} - -static void -conn_data(struct conn *c, int size, int response) -{ - struct packet p; - - log_debug("user: conn_data"); - - c->lastseen = cap->time; - - bzero(&p, sizeof(p)); - p.ver = PACKET_VERSION; - p.type = PACKET_DATA; - p.data_connid = c->id; - p.data_size = htons(size << 8 | response); //XXX - sendto_all(&p, PACKET_DATA_SIZE); -} - -static void -conn_del(struct conn *c) -{ - struct packet p; - - log_debug("user: conn_del"); - - if (c->proto == IPPROTO_TCP) { - switch (c->state) { - case CONNSTATE_ESTABLISHED: - c->state = CONNSTATE_TCPFIN; - return; - case CONNSTATE_TCPFIN: - c->state = CONNSTATE_TCPFIN2; - return; - case CONNSTATE_TCPFIN2: - break; - } - } - - bzero(&p, sizeof(p)); - p.ver = PACKET_VERSION; - p.type = PACKET_DELCONN; - p.delconn_id = c->id; - sendto_all(&p, PACKET_DELCONN_SIZE); - - if (cap->conn_freeids_ptr == 0) - fatal("cap->conn_freeids_ptr == 0"); - cap->conn_freeids_ptr--; - cap->conn_freeids[cap->conn_freeids_ptr] = c->id; - - c->src->used--; - c->dst->used--; - - LIST_REMOVE(c, entry); - free(c); -} - -static pcap_handler -lookup_phandler(int type) -{ - struct phandler *p; - - for (p = phandlers; p->f; ++p) { - if (type == p->type) - return p->f; - } - fatal("user: unknown data link type 0x%x", type); - /* NOTREACHED */ - return NULL; -} - -static struct user * -finduser(struct sockaddr_in *remote) -{ - struct user *usr; - struct sockaddr_in *u; - - LIST_FOREACH(usr, &usr_list, entry) { - u = &usr->addr; - if (u->sin_addr.s_addr == remote->sin_addr.s_addr && - u->sin_port == remote->sin_port) - return usr; - } - return NULL; -} - -static void -phandler_ether(u_char *user, const struct pcap_pkthdr *h, const u_char *p) -{ - struct ether_header *ep; - struct ip *ip; - u_short ether_type; - const u_char *pend; - u_int len; - - log_debug("user: pcap handler ethernet !"); - - /* XXX here i assume that packets are alligned, which might not - * be the case when using dump files, says tcpdump sources */ - - ep = (struct ether_header *)p; - pend = p + h->caplen; - len = h->len - sizeof(struct ether_header); - - - ether_type = ntohs(ep->ether_type); - if (ether_type <= ETHERMTU) - log_tmp("llc packet !"); - else { - switch (ether_type) { - case ETHERTYPE_IP: - log_tmp("ether IP"); - ip = (struct ip *)((u_char *)ep + sizeof(struct ether_header)); - ip_handle(ip, pend, len); - break; - default: - log_tmp("non ip packet !"); - break; - } - } -} - -static void -phandler_loop(u_char *user, const struct pcap_pkthdr *h, const u_char *p) -{ - struct ip *ip; - struct ether_header *ep; - u_short ether_type; - u_int family; - const u_char *pend; - u_int len; - - log_debug("user: pcap handler loop !"); - - /* XXX here i assume that packets are alligned, which might not - * be the case when using dump files, says tcpdump sources */ - - pend = p + h->caplen; - len = h->len; - - memcpy((char *)&family, (char *)p, sizeof(family)); - family = ntohl(family); - switch (family) { - case AF_INET: - log_tmp("loop family AF_INET"); - ip = (struct ip *)(p + NULL_HDRLEN); - len -= NULL_HDRLEN; - ip_handle(ip, pend, len); - break; -#if defined(__OpenBSD__) - case AF_LINK: -#else - case AF_LOCAL: -#endif - ep = (struct ether_header *)(p + NULL_HDRLEN); - ether_type = ntohs(ep->ether_type); - if (ether_type <= ETHERMTU) - log_tmp("llc packet !"); - else { - switch (ether_type) { - case ETHERTYPE_IP: - log_tmp("loop family AF_LINK IP"); - ip = (struct ip *)((u_char *)ep + sizeof(*ep)); - len -= NULL_HDRLEN + sizeof(*ep); - ip_handle(ip, pend, len); - break; - default: - log_tmp("loop non ip packet !"); - break; - } - } - default: - log_tmp("unknown family %x !", family); - break; - } -} - -static void -ev_pcap(int fd, short why, void *data) -{ - log_tmp("ev_pcap"); - pcap_dispatch(cap->pcap, PCAP_COUNT, cap->pcap_handler, NULL); - - /* reschedule */ - if (event_add(&cap->pcap_ev, &cap->pcap_tv) == -1) - fatal("user: event_add pcap failed : %s", strerror(errno)); -} - -static void -ev_timer(int fd, short why, void *data) -{ - struct conn *c, *ctmp; - struct node *n, *ntmp; - int i, to; - - log_debug("ev_timer"); - cap->time = time(NULL); - - i = 0; - LIST_FOREACH_SAFE(c, &cap->conn_list, entry, ctmp) { - switch (c->proto) { - case IPPROTO_UDP: - to = CONN_TIMEOUT_UDP; - break; - case IPPROTO_ICMP: - to = CONN_TIMEOUT_ICMP; - break; - default: - to = CONN_TIMEOUT; - break; - } - if (cap->time > c->lastseen + to) - conn_del(c); - else - i++; - } - - if (cap->node_count > NODE_MAX_WITHOUT_TIMEOUT) { - LIST_FOREACH_SAFE(n, &cap->node_list, entry, ntmp) { - if (n->used == 0 && - cap->time > n->lastseen + NODE_TIMEOUT) - node_del(n); - } - } - - log_debug("user: ev_timer leaving with %d active connections and %d active nodes", i, cap->node_count); - if (event_add(&cap->conntimer_ev, &cap->conntimer_tv) == -1) - fatal("user: event_add conntimer failed : %s", strerror(errno)); -} - -static void -usrconn(struct imsgev *iev, struct imsg *imsg) -{ - struct imsg_usrconn *req; - struct imsg_usrconn res; - struct user *usr; - - req = imsg->data; - - if (req->deco) { - usr = finduser(&req->addr); - if (!usr) - fatal("user: trying to deco an inexistant user !"); - LIST_REMOVE(usr, entry); - free(usr); - usr_count--; - if (usr_count == 0) - event_del(&cap->pcap_ev); - - return; - } - - usr = xmalloc(sizeof(struct user)); - addrcpy(&usr->addr, &req->addr); - LIST_INSERT_HEAD(&usr_list, usr, entry); - if (usr_count == 0) { - if (event_add(&cap->pcap_ev, &cap->pcap_tv) == -1) - fatal("user: event_add failed : %s", strerror(errno)); - } - usr_count++; - - addrcpy(&res.addr, &usr->addr); - res.ok = 1; - imsgev_compose(&cap->iev, IMSG_USRCONN_RES, 0, 0, -1, - &res, sizeof(res)); -} - -static void -usrdns(struct imsgev *iev, struct imsg *imsg) -{ - struct imsg_usrdns_res *res; - struct node *n; - struct packet p; - - res = imsg->data; - - n = node_find(&res->addr); - if (!n) - fatal("user: received usrdns response for inexistant node !"); - if (n->namelen != NODENAME_WAITING) - fatal("user: received usrdns response for a nonwaiting node!"); - - if (res->name[0] == '\0') { - log_debug("user: resolv for %x failed", res->addr.s_addr); - n->namelen = NODENAME_FAILED; - return; - } - n->namelen = strnlen(res->name, DNSNAME_MAX); - n->name = strndup(res->name, DNSNAME_MAX); - - log_debug("user: sending node name of %x is %s", - n->addr.s_addr, n->name); - bzero(&p, sizeof(p)); - p.ver = PACKET_VERSION; - p.type = PACKET_NAME; - p.name_addr = htonl(n->addr.s_addr); - p.name_len = n->namelen; - strncpy(p.name_fqdn, n->name, sizeof(p.name_fqdn)); - sendto_all(&p, PACKET_NAME_SIZE + p.name_len); -} - -static void -imsgev_main(struct imsgev *iev, int code, struct imsg *imsg) -{ - switch (code) { - case IMSGEV_IMSG: - log_debug("user: %s got imsg %i on fd %i", - __func__, imsg->hdr.type, iev->ibuf.fd); - switch (imsg->hdr.type) { - case IMSG_USRCONN_REQ: - usrconn(iev, imsg); - break; - case IMSG_USRDNS_RES: - usrdns(iev, imsg); - break; - default: - fatal("user: %s, unexpected imsg %d", - __func__, imsg->hdr.type); - } - break; - case IMSGEV_EREAD: - case IMSGEV_EWRITE: - case IMSGEV_EIMSG: - fatal("user: imsgev read/write error"); - /* NOTREACHED */ - break; - case IMSGEV_DONE: - event_loopexit(NULL); - /* NOTREACHED */ - break; - } -} - -static void -imsgev_main_needfd(struct imsgev *iev) -{ - fatal("server: imsgev_main_needfd"); -} diff --git a/glougloud/util.c b/glougloud/util.c deleted file mode 100644 index c077bd3..0000000 --- a/glougloud/util.c +++ /dev/null @@ -1,192 +0,0 @@ -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "glougloud.h" - -FILE *logfile; -int loglevel; -int logpinvalid; - -#define LOGFILE "/var/log/glougloud" -#define LOG_FORCED -2 -#define LOG_FATAL -1 -#define LOG_WARN 0 -#define LOG_INFO 1 -#define LOG_DEBUG 2 - -static void logit(int, const char *, const char *, va_list); - -void -log_init(int level, int pinvalid) -{ - logfile = fopen(LOGFILE, "a+"); - if (!logfile) { - printf("cannot open log file %s!\n", LOGFILE); - exit(1); - } - loglevel = level; - logpinvalid = pinvalid; -} - -void -log_tmp(const char *msg, ...) -{ - va_list ap; - - va_start(ap, msg); - logit(LOG_FORCED, "XXX ", msg, ap); - va_end(ap); -} -void -log_pinvalid(const char *msg, ...) -{ - va_list ap; - - if (!logpinvalid) - return; - - va_start(ap, msg); - logit(LOG_FORCED, "pinvalid: ", msg, ap); - va_end(ap); -} -void -log_debug(const char *msg, ...) -{ - va_list ap; - - va_start(ap, msg); - logit(LOG_DEBUG, "", msg, ap); - va_end(ap); -} -void -log_info(const char *msg, ...) -{ - va_list ap; - - va_start(ap, msg); - logit(LOG_INFO, "", msg, ap); - va_end(ap); -} -void -log_warn(const char *msg, ...) -{ - va_list ap; - - va_start(ap, msg); - logit(LOG_WARN, "", msg, ap); - va_end(ap); -} -#if defined(__OpenBSD__) -void __dead -#else -void -#endif -fatal(const char *msg, ...) -{ - va_list ap; - - va_start(ap, msg); - logit(LOG_FATAL, "fatal: ", msg, ap); - va_end(ap); - - exit(1); -} - -/* XXX mpsafe */ -static void -logit(int level, const char *prefix, const char *msg, va_list ap) -{ - time_t clock; - - if (level <= loglevel) { - time(&clock); - fprintf(logfile, "%d ", (int)clock); - vfprintf(logfile, prefix, ap); - vfprintf(logfile, msg, ap); - fprintf(logfile, "\n"); - fflush(logfile); - } -} - -void * -xmalloc(size_t size) -{ - void *ptr; - - if (size == 0) - fatal("xmalloc: zero size"); - ptr = malloc(size); - if (ptr == NULL) - fatal("xmalloc: out of memory (allocating %lu bytes)", (u_long) size); - return ptr; -} - -void * -xcalloc(size_t nmemb, size_t size) -{ - void *ptr; - - if (size == 0) - fatal("xcalloc: zero size"); - ptr = calloc(nmemb, size); - if (ptr == NULL) - fatal("xcalloc: out of memory (allocating %lu bytes)", (u_long) size); - return ptr; -} - -void -fd_nonblock(int fd) -{ - int flags = fcntl(fd, F_GETFL, 0); - int rc = fcntl(fd, F_SETFL, flags | O_NONBLOCK); - if (rc == -1) - log_warn("failed to set fd %i non-blocking", fd); -} - -void -droppriv() -{ - struct passwd *pw; - - pw = getpwnam(GLOUGLOUD_USER); - if (!pw) - fatal("unknown user %s", GLOUGLOUD_USER); - if (chroot(pw->pw_dir) != 0) - fatal("unable to chroot"); - if (chdir("/") != 0) - fatal("unable to chdir"); - if (setgroups(1, &pw->pw_gid) == -1) - fatal("setgroups() failed"); - if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1) - fatal("setresgid failed"); - if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1) - fatal("setresuid() failed"); - endpwent(); -} - -void -addrcpy(struct sockaddr_in *dst, struct sockaddr_in *src) -{ - dst->sin_addr.s_addr = src->sin_addr.s_addr; - dst->sin_port = src->sin_port; - dst->sin_family = src->sin_family; -} - -void -socketpair_prepare(int fd[2]) -{ - if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, fd) == -1) - fatal("socketpair_prepare"); - fd_nonblock(fd[0]); - fd_nonblock(fd[1]); -} - -- cgit v1.2.3-59-g8ed1b