*** empty log message ***
authorMatthew Mondor <mmondor@pulsar-zone.net>
Mon, 24 Dec 2007 03:16:21 +0000 (03:16 +0000)
committerMatthew Mondor <mmondor@pulsar-zone.net>
Mon, 24 Dec 2007 03:16:21 +0000 (03:16 +0000)
mmsoftware/tap-bridge/modules/tap-logger.c
mmsoftware/tap-bridge/tap-bridge.c

index 631abf1..0c7e4ee 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: tap-logger.c,v 1.4 2007/12/23 16:52:17 mmondor Exp $ */
+/* $Id: tap-logger.c,v 1.5 2007/12/24 03:16:21 mmondor Exp $ */
 
 /*
  * Copyright (C) 2007, Matthew Mondor
 
 /*
  * Copyright (C) 2007, Matthew Mondor
  */
 
 #include <errno.h>
  */
 
 #include <errno.h>
-#include <fcntl.h>
 #include <stdarg.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdarg.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <unistd.h>
 
 #include <tap-bridge.h>
 #include <tap-headers.h>
 
 
 
 #include <tap-bridge.h>
 #include <tap-headers.h>
 
 
-static bool    mod_init(tap_t *, tap_t *);
-static bool    mod_recv_int(tap_t *, fnode_t *);
-static bool    mod_recv_ext(tap_t *, fnode_t *);
-static void    mod_exit(void);
+static bool            mod_init(tap_t *, tap_t *);
+static bool            mod_recv_int(tap_t *, fnode_t *);
+static bool            mod_recv_ext(tap_t *, fnode_t *);
+static void            mod_exit(void);
 
 
-static void    logprintf(const char *, ...);
-static void    frame_log(frame_t *, const char *);
+static void            logprintf(const char *, ...);
+static void            frame_log(frame_t *, int);
 
 
 module_t module = {
 
 
 module_t module = {
@@ -63,8 +61,8 @@ module_t module = {
 };
 
 
 };
 
 
-static tap_t   *tap_int, *tap_ext;
-static int     logfd = -1;
+static tap_t           *tap_int, *tap_ext;
+static FILE            *logfh = NULL;
 
 
 static bool
 
 
 static bool
@@ -78,21 +76,16 @@ mod_init(tap_t *tap_i, tap_t *tap_e)
        if ((udata = key_lookup("tap_logger_file")) == NULL) {
                if ((udata = key_create("tap_logger_file")) == NULL)
                        return false;
        if ((udata = key_lookup("tap_logger_file")) == NULL) {
                if ((udata = key_create("tap_logger_file")) == NULL)
                        return false;
-               if ((logfd = open("/tmp/tap-filter.log",
-                   O_CREAT | O_WRONLY | O_APPEND)) == -1) {
+               if ((logfh = fopen("/tmp/tap-filter.log", "a")) == NULL) {
                        key_destroy("tap_logger_file");
                        warning(errno, "fopen(/tmp/tap-filter.log)");
                        return false;
                }
                        key_destroy("tap_logger_file");
                        warning(errno, "fopen(/tmp/tap-filter.log)");
                        return false;
                }
-               if ((*udata = malloc(sizeof(int))) == NULL) {
-                       key_destroy("tap_logger_file");
-                       warning(errno, "malloc(int)");
-                       return false;
-               }
+               (void) setvbuf(logfh, NULL, _IOLBF, 0);
 
 
-               *((int *)*udata) = logfd;
+               *udata = logfh;
        } else
        } else
-               logfd = *((int *)*udata);
+               logfh = *udata;
 
        return true;
 }
 
        return true;
 }
@@ -101,7 +94,7 @@ static bool
 mod_recv_int(tap_t *tap, fnode_t *n)
 {
 
 mod_recv_int(tap_t *tap, fnode_t *n)
 {
 
-       frame_log(n->frame, "<");
+       frame_log(n->frame, '<');
        fnode_destroy(n);
        return true;
 }
        fnode_destroy(n);
        return true;
 }
