Merge branch 'fwd' 1.3.5
authorMark Wooding <mdw@distorted.org.uk>
Wed, 2 Apr 2008 09:02:05 +0000 (10:02 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Wed, 2 Apr 2008 09:02:05 +0000 (10:02 +0100)
* fwd:
  Rename entire project from `fw' to `fwd'.

Makefile.am
blast.c
fwd.1.in
socket.c

index eb33ab4..57b1a83 100644 (file)
@@ -24,6 +24,7 @@
 ### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
 bin_PROGRAMS            =
+noinst_PROGRAMS                 =
 man_MANS                =
 
 EXTRA_DIST              =
@@ -99,6 +100,13 @@ mantext.c: fwd.1.in make-manpage
        $(make_manpage) c >$@.new && mv $@.new $@
 
 ###--------------------------------------------------------------------------
+### The blast tool.
+
+noinst_PROGRAMS                += blast
+blast_SOURCES           = blast.c
+blast_LDADD             = $(mLib_LIBS)
+
+###--------------------------------------------------------------------------
 ### Other infrastructure.
 
 ## Set the release number.
diff --git a/blast.c b/blast.c
index 597263e..60ef0f7 100644 (file)
--- a/blast.c
+++ b/blast.c
@@ -112,13 +112,14 @@ static void newconn(blast *b)
     goto fail;
   gettimeofday(&tv, 0);
   TV_ADD(&tv, &tv, &ctv);
+  sel_addtimer(&sel, &b->t, &tv, timeout, b);
   if (conn_init(&b->c, &sel, fd, (struct sockaddr *)&sin, sizeof(sin),
                connected, b))
     goto fail;
-  sel_addtimer(&sel, &b->t, &tv, timeout, b);
   return;
 
 fail:
+  sel_rmtimer(&b->t);
   backoff(b);
 }
 
index d596b79..e5ecf6c 100644 (file)
--- a/fwd.1.in
+++ b/fwd.1.in
@@ -953,6 +953,24 @@ is given, is
 Socket sources support options; socket targets do not.  The source
 options provided are:
 .OS "Socket options"
+.BR socket. [ accept | accept-count ]
+.RB [ = ]
+.IR number | \c
+.B unlimited
+.OD
+Controls the number of connections that
+.B fw
+accepts at a time on a particular socket.  This parameter affects how
+.B fw
+prioritizes between keeping up with connection turnover and processing
+existing connections.  The default is 1, which strongly favours existing
+connections.  The special value
+.B unlimited
+(or
+.BR infinite )
+removes any limit, and therefore favours connection turnover.
+.OE
+.OS "Socket options"
 .B socket.conn
 .RB [ = ]
 .IR number | \c
index f8f8dec..518117c 100644 (file)
--- a/socket.c
+++ b/socket.c
@@ -34,9 +34,10 @@ typedef struct ssource_opts {
   unsigned opt;
   unsigned conn;
   unsigned listen;
+  unsigned naccept;
 } ssource_opts;
 
-static ssource_opts ssgo = { 256, 0, 5 };
+static ssource_opts ssgo = { 256, 0, 5, 1 };
 
 #define SOCKOPT_LIMIT 0u
 #define SOCKOPT_NOLIMIT 1u
@@ -290,6 +291,26 @@ static int ssource_option(source *s, scanner *sc)
     CONF_ACCEPT;
   }
 
+  if (strcmp(sc->d.buf, "accept") == 0 ||
+      strcmp(sc->d.buf, "accept-count") == 0) {
+    token(sc);
+    if (sc->t == '=')
+      token(sc);
+    if (sc->t != CTOK_WORD)
+      error(sc, "parse error, expected `unlimited' or number");
+    else if (isdigit((unsigned char)sc->d.buf[0])) {
+      sso->naccept = atoi(sc->d.buf);
+      if (sso->naccept == 0)
+       error(sc, "argument of `accept-count' must be positive");
+    } else {
+      sso->naccept = 0;
+      conf_enum(sc, "unlimited,infinite",
+               ENUM_ABBREV, "`accept-count' option");
+    }
+    token(sc);
+    CONF_ACCEPT;
+  }
+
   if (strcmp(sc->d.buf, "logging") == 0 ||
       strcmp(sc->d.buf, "log") == 0) {
     addr_opts *ao = ss ? ss->ao : &gsao;
@@ -335,10 +356,9 @@ static source *ssource_read(scanner *sc)
   ss->a = getaddr(sc, ADDR_SRC);
   if (ss->a->ops->initsrcopts)
     ss->ao = ss->a->ops->initsrcopts();
-  else {
+  else
     ss->ao = CREATE(addr_opts);
-    *ss->ao = gsao;
-  }
+  *ss->ao = gsao;
   ss->o = ssgo;
   return (&ss->s);
 }
