1
0
mirror of git://projects.qi-hardware.com/openwrt-xburst.git synced 2024-11-24 01:43:08 +02:00

[package] uhttpd: protect tcp receive operations with select, make tcp keep-alive optional (#8272)

git-svn-id: svn://svn.openwrt.org/openwrt/trunk@24952 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
jow 2011-01-09 23:35:45 +00:00
parent 13ec8222a8
commit 6e21adc1e0
6 changed files with 56 additions and 24 deletions

View File

@ -8,7 +8,7 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=uhttpd PKG_NAME:=uhttpd
PKG_RELEASE:=20 PKG_RELEASE:=21
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
PKG_BUILD_DEPENDS := libcyassl liblua PKG_BUILD_DEPENDS := libcyassl liblua

View File

@ -51,6 +51,13 @@ config uhttpd main
# request process. # request process.
option network_timeout 30 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 # Basic auth realm, defaults to local hostname
# option realm OpenWrt # option realm OpenWrt

View File

@ -66,6 +66,7 @@ start_instance()
append_arg "$cfg" lua_handler "-L" append_arg "$cfg" lua_handler "-L"
append_arg "$cfg" script_timeout "-t" append_arg "$cfg" script_timeout "-t"
append_arg "$cfg" network_timeout "-T" append_arg "$cfg" network_timeout "-T"
append_arg "$cfg" tcp_keepalive "-A"
append_arg "$cfg" error_page "-E" append_arg "$cfg" error_page "-E"
append_arg "$cfg" index_page "-I" append_arg "$cfg" index_page "-I"

View File

@ -167,6 +167,9 @@ int uh_tcp_recv(struct client *cl, char *buf, int len)
int sz = 0; int sz = 0;
int rsz = 0; int rsz = 0;
fd_set reader;
struct timeval timeout;
/* first serve data from peek buffer */ /* first serve data from peek buffer */
if( cl->peeklen > 0 ) if( cl->peeklen > 0 )
{ {
@ -180,15 +183,28 @@ int uh_tcp_recv(struct client *cl, char *buf, int len)
/* caller wants more */ /* caller wants more */
if( len > 0 ) if( len > 0 )
{ {
#ifdef HAVE_TLS FD_ZERO(&reader);
if( cl->tls ) FD_SET(cl->socket, &reader);
rsz = cl->server->conf->tls_recv(cl, (void *)&buf[sz], len);
else
#endif
rsz = recv(cl->socket, (void *)&buf[sz], len, 0);
if( (sz == 0) || (rsz > 0) ) timeout.tv_sec = cl->server->conf->network_timeout;
sz += rsz; 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
#endif
rsz = recv(cl->socket, (void *)&buf[sz], len, 0);
if( (sz == 0) || (rsz > 0) )
sz += rsz;
}
else if( sz == 0 )
{
sz = -1;
}
} }
return sz; return sz;
@ -233,7 +249,7 @@ int uh_http_sendc(struct client *cl, const char *data, int len)
if( len > 0 ) 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, chunk, clen));
ensure_ret(uh_tcp_send(cl, data, len)); ensure_ret(uh_tcp_send(cl, data, len));
ensure_ret(uh_tcp_send(cl, "\r\n", 2)); ensure_ret(uh_tcp_send(cl, "\r\n", 2));

View File

@ -127,9 +127,7 @@ static int uh_socket_bind(
int status; int status;
int bound = 0; int bound = 0;
int tcp_ka_idl = 1; int tcp_ka_idl, tcp_ka_int, tcp_ka_cnt;
int tcp_ka_int = 1;
int tcp_ka_cnt = 3;
struct listener *l = NULL; struct listener *l = NULL;
struct addrinfo *addrs = NULL, *p = NULL; struct addrinfo *addrs = NULL, *p = NULL;
@ -157,13 +155,20 @@ static int uh_socket_bind(
} }
/* TCP keep-alive */ /* TCP keep-alive */
if( setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &yes, sizeof(yes)) || if( conf->tcp_keepalive > 0 )
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", tcp_ka_idl = 1;
strerror(errno)); 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 */ /* 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) int main (int argc, char **argv)
{ {
/* master file descriptor list */ /* master file descriptor list */
fd_set used_fds, serv_fds, read_fds; fd_set serv_fds;
/* working structs */ /* working structs */
struct addrinfo hints; struct addrinfo hints;
@ -650,10 +655,7 @@ int main (int argc, char **argv)
void *lib; void *lib;
#endif #endif
/* clear the master and temp sets */
FD_ZERO(&used_fds);
FD_ZERO(&serv_fds); FD_ZERO(&serv_fds);
FD_ZERO(&read_fds);
/* handle SIGPIPE, SIGINT, SIGTERM, SIGCHLD */ /* handle SIGPIPE, SIGINT, SIGTERM, SIGCHLD */
sa.sa_flags = 0; sa.sa_flags = 0;
@ -722,7 +724,7 @@ int main (int argc, char **argv)
#endif #endif
while( (opt = getopt(argc, argv, 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) switch(opt)
{ {
@ -896,6 +898,11 @@ int main (int argc, char **argv)
conf.network_timeout = atoi(optarg); conf.network_timeout = atoi(optarg);
break; break;
/* tcp keep-alive */
case 'A':
conf.tcp_keepalive = atoi(optarg);
break;
/* no fork */ /* no fork */
case 'f': case 'f':
nofork = 1; nofork = 1;

View File

@ -75,6 +75,7 @@ struct config {
int no_dirlists; int no_dirlists;
int network_timeout; int network_timeout;
int rfc1918_filter; int rfc1918_filter;
int tcp_keepalive;
#ifdef HAVE_CGI #ifdef HAVE_CGI
char *cgi_prefix; char *cgi_prefix;
#endif #endif