@@ -110,7 +103,7 @@ static bool
 mod_recv_ext(tap_t *tap, fnode_t *n)
 {
 
 mod_recv_ext(tap_t *tap, fnode_t *n)
 {
 
-       frame_log(n->frame, ">");
+       frame_log(n->frame, '>');
        fnode_destroy(n);
        return true;
 }
        fnode_destroy(n);
        return true;
 }
@@ -123,39 +116,31 @@ mod_exit(void)
 }
 
 
 }
 
 
-/*
- * We want line buffering, and can't use stdio as it won't restart write(2) on
- * EINTR events.
- */
 static void
 logprintf(const char *fmt, ...)
 {
 static void
 logprintf(const char *fmt, ...)
 {
-       char    buf[1024];
        va_list lst;
        va_list lst;
-       int     len;
 
        va_start(lst, fmt);
 
        va_start(lst, fmt);
-       len = vsnprintf(buf, sizeof(buf) - 1, fmt, lst);
+       (void) vfprintf(logfh, fmt, lst);
        va_end(lst);
        va_end(lst);
-
-       while (write(logfd, buf, len) == -1 && errno == EINTR) ;
 }
 
 static void
 }
 
 static void
-frame_log(frame_t *f, const char *d)
+frame_log(frame_t *f, int d)
 {
        char            origin[32], destination[32];
        struct hdr_tap  *hdrtap = (struct hdr_tap *)f->data;
        void            *ahdrtap = &hdrtap[1];
 
        if (f->size < sizeof(struct hdr_tap)) {
 {
        char            origin[32], destination[32];
        struct hdr_tap  *hdrtap = (struct hdr_tap *)f->data;
        void            *ahdrtap = &hdrtap[1];
 
        if (f->size < sizeof(struct hdr_tap)) {
-               logprintf("%s Short ethernet frame: size=%u\n", d, f->size);
+               logprintf("%c Short ethernet frame: size=%u\n", d, f->size);
                return;
        }
 
        (void) macaddr_string(origin, 31, &f->origin);
        (void) macaddr_string(destination, 31, &f->destination);
                return;
        }
 
        (void) macaddr_string(origin, 31, &f->origin);
        (void) macaddr_string(destination, 31, &f->destination);
-       logprintf("%s src=%s, dst=%s etype=%04x size=%u\n",
+       logprintf("%c src=%s, dst=%s etype=%04x size=%u\n",
            d, origin, destination, f->type, f->size);
 
        /*
            d, origin, destination, f->type, f->size);
 
        /*
@@ -167,7 +152,7 @@ frame_log(frame_t *f, const char *d)
 
                if (f->size < sizeof(struct hdr_tap) +
                    sizeof(struct hdr_arp)) {
 
                if (f->size < sizeof(struct hdr_tap) +
                    sizeof(struct hdr_arp)) {
-                       logprintf(" Short ARP header\n");
+                       logprintf("  Short ARP header\n");
                        return;
                }
                hdrarp = ahdrtap;
                        return;
                }
                hdrarp = ahdrtap;
@@ -179,22 +164,46 @@ frame_log(frame_t *f, const char *d)
        if (f->type == HDR_TAP_ETYPE_IP) {
                struct hdr_ip   *hdrip;
                uint16_t        t;
        if (f->type == HDR_TAP_ETYPE_IP) {
                struct hdr_ip   *hdrip;
                uint16_t        t;
-               int             flags, off;
-               /*void          *ahdrip;*/
+               int             ver, hlen, flags, off;
+               void            *ahdrip;
 
                if (f->size < sizeof(struct hdr_tap) + sizeof(struct hdr_ip)) {
 
                if (f->size < sizeof(struct hdr_tap) + sizeof(struct hdr_ip)) {
-                       logprintf(" Short IP header\n");
+                       logprintf("  Short IP header\n");
                        return;
                }
                hdrip = ahdrtap;
                        return;
                }
                hdrip = ahdrtap;
+
+               t = BYTEORDER_HOST16(hdrip->ver_hlen);
+               ver = HDR_IP_VER_GET(t);
+               hlen = HDR_IP_HLEN_GET(t);
+               if (hlen < 4) {
+                       logprintf("  Short IP header length (%d)\n", hlen);
+                       return;
+               }
+               ahdrip = &((uint32_t *)hdrip)[hlen];
+
                t = BYTEORDER_HOST16(hdrip->flags_off);
                flags = HDR_IP_FLAGS_GET(t);
                off = HDR_IP_OFF_GET(t);
                t = BYTEORDER_HOST16(hdrip->flags_off);
                flags = HDR_IP_FLAGS_GET(t);
                off = HDR_IP_OFF_GET(t);
-               logprintf("  IP: flags=%02x off=%04x\n", flags, off);
+
                /* XXX */
 
                /* XXX */
 
+               if (hdrip->protocol == HDR_IP_PROTO_UDP) {
+                       return;
+               }
+
+               if (hdrip->protocol == HDR_IP_PROTO_TCP) {
+                       return;
+               }
+
+               if (hdrip->protocol == HDR_IP_PROTO_ICMP) {
+                       return;
+               }
+
+               logprintf("  Unsupported IP protocol (0x%02x)\n",
+                   hdrip->protocol);
                return;
        }
 
                return;
        }
 
-       logprintf(" Unsupported ethertype (0x%04x)\n", f->type);
+       logprintf("  Unsupported ethertype (0x%04x)\n", f->type);
 }
 }
