diff options
| -rw-r--r-- | package/uhttpd/Makefile | 2 | ||||
| -rw-r--r-- | package/uhttpd/files/uhttpd.config | 7 | ||||
| -rwxr-xr-x | package/uhttpd/files/uhttpd.init | 1 | ||||
| -rw-r--r-- | package/uhttpd/src/uhttpd-utils.c | 30 | ||||
| -rw-r--r-- | package/uhttpd/src/uhttpd.c | 35 | ||||
| -rw-r--r-- | package/uhttpd/src/uhttpd.h | 1 | 
6 files changed, 54 insertions, 22 deletions
| diff --git a/package/uhttpd/Makefile b/package/uhttpd/Makefile index a0b7d24eb..bba7ac53a 100644 --- a/package/uhttpd/Makefile +++ b/package/uhttpd/Makefile @@ -8,7 +8,7 @@  include $(TOPDIR)/rules.mk  PKG_NAME:=uhttpd -PKG_RELEASE:=20 +PKG_RELEASE:=21  PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)  PKG_BUILD_DEPENDS := libcyassl liblua diff --git a/package/uhttpd/files/uhttpd.config b/package/uhttpd/files/uhttpd.config index a29910a65..08ca5e5e0 100644 --- a/package/uhttpd/files/uhttpd.config +++ b/package/uhttpd/files/uhttpd.config @@ -51,6 +51,13 @@ config uhttpd main  	# request process.  	option network_timeout	30 +	# TCP Keep-Alive, send periodic keep-alive probes +	# over established connections to detect dead peers. +	# The value is given in seconds to specify the +	# interval between subsequent probes. +	# Setting this to 0 will disable TCP keep-alive. +	option tcp_keepalive	1 +  	# Basic auth realm, defaults to local hostname  #	option realm	OpenWrt diff --git a/package/uhttpd/files/uhttpd.init b/package/uhttpd/files/uhttpd.init index f8f1754e9..069e16fff 100755 --- a/package/uhttpd/files/uhttpd.init +++ b/package/uhttpd/files/uhttpd.init @@ -66,6 +66,7 @@ start_instance()  	append_arg "$cfg" lua_handler "-L"  	append_arg "$cfg" script_timeout "-t"  	append_arg "$cfg" network_timeout "-T" +	append_arg "$cfg" tcp_keepalive "-A"  	append_arg "$cfg" error_page "-E"  	append_arg "$cfg" index_page "-I" diff --git a/package/uhttpd/src/uhttpd-utils.c b/package/uhttpd/src/uhttpd-utils.c index c7bc867aa..ac00af824 100644 --- a/package/uhttpd/src/uhttpd-utils.c +++ b/package/uhttpd/src/uhttpd-utils.c @@ -167,6 +167,9 @@ int uh_tcp_recv(struct client *cl, char *buf, int len)  	int sz = 0;  	int rsz = 0; +	fd_set reader; +	struct timeval timeout; +  	/* first serve data from peek buffer */  	if( cl->peeklen > 0 )  	{ @@ -180,15 +183,28 @@ int uh_tcp_recv(struct client *cl, char *buf, int len)  	/* caller wants more */  	if( len > 0 )  	{ +		FD_ZERO(&reader); +		FD_SET(cl->socket, &reader); + +		timeout.tv_sec  = cl->server->conf->network_timeout; +		timeout.tv_usec = 0; + +		if( select(cl->socket + 1, &reader, NULL, NULL, &timeout) > 0 ) +		{  #ifdef HAVE_TLS -		if( cl->tls ) -			rsz = cl->server->conf->tls_recv(cl, (void *)&buf[sz], len); -		else +			if( cl->tls ) +				rsz = cl->server->conf->tls_recv(cl, (void *)&buf[sz], len); +			else  #endif -			rsz = recv(cl->socket, (void *)&buf[sz], len, 0); +				rsz = recv(cl->socket, (void *)&buf[sz], len, 0); -		if( (sz == 0) || (rsz > 0) ) -			sz += rsz; +			if( (sz == 0) || (rsz > 0) ) +				sz += rsz; +		} +		else if( sz == 0 ) +		{ +			sz = -1; +		}  	}  	return sz; @@ -233,7 +249,7 @@ int uh_http_sendc(struct client *cl, const char *data, int len)  	if( len > 0 )  	{ -	 	clen = snprintf(chunk, sizeof(chunk), "%X\r\n", len); +		clen = snprintf(chunk, sizeof(chunk), "%X\r\n", len);  		ensure_ret(uh_tcp_send(cl, chunk, clen));  		ensure_ret(uh_tcp_send(cl, data, len));  		ensure_ret(uh_tcp_send(cl, "\r\n", 2)); diff --git a/package/uhttpd/src/uhttpd.c b/package/uhttpd/src/uhttpd.c index 2c7755f8d..1fd21344f 100644 --- a/package/uhttpd/src/uhttpd.c +++ b/package/uhttpd/src/uhttpd.c @@ -127,9 +127,7 @@ static int uh_socket_bind(  	int status;  	int bound = 0; -	int tcp_ka_idl = 1; -	int tcp_ka_int = 1; -	int tcp_ka_cnt = 3; +	int tcp_ka_idl, tcp_ka_int, tcp_ka_cnt;  	struct listener *l = NULL;  	struct addrinfo *addrs = NULL, *p = NULL; @@ -157,13 +155,20 @@ static int uh_socket_bind(  		}  		/* TCP keep-alive */ -		if( setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &yes, sizeof(yes)) || -		    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)) ) +		if( conf->tcp_keepalive > 0 )  		{ -		    fprintf(stderr, "Notice: Unable to enable TCP keep-alive: %s\n", -		    	strerror(errno)); +			tcp_ka_idl = 1; +			tcp_ka_cnt = 3; +			tcp_ka_int = conf->tcp_keepalive; + +			if( setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &yes, sizeof(yes)) || +			    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)) ) +			{ +			    fprintf(stderr, "Notice: Unable to enable TCP keep-alive: %s\n", +			    	strerror(errno)); +			}  		}  		/* required to get parallel v4 + v6 working */ @@ -619,7 +624,7 @@ static void uh_mainloop(struct config *conf, fd_set serv_fds, int max_fd)  int main (int argc, char **argv)  {  	/* master file descriptor list */ -	fd_set used_fds, serv_fds, read_fds; +	fd_set serv_fds;  	/* working structs */  	struct addrinfo hints; @@ -650,10 +655,7 @@ int main (int argc, char **argv)  	void *lib;  #endif -	/* clear the master and temp sets */ -	FD_ZERO(&used_fds);  	FD_ZERO(&serv_fds); -	FD_ZERO(&read_fds);  	/* handle SIGPIPE, SIGINT, SIGTERM, SIGCHLD */  	sa.sa_flags = 0; @@ -722,7 +724,7 @@ int main (int argc, char **argv)  #endif  	while( (opt = getopt(argc, argv, -		"fSDRC:K:E:I:p:s:h:c:l:L:d:r:m:x:i:t:T:")) > 0 +		"fSDRC:K:E:I:p:s:h:c:l:L:d:r:m:x:i:t:T:A:")) > 0  	) {  		switch(opt)  		{ @@ -896,6 +898,11 @@ int main (int argc, char **argv)  				conf.network_timeout = atoi(optarg);  				break; +			/* tcp keep-alive */ +			case 'A': +				conf.tcp_keepalive = atoi(optarg); +				break; +  			/* no fork */  			case 'f':  				nofork = 1; diff --git a/package/uhttpd/src/uhttpd.h b/package/uhttpd/src/uhttpd.h index 6747b905f..ff058d62b 100644 --- a/package/uhttpd/src/uhttpd.h +++ b/package/uhttpd/src/uhttpd.h @@ -75,6 +75,7 @@ struct config {  	int no_dirlists;  	int network_timeout;  	int rfc1918_filter; +	int tcp_keepalive;  #ifdef HAVE_CGI  	char *cgi_prefix;  #endif | 
