X-Git-Url: http://www.dolda2000.com/gitweb/?p=ashd.git;a=blobdiff_plain;f=src%2Fplaintcp.c;h=de99dcddf872759db1bd011ffc50e018f1e5dce7;hp=cf46b29fd982925d3978d7bf90b3ab514ead8b05;hb=fc253e2fa06742656bd018981ec000799c956391;hpb=7595e3a4d77b7e498fa84e27d93cc9f680076561 diff --git a/src/plaintcp.c b/src/plaintcp.c index cf46b29..de99dcd 100644 --- a/src/plaintcp.c +++ b/src/plaintcp.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -64,10 +65,11 @@ int listensock4(int port) close(fd); return(-1); } - if(listen(fd, 16) < 0) { + if(listen(fd, 128) < 0) { close(fd); return(-1); } + fcntl(fd, F_SETFD, FD_CLOEXEC); return(fd); } @@ -88,10 +90,11 @@ int listensock6(int port) close(fd); return(-1); } - if(listen(fd, 16) < 0) { + if(listen(fd, 128) < 0) { close(fd); return(-1); } + fcntl(fd, F_SETFD, FD_CLOEXEC); return(fd); } @@ -147,13 +150,13 @@ void servetcp(struct muth *muth, va_list args) vavar(int, fd); vavar(struct sockaddr_storage, name); vavar(struct tcpport *, stcp); - FILE *in; + struct bufio *in; struct conn conn; struct tcpconn tcp; memset(&conn, 0, sizeof(conn)); memset(&tcp, 0, sizeof(tcp)); - in = mtstdopen(fd, 1, 60, "r+"); + in = mtbioopen(fd, 1, 60, "r+", NULL); conn.pdata = &tcp; conn.initreq = initreq; tcp.fd = fd; @@ -165,24 +168,39 @@ void servetcp(struct muth *muth, va_list args) static void listenloop(struct muth *muth, va_list args) { vavar(struct tcpport *, tcp); - int ns; + int i, ns, n; struct sockaddr_storage name; socklen_t namelen; + fcntl(tcp->fd, F_SETFL, fcntl(tcp->fd, F_GETFL) | O_NONBLOCK); while(1) { namelen = sizeof(name); - block(tcp->fd, EV_READ, 0); - ns = accept(tcp->fd, (struct sockaddr *)&name, &namelen); - if(ns < 0) { - flog(LOG_ERR, "accept: %s", strerror(errno)); + if(block(tcp->fd, EV_READ, 0) == 0) goto out; + n = 0; + while(1) { + ns = accept(tcp->fd, (struct sockaddr *)&name, &namelen); + if(ns < 0) { + if(errno == EAGAIN) + break; + if(errno == ECONNABORTED) + continue; + flog(LOG_ERR, "accept: %s", strerror(errno)); + goto out; + } + mustart(servetcp, ns, name, tcp); + if(++n >= 100) + break; } - mustart(servetcp, ns, name, tcp); } out: close(tcp->fd); free(tcp); + for(i = 0; i < listeners.d; i++) { + if(listeners.b[i] == muth) + bufdel(listeners, i); + } } void handleplain(int argc, char **argp, char **argv) @@ -212,7 +230,7 @@ void handleplain(int argc, char **argp, char **argv) omalloc(tcp); tcp->fd = fd; tcp->sport = port; - mustart(listenloop, tcp); + bufadd(listeners, mustart(listenloop, tcp)); if((fd = listensock4(port)) < 0) { if(errno != EADDRINUSE) { flog(LOG_ERR, "could not listen on IPv4 (port %i): %s", port, strerror(errno)); @@ -222,6 +240,6 @@ void handleplain(int argc, char **argp, char **argv) omalloc(tcp); tcp->fd = fd; tcp->sport = port; - mustart(listenloop, tcp); + bufadd(listeners, mustart(listenloop, tcp)); } }