X-Git-Url: https://git.rohieb.name/openwrt.git/blobdiff_plain/8618e98eabec2b5677698daa631f195cae92c30b..4b388ef792899cff8640179064a0885d335004eb:/package/uhttpd/src/uhttpd.c diff --git a/package/uhttpd/src/uhttpd.c b/package/uhttpd/src/uhttpd.c index 6f5e61634..3563d91d1 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 */ @@ -339,8 +344,8 @@ static struct http_request * uh_http_header_parse(struct client *cl, char *buffe hdrdata = &buffer[i+2]; } - /* have no name and found [A-Z], start of name */ - else if( !hdrname && isalpha(buffer[i]) && isupper(buffer[i]) ) + /* have no name and found [A-Za-z], start of name */ + else if( !hdrname && isalpha(buffer[i]) ) { hdrname = &buffer[i]; } @@ -401,6 +406,10 @@ static struct http_request * uh_http_header_recv(struct client *cl) { ensure_out(rlen = uh_tcp_recv(cl, bufptr, rlen)); + /* unexpected eof - #7904 */ + if( rlen == 0 ) + return NULL; + blen -= rlen; bufptr += rlen; } @@ -503,7 +512,22 @@ static void uh_mainloop(struct config *conf, fd_set serv_fds, int max_fd) #ifdef HAVE_TLS /* setup client tls context */ if( conf->tls ) - conf->tls_accept(cl); + { + if( conf->tls_accept(cl) < 1 ) + { + fprintf(stderr, + "tls_accept failed, " + "connection dropped\n"); + + /* close client socket */ + close(new_fd); + + /* remove from global client list */ + uh_client_remove(new_fd); + + continue; + } + } #endif /* add client socket to global fdset */ @@ -562,7 +586,7 @@ static void uh_mainloop(struct config *conf, fd_set serv_fds, int max_fd) if( (pin = uh_path_lookup(cl, req->url)) != NULL ) { /* auth ok? */ - if( uh_auth_check(cl, req, pin) ) + if( !pin->redirected && uh_auth_check(cl, req, pin) ) uh_dispatch_request(cl, req, pin); } @@ -611,11 +635,61 @@ static void uh_mainloop(struct config *conf, fd_set serv_fds, int max_fd) #endif } +#ifdef HAVE_TLS +static inline int uh_inittls(struct config *conf) +{ + /* library handle */ + void *lib; + + /* already loaded */ + if( conf->tls != NULL ) + return 0; + + /* load TLS plugin */ + if( ! (lib = dlopen("uhttpd_tls.so", RTLD_LAZY | RTLD_GLOBAL)) ) + { + fprintf(stderr, + "Notice: Unable to load TLS plugin - disabling SSL support! " + "(Reason: %s)\n", dlerror() + ); + + return 1; + } + else + { + /* resolve functions */ + if( !(conf->tls_init = dlsym(lib, "uh_tls_ctx_init")) || + !(conf->tls_cert = dlsym(lib, "uh_tls_ctx_cert")) || + !(conf->tls_key = dlsym(lib, "uh_tls_ctx_key")) || + !(conf->tls_free = dlsym(lib, "uh_tls_ctx_free")) || + !(conf->tls_accept = dlsym(lib, "uh_tls_client_accept")) || + !(conf->tls_close = dlsym(lib, "uh_tls_client_close")) || + !(conf->tls_recv = dlsym(lib, "uh_tls_client_recv")) || + !(conf->tls_send = dlsym(lib, "uh_tls_client_send")) + ) { + fprintf(stderr, + "Error: Failed to lookup required symbols " + "in TLS plugin: %s\n", dlerror() + ); + exit(1); + } + + /* init SSL context */ + if( ! (conf->tls = conf->tls_init()) ) + { + fprintf(stderr, "Error: Failed to initalize SSL context\n"); + exit(1); + } + } + + return 0; +} +#endif 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; @@ -641,15 +715,12 @@ int main (int argc, char **argv) char bind[128]; char *port = NULL; -#if defined(HAVE_TLS) || defined(HAVE_LUA) +#ifdef HAVE_LUA /* library handle */ 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; @@ -680,45 +751,9 @@ int main (int argc, char **argv) memset(&conf, 0, sizeof(conf)); memset(bind, 0, sizeof(bind)); -#ifdef HAVE_TLS - /* load TLS plugin */ - if( ! (lib = dlopen("uhttpd_tls.so", RTLD_LAZY | RTLD_GLOBAL)) ) - { - fprintf(stderr, - "Notice: Unable to load TLS plugin - disabling SSL support! " - "(Reason: %s)\n", dlerror() - ); - } - else - { - /* resolve functions */ - if( !(conf.tls_init = dlsym(lib, "uh_tls_ctx_init")) || - !(conf.tls_cert = dlsym(lib, "uh_tls_ctx_cert")) || - !(conf.tls_key = dlsym(lib, "uh_tls_ctx_key")) || - !(conf.tls_free = dlsym(lib, "uh_tls_ctx_free")) || - !(conf.tls_accept = dlsym(lib, "uh_tls_client_accept")) || - !(conf.tls_close = dlsym(lib, "uh_tls_client_close")) || - !(conf.tls_recv = dlsym(lib, "uh_tls_client_recv")) || - !(conf.tls_send = dlsym(lib, "uh_tls_client_send")) - ) { - fprintf(stderr, - "Error: Failed to lookup required symbols " - "in TLS plugin: %s\n", dlerror() - ); - exit(1); - } - - /* init SSL context */ - if( ! (conf.tls = conf.tls_init()) ) - { - fprintf(stderr, "Error: Failed to initalize SSL context\n"); - exit(1); - } - } -#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) { @@ -744,7 +779,7 @@ int main (int argc, char **argv) #ifdef HAVE_TLS if( opt == 's' ) { - if( !conf.tls ) + if( uh_inittls(&conf) ) { fprintf(stderr, "Notice: TLS support is disabled, " @@ -769,7 +804,7 @@ int main (int argc, char **argv) #ifdef HAVE_TLS /* certificate */ case 'C': - if( conf.tls ) + if( !uh_inittls(&conf) ) { if( conf.tls_cert(conf.tls, optarg) < 1 ) { @@ -785,7 +820,7 @@ int main (int argc, char **argv) /* key */ case 'K': - if( conf.tls ) + if( !uh_inittls(&conf) ) { if( conf.tls_key(conf.tls, optarg) < 1 ) { @@ -892,6 +927,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; @@ -901,8 +941,14 @@ int main (int argc, char **argv) case 'd': if( (port = malloc(strlen(optarg)+1)) != NULL ) { + /* "decode" plus to space to retain compat */ + for (opt = 0; optarg[opt]; opt++) + if (optarg[opt] == '+') + optarg[opt] = ' '; + memset(port, 0, strlen(optarg)+1); uh_urldecode(port, strlen(optarg), optarg, strlen(optarg)); + printf("%s", port); free(port); exit(0); @@ -1085,4 +1131,3 @@ int main (int argc, char **argv) return 0; } -