index cf5b0b4..830f82a 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: tap-bridge.c,v 1.2 2007/12/20 01:32:19 mmondor Exp $ */
+/* $Id: tap-bridge.c,v 1.3 2007/12/24 03:16:21 mmondor Exp $ */
 
 /*
  * Copyright (C) 2007, Matthew Mondor
 
 /*
  * Copyright (C) 2007, Matthew Mondor
@@ -45,7 +45,6 @@
 #include <fcntl.h>
 #include <grp.h>
 #include <pwd.h>
 #include <fcntl.h>
 #include <grp.h>
 #include <pwd.h>
-#include <poll.h>
 #include <signal.h>
 #include <stdarg.h>
 #include <stdbool.h>
 #include <signal.h>
 #include <stdarg.h>
 #include <stdbool.h>
@@ -156,6 +155,7 @@ static bool         parent_exit = false;
 static pid_t           child_pid = -1;
 static bool            child_exit = false;
 static bool            schedule_now = false;
 static pid_t           child_pid = -1;
 static bool            child_exit = false;
 static bool            schedule_now = false;
+static bool            revents = false;
 static struct timeval  time_current, time_event;
 static pool_t          frame_pool, fnode_pool, key_pool, modnode_pool;
 static hashtable_t     storage_table;
 static struct timeval  time_current, time_event;
 static pool_t          frame_pool, fnode_pool, key_pool, modnode_pool;
 static hashtable_t     storage_table;
@@ -416,13 +416,6 @@ parent_init(void)
                        goto err;
        }
 
                        goto err;
        }
 
-       /* Set non-blocking mode */
-       if (fcntl(tap_ext->fd, F_SETFL, O_NONBLOCK) == -1 ||
-           fcntl(tap_int->fd, F_SETFL, O_NONBLOCK) == -1) {
-               warning(errno, "fcntl(O_NONBLOCK)");
-               goto err;
-       }
-
        /* Create bridge interface */
        if (if_create(ifbr) == -1)
                goto err;
        /* Create bridge interface */
        if (if_create(ifbr) == -1)
                goto err;
@@ -444,7 +437,7 @@ parent_init(void)
 
                act.sa_handler = parent_sighandler;
                (void) sigemptyset(&act.sa_mask);
 
                act.sa_handler = parent_sighandler;
                (void) sigemptyset(&act.sa_mask);
