fix resuming accept() calls after exceeding client limit
authorFelix Fietkau <nbd@openwrt.org>
Fri, 4 Jan 2013 00:15:08 +0000 (01:15 +0100)
committerFelix Fietkau <nbd@openwrt.org>
Fri, 4 Jan 2013 00:15:08 +0000 (01:15 +0100)
client.c
listen.c
uhttpd.h

index 79201022a56fce1ce2ea7fc846b206d3d7bafc72..dd3f912247a500a58b3f9de0810ce25262444d93 100644 (file)
--- a/client.c
+++ b/client.c
@@ -438,7 +438,7 @@ static void set_addr(struct uh_addr *addr, void *src)
        }
 }
 
-void uh_accept_client(int fd)
+bool uh_accept_client(int fd)
 {
        static struct client *next_client;
        struct client *cl;
@@ -455,7 +455,7 @@ void uh_accept_client(int fd)
        sl = sizeof(addr);
        sfd = accept(fd, (struct sockaddr *) &addr, &sl);
        if (sfd < 0)
-               return;
+               return false;
 
        set_addr(&cl->peer_addr, &addr);
        sl = sizeof(addr);
@@ -476,6 +476,7 @@ void uh_accept_client(int fd)
        next_client = NULL;
        n_clients++;
        cl->id = client_id++;
+       return true;
 }
 
 void uh_close_fds(void)
index c4b6b2bb9faeab050ade6e257e04f463bfd3908e..f11768ae1bfbba2ec2e72536fc817121228053b9 100644 (file)
--- a/listen.c
+++ b/listen.c
@@ -56,7 +56,7 @@ void uh_unblock_listeners(void)
 {
        struct listener *l;
 
-       if (!n_blocked && conf.max_requests &&
+       if ((!n_blocked && conf.max_requests) ||
            n_clients >= conf.max_requests)
                return;
 
@@ -64,6 +64,10 @@ void uh_unblock_listeners(void)
                if (!l->blocked)
                        continue;
 
+               l->fd.cb(&l->fd, ULOOP_READ);
+           if (n_clients >= conf.max_requests)
+                       break;
+
                n_blocked--;
                l->blocked = false;
                uloop_fd_add(&l->fd, ULOOP_READ);
@@ -74,7 +78,10 @@ static void listener_cb(struct uloop_fd *fd, unsigned int events)
 {
        struct listener *l = container_of(fd, struct listener, fd);
 
-       uh_accept_client(fd->fd);
+       while (1) {
+               if (!uh_accept_client(fd->fd))
+                       break;
+       }
 
        if (conf.max_requests && n_clients >= conf.max_requests)
                uh_block_listener(l);
index a9777e86e26e8cc30ad83c3a939f16d622a6ccbf..d67e48c14712fd9fcb2dcf59e466d264ef312e1b 100644 (file)
--- a/uhttpd.h
+++ b/uhttpd.h
@@ -192,7 +192,7 @@ extern struct dispatch_handler cgi_dispatch;
 
 void uh_index_add(const char *filename);
 
-void uh_accept_client(int fd);
+bool uh_accept_client(int fd);
 
 void uh_unblock_listeners(void);
 void uh_setup_listeners(void);