@@ -363,66 +383,79 @@ static void ss_accept(int fd, unsigned mode, void *p)
   ssept *e;
   endpt *ee;
   reffd *r;
+  int acceptp = 1;
+  unsigned i = 0;
 
-  /* --- Make the file descriptor --- */
+  while (acceptp) {
 
-  {
-    int opt = 1;
-    if ((r = ss->a->ops->accept(fd, ss->ao, ss->s.desc)) == 0)
-      return;
-    setsockopt(r->fd, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(opt));
-    fdflags(r->fd, O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC);
-  }
-
-  /* --- Make an endpoint --- */
+    /* --- Make the file descriptor --- */
 
-  e = CREATE(ssept);
-  e->e.ops = &ssept_ops;
-  e->e.other = 0;
-  e->e.f = EPF_FILE;
-  e->e.t = 0;
-  e->e.in = e->e.out = r;
-  e->s = ss;
-  REFFD_INC(r);
+    {
+      int opt = 1;
+      if ((r = ss->a->ops->accept(fd, ss->ao, ss->s.desc)) == 0)
+       return;
+      setsockopt(r->fd, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(opt));
+      fdflags(r->fd, O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC);
+    }
 
-  /* --- Obtain the target endpoint and let rip --- */
+    /* --- Make an endpoint --- */
 
-  if ((ee = ss->t->ops->create(ss->t, ss->s.desc)) == 0) {
-    REFFD_DEC(r);
-    REFFD_DEC(r);
-    DESTROY(e);
-    return;
-  }
-  fw_inc();
+    e = CREATE(ssept);
+    e->e.ops = &ssept_ops;
+    e->e.other = 0;
+    e->e.f = EPF_FILE;
+    e->e.t = 0;
+    e->e.in = e->e.out = r;
+    e->s = ss;
+    REFFD_INC(r);
 
-  /* --- Remove the listening socket if necessary --- */
+    /* --- Obtain the target endpoint and let rip --- */
 
-  switch (ss->o.opt) {
-    case SOCKOPT_LIMIT:
-      ss->o.conn--;
-      if (!ss->o.conn) {
-       if (!(ss->ao->f & ADDRF_NOLOG))
-         fw_log(-1, "[%s] maximum connections reached", ss->s.desc);
+    if ((ee = ss->t->ops->create(ss->t, ss->s.desc)) == 0) {
+      REFFD_DEC(r);
+      REFFD_DEC(r);
+      DESTROY(e);
+      return;
+    }
+    fw_inc();
+
+    /* --- Note that we've done one --- */
+
+    i++;
+    if (i >= ss->o.naccept)
+      acceptp = 0;
+
+    /* --- Remove the listening socket if necessary --- */
+
+    switch (ss->o.opt) {
+      case SOCKOPT_LIMIT:
+       ss->o.conn--;
+       if (!ss->o.conn) {
+         if (!(ss->ao->f & ADDRF_NOLOG))
+           fw_log(-1, "[%s] maximum connections reached", ss->s.desc);
+         sel_rmfile(&ss->r);
+         close(ss->r.fd);
+         if (ss->a->ops->unbind)
+           ss->a->ops->unbind(ss->a);
+         acceptp = 0;
+       }
+       break;
+      case SOCKOPT_NOLIMIT:
+       break;
+      case SOCKOPT_ONESHOT:
        sel_rmfile(&ss->r);
        close(ss->r.fd);
        if (ss->a->ops->unbind)
          ss->a->ops->unbind(ss->a);
-      }
-      break;
-    case SOCKOPT_NOLIMIT:
-      break;
-    case SOCKOPT_ONESHOT:
-      sel_rmfile(&ss->r);
-      close(ss->r.fd);
-      if (ss->a->ops->unbind)
-       ss->a->ops->unbind(ss->a);
-      ssource_destroy(&ss->s);
-      break;
-  }
+       ssource_destroy(&ss->s);
+       acceptp = 0;
+       break;
+    }
 
-  /* --- Let everything else happen --- */
+    /* --- Let everything else happen --- */
 
-  endpt_join(&e->e, ee);
+    endpt_join(&e->e, ee);
+  }
 }
 
 /* --- @ss_listen@ --- *