-               act.sa_flags = 0;
+               act.sa_flags = SA_RESTART;
                if (sigaction(SIGTERM, &act, NULL) == -1 ||
                    sigaction(SIGINT, &act, NULL) == -1 ||
                    sigaction(SIGCHLD, &act, NULL) == -1 ||
                if (sigaction(SIGTERM, &act, NULL) == -1 ||
                    sigaction(SIGINT, &act, NULL) == -1 ||
                    sigaction(SIGCHLD, &act, NULL) == -1 ||
@@ -510,9 +503,7 @@ parent_sighandler(int sig)
                        pid_t   pid;
                        int     status = 0;
 
                        pid_t   pid;
                        int     status = 0;
 
-                       while ((pid = wait3(&status, WNOHANG, NULL)) == -1 &&
-                           errno == EINTR) ;
-                       if (pid < 1)
+                       if ((pid = wait3(&status, WNOHANG, NULL)) < 1)
                                break;
                        if (!WIFEXITED(status))
                                continue;
                                break;
                        if (!WIFEXITED(status))
                                continue;
@@ -579,11 +570,12 @@ child_init(void)
 
                act.sa_handler = child_sighandler;
                (void) sigemptyset(&act.sa_mask);
 
                act.sa_handler = child_sighandler;
                (void) sigemptyset(&act.sa_mask);
-               act.sa_flags = 0;
+               act.sa_flags = SA_RESTART;
                if (sigaction(SIGTERM, &act, NULL) == -1 ||
                    sigaction(SIGINT, &act, NULL) == -1 ||
                    sigaction(SIGALRM, &act, NULL) == -1 ||
                if (sigaction(SIGTERM, &act, NULL) == -1 ||
                    sigaction(SIGINT, &act, NULL) == -1 ||
                    sigaction(SIGALRM, &act, NULL) == -1 ||
-                   sigaction(SIGHUP, &act, NULL) == -1) {
+                   sigaction(SIGHUP, &act, NULL) == -1 ||
+                   sigaction(SIGIO, &act, NULL) == -1) {
                        warning(errno, "sigaction(child)");
                        goto err;
                }
                        warning(errno, "sigaction(child)");
                        goto err;
                }
@@ -591,6 +583,24 @@ child_init(void)
                (void) sigaction(SIGCHLD, &act, NULL);
        }
 
                (void) sigaction(SIGCHLD, &act, NULL);
        }
 
