X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fuhttpd.git;a=blobdiff_plain;f=listen.c;h=f11768ae1bfbba2ec2e72536fc817121228053b9;hp=7e59d1dc4673280391b0a6af1b31f192c8abe8cf;hb=cf9c6c30f1328f8804f55896b3fcfcd1f5ae0212;hpb=54443d7f29f03987879b8f374a88cc7ea7599609 diff --git a/listen.c b/listen.c index 7e59d1d..f11768a 100644 --- a/listen.c +++ b/listen.c @@ -37,6 +37,14 @@ struct listener { static LIST_HEAD(listeners); static int n_blocked; +void uh_close_listen_fds(void) +{ + struct listener *l; + + list_for_each_entry(l, &listeners, list) + close(l->fd.fd); +} + static void uh_block_listener(struct listener *l) { uloop_fd_delete(&l->fd); @@ -48,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; @@ -56,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); @@ -66,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); @@ -75,8 +90,28 @@ static void listener_cb(struct uloop_fd *fd, unsigned int events) void uh_setup_listeners(void) { struct listener *l; + int yes = 1; list_for_each_entry(l, &listeners, list) { + int sock = l->fd.fd; + + /* TCP keep-alive */ + if (conf.tcp_keepalive > 0) { +#ifdef linux + int tcp_ka_idl, tcp_ka_int, tcp_ka_cnt; + + tcp_ka_idl = 1; + tcp_ka_cnt = 3; + tcp_ka_int = conf.tcp_keepalive; + + setsockopt(sock, SOL_TCP, TCP_KEEPIDLE, &tcp_ka_idl, sizeof(tcp_ka_idl)); + setsockopt(sock, SOL_TCP, TCP_KEEPINTVL, &tcp_ka_int, sizeof(tcp_ka_int)); + setsockopt(sock, SOL_TCP, TCP_KEEPCNT, &tcp_ka_cnt, sizeof(tcp_ka_cnt)); +#endif + + setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &yes, sizeof(yes)); + } + l->fd.cb = listener_cb; uloop_fd_add(&l->fd, ULOOP_READ); } @@ -98,7 +133,7 @@ int uh_socket_bind(const char *host, const char *port, bool tls) if ((status = getaddrinfo(host, port, &hints, &addrs)) != 0) { fprintf(stderr, "getaddrinfo(): %s\n", gai_strerror(status)); - return -1; + return 0; } /* try to bind a new socket to each found address */ @@ -116,25 +151,6 @@ int uh_socket_bind(const char *host, const char *port, bool tls) goto error; } - /* TCP keep-alive */ - if (conf.tcp_keepalive > 0) { - int ret = 0; -#ifdef linux - int tcp_ka_idl, tcp_ka_int, tcp_ka_cnt; - - tcp_ka_idl = 1; - tcp_ka_cnt = 3; - tcp_ka_int = conf.tcp_keepalive; - ret = setsockopt(sock, SOL_TCP, TCP_KEEPIDLE, &tcp_ka_idl, sizeof(tcp_ka_idl)) || - setsockopt(sock, SOL_TCP, TCP_KEEPINTVL, &tcp_ka_int, sizeof(tcp_ka_int)) || - setsockopt(sock, SOL_TCP, TCP_KEEPCNT, &tcp_ka_cnt, sizeof(tcp_ka_cnt)); -#endif - - if (ret || setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &yes, sizeof(yes))) - fprintf(stderr, "Notice: Unable to enable TCP keep-alive: %s\n", - strerror(errno)); - } - /* required to get parallel v4 + v6 working */ if (p->ai_family == AF_INET6 && setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof(yes)) < 0) { @@ -163,6 +179,7 @@ int uh_socket_bind(const char *host, const char *port, bool tls) l->fd.fd = sock; l->tls = tls; list_add_tail(&l->list, &listeners); + bound++; continue;