+       /*
+        * Get SIGIO signal when data is available and use non-blocking mode
+        */
+       {
+               pid_t   pid = getpid();
+
+               if (fcntl(tap_ext->fd, F_SETOWN, pid) == -1 ||
+                   fcntl(tap_int->fd, F_SETOWN, pid) == -1) {
+                       warning(errno, "fcntl(F_SETOWN)");
+                       goto err;
+               }
+               if (fcntl(tap_ext->fd, F_SETFL, O_NONBLOCK | O_ASYNC) == -1 ||
+                   fcntl(tap_int->fd, F_SETFL, O_NONBLOCK | O_ASYNC) == -1) {
+                       warning(errno, "fcntl(O_NONBLOCK | O_ASYNC)");
+                       goto err;
+               }
+       }
+
        /* Setup our pools */
        {
                size_t pagesize;
        /* Setup our pools */
        {
                size_t pagesize;
@@ -662,14 +672,12 @@ err:
 static void
 child_main(void)
 {
 static void
 child_main(void)
 {
-       struct pollfd   fds[2];
+       sigset_t        set;
 
        warning(0, "Child unprivileged process started");
 
 
        warning(0, "Child unprivileged process started");
 
-       fds[0].fd = tap_ext->fd;
-       fds[1].fd = tap_int->fd;
-       fds[0].events = fds[1].events = POLLIN;
-       fds[0].revents = fds[1].revents = 0;
+       (void) sigemptyset(&set);
+
        while (!child_exit) {
 
                /*
        while (!child_exit) {
 
                /*
@@ -694,12 +702,6 @@ child_main(void)
                }
 
                /*
                }
 
                /*
-                * For performance we process as much data as possible
-                * before polling.  Prioritize output, and use a limit to
-                * prevent starvation of one direction.
-                */
-
-               /*
                 * Send out some data from our send queue if any.
                 * What resides here should already have been sanity checked
                 * by any user code, as it was queued by user code for
                 * Send out some data from our send queue if any.
                 * What resides here should already have been sanity checked
                 * by any user code, as it was queued by user code for
@@ -723,6 +725,7 @@ child_main(void)
                 * few fields of the frame_t structure prior to passing them
                 * to user code.
                 */
                 * few fields of the frame_t structure prior to passing them
                 * to user code.
                 */
+               revents = false;
                if (!frame_receive(tap_int) && errno != EAGAIN &&
                    errno != EHOSTDOWN) {
                        warning(errno, "frame_receive(tap_int)");
                if (!frame_receive(tap_int) && errno != EAGAIN &&
                    errno != EHOSTDOWN) {
                        warning(errno, "frame_receive(tap_int)");
@@ -738,49 +741,27 @@ child_main(void)
                if (child_exit)
                        break;
 
                if (child_exit)
                        break;
 
-               /* Don't poll yet if we have more events to process. */
-               if (schedule_now && errno != EHOSTDOWN)
+               /* Don't sleep yet if we have more events to process. */
+               if ((schedule_now || revents) && errno != EHOSTDOWN)
                        continue;
 
                        continue;
 
-               /*
-                * Poll and continue loop if any interesting data.
-                */
-               for (;;) {
-                       int     ret;
-
-                       ret = poll(fds, 2, -1);
-                       if (ret == 0) {
-                               if (schedule_now)
-                                       break;
-                               continue;
-                       }
-                       if (ret == -1) {
-                               if (errno == EINTR)
-                                       break;
-                               warning(errno, "poll");
-                               goto out;
-                       }
-                       if ((fds[0].revents & (POLLHUP | POLLERR)) != 0 ||
-                           (fds[1].revents & (POLLHUP | POLLERR)) != 0) {
-                               warning(errno, "poll");
-                               goto out;
-                       }
-                       if ((fds[0].revents & POLLIN) != 0 ||
-                           (fds[1].revents & POLLIN) != 0)
-                               break;
-               }
+               while (!revents)
+                       (void) sigsuspend(&set);
        }
 
        }
 
-out:
        warning(0, "Child unprivileged process exiting");
 }
 
        warning(0, "Child unprivileged process exiting");
 }
 
+/* ARGSUSED */
 static void
 child_sighandler(int sig)
 {
        modnode_t       *n;
 
        switch (sig) {
 static void
 child_sighandler(int sig)
 {
        modnode_t       *n;
 
        switch (sig) {
+       case SIGIO:
+               revents = true;
+               break;
        case SIGTERM:
                /* FALLTHROUGH */
        case SIGINT:
        case SIGTERM:
                /* FALLTHROUGH */
        case SIGINT:
@@ -1186,10 +1167,8 @@ queue_send(tap_t *tap)
                iov[0].iov_len = 14;
                iov[1].iov_base = &fn->frame->data[16];
                iov[1].iov_len = fn->frame->size - 16;
                iov[0].iov_len = 14;
                iov[1].iov_base = &fn->frame->data[16];
                iov[1].iov_len = fn->frame->size - 16;
-               while ((ret = writev(tap->fd, iov, 2)) == -1 &&
-                   errno == EINTR) ;
                /* On error leave pending frame on queue */
                /* On error leave pending frame on queue */
-               if (ret != fn->frame->size - 2)
+               if ((ret = writev(tap->fd, iov, 2)) != fn->frame->size - 2)
                        return false;
 
                count += fn->frame->size;
                        return false;
 
                count += fn->frame->size;
@@ -1224,9 +1203,7 @@ frame_receive(tap_t *tap)
                iov[0].iov_len = 14;
                iov[1].iov_base = &f->data[16];
                iov[1].iov_len = FRAMESIZE - 14;
                iov[0].iov_len = 14;
                iov[1].iov_base = &f->data[16];
                iov[1].iov_len = FRAMESIZE - 14;
-               while ((len = readv(tap->fd, iov, 2)) == -1
-                   && errno == EINTR) ;
-
+               len = readv(tap->fd, iov, 2);
                if (len == -1 || len == 0) {
                        (void) pool_free((pnode_t *)f);
                        return false;
                if (len == -1 || len == 0) {
                        (void) pool_free((pnode_t *)f);
                        return false;