* khttpd rotten? @ 2002-05-06 0:28 Dan Kegel 2002-05-06 2:14 ` David S. Miller 0 siblings, 1 reply; 35+ messages in thread From: Dan Kegel @ 2002-05-06 0:28 UTC (permalink / raw) To: khttpd-users@lists.alt.org, linux-kernel@vger.kernel.org On vanilla 2.4.17, 2.4.18, and 2.4.19-pre8, I'm seeing some mighty strange khttpd behavior. It's chewing CPU time, failing in mysterious ways under light or no load, and oopsing easily. I'm compiling a writeup at http://www.kegel.com/linux/khttpd/ and it just keeps getting worse. It looks like you have to 1) turn on sloppymime, 2) never restart it, and 3) run with only 1 thread to have any hope of stability -- and even then, abruptly terminating client connections causes an oops fairly frequently. If I didn't need it for a demo this week (don't ask), I wouldn't be messing with khttpd; I'd be switching to Tux. Seems like it's time to either fix khttpd or pull it from the kernel. What was the last kernel version where khttpd was stable (if any)? - Dan ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: khttpd rotten? 2002-05-06 0:28 khttpd rotten? Dan Kegel @ 2002-05-06 2:14 ` David S. Miller 2002-05-06 2:39 ` Dan Kegel 2002-05-09 11:40 ` khttpd rotten? john slee 0 siblings, 2 replies; 35+ messages in thread From: David S. Miller @ 2002-05-06 2:14 UTC (permalink / raw) To: dank; +Cc: khttpd-users, linux-kernel From: Dan Kegel <dank@kegel.com> Date: Sun, 05 May 2002 17:28:37 -0700 If I didn't need it for a demo this week (don't ask), I wouldn't be messing with khttpd; I'd be switching to Tux. Seems like it's time to either fix khttpd or pull it from the kernel. We are going to pull it from the kernel. The only argument is whether to replace it with TUX or not. There is a lot of compelling evidence that suggests that reasonably close performance can be obtained in userspace. I guess the decision on TUX is not a prerequisite for pulling khttpd though. ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: khttpd rotten? 2002-05-06 2:14 ` David S. Miller @ 2002-05-06 2:39 ` Dan Kegel 2002-05-06 10:23 ` Christoph Hellwig 2002-05-06 14:17 ` Tux in main kernel tree? (was khttpd rotten?) Roy Sigurd Karlsbakk 2002-05-09 11:40 ` khttpd rotten? john slee 1 sibling, 2 replies; 35+ messages in thread From: Dan Kegel @ 2002-05-06 2:39 UTC (permalink / raw) To: David S. Miller; +Cc: khttpd-users, linux-kernel "David S. Miller" wrote: > > From: Dan Kegel <dank@kegel.com> > Date: Sun, 05 May 2002 17:28:37 -0700 > > If I didn't need it for a demo this week (don't ask), I > wouldn't be messing with khttpd; I'd be switching to Tux. > > Seems like it's time to either fix khttpd or pull it from the kernel. > > We are going to pull it from the kernel. > > The only argument is whether to replace it with TUX or not. > There is a lot of compelling evidence that suggests that > reasonably close performance can be obtained in userspace. > > I guess the decision on TUX is not a prerequisite for pulling > khttpd though. Right. If khttpd had been pulled from 2.4.17, I would have had weeks of warning that khttpd is unstable; instead, I learned only when someone started doing his own stress testing, and I have little time to fix it. I say pull it from 2.4.19-pre9. Marcello, put it out of its misery asap, please... it'd time for khttpd to become a standalone patch again. - Dan ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: khttpd rotten? 2002-05-06 2:39 ` Dan Kegel @ 2002-05-06 10:23 ` Christoph Hellwig 2002-05-06 11:28 ` [PATCH] " Dan Kegel ` (2 more replies) 2002-05-06 14:17 ` Tux in main kernel tree? (was khttpd rotten?) Roy Sigurd Karlsbakk 1 sibling, 3 replies; 35+ messages in thread From: Christoph Hellwig @ 2002-05-06 10:23 UTC (permalink / raw) To: Dan Kegel; +Cc: David S. Miller, arjanv, marcelo, khttpd-users, linux-kernel On Sun, May 05, 2002 at 07:39:42PM -0700, Dan Kegel wrote: > > We are going to pull it from the kernel. > > Right. If khttpd had been pulled from 2.4.17, I would have > had weeks of warning that khttpd is unstable; instead, I learned > only when someone started doing his own stress testing, and I > have little time to fix it. I say pull it from > 2.4.19-pre9. Marcello, put it out of its misery asap, please... > it'd time for khttpd to become a standalone patch again. Okay, what about the following: - the below patch remove khttpd from 2.4.19-pre, but lets the sysctls in so it can compile out-of-tree - http://verein.lst.de/~hch/khttpd/khttpd-20020506.tar.gz has a tarball with khttpd as of 2.4.19-pre8, a simple makefile to build it and a simple patch to allow loading it when CONFIG_IPV6 != m, Arjan, could you please put it on the official khttpd website if one still exists. - for 2.5 the sysctls can go aswell diff -uNr -Xdontdiff linux-2.4.19-pre8/Documentation/Configure.help linux/Documentation/Configure.help --- linux-2.4.19-pre8/Documentation/Configure.help Fri May 3 23:02:47 2002 +++ linux/Documentation/Configure.help Mon May 6 13:05:24 2002 @@ -5406,25 +5406,6 @@ say Y to "Kernel/User network link driver" and to "Routing messages" instead. -Kernel httpd acceleration -CONFIG_KHTTPD - The kernel httpd acceleration daemon (kHTTPd) is a (limited) web - server built into the kernel. It is limited since it can only serve - files from the file system and cannot deal with executable content - such as CGI scripts. Serving files is sped up if you use kHTTPd. - If kHTTPd is not able to fulfill a request, it can transparently - pass it through to a user space web server such as apache. - - Saying "M" here builds the kHTTPd module; this is NOT enough to have - a working kHTTPd. For safety reasons, the module has to be activated - by doing a "echo 1 > /proc/sys/net/khttpd/start" after inserting the - module. - - Before using this, read the README in net/khttpd ! - - The kHTTPd is experimental. Be careful when using it on a production - machine. Also note that kHTTPd doesn't support virtual servers yet. - The IPX protocol CONFIG_IPX This is support for the Novell networking protocol, IPX, commonly @@ -25233,7 +25214,7 @@ # LocalWords: Unixware cymru Computone IntelliPort Intelliport computone SI sx # LocalWords: adbmouse DRI DRM dlabs GMX PLCs Applicom fieldbus applicom int # LocalWords: VWSND eg ESSSOLO CFU CFNR scribed eiconctrl eicon hylafax KFPU -# LocalWords: EXTRAPREC fpu mainboards KHTTPD kHTTPd khttpd Xcelerator SBNI tw +# LocalWords: EXTRAPREC fpu mainboards Xcelerator SBNI tw # LocalWords: LOGIBUSMOUSE Granch granch sbni Raylink NOHIGHMEM Athlon SIM sim # LocalWords: hpl Tourrilhes DuraLAN starfire Davicom davicom dmfe auk tms tr # LocalWords: TokenExpress Belkin Peracom eTek DVDs infradead Cxxx Adlib AV ZX diff -uNr -Xdontdiff linux-2.4.19-pre8/Makefile linux/Makefile --- linux-2.4.19-pre8/Makefile Fri May 3 23:02:46 2002 +++ linux/Makefile Mon May 6 13:05:36 2002 @@ -214,8 +214,6 @@ drivers/scsi/aic7xxx/aicasm/aicdb.h \ drivers/scsi/aic7xxx/aicasm/y.tab.h \ drivers/scsi/53c700_d.h \ - net/khttpd/make_times_h \ - net/khttpd/times.h \ submenu* # directories removed with 'make clean' CLEAN_DIRS = \ diff -uNr -Xdontdiff linux-2.4.19-pre8/include/linux/sysctl.h linux/include/linux/sysctl.h --- linux-2.4.19-pre8/include/linux/sysctl.h Fri May 3 23:02:46 2002 +++ linux/include/linux/sysctl.h Mon May 6 13:06:25 2002 @@ -487,6 +487,8 @@ }; /* /proc/sys/net/khttpd/ */ +/* khttpd has been removed from the main kernel. + please keep this to allow out-of-tree compilation for 2.4. --hch */ enum { NET_KHTTPD_DOCROOT = 1, NET_KHTTPD_START = 2, diff -uNr -Xdontdiff linux-2.4.19-pre8/net/Config.in linux/net/Config.in --- linux-2.4.19-pre8/net/Config.in Fri May 3 13:36:27 2002 +++ linux/net/Config.in Mon May 6 12:54:18 2002 @@ -26,9 +26,6 @@ source net/ipv6/Config.in fi fi - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - source net/khttpd/Config.in - fi fi if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then bool 'Asynchronous Transfer Mode (ATM) (EXPERIMENTAL)' CONFIG_ATM diff -uNr -Xdontdiff linux-2.4.19-pre8/net/Makefile linux/net/Makefile --- linux-2.4.19-pre8/net/Makefile Fri May 3 13:37:42 2002 +++ linux/net/Makefile Mon May 6 12:54:10 2002 @@ -26,7 +26,6 @@ endif endif -subdir-$(CONFIG_KHTTPD) += khttpd subdir-$(CONFIG_PACKET) += packet subdir-$(CONFIG_NET_SCHED) += sched subdir-$(CONFIG_BRIDGE) += bridge diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/Config.in linux/net/khttpd/Config.in --- linux-2.4.19-pre8/net/khttpd/Config.in Fri May 3 13:36:06 2002 +++ linux/net/khttpd/Config.in Thu Jan 1 01:00:00 1970 @@ -1,4 +0,0 @@ -# -# kHTTPd -# -tristate ' Kernel httpd acceleration (EXPERIMENTAL)' CONFIG_KHTTPD diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/Makefile linux/net/khttpd/Makefile --- linux-2.4.19-pre8/net/khttpd/Makefile Fri May 3 13:38:44 2002 +++ linux/net/khttpd/Makefile Thu Jan 1 01:00:00 1970 @@ -1,25 +0,0 @@ -# -# Makefile for kHTTPd -# -# Note! Dependencies are done automagically by 'make dep', which also -# removes any old dependencies. DON'T put your own dependencies here -# unless it's something special (ie not a .c file). -# -# Note 2! The CFLAGS definition is now in the main makefile... - -O_TARGET := khttpd.o - -obj-m := $(O_TARGET) -obj-y := main.o accept.o datasending.o logging.o misc.o rfc.o rfc_time.o security.o \ - sockets.o sysctl.o userspace.o waitheaders.o - - -include $(TOPDIR)/Rules.make - -rfc_time.o: times.h - -make_times_h: make_times_h.c - $(HOSTCC) $(HOSTCFLAGS) -o make_times_h make_times_h.c - -times.h: make_times_h - ./make_times_h diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/README linux/net/khttpd/README --- linux-2.4.19-pre8/net/khttpd/README Fri May 3 13:35:57 2002 +++ linux/net/khttpd/README Thu Jan 1 01:00:00 1970 @@ -1,224 +0,0 @@ -===== - -kHTTPd - Kernel httpd accelerator - -(C) 1999 by Arjan van de Ven -Licensed under the terms of the GNU General Public License - -===== - - -1. Introduction ---------------- - kHTTPd is a http-daemon (webserver) for Linux. kHTTPd is different from - other webservers in that it runs from within the Linux-kernel as a module - (device-driver). - - kHTTPd handles only static (file based) web-pages, and passes all requests - for non-static information to a regular userspace-webserver such as Apache or - Zeus. The userspace-daemon doesn't have to be altered in any way. - - Static web-pages are not a very complex thing to serve, but these are very - important nevertheless, since virtually all images are static, and a large - portion of the html-pages are static also. A "regular" webserver has little - added value for static pages, it is simply a "copy file to network"-operation. - This can be done very efficiently from within the Linux-kernel, for example - the nfs (network file system) daemon performs a similar task and also runs - in the kernel. - - By "accelerating" the simple case within the kernel, userspace daemons can - do what they are very good at: Generating user-specific, dynamic content. - - Note: This document sometimes uses "Apache" instead of "any webserver you - ever might want to use", just for reasons of readability. - - -2. Quick Start --------------- - - 1) compile and load the module - 2) configure the module in /proc/sys/net/khttpd if needed - 3) echo 1 > /proc/sys/net/khttpd/start - - unloading: - - echo 1 > /proc/sys/net/khttpd/stop - echo 1 > /proc/sys/net/khttpd/unload - rmmod khttpd - - - -3. Configuration ----------------- - - Modes of operation - ================== - - - There are two recommended modes of operation: - - 1) "Apache" is main webserver, kHTTPd is assistant - clientport -> 80 - serverport -> 8080 (or whatever) - - 2) kHTTPd is main webserver, "Apache" is assistant - clientport -> 8080 (or whatever) - serverport -> 80 - - - Configuring kHTTPd - ================== - - Before you can start using kHTTPd, you have to configure it. This - is done through the /proc filesystem, and can thus be done from inside - a script. Most parameters can only be set when kHTTPd is not active. - - The following things need configuration: - - 1) The port where kHTTPd should listen for requests - 2) The port (on "localhost") where "Apache" is listening - 3) The location of the documents (documentroot) - 4) The strings that indicate dynamic content (optional) - [ "cgi-bin" is added by default ] - - It is very important that the documentroot for kHTTPd matches the - documentroot for the userspace-daemon, as kHTTPd might "redirect" - any request to this userspace-daemon. - - A typical script (for the first mode of operation) to do this would - look like: - -#!/bin/sh -modprobe khttpd -echo 80 > /proc/sys/net/khttpd/clientport -echo 8080 > /proc/sys/net/khttpd/serverport -echo /var/www > /proc/sys/net/khttpd/documentroot -echo php3 > /proc/sys/net/khttpd/dynamic -echo shtml > /proc/sys/net/khttpd/dynamic -echo 1 > /proc/sys/net/khttpd/start - - For the second mode of operation, this would be: - -#!/bin/sh -modprobe khttpd -echo 8080 > /proc/sys/net/khttpd/clientport -echo 80 > /proc/sys/net/khttpd/serverport -echo /var/www > /proc/sys/net/khttpd/documentroot -echo php3 > /proc/sys/net/khttpd/dynamic -echo shtml > /proc/sys/net/khttpd/dynamic -echo 1 > /proc/sys/net/khttpd/start - - In this case, you also have to change the configuration of the - userspace-daemon. For Apache, you do this by changing - - Port 80 - - to - - Port 8080 - - - - Stopping kHTTPd - =============== - In order to change the configuration, you should stop kHTTPd by typing - echo 1 > /proc/sys/net/khttpd/stop - on a command-prompt. - - If you want to unload the module, you should type - echo 1 > /proc/sys/net/khttpd/unload - after stopping kHTTPd first. - - If this doesn't work fast enough for you (the commands above can wait for - a remote connection to close down), you can send the daemons a "HUP" - signal after you told them to stop. This will cause the daemon-threads to - stop immediately. - - Note that the daemons will restart immediately if they are not told to - stop. - - - -4. Permissions --------------- - The security model of kHTTPd is very strict. It can be, since there is a - userspace daemon that can handle the complex exceptions. - - kHTTPd only serves a file if - - 1) There is no "?" in the URL - 2) The URL starts with a "/" - 3) The file indicated by the URL exists - 4) The file is world-readable (*) - 5) The file is not a directory, executable or has the Sticky-bit - set (*) - 6) The URL doesn't contain any "forbidden" substrings such as ".." - and "cgi-bin" (*) - 7) The mime-type is known (*) - - The items marked with a (*) are configurable through the - sysctl-parameters in /proc/sys/net/khttpd. - - - In all cases where any of the above conditions isn't met, the - userspace-daemon is handed the request. - - - -5. Parameters -------------- - The following parameters are settable through /proc/sys/net/khttpd: - - Name Default Description - - serverport 8080 The port where kHTTPd listens on - - clientport 80 The port of the userspace - http-daemon - - threads 2 The number of server-threads. Should - be 1 per CPU for small websites, 2 - per CPU for big (the active files - do not fit in the RAM) websites. - - documentroot /var/www the directory where the - document-files are - - start 0 Set to 1 to start kHTTPd - (this also resets "stop" to 0) - - stop 0 Set to 1 to stop kHTTPd - (this also resets "start" to 0) - - unload 0 Set to 1 to prepare kHTTPd for - unloading of the module - - sloppymime 0 If set to 1, unknown mime-types are - set to text/html. If set to 0, - files with unknown mime-types are - handled by the userspace daemon - - perm_required S_IROTH Minimum permissions required - (for values see "man 2 stat") - - perm_forbid dir+sticky+ Permission-mask with "forbidden" - execute permissions. - (for values see "man 2 stat") - - dynamic cgi-bin .. Strings that, if they are a subset - of the URL, indicate "dynamic - content" - - maxconnect 1000 Maximum number of concurrent - connections - -6. More information -------------------- - More information about the architecture of kHTTPd, the mailinglist and - configuration-examples can be found at the kHTTPd homepage: - - http://www.fenrus.demon.nl - - Bugreports, patches, etc can be send to the mailinglist - (khttpd-users@zgp.org) or to khttpd@fenrus.demon.nl - diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/accept.c linux/net/khttpd/accept.c --- linux-2.4.19-pre8/net/khttpd/accept.c Fri May 3 13:35:46 2002 +++ linux/net/khttpd/accept.c Thu Jan 1 01:00:00 1970 @@ -1,127 +0,0 @@ -/* - -kHTTPd -- the next generation - -Accept connections - -*/ -/**************************************************************** - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - ****************************************************************/ - -#include "structure.h" -#include "prototypes.h" -#include "sysctl.h" - -#include <linux/smp_lock.h> - -/* - -Purpose: - -AcceptConnections puts all "accepted" connections in the -"WaitForHeader" queue. - -Return value: - The number of accepted connections -*/ - - -int AcceptConnections(const int CPUNR, struct socket *Socket) -{ - struct http_request *NewRequest; - struct socket *NewSock; - int count = 0; - int error; - - EnterFunction("AcceptConnections"); - - if (atomic_read(&ConnectCount)>sysctl_khttpd_maxconnect) - { - LeaveFunction("AcceptConnections - to many active connections"); - return 0; - } - - if (Socket==NULL) return 0; - - /* - Quick test to see if there are connections on the queue. - This is cheaper than accept() itself because this saves us - the allocation of a new socket. (Which doesn't seem to be - used anyway) - */ - if (Socket->sk->tp_pinfo.af_tcp.accept_queue==NULL) - { - return 0; - } - - error = 0; - while (error>=0) - { - NewSock = sock_alloc(); - if (NewSock==NULL) - break; - - - NewSock->type = Socket->type; - NewSock->ops = Socket->ops; - - - error = Socket->ops->accept(Socket,NewSock,O_NONBLOCK); - - - if (error<0) - { - sock_release(NewSock); - break; - } - - if (NewSock->sk->state==TCP_CLOSE) - { - sock_release(NewSock); - continue; - } - - /* Allocate a request-entry for the connection */ - NewRequest = kmalloc(sizeof(struct http_request),(int)GFP_KERNEL); - - if (NewRequest == NULL) - { - Send50x(NewSock); /* Service not available. Try again later */ - sock_release(NewSock); - break; - } - memset(NewRequest,0,sizeof(struct http_request)); - - NewRequest->sock = NewSock; - - NewRequest->Next = threadinfo[CPUNR].WaitForHeaderQueue; - - init_waitqueue_entry(&NewRequest->sleep,current); - - add_wait_queue(NewSock->sk->sleep,&(NewRequest->sleep)); - - threadinfo[CPUNR].WaitForHeaderQueue = NewRequest; - - atomic_inc(&ConnectCount); - - - count++; - } - - LeaveFunction("AcceptConnections"); - return count; -} diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/datasending.c linux/net/khttpd/datasending.c --- linux-2.4.19-pre8/net/khttpd/datasending.c Fri May 3 13:36:56 2002 +++ linux/net/khttpd/datasending.c Thu Jan 1 01:00:00 1970 @@ -1,241 +0,0 @@ -/* - -kHTTPd -- the next generation - -Send actual file-data to the connections - -*/ -/**************************************************************** - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - ****************************************************************/ - -/* - -Purpose: - -DataSending does the actual sending of file-data to the socket. - -Note: Since asynchronous reads do not -yet- exists, this might block! - -Return value: - The number of requests that changed status (ie: made some progress) -*/ - -#include <linux/config.h> -#include <linux/kernel.h> -#include <linux/locks.h> -#include <linux/skbuff.h> - -#include <net/tcp.h> - -#include <asm/uaccess.h> -#include <linux/smp_lock.h> - -#include "structure.h" -#include "prototypes.h" - -static char *Block[CONFIG_KHTTPD_NUMCPU]; - -/* - -This send_actor is for use with do_generic_file_read (ie sendfile()) -It sends the data to the socket indicated by desc->buf. - -*/ -static int sock_send_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size) -{ - int written; - char *kaddr; - unsigned long count = desc->count; - struct socket *sock = (struct socket *) desc->buf; - mm_segment_t old_fs; - - if (size > count) - size = count; - old_fs = get_fs(); - set_fs(KERNEL_DS); - - kaddr = kmap(page); - written = SendBuffer_async(sock, kaddr + offset, size); - kunmap(page); - set_fs(old_fs); - if (written < 0) { - desc->error = written; - written = 0; - } - desc->count = count - written; - desc->written += written; - return written; -} - - - - -int DataSending(const int CPUNR) -{ - struct http_request *CurrentRequest,**Prev; - int count = 0; - - EnterFunction("DataSending"); - - Prev = &(threadinfo[CPUNR].DataSendingQueue); - CurrentRequest = threadinfo[CPUNR].DataSendingQueue; - while (CurrentRequest!=NULL) - { - int ReadSize,Space; - int retval; - - - /* First, test if the socket has any buffer-space left. - If not, no need to actually try to send something. */ - - - Space = sock_wspace(CurrentRequest->sock->sk); - - ReadSize = min_t(int, 4 * 4096, CurrentRequest->FileLength - CurrentRequest->BytesSent); - ReadSize = min_t(int, ReadSize, Space); - - if (ReadSize>0) - { - struct inode *inode; - - inode = CurrentRequest->filp->f_dentry->d_inode; - - if (inode->i_mapping->a_ops->readpage) { - /* This does the actual transfer using sendfile */ - read_descriptor_t desc; - loff_t *ppos; - - CurrentRequest->filp->f_pos = CurrentRequest->BytesSent; - - ppos = &CurrentRequest->filp->f_pos; - - desc.written = 0; - desc.count = ReadSize; - desc.buf = (char *) CurrentRequest->sock; - desc.error = 0; - do_generic_file_read(CurrentRequest->filp, ppos, &desc, sock_send_actor); - if (desc.written>0) - { - CurrentRequest->BytesSent += desc.written; - count++; - } - } - else /* FS doesn't support sendfile() */ - { - mm_segment_t oldfs; - CurrentRequest->filp->f_pos = CurrentRequest->BytesSent; - - oldfs = get_fs(); set_fs(KERNEL_DS); - retval = CurrentRequest->filp->f_op->read(CurrentRequest->filp, Block[CPUNR], ReadSize, &CurrentRequest->filp->f_pos); - set_fs(oldfs); - - if (retval>0) - { - retval = SendBuffer_async(CurrentRequest->sock,Block[CPUNR],(size_t)retval); - if (retval>0) - { - CurrentRequest->BytesSent += retval; - count++; - } - } - } - - } - - /* - If end-of-file or closed connection: Finish this request - by moving it to the "logging" queue. - */ - if ((CurrentRequest->BytesSent>=CurrentRequest->FileLength)|| - (CurrentRequest->sock->sk->state!=TCP_ESTABLISHED - && CurrentRequest->sock->sk->state!=TCP_CLOSE_WAIT)) - { - struct http_request *Next; - Next = CurrentRequest->Next; - - lock_sock(CurrentRequest->sock->sk); - if (CurrentRequest->sock->sk->state == TCP_ESTABLISHED || - CurrentRequest->sock->sk->state == TCP_CLOSE_WAIT) - { - CurrentRequest->sock->sk->tp_pinfo.af_tcp.nonagle = 0; - tcp_push_pending_frames(CurrentRequest->sock->sk,&(CurrentRequest->sock->sk->tp_pinfo.af_tcp)); - } - release_sock(CurrentRequest->sock->sk); - - (*Prev) = CurrentRequest->Next; - - CurrentRequest->Next = threadinfo[CPUNR].LoggingQueue; - threadinfo[CPUNR].LoggingQueue = CurrentRequest; - - CurrentRequest = Next; - continue; - - } - - - Prev = &(CurrentRequest->Next); - CurrentRequest = CurrentRequest->Next; - } - - LeaveFunction("DataSending"); - return count; -} - -int InitDataSending(int ThreadCount) -{ - int I,I2; - - EnterFunction("InitDataSending"); - I=0; - while (I<ThreadCount) - { - Block[I] = (char*)get_free_page((int)GFP_KERNEL); - if (Block[I] == NULL) - { - I2=0; - while (I2<I-1) - { - free_page((unsigned long)Block[I2++]); - } - LeaveFunction("InitDataSending - abort"); - return -1; - } - I++; - } - LeaveFunction("InitDataSending"); - return 0; -} - -void StopDataSending(const int CPUNR) -{ - struct http_request *CurrentRequest,*Next; - - EnterFunction("StopDataSending"); - CurrentRequest = threadinfo[CPUNR].DataSendingQueue; - - while (CurrentRequest!=NULL) - { - Next = CurrentRequest->Next; - CleanUpRequest(CurrentRequest); - CurrentRequest=Next; - } - - threadinfo[CPUNR].DataSendingQueue = NULL; - - free_page( (unsigned long)Block[CPUNR]); - LeaveFunction("StopDataSending"); -} diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/logging.c linux/net/khttpd/logging.c --- linux-2.4.19-pre8/net/khttpd/logging.c Fri May 3 13:36:20 2002 +++ linux/net/khttpd/logging.c Thu Jan 1 01:00:00 1970 @@ -1,95 +0,0 @@ -/* - -kHTTPd -- the next generation - -logging.c takes care of shutting down a connection. - -*/ -/**************************************************************** - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - ****************************************************************/ - -#include <linux/kernel.h> -#include <linux/skbuff.h> -#include <linux/smp_lock.h> -#include <net/tcp.h> -#include <asm/uaccess.h> -#include "structure.h" -#include "prototypes.h" - -/* - -Purpose: - -Logging() terminates "finished" connections and will eventually log them to a -userspace daemon. - -Return value: - The number of requests that changed status, thus the number of connections - that shut down. -*/ - - -int Logging(const int CPUNR) -{ - struct http_request *CurrentRequest,*Req; - int count = 0; - - EnterFunction("Logging"); - - CurrentRequest = threadinfo[CPUNR].LoggingQueue; - - /* For now, all requests are removed immediatly, but this changes - when userspace-logging is added. */ - - while (CurrentRequest!=NULL) - { - - Req = CurrentRequest->Next; - - CleanUpRequest(CurrentRequest); - - threadinfo[CPUNR].LoggingQueue = Req; - - CurrentRequest = Req; - - count++; - - } - - LeaveFunction("Logging"); - return count; -} - - - -void StopLogging(const int CPUNR) -{ - struct http_request *CurrentRequest,*Next; - - EnterFunction("StopLogging"); - CurrentRequest = threadinfo[CPUNR].LoggingQueue; - - while (CurrentRequest!=NULL) - { - Next=CurrentRequest->Next; - CleanUpRequest(CurrentRequest); - CurrentRequest=Next; - } - - threadinfo[CPUNR].LoggingQueue = NULL; - LeaveFunction("StopLogging"); -} diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/main.c linux/net/khttpd/main.c --- linux-2.4.19-pre8/net/khttpd/main.c Fri May 3 13:35:12 2002 +++ linux/net/khttpd/main.c Thu Jan 1 01:00:00 1970 @@ -1,394 +0,0 @@ -/* - -kHTTPd -- the next generation - -Main program - - -kHTTPd TNG consists of 1 thread, this main-thread handles ALL connections -simultanious. It does this by keeping queues with the requests in different -stages. - -The stages are - -<not accepted> - TCP/IP connection is not accepted yet -WaitForHeaders - Connection is accepted, waiting for headers -DataSending - Headers decoded, sending file-data -Userspace - Requires userspace daemon -Logging - The request is finished, cleanup and logging - -A typical flow for a request would be: - -<not accepted> -WaitForHeaders -DataSending -Logging - -or - -<not accepted> -WaitForHeaders -Userspace - - - -*/ -/**************************************************************** - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - ****************************************************************/ - - -static int errno; -#define __KERNEL_SYSCALLS__ - -#include <linux/config.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/signal.h> -#include <linux/init.h> -#include <linux/wait.h> -#include <linux/smp_lock.h> -#include <asm/unistd.h> - -#include "structure.h" -#include "prototypes.h" -#include "sysctl.h" - -struct khttpd_threadinfo threadinfo[CONFIG_KHTTPD_NUMCPU]; /* The actual work-queues */ - - -atomic_t ConnectCount; -atomic_t DaemonCount; - -static int ActualThreads; /* The number of actual, active threads */ - - -static int ConnectionsPending(int CPUNR) -{ - if (threadinfo[CPUNR].DataSendingQueue!=NULL) return O_NONBLOCK; - if (threadinfo[CPUNR].WaitForHeaderQueue!=NULL) return O_NONBLOCK; - if (threadinfo[CPUNR].LoggingQueue!=NULL) return O_NONBLOCK; - if (threadinfo[CPUNR].UserspaceQueue!=NULL) return O_NONBLOCK; - return 0; -} - - - -static wait_queue_head_t DummyWQ[CONFIG_KHTTPD_NUMCPU]; -static atomic_t Running[CONFIG_KHTTPD_NUMCPU]; - -static int MainDaemon(void *cpu_pointer) -{ - int CPUNR; - sigset_t tmpsig; - - DECLARE_WAITQUEUE(main_wait,current); - - MOD_INC_USE_COUNT; - - - CPUNR=0; - if (cpu_pointer!=NULL) - CPUNR=(int)*(int*)cpu_pointer; - - sprintf(current->comm,"khttpd - %i",CPUNR); - daemonize(); - - init_waitqueue_head(&(DummyWQ[CPUNR])); - - - /* Block all signals except SIGKILL, SIGSTOP and SIGHUP */ - spin_lock_irq(¤t->sigmask_lock); - tmpsig = current->blocked; - siginitsetinv(¤t->blocked, sigmask(SIGKILL) | sigmask(SIGSTOP)| sigmask(SIGHUP)); - recalc_sigpending(current); - spin_unlock_irq(¤t->sigmask_lock); - - - if (MainSocket->sk==NULL) - return 0; - add_wait_queue_exclusive(MainSocket->sk->sleep,&(main_wait)); - atomic_inc(&DaemonCount); - atomic_set(&Running[CPUNR],1); - - while (sysctl_khttpd_stop==0) - { - int changes = 0; - - - - changes +=AcceptConnections(CPUNR,MainSocket); - if (ConnectionsPending(CPUNR)) - { - changes +=WaitForHeaders(CPUNR); - changes +=DataSending(CPUNR); - changes +=Userspace(CPUNR); - changes +=Logging(CPUNR); - /* Test for incoming connections _again_, because it is possible - one came in during the other steps, and the wakeup doesn't happen - then. - */ - changes +=AcceptConnections(CPUNR,MainSocket); - } - - if (changes==0) - { - (void)interruptible_sleep_on_timeout(&(DummyWQ[CPUNR]),1); - if (CPUNR==0) - UpdateCurrentDate(); - } - - if (signal_pending(current)!=0) - { - (void)printk(KERN_NOTICE "kHTTPd: Ring Ring - signal received\n"); - break; - } - - } - - remove_wait_queue(MainSocket->sk->sleep,&(main_wait)); - - StopWaitingForHeaders(CPUNR); - StopDataSending(CPUNR); - StopUserspace(CPUNR); - StopLogging(CPUNR); - - atomic_set(&Running[CPUNR],0); - atomic_dec(&DaemonCount); - (void)printk(KERN_NOTICE "kHTTPd: Daemon %i has ended\n",CPUNR); - MOD_DEC_USE_COUNT; - return 0; -} - -static int CountBuf[CONFIG_KHTTPD_NUMCPU]; - - - -/* - -The ManagementDaemon has a very simple task: Start the real daemons when the user wants us -to, and cleanup when the users wants to unload the module. - -Initially, kHTTPd didn't have this thread, but it is the only way to have "delayed activation", -a feature required to prevent accidental activations resulting in unexpected backdoors. - -*/ -static int ManagementDaemon(void *unused) -{ - sigset_t tmpsig; - int waitpid_result; - - DECLARE_WAIT_QUEUE_HEAD(WQ); - - - sprintf(current->comm,"khttpd manager"); - daemonize(); - - - /* Block all signals except SIGKILL and SIGSTOP */ - spin_lock_irq(¤t->sigmask_lock); - tmpsig = current->blocked; - siginitsetinv(¤t->blocked, sigmask(SIGKILL) | sigmask(SIGSTOP) ); - recalc_sigpending(current); - spin_unlock_irq(¤t->sigmask_lock); - - - /* main loop */ - while (sysctl_khttpd_unload==0) - { - int I; - - - /* First : wait for activation */ - - sysctl_khttpd_start = 0; - - while ( (sysctl_khttpd_start==0) && (!signal_pending(current)) && (sysctl_khttpd_unload==0) ) - { - current->state = TASK_INTERRUPTIBLE; - interruptible_sleep_on_timeout(&WQ,HZ); - } - - if ( (signal_pending(current)) || (sysctl_khttpd_unload!=0) ) - break; - - /* Then start listening and spawn the daemons */ - - if (StartListening(sysctl_khttpd_serverport)==0) - { - continue; - } - - ActualThreads = sysctl_khttpd_threads; - if (ActualThreads<1) - ActualThreads = 1; - - if (ActualThreads>CONFIG_KHTTPD_NUMCPU) - ActualThreads = CONFIG_KHTTPD_NUMCPU; - - /* Write back the actual value */ - - sysctl_khttpd_threads = ActualThreads; - - InitUserspace(ActualThreads); - - if (InitDataSending(ActualThreads)!=0) - { - StopListening(); - continue; - } - if (InitWaitHeaders(ActualThreads)!=0) - { - I=0; - while (I<ActualThreads) - { - StopDataSending(I); - I++; - } - StopListening(); - continue; - } - - /* Clean all queues */ - memset(threadinfo, 0, sizeof(struct khttpd_threadinfo)); - - - - I=0; - while (I<ActualThreads) - { - atomic_set(&Running[I],1); - (void)kernel_thread(MainDaemon,&(CountBuf[I]), CLONE_FS | CLONE_FILES | CLONE_SIGHAND); - I++; - } - - /* Then wait for deactivation */ - sysctl_khttpd_stop = 0; - - while ( (sysctl_khttpd_stop==0) && (!signal_pending(current)) && (sysctl_khttpd_unload==0) ) - { - if (atomic_read(&DaemonCount)<ActualThreads) - { - I=0; - while (I<ActualThreads) - { - if (atomic_read(&Running[I])==0) - { - atomic_set(&Running[I],1); - (void)kernel_thread(MainDaemon,&(CountBuf[I]), CLONE_FS | CLONE_FILES | CLONE_SIGHAND); - (void)printk(KERN_CRIT "kHTTPd: Restarting daemon %i \n",I); - } - I++; - } - } - interruptible_sleep_on_timeout(&WQ,HZ); - - /* reap the daemons */ - waitpid_result = waitpid(-1,NULL,__WCLONE|WNOHANG); - - } - - - /* The user wants us to stop. So stop listening on the socket. */ - if (sysctl_khttpd_stop!=0) - { - /* Wait for the daemons to stop, one second per iteration */ - while (atomic_read(&DaemonCount)>0) - interruptible_sleep_on_timeout(&WQ,HZ); - StopListening(); - } - - - - } - - sysctl_khttpd_stop = 1; - - /* Wait for the daemons to stop, one second per iteration */ - while (atomic_read(&DaemonCount)>0) - interruptible_sleep_on_timeout(&WQ,HZ); - - - waitpid_result = 1; - /* reap the zombie-daemons */ - while (waitpid_result>0) - waitpid_result = waitpid(-1,NULL,__WCLONE|WNOHANG); - - StopListening(); - - - (void)printk(KERN_NOTICE "kHTTPd: Management daemon stopped. \n You can unload the module now.\n"); - - MOD_DEC_USE_COUNT; - - return 0; -} - -int __init khttpd_init(void) -{ - int I; - - MOD_INC_USE_COUNT; - - I=0; - while (I<CONFIG_KHTTPD_NUMCPU) - { - CountBuf[I]=I; - - I++; - } - - atomic_set(&ConnectCount,0); - atomic_set(&DaemonCount,0); - - - /* Maybe the mime-types will be set-able through sysctl in the future */ - - AddMimeType(".htm","text/html"); - AddMimeType("html","text/html"); - AddMimeType(".gif","image/gif"); - AddMimeType(".jpg","image/jpeg"); - AddMimeType(".png","image/png"); - AddMimeType("tiff","image/tiff"); - AddMimeType(".zip","application/zip"); - AddMimeType(".pdf","application/pdf"); - AddMimeType("r.gz","application/x-gtar"); - AddMimeType(".tgz","application/x-gtar"); - AddMimeType(".deb","application/x-debian-package"); - AddMimeType("lass","application/x-java"); - AddMimeType(".mp3","audio/mpeg"); - AddMimeType(".txt","text/plain"); - - AddDynamicString(".."); - AddDynamicString("cgi-bin"); - - StartSysctl(); - - (void)kernel_thread(ManagementDaemon,NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); - - return 0; -} - -void khttpd_cleanup(void) -{ - EndSysctl(); -} - - module_init(khttpd_init) - module_exit(khttpd_cleanup) - - MODULE_LICENSE("GPL"); diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/make_times_h.c linux/net/khttpd/make_times_h.c --- linux-2.4.19-pre8/net/khttpd/make_times_h.c Fri May 3 13:36:34 2002 +++ linux/net/khttpd/make_times_h.c Thu Jan 1 01:00:00 1970 @@ -1,122 +0,0 @@ -/* - -This program generates the "times.h" file with the zulu-times of the first of -every month of a decade. - -*/ -/**************************************************************** - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - ****************************************************************/ - -#include <time.h> -#include <stdio.h> - -static time_t GetDay(int D,int M,int Y) -{ - struct tm TM; - - TM.tm_sec = 0; - TM.tm_min = 0; - TM.tm_hour = 0; - TM.tm_mday = D; - TM.tm_mon = M; - TM.tm_wday = 0; - TM.tm_yday = 0; - TM.tm_year = Y-1900; - TM.tm_isdst = 0; - - return mktime(&TM); - -} -static int WeekGetDay(int D,int M,int Y) -{ - struct tm TM; - - TM.tm_sec = 0; - TM.tm_min = 0; - TM.tm_hour = 0; - TM.tm_mday = D; - TM.tm_mon = M; - TM.tm_year = Y-1900; - TM.tm_isdst = 0; - TM.tm_wday = 0; - TM.tm_yday = 0; - - (void)mktime(&TM); - - return TM.tm_wday; - -} - -int main(void) -{ - int M,Y; - FILE *file; - - file=fopen("times.h","w"); - - if (file==NULL) - return 0; - - fprintf(file,"static time_t TimeDays[10][13] = { \n"); - - Y=1997; - while (Y<2007) - { - M=0; - fprintf(file," { "); - while (M<12) - { - fprintf(file,"%i",(int)GetDay(1,M,Y)); - fprintf(file,",\t"); - - M++; - } - - fprintf(file,"%i } ",(int)GetDay(1,0,Y+1)); - if (Y!=2006) fprintf(file,","); - fprintf(file,"\n"); - Y++; - } - fprintf(file,"};\n"); - - fprintf(file,"static int WeekDays[10][13] = { \n"); - - Y=1997; - while (Y<2007) - { - M=0; - fprintf(file," { "); - while (M<12) - { - fprintf(file,"%i",(int)WeekGetDay(1,M,Y)); - fprintf(file,",\t"); - - M++; - } - - fprintf(file,"%i } ",(int)WeekGetDay(1,0,Y+1)); - if (Y!=2006) fprintf(file,","); - fprintf(file,"\n"); - Y++; - } - fprintf(file,"};\n"); - fprintf(file,"#define KHTTPD_YEAROFFSET 1997\n"); - fprintf(file,"#define KHTTPD_NUMYEARS 10\n"); - (void)fclose(file); - - return 0; -} diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/misc.c linux/net/khttpd/misc.c --- linux-2.4.19-pre8/net/khttpd/misc.c Fri May 3 13:37:41 2002 +++ linux/net/khttpd/misc.c Thu Jan 1 01:00:00 1970 @@ -1,242 +0,0 @@ -/* - -kHTTPd -- the next generation - -General functions - -*/ -/**************************************************************** - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - ****************************************************************/ - -#include <linux/kernel.h> - -#include <linux/ctype.h> -#include <linux/errno.h> -#include <linux/slab.h> -#include <linux/net.h> -#include <linux/sched.h> -#include <linux/skbuff.h> -#include <linux/unistd.h> -#include <linux/file.h> -#include <linux/smp_lock.h> - -#include <net/ip.h> -#include <net/sock.h> - -#include <asm/atomic.h> -#include <asm/errno.h> -#include <asm/semaphore.h> -#include <asm/processor.h> -#include <asm/uaccess.h> - -#include "structure.h" -#include "prototypes.h" - -#ifndef ECONNRESET -#define ECONNRESET 102 -#endif - - -/* - -Readrest reads and discards all pending input on a socket. This is required -before closing the socket. - -*/ -static void ReadRest(struct socket *sock) -{ - struct msghdr msg; - struct iovec iov; - int len; - - mm_segment_t oldfs; - - - EnterFunction("ReadRest"); - - - if (sock->sk==NULL) - return; - - len = 1; - - while (len>0) - { - static char Buffer[1024]; /* Never read, so doesn't need to - be SMP safe */ - - msg.msg_name = 0; - msg.msg_namelen = 0; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = MSG_DONTWAIT; - - msg.msg_iov->iov_base = &Buffer[0]; - msg.msg_iov->iov_len = (__kernel_size_t)1024; - - len = 0; - oldfs = get_fs(); set_fs(KERNEL_DS); - len = sock_recvmsg(sock,&msg,1024,MSG_DONTWAIT); - set_fs(oldfs); - } - LeaveFunction("ReadRest"); -} - - -/* - -CleanUpRequest takes care of shutting down the connection, closing the file-pointer -and releasing the memory of the request-structure. Do not try to access it afterwards! - -*/ -void CleanUpRequest(struct http_request *Req) -{ - EnterFunction("CleanUpRequest"); - - /* Close the socket ....*/ - if ((Req->sock!=NULL)&&(Req->sock->sk!=NULL)) - { - ReadRest(Req->sock); - remove_wait_queue(Req->sock->sk->sleep,&(Req->sleep)); - sock_release(Req->sock); - } - - /* ... and the file-pointer ... */ - if (Req->filp!=NULL) - { - fput(Req->filp); - Req->filp = NULL; - } - - - /* ... and release the memory for the structure. */ - kfree(Req); - - atomic_dec(&ConnectCount); - LeaveFunction("CleanUpRequest"); -} - - -/* - -SendBuffer and Sendbuffer_async send "Length" bytes from "Buffer" to the "sock"et. -The _async-version is non-blocking. - -A positive return-value indicates the number of bytes sent, a negative value indicates -an error-condition. - -*/ -int SendBuffer(struct socket *sock, const char *Buffer,const size_t Length) -{ - struct msghdr msg; - mm_segment_t oldfs; - struct iovec iov; - int len; - - EnterFunction("SendBuffer"); - - msg.msg_name = 0; - msg.msg_namelen = 0; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = MSG_NOSIGNAL; - msg.msg_iov->iov_len = (__kernel_size_t)Length; - msg.msg_iov->iov_base = (char*) Buffer; - - - len = 0; - - oldfs = get_fs(); set_fs(KERNEL_DS); - len = sock_sendmsg(sock,&msg,(size_t)(Length-len)); - set_fs(oldfs); - LeaveFunction("SendBuffer"); - return len; -} - -int SendBuffer_async(struct socket *sock, const char *Buffer,const size_t Length) -{ - struct msghdr msg; - mm_segment_t oldfs; - struct iovec iov; - int len; - - EnterFunction("SendBuffer_async"); - msg.msg_name = 0; - msg.msg_namelen = 0; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = MSG_DONTWAIT|MSG_NOSIGNAL; - msg.msg_iov->iov_base = (char*) Buffer; - msg.msg_iov->iov_len = (__kernel_size_t)Length; - - - if (sock->sk) - { - oldfs = get_fs(); set_fs(KERNEL_DS); - len = sock_sendmsg(sock,&msg,(size_t)(Length)); - set_fs(oldfs); - } else - { - return -ECONNRESET; - } - - LeaveFunction("SendBuffer_async"); - return len; -} - - - - -/* - -HTTP header shortcuts. Hardcoded since these might be called in a low-memory -situation, and they don't change anyhow. - -*/ - -static char NoPerm[] = "HTTP/1.0 403 Forbidden\r\nServer: kHTTPd 0.1.6\r\n\r\n"; -static char TryLater[] = "HTTP/1.0 503 Service Unavailable\r\nServer: kHTTPd 0.1.6\r\nContent-Length: 15\r\n\r\nTry again later"; -static char NotModified[] = "HTTP/1.0 304 Not Modified\r\nServer: kHTTPd 0.1.6\r\n\r\n"; - - -void Send403(struct socket *sock) -{ - EnterFunction("Send403"); - (void)SendBuffer(sock,NoPerm,strlen(NoPerm)); - LeaveFunction("Send403"); -} - -void Send304(struct socket *sock) -{ - EnterFunction("Send304"); - (void)SendBuffer(sock,NotModified,strlen(NotModified)); - LeaveFunction("Send304"); -} - -void Send50x(struct socket *sock) -{ - EnterFunction("Send50x"); - (void)SendBuffer(sock,TryLater,strlen(TryLater)); - LeaveFunction("Send50x"); -} - diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/prototypes.h linux/net/khttpd/prototypes.h --- linux-2.4.19-pre8/net/khttpd/prototypes.h Fri May 3 13:38:39 2002 +++ linux/net/khttpd/prototypes.h Thu Jan 1 01:00:00 1970 @@ -1,120 +0,0 @@ -#ifndef _INCLUDE_GUARD_PROTOTYPES_H -#define _INCLUDE_GUARD_PROTOTYPES_H - - -#include <linux/config.h> -#include <linux/kernel.h> -#include <linux/net.h> -#include <linux/time.h> -#include <linux/types.h> -#include <linux/wait.h> -#include <net/sock.h> -#include <asm/uaccess.h> - -#include "structure.h" - - -/* General defines and stuff */ - - -#define CONFIG_KHTTPD_NUMCPU 16 /* Maximum number of threads */ - -#ifdef OOPSTRACE -#define EnterFunction(x) printk("Enter: %s, %s line %i\n",x,__FILE__,__LINE__) -#define LeaveFunction(x) printk("Leave: %s, %s line %i\n",x,__FILE__,__LINE__) -#else -#define EnterFunction(x) do {} while (0) -#define LeaveFunction(x) do {} while (0) -#endif - - - -/* sockets.c */ -int StartListening(const int Port); -void StopListening(void); - -extern struct socket *MainSocket; - - -/* sysctl.c */ -void StartSysctl(void); -void EndSysctl(void); - -extern int sysctl_khttpd_stop; - - -/* main.c */ - - -extern struct khttpd_threadinfo threadinfo[CONFIG_KHTTPD_NUMCPU]; -extern char CurrentTime[]; -extern atomic_t ConnectCount; -extern struct wait_queue main_wait[CONFIG_KHTTPD_NUMCPU]; - -/* misc.c */ - -void CleanUpRequest(struct http_request *Req); -int SendBuffer(struct socket *sock, const char *Buffer,const size_t Length); -int SendBuffer_async(struct socket *sock, const char *Buffer,const size_t Length); -void Send403(struct socket *sock); -void Send304(struct socket *sock); -void Send50x(struct socket *sock); - -/* accept.c */ - -int AcceptConnections(const int CPUNR,struct socket *Socket); - -/* waitheaders.c */ - -int WaitForHeaders(const int CPUNR); -void StopWaitingForHeaders(const int CPUNR); -int InitWaitHeaders(int ThreadCount); - -/* datasending.c */ - -int DataSending(const int CPUNR); -void StopDataSending(const int CPUNR); -int InitDataSending(int ThreadCount); - - -/* userspace.c */ - -int Userspace(const int CPUNR); -void StopUserspace(const int CPUNR); -void InitUserspace(const int CPUNR); - - -/* rfc_time.c */ - -void time_Unix2RFC(const time_t Zulu,char *Buffer); -void UpdateCurrentDate(void); -time_t mimeTime_to_UnixTime(char *Q); -extern int CurrentTime_i; - -/* rfc.c */ - -void ParseHeader(char *Buffer,const int length, struct http_request *Head); -char *ResolveMimeType(const char *File,__kernel_size_t *Len); -void AddMimeType(const char *Ident,const char *Type); -void SendHTTPHeader(struct http_request *Request); - - - -/* security.c */ - -struct file *OpenFileForSecurity(char *Filename); -void AddDynamicString(const char *String); -void GetSecureString(char *String); - - -/* logging.c */ - -int Logging(const int CPUNR); -void StopLogging(const int CPUNR); - - -/* Other prototypes */ - - - -#endif diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/rfc.c linux/net/khttpd/rfc.c --- linux-2.4.19-pre8/net/khttpd/rfc.c Fri May 3 13:37:47 2002 +++ linux/net/khttpd/rfc.c Thu Jan 1 01:00:00 1970 @@ -1,374 +0,0 @@ -/* - -kHTTPd -- the next generation - -RFC related functions (headers and stuff) - -*/ - -/**************************************************************** - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - ****************************************************************/ - - -#include <linux/kernel.h> - -#include <linux/ctype.h> -#include <linux/errno.h> -#include <linux/slab.h> -#include <linux/net.h> -#include <linux/sched.h> -#include <linux/skbuff.h> -#include <linux/unistd.h> -#include <linux/file.h> -#include <linux/smp_lock.h> - -#include <net/ip.h> -#include <net/sock.h> - -#include <asm/atomic.h> -#include <asm/semaphore.h> -#include <asm/processor.h> -#include <asm/uaccess.h> - - -#include "prototypes.h" -#include "structure.h" -#include "sysctl.h" - - -#define KHTTPD_NUMMIMETYPES 40 - -static atomic_t MimeCount; - -struct MimeType -{ - __u32 identifier; - char type[64-sizeof(__u32)-sizeof(__kernel_size_t)]; - __kernel_size_t len; -}; - -static struct MimeType MimeTypes[KHTTPD_NUMMIMETYPES]; - - -void AddMimeType(const char *Ident,const char *Type) -{ - __u32 *I; - - EnterFunction("AddMimeType"); - - if (strlen(Ident)!=4) - { - (void)printk(KERN_ERR "httpd: Only 4-byte mime-identifiers are accepted\n"); - return; - } - - if (strlen(Type)>(64-sizeof(__u32)-sizeof(__kernel_size_t) ) ) - { - (void)printk(KERN_ERR "httpd: Mime-string too long.\n"); - return; - } - - I=(__u32*)Ident; - - /* FIXME: Need to lock-down all access to the mime-structure here */ - /* For now, just don't add mime-types after initialisation */ - - - MimeTypes[atomic_read(&MimeCount)].identifier=*I; - strncpy(MimeTypes[atomic_read(&MimeCount)].type,Type,(64-sizeof(__u32)-sizeof(__kernel_size_t))); - MimeTypes[atomic_read(&MimeCount)].len = strlen(Type); - - atomic_inc(&MimeCount); - LeaveFunction("AddMimeType"); -} - - -char *ResolveMimeType(const char *File,__kernel_size_t *Len) -/* - - The returned string is for READ ONLY, ownership of the memory is NOT - transferred. - -*/ -{ - __u32 *I; - int pos,lc,filelen; - - EnterFunction("ResolveMimeType"); - - *Len = 0; - - if (File==NULL) - return NULL; - - filelen = (int)strlen(File); - - if (filelen<4) - { - return NULL; - } - - /* The Merced-people are NOT going to like this! So this has to be fixed - in a later stage. */ - - pos = filelen-4; - I=(__u32*)(File+pos); - - lc=0; - - while (lc<atomic_read(&MimeCount)) - { - if (MimeTypes[lc].identifier == *I) - { - *Len = MimeTypes[lc].len; - LeaveFunction("ResolveMimeType - success"); - return MimeTypes[lc].type; - } - lc++; - } - - if (sysctl_khttpd_sloppymime) - { - *Len = MimeTypes[0].len; - LeaveFunction("ResolveMimeType - unknown"); - return MimeTypes[0].type; - } - else - { - LeaveFunction("ResolveMimeType - failure"); - return NULL; - } -} - - -static char HeaderPart1[] = "HTTP/1.0 200 OK\r\nServer: kHTTPd/0.1.6\r\nDate: "; -#ifdef BENCHMARK -static char HeaderPart1b[] ="HTTP/1.0 200 OK"; -#endif -static char HeaderPart3[] = "\r\nContent-type: "; -static char HeaderPart5[] = "\r\nLast-modified: "; -static char HeaderPart7[] = "\r\nContent-length: "; -static char HeaderPart9[] = "\r\n\r\n"; - -#ifdef BENCHMARK -/* In BENCHMARK-mode, just send the bare essentials */ -void SendHTTPHeader(struct http_request *Request) -{ - struct msghdr msg; - mm_segment_t oldfs; - struct iovec iov[9]; - int len,len2; - - - EnterFunction("SendHTTPHeader"); - - msg.msg_name = 0; - msg.msg_namelen = 0; - msg.msg_iov = &iov[0]; - msg.msg_iovlen = 6; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = 0; /* Synchronous for now */ - - iov[0].iov_base = HeaderPart1b; - iov[0].iov_len = 15; - iov[1].iov_base = HeaderPart3; - iov[1].iov_len = 16; - iov[2].iov_base = Request->MimeType; - iov[2].iov_len = Request->MimeLength; - - iov[3].iov_base = HeaderPart7; - iov[3].iov_len = 18; - - - sprintf(Request->LengthS,"%i",Request->FileLength); - iov[4].iov_base = Request->LengthS; - iov[4].iov_len = strlen(Request->LengthS); - iov[5].iov_base = HeaderPart9; - iov[5].iov_len = 4; - - len2=15+16+18+iov[2].iov_len+iov[4].iov_len+4; - - - len = 0; - - - oldfs = get_fs(); set_fs(KERNEL_DS); - len = sock_sendmsg(Request->sock,&msg,len2); - set_fs(oldfs); - - - return; -} -#else -void SendHTTPHeader(struct http_request *Request) -{ - struct msghdr msg; - mm_segment_t oldfs; - struct iovec iov[9]; - int len,len2; - __kernel_size_t slen; - - EnterFunction("SendHTTPHeader"); - - msg.msg_name = 0; - msg.msg_namelen = 0; - msg.msg_iov = &(iov[0]); - msg.msg_iovlen = 9; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = 0; /* Synchronous for now */ - - iov[0].iov_base = HeaderPart1; - iov[0].iov_len = 45; - iov[1].iov_base = CurrentTime; - iov[1].iov_len = 29; - iov[2].iov_base = HeaderPart3; - iov[2].iov_len = 16; - - iov[3].iov_base = Request->MimeType; - iov[3].iov_len = Request->MimeLength; - - iov[4].iov_base = HeaderPart5; - iov[4].iov_len = 17; - iov[5].iov_base = &(Request->TimeS[0]); - iov[5].iov_len = 29; - iov[6].iov_base = HeaderPart7; - iov[6].iov_len = 18; - iov[7].iov_base = &(Request->LengthS[0]); - slen = strlen(Request->LengthS); - iov[7].iov_len = slen; - iov[8].iov_base = HeaderPart9; - iov[8].iov_len = 4; - - len2=45+2*29+16+17+18+slen+4+iov[3].iov_len; - - len = 0; - - oldfs = get_fs(); set_fs(KERNEL_DS); - len = sock_sendmsg(Request->sock,&msg,len2); - set_fs(oldfs); - LeaveFunction("SendHTTPHeader"); - - - return; -} -#endif - - - -/* - -Parse a HTTP-header. Be careful for buffer-overflows here, this is the most important -place for this, since the remote-user controls the data. - -*/ -void ParseHeader(char *Buffer,const int length, struct http_request *Head) -{ - char *Endval,*EOL,*tmp; - - EnterFunction("ParseHeader"); - Endval = Buffer + length; - - /* We want to parse only the first header if multiple headers are present */ - tmp = strstr(Buffer,"\r\n\r\n"); - if (tmp!=NULL) - Endval = tmp; - - - while (Buffer<Endval) - { - if (isspace(Buffer[0])) - { - Buffer++; - continue; - } - - - EOL=strchr(Buffer,'\n'); - - if (EOL==NULL) EOL=Endval; - - if (EOL-Buffer<4) - { - Buffer++; - continue; - } - - if (strncmp("GET ",Buffer,4)==0) - { - int PrefixLen; - Buffer+=4; - - tmp=strchr(Buffer,' '); - if (tmp==0) - { - tmp=EOL-1; - Head->HTTPVER = 9; - } else - Head->HTTPVER = 10; - - if (tmp>Endval) continue; - - strncpy(Head->FileName,sysctl_khttpd_docroot,sizeof(Head->FileName)); - PrefixLen = strlen(sysctl_khttpd_docroot); - Head->FileNameLength = min_t(unsigned int, 255, tmp - Buffer + PrefixLen); - - strncat(Head->FileName,Buffer,min_t(unsigned int, 255 - PrefixLen, tmp - Buffer)); - - Buffer=EOL+1; -#ifdef BENCHMARK - break; -#endif - continue; - } -#ifndef BENCHMARK - if (strncmp("If-Modified-Since: ",Buffer,19)==0) - { - Buffer+=19; - - strncpy(Head->IMS,Buffer,min_t(unsigned int, 127,EOL-Buffer-1)); - - Buffer=EOL+1; - continue; - } - - if (strncmp("User-Agent: ",Buffer,12)==0) - { - Buffer+=12; - - strncpy(Head->Agent,Buffer,min_t(unsigned int, 127,EOL-Buffer-1)); - - Buffer=EOL+1; - continue; - } - - - if (strncmp("Host: ",Buffer,6)==0) - { - Buffer+=6; - - strncpy(Head->Host,Buffer,min_t(unsigned int, 127,EOL-Buffer-1)); - - Buffer=EOL+1; - continue; - } -#endif - Buffer = EOL+1; /* Skip line */ - } - LeaveFunction("ParseHeader"); -} diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/rfc_time.c linux/net/khttpd/rfc_time.c --- linux-2.4.19-pre8/net/khttpd/rfc_time.c Fri May 3 13:35:37 2002 +++ linux/net/khttpd/rfc_time.c Thu Jan 1 01:00:00 1970 @@ -1,227 +0,0 @@ -/* - -Functions related to time: - -1) rfc (string) time to unix-time -2) unix-time to rfc (string) time -3) current time to rfc (string) time for the "Date:" header - -*/ - -/**************************************************************** - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - ****************************************************************/ - -#include <linux/time.h> -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/ctype.h> - - -#include "times.h" -#include "prototypes.h" -static char *dayName[7] = { - "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" -}; - -static char *monthName[12] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" -}; - - -char CurrentTime[64]; -int CurrentTime_i; - - -static char itoa_h[60]={'0','0','0','0','0','0','0','0','0','0', - '1','1','1','1','1','1','1','1','1','1', - '2','2','2','2','2','2','2','2','2','2', - '3','3','3','3','3','3','3','3','3','3', - '4','4','4','4','4','4','4','4','4','4', - '5','5','5','5','5','5','5','5','5','5'}; - -static char itoa_l[60]={'0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9'}; -void time_Unix2RFC(const time_t Zulu,char *Buffer) -{ - int Y=0,M=0,D=0; - int H=0,Min=0,S=0,WD=0; - int I,I2; - time_t rest; - - - - I=0; - while (I<KHTTPD_NUMYEARS) - { - if (TimeDays[I][0]>Zulu) - break; - I++; - } - - Y=--I; - if (I<0) - { - Y=0; - goto BuildYear; - } - I2=0; - while (I2<=12) - { - if (TimeDays[I][I2]>Zulu) - break; - I2++; - } - - M=I2-1; - - rest=Zulu - TimeDays[Y][M]; - WD=WeekDays[Y][M]; - D=rest/86400; - rest=rest%86400; - WD+=D; - WD=WD%7; - H=rest/3600; - rest=rest%3600; - Min=rest/60; - rest=rest%60; - S=rest; - -BuildYear: - Y+=KHTTPD_YEAROFFSET; - - - /* Format: Day, 01 Mon 1999 01:01:01 GMT */ - -/* - We want to do - - sprintf( Buffer, "%s, %02i %s %04i %02i:%02i:%02i GMT", - dayName[ WD ], D+1, monthName[ M ], Y, - H, Min, S - ); - - but this is very expensive. Since the string is fixed length, - it is filled manually. -*/ - Buffer[0]=dayName[WD][0]; - Buffer[1]=dayName[WD][1]; - Buffer[2]=dayName[WD][2]; - Buffer[3]=','; - Buffer[4]=' '; - Buffer[5]=itoa_h[D+1]; - Buffer[6]=itoa_l[D+1]; - Buffer[7]=' '; - Buffer[8]=monthName[M][0]; - Buffer[9]=monthName[M][1]; - Buffer[10]=monthName[M][2]; - Buffer[11]=' '; - Buffer[12]=itoa_l[Y/1000]; - Buffer[13]=itoa_l[(Y/100)%10]; - Buffer[14]=itoa_l[(Y/10)%10]; - Buffer[15]=itoa_l[Y%10]; - Buffer[16]=' '; - Buffer[17]=itoa_h[H]; - Buffer[18]=itoa_l[H]; - Buffer[19]=':'; - Buffer[20]=itoa_h[Min]; - Buffer[21]=itoa_l[Min]; - Buffer[22]=':'; - Buffer[23]=itoa_h[S]; - Buffer[24]=itoa_l[S]; - Buffer[25]=' '; - Buffer[26]='G'; - Buffer[27]='M'; - Buffer[28]='T'; - Buffer[29]=0; - - - - -} - -void UpdateCurrentDate(void) -{ - struct timeval tv; - - do_gettimeofday(&tv); - if (CurrentTime_i!=tv.tv_sec) - time_Unix2RFC(tv.tv_sec,CurrentTime); - - CurrentTime_i = tv.tv_sec; -} - -static int MonthHash[32] = {0,0,7,0,0,0,0,0,0,0,0,3,0,0,0,2,6,0,5,0,9,8,4,0,0,11,1,10,0,0,0,0}; - -#define is_digit(c) ((c) >= '0' && (c) <= '9') - -__inline static int skip_atoi(char **s) -{ - int i=0; - - while (is_digit(**s)) - i = i*10 + *((*s)++) - '0'; - return i; -} - -time_t mimeTime_to_UnixTime(char *Q) -{ - int Y,M,D,H,Min,S; - unsigned int Hash; - time_t Temp; - char *s,**s2; - - s=Q; - s2=&s; - - if (strlen(s)<30) return 0; - if (s[3]!=',') return 0; - if (s[19]!=':') return 0; - - s+=5; /* Skip day of week */ - D = skip_atoi(s2); /* Day of month */ - s++; - Hash = (unsigned char)s[0]+(unsigned char)s[2]; - Hash = (Hash<<1) + (unsigned char)s[1]; - Hash = (Hash&63)>>1; - M = MonthHash[Hash]; - s+=4; - Y = skip_atoi(s2); /* Year */ - s++; - H = skip_atoi(s2); /* Hour */ - s++; - Min = skip_atoi(s2); /* Minutes */ - s++; - S = skip_atoi(s2); /* Seconds */ - s++; - if ((s[0]!='G')||(s[1]!='M')||(s[2]!='T')) - { - return 0; /* No GMT */ - } - - if (Y<KHTTPD_YEAROFFSET) Y = KHTTPD_YEAROFFSET; - if (Y>KHTTPD_YEAROFFSET+9) Y = KHTTPD_YEAROFFSET+9; - - Temp = TimeDays[Y-KHTTPD_YEAROFFSET][M]; - Temp += D*86400+H*3600+Min*60+S; - - return Temp; -} diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/security.c linux/net/khttpd/security.c --- linux-2.4.19-pre8/net/khttpd/security.c Fri May 3 13:35:31 2002 +++ linux/net/khttpd/security.c Thu Jan 1 01:00:00 1970 @@ -1,267 +0,0 @@ -/* - -kHTTPd -- the next generation - -Permissions/Security functions - -*/ - -/**************************************************************** - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - ****************************************************************/ - - -#include <linux/kernel.h> - -#include <linux/errno.h> -#include <linux/slab.h> -#include <linux/net.h> -#include <linux/sched.h> -#include <linux/skbuff.h> -#include <linux/smp_lock.h> -#include <linux/un.h> -#include <linux/unistd.h> - -#include <net/ip.h> -#include <net/sock.h> -#include <net/tcp.h> - -#include <asm/atomic.h> -#include <asm/semaphore.h> -#include <asm/processor.h> -#include <asm/uaccess.h> - -#include <linux/file.h> - -#include "sysctl.h" -#include "security.h" -#include "prototypes.h" - -/* - -The basic security function answers "Userspace" when any one of the following -conditions is met: - -1) The filename contains a "?" (this is before % decoding, all others are - after % decoding) -2) The filename doesn't start with a "/" -3) The file does not exist -4) The file does not have enough permissions - (sysctl-configurable, default = worldreadble) -5) The file has any of the "forbidden" permissions - (sysctl-configurable, default = execute, directory and sticky) -6) The filename contains a string as defined in the "Dynamic" list. - -*/ - - -/* Prototypes */ - -static void DecodeHexChars(char *URL); -static struct DynamicString *DynamicList=NULL; - - - -/* - -The function "OpenFileForSecurity" returns either the "struct file" pointer -of the file, or NULL. NULL means "let userspace handle it". - -*/ -struct file *OpenFileForSecurity(char *Filename) -{ - struct file *filp; - struct DynamicString *List; - umode_t permission; - - - - EnterFunction("OpenFileForSecurity"); - if (Filename==NULL) - return NULL; - - if (strlen(Filename)>=256 ) return NULL; /* Sanity check */ - - /* Rule no. 1 -- No "?" characters */ -#ifndef BENCHMARK - if (strchr(Filename,'?')!=NULL) - return NULL; - - /* Intermediate step: decode all %hex sequences */ - - DecodeHexChars(Filename); - - /* Rule no. 2 -- Must start with a "/" */ - - - if (Filename[0]!='/') - return NULL; - -#endif - /* Rule no. 3 -- Does the file exist ? */ - - filp = filp_open(Filename, O_RDONLY, 0); - - if (IS_ERR(filp)) - return NULL; - -#ifndef BENCHMARK - permission = filp->f_dentry->d_inode->i_mode; - - /* Rule no. 4 : must have enough permissions */ - - - if ((permission & sysctl_khttpd_permreq)==0) - { - if (filp!=NULL) - fput(filp); - filp=NULL; - return NULL; - } - - /* Rule no. 5 : cannot have "forbidden" permission */ - - - if ((permission & sysctl_khttpd_permforbid)!=0) - { - if (filp!=NULL) - fput(filp); - filp=NULL; - return NULL; - } - - /* Rule no. 6 : No string in DynamicList can be a - substring of the filename */ - - - List = DynamicList; - - while (List!=NULL) - { - if (strstr(Filename,List->value)!=NULL) - { - if (filp!=NULL) - fput(filp); - filp=NULL; - return NULL; - } - List = List->Next; - } - -#endif - LeaveFunction("OpenFileForSecurity - success"); - - return filp; -} - -/* - -DecodeHexChars does the actual %HEX decoding, in place. -In place is possible because strings only get shorter by this. - -*/ -static void DecodeHexChars(char *URL) -{ - char *Source,*Dest; - int val,val2; - - EnterFunction("DecodeHexChars"); - - Source = strchr(URL,'%'); - - if (Source==NULL) - return; - - Dest = Source; - - while (*Source!=0) - { - if (*Source=='%') - { - Source++; - val = *Source; - - if (val>'Z') val-=0x20; - val = val - '0'; - if (val<0) val=0; - if (val>9) val-=7; - if (val>15) val=15; - - Source++; - - val2 = *Source; - - if (val2>'Z') val2-=0x20; - val2 = val2 - '0'; - if (val2<0) val2=0; - if (val2>9) val2-=7; - if (val2>15) val2=15; - - *Dest=val*16+val2; - } else *Dest = *Source; - Dest++; - Source++; - } - *Dest=0; - - LeaveFunction("DecodeHexChars"); -} - - -void AddDynamicString(const char *String) -{ - struct DynamicString *Temp; - - EnterFunction("AddDynamicString"); - - Temp = (struct DynamicString*)kmalloc(sizeof(struct DynamicString),(int)GFP_KERNEL); - - if (Temp==NULL) - return; - - memset(Temp->value,0,sizeof(Temp->value)); - strncpy(Temp->value,String,sizeof(Temp->value)-1); - - Temp->Next = DynamicList; - DynamicList = Temp; - - LeaveFunction("AddDynamicString"); -} - -void GetSecureString(char *String) -{ - struct DynamicString *Temp; - int max; - - EnterFunction("GetSecureString"); - - *String = 0; - - memset(String,0,255); - - strncpy(String,"Dynamic strings are : -",255); - Temp = DynamicList; - while (Temp!=NULL) - { - max=253 - strlen(String) - strlen(Temp->value); - strncat(String,Temp->value,max); - max=253 - strlen(String) - 3; - strncat(String,"- -",max); - Temp = Temp->Next; - } - - LeaveFunction("GetSecureString"); -} diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/security.h linux/net/khttpd/security.h --- linux-2.4.19-pre8/net/khttpd/security.h Fri May 3 13:35:46 2002 +++ linux/net/khttpd/security.h Thu Jan 1 01:00:00 1970 @@ -1,12 +0,0 @@ -#ifndef _INCLUDE_GUARD_SECURITY_H -#define _INCLUDE_GUARD_SECURITY_H - -struct DynamicString; - -struct DynamicString -{ - struct DynamicString* Next; - char value[32-sizeof(void*)]; /* fill 1 cache-line */ -}; - -#endif diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/sockets.c linux/net/khttpd/sockets.c --- linux-2.4.19-pre8/net/khttpd/sockets.c Fri May 3 13:35:39 2002 +++ linux/net/khttpd/sockets.c Thu Jan 1 01:00:00 1970 @@ -1,101 +0,0 @@ -/* - -kHTTPd -- the next generation - -Basic socket functions - -*/ -/**************************************************************** - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - ****************************************************************/ - -#include "prototypes.h" -#include <linux/kernel.h> -#include <linux/net.h> -#include <linux/version.h> -#include <linux/smp_lock.h> -#include <net/sock.h> - - -/* - -MainSocket is shared by all threads, therefore it has to be -a global variable. - -*/ -struct socket *MainSocket=NULL; - - -int StartListening(const int Port) -{ - struct socket *sock; - struct sockaddr_in sin; - int error; - - EnterFunction("StartListening"); - - /* First create a socket */ - - error = sock_create(PF_INET,SOCK_STREAM,IPPROTO_TCP,&sock); - if (error<0) - (void)printk(KERN_ERR "Error during creation of socket; terminating\n"); - - - - /* Now bind the socket */ - - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = INADDR_ANY; - sin.sin_port = htons((unsigned short)Port); - - error = sock->ops->bind(sock,(struct sockaddr*)&sin,sizeof(sin)); - if (error<0) - { - (void)printk(KERN_ERR "kHTTPd: Error binding socket. This means that some other \n"); - (void)printk(KERN_ERR " daemon is (or was a short time ago) using port %i.\n",Port); - return 0; - } - - /* Grrr... setsockopt() does this. */ - sock->sk->reuse = 1; - - /* Now, start listening on the socket */ - - /* I have no idea what a sane backlog-value is. 48 works so far. */ - - error=sock->ops->listen(sock,48); - if (error!=0) - (void)printk(KERN_ERR "kHTTPd: Error listening on socket \n"); - - MainSocket = sock; - - LeaveFunction("StartListening"); - return 1; -} - -void StopListening(void) -{ - struct socket *sock; - - EnterFunction("StopListening"); - if (MainSocket==NULL) return; - - sock=MainSocket; - MainSocket = NULL; - sock_release(sock); - - LeaveFunction("StopListening"); -} diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/structure.h linux/net/khttpd/structure.h --- linux-2.4.19-pre8/net/khttpd/structure.h Fri May 3 13:34:57 2002 +++ linux/net/khttpd/structure.h Thu Jan 1 01:00:00 1970 @@ -1,68 +0,0 @@ -#ifndef _INCLUDE_GUARD_STRUCTURE_H_ -#define _INCLUDE_GUARD_STRUCTURE_H_ - -#include <linux/time.h> -#include <linux/wait.h> - - -struct http_request; - -struct http_request -{ - /* Linked list */ - struct http_request *Next; - - /* Network and File data */ - struct socket *sock; - struct file *filp; - - /* Raw data about the file */ - - int FileLength; /* File length in bytes */ - int Time; /* mtime of the file, unix format */ - int BytesSent; /* The number of bytes already sent */ - int IsForUserspace; /* 1 means let Userspace handle this one */ - - /* Wait queue */ - - wait_queue_t sleep; /* For putting in the socket's waitqueue */ - - /* HTTP request information */ - char FileName[256]; /* The requested filename */ - int FileNameLength; /* The length of the string representing the filename */ - char Agent[128]; /* The agent-string of the remote browser */ - char IMS[128]; /* If-modified-since time, rfc string format */ - char Host[128]; /* Value given by the Host: header */ - int HTTPVER; /* HTTP-version; 9 for 0.9, 10 for 1.0 and above */ - - - /* Derived date from the above fields */ - int IMS_Time; /* if-modified-since time, unix format */ - char TimeS[64]; /* File mtime, rfc string representation */ - char LengthS[14]; /* File length, string representation */ - char *MimeType; /* Pointer to a string with the mime-type - based on the filename */ - __kernel_size_t MimeLength; /* The length of this string */ - -}; - - - -/* - -struct khttpd_threadinfo represents the four queues that 1 thread has to deal with. -It is padded to occupy 1 (Intel) cache-line, to avoid "cacheline-pingpong". - -*/ -struct khttpd_threadinfo -{ - struct http_request* WaitForHeaderQueue; - struct http_request* DataSendingQueue; - struct http_request* LoggingQueue; - struct http_request* UserspaceQueue; - char dummy[16]; /* Padding for cache-lines */ -}; - - - -#endif diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/sysctl.c linux/net/khttpd/sysctl.c --- linux-2.4.19-pre8/net/khttpd/sysctl.c Fri May 3 13:39:20 2002 +++ linux/net/khttpd/sysctl.c Thu Jan 1 01:00:00 1970 @@ -1,320 +0,0 @@ -/* - -kHTTPd -- the next generation - -Sysctl interface - -*/ -/**************************************************************** - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - ****************************************************************/ - - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/slab.h> -#include <linux/net.h> -#include <linux/sched.h> -#include <linux/skbuff.h> -#include <linux/smp_lock.h> -#include <linux/sysctl.h> -#include <linux/un.h> -#include <linux/unistd.h> - -#include <net/ip.h> -#include <net/sock.h> -#include <net/tcp.h> - -#include <asm/atomic.h> -#include <asm/semaphore.h> -#include <asm/processor.h> -#include <asm/uaccess.h> - -#include <linux/file.h> -#include "prototypes.h" - - - -char sysctl_khttpd_docroot[200] = "/var/www"; -int sysctl_khttpd_stop = 0; -int sysctl_khttpd_start = 0; -int sysctl_khttpd_unload = 0; -int sysctl_khttpd_clientport = 80; -int sysctl_khttpd_permreq = S_IROTH; /* "other" read-access is required by default*/ -int sysctl_khttpd_permforbid = S_IFDIR | S_ISVTX | S_IXOTH | S_IXGRP | S_IXUSR; - /* forbidden is execute, directory and sticky*/ -int sysctl_khttpd_logging = 0; -int sysctl_khttpd_serverport= 8080; - -char sysctl_khttpd_dynamicstring[200]; -int sysctl_khttpd_sloppymime= 0; -int sysctl_khttpd_threads = 2; -int sysctl_khttpd_maxconnect = 1000; - - -static struct ctl_table_header *khttpd_table_header; - -static int sysctl_SecureString(ctl_table *table, int *name, int nlen, - void *oldval, size_t *oldlenp, - void *newval, size_t newlen, void **context); -static int proc_dosecurestring(ctl_table *table, int write, struct file *filp, - void *buffer, size_t *lenp); - - -static ctl_table khttpd_table[] = { - { NET_KHTTPD_DOCROOT, - "documentroot", - &sysctl_khttpd_docroot, - sizeof(sysctl_khttpd_docroot), - 0644, - NULL, - proc_dostring, - &sysctl_string, - NULL, - NULL, - NULL - }, - { NET_KHTTPD_STOP, - "stop", - &sysctl_khttpd_stop, - sizeof(int), - 0644, - NULL, - proc_dointvec, - &sysctl_intvec, - NULL, - NULL, - NULL - }, - { NET_KHTTPD_START, - "start", - &sysctl_khttpd_start, - sizeof(int), - 0644, - NULL, - proc_dointvec, - &sysctl_intvec, - NULL, - NULL, - NULL - }, - { NET_KHTTPD_UNLOAD, - "unload", - &sysctl_khttpd_unload, - sizeof(int), - 0644, - NULL, - proc_dointvec, - &sysctl_intvec, - NULL, - NULL, - NULL - }, - { NET_KHTTPD_THREADS, - "threads", - &sysctl_khttpd_threads, - sizeof(int), - 0644, - NULL, - proc_dointvec, - &sysctl_intvec, - NULL, - NULL, - NULL - }, - { NET_KHTTPD_MAXCONNECT, - "maxconnect", - &sysctl_khttpd_maxconnect, - sizeof(int), - 0644, - NULL, - proc_dointvec, - &sysctl_intvec, - NULL, - NULL, - NULL - }, - { NET_KHTTPD_SLOPPYMIME, - "sloppymime", - &sysctl_khttpd_sloppymime, - sizeof(int), - 0644, - NULL, - proc_dointvec, - &sysctl_intvec, - NULL, - NULL, - NULL - }, - { NET_KHTTPD_CLIENTPORT, - "clientport", - &sysctl_khttpd_clientport, - sizeof(int), - 0644, - NULL, - proc_dointvec, - &sysctl_intvec, - NULL, - NULL, - NULL - }, - { NET_KHTTPD_PERMREQ, - "perm_required", - &sysctl_khttpd_permreq, - sizeof(int), - 0644, - NULL, - proc_dointvec, - &sysctl_intvec, - NULL, - NULL, - NULL - }, - { NET_KHTTPD_PERMFORBID, - "perm_forbid", - &sysctl_khttpd_permforbid, - sizeof(int), - 0644, - NULL, - proc_dointvec, - &sysctl_intvec, - NULL, - NULL, - NULL - }, - { NET_KHTTPD_LOGGING, - "logging", - &sysctl_khttpd_logging, - sizeof(int), - 0644, - NULL, - proc_dointvec, - &sysctl_intvec, - NULL, - NULL, - NULL - }, - { NET_KHTTPD_SERVERPORT, - "serverport", - &sysctl_khttpd_serverport, - sizeof(int), - 0644, - NULL, - proc_dointvec, - &sysctl_intvec, - NULL, - NULL, - NULL - }, - { NET_KHTTPD_DYNAMICSTRING, - "dynamic", - &sysctl_khttpd_dynamicstring, - sizeof(sysctl_khttpd_dynamicstring), - 0644, - NULL, - proc_dosecurestring, - &sysctl_SecureString, - NULL, - NULL, - NULL - }, - {0,0,0,0,0,0,0,0,0,0,0} }; - - -static ctl_table khttpd_dir_table[] = { - {NET_KHTTPD, "khttpd", NULL, 0, 0555, khttpd_table,0,0,0,0,0}, - {0,0,0,0,0,0,0,0,0,0,0} -}; - -static ctl_table khttpd_root_table[] = { - {CTL_NET, "net", NULL, 0, 0555, khttpd_dir_table,0,0,0,0,0}, - {0,0,0,0,0,0,0,0,0,0,0} -}; - - -void StartSysctl(void) -{ - khttpd_table_header = register_sysctl_table(khttpd_root_table,1); -} - - -void EndSysctl(void) -{ - unregister_sysctl_table(khttpd_table_header); -} - -static int proc_dosecurestring(ctl_table *table, int write, struct file *filp, - void *buffer, size_t *lenp) -{ - size_t len; - char *p, c=0; - char String[256]; - - if ((table->data==0) || (table->maxlen==0) || (*lenp==0) || - ((filp->f_pos!=0) && (write==0))) { - *lenp = 0; - return 0; - } - - if (write!=0) { - len = 0; - p = buffer; - while (len < *lenp) { - if(get_user(c, p++)) - return -EFAULT; - if (c == 0 || c == '\n') - break; - len++; - } - if (len >= table->maxlen) - len = table->maxlen-1; - if(copy_from_user(String, buffer,(unsigned long)len)) - return -EFAULT; - ((char *) String)[len] = 0; - filp->f_pos += *lenp; - AddDynamicString(String); - } else { - GetSecureString(String); - len = strlen(String); - if (len > table->maxlen) - len = table->maxlen; - if (len > *lenp) - len = *lenp; - if (len!=0) - if(copy_to_user(buffer, String,(unsigned long)len)) - return -EFAULT; - if (len < *lenp) { - if(put_user('\n', ((char *) buffer) + len)) - return -EFAULT; - len++; - } - *lenp = len; - filp->f_pos += len; - } - return 0; -} - -static int sysctl_SecureString (/*@unused@*/ctl_table *table, - /*@unused@*/int *name, - /*@unused@*/int nlen, - /*@unused@*/void *oldval, - /*@unused@*/size_t *oldlenp, - /*@unused@*/void *newval, - /*@unused@*/size_t newlen, - /*@unused@*/void **context) -{ - return -ENOSYS; -} diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/sysctl.h linux/net/khttpd/sysctl.h --- linux-2.4.19-pre8/net/khttpd/sysctl.h Fri May 3 13:36:47 2002 +++ linux/net/khttpd/sysctl.h Thu Jan 1 01:00:00 1970 @@ -1,17 +0,0 @@ -#ifndef _KHTTPD_INCLUDE_GUARD_SYSCTL_H -#define _KHTTPD_INCLUDE_GUARD_SYSCTL_H - -extern char sysctl_khttpd_docroot[200]; -extern int sysctl_khttpd_stop; -extern int sysctl_khttpd_start; -extern int sysctl_khttpd_unload; -extern int sysctl_khttpd_clientport; -extern int sysctl_khttpd_permreq; -extern int sysctl_khttpd_permforbid; -extern int sysctl_khttpd_logging; -extern int sysctl_khttpd_serverport; -extern int sysctl_khttpd_sloppymime; -extern int sysctl_khttpd_threads; -extern int sysctl_khttpd_maxconnect; - -#endif diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/userspace.c linux/net/khttpd/userspace.c --- linux-2.4.19-pre8/net/khttpd/userspace.c Fri May 3 13:35:53 2002 +++ linux/net/khttpd/userspace.c Thu Jan 1 01:00:00 1970 @@ -1,243 +0,0 @@ -/* - -kHTTPd -- the next generation - -Pass connections to userspace-daemons - -*/ -/**************************************************************** - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - ****************************************************************/ - -/* - -Purpose: - -Userspace() hands all requests in the queue to the userspace-daemon, if -such beast exists. - -Return value: - The number of requests that changed status -*/ -#include <linux/kernel.h> - -#include <linux/errno.h> -#include <linux/slab.h> -#include <linux/net.h> -#include <linux/sched.h> -#include <linux/skbuff.h> -#include <linux/smp_lock.h> -#include <linux/un.h> -#include <linux/unistd.h> -#include <linux/wait.h> - -#include <net/ip.h> -#include <net/sock.h> -#include <net/tcp.h> - -#include <asm/atomic.h> -#include <asm/semaphore.h> -#include <asm/processor.h> -#include <asm/uaccess.h> - -#include <linux/file.h> - - -#include "structure.h" -#include "prototypes.h" -#include "sysctl.h" - -/* prototypes of local, static functions */ -static int AddSocketToAcceptQueue(struct socket *sock,const int Port); - - -int Userspace(const int CPUNR) -{ - struct http_request *CurrentRequest,**Prev,*Next; - - EnterFunction("Userspace"); - - - - - CurrentRequest = threadinfo[CPUNR].UserspaceQueue; - Prev = &(threadinfo[CPUNR].UserspaceQueue); - - while (CurrentRequest!=NULL) - { - - /* Clean-up the waitqueue of the socket.. Bad things happen if - this is forgotten. */ - if (CurrentRequest->sock!=NULL) - { - if ((CurrentRequest->sock!=NULL)&&(CurrentRequest->sock->sk!=NULL)) - { - remove_wait_queue(CurrentRequest->sock->sk->sleep,&(CurrentRequest->sleep)); - } - } - - - if (AddSocketToAcceptQueue(CurrentRequest->sock,sysctl_khttpd_clientport)>=0) - { - - (*Prev) = CurrentRequest->Next; - Next = CurrentRequest->Next; - - - sock_release(CurrentRequest->sock); - CurrentRequest->sock = NULL; /* We no longer own it */ - - CleanUpRequest(CurrentRequest); - - CurrentRequest = Next; - continue; - - } - else /* No userspace-daemon present, or other problems with it */ - { - (*Prev) = CurrentRequest->Next; - Next = CurrentRequest->Next; - - Send403(CurrentRequest->sock); /* Sorry, no go... */ - - CleanUpRequest(CurrentRequest); - - CurrentRequest = Next; - continue; - - } - - - Prev = &(CurrentRequest->Next); - CurrentRequest = CurrentRequest->Next; - } - - LeaveFunction("Userspace"); - return 0; -} - -void StopUserspace(const int CPUNR) -{ - struct http_request *CurrentRequest,*Next; - - EnterFunction("StopUserspace"); - CurrentRequest = threadinfo[CPUNR].UserspaceQueue; - - while (CurrentRequest!=NULL) - { - Next= CurrentRequest->Next; - CleanUpRequest(CurrentRequest); - CurrentRequest=Next; - } - threadinfo[CPUNR].UserspaceQueue = NULL; - - LeaveFunction("StopUserspace"); -} - - -/* - "FindUserspace" returns the struct sock of the userspace-daemon, so that we can - "drop" our request in the accept-queue -*/ - -static struct sock *FindUserspace(const unsigned short Port) -{ - struct sock *sk; - - EnterFunction("FindUserspace"); - - local_bh_disable(); - sk = tcp_v4_lookup_listener(INADDR_ANY,Port,0); - local_bh_enable(); - return sk; -} - -static void dummy_destructor(struct open_request *req) -{ -} - -static struct or_calltable Dummy = -{ - 0, - NULL, - NULL, - &dummy_destructor, - NULL -}; - -static int AddSocketToAcceptQueue(struct socket *sock,const int Port) -{ - struct open_request *req; - struct sock *sk, *nsk; - - EnterFunction("AddSocketToAcceptQueue"); - - - sk = FindUserspace((unsigned short)Port); - - if (sk==NULL) /* No userspace-daemon found */ - { - return -1; - } - - lock_sock(sk); - - if (sk->state != TCP_LISTEN || tcp_acceptq_is_full(sk)) - { - release_sock(sk); - sock_put(sk); - return -1; - } - - req = tcp_openreq_alloc(); - - if (req==NULL) - { - release_sock(sk); - sock_put(sk); - return -1; - } - - nsk = sock->sk; - sock->sk = NULL; - sock->state = SS_UNCONNECTED; - - req->class = &Dummy; - write_lock_bh(&nsk->callback_lock); - nsk->socket = NULL; - nsk->sleep = NULL; - write_unlock_bh(&nsk->callback_lock); - - tcp_acceptq_queue(sk, req, nsk); - - sk->data_ready(sk, 0); - - release_sock(sk); - sock_put(sk); - - LeaveFunction("AddSocketToAcceptQueue"); - - return +1; - - - -} - -void InitUserspace(const int CPUNR) -{ -} - - diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/waitheaders.c linux/net/khttpd/waitheaders.c --- linux-2.4.19-pre8/net/khttpd/waitheaders.c Fri May 3 13:36:59 2002 +++ linux/net/khttpd/waitheaders.c Thu Jan 1 01:00:00 1970 @@ -1,296 +0,0 @@ -/* - -kHTTPd -- the next generation - -Wait for headers on the accepted connections - -*/ -/**************************************************************** - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - ****************************************************************/ - -/* - -Purpose: - -WaitForHeaders polls all connections in "WaitForHeaderQueue" to see if -headers have arived. If so, the headers are decoded and the request is -moved to either the "SendingDataQueue" or the "UserspaceQueue". - -Return value: - The number of requests that changed status -*/ - -#include <linux/config.h> -#include <linux/kernel.h> -#include <linux/skbuff.h> -#include <linux/smp_lock.h> -#include <linux/file.h> - -#include <asm/uaccess.h> - -#include "structure.h" -#include "prototypes.h" - -static char *Buffer[CONFIG_KHTTPD_NUMCPU]; - - -static int DecodeHeader(const int CPUNR, struct http_request *Request); - - -int WaitForHeaders(const int CPUNR) -{ - struct http_request *CurrentRequest,**Prev; - struct sock *sk; - int count = 0; - - EnterFunction("WaitForHeaders"); - - CurrentRequest = threadinfo[CPUNR].WaitForHeaderQueue; - - Prev = &(threadinfo[CPUNR].WaitForHeaderQueue); - - while (CurrentRequest!=NULL) - { - - /* If the connection is lost, remove from queue */ - - if (CurrentRequest->sock->sk->state != TCP_ESTABLISHED - && CurrentRequest->sock->sk->state != TCP_CLOSE_WAIT) - { - struct http_request *Next; - - Next = CurrentRequest->Next; - - *Prev = CurrentRequest->Next; - CurrentRequest->Next = NULL; - - - CleanUpRequest(CurrentRequest); - CurrentRequest = Next; - continue; - } - - - - /* If data pending, take action */ - - sk = CurrentRequest->sock->sk; - - if (!skb_queue_empty(&(sk->receive_queue))) /* Do we have data ? */ - { - struct http_request *Next; - - - - /* Decode header */ - - if (DecodeHeader(CPUNR,CurrentRequest)<0) - { - CurrentRequest = CurrentRequest->Next; - continue; - } - - - /* Remove from WaitForHeaderQueue */ - - Next= CurrentRequest->Next; - - *Prev = Next; - count++; - - /* Add to either the UserspaceQueue or the DataSendingQueue */ - - if (CurrentRequest->IsForUserspace!=0) - { - CurrentRequest->Next = threadinfo[CPUNR].UserspaceQueue; - threadinfo[CPUNR].UserspaceQueue = CurrentRequest; - } else - { - CurrentRequest->Next = threadinfo[CPUNR].DataSendingQueue; - threadinfo[CPUNR].DataSendingQueue = CurrentRequest; - } - - CurrentRequest = Next; - continue; - - } - - - Prev = &(CurrentRequest->Next); - CurrentRequest = CurrentRequest->Next; - } - - LeaveFunction("WaitHeaders"); - return count; -} - -void StopWaitingForHeaders(const int CPUNR) -{ - struct http_request *CurrentRequest,*Next; - - EnterFunction("StopWaitingForHeaders"); - CurrentRequest = threadinfo[CPUNR].WaitForHeaderQueue; - - while (CurrentRequest!=NULL) - { - Next = CurrentRequest->Next; - CleanUpRequest(CurrentRequest); - CurrentRequest=Next; - } - - threadinfo[CPUNR].WaitForHeaderQueue = NULL; /* The queue is empty now */ - - free_page((unsigned long)Buffer[CPUNR]); - Buffer[CPUNR]=NULL; - - EnterFunction("StopWaitingForHeaders"); -} - - -/* - -DecodeHeader peeks at the TCP/IP data, determines what the request is, -fills the request-structure and sends the HTTP-header when apropriate. - -*/ - -static int DecodeHeader(const int CPUNR, struct http_request *Request) -{ - struct msghdr msg; - struct iovec iov; - int len; - - mm_segment_t oldfs; - - EnterFunction("DecodeHeader"); - - /* First, read the data */ - - msg.msg_name = 0; - msg.msg_namelen = 0; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = 0; - - msg.msg_iov->iov_base = &Buffer[CPUNR][0]; - msg.msg_iov->iov_len = (size_t)4095; - - len = 0; - oldfs = get_fs(); set_fs(KERNEL_DS); - /* 4095 leaves a "0" to terminate the string */ - - len = sock_recvmsg(Request->sock,&msg,4095,MSG_PEEK); - set_fs(oldfs); - - if (len<0) { - /* WONDERFUL. NO COMMENTS. --ANK */ - Request->IsForUserspace = 1; - return 0; - } - - if (len>=4094) /* BIG header, we cannot decode it so leave it to userspace */ - { - Request->IsForUserspace = 1; - return 0; - } - - /* Then, decode the header */ - - - ParseHeader(Buffer[CPUNR],len,Request); - - Request->filp = OpenFileForSecurity(Request->FileName); - - - Request->MimeType = ResolveMimeType(Request->FileName,&Request->MimeLength); - - - if (Request->MimeType==NULL) /* Unknown mime-type */ - { - if (Request->filp!=NULL) - { - fput(Request->filp); - Request->filp = NULL; - } - Request->IsForUserspace = 1; - - return 0; - } - - if (Request->filp==NULL) - { - Request->IsForUserspace = 1; - return 0; - } - else - { - Request->FileLength = (int)Request->filp->f_dentry->d_inode->i_size; - Request->Time = Request->filp->f_dentry->d_inode->i_mtime; - Request->IMS_Time = mimeTime_to_UnixTime(Request->IMS); - sprintf(Request->LengthS,"%i",Request->FileLength); - time_Unix2RFC(min_t(unsigned int, Request->Time,CurrentTime_i),Request->TimeS); - /* The min() is required by rfc1945, section 10.10: - It is not allowed to send a filetime in the future */ - - if (Request->IMS_Time>Request->Time) - { /* Not modified since last time */ - Send304(Request->sock); - Request->FileLength=0; - } - else /* Normal Case */ - { - Request->sock->sk->tp_pinfo.af_tcp.nonagle = 2; /* this is TCP_CORK */ - if (Request->HTTPVER!=9) /* HTTP/0.9 doesn't allow a header */ - SendHTTPHeader(Request); - } - - - } - - LeaveFunction("DecodeHeader"); - return 0; -} - - -int InitWaitHeaders(int ThreadCount) -{ - int I,I2; - - EnterFunction("InitWaitHeaders"); - I=0; - while (I<ThreadCount) - { - Buffer[I] = (char*)get_free_page((int)GFP_KERNEL); - if (Buffer[I] == NULL) - { - printk(KERN_CRIT "kHTTPd: Not enough memory for basic needs\n"); - I2=0; - while (I2<I-1) - { - free_page( (unsigned long)Buffer[I2++]); - } - return -1; - } - I++; - } - - LeaveFunction("InitWaitHeaders"); - return 0; - -} diff -uNr -Xdontdiff linux-2.4.19-pre8/net/netsyms.c linux/net/netsyms.c --- linux-2.4.19-pre8/net/netsyms.c Fri May 3 13:37:36 2002 +++ linux/net/netsyms.c Mon May 6 12:53:39 2002 @@ -56,7 +56,7 @@ extern struct net_proto_family inet_family_ops; -#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) || defined (CONFIG_KHTTPD) || defined (CONFIG_KHTTPD_MODULE) +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) #include <linux/in6.h> #include <linux/icmpv6.h> #include <net/ipv6.h> @@ -295,7 +295,7 @@ #include <net/ip6_route.h> EXPORT_SYMBOL(ip6_route_output); #endif -#if defined (CONFIG_IPV6_MODULE) || defined (CONFIG_KHTTPD) || defined (CONFIG_KHTTPD_MODULE) +#if defined (CONFIG_IPV6_MODULE) /* inet functions common to v4 and v6 */ EXPORT_SYMBOL(inet_release); EXPORT_SYMBOL(inet_stream_connect); ^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH] Re: khttpd rotten? 2002-05-06 10:23 ` Christoph Hellwig @ 2002-05-06 11:28 ` Dan Kegel 2002-05-06 17:23 ` Luigi Genoni 2002-05-09 9:49 ` David S. Miller 2 siblings, 0 replies; 35+ messages in thread From: Dan Kegel @ 2002-05-06 11:28 UTC (permalink / raw) To: Christoph Hellwig Cc: David S. Miller, arjanv, marcelo, khttpd-users, linux-kernel Christoph Hellwig wrote: > > On Sun, May 05, 2002 at 07:39:42PM -0700, Dan Kegel wrote: > > ... I say pull it from 2.4.19-pre9. > > Marcello, put it out of its misery asap, please... > > it'd time for khttpd to become a standalone patch again. > > Okay, what about the following: > - the below patch remove khttpd from 2.4.19-pre, but lets the > sysctls in so it can compile out-of-tree > - http://verein.lst.de/~hch/khttpd/khttpd-20020506.tar.gz has a tarball > with khttpd as of 2.4.19-pre8, a simple makefile to build it and > a simple patch to allow loading it when CONFIG_IPV6 != m, > Arjan, could you please put it on the official khttpd website if one > still exists. > - for 2.5 the sysctls can go aswell That's probably good. However, I may have been a bit hasty in my general condemnation of khttpd. The following patch seems to solve the nasty problems; perhaps removing khttpd can wait a bit. (I only tested the patch briefly, but it makes a lot of sense, and it did improve things here.) - Dan diff -aur linux-2.4.19-pre8.orig/net/khttpd/README linux-2.4.19-pre8/net/khttpd/README --- linux-2.4.19-pre8.orig/net/khttpd/README Mon May 6 11:37:33 2002 +++ linux-2.4.19-pre8/net/khttpd/README Mon May 6 12:10:27 2002 @@ -44,6 +44,7 @@ echo 1 > /proc/sys/net/khttpd/stop echo 1 > /proc/sys/net/khttpd/unload + sleep 2 rmmod khttpd @@ -123,7 +124,9 @@ =============== In order to change the configuration, you should stop kHTTPd by typing echo 1 > /proc/sys/net/khttpd/stop - on a command-prompt. + sleep 2 + on a command-prompt. (The sleep makes it more likely + that all kHTTPd threads notice the stop request.) If you want to unload the module, you should type echo 1 > /proc/sys/net/khttpd/unload diff -aur linux-2.4.19-pre8.orig/net/khttpd/main.c linux-2.4.19-pre8/net/khttpd/main.c --- linux-2.4.19-pre8.orig/net/khttpd/main.c Mon May 6 11:37:33 2002 +++ linux-2.4.19-pre8/net/khttpd/main.c Mon May 6 11:48:47 2002 @@ -226,6 +226,9 @@ if ( (signal_pending(current)) || (sysctl_khttpd_unload!=0) ) break; + /* must clear 'stop' flag before starting threads! -dank */ + sysctl_khttpd_stop = 0; + /* Then start listening and spawn the daemons */ if (StartListening(sysctl_khttpd_serverport)==0) @@ -277,10 +278,20 @@ } /* Then wait for deactivation */ - sysctl_khttpd_stop = 0; while ( (sysctl_khttpd_stop==0) && (!signal_pending(current)) && (sysctl_khttpd_unload==0) ) { + +#if 0 + /* FIXME This section seems to be here to restart worker + * threads that have died for any reason, but it has a bug: + * if 'stop' is set briefly while this thread is asleep, and + * a worker thread notices, it terminates and free its buffer, + * and this thread will restart it without reallocating + * its buffer. This happened *every time* until I moved + * the 'sysctl_khttpd_stop = 0' statement up above the thread + * creation. dank@kegel.com + */ if (atomic_read(&DaemonCount)<ActualThreads) { I=0; @@ -295,6 +306,8 @@ I++; } } +#endif + interruptible_sleep_on_timeout(&WQ,HZ); /* reap the daemons */ diff -aur linux-2.4.19-pre8.orig/net/khttpd/waitheaders.c linux-2.4.19-pre8/net/khttpd/waitheaders.c --- linux-2.4.19-pre8.orig/net/khttpd/waitheaders.c Mon May 6 11:37:33 2002 +++ linux-2.4.19-pre8/net/khttpd/waitheaders.c Mon May 6 11:54:23 2002 @@ -134,7 +134,7 @@ CurrentRequest = CurrentRequest->Next; } - LeaveFunction("WaitHeaders"); + LeaveFunction("WaitForHeaders"); return count; } @@ -178,6 +178,12 @@ EnterFunction("DecodeHeader"); + if (Buffer[CPUNR] == NULL) { + /* see comments in main.c regarding buffer managemnet - dank */ + printk(KERN_CRIT "khttpd: lost my buffer"); + BUG(); + } + /* First, read the data */ msg.msg_name = 0; ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: khttpd rotten? 2002-05-06 10:23 ` Christoph Hellwig 2002-05-06 11:28 ` [PATCH] " Dan Kegel @ 2002-05-06 17:23 ` Luigi Genoni 2002-05-09 9:49 ` David S. Miller 2 siblings, 0 replies; 35+ messages in thread From: Luigi Genoni @ 2002-05-06 17:23 UTC (permalink / raw) To: Christoph Hellwig Cc: Dan Kegel, David S. Miller, arjanv, marcelo, khttpd-users, linux-kernel Oh well, I suppose I should be sorry. I have been using khttpd since more than 1 year, and it was well working for me... On Mon, 6 May 2002, Christoph Hellwig wrote: > On Sun, May 05, 2002 at 07:39:42PM -0700, Dan Kegel wrote: > > > We are going to pull it from the kernel. > > > > Right. If khttpd had been pulled from 2.4.17, I would have > > had weeks of warning that khttpd is unstable; instead, I learned > > only when someone started doing his own stress testing, and I > > have little time to fix it. I say pull it from > > 2.4.19-pre9. Marcello, put it out of its misery asap, please... > > it'd time for khttpd to become a standalone patch again. > > Okay, what about the following: > > - the below patch remove khttpd from 2.4.19-pre, but lets the > sysctls in so it can compile out-of-tree > - http://verein.lst.de/~hch/khttpd/khttpd-20020506.tar.gz has a tarball > with khttpd as of 2.4.19-pre8, a simple makefile to build it and > a simple patch to allow loading it when CONFIG_IPV6 != m, > Arjan, could you please put it on the official khttpd website if one > still exists. > - for 2.5 the sysctls can go aswell > > > diff -uNr -Xdontdiff linux-2.4.19-pre8/Documentation/Configure.help linux/Documentation/Configure.help > --- linux-2.4.19-pre8/Documentation/Configure.help Fri May 3 23:02:47 2002 > +++ linux/Documentation/Configure.help Mon May 6 13:05:24 2002 > @@ -5406,25 +5406,6 @@ > say Y to "Kernel/User network link driver" and to "Routing > messages" instead. > > -Kernel httpd acceleration > -CONFIG_KHTTPD > - The kernel httpd acceleration daemon (kHTTPd) is a (limited) web > - server built into the kernel. It is limited since it can only serve > - files from the file system and cannot deal with executable content > - such as CGI scripts. Serving files is sped up if you use kHTTPd. > - If kHTTPd is not able to fulfill a request, it can transparently > - pass it through to a user space web server such as apache. > - > - Saying "M" here builds the kHTTPd module; this is NOT enough to have > - a working kHTTPd. For safety reasons, the module has to be activated > - by doing a "echo 1 > /proc/sys/net/khttpd/start" after inserting the > - module. > - > - Before using this, read the README in net/khttpd ! > - > - The kHTTPd is experimental. Be careful when using it on a production > - machine. Also note that kHTTPd doesn't support virtual servers yet. > - > The IPX protocol > CONFIG_IPX > This is support for the Novell networking protocol, IPX, commonly > @@ -25233,7 +25214,7 @@ > # LocalWords: Unixware cymru Computone IntelliPort Intelliport computone SI sx > # LocalWords: adbmouse DRI DRM dlabs GMX PLCs Applicom fieldbus applicom int > # LocalWords: VWSND eg ESSSOLO CFU CFNR scribed eiconctrl eicon hylafax KFPU > -# LocalWords: EXTRAPREC fpu mainboards KHTTPD kHTTPd khttpd Xcelerator SBNI tw > +# LocalWords: EXTRAPREC fpu mainboards Xcelerator SBNI tw > # LocalWords: LOGIBUSMOUSE Granch granch sbni Raylink NOHIGHMEM Athlon SIM sim > # LocalWords: hpl Tourrilhes DuraLAN starfire Davicom davicom dmfe auk tms tr > # LocalWords: TokenExpress Belkin Peracom eTek DVDs infradead Cxxx Adlib AV ZX > diff -uNr -Xdontdiff linux-2.4.19-pre8/Makefile linux/Makefile > --- linux-2.4.19-pre8/Makefile Fri May 3 23:02:46 2002 > +++ linux/Makefile Mon May 6 13:05:36 2002 > @@ -214,8 +214,6 @@ > drivers/scsi/aic7xxx/aicasm/aicdb.h \ > drivers/scsi/aic7xxx/aicasm/y.tab.h \ > drivers/scsi/53c700_d.h \ > - net/khttpd/make_times_h \ > - net/khttpd/times.h \ > submenu* > # directories removed with 'make clean' > CLEAN_DIRS = \ > diff -uNr -Xdontdiff linux-2.4.19-pre8/include/linux/sysctl.h linux/include/linux/sysctl.h > --- linux-2.4.19-pre8/include/linux/sysctl.h Fri May 3 23:02:46 2002 > +++ linux/include/linux/sysctl.h Mon May 6 13:06:25 2002 > @@ -487,6 +487,8 @@ > }; > > /* /proc/sys/net/khttpd/ */ > +/* khttpd has been removed from the main kernel. > + please keep this to allow out-of-tree compilation for 2.4. --hch */ > enum { > NET_KHTTPD_DOCROOT = 1, > NET_KHTTPD_START = 2, > diff -uNr -Xdontdiff linux-2.4.19-pre8/net/Config.in linux/net/Config.in > --- linux-2.4.19-pre8/net/Config.in Fri May 3 13:36:27 2002 > +++ linux/net/Config.in Mon May 6 12:54:18 2002 > @@ -26,9 +26,6 @@ > source net/ipv6/Config.in > fi > fi > - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then > - source net/khttpd/Config.in > - fi > fi > if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then > bool 'Asynchronous Transfer Mode (ATM) (EXPERIMENTAL)' CONFIG_ATM > diff -uNr -Xdontdiff linux-2.4.19-pre8/net/Makefile linux/net/Makefile > --- linux-2.4.19-pre8/net/Makefile Fri May 3 13:37:42 2002 > +++ linux/net/Makefile Mon May 6 12:54:10 2002 > @@ -26,7 +26,6 @@ > endif > endif > > -subdir-$(CONFIG_KHTTPD) += khttpd > subdir-$(CONFIG_PACKET) += packet > subdir-$(CONFIG_NET_SCHED) += sched > subdir-$(CONFIG_BRIDGE) += bridge > diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/Config.in linux/net/khttpd/Config.in > --- linux-2.4.19-pre8/net/khttpd/Config.in Fri May 3 13:36:06 2002 > +++ linux/net/khttpd/Config.in Thu Jan 1 01:00:00 1970 > @@ -1,4 +0,0 @@ > -# > -# kHTTPd > -# > -tristate ' Kernel httpd acceleration (EXPERIMENTAL)' CONFIG_KHTTPD > diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/Makefile linux/net/khttpd/Makefile > --- linux-2.4.19-pre8/net/khttpd/Makefile Fri May 3 13:38:44 2002 > +++ linux/net/khttpd/Makefile Thu Jan 1 01:00:00 1970 > @@ -1,25 +0,0 @@ > -# > -# Makefile for kHTTPd > -# > -# Note! Dependencies are done automagically by 'make dep', which also > -# removes any old dependencies. DON'T put your own dependencies here > -# unless it's something special (ie not a .c file). > -# > -# Note 2! The CFLAGS definition is now in the main makefile... > - > -O_TARGET := khttpd.o > - > -obj-m := $(O_TARGET) > -obj-y := main.o accept.o datasending.o logging.o misc.o rfc.o rfc_time.o security.o \ > - sockets.o sysctl.o userspace.o waitheaders.o > - > - > -include $(TOPDIR)/Rules.make > - > -rfc_time.o: times.h > - > -make_times_h: make_times_h.c > - $(HOSTCC) $(HOSTCFLAGS) -o make_times_h make_times_h.c > - > -times.h: make_times_h > - ./make_times_h > diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/README linux/net/khttpd/README > --- linux-2.4.19-pre8/net/khttpd/README Fri May 3 13:35:57 2002 > +++ linux/net/khttpd/README Thu Jan 1 01:00:00 1970 > @@ -1,224 +0,0 @@ > -===== > - > -kHTTPd - Kernel httpd accelerator > - > -(C) 1999 by Arjan van de Ven > -Licensed under the terms of the GNU General Public License > - > -===== > - > - > -1. Introduction > ---------------- > - kHTTPd is a http-daemon (webserver) for Linux. kHTTPd is different from > - other webservers in that it runs from within the Linux-kernel as a module > - (device-driver). > - > - kHTTPd handles only static (file based) web-pages, and passes all requests > - for non-static information to a regular userspace-webserver such as Apache or > - Zeus. The userspace-daemon doesn't have to be altered in any way. > - > - Static web-pages are not a very complex thing to serve, but these are very > - important nevertheless, since virtually all images are static, and a large > - portion of the html-pages are static also. A "regular" webserver has little > - added value for static pages, it is simply a "copy file to network"-operation. > - This can be done very efficiently from within the Linux-kernel, for example > - the nfs (network file system) daemon performs a similar task and also runs > - in the kernel. > - > - By "accelerating" the simple case within the kernel, userspace daemons can > - do what they are very good at: Generating user-specific, dynamic content. > - > - Note: This document sometimes uses "Apache" instead of "any webserver you > - ever might want to use", just for reasons of readability. > - > - > -2. Quick Start > --------------- > - > - 1) compile and load the module > - 2) configure the module in /proc/sys/net/khttpd if needed > - 3) echo 1 > /proc/sys/net/khttpd/start > - > - unloading: > - > - echo 1 > /proc/sys/net/khttpd/stop > - echo 1 > /proc/sys/net/khttpd/unload > - rmmod khttpd > - > - > - > -3. Configuration > ----------------- > - > - Modes of operation > - ================== > - > - > - There are two recommended modes of operation: > - > - 1) "Apache" is main webserver, kHTTPd is assistant > - clientport -> 80 > - serverport -> 8080 (or whatever) > - > - 2) kHTTPd is main webserver, "Apache" is assistant > - clientport -> 8080 (or whatever) > - serverport -> 80 > - > - > - Configuring kHTTPd > - ================== > - > - Before you can start using kHTTPd, you have to configure it. This > - is done through the /proc filesystem, and can thus be done from inside > - a script. Most parameters can only be set when kHTTPd is not active. > - > - The following things need configuration: > - > - 1) The port where kHTTPd should listen for requests > - 2) The port (on "localhost") where "Apache" is listening > - 3) The location of the documents (documentroot) > - 4) The strings that indicate dynamic content (optional) > - [ "cgi-bin" is added by default ] > - > - It is very important that the documentroot for kHTTPd matches the > - documentroot for the userspace-daemon, as kHTTPd might "redirect" > - any request to this userspace-daemon. > - > - A typical script (for the first mode of operation) to do this would > - look like: > - > -#!/bin/sh > -modprobe khttpd > -echo 80 > /proc/sys/net/khttpd/clientport > -echo 8080 > /proc/sys/net/khttpd/serverport > -echo /var/www > /proc/sys/net/khttpd/documentroot > -echo php3 > /proc/sys/net/khttpd/dynamic > -echo shtml > /proc/sys/net/khttpd/dynamic > -echo 1 > /proc/sys/net/khttpd/start > - > - For the second mode of operation, this would be: > - > -#!/bin/sh > -modprobe khttpd > -echo 8080 > /proc/sys/net/khttpd/clientport > -echo 80 > /proc/sys/net/khttpd/serverport > -echo /var/www > /proc/sys/net/khttpd/documentroot > -echo php3 > /proc/sys/net/khttpd/dynamic > -echo shtml > /proc/sys/net/khttpd/dynamic > -echo 1 > /proc/sys/net/khttpd/start > - > - In this case, you also have to change the configuration of the > - userspace-daemon. For Apache, you do this by changing > - > - Port 80 > - > - to > - > - Port 8080 > - > - > - > - Stopping kHTTPd > - =============== > - In order to change the configuration, you should stop kHTTPd by typing > - echo 1 > /proc/sys/net/khttpd/stop > - on a command-prompt. > - > - If you want to unload the module, you should type > - echo 1 > /proc/sys/net/khttpd/unload > - after stopping kHTTPd first. > - > - If this doesn't work fast enough for you (the commands above can wait for > - a remote connection to close down), you can send the daemons a "HUP" > - signal after you told them to stop. This will cause the daemon-threads to > - stop immediately. > - > - Note that the daemons will restart immediately if they are not told to > - stop. > - > - > - > -4. Permissions > --------------- > - The security model of kHTTPd is very strict. It can be, since there is a > - userspace daemon that can handle the complex exceptions. > - > - kHTTPd only serves a file if > - > - 1) There is no "?" in the URL > - 2) The URL starts with a "/" > - 3) The file indicated by the URL exists > - 4) The file is world-readable (*) > - 5) The file is not a directory, executable or has the Sticky-bit > - set (*) > - 6) The URL doesn't contain any "forbidden" substrings such as ".." > - and "cgi-bin" (*) > - 7) The mime-type is known (*) > - > - The items marked with a (*) are configurable through the > - sysctl-parameters in /proc/sys/net/khttpd. > - > - > - In all cases where any of the above conditions isn't met, the > - userspace-daemon is handed the request. > - > - > - > -5. Parameters > -------------- > - The following parameters are settable through /proc/sys/net/khttpd: > - > - Name Default Description > - > - serverport 8080 The port where kHTTPd listens on > - > - clientport 80 The port of the userspace > - http-daemon > - > - threads 2 The number of server-threads. Should > - be 1 per CPU for small websites, 2 > - per CPU for big (the active files > - do not fit in the RAM) websites. > - > - documentroot /var/www the directory where the > - document-files are > - > - start 0 Set to 1 to start kHTTPd > - (this also resets "stop" to 0) > - > - stop 0 Set to 1 to stop kHTTPd > - (this also resets "start" to 0) > - > - unload 0 Set to 1 to prepare kHTTPd for > - unloading of the module > - > - sloppymime 0 If set to 1, unknown mime-types are > - set to text/html. If set to 0, > - files with unknown mime-types are > - handled by the userspace daemon > - > - perm_required S_IROTH Minimum permissions required > - (for values see "man 2 stat") > - > - perm_forbid dir+sticky+ Permission-mask with "forbidden" > - execute permissions. > - (for values see "man 2 stat") > - > - dynamic cgi-bin .. Strings that, if they are a subset > - of the URL, indicate "dynamic > - content" > - > - maxconnect 1000 Maximum number of concurrent > - connections > - > -6. More information > -------------------- > - More information about the architecture of kHTTPd, the mailinglist and > - configuration-examples can be found at the kHTTPd homepage: > - > - http://www.fenrus.demon.nl > - > - Bugreports, patches, etc can be send to the mailinglist > - (khttpd-users@zgp.org) or to khttpd@fenrus.demon.nl > - > diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/accept.c linux/net/khttpd/accept.c > --- linux-2.4.19-pre8/net/khttpd/accept.c Fri May 3 13:35:46 2002 > +++ linux/net/khttpd/accept.c Thu Jan 1 01:00:00 1970 > @@ -1,127 +0,0 @@ > -/* > - > -kHTTPd -- the next generation > - > -Accept connections > - > -*/ > -/**************************************************************** > - * This program is free software; you can redistribute it and/or modify > - * it under the terms of the GNU General Public License as published by > - * the Free Software Foundation; either version 2, or (at your option) > - * any later version. > - * > - * This program is distributed in the hope that it will be useful, > - * but WITHOUT ANY WARRANTY; without even the implied warranty of > - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > - * GNU General Public License for more details. > - * > - * You should have received a copy of the GNU General Public License > - * along with this program; if not, write to the Free Software > - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. > - * > - ****************************************************************/ > - > -#include "structure.h" > -#include "prototypes.h" > -#include "sysctl.h" > - > -#include <linux/smp_lock.h> > - > -/* > - > -Purpose: > - > -AcceptConnections puts all "accepted" connections in the > -"WaitForHeader" queue. > - > -Return value: > - The number of accepted connections > -*/ > - > - > -int AcceptConnections(const int CPUNR, struct socket *Socket) > -{ > - struct http_request *NewRequest; > - struct socket *NewSock; > - int count = 0; > - int error; > - > - EnterFunction("AcceptConnections"); > - > - if (atomic_read(&ConnectCount)>sysctl_khttpd_maxconnect) > - { > - LeaveFunction("AcceptConnections - to many active connections"); > - return 0; > - } > - > - if (Socket==NULL) return 0; > - > - /* > - Quick test to see if there are connections on the queue. > - This is cheaper than accept() itself because this saves us > - the allocation of a new socket. (Which doesn't seem to be > - used anyway) > - */ > - if (Socket->sk->tp_pinfo.af_tcp.accept_queue==NULL) > - { > - return 0; > - } > - > - error = 0; > - while (error>=0) > - { > - NewSock = sock_alloc(); > - if (NewSock==NULL) > - break; > - > - > - NewSock->type = Socket->type; > - NewSock->ops = Socket->ops; > - > - > - error = Socket->ops->accept(Socket,NewSock,O_NONBLOCK); > - > - > - if (error<0) > - { > - sock_release(NewSock); > - break; > - } > - > - if (NewSock->sk->state==TCP_CLOSE) > - { > - sock_release(NewSock); > - continue; > - } > - > - /* Allocate a request-entry for the connection */ > - NewRequest = kmalloc(sizeof(struct http_request),(int)GFP_KERNEL); > - > - if (NewRequest == NULL) > - { > - Send50x(NewSock); /* Service not available. Try again later */ > - sock_release(NewSock); > - break; > - } > - memset(NewRequest,0,sizeof(struct http_request)); > - > - NewRequest->sock = NewSock; > - > - NewRequest->Next = threadinfo[CPUNR].WaitForHeaderQueue; > - > - init_waitqueue_entry(&NewRequest->sleep,current); > - > - add_wait_queue(NewSock->sk->sleep,&(NewRequest->sleep)); > - > - threadinfo[CPUNR].WaitForHeaderQueue = NewRequest; > - > - atomic_inc(&ConnectCount); > - > - > - count++; > - } > - > - LeaveFunction("AcceptConnections"); > - return count; > -} > diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/datasending.c linux/net/khttpd/datasending.c > --- linux-2.4.19-pre8/net/khttpd/datasending.c Fri May 3 13:36:56 2002 > +++ linux/net/khttpd/datasending.c Thu Jan 1 01:00:00 1970 > @@ -1,241 +0,0 @@ > -/* > - > -kHTTPd -- the next generation > - > -Send actual file-data to the connections > - > -*/ > -/**************************************************************** > - * This program is free software; you can redistribute it and/or modify > - * it under the terms of the GNU General Public License as published by > - * the Free Software Foundation; either version 2, or (at your option) > - * any later version. > - * > - * This program is distributed in the hope that it will be useful, > - * but WITHOUT ANY WARRANTY; without even the implied warranty of > - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > - * GNU General Public License for more details. > - * > - * You should have received a copy of the GNU General Public License > - * along with this program; if not, write to the Free Software > - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. > - * > - ****************************************************************/ > - > -/* > - > -Purpose: > - > -DataSending does the actual sending of file-data to the socket. > - > -Note: Since asynchronous reads do not -yet- exists, this might block! > - > -Return value: > - The number of requests that changed status (ie: made some progress) > -*/ > - > -#include <linux/config.h> > -#include <linux/kernel.h> > -#include <linux/locks.h> > -#include <linux/skbuff.h> > - > -#include <net/tcp.h> > - > -#include <asm/uaccess.h> > -#include <linux/smp_lock.h> > - > -#include "structure.h" > -#include "prototypes.h" > - > -static char *Block[CONFIG_KHTTPD_NUMCPU]; > - > -/* > - > -This send_actor is for use with do_generic_file_read (ie sendfile()) > -It sends the data to the socket indicated by desc->buf. > - > -*/ > -static int sock_send_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size) > -{ > - int written; > - char *kaddr; > - unsigned long count = desc->count; > - struct socket *sock = (struct socket *) desc->buf; > - mm_segment_t old_fs; > - > - if (size > count) > - size = count; > - old_fs = get_fs(); > - set_fs(KERNEL_DS); > - > - kaddr = kmap(page); > - written = SendBuffer_async(sock, kaddr + offset, size); > - kunmap(page); > - set_fs(old_fs); > - if (written < 0) { > - desc->error = written; > - written = 0; > - } > - desc->count = count - written; > - desc->written += written; > - return written; > -} > - > - > - > - > -int DataSending(const int CPUNR) > -{ > - struct http_request *CurrentRequest,**Prev; > - int count = 0; > - > - EnterFunction("DataSending"); > - > - Prev = &(threadinfo[CPUNR].DataSendingQueue); > - CurrentRequest = threadinfo[CPUNR].DataSendingQueue; > - while (CurrentRequest!=NULL) > - { > - int ReadSize,Space; > - int retval; > - > - > - /* First, test if the socket has any buffer-space left. > - If not, no need to actually try to send something. */ > - > - > - Space = sock_wspace(CurrentRequest->sock->sk); > - > - ReadSize = min_t(int, 4 * 4096, CurrentRequest->FileLength - CurrentRequest->BytesSent); > - ReadSize = min_t(int, ReadSize, Space); > - > - if (ReadSize>0) > - { > - struct inode *inode; > - > - inode = CurrentRequest->filp->f_dentry->d_inode; > - > - if (inode->i_mapping->a_ops->readpage) { > - /* This does the actual transfer using sendfile */ > - read_descriptor_t desc; > - loff_t *ppos; > - > - CurrentRequest->filp->f_pos = CurrentRequest->BytesSent; > - > - ppos = &CurrentRequest->filp->f_pos; > - > - desc.written = 0; > - desc.count = ReadSize; > - desc.buf = (char *) CurrentRequest->sock; > - desc.error = 0; > - do_generic_file_read(CurrentRequest->filp, ppos, &desc, sock_send_actor); > - if (desc.written>0) > - { > - CurrentRequest->BytesSent += desc.written; > - count++; > - } > - } > - else /* FS doesn't support sendfile() */ > - { > - mm_segment_t oldfs; > - CurrentRequest->filp->f_pos = CurrentRequest->BytesSent; > - > - oldfs = get_fs(); set_fs(KERNEL_DS); > - retval = CurrentRequest->filp->f_op->read(CurrentRequest->filp, Block[CPUNR], ReadSize, &CurrentRequest->filp->f_pos); > - set_fs(oldfs); > - > - if (retval>0) > - { > - retval = SendBuffer_async(CurrentRequest->sock,Block[CPUNR],(size_t)retval); > - if (retval>0) > - { > - CurrentRequest->BytesSent += retval; > - count++; > - } > - } > - } > - > - } > - > - /* > - If end-of-file or closed connection: Finish this request > - by moving it to the "logging" queue. > - */ > - if ((CurrentRequest->BytesSent>=CurrentRequest->FileLength)|| > - (CurrentRequest->sock->sk->state!=TCP_ESTABLISHED > - && CurrentRequest->sock->sk->state!=TCP_CLOSE_WAIT)) > - { > - struct http_request *Next; > - Next = CurrentRequest->Next; > - > - lock_sock(CurrentRequest->sock->sk); > - if (CurrentRequest->sock->sk->state == TCP_ESTABLISHED || > - CurrentRequest->sock->sk->state == TCP_CLOSE_WAIT) > - { > - CurrentRequest->sock->sk->tp_pinfo.af_tcp.nonagle = 0; > - tcp_push_pending_frames(CurrentRequest->sock->sk,&(CurrentRequest->sock->sk->tp_pinfo.af_tcp)); > - } > - release_sock(CurrentRequest->sock->sk); > - > - (*Prev) = CurrentRequest->Next; > - > - CurrentRequest->Next = threadinfo[CPUNR].LoggingQueue; > - threadinfo[CPUNR].LoggingQueue = CurrentRequest; > - > - CurrentRequest = Next; > - continue; > - > - } > - > - > - Prev = &(CurrentRequest->Next); > - CurrentRequest = CurrentRequest->Next; > - } > - > - LeaveFunction("DataSending"); > - return count; > -} > - > -int InitDataSending(int ThreadCount) > -{ > - int I,I2; > - > - EnterFunction("InitDataSending"); > - I=0; > - while (I<ThreadCount) > - { > - Block[I] = (char*)get_free_page((int)GFP_KERNEL); > - if (Block[I] == NULL) > - { > - I2=0; > - while (I2<I-1) > - { > - free_page((unsigned long)Block[I2++]); > - } > - LeaveFunction("InitDataSending - abort"); > - return -1; > - } > - I++; > - } > - LeaveFunction("InitDataSending"); > - return 0; > -} > - > -void StopDataSending(const int CPUNR) > -{ > - struct http_request *CurrentRequest,*Next; > - > - EnterFunction("StopDataSending"); > - CurrentRequest = threadinfo[CPUNR].DataSendingQueue; > - > - while (CurrentRequest!=NULL) > - { > - Next = CurrentRequest->Next; > - CleanUpRequest(CurrentRequest); > - CurrentRequest=Next; > - } > - > - threadinfo[CPUNR].DataSendingQueue = NULL; > - > - free_page( (unsigned long)Block[CPUNR]); > - LeaveFunction("StopDataSending"); > -} > diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/logging.c linux/net/khttpd/logging.c > --- linux-2.4.19-pre8/net/khttpd/logging.c Fri May 3 13:36:20 2002 > +++ linux/net/khttpd/logging.c Thu Jan 1 01:00:00 1970 > @@ -1,95 +0,0 @@ > -/* > - > -kHTTPd -- the next generation > - > -logging.c takes care of shutting down a connection. > - > -*/ > -/**************************************************************** > - * This program is free software; you can redistribute it and/or modify > - * it under the terms of the GNU General Public License as published by > - * the Free Software Foundation; either version 2, or (at your option) > - * any later version. > - * > - * This program is distributed in the hope that it will be useful, > - * but WITHOUT ANY WARRANTY; without even the implied warranty of > - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > - * GNU General Public License for more details. > - * > - * You should have received a copy of the GNU General Public License > - * along with this program; if not, write to the Free Software > - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. > - * > - ****************************************************************/ > - > -#include <linux/kernel.h> > -#include <linux/skbuff.h> > -#include <linux/smp_lock.h> > -#include <net/tcp.h> > -#include <asm/uaccess.h> > -#include "structure.h" > -#include "prototypes.h" > - > -/* > - > -Purpose: > - > -Logging() terminates "finished" connections and will eventually log them to a > -userspace daemon. > - > -Return value: > - The number of requests that changed status, thus the number of connections > - that shut down. > -*/ > - > - > -int Logging(const int CPUNR) > -{ > - struct http_request *CurrentRequest,*Req; > - int count = 0; > - > - EnterFunction("Logging"); > - > - CurrentRequest = threadinfo[CPUNR].LoggingQueue; > - > - /* For now, all requests are removed immediatly, but this changes > - when userspace-logging is added. */ > - > - while (CurrentRequest!=NULL) > - { > - > - Req = CurrentRequest->Next; > - > - CleanUpRequest(CurrentRequest); > - > - threadinfo[CPUNR].LoggingQueue = Req; > - > - CurrentRequest = Req; > - > - count++; > - > - } > - > - LeaveFunction("Logging"); > - return count; > -} > - > - > - > -void StopLogging(const int CPUNR) > -{ > - struct http_request *CurrentRequest,*Next; > - > - EnterFunction("StopLogging"); > - CurrentRequest = threadinfo[CPUNR].LoggingQueue; > - > - while (CurrentRequest!=NULL) > - { > - Next=CurrentRequest->Next; > - CleanUpRequest(CurrentRequest); > - CurrentRequest=Next; > - } > - > - threadinfo[CPUNR].LoggingQueue = NULL; > - LeaveFunction("StopLogging"); > -} > diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/main.c linux/net/khttpd/main.c > --- linux-2.4.19-pre8/net/khttpd/main.c Fri May 3 13:35:12 2002 > +++ linux/net/khttpd/main.c Thu Jan 1 01:00:00 1970 > @@ -1,394 +0,0 @@ > -/* > - > -kHTTPd -- the next generation > - > -Main program > - > - > -kHTTPd TNG consists of 1 thread, this main-thread handles ALL connections > -simultanious. It does this by keeping queues with the requests in different > -stages. > - > -The stages are > - > -<not accepted> - TCP/IP connection is not accepted yet > -WaitForHeaders - Connection is accepted, waiting for headers > -DataSending - Headers decoded, sending file-data > -Userspace - Requires userspace daemon > -Logging - The request is finished, cleanup and logging > - > -A typical flow for a request would be: > - > -<not accepted> > -WaitForHeaders > -DataSending > -Logging > - > -or > - > -<not accepted> > -WaitForHeaders > -Userspace > - > - > - > -*/ > -/**************************************************************** > - * This program is free software; you can redistribute it and/or modify > - * it under the terms of the GNU General Public License as published by > - * the Free Software Foundation; either version 2, or (at your option) > - * any later version. > - * > - * This program is distributed in the hope that it will be useful, > - * but WITHOUT ANY WARRANTY; without even the implied warranty of > - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > - * GNU General Public License for more details. > - * > - * You should have received a copy of the GNU General Public License > - * along with this program; if not, write to the Free Software > - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. > - * > - ****************************************************************/ > - > - > -static int errno; > -#define __KERNEL_SYSCALLS__ > - > -#include <linux/config.h> > -#include <linux/module.h> > -#include <linux/kernel.h> > -#include <linux/sched.h> > -#include <linux/signal.h> > -#include <linux/init.h> > -#include <linux/wait.h> > -#include <linux/smp_lock.h> > -#include <asm/unistd.h> > - > -#include "structure.h" > -#include "prototypes.h" > -#include "sysctl.h" > - > -struct khttpd_threadinfo threadinfo[CONFIG_KHTTPD_NUMCPU]; /* The actual work-queues */ > - > - > -atomic_t ConnectCount; > -atomic_t DaemonCount; > - > -static int ActualThreads; /* The number of actual, active threads */ > - > - > -static int ConnectionsPending(int CPUNR) > -{ > - if (threadinfo[CPUNR].DataSendingQueue!=NULL) return O_NONBLOCK; > - if (threadinfo[CPUNR].WaitForHeaderQueue!=NULL) return O_NONBLOCK; > - if (threadinfo[CPUNR].LoggingQueue!=NULL) return O_NONBLOCK; > - if (threadinfo[CPUNR].UserspaceQueue!=NULL) return O_NONBLOCK; > - return 0; > -} > - > - > - > -static wait_queue_head_t DummyWQ[CONFIG_KHTTPD_NUMCPU]; > -static atomic_t Running[CONFIG_KHTTPD_NUMCPU]; > - > -static int MainDaemon(void *cpu_pointer) > -{ > - int CPUNR; > - sigset_t tmpsig; > - > - DECLARE_WAITQUEUE(main_wait,current); > - > - MOD_INC_USE_COUNT; > - > - > - CPUNR=0; > - if (cpu_pointer!=NULL) > - CPUNR=(int)*(int*)cpu_pointer; > - > - sprintf(current->comm,"khttpd - %i",CPUNR); > - daemonize(); > - > - init_waitqueue_head(&(DummyWQ[CPUNR])); > - > - > - /* Block all signals except SIGKILL, SIGSTOP and SIGHUP */ > - spin_lock_irq(¤t->sigmask_lock); > - tmpsig = current->blocked; > - siginitsetinv(¤t->blocked, sigmask(SIGKILL) | sigmask(SIGSTOP)| sigmask(SIGHUP)); > - recalc_sigpending(current); > - spin_unlock_irq(¤t->sigmask_lock); > - > - > - if (MainSocket->sk==NULL) > - return 0; > - add_wait_queue_exclusive(MainSocket->sk->sleep,&(main_wait)); > - atomic_inc(&DaemonCount); > - atomic_set(&Running[CPUNR],1); > - > - while (sysctl_khttpd_stop==0) > - { > - int changes = 0; > - > - > - > - changes +=AcceptConnections(CPUNR,MainSocket); > - if (ConnectionsPending(CPUNR)) > - { > - changes +=WaitForHeaders(CPUNR); > - changes +=DataSending(CPUNR); > - changes +=Userspace(CPUNR); > - changes +=Logging(CPUNR); > - /* Test for incoming connections _again_, because it is possible > - one came in during the other steps, and the wakeup doesn't happen > - then. > - */ > - changes +=AcceptConnections(CPUNR,MainSocket); > - } > - > - if (changes==0) > - { > - (void)interruptible_sleep_on_timeout(&(DummyWQ[CPUNR]),1); > - if (CPUNR==0) > - UpdateCurrentDate(); > - } > - > - if (signal_pending(current)!=0) > - { > - (void)printk(KERN_NOTICE "kHTTPd: Ring Ring - signal received\n"); > - break; > - } > - > - } > - > - remove_wait_queue(MainSocket->sk->sleep,&(main_wait)); > - > - StopWaitingForHeaders(CPUNR); > - StopDataSending(CPUNR); > - StopUserspace(CPUNR); > - StopLogging(CPUNR); > - > - atomic_set(&Running[CPUNR],0); > - atomic_dec(&DaemonCount); > - (void)printk(KERN_NOTICE "kHTTPd: Daemon %i has ended\n",CPUNR); > - MOD_DEC_USE_COUNT; > - return 0; > -} > - > -static int CountBuf[CONFIG_KHTTPD_NUMCPU]; > - > - > - > -/* > - > -The ManagementDaemon has a very simple task: Start the real daemons when the user wants us > -to, and cleanup when the users wants to unload the module. > - > -Initially, kHTTPd didn't have this thread, but it is the only way to have "delayed activation", > -a feature required to prevent accidental activations resulting in unexpected backdoors. > - > -*/ > -static int ManagementDaemon(void *unused) > -{ > - sigset_t tmpsig; > - int waitpid_result; > - > - DECLARE_WAIT_QUEUE_HEAD(WQ); > - > - > - sprintf(current->comm,"khttpd manager"); > - daemonize(); > - > - > - /* Block all signals except SIGKILL and SIGSTOP */ > - spin_lock_irq(¤t->sigmask_lock); > - tmpsig = current->blocked; > - siginitsetinv(¤t->blocked, sigmask(SIGKILL) | sigmask(SIGSTOP) ); > - recalc_sigpending(current); > - spin_unlock_irq(¤t->sigmask_lock); > - > - > - /* main loop */ > - while (sysctl_khttpd_unload==0) > - { > - int I; > - > - > - /* First : wait for activation */ > - > - sysctl_khttpd_start = 0; > - > - while ( (sysctl_khttpd_start==0) && (!signal_pending(current)) && (sysctl_khttpd_unload==0) ) > - { > - current->state = TASK_INTERRUPTIBLE; > - interruptible_sleep_on_timeout(&WQ,HZ); > - } > - > - if ( (signal_pending(current)) || (sysctl_khttpd_unload!=0) ) > - break; > - > - /* Then start listening and spawn the daemons */ > - > - if (StartListening(sysctl_khttpd_serverport)==0) > - { > - continue; > - } > - > - ActualThreads = sysctl_khttpd_threads; > - if (ActualThreads<1) > - ActualThreads = 1; > - > - if (ActualThreads>CONFIG_KHTTPD_NUMCPU) > - ActualThreads = CONFIG_KHTTPD_NUMCPU; > - > - /* Write back the actual value */ > - > - sysctl_khttpd_threads = ActualThreads; > - > - InitUserspace(ActualThreads); > - > - if (InitDataSending(ActualThreads)!=0) > - { > - StopListening(); > - continue; > - } > - if (InitWaitHeaders(ActualThreads)!=0) > - { > - I=0; > - while (I<ActualThreads) > - { > - StopDataSending(I); > - I++; > - } > - StopListening(); > - continue; > - } > - > - /* Clean all queues */ > - memset(threadinfo, 0, sizeof(struct khttpd_threadinfo)); > - > - > - > - I=0; > - while (I<ActualThreads) > - { > - atomic_set(&Running[I],1); > - (void)kernel_thread(MainDaemon,&(CountBuf[I]), CLONE_FS | CLONE_FILES | CLONE_SIGHAND); > - I++; > - } > - > - /* Then wait for deactivation */ > - sysctl_khttpd_stop = 0; > - > - while ( (sysctl_khttpd_stop==0) && (!signal_pending(current)) && (sysctl_khttpd_unload==0) ) > - { > - if (atomic_read(&DaemonCount)<ActualThreads) > - { > - I=0; > - while (I<ActualThreads) > - { > - if (atomic_read(&Running[I])==0) > - { > - atomic_set(&Running[I],1); > - (void)kernel_thread(MainDaemon,&(CountBuf[I]), CLONE_FS | CLONE_FILES | CLONE_SIGHAND); > - (void)printk(KERN_CRIT "kHTTPd: Restarting daemon %i \n",I); > - } > - I++; > - } > - } > - interruptible_sleep_on_timeout(&WQ,HZ); > - > - /* reap the daemons */ > - waitpid_result = waitpid(-1,NULL,__WCLONE|WNOHANG); > - > - } > - > - > - /* The user wants us to stop. So stop listening on the socket. */ > - if (sysctl_khttpd_stop!=0) > - { > - /* Wait for the daemons to stop, one second per iteration */ > - while (atomic_read(&DaemonCount)>0) > - interruptible_sleep_on_timeout(&WQ,HZ); > - StopListening(); > - } > - > - > - > - } > - > - sysctl_khttpd_stop = 1; > - > - /* Wait for the daemons to stop, one second per iteration */ > - while (atomic_read(&DaemonCount)>0) > - interruptible_sleep_on_timeout(&WQ,HZ); > - > - > - waitpid_result = 1; > - /* reap the zombie-daemons */ > - while (waitpid_result>0) > - waitpid_result = waitpid(-1,NULL,__WCLONE|WNOHANG); > - > - StopListening(); > - > - > - (void)printk(KERN_NOTICE "kHTTPd: Management daemon stopped. \n You can unload the module now.\n"); > - > - MOD_DEC_USE_COUNT; > - > - return 0; > -} > - > -int __init khttpd_init(void) > -{ > - int I; > - > - MOD_INC_USE_COUNT; > - > - I=0; > - while (I<CONFIG_KHTTPD_NUMCPU) > - { > - CountBuf[I]=I; > - > - I++; > - } > - > - atomic_set(&ConnectCount,0); > - atomic_set(&DaemonCount,0); > - > - > - /* Maybe the mime-types will be set-able through sysctl in the future */ > - > - AddMimeType(".htm","text/html"); > - AddMimeType("html","text/html"); > - AddMimeType(".gif","image/gif"); > - AddMimeType(".jpg","image/jpeg"); > - AddMimeType(".png","image/png"); > - AddMimeType("tiff","image/tiff"); > - AddMimeType(".zip","application/zip"); > - AddMimeType(".pdf","application/pdf"); > - AddMimeType("r.gz","application/x-gtar"); > - AddMimeType(".tgz","application/x-gtar"); > - AddMimeType(".deb","application/x-debian-package"); > - AddMimeType("lass","application/x-java"); > - AddMimeType(".mp3","audio/mpeg"); > - AddMimeType(".txt","text/plain"); > - > - AddDynamicString(".."); > - AddDynamicString("cgi-bin"); > - > - StartSysctl(); > - > - (void)kernel_thread(ManagementDaemon,NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); > - > - return 0; > -} > - > -void khttpd_cleanup(void) > -{ > - EndSysctl(); > -} > - > - module_init(khttpd_init) > - module_exit(khttpd_cleanup) > - > - MODULE_LICENSE("GPL"); > diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/make_times_h.c linux/net/khttpd/make_times_h.c > --- linux-2.4.19-pre8/net/khttpd/make_times_h.c Fri May 3 13:36:34 2002 > +++ linux/net/khttpd/make_times_h.c Thu Jan 1 01:00:00 1970 > @@ -1,122 +0,0 @@ > -/* > - > -This program generates the "times.h" file with the zulu-times of the first of > -every month of a decade. > - > -*/ > -/**************************************************************** > - * This program is free software; you can redistribute it and/or modify > - * it under the terms of the GNU General Public License as published by > - * the Free Software Foundation; either version 2, or (at your option) > - * any later version. > - * > - * This program is distributed in the hope that it will be useful, > - * but WITHOUT ANY WARRANTY; without even the implied warranty of > - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > - * GNU General Public License for more details. > - * > - * You should have received a copy of the GNU General Public License > - * along with this program; if not, write to the Free Software > - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. > - * > - ****************************************************************/ > - > -#include <time.h> > -#include <stdio.h> > - > -static time_t GetDay(int D,int M,int Y) > -{ > - struct tm TM; > - > - TM.tm_sec = 0; > - TM.tm_min = 0; > - TM.tm_hour = 0; > - TM.tm_mday = D; > - TM.tm_mon = M; > - TM.tm_wday = 0; > - TM.tm_yday = 0; > - TM.tm_year = Y-1900; > - TM.tm_isdst = 0; > - > - return mktime(&TM); > - > -} > -static int WeekGetDay(int D,int M,int Y) > -{ > - struct tm TM; > - > - TM.tm_sec = 0; > - TM.tm_min = 0; > - TM.tm_hour = 0; > - TM.tm_mday = D; > - TM.tm_mon = M; > - TM.tm_year = Y-1900; > - TM.tm_isdst = 0; > - TM.tm_wday = 0; > - TM.tm_yday = 0; > - > - (void)mktime(&TM); > - > - return TM.tm_wday; > - > -} > - > -int main(void) > -{ > - int M,Y; > - FILE *file; > - > - file=fopen("times.h","w"); > - > - if (file==NULL) > - return 0; > - > - fprintf(file,"static time_t TimeDays[10][13] = { \n"); > - > - Y=1997; > - while (Y<2007) > - { > - M=0; > - fprintf(file," { "); > - while (M<12) > - { > - fprintf(file,"%i",(int)GetDay(1,M,Y)); > - fprintf(file,",\t"); > - > - M++; > - } > - > - fprintf(file,"%i } ",(int)GetDay(1,0,Y+1)); > - if (Y!=2006) fprintf(file,","); > - fprintf(file,"\n"); > - Y++; > - } > - fprintf(file,"};\n"); > - > - fprintf(file,"static int WeekDays[10][13] = { \n"); > - > - Y=1997; > - while (Y<2007) > - { > - M=0; > - fprintf(file," { "); > - while (M<12) > - { > - fprintf(file,"%i",(int)WeekGetDay(1,M,Y)); > - fprintf(file,",\t"); > - > - M++; > - } > - > - fprintf(file,"%i } ",(int)WeekGetDay(1,0,Y+1)); > - if (Y!=2006) fprintf(file,","); > - fprintf(file,"\n"); > - Y++; > - } > - fprintf(file,"};\n"); > - fprintf(file,"#define KHTTPD_YEAROFFSET 1997\n"); > - fprintf(file,"#define KHTTPD_NUMYEARS 10\n"); > - (void)fclose(file); > - > - return 0; > -} > diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/misc.c linux/net/khttpd/misc.c > --- linux-2.4.19-pre8/net/khttpd/misc.c Fri May 3 13:37:41 2002 > +++ linux/net/khttpd/misc.c Thu Jan 1 01:00:00 1970 > @@ -1,242 +0,0 @@ > -/* > - > -kHTTPd -- the next generation > - > -General functions > - > -*/ > -/**************************************************************** > - * This program is free software; you can redistribute it and/or modify > - * it under the terms of the GNU General Public License as published by > - * the Free Software Foundation; either version 2, or (at your option) > - * any later version. > - * > - * This program is distributed in the hope that it will be useful, > - * but WITHOUT ANY WARRANTY; without even the implied warranty of > - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > - * GNU General Public License for more details. > - * > - * You should have received a copy of the GNU General Public License > - * along with this program; if not, write to the Free Software > - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. > - * > - ****************************************************************/ > - > -#include <linux/kernel.h> > - > -#include <linux/ctype.h> > -#include <linux/errno.h> > -#include <linux/slab.h> > -#include <linux/net.h> > -#include <linux/sched.h> > -#include <linux/skbuff.h> > -#include <linux/unistd.h> > -#include <linux/file.h> > -#include <linux/smp_lock.h> > - > -#include <net/ip.h> > -#include <net/sock.h> > - > -#include <asm/atomic.h> > -#include <asm/errno.h> > -#include <asm/semaphore.h> > -#include <asm/processor.h> > -#include <asm/uaccess.h> > - > -#include "structure.h" > -#include "prototypes.h" > - > -#ifndef ECONNRESET > -#define ECONNRESET 102 > -#endif > - > - > -/* > - > -Readrest reads and discards all pending input on a socket. This is required > -before closing the socket. > - > -*/ > -static void ReadRest(struct socket *sock) > -{ > - struct msghdr msg; > - struct iovec iov; > - int len; > - > - mm_segment_t oldfs; > - > - > - EnterFunction("ReadRest"); > - > - > - if (sock->sk==NULL) > - return; > - > - len = 1; > - > - while (len>0) > - { > - static char Buffer[1024]; /* Never read, so doesn't need to > - be SMP safe */ > - > - msg.msg_name = 0; > - msg.msg_namelen = 0; > - msg.msg_iov = &iov; > - msg.msg_iovlen = 1; > - msg.msg_control = NULL; > - msg.msg_controllen = 0; > - msg.msg_flags = MSG_DONTWAIT; > - > - msg.msg_iov->iov_base = &Buffer[0]; > - msg.msg_iov->iov_len = (__kernel_size_t)1024; > - > - len = 0; > - oldfs = get_fs(); set_fs(KERNEL_DS); > - len = sock_recvmsg(sock,&msg,1024,MSG_DONTWAIT); > - set_fs(oldfs); > - } > - LeaveFunction("ReadRest"); > -} > - > - > -/* > - > -CleanUpRequest takes care of shutting down the connection, closing the file-pointer > -and releasing the memory of the request-structure. Do not try to access it afterwards! > - > -*/ > -void CleanUpRequest(struct http_request *Req) > -{ > - EnterFunction("CleanUpRequest"); > - > - /* Close the socket ....*/ > - if ((Req->sock!=NULL)&&(Req->sock->sk!=NULL)) > - { > - ReadRest(Req->sock); > - remove_wait_queue(Req->sock->sk->sleep,&(Req->sleep)); > - sock_release(Req->sock); > - } > - > - /* ... and the file-pointer ... */ > - if (Req->filp!=NULL) > - { > - fput(Req->filp); > - Req->filp = NULL; > - } > - > - > - /* ... and release the memory for the structure. */ > - kfree(Req); > - > - atomic_dec(&ConnectCount); > - LeaveFunction("CleanUpRequest"); > -} > - > - > -/* > - > -SendBuffer and Sendbuffer_async send "Length" bytes from "Buffer" to the "sock"et. > -The _async-version is non-blocking. > - > -A positive return-value indicates the number of bytes sent, a negative value indicates > -an error-condition. > - > -*/ > -int SendBuffer(struct socket *sock, const char *Buffer,const size_t Length) > -{ > - struct msghdr msg; > - mm_segment_t oldfs; > - struct iovec iov; > - int len; > - > - EnterFunction("SendBuffer"); > - > - msg.msg_name = 0; > - msg.msg_namelen = 0; > - msg.msg_iov = &iov; > - msg.msg_iovlen = 1; > - msg.msg_control = NULL; > - msg.msg_controllen = 0; > - msg.msg_flags = MSG_NOSIGNAL; > - msg.msg_iov->iov_len = (__kernel_size_t)Length; > - msg.msg_iov->iov_base = (char*) Buffer; > - > - > - len = 0; > - > - oldfs = get_fs(); set_fs(KERNEL_DS); > - len = sock_sendmsg(sock,&msg,(size_t)(Length-len)); > - set_fs(oldfs); > - LeaveFunction("SendBuffer"); > - return len; > -} > - > -int SendBuffer_async(struct socket *sock, const char *Buffer,const size_t Length) > -{ > - struct msghdr msg; > - mm_segment_t oldfs; > - struct iovec iov; > - int len; > - > - EnterFunction("SendBuffer_async"); > - msg.msg_name = 0; > - msg.msg_namelen = 0; > - msg.msg_iov = &iov; > - msg.msg_iovlen = 1; > - msg.msg_control = NULL; > - msg.msg_controllen = 0; > - msg.msg_flags = MSG_DONTWAIT|MSG_NOSIGNAL; > - msg.msg_iov->iov_base = (char*) Buffer; > - msg.msg_iov->iov_len = (__kernel_size_t)Length; > - > - > - if (sock->sk) > - { > - oldfs = get_fs(); set_fs(KERNEL_DS); > - len = sock_sendmsg(sock,&msg,(size_t)(Length)); > - set_fs(oldfs); > - } else > - { > - return -ECONNRESET; > - } > - > - LeaveFunction("SendBuffer_async"); > - return len; > -} > - > - > - > - > -/* > - > -HTTP header shortcuts. Hardcoded since these might be called in a low-memory > -situation, and they don't change anyhow. > - > -*/ > - > -static char NoPerm[] = "HTTP/1.0 403 Forbidden\r\nServer: kHTTPd 0.1.6\r\n\r\n"; > -static char TryLater[] = "HTTP/1.0 503 Service Unavailable\r\nServer: kHTTPd 0.1.6\r\nContent-Length: 15\r\n\r\nTry again later"; > -static char NotModified[] = "HTTP/1.0 304 Not Modified\r\nServer: kHTTPd 0.1.6\r\n\r\n"; > - > - > -void Send403(struct socket *sock) > -{ > - EnterFunction("Send403"); > - (void)SendBuffer(sock,NoPerm,strlen(NoPerm)); > - LeaveFunction("Send403"); > -} > - > -void Send304(struct socket *sock) > -{ > - EnterFunction("Send304"); > - (void)SendBuffer(sock,NotModified,strlen(NotModified)); > - LeaveFunction("Send304"); > -} > - > -void Send50x(struct socket *sock) > -{ > - EnterFunction("Send50x"); > - (void)SendBuffer(sock,TryLater,strlen(TryLater)); > - LeaveFunction("Send50x"); > -} > - > diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/prototypes.h linux/net/khttpd/prototypes.h > --- linux-2.4.19-pre8/net/khttpd/prototypes.h Fri May 3 13:38:39 2002 > +++ linux/net/khttpd/prototypes.h Thu Jan 1 01:00:00 1970 > @@ -1,120 +0,0 @@ > -#ifndef _INCLUDE_GUARD_PROTOTYPES_H > -#define _INCLUDE_GUARD_PROTOTYPES_H > - > - > -#include <linux/config.h> > -#include <linux/kernel.h> > -#include <linux/net.h> > -#include <linux/time.h> > -#include <linux/types.h> > -#include <linux/wait.h> > -#include <net/sock.h> > -#include <asm/uaccess.h> > - > -#include "structure.h" > - > - > -/* General defines and stuff */ > - > - > -#define CONFIG_KHTTPD_NUMCPU 16 /* Maximum number of threads */ > - > -#ifdef OOPSTRACE > -#define EnterFunction(x) printk("Enter: %s, %s line %i\n",x,__FILE__,__LINE__) > -#define LeaveFunction(x) printk("Leave: %s, %s line %i\n",x,__FILE__,__LINE__) > -#else > -#define EnterFunction(x) do {} while (0) > -#define LeaveFunction(x) do {} while (0) > -#endif > - > - > - > -/* sockets.c */ > -int StartListening(const int Port); > -void StopListening(void); > - > -extern struct socket *MainSocket; > - > - > -/* sysctl.c */ > -void StartSysctl(void); > -void EndSysctl(void); > - > -extern int sysctl_khttpd_stop; > - > - > -/* main.c */ > - > - > -extern struct khttpd_threadinfo threadinfo[CONFIG_KHTTPD_NUMCPU]; > -extern char CurrentTime[]; > -extern atomic_t ConnectCount; > -extern struct wait_queue main_wait[CONFIG_KHTTPD_NUMCPU]; > - > -/* misc.c */ > - > -void CleanUpRequest(struct http_request *Req); > -int SendBuffer(struct socket *sock, const char *Buffer,const size_t Length); > -int SendBuffer_async(struct socket *sock, const char *Buffer,const size_t Length); > -void Send403(struct socket *sock); > -void Send304(struct socket *sock); > -void Send50x(struct socket *sock); > - > -/* accept.c */ > - > -int AcceptConnections(const int CPUNR,struct socket *Socket); > - > -/* waitheaders.c */ > - > -int WaitForHeaders(const int CPUNR); > -void StopWaitingForHeaders(const int CPUNR); > -int InitWaitHeaders(int ThreadCount); > - > -/* datasending.c */ > - > -int DataSending(const int CPUNR); > -void StopDataSending(const int CPUNR); > -int InitDataSending(int ThreadCount); > - > - > -/* userspace.c */ > - > -int Userspace(const int CPUNR); > -void StopUserspace(const int CPUNR); > -void InitUserspace(const int CPUNR); > - > - > -/* rfc_time.c */ > - > -void time_Unix2RFC(const time_t Zulu,char *Buffer); > -void UpdateCurrentDate(void); > -time_t mimeTime_to_UnixTime(char *Q); > -extern int CurrentTime_i; > - > -/* rfc.c */ > - > -void ParseHeader(char *Buffer,const int length, struct http_request *Head); > -char *ResolveMimeType(const char *File,__kernel_size_t *Len); > -void AddMimeType(const char *Ident,const char *Type); > -void SendHTTPHeader(struct http_request *Request); > - > - > - > -/* security.c */ > - > -struct file *OpenFileForSecurity(char *Filename); > -void AddDynamicString(const char *String); > -void GetSecureString(char *String); > - > - > -/* logging.c */ > - > -int Logging(const int CPUNR); > -void StopLogging(const int CPUNR); > - > - > -/* Other prototypes */ > - > - > - > -#endif > diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/rfc.c linux/net/khttpd/rfc.c > --- linux-2.4.19-pre8/net/khttpd/rfc.c Fri May 3 13:37:47 2002 > +++ linux/net/khttpd/rfc.c Thu Jan 1 01:00:00 1970 > @@ -1,374 +0,0 @@ > -/* > - > -kHTTPd -- the next generation > - > -RFC related functions (headers and stuff) > - > -*/ > - > -/**************************************************************** > - * This program is free software; you can redistribute it and/or modify > - * it under the terms of the GNU General Public License as published by > - * the Free Software Foundation; either version 2, or (at your option) > - * any later version. > - * > - * This program is distributed in the hope that it will be useful, > - * but WITHOUT ANY WARRANTY; without even the implied warranty of > - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > - * GNU General Public License for more details. > - * > - * You should have received a copy of the GNU General Public License > - * along with this program; if not, write to the Free Software > - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. > - * > - ****************************************************************/ > - > - > -#include <linux/kernel.h> > - > -#include <linux/ctype.h> > -#include <linux/errno.h> > -#include <linux/slab.h> > -#include <linux/net.h> > -#include <linux/sched.h> > -#include <linux/skbuff.h> > -#include <linux/unistd.h> > -#include <linux/file.h> > -#include <linux/smp_lock.h> > - > -#include <net/ip.h> > -#include <net/sock.h> > - > -#include <asm/atomic.h> > -#include <asm/semaphore.h> > -#include <asm/processor.h> > -#include <asm/uaccess.h> > - > - > -#include "prototypes.h" > -#include "structure.h" > -#include "sysctl.h" > - > - > -#define KHTTPD_NUMMIMETYPES 40 > - > -static atomic_t MimeCount; > - > -struct MimeType > -{ > - __u32 identifier; > - char type[64-sizeof(__u32)-sizeof(__kernel_size_t)]; > - __kernel_size_t len; > -}; > - > -static struct MimeType MimeTypes[KHTTPD_NUMMIMETYPES]; > - > - > -void AddMimeType(const char *Ident,const char *Type) > -{ > - __u32 *I; > - > - EnterFunction("AddMimeType"); > - > - if (strlen(Ident)!=4) > - { > - (void)printk(KERN_ERR "httpd: Only 4-byte mime-identifiers are accepted\n"); > - return; > - } > - > - if (strlen(Type)>(64-sizeof(__u32)-sizeof(__kernel_size_t) ) ) > - { > - (void)printk(KERN_ERR "httpd: Mime-string too long.\n"); > - return; > - } > - > - I=(__u32*)Ident; > - > - /* FIXME: Need to lock-down all access to the mime-structure here */ > - /* For now, just don't add mime-types after initialisation */ > - > - > - MimeTypes[atomic_read(&MimeCount)].identifier=*I; > - strncpy(MimeTypes[atomic_read(&MimeCount)].type,Type,(64-sizeof(__u32)-sizeof(__kernel_size_t))); > - MimeTypes[atomic_read(&MimeCount)].len = strlen(Type); > - > - atomic_inc(&MimeCount); > - LeaveFunction("AddMimeType"); > -} > - > - > -char *ResolveMimeType(const char *File,__kernel_size_t *Len) > -/* > - > - The returned string is for READ ONLY, ownership of the memory is NOT > - transferred. > - > -*/ > -{ > - __u32 *I; > - int pos,lc,filelen; > - > - EnterFunction("ResolveMimeType"); > - > - *Len = 0; > - > - if (File==NULL) > - return NULL; > - > - filelen = (int)strlen(File); > - > - if (filelen<4) > - { > - return NULL; > - } > - > - /* The Merced-people are NOT going to like this! So this has to be fixed > - in a later stage. */ > - > - pos = filelen-4; > - I=(__u32*)(File+pos); > - > - lc=0; > - > - while (lc<atomic_read(&MimeCount)) > - { > - if (MimeTypes[lc].identifier == *I) > - { > - *Len = MimeTypes[lc].len; > - LeaveFunction("ResolveMimeType - success"); > - return MimeTypes[lc].type; > - } > - lc++; > - } > - > - if (sysctl_khttpd_sloppymime) > - { > - *Len = MimeTypes[0].len; > - LeaveFunction("ResolveMimeType - unknown"); > - return MimeTypes[0].type; > - } > - else > - { > - LeaveFunction("ResolveMimeType - failure"); > - return NULL; > - } > -} > - > - > -static char HeaderPart1[] = "HTTP/1.0 200 OK\r\nServer: kHTTPd/0.1.6\r\nDate: "; > -#ifdef BENCHMARK > -static char HeaderPart1b[] ="HTTP/1.0 200 OK"; > -#endif > -static char HeaderPart3[] = "\r\nContent-type: "; > -static char HeaderPart5[] = "\r\nLast-modified: "; > -static char HeaderPart7[] = "\r\nContent-length: "; > -static char HeaderPart9[] = "\r\n\r\n"; > - > -#ifdef BENCHMARK > -/* In BENCHMARK-mode, just send the bare essentials */ > -void SendHTTPHeader(struct http_request *Request) > -{ > - struct msghdr msg; > - mm_segment_t oldfs; > - struct iovec iov[9]; > - int len,len2; > - > - > - EnterFunction("SendHTTPHeader"); > - > - msg.msg_name = 0; > - msg.msg_namelen = 0; > - msg.msg_iov = &iov[0]; > - msg.msg_iovlen = 6; > - msg.msg_control = NULL; > - msg.msg_controllen = 0; > - msg.msg_flags = 0; /* Synchronous for now */ > - > - iov[0].iov_base = HeaderPart1b; > - iov[0].iov_len = 15; > - iov[1].iov_base = HeaderPart3; > - iov[1].iov_len = 16; > - iov[2].iov_base = Request->MimeType; > - iov[2].iov_len = Request->MimeLength; > - > - iov[3].iov_base = HeaderPart7; > - iov[3].iov_len = 18; > - > - > - sprintf(Request->LengthS,"%i",Request->FileLength); > - iov[4].iov_base = Request->LengthS; > - iov[4].iov_len = strlen(Request->LengthS); > - iov[5].iov_base = HeaderPart9; > - iov[5].iov_len = 4; > - > - len2=15+16+18+iov[2].iov_len+iov[4].iov_len+4; > - > - > - len = 0; > - > - > - oldfs = get_fs(); set_fs(KERNEL_DS); > - len = sock_sendmsg(Request->sock,&msg,len2); > - set_fs(oldfs); > - > - > - return; > -} > -#else > -void SendHTTPHeader(struct http_request *Request) > -{ > - struct msghdr msg; > - mm_segment_t oldfs; > - struct iovec iov[9]; > - int len,len2; > - __kernel_size_t slen; > - > - EnterFunction("SendHTTPHeader"); > - > - msg.msg_name = 0; > - msg.msg_namelen = 0; > - msg.msg_iov = &(iov[0]); > - msg.msg_iovlen = 9; > - msg.msg_control = NULL; > - msg.msg_controllen = 0; > - msg.msg_flags = 0; /* Synchronous for now */ > - > - iov[0].iov_base = HeaderPart1; > - iov[0].iov_len = 45; > - iov[1].iov_base = CurrentTime; > - iov[1].iov_len = 29; > - iov[2].iov_base = HeaderPart3; > - iov[2].iov_len = 16; > - > - iov[3].iov_base = Request->MimeType; > - iov[3].iov_len = Request->MimeLength; > - > - iov[4].iov_base = HeaderPart5; > - iov[4].iov_len = 17; > - iov[5].iov_base = &(Request->TimeS[0]); > - iov[5].iov_len = 29; > - iov[6].iov_base = HeaderPart7; > - iov[6].iov_len = 18; > - iov[7].iov_base = &(Request->LengthS[0]); > - slen = strlen(Request->LengthS); > - iov[7].iov_len = slen; > - iov[8].iov_base = HeaderPart9; > - iov[8].iov_len = 4; > - > - len2=45+2*29+16+17+18+slen+4+iov[3].iov_len; > - > - len = 0; > - > - oldfs = get_fs(); set_fs(KERNEL_DS); > - len = sock_sendmsg(Request->sock,&msg,len2); > - set_fs(oldfs); > - LeaveFunction("SendHTTPHeader"); > - > - > - return; > -} > -#endif > - > - > - > -/* > - > -Parse a HTTP-header. Be careful for buffer-overflows here, this is the most important > -place for this, since the remote-user controls the data. > - > -*/ > -void ParseHeader(char *Buffer,const int length, struct http_request *Head) > -{ > - char *Endval,*EOL,*tmp; > - > - EnterFunction("ParseHeader"); > - Endval = Buffer + length; > - > - /* We want to parse only the first header if multiple headers are present */ > - tmp = strstr(Buffer,"\r\n\r\n"); > - if (tmp!=NULL) > - Endval = tmp; > - > - > - while (Buffer<Endval) > - { > - if (isspace(Buffer[0])) > - { > - Buffer++; > - continue; > - } > - > - > - EOL=strchr(Buffer,'\n'); > - > - if (EOL==NULL) EOL=Endval; > - > - if (EOL-Buffer<4) > - { > - Buffer++; > - continue; > - } > - > - if (strncmp("GET ",Buffer,4)==0) > - { > - int PrefixLen; > - Buffer+=4; > - > - tmp=strchr(Buffer,' '); > - if (tmp==0) > - { > - tmp=EOL-1; > - Head->HTTPVER = 9; > - } else > - Head->HTTPVER = 10; > - > - if (tmp>Endval) continue; > - > - strncpy(Head->FileName,sysctl_khttpd_docroot,sizeof(Head->FileName)); > - PrefixLen = strlen(sysctl_khttpd_docroot); > - Head->FileNameLength = min_t(unsigned int, 255, tmp - Buffer + PrefixLen); > - > - strncat(Head->FileName,Buffer,min_t(unsigned int, 255 - PrefixLen, tmp - Buffer)); > - > - Buffer=EOL+1; > -#ifdef BENCHMARK > - break; > -#endif > - continue; > - } > -#ifndef BENCHMARK > - if (strncmp("If-Modified-Since: ",Buffer,19)==0) > - { > - Buffer+=19; > - > - strncpy(Head->IMS,Buffer,min_t(unsigned int, 127,EOL-Buffer-1)); > - > - Buffer=EOL+1; > - continue; > - } > - > - if (strncmp("User-Agent: ",Buffer,12)==0) > - { > - Buffer+=12; > - > - strncpy(Head->Agent,Buffer,min_t(unsigned int, 127,EOL-Buffer-1)); > - > - Buffer=EOL+1; > - continue; > - } > - > - > - if (strncmp("Host: ",Buffer,6)==0) > - { > - Buffer+=6; > - > - strncpy(Head->Host,Buffer,min_t(unsigned int, 127,EOL-Buffer-1)); > - > - Buffer=EOL+1; > - continue; > - } > -#endif > - Buffer = EOL+1; /* Skip line */ > - } > - LeaveFunction("ParseHeader"); > -} > diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/rfc_time.c linux/net/khttpd/rfc_time.c > --- linux-2.4.19-pre8/net/khttpd/rfc_time.c Fri May 3 13:35:37 2002 > +++ linux/net/khttpd/rfc_time.c Thu Jan 1 01:00:00 1970 > @@ -1,227 +0,0 @@ > -/* > - > -Functions related to time: > - > -1) rfc (string) time to unix-time > -2) unix-time to rfc (string) time > -3) current time to rfc (string) time for the "Date:" header > - > -*/ > - > -/**************************************************************** > - * This program is free software; you can redistribute it and/or modify > - * it under the terms of the GNU General Public License as published by > - * the Free Software Foundation; either version 2, or (at your option) > - * any later version. > - * > - * This program is distributed in the hope that it will be useful, > - * but WITHOUT ANY WARRANTY; without even the implied warranty of > - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > - * GNU General Public License for more details. > - * > - * You should have received a copy of the GNU General Public License > - * along with this program; if not, write to the Free Software > - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. > - * > - ****************************************************************/ > - > -#include <linux/time.h> > -#include <linux/kernel.h> > -#include <linux/slab.h> > -#include <linux/ctype.h> > - > - > -#include "times.h" > -#include "prototypes.h" > -static char *dayName[7] = { > - "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" > -}; > - > -static char *monthName[12] = { > - "Jan", "Feb", "Mar", "Apr", "May", "Jun", > - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" > -}; > - > - > -char CurrentTime[64]; > -int CurrentTime_i; > - > - > -static char itoa_h[60]={'0','0','0','0','0','0','0','0','0','0', > - '1','1','1','1','1','1','1','1','1','1', > - '2','2','2','2','2','2','2','2','2','2', > - '3','3','3','3','3','3','3','3','3','3', > - '4','4','4','4','4','4','4','4','4','4', > - '5','5','5','5','5','5','5','5','5','5'}; > - > -static char itoa_l[60]={'0','1','2','3','4','5','6','7','8','9', > - '0','1','2','3','4','5','6','7','8','9', > - '0','1','2','3','4','5','6','7','8','9', > - '0','1','2','3','4','5','6','7','8','9', > - '0','1','2','3','4','5','6','7','8','9', > - '0','1','2','3','4','5','6','7','8','9'}; > -void time_Unix2RFC(const time_t Zulu,char *Buffer) > -{ > - int Y=0,M=0,D=0; > - int H=0,Min=0,S=0,WD=0; > - int I,I2; > - time_t rest; > - > - > - > - I=0; > - while (I<KHTTPD_NUMYEARS) > - { > - if (TimeDays[I][0]>Zulu) > - break; > - I++; > - } > - > - Y=--I; > - if (I<0) > - { > - Y=0; > - goto BuildYear; > - } > - I2=0; > - while (I2<=12) > - { > - if (TimeDays[I][I2]>Zulu) > - break; > - I2++; > - } > - > - M=I2-1; > - > - rest=Zulu - TimeDays[Y][M]; > - WD=WeekDays[Y][M]; > - D=rest/86400; > - rest=rest%86400; > - WD+=D; > - WD=WD%7; > - H=rest/3600; > - rest=rest%3600; > - Min=rest/60; > - rest=rest%60; > - S=rest; > - > -BuildYear: > - Y+=KHTTPD_YEAROFFSET; > - > - > - /* Format: Day, 01 Mon 1999 01:01:01 GMT */ > - > -/* > - We want to do > - > - sprintf( Buffer, "%s, %02i %s %04i %02i:%02i:%02i GMT", > - dayName[ WD ], D+1, monthName[ M ], Y, > - H, Min, S > - ); > - > - but this is very expensive. Since the string is fixed length, > - it is filled manually. > -*/ > - Buffer[0]=dayName[WD][0]; > - Buffer[1]=dayName[WD][1]; > - Buffer[2]=dayName[WD][2]; > - Buffer[3]=','; > - Buffer[4]=' '; > - Buffer[5]=itoa_h[D+1]; > - Buffer[6]=itoa_l[D+1]; > - Buffer[7]=' '; > - Buffer[8]=monthName[M][0]; > - Buffer[9]=monthName[M][1]; > - Buffer[10]=monthName[M][2]; > - Buffer[11]=' '; > - Buffer[12]=itoa_l[Y/1000]; > - Buffer[13]=itoa_l[(Y/100)%10]; > - Buffer[14]=itoa_l[(Y/10)%10]; > - Buffer[15]=itoa_l[Y%10]; > - Buffer[16]=' '; > - Buffer[17]=itoa_h[H]; > - Buffer[18]=itoa_l[H]; > - Buffer[19]=':'; > - Buffer[20]=itoa_h[Min]; > - Buffer[21]=itoa_l[Min]; > - Buffer[22]=':'; > - Buffer[23]=itoa_h[S]; > - Buffer[24]=itoa_l[S]; > - Buffer[25]=' '; > - Buffer[26]='G'; > - Buffer[27]='M'; > - Buffer[28]='T'; > - Buffer[29]=0; > - > - > - > - > -} > - > -void UpdateCurrentDate(void) > -{ > - struct timeval tv; > - > - do_gettimeofday(&tv); > - if (CurrentTime_i!=tv.tv_sec) > - time_Unix2RFC(tv.tv_sec,CurrentTime); > - > - CurrentTime_i = tv.tv_sec; > -} > - > -static int MonthHash[32] = {0,0,7,0,0,0,0,0,0,0,0,3,0,0,0,2,6,0,5,0,9,8,4,0,0,11,1,10,0,0,0,0}; > - > -#define is_digit(c) ((c) >= '0' && (c) <= '9') > - > -__inline static int skip_atoi(char **s) > -{ > - int i=0; > - > - while (is_digit(**s)) > - i = i*10 + *((*s)++) - '0'; > - return i; > -} > - > -time_t mimeTime_to_UnixTime(char *Q) > -{ > - int Y,M,D,H,Min,S; > - unsigned int Hash; > - time_t Temp; > - char *s,**s2; > - > - s=Q; > - s2=&s; > - > - if (strlen(s)<30) return 0; > - if (s[3]!=',') return 0; > - if (s[19]!=':') return 0; > - > - s+=5; /* Skip day of week */ > - D = skip_atoi(s2); /* Day of month */ > - s++; > - Hash = (unsigned char)s[0]+(unsigned char)s[2]; > - Hash = (Hash<<1) + (unsigned char)s[1]; > - Hash = (Hash&63)>>1; > - M = MonthHash[Hash]; > - s+=4; > - Y = skip_atoi(s2); /* Year */ > - s++; > - H = skip_atoi(s2); /* Hour */ > - s++; > - Min = skip_atoi(s2); /* Minutes */ > - s++; > - S = skip_atoi(s2); /* Seconds */ > - s++; > - if ((s[0]!='G')||(s[1]!='M')||(s[2]!='T')) > - { > - return 0; /* No GMT */ > - } > - > - if (Y<KHTTPD_YEAROFFSET) Y = KHTTPD_YEAROFFSET; > - if (Y>KHTTPD_YEAROFFSET+9) Y = KHTTPD_YEAROFFSET+9; > - > - Temp = TimeDays[Y-KHTTPD_YEAROFFSET][M]; > - Temp += D*86400+H*3600+Min*60+S; > - > - return Temp; > -} > diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/security.c linux/net/khttpd/security.c > --- linux-2.4.19-pre8/net/khttpd/security.c Fri May 3 13:35:31 2002 > +++ linux/net/khttpd/security.c Thu Jan 1 01:00:00 1970 > @@ -1,267 +0,0 @@ > -/* > - > -kHTTPd -- the next generation > - > -Permissions/Security functions > - > -*/ > - > -/**************************************************************** > - * This program is free software; you can redistribute it and/or modify > - * it under the terms of the GNU General Public License as published by > - * the Free Software Foundation; either version 2, or (at your option) > - * any later version. > - * > - * This program is distributed in the hope that it will be useful, > - * but WITHOUT ANY WARRANTY; without even the implied warranty of > - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > - * GNU General Public License for more details. > - * > - * You should have received a copy of the GNU General Public License > - * along with this program; if not, write to the Free Software > - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. > - * > - ****************************************************************/ > - > - > -#include <linux/kernel.h> > - > -#include <linux/errno.h> > -#include <linux/slab.h> > -#include <linux/net.h> > -#include <linux/sched.h> > -#include <linux/skbuff.h> > -#include <linux/smp_lock.h> > -#include <linux/un.h> > -#include <linux/unistd.h> > - > -#include <net/ip.h> > -#include <net/sock.h> > -#include <net/tcp.h> > - > -#include <asm/atomic.h> > -#include <asm/semaphore.h> > -#include <asm/processor.h> > -#include <asm/uaccess.h> > - > -#include <linux/file.h> > - > -#include "sysctl.h" > -#include "security.h" > -#include "prototypes.h" > - > -/* > - > -The basic security function answers "Userspace" when any one of the following > -conditions is met: > - > -1) The filename contains a "?" (this is before % decoding, all others are > - after % decoding) > -2) The filename doesn't start with a "/" > -3) The file does not exist > -4) The file does not have enough permissions > - (sysctl-configurable, default = worldreadble) > -5) The file has any of the "forbidden" permissions > - (sysctl-configurable, default = execute, directory and sticky) > -6) The filename contains a string as defined in the "Dynamic" list. > - > -*/ > - > - > -/* Prototypes */ > - > -static void DecodeHexChars(char *URL); > -static struct DynamicString *DynamicList=NULL; > - > - > - > -/* > - > -The function "OpenFileForSecurity" returns either the "struct file" pointer > -of the file, or NULL. NULL means "let userspace handle it". > - > -*/ > -struct file *OpenFileForSecurity(char *Filename) > -{ > - struct file *filp; > - struct DynamicString *List; > - umode_t permission; > - > - > - > - EnterFunction("OpenFileForSecurity"); > - if (Filename==NULL) > - return NULL; > - > - if (strlen(Filename)>=256 ) return NULL; /* Sanity check */ > - > - /* Rule no. 1 -- No "?" characters */ > -#ifndef BENCHMARK > - if (strchr(Filename,'?')!=NULL) > - return NULL; > - > - /* Intermediate step: decode all %hex sequences */ > - > - DecodeHexChars(Filename); > - > - /* Rule no. 2 -- Must start with a "/" */ > - > - > - if (Filename[0]!='/') > - return NULL; > - > -#endif > - /* Rule no. 3 -- Does the file exist ? */ > - > - filp = filp_open(Filename, O_RDONLY, 0); > - > - if (IS_ERR(filp)) > - return NULL; > - > -#ifndef BENCHMARK > - permission = filp->f_dentry->d_inode->i_mode; > - > - /* Rule no. 4 : must have enough permissions */ > - > - > - if ((permission & sysctl_khttpd_permreq)==0) > - { > - if (filp!=NULL) > - fput(filp); > - filp=NULL; > - return NULL; > - } > - > - /* Rule no. 5 : cannot have "forbidden" permission */ > - > - > - if ((permission & sysctl_khttpd_permforbid)!=0) > - { > - if (filp!=NULL) > - fput(filp); > - filp=NULL; > - return NULL; > - } > - > - /* Rule no. 6 : No string in DynamicList can be a > - substring of the filename */ > - > - > - List = DynamicList; > - > - while (List!=NULL) > - { > - if (strstr(Filename,List->value)!=NULL) > - { > - if (filp!=NULL) > - fput(filp); > - filp=NULL; > - return NULL; > - } > - List = List->Next; > - } > - > -#endif > - LeaveFunction("OpenFileForSecurity - success"); > - > - return filp; > -} > - > -/* > - > -DecodeHexChars does the actual %HEX decoding, in place. > -In place is possible because strings only get shorter by this. > - > -*/ > -static void DecodeHexChars(char *URL) > -{ > - char *Source,*Dest; > - int val,val2; > - > - EnterFunction("DecodeHexChars"); > - > - Source = strchr(URL,'%'); > - > - if (Source==NULL) > - return; > - > - Dest = Source; > - > - while (*Source!=0) > - { > - if (*Source=='%') > - { > - Source++; > - val = *Source; > - > - if (val>'Z') val-=0x20; > - val = val - '0'; > - if (val<0) val=0; > - if (val>9) val-=7; > - if (val>15) val=15; > - > - Source++; > - > - val2 = *Source; > - > - if (val2>'Z') val2-=0x20; > - val2 = val2 - '0'; > - if (val2<0) val2=0; > - if (val2>9) val2-=7; > - if (val2>15) val2=15; > - > - *Dest=val*16+val2; > - } else *Dest = *Source; > - Dest++; > - Source++; > - } > - *Dest=0; > - > - LeaveFunction("DecodeHexChars"); > -} > - > - > -void AddDynamicString(const char *String) > -{ > - struct DynamicString *Temp; > - > - EnterFunction("AddDynamicString"); > - > - Temp = (struct DynamicString*)kmalloc(sizeof(struct DynamicString),(int)GFP_KERNEL); > - > - if (Temp==NULL) > - return; > - > - memset(Temp->value,0,sizeof(Temp->value)); > - strncpy(Temp->value,String,sizeof(Temp->value)-1); > - > - Temp->Next = DynamicList; > - DynamicList = Temp; > - > - LeaveFunction("AddDynamicString"); > -} > - > -void GetSecureString(char *String) > -{ > - struct DynamicString *Temp; > - int max; > - > - EnterFunction("GetSecureString"); > - > - *String = 0; > - > - memset(String,0,255); > - > - strncpy(String,"Dynamic strings are : -",255); > - Temp = DynamicList; > - while (Temp!=NULL) > - { > - max=253 - strlen(String) - strlen(Temp->value); > - strncat(String,Temp->value,max); > - max=253 - strlen(String) - 3; > - strncat(String,"- -",max); > - Temp = Temp->Next; > - } > - > - LeaveFunction("GetSecureString"); > -} > diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/security.h linux/net/khttpd/security.h > --- linux-2.4.19-pre8/net/khttpd/security.h Fri May 3 13:35:46 2002 > +++ linux/net/khttpd/security.h Thu Jan 1 01:00:00 1970 > @@ -1,12 +0,0 @@ > -#ifndef _INCLUDE_GUARD_SECURITY_H > -#define _INCLUDE_GUARD_SECURITY_H > - > -struct DynamicString; > - > -struct DynamicString > -{ > - struct DynamicString* Next; > - char value[32-sizeof(void*)]; /* fill 1 cache-line */ > -}; > - > -#endif > diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/sockets.c linux/net/khttpd/sockets.c > --- linux-2.4.19-pre8/net/khttpd/sockets.c Fri May 3 13:35:39 2002 > +++ linux/net/khttpd/sockets.c Thu Jan 1 01:00:00 1970 > @@ -1,101 +0,0 @@ > -/* > - > -kHTTPd -- the next generation > - > -Basic socket functions > - > -*/ > -/**************************************************************** > - * This program is free software; you can redistribute it and/or modify > - * it under the terms of the GNU General Public License as published by > - * the Free Software Foundation; either version 2, or (at your option) > - * any later version. > - * > - * This program is distributed in the hope that it will be useful, > - * but WITHOUT ANY WARRANTY; without even the implied warranty of > - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > - * GNU General Public License for more details. > - * > - * You should have received a copy of the GNU General Public License > - * along with this program; if not, write to the Free Software > - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. > - * > - ****************************************************************/ > - > -#include "prototypes.h" > -#include <linux/kernel.h> > -#include <linux/net.h> > -#include <linux/version.h> > -#include <linux/smp_lock.h> > -#include <net/sock.h> > - > - > -/* > - > -MainSocket is shared by all threads, therefore it has to be > -a global variable. > - > -*/ > -struct socket *MainSocket=NULL; > - > - > -int StartListening(const int Port) > -{ > - struct socket *sock; > - struct sockaddr_in sin; > - int error; > - > - EnterFunction("StartListening"); > - > - /* First create a socket */ > - > - error = sock_create(PF_INET,SOCK_STREAM,IPPROTO_TCP,&sock); > - if (error<0) > - (void)printk(KERN_ERR "Error during creation of socket; terminating\n"); > - > - > - > - /* Now bind the socket */ > - > - sin.sin_family = AF_INET; > - sin.sin_addr.s_addr = INADDR_ANY; > - sin.sin_port = htons((unsigned short)Port); > - > - error = sock->ops->bind(sock,(struct sockaddr*)&sin,sizeof(sin)); > - if (error<0) > - { > - (void)printk(KERN_ERR "kHTTPd: Error binding socket. This means that some other \n"); > - (void)printk(KERN_ERR " daemon is (or was a short time ago) using port %i.\n",Port); > - return 0; > - } > - > - /* Grrr... setsockopt() does this. */ > - sock->sk->reuse = 1; > - > - /* Now, start listening on the socket */ > - > - /* I have no idea what a sane backlog-value is. 48 works so far. */ > - > - error=sock->ops->listen(sock,48); > - if (error!=0) > - (void)printk(KERN_ERR "kHTTPd: Error listening on socket \n"); > - > - MainSocket = sock; > - > - LeaveFunction("StartListening"); > - return 1; > -} > - > -void StopListening(void) > -{ > - struct socket *sock; > - > - EnterFunction("StopListening"); > - if (MainSocket==NULL) return; > - > - sock=MainSocket; > - MainSocket = NULL; > - sock_release(sock); > - > - LeaveFunction("StopListening"); > -} > diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/structure.h linux/net/khttpd/structure.h > --- linux-2.4.19-pre8/net/khttpd/structure.h Fri May 3 13:34:57 2002 > +++ linux/net/khttpd/structure.h Thu Jan 1 01:00:00 1970 > @@ -1,68 +0,0 @@ > -#ifndef _INCLUDE_GUARD_STRUCTURE_H_ > -#define _INCLUDE_GUARD_STRUCTURE_H_ > - > -#include <linux/time.h> > -#include <linux/wait.h> > - > - > -struct http_request; > - > -struct http_request > -{ > - /* Linked list */ > - struct http_request *Next; > - > - /* Network and File data */ > - struct socket *sock; > - struct file *filp; > - > - /* Raw data about the file */ > - > - int FileLength; /* File length in bytes */ > - int Time; /* mtime of the file, unix format */ > - int BytesSent; /* The number of bytes already sent */ > - int IsForUserspace; /* 1 means let Userspace handle this one */ > - > - /* Wait queue */ > - > - wait_queue_t sleep; /* For putting in the socket's waitqueue */ > - > - /* HTTP request information */ > - char FileName[256]; /* The requested filename */ > - int FileNameLength; /* The length of the string representing the filename */ > - char Agent[128]; /* The agent-string of the remote browser */ > - char IMS[128]; /* If-modified-since time, rfc string format */ > - char Host[128]; /* Value given by the Host: header */ > - int HTTPVER; /* HTTP-version; 9 for 0.9, 10 for 1.0 and above */ > - > - > - /* Derived date from the above fields */ > - int IMS_Time; /* if-modified-since time, unix format */ > - char TimeS[64]; /* File mtime, rfc string representation */ > - char LengthS[14]; /* File length, string representation */ > - char *MimeType; /* Pointer to a string with the mime-type > - based on the filename */ > - __kernel_size_t MimeLength; /* The length of this string */ > - > -}; > - > - > - > -/* > - > -struct khttpd_threadinfo represents the four queues that 1 thread has to deal with. > -It is padded to occupy 1 (Intel) cache-line, to avoid "cacheline-pingpong". > - > -*/ > -struct khttpd_threadinfo > -{ > - struct http_request* WaitForHeaderQueue; > - struct http_request* DataSendingQueue; > - struct http_request* LoggingQueue; > - struct http_request* UserspaceQueue; > - char dummy[16]; /* Padding for cache-lines */ > -}; > - > - > - > -#endif > diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/sysctl.c linux/net/khttpd/sysctl.c > --- linux-2.4.19-pre8/net/khttpd/sysctl.c Fri May 3 13:39:20 2002 > +++ linux/net/khttpd/sysctl.c Thu Jan 1 01:00:00 1970 > @@ -1,320 +0,0 @@ > -/* > - > -kHTTPd -- the next generation > - > -Sysctl interface > - > -*/ > -/**************************************************************** > - * This program is free software; you can redistribute it and/or modify > - * it under the terms of the GNU General Public License as published by > - * the Free Software Foundation; either version 2, or (at your option) > - * any later version. > - * > - * This program is distributed in the hope that it will be useful, > - * but WITHOUT ANY WARRANTY; without even the implied warranty of > - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > - * GNU General Public License for more details. > - * > - * You should have received a copy of the GNU General Public License > - * along with this program; if not, write to the Free Software > - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. > - * > - ****************************************************************/ > - > - > -#include <linux/kernel.h> > -#include <linux/errno.h> > -#include <linux/slab.h> > -#include <linux/net.h> > -#include <linux/sched.h> > -#include <linux/skbuff.h> > -#include <linux/smp_lock.h> > -#include <linux/sysctl.h> > -#include <linux/un.h> > -#include <linux/unistd.h> > - > -#include <net/ip.h> > -#include <net/sock.h> > -#include <net/tcp.h> > - > -#include <asm/atomic.h> > -#include <asm/semaphore.h> > -#include <asm/processor.h> > -#include <asm/uaccess.h> > - > -#include <linux/file.h> > -#include "prototypes.h" > - > - > - > -char sysctl_khttpd_docroot[200] = "/var/www"; > -int sysctl_khttpd_stop = 0; > -int sysctl_khttpd_start = 0; > -int sysctl_khttpd_unload = 0; > -int sysctl_khttpd_clientport = 80; > -int sysctl_khttpd_permreq = S_IROTH; /* "other" read-access is required by default*/ > -int sysctl_khttpd_permforbid = S_IFDIR | S_ISVTX | S_IXOTH | S_IXGRP | S_IXUSR; > - /* forbidden is execute, directory and sticky*/ > -int sysctl_khttpd_logging = 0; > -int sysctl_khttpd_serverport= 8080; > - > -char sysctl_khttpd_dynamicstring[200]; > -int sysctl_khttpd_sloppymime= 0; > -int sysctl_khttpd_threads = 2; > -int sysctl_khttpd_maxconnect = 1000; > - > - > -static struct ctl_table_header *khttpd_table_header; > - > -static int sysctl_SecureString(ctl_table *table, int *name, int nlen, > - void *oldval, size_t *oldlenp, > - void *newval, size_t newlen, void **context); > -static int proc_dosecurestring(ctl_table *table, int write, struct file *filp, > - void *buffer, size_t *lenp); > - > - > -static ctl_table khttpd_table[] = { > - { NET_KHTTPD_DOCROOT, > - "documentroot", > - &sysctl_khttpd_docroot, > - sizeof(sysctl_khttpd_docroot), > - 0644, > - NULL, > - proc_dostring, > - &sysctl_string, > - NULL, > - NULL, > - NULL > - }, > - { NET_KHTTPD_STOP, > - "stop", > - &sysctl_khttpd_stop, > - sizeof(int), > - 0644, > - NULL, > - proc_dointvec, > - &sysctl_intvec, > - NULL, > - NULL, > - NULL > - }, > - { NET_KHTTPD_START, > - "start", > - &sysctl_khttpd_start, > - sizeof(int), > - 0644, > - NULL, > - proc_dointvec, > - &sysctl_intvec, > - NULL, > - NULL, > - NULL > - }, > - { NET_KHTTPD_UNLOAD, > - "unload", > - &sysctl_khttpd_unload, > - sizeof(int), > - 0644, > - NULL, > - proc_dointvec, > - &sysctl_intvec, > - NULL, > - NULL, > - NULL > - }, > - { NET_KHTTPD_THREADS, > - "threads", > - &sysctl_khttpd_threads, > - sizeof(int), > - 0644, > - NULL, > - proc_dointvec, > - &sysctl_intvec, > - NULL, > - NULL, > - NULL > - }, > - { NET_KHTTPD_MAXCONNECT, > - "maxconnect", > - &sysctl_khttpd_maxconnect, > - sizeof(int), > - 0644, > - NULL, > - proc_dointvec, > - &sysctl_intvec, > - NULL, > - NULL, > - NULL > - }, > - { NET_KHTTPD_SLOPPYMIME, > - "sloppymime", > - &sysctl_khttpd_sloppymime, > - sizeof(int), > - 0644, > - NULL, > - proc_dointvec, > - &sysctl_intvec, > - NULL, > - NULL, > - NULL > - }, > - { NET_KHTTPD_CLIENTPORT, > - "clientport", > - &sysctl_khttpd_clientport, > - sizeof(int), > - 0644, > - NULL, > - proc_dointvec, > - &sysctl_intvec, > - NULL, > - NULL, > - NULL > - }, > - { NET_KHTTPD_PERMREQ, > - "perm_required", > - &sysctl_khttpd_permreq, > - sizeof(int), > - 0644, > - NULL, > - proc_dointvec, > - &sysctl_intvec, > - NULL, > - NULL, > - NULL > - }, > - { NET_KHTTPD_PERMFORBID, > - "perm_forbid", > - &sysctl_khttpd_permforbid, > - sizeof(int), > - 0644, > - NULL, > - proc_dointvec, > - &sysctl_intvec, > - NULL, > - NULL, > - NULL > - }, > - { NET_KHTTPD_LOGGING, > - "logging", > - &sysctl_khttpd_logging, > - sizeof(int), > - 0644, > - NULL, > - proc_dointvec, > - &sysctl_intvec, > - NULL, > - NULL, > - NULL > - }, > - { NET_KHTTPD_SERVERPORT, > - "serverport", > - &sysctl_khttpd_serverport, > - sizeof(int), > - 0644, > - NULL, > - proc_dointvec, > - &sysctl_intvec, > - NULL, > - NULL, > - NULL > - }, > - { NET_KHTTPD_DYNAMICSTRING, > - "dynamic", > - &sysctl_khttpd_dynamicstring, > - sizeof(sysctl_khttpd_dynamicstring), > - 0644, > - NULL, > - proc_dosecurestring, > - &sysctl_SecureString, > - NULL, > - NULL, > - NULL > - }, > - {0,0,0,0,0,0,0,0,0,0,0} }; > - > - > -static ctl_table khttpd_dir_table[] = { > - {NET_KHTTPD, "khttpd", NULL, 0, 0555, khttpd_table,0,0,0,0,0}, > - {0,0,0,0,0,0,0,0,0,0,0} > -}; > - > -static ctl_table khttpd_root_table[] = { > - {CTL_NET, "net", NULL, 0, 0555, khttpd_dir_table,0,0,0,0,0}, > - {0,0,0,0,0,0,0,0,0,0,0} > -}; > - > - > -void StartSysctl(void) > -{ > - khttpd_table_header = register_sysctl_table(khttpd_root_table,1); > -} > - > - > -void EndSysctl(void) > -{ > - unregister_sysctl_table(khttpd_table_header); > -} > - > -static int proc_dosecurestring(ctl_table *table, int write, struct file *filp, > - void *buffer, size_t *lenp) > -{ > - size_t len; > - char *p, c=0; > - char String[256]; > - > - if ((table->data==0) || (table->maxlen==0) || (*lenp==0) || > - ((filp->f_pos!=0) && (write==0))) { > - *lenp = 0; > - return 0; > - } > - > - if (write!=0) { > - len = 0; > - p = buffer; > - while (len < *lenp) { > - if(get_user(c, p++)) > - return -EFAULT; > - if (c == 0 || c == '\n') > - break; > - len++; > - } > - if (len >= table->maxlen) > - len = table->maxlen-1; > - if(copy_from_user(String, buffer,(unsigned long)len)) > - return -EFAULT; > - ((char *) String)[len] = 0; > - filp->f_pos += *lenp; > - AddDynamicString(String); > - } else { > - GetSecureString(String); > - len = strlen(String); > - if (len > table->maxlen) > - len = table->maxlen; > - if (len > *lenp) > - len = *lenp; > - if (len!=0) > - if(copy_to_user(buffer, String,(unsigned long)len)) > - return -EFAULT; > - if (len < *lenp) { > - if(put_user('\n', ((char *) buffer) + len)) > - return -EFAULT; > - len++; > - } > - *lenp = len; > - filp->f_pos += len; > - } > - return 0; > -} > - > -static int sysctl_SecureString (/*@unused@*/ctl_table *table, > - /*@unused@*/int *name, > - /*@unused@*/int nlen, > - /*@unused@*/void *oldval, > - /*@unused@*/size_t *oldlenp, > - /*@unused@*/void *newval, > - /*@unused@*/size_t newlen, > - /*@unused@*/void **context) > -{ > - return -ENOSYS; > -} > diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/sysctl.h linux/net/khttpd/sysctl.h > --- linux-2.4.19-pre8/net/khttpd/sysctl.h Fri May 3 13:36:47 2002 > +++ linux/net/khttpd/sysctl.h Thu Jan 1 01:00:00 1970 > @@ -1,17 +0,0 @@ > -#ifndef _KHTTPD_INCLUDE_GUARD_SYSCTL_H > -#define _KHTTPD_INCLUDE_GUARD_SYSCTL_H > - > -extern char sysctl_khttpd_docroot[200]; > -extern int sysctl_khttpd_stop; > -extern int sysctl_khttpd_start; > -extern int sysctl_khttpd_unload; > -extern int sysctl_khttpd_clientport; > -extern int sysctl_khttpd_permreq; > -extern int sysctl_khttpd_permforbid; > -extern int sysctl_khttpd_logging; > -extern int sysctl_khttpd_serverport; > -extern int sysctl_khttpd_sloppymime; > -extern int sysctl_khttpd_threads; > -extern int sysctl_khttpd_maxconnect; > - > -#endif > diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/userspace.c linux/net/khttpd/userspace.c > --- linux-2.4.19-pre8/net/khttpd/userspace.c Fri May 3 13:35:53 2002 > +++ linux/net/khttpd/userspace.c Thu Jan 1 01:00:00 1970 > @@ -1,243 +0,0 @@ > -/* > - > -kHTTPd -- the next generation > - > -Pass connections to userspace-daemons > - > -*/ > -/**************************************************************** > - * This program is free software; you can redistribute it and/or modify > - * it under the terms of the GNU General Public License as published by > - * the Free Software Foundation; either version 2, or (at your option) > - * any later version. > - * > - * This program is distributed in the hope that it will be useful, > - * but WITHOUT ANY WARRANTY; without even the implied warranty of > - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > - * GNU General Public License for more details. > - * > - * You should have received a copy of the GNU General Public License > - * along with this program; if not, write to the Free Software > - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. > - * > - ****************************************************************/ > - > -/* > - > -Purpose: > - > -Userspace() hands all requests in the queue to the userspace-daemon, if > -such beast exists. > - > -Return value: > - The number of requests that changed status > -*/ > -#include <linux/kernel.h> > - > -#include <linux/errno.h> > -#include <linux/slab.h> > -#include <linux/net.h> > -#include <linux/sched.h> > -#include <linux/skbuff.h> > -#include <linux/smp_lock.h> > -#include <linux/un.h> > -#include <linux/unistd.h> > -#include <linux/wait.h> > - > -#include <net/ip.h> > -#include <net/sock.h> > -#include <net/tcp.h> > - > -#include <asm/atomic.h> > -#include <asm/semaphore.h> > -#include <asm/processor.h> > -#include <asm/uaccess.h> > - > -#include <linux/file.h> > - > - > -#include "structure.h" > -#include "prototypes.h" > -#include "sysctl.h" > - > -/* prototypes of local, static functions */ > -static int AddSocketToAcceptQueue(struct socket *sock,const int Port); > - > - > -int Userspace(const int CPUNR) > -{ > - struct http_request *CurrentRequest,**Prev,*Next; > - > - EnterFunction("Userspace"); > - > - > - > - > - CurrentRequest = threadinfo[CPUNR].UserspaceQueue; > - Prev = &(threadinfo[CPUNR].UserspaceQueue); > - > - while (CurrentRequest!=NULL) > - { > - > - /* Clean-up the waitqueue of the socket.. Bad things happen if > - this is forgotten. */ > - if (CurrentRequest->sock!=NULL) > - { > - if ((CurrentRequest->sock!=NULL)&&(CurrentRequest->sock->sk!=NULL)) > - { > - remove_wait_queue(CurrentRequest->sock->sk->sleep,&(CurrentRequest->sleep)); > - } > - } > - > - > - if (AddSocketToAcceptQueue(CurrentRequest->sock,sysctl_khttpd_clientport)>=0) > - { > - > - (*Prev) = CurrentRequest->Next; > - Next = CurrentRequest->Next; > - > - > - sock_release(CurrentRequest->sock); > - CurrentRequest->sock = NULL; /* We no longer own it */ > - > - CleanUpRequest(CurrentRequest); > - > - CurrentRequest = Next; > - continue; > - > - } > - else /* No userspace-daemon present, or other problems with it */ > - { > - (*Prev) = CurrentRequest->Next; > - Next = CurrentRequest->Next; > - > - Send403(CurrentRequest->sock); /* Sorry, no go... */ > - > - CleanUpRequest(CurrentRequest); > - > - CurrentRequest = Next; > - continue; > - > - } > - > - > - Prev = &(CurrentRequest->Next); > - CurrentRequest = CurrentRequest->Next; > - } > - > - LeaveFunction("Userspace"); > - return 0; > -} > - > -void StopUserspace(const int CPUNR) > -{ > - struct http_request *CurrentRequest,*Next; > - > - EnterFunction("StopUserspace"); > - CurrentRequest = threadinfo[CPUNR].UserspaceQueue; > - > - while (CurrentRequest!=NULL) > - { > - Next= CurrentRequest->Next; > - CleanUpRequest(CurrentRequest); > - CurrentRequest=Next; > - } > - threadinfo[CPUNR].UserspaceQueue = NULL; > - > - LeaveFunction("StopUserspace"); > -} > - > - > -/* > - "FindUserspace" returns the struct sock of the userspace-daemon, so that we can > - "drop" our request in the accept-queue > -*/ > - > -static struct sock *FindUserspace(const unsigned short Port) > -{ > - struct sock *sk; > - > - EnterFunction("FindUserspace"); > - > - local_bh_disable(); > - sk = tcp_v4_lookup_listener(INADDR_ANY,Port,0); > - local_bh_enable(); > - return sk; > -} > - > -static void dummy_destructor(struct open_request *req) > -{ > -} > - > -static struct or_calltable Dummy = > -{ > - 0, > - NULL, > - NULL, > - &dummy_destructor, > - NULL > -}; > - > -static int AddSocketToAcceptQueue(struct socket *sock,const int Port) > -{ > - struct open_request *req; > - struct sock *sk, *nsk; > - > - EnterFunction("AddSocketToAcceptQueue"); > - > - > - sk = FindUserspace((unsigned short)Port); > - > - if (sk==NULL) /* No userspace-daemon found */ > - { > - return -1; > - } > - > - lock_sock(sk); > - > - if (sk->state != TCP_LISTEN || tcp_acceptq_is_full(sk)) > - { > - release_sock(sk); > - sock_put(sk); > - return -1; > - } > - > - req = tcp_openreq_alloc(); > - > - if (req==NULL) > - { > - release_sock(sk); > - sock_put(sk); > - return -1; > - } > - > - nsk = sock->sk; > - sock->sk = NULL; > - sock->state = SS_UNCONNECTED; > - > - req->class = &Dummy; > - write_lock_bh(&nsk->callback_lock); > - nsk->socket = NULL; > - nsk->sleep = NULL; > - write_unlock_bh(&nsk->callback_lock); > - > - tcp_acceptq_queue(sk, req, nsk); > - > - sk->data_ready(sk, 0); > - > - release_sock(sk); > - sock_put(sk); > - > - LeaveFunction("AddSocketToAcceptQueue"); > - > - return +1; > - > - > - > -} > - > -void InitUserspace(const int CPUNR) > -{ > -} > - > - > diff -uNr -Xdontdiff linux-2.4.19-pre8/net/khttpd/waitheaders.c linux/net/khttpd/waitheaders.c > --- linux-2.4.19-pre8/net/khttpd/waitheaders.c Fri May 3 13:36:59 2002 > +++ linux/net/khttpd/waitheaders.c Thu Jan 1 01:00:00 1970 > @@ -1,296 +0,0 @@ > -/* > - > -kHTTPd -- the next generation > - > -Wait for headers on the accepted connections > - > -*/ > -/**************************************************************** > - * This program is free software; you can redistribute it and/or modify > - * it under the terms of the GNU General Public License as published by > - * the Free Software Foundation; either version 2, or (at your option) > - * any later version. > - * > - * This program is distributed in the hope that it will be useful, > - * but WITHOUT ANY WARRANTY; without even the implied warranty of > - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > - * GNU General Public License for more details. > - * > - * You should have received a copy of the GNU General Public License > - * along with this program; if not, write to the Free Software > - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. > - * > - ****************************************************************/ > - > -/* > - > -Purpose: > - > -WaitForHeaders polls all connections in "WaitForHeaderQueue" to see if > -headers have arived. If so, the headers are decoded and the request is > -moved to either the "SendingDataQueue" or the "UserspaceQueue". > - > -Return value: > - The number of requests that changed status > -*/ > - > -#include <linux/config.h> > -#include <linux/kernel.h> > -#include <linux/skbuff.h> > -#include <linux/smp_lock.h> > -#include <linux/file.h> > - > -#include <asm/uaccess.h> > - > -#include "structure.h" > -#include "prototypes.h" > - > -static char *Buffer[CONFIG_KHTTPD_NUMCPU]; > - > - > -static int DecodeHeader(const int CPUNR, struct http_request *Request); > - > - > -int WaitForHeaders(const int CPUNR) > -{ > - struct http_request *CurrentRequest,**Prev; > - struct sock *sk; > - int count = 0; > - > - EnterFunction("WaitForHeaders"); > - > - CurrentRequest = threadinfo[CPUNR].WaitForHeaderQueue; > - > - Prev = &(threadinfo[CPUNR].WaitForHeaderQueue); > - > - while (CurrentRequest!=NULL) > - { > - > - /* If the connection is lost, remove from queue */ > - > - if (CurrentRequest->sock->sk->state != TCP_ESTABLISHED > - && CurrentRequest->sock->sk->state != TCP_CLOSE_WAIT) > - { > - struct http_request *Next; > - > - Next = CurrentRequest->Next; > - > - *Prev = CurrentRequest->Next; > - CurrentRequest->Next = NULL; > - > - > - CleanUpRequest(CurrentRequest); > - CurrentRequest = Next; > - continue; > - } > - > - > - > - /* If data pending, take action */ > - > - sk = CurrentRequest->sock->sk; > - > - if (!skb_queue_empty(&(sk->receive_queue))) /* Do we have data ? */ > - { > - struct http_request *Next; > - > - > - > - /* Decode header */ > - > - if (DecodeHeader(CPUNR,CurrentRequest)<0) > - { > - CurrentRequest = CurrentRequest->Next; > - continue; > - } > - > - > - /* Remove from WaitForHeaderQueue */ > - > - Next= CurrentRequest->Next; > - > - *Prev = Next; > - count++; > - > - /* Add to either the UserspaceQueue or the DataSendingQueue */ > - > - if (CurrentRequest->IsForUserspace!=0) > - { > - CurrentRequest->Next = threadinfo[CPUNR].UserspaceQueue; > - threadinfo[CPUNR].UserspaceQueue = CurrentRequest; > - } else > - { > - CurrentRequest->Next = threadinfo[CPUNR].DataSendingQueue; > - threadinfo[CPUNR].DataSendingQueue = CurrentRequest; > - } > - > - CurrentRequest = Next; > - continue; > - > - } > - > - > - Prev = &(CurrentRequest->Next); > - CurrentRequest = CurrentRequest->Next; > - } > - > - LeaveFunction("WaitHeaders"); > - return count; > -} > - > -void StopWaitingForHeaders(const int CPUNR) > -{ > - struct http_request *CurrentRequest,*Next; > - > - EnterFunction("StopWaitingForHeaders"); > - CurrentRequest = threadinfo[CPUNR].WaitForHeaderQueue; > - > - while (CurrentRequest!=NULL) > - { > - Next = CurrentRequest->Next; > - CleanUpRequest(CurrentRequest); > - CurrentRequest=Next; > - } > - > - threadinfo[CPUNR].WaitForHeaderQueue = NULL; /* The queue is empty now */ > - > - free_page((unsigned long)Buffer[CPUNR]); > - Buffer[CPUNR]=NULL; > - > - EnterFunction("StopWaitingForHeaders"); > -} > - > - > -/* > - > -DecodeHeader peeks at the TCP/IP data, determines what the request is, > -fills the request-structure and sends the HTTP-header when apropriate. > - > -*/ > - > -static int DecodeHeader(const int CPUNR, struct http_request *Request) > -{ > - struct msghdr msg; > - struct iovec iov; > - int len; > - > - mm_segment_t oldfs; > - > - EnterFunction("DecodeHeader"); > - > - /* First, read the data */ > - > - msg.msg_name = 0; > - msg.msg_namelen = 0; > - msg.msg_iov = &iov; > - msg.msg_iovlen = 1; > - msg.msg_control = NULL; > - msg.msg_controllen = 0; > - msg.msg_flags = 0; > - > - msg.msg_iov->iov_base = &Buffer[CPUNR][0]; > - msg.msg_iov->iov_len = (size_t)4095; > - > - len = 0; > - oldfs = get_fs(); set_fs(KERNEL_DS); > - /* 4095 leaves a "0" to terminate the string */ > - > - len = sock_recvmsg(Request->sock,&msg,4095,MSG_PEEK); > - set_fs(oldfs); > - > - if (len<0) { > - /* WONDERFUL. NO COMMENTS. --ANK */ > - Request->IsForUserspace = 1; > - return 0; > - } > - > - if (len>=4094) /* BIG header, we cannot decode it so leave it to userspace */ > - { > - Request->IsForUserspace = 1; > - return 0; > - } > - > - /* Then, decode the header */ > - > - > - ParseHeader(Buffer[CPUNR],len,Request); > - > - Request->filp = OpenFileForSecurity(Request->FileName); > - > - > - Request->MimeType = ResolveMimeType(Request->FileName,&Request->MimeLength); > - > - > - if (Request->MimeType==NULL) /* Unknown mime-type */ > - { > - if (Request->filp!=NULL) > - { > - fput(Request->filp); > - Request->filp = NULL; > - } > - Request->IsForUserspace = 1; > - > - return 0; > - } > - > - if (Request->filp==NULL) > - { > - Request->IsForUserspace = 1; > - return 0; > - } > - else > - { > - Request->FileLength = (int)Request->filp->f_dentry->d_inode->i_size; > - Request->Time = Request->filp->f_dentry->d_inode->i_mtime; > - Request->IMS_Time = mimeTime_to_UnixTime(Request->IMS); > - sprintf(Request->LengthS,"%i",Request->FileLength); > - time_Unix2RFC(min_t(unsigned int, Request->Time,CurrentTime_i),Request->TimeS); > - /* The min() is required by rfc1945, section 10.10: > - It is not allowed to send a filetime in the future */ > - > - if (Request->IMS_Time>Request->Time) > - { /* Not modified since last time */ > - Send304(Request->sock); > - Request->FileLength=0; > - } > - else /* Normal Case */ > - { > - Request->sock->sk->tp_pinfo.af_tcp.nonagle = 2; /* this is TCP_CORK */ > - if (Request->HTTPVER!=9) /* HTTP/0.9 doesn't allow a header */ > - SendHTTPHeader(Request); > - } > - > - > - } > - > - LeaveFunction("DecodeHeader"); > - return 0; > -} > - > - > -int InitWaitHeaders(int ThreadCount) > -{ > - int I,I2; > - > - EnterFunction("InitWaitHeaders"); > - I=0; > - while (I<ThreadCount) > - { > - Buffer[I] = (char*)get_free_page((int)GFP_KERNEL); > - if (Buffer[I] == NULL) > - { > - printk(KERN_CRIT "kHTTPd: Not enough memory for basic needs\n"); > - I2=0; > - while (I2<I-1) > - { > - free_page( (unsigned long)Buffer[I2++]); > - } > - return -1; > - } > - I++; > - } > - > - LeaveFunction("InitWaitHeaders"); > - return 0; > - > -} > diff -uNr -Xdontdiff linux-2.4.19-pre8/net/netsyms.c linux/net/netsyms.c > --- linux-2.4.19-pre8/net/netsyms.c Fri May 3 13:37:36 2002 > +++ linux/net/netsyms.c Mon May 6 12:53:39 2002 > @@ -56,7 +56,7 @@ > > extern struct net_proto_family inet_family_ops; > > -#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) || defined (CONFIG_KHTTPD) || defined (CONFIG_KHTTPD_MODULE) > +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) > #include <linux/in6.h> > #include <linux/icmpv6.h> > #include <net/ipv6.h> > @@ -295,7 +295,7 @@ > #include <net/ip6_route.h> > EXPORT_SYMBOL(ip6_route_output); > #endif > -#if defined (CONFIG_IPV6_MODULE) || defined (CONFIG_KHTTPD) || defined (CONFIG_KHTTPD_MODULE) > +#if defined (CONFIG_IPV6_MODULE) > /* inet functions common to v4 and v6 */ > EXPORT_SYMBOL(inet_release); > EXPORT_SYMBOL(inet_stream_connect); > > > - > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ > ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: khttpd rotten? 2002-05-06 10:23 ` Christoph Hellwig 2002-05-06 11:28 ` [PATCH] " Dan Kegel 2002-05-06 17:23 ` Luigi Genoni @ 2002-05-09 9:49 ` David S. Miller 2002-05-09 10:09 ` Christoph Hellwig 2 siblings, 1 reply; 35+ messages in thread From: David S. Miller @ 2002-05-09 9:49 UTC (permalink / raw) To: hch; +Cc: dank, arjanv, marcelo, khttpd-users, linux-kernel From: Christoph Hellwig <hch@infradead.org> Date: Mon, 6 May 2002 11:23:00 +0100 On Sun, May 05, 2002 at 07:39:42PM -0700, Dan Kegel wrote: > Right. If khttpd had been pulled from 2.4.17, I would have > had weeks of warning that khttpd is unstable; instead, I learned > only when someone started doing his own stress testing, and I > have little time to fix it. I say pull it from > 2.4.19-pre9. Marcello, put it out of its misery asap, please... > it'd time for khttpd to become a standalone patch again. Okay, what about the following: Are you willing to start being the khttp maintainer? I have not seen updates or any attempts at maintaining the thing in about 2 years. Basically, since it went into the tree. If we aren't changing that situation, we are not removing the impetus for taking khttpd out of the tree entirely. ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: khttpd rotten? 2002-05-09 9:49 ` David S. Miller @ 2002-05-09 10:09 ` Christoph Hellwig 2002-05-09 13:04 ` Luigi Genoni 0 siblings, 1 reply; 35+ messages in thread From: Christoph Hellwig @ 2002-05-09 10:09 UTC (permalink / raw) To: David S. Miller; +Cc: dank, arjanv, marcelo, khttpd-users, linux-kernel On Thu, May 09, 2002 at 02:49:12AM -0700, David S. Miller wrote: > > have little time to fix it. I say pull it from > > 2.4.19-pre9. Marcello, put it out of its misery asap, please... > > it'd time for khttpd to become a standalone patch again. > > Okay, what about the following: > > Are you willing to start being the khttp maintainer? > > I have not seen updates or any attempts at maintaining the > thing in about 2 years. Basically, since it went into the > tree. > > If we aren't changing that situation, we are not removing > the impetus for taking khttpd out of the tree entirely. If khttpd is out-of-tree I volunteer for collecting patches if that is enough for the maintainer status. But I have to admit that I don't really care for it.. ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: khttpd rotten? 2002-05-09 10:09 ` Christoph Hellwig @ 2002-05-09 13:04 ` Luigi Genoni 2002-05-11 0:13 ` Ken Brownfield 0 siblings, 1 reply; 35+ messages in thread From: Luigi Genoni @ 2002-05-09 13:04 UTC (permalink / raw) To: Christoph Hellwig Cc: David S. Miller, dank, arjanv, marcelo, khttpd-users, linux-kernel On Thu, 9 May 2002, Christoph Hellwig wrote: > On Thu, May 09, 2002 at 02:49:12AM -0700, David S. Miller wrote: > > > have little time to fix it. I say pull it from > > > 2.4.19-pre9. Marcello, put it out of its misery asap, please... > > > it'd time for khttpd to become a standalone patch again. > > > > Okay, what about the following: > > > > Are you willing to start being the khttp maintainer? > > > > I have not seen updates or any attempts at maintaining the > > thing in about 2 years. Basically, since it went into the > > tree. > > > > If we aren't changing that situation, we are not removing > > the impetus for taking khttpd out of the tree entirely. > > If khttpd is out-of-tree I volunteer for collecting patches if that > is enough for the maintainer status. But I have to admit that I don't > really care for it.. > - I do care, but I have no time at all. Onestly, I do not think I am the only one using khttpd fruitfully, but I tend to suspect that people using it are more silent in front of people who do not care for it. ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: khttpd rotten? 2002-05-09 13:04 ` Luigi Genoni @ 2002-05-11 0:13 ` Ken Brownfield 0 siblings, 0 replies; 35+ messages in thread From: Ken Brownfield @ 2002-05-11 0:13 UTC (permalink / raw) To: Luigi Genoni Cc: Christoph Hellwig, David S. Miller, dank, arjanv, marcelo, khttpd-users, linux-kernel I've been using it quite fruitfully. I think taking it out of 2.4 isn't a good decision. If 2.4 is supposed to be a stable tree with few major changes, suddenly taking out functionality that some people rely on seems inconsistent with that goal. This action would be much more fatal for the average person who doesn't routinely add feature patchsets to their kernels, unlike most of us. However, I am by no means saying khttpd deserves to be in the kernel, per se. But the decision to remove or not should be a consensus either way. Taking it out of 2.5 seems like a very good idea, especially if it's not being maintained, and especially once TUX2 becomes production-quality, Replace khttpd with TUX2 in 2.5, says this 'more silent' khttpd user. :) -- Ken. ken@irridia.com On Thu, May 09, 2002 at 03:04:26PM +0200, Luigi Genoni wrote: | | | On Thu, 9 May 2002, Christoph Hellwig wrote: | | > On Thu, May 09, 2002 at 02:49:12AM -0700, David S. Miller wrote: | > > > have little time to fix it. I say pull it from | > > > 2.4.19-pre9. Marcello, put it out of its misery asap, please... | > > > it'd time for khttpd to become a standalone patch again. | > > | > > Okay, what about the following: | > > | > > Are you willing to start being the khttp maintainer? | > > | > > I have not seen updates or any attempts at maintaining the | > > thing in about 2 years. Basically, since it went into the | > > tree. | > > | > > If we aren't changing that situation, we are not removing | > > the impetus for taking khttpd out of the tree entirely. | > | > If khttpd is out-of-tree I volunteer for collecting patches if that | > is enough for the maintainer status. But I have to admit that I don't | > really care for it.. | > - | I do care, but I have no time at all. | Onestly, I do not think I am the only one using khttpd fruitfully, but I | tend to suspect that people using it are more silent in front of people | who do not care for it. | | | | | | - | To unsubscribe from this list: send the line "unsubscribe linux-kernel" in | the body of a message to majordomo@vger.kernel.org | More majordomo info at http://vger.kernel.org/majordomo-info.html | Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 35+ messages in thread
* Tux in main kernel tree? (was khttpd rotten?) 2002-05-06 2:39 ` Dan Kegel 2002-05-06 10:23 ` Christoph Hellwig @ 2002-05-06 14:17 ` Roy Sigurd Karlsbakk 2002-05-06 16:08 ` Andy Carlson ` (2 more replies) 1 sibling, 3 replies; 35+ messages in thread From: Roy Sigurd Karlsbakk @ 2002-05-06 14:17 UTC (permalink / raw) To: Dan Kegel; +Cc: David S. Miller, khttpd-users, linux-kernel > Right. If khttpd had been pulled from 2.4.17, I would have > had weeks of warning that khttpd is unstable; instead, I learned > only when someone started doing his own stress testing, and I > have little time to fix it. I say pull it from > 2.4.19-pre9. Marcello, put it out of its misery asap, please... > it'd time for khttpd to become a standalone patch again. > - Dan Hi all Perhaps it's about time to talk about pulling Tux into the main kernel tree, as khttpd once again has proved ususable. roy -- Roy Sigurd Karlsbakk, Datavaktmester Computers are like air conditioners. They stop working when you open Windows. ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: Tux in main kernel tree? (was khttpd rotten?) 2002-05-06 14:17 ` Tux in main kernel tree? (was khttpd rotten?) Roy Sigurd Karlsbakk @ 2002-05-06 16:08 ` Andy Carlson 2002-05-06 23:35 ` Anton Blanchard 2002-05-07 14:42 ` Alan Cox 2002-05-06 17:21 ` Dan Kegel 2002-05-06 18:42 ` John Stoffel 2 siblings, 2 replies; 35+ messages in thread From: Andy Carlson @ 2002-05-06 16:08 UTC (permalink / raw) To: linux-kernel On Mon, 6 May 2002, Roy Sigurd Karlsbakk wrote: > Perhaps it's about time to talk about pulling Tux into the main kernel > tree, as khttpd once again has proved ususable. > Do the userspace tools still depend on Redhat or a derivative? If this is true, I would say that Tux should stay out of the kernel. It is aggravating when you want to try something new, and run into dependencies on specific distros. -- Andy Carlson |\ _,,,---,,_ naclos@swbell.net ZZZzz /,`.-'`' -. ;-;;,_ Cat Pics: http://andyc.dyndns.org/animal.html |,4- ) )-,_. ,\ ( `'-' St. Louis, Missouri '---''(_/--' `-'\_) ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: Tux in main kernel tree? (was khttpd rotten?) 2002-05-06 16:08 ` Andy Carlson @ 2002-05-06 23:35 ` Anton Blanchard 2002-05-07 14:42 ` Alan Cox 1 sibling, 0 replies; 35+ messages in thread From: Anton Blanchard @ 2002-05-06 23:35 UTC (permalink / raw) To: Andy Carlson; +Cc: linux-kernel > Do the userspace tools still depend on Redhat or a derivative? If this > is true, I would say that Tux should stay out of the kernel. It is > aggravating when you want to try something new, and run into > dependencies on specific distros. No, I use tux on a ppc64 debian machine. It took 30 seconds of adapting the tux rc file. Anton ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: Tux in main kernel tree? (was khttpd rotten?) 2002-05-06 16:08 ` Andy Carlson 2002-05-06 23:35 ` Anton Blanchard @ 2002-05-07 14:42 ` Alan Cox 2002-05-07 15:03 ` Andrea Arcangeli 1 sibling, 1 reply; 35+ messages in thread From: Alan Cox @ 2002-05-07 14:42 UTC (permalink / raw) To: Andy Carlson; +Cc: linux-kernel > Do the userspace tools still depend on Redhat or a derivative? If this Never have done. > is true, I would say that Tux should stay out of the kernel. It is > aggravating when you want to try something new, and run into > dependencies on specific distros. Tux has a lot of other things that make it questionable for merging - incredibly so for 2.4 - it sticks its fingers into task structs, dcache and other places. ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: Tux in main kernel tree? (was khttpd rotten?) 2002-05-07 14:42 ` Alan Cox @ 2002-05-07 15:03 ` Andrea Arcangeli 2002-05-07 15:26 ` Alan Cox 2002-05-07 16:02 ` Luigi Genoni 0 siblings, 2 replies; 35+ messages in thread From: Andrea Arcangeli @ 2002-05-07 15:03 UTC (permalink / raw) To: Alan Cox; +Cc: Andy Carlson, linux-kernel On Tue, May 07, 2002 at 03:42:47PM +0100, Alan Cox wrote: > Tux has a lot of other things that make it questionable for merging - > incredibly so for 2.4 - it sticks its fingers into task structs, dcache I don't buy that, so you may want to give us an answer for why is it included into the redhat 2.4 kernel if according to you it's incredibly questionable for merging into 2.4? I merged it and it's trivial to merge, all "questionable" patches are obviously safe. If Marcelo accepts my patches, I will be very glad to replace khttpd with tux into mainline 2.4. The two products are completly equivalent and risking to increase the khttpd userbase just because tux isn't in mainline doesn't make any sense to me, it can only waste resources. (despite it makes much more sense to use zope, apache, servlets and php instead of tux for anything real, first of all for security reasons, but that's another issue, here the issue is khttpd vs tux and this one is a no brainer) Andrea ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: Tux in main kernel tree? (was khttpd rotten?) 2002-05-07 15:03 ` Andrea Arcangeli @ 2002-05-07 15:26 ` Alan Cox 2002-05-07 15:38 ` Andrea Arcangeli 2002-05-07 16:02 ` Luigi Genoni 1 sibling, 1 reply; 35+ messages in thread From: Alan Cox @ 2002-05-07 15:26 UTC (permalink / raw) To: Andrea Arcangeli; +Cc: Alan Cox, Andy Carlson, linux-kernel > On Tue, May 07, 2002 at 03:42:47PM +0100, Alan Cox wrote: > > Tux has a lot of other things that make it questionable for merging - > > incredibly so for 2.4 - it sticks its fingers into task structs, dcache > > I don't buy that, so you may want to give us an answer for why is it > included into the redhat 2.4 kernel if according to you it's incredibly > questionable for merging into 2.4? The Red Hat goal is to provide an extremely high quality tested distribution. There are several things TuX needs that are stable, and high quality but which Linus rejected because they put TuX specific code in places like the dcache where from a pure clean kernel point of view it is undesirable. Alan ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: Tux in main kernel tree? (was khttpd rotten?) 2002-05-07 15:26 ` Alan Cox @ 2002-05-07 15:38 ` Andrea Arcangeli 0 siblings, 0 replies; 35+ messages in thread From: Andrea Arcangeli @ 2002-05-07 15:38 UTC (permalink / raw) To: Alan Cox; +Cc: Andy Carlson, linux-kernel On Tue, May 07, 2002 at 04:26:02PM +0100, Alan Cox wrote: > which Linus rejected because they put TuX specific code in places like > the dcache where from a pure clean kernel point of view it is not a good example, that is been cleanedup in latest tux releases, there's no tux specific code anymore in the dcache: ftp://ftp.us.kernel.org/pub/linux/kernel/people/andrea/kernels/v2.4/2.4.19pre8aa2/60_tux-vfs-5 there are still a a few lines of tux in the task struct and the socks but it doesn't really matter to the non tux users, and it obviously cannot affect stability in any way. Andrea ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: Tux in main kernel tree? (was khttpd rotten?) 2002-05-07 15:03 ` Andrea Arcangeli 2002-05-07 15:26 ` Alan Cox @ 2002-05-07 16:02 ` Luigi Genoni 1 sibling, 0 replies; 35+ messages in thread From: Luigi Genoni @ 2002-05-07 16:02 UTC (permalink / raw) To: Andrea Arcangeli; +Cc: Alan Cox, Andy Carlson, linux-kernel On Tue, 7 May 2002, Andrea Arcangeli wrote: > > If Marcelo accepts my patches, I will be very glad to replace khttpd > with tux into mainline 2.4. The two products are completly equivalent > and risking to increase the khttpd userbase just because tux isn't in > mainline doesn't make any sense to me, it can only waste resources. > (despite it makes much more sense to use zope, apache, servlets and php > instead of tux for anything real, first of all for security reasons, but > that's another issue, here the issue is khttpd vs tux and this one is a > no brainer) > Yes, functionally khttpd and TuX are more or less equivalent, but khttpd does not depend on any user space command, it is fully configurable via procfs. If I do remember well when you showed me TuX at SNS, it had to be managed trought some command line. If khttpd bugs can be fixed, there is no real reason to replace it with TuX. On the other side to merge TuX together with khttpd could seem a bad replication, unnecessary for cleanness. What could be the really important point is how well khttpd and TuX are maintained. TuX semms to be activelly maintained, while khttpd maintainer was a little absent in recent past, it seems... What was surprising me is that I use khttpd since a lot of time, and while I saw some of the secundary bugs reported here, it was stable for server user on my servers, and they can be very stressed, and khttpd is very usefull with high loads, expecially with sparc linux. Probably that is because I do not change khttpd configuration on the fly (I use from 2 to 8 threads depending on how many CPUs I have). So I tested the patch posted here, and it worked (well the addons to the README are quite important, but I am using even longer sleeps ;), due to experience I had with khttpd, but that is not a real bug ) About the security reasons, you are not complitelly wrong nor complitelly right. khttpd use apache or whatelse web server for everything is not a static page, and for every static page that has not the correct permissions. I tried a lot of time to crash it with high loads, but nope even on a gigabit ethernet, all I could get is a 403 message. Maybe on PCs it behaves differently... ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: Tux in main kernel tree? (was khttpd rotten?) 2002-05-06 14:17 ` Tux in main kernel tree? (was khttpd rotten?) Roy Sigurd Karlsbakk 2002-05-06 16:08 ` Andy Carlson @ 2002-05-06 17:21 ` Dan Kegel 2002-05-06 18:42 ` John Stoffel 2 siblings, 0 replies; 35+ messages in thread From: Dan Kegel @ 2002-05-06 17:21 UTC (permalink / raw) To: Roy Sigurd Karlsbakk; +Cc: David S. Miller, khttpd-users, linux-kernel Roy Sigurd Karlsbakk wrote: > Perhaps it's about time to talk about pulling Tux into the main kernel > tree, as khttpd once again has proved ususable. Hang on a minute -- I posted a patch that makes khttpd usable again, I think... - Dan ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: Tux in main kernel tree? (was khttpd rotten?) 2002-05-06 14:17 ` Tux in main kernel tree? (was khttpd rotten?) Roy Sigurd Karlsbakk 2002-05-06 16:08 ` Andy Carlson 2002-05-06 17:21 ` Dan Kegel @ 2002-05-06 18:42 ` John Stoffel 2002-05-06 19:07 ` Diego Calleja ` (3 more replies) 2 siblings, 4 replies; 35+ messages in thread From: John Stoffel @ 2002-05-06 18:42 UTC (permalink / raw) To: Roy Sigurd Karlsbakk Cc: Dan Kegel, David S. Miller, khttpd-users, linux-kernel Roy> Perhaps it's about time to talk about pulling Tux into the main Roy> kernel tree, as khttpd once again has proved ususable. And why does a Web server belong in the kernel? I've never understood this, and I personally do not think it has any need to be there. <sarcasm> Or maybe we should include kDNS and kftpd as well now? </sarcasm> An httpd server is a *user space* issue, not a kernel issue. John John Stoffel - Senior Unix Systems Administrator - Lucent Technologies stoffel@lucent.com - http://www.lucent.com - 978-399-0479 ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: Tux in main kernel tree? (was khttpd rotten?) 2002-05-06 18:42 ` John Stoffel @ 2002-05-06 19:07 ` Diego Calleja 2002-05-06 19:18 ` Cort Dougan 2002-05-06 20:47 ` Michael Rothwell ` (2 subsequent siblings) 3 siblings, 1 reply; 35+ messages in thread From: Diego Calleja @ 2002-05-06 19:07 UTC (permalink / raw) To: John Stoffel; +Cc: Dan Kegel, David S. Miller, khttpd-users, linux-kernel On Mon, 6 May 2002 14:42:08 -0400 John Stoffel <stoffel@casc.com> escribió: > And why does a Web server belong in the kernel? I've never understood > this, and I personally do not think it has any need to be there. But *f I have a dedicated web server, and I have a lot of traffic, *if* (and only if) I can take some performance advantages from putting a web server into kernel space, I'd like to have those advantages. > > <sarcasm> > > Or maybe we should include kDNS and kftpd as well now? Why not for dedicated servers if this can take some advantages for them? > > </sarcasm> > > An httpd server is a *user space* issue, not a kernel issue. It's true. But I'd be an idiot if I can improve performance and I don't do it. However, if an httpd can be as fast as an kernel space httpd it'd be a bad thing to put it in kernel space. > > John > John Stoffel - Senior Unix Systems Administrator - Lucent Technologies > stoffel@lucent.com - http://www.lucent.com - 978-399-0479 > - > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: Tux in main kernel tree? (was khttpd rotten?) 2002-05-06 19:07 ` Diego Calleja @ 2002-05-06 19:18 ` Cort Dougan 0 siblings, 0 replies; 35+ messages in thread From: Cort Dougan @ 2002-05-06 19:18 UTC (permalink / raw) To: Diego Calleja Cc: John Stoffel, Dan Kegel, David S. Miller, khttpd-users, linux-kernel I put MPI in the kernel and got a huge performance advantage from it. I think that was a valuable idea and the results show that's definitely the case. I don't think the argument could ever be made that it belongs in the main kernel, though. A separate project with a loadable module is definitely the way to go for these things. "Keep that out of my kernel" is an old operating system design adage that isn't paid attention to enough. } > An httpd server is a *user space* issue, not a kernel issue. } } It's true. But I'd be an idiot if I can improve performance and I don't do it. } } However, if an httpd can be as fast as an kernel space httpd it'd be a bad thing to put it } in kernel space. ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: Tux in main kernel tree? (was khttpd rotten?) 2002-05-06 18:42 ` John Stoffel 2002-05-06 19:07 ` Diego Calleja @ 2002-05-06 20:47 ` Michael Rothwell 2002-05-09 11:20 ` Appications in kernelspace (was:Tux in main kernel tree?) Anders Peter Fugmann 2002-05-06 21:52 ` Tux in main kernel tree? (was khttpd rotten?) Paul Jakma 2002-05-07 3:00 ` J Sloan 3 siblings, 1 reply; 35+ messages in thread From: Michael Rothwell @ 2002-05-06 20:47 UTC (permalink / raw) To: khttpd-users, linux-kernel From: "John Stoffel" <stoffel@casc.com> > Or maybe we should include kDNS and kftpd as well now? Or even (laugh), an NFS server... </sarcasm> ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: Appications in kernelspace (was:Tux in main kernel tree?) 2002-05-06 20:47 ` Michael Rothwell @ 2002-05-09 11:20 ` Anders Peter Fugmann 0 siblings, 0 replies; 35+ messages in thread From: Anders Peter Fugmann @ 2002-05-09 11:20 UTC (permalink / raw) To: Michael Rothwell; +Cc: khttpd-users, linux-kernel Michael Rothwell wrote: > From: "John Stoffel" <stoffel@casc.com> > >>Or maybe we should include kDNS and kftpd as well now? > > Or even (laugh), an NFS server... > Before I begin, I would like to say that I have never tried khttpd or TUX, and I do not tknow how they are implemented. It has been postulated (and I beleive that) that tux and khttpd in kernel space outperforms the userspace equivelent. In my oppinion, application level protocols should not exist in the kernel-space. Whenever a functionality is implementented in the kernel, people tends to optimizing generic tings in the kernel for this functionality (at the cost of genericness). If we take this thought to the extreme, I can see lots of different kernels in the future with names like: 3.8.23-http, 3.8.22-nfsd, 3.8.56-IE7 etc, and changlogs like: - backport VM-IE7 changes from 3.8.56-IE7 to 3.8.23-http. What we end up with is unmaintainable kernel-code, since focus is removed from the generic kernel to specific kernels. Alternative: Since TUX and khttpd does gain extra performance by running in kernel space, I think that the problem is clear. Userspace programs have no change of performing near the harware/theoretic optimum. Lets fix that. The kernel should not be optimized for a single program, but allow any program to take advantage of some interface. NFSd might belong to userspace (I dont know - really), but if its significantly faster in kernel then we need some changes in the kernel API, to allow same speed in userspace if nfsd belongs there. Conclusion: Khttpd et. al. does not belong to the kernel. Adding applications to the kernel moves focus from generic correct implementations to specific optimizations. Effort should be made to find out why httpd et. al. is faster, and what can be done _genericly_ to allow near same performance in userspace. Hope that this starts some thoughts. Anders Fugmann ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: Tux in main kernel tree? (was khttpd rotten?) 2002-05-06 18:42 ` John Stoffel 2002-05-06 19:07 ` Diego Calleja 2002-05-06 20:47 ` Michael Rothwell @ 2002-05-06 21:52 ` Paul Jakma 2002-05-09 11:28 ` john slee 2002-05-07 3:00 ` J Sloan 3 siblings, 1 reply; 35+ messages in thread From: Paul Jakma @ 2002-05-06 21:52 UTC (permalink / raw) To: John Stoffel Cc: Roy Sigurd Karlsbakk, Dan Kegel, David S. Miller, khttpd-users, Linux Kernel On Mon, 6 May 2002, John Stoffel wrote: > And why does a Web server belong in the kernel? I've never understood > this, and I personally do not think it has any need to be there. <humour> it's all part of a fiendish plot, principal conspirator in which is Jeff Merkey, to turn linux into the new Netware... </humour> regards, -- Paul Jakma paul@clubi.ie paul@jakma.org Key ID: 64A2FF6A Fortune: Ma Bell is a mean mother! ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: Tux in main kernel tree? (was khttpd rotten?) 2002-05-06 21:52 ` Tux in main kernel tree? (was khttpd rotten?) Paul Jakma @ 2002-05-09 11:28 ` john slee 0 siblings, 0 replies; 35+ messages in thread From: john slee @ 2002-05-09 11:28 UTC (permalink / raw) To: Paul Jakma Cc: John Stoffel, Roy Sigurd Karlsbakk, Dan Kegel, David S. Miller, khttpd-users, Linux Kernel On Mon, May 06, 2002 at 10:52:48PM +0100, Paul Jakma wrote: > On Mon, 6 May 2002, John Stoffel wrote: > > > And why does a Web server belong in the kernel? I've never understood > > this, and I personally do not think it has any need to be there. > > <humour> > > it's all part of a fiendish plot, principal conspirator in which is > Jeff Merkey, to turn linux into the new Netware... this i find genuinely amusing. jeff would probably disagree though as he's apparently been doing anything but netware stuff lately. in fact ive hardly seen him mention the N-word at all in the past few months on this list j. -- R N G G "Well, there it goes again... And we just sit I G G G here without opposable thumbs." -- gary larson ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: Tux in main kernel tree? (was khttpd rotten?) 2002-05-06 18:42 ` John Stoffel ` (2 preceding siblings ...) 2002-05-06 21:52 ` Tux in main kernel tree? (was khttpd rotten?) Paul Jakma @ 2002-05-07 3:00 ` J Sloan 3 siblings, 0 replies; 35+ messages in thread From: J Sloan @ 2002-05-07 3:00 UTC (permalink / raw) To: John Stoffel; +Cc: linux kernel John Stoffel wrote: >Or maybe we should include kDNS and kftpd as well now? > We do have knfsd - and FWIW, tux does ftp as well as http - ></sarcasm> > >An httpd server is a *user space* issue, not a kernel issue. > What about nfs? also a user space issue? If a userspace httpd could come anywhere near the performance of tux, your protest might be just a little more beleivable. google "specweb champ" for a gentle heads-up on the subject. Joe ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: khttpd rotten? 2002-05-06 2:14 ` David S. Miller 2002-05-06 2:39 ` Dan Kegel @ 2002-05-09 11:40 ` john slee 2002-05-09 11:29 ` David S. Miller 2002-05-09 20:12 ` Ian Molton 1 sibling, 2 replies; 35+ messages in thread From: john slee @ 2002-05-09 11:40 UTC (permalink / raw) To: David S. Miller; +Cc: dank, khttpd-users, linux-kernel On Sun, May 05, 2002 at 07:14:22PM -0700, David S. Miller wrote: > From: Dan Kegel <dank@kegel.com> > Date: Sun, 05 May 2002 17:28:37 -0700 > > If I didn't need it for a demo this week (don't ask), I > wouldn't be messing with khttpd; I'd be switching to Tux. > > Seems like it's time to either fix khttpd or pull it from the kernel. > > We are going to pull it from the kernel. > > The only argument is whether to replace it with TUX or not. > There is a lot of compelling evidence that suggests that > reasonably close performance can be obtained in userspace. > > I guess the decision on TUX is not a prerequisite for pulling > khttpd though. people who want tux are probably going to want some other related bits and pieces. this is a distribution issue. remove khttpd (even if it is suddenly maintained again) and let it and tux both be external entities. tux is more an application than an interface or mechanism. applications historically haven't been distributed as part of the main kernel tree. j. -- R N G G "Well, there it goes again... And we just sit I G G G here without opposable thumbs." -- gary larson ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: khttpd rotten? 2002-05-09 11:40 ` khttpd rotten? john slee @ 2002-05-09 11:29 ` David S. Miller 2002-05-09 19:30 ` Andrew Morton 2002-05-09 20:12 ` Ian Molton 1 sibling, 1 reply; 35+ messages in thread From: David S. Miller @ 2002-05-09 11:29 UTC (permalink / raw) To: indigoid; +Cc: dank, khttpd-users, linux-kernel From: john slee <indigoid@higherplane.net> Date: Thu, 9 May 2002 21:40:09 +1000 tux is more an application than an interface or mechanism. applications historically haven't been distributed as part of the main kernel tree. Arguable nfsd is an application. Providing a direct in-kernel link between the page cache and providing content (be it HTTP, FTP, NFS files, whatever) over sockets is a very powerful concept. ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: khttpd rotten? 2002-05-09 11:29 ` David S. Miller @ 2002-05-09 19:30 ` Andrew Morton 2002-05-09 19:35 ` David S. Miller 2002-05-10 10:20 ` Andi Kleen 0 siblings, 2 replies; 35+ messages in thread From: Andrew Morton @ 2002-05-09 19:30 UTC (permalink / raw) To: David S. Miller; +Cc: indigoid, dank, khttpd-users, linux-kernel "David S. Miller" wrote: > > From: john slee <indigoid@higherplane.net> > Date: Thu, 9 May 2002 21:40:09 +1000 > > tux is more an application than an interface or mechanism. applications > historically haven't been distributed as part of the main kernel tree. > > Arguable nfsd is an application. > > Providing a direct in-kernel link between the page cache and providing > content (be it HTTP, FTP, NFS files, whatever) over sockets is a very > powerful concept. We want to expose all the zerocopy infrastructure to userspace so all relevant applications can benefit. The concern with moving one (major) application into the kernel is that this will weaken the testing/motivation to get zerocopy, aio and sophisticated notifications working well for userspace. Everyone who cares will end up implementing things as TUX modules. - ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: khttpd rotten? 2002-05-09 19:30 ` Andrew Morton @ 2002-05-09 19:35 ` David S. Miller 2002-05-09 19:39 ` Martin Dalecki 2002-05-10 10:20 ` Andi Kleen 1 sibling, 1 reply; 35+ messages in thread From: David S. Miller @ 2002-05-09 19:35 UTC (permalink / raw) To: akpm; +Cc: indigoid, dank, khttpd-users, linux-kernel From: Andrew Morton <akpm@zip.com.au> Date: Thu, 09 May 2002 12:30:59 -0700 The concern with moving one (major) application into the kernel is that this will weaken the testing/motivation to get zerocopy, aio and sophisticated notifications working well for userspace. Actually, to the contrary, TUX was in fact an impetus for the userlevel zerocopy and AIO bits :-) I personally don't see anything wrong with something like the TUX engine being in there. At the same time I want to reiterate what Ingo said which is what we can do in userspace catches up to what TUX can do then we pull it out and move on to the next thing :-) ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: khttpd rotten? 2002-05-09 19:35 ` David S. Miller @ 2002-05-09 19:39 ` Martin Dalecki 0 siblings, 0 replies; 35+ messages in thread From: Martin Dalecki @ 2002-05-09 19:39 UTC (permalink / raw) To: David S. Miller; +Cc: akpm, indigoid, dank, khttpd-users, linux-kernel Uz.ytkownik David S. Miller napisa?: > From: Andrew Morton <akpm@zip.com.au> > Date: Thu, 09 May 2002 12:30:59 -0700 > > The concern with moving one (major) application into the > kernel is that this will weaken the testing/motivation to get > zerocopy, aio and sophisticated notifications working well > for userspace. > > Actually, to the contrary, TUX was in fact an impetus for the > userlevel zerocopy and AIO bits :-) > > I personally don't see anything wrong with something like the > TUX engine being in there. At the same time I want to reiterate what > Ingo said which is what we can do in userspace catches up to what > TUX can do then we pull it out and move on to the next thing :-) It's far easiet to add then to remove. Trust me ;-). I vote against both of them: tux and khttpd are should have no place in the kernel of a General Pupose OS kernel. ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: khttpd rotten? 2002-05-09 19:30 ` Andrew Morton 2002-05-09 19:35 ` David S. Miller @ 2002-05-10 10:20 ` Andi Kleen 2002-05-10 10:49 ` David S. Miller 1 sibling, 1 reply; 35+ messages in thread From: Andi Kleen @ 2002-05-10 10:20 UTC (permalink / raw) To: Andrew Morton; +Cc: linux-kernel Andrew Morton <akpm@zip.com.au> writes: > "David S. Miller" wrote: > > > > From: john slee <indigoid@higherplane.net> > > Date: Thu, 9 May 2002 21:40:09 +1000 > > > > tux is more an application than an interface or mechanism. applications > > historically haven't been distributed as part of the main kernel tree. > > > > Arguable nfsd is an application. > > > > Providing a direct in-kernel link between the page cache and providing > > content (be it HTTP, FTP, NFS files, whatever) over sockets is a very > > powerful concept. > > We want to expose all the zerocopy infrastructure to > userspace so all relevant applications can benefit. It is basically impossible without hardware support/major stack changes to do it securely for networking RX. The problem is that to put data directly from the NIC into an user space address range the NIC already needs to demultiplex the sockets before it starts to DMA. With kernel space applications you can just DMA into a shared buffer like it is currently done and give whoever ends up to be the socket owner that shared buffer. For userspace you would need to put it into an page aligned buffer and change the page tables of the user space process, but especially on SMP that is usually slower than just copying. Managing the stuff in a shared memory segment is also likely not secure [There is a special hack in the stack to do it for network sniffing, but it is not general purpose enough for real protocols] Zerocopy TX is different of course and easier and can be exposed to user space. The natural interface for that is POSIX aio; I believe one of the kernel aio patchkits floating around already does it. -Andi ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: khttpd rotten? 2002-05-10 10:20 ` Andi Kleen @ 2002-05-10 10:49 ` David S. Miller 0 siblings, 0 replies; 35+ messages in thread From: David S. Miller @ 2002-05-10 10:49 UTC (permalink / raw) To: ak; +Cc: akpm, linux-kernel From: Andi Kleen <ak@muc.de> Date: 10 May 2002 12:20:17 +0200 It is basically impossible without hardware support/major stack changes to do it securely for networking RX. The problem is that to put data directly from the NIC into an user space address range the NIC already needs to demultiplex the sockets before it starts to DMA. Sun's Cassini gigabit chips have the infrastructure. It's a very simple onboard header parser (it's not a real CPU, just some thick ASIC logic). You write small header parsing scripts plus provide it with a socket cache table, it accumulates data into pages from the streams for you. Of course all of this is moot until we can actually write a driver for one of these cards with such features (I'm working on it for Cassini and things look good right now). For userspace you would need to put it into an page aligned buffer and change the page tables of the user space process, but especially on SMP that is usually slower than just copying. Managing the stuff in a shared memory segment is also likely not secure Alexey already did hacks to make this work on xmit, we have all of the infrastructure really due to the direct I/O bits. [There is a special hack in the stack to do it for network sniffing, but it is not general purpose enough for real protocols] RX TCP is very doable with the correct hardware. I already have the implementation in my head given something like Cassini HW. ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: khttpd rotten? 2002-05-09 11:40 ` khttpd rotten? john slee 2002-05-09 11:29 ` David S. Miller @ 2002-05-09 20:12 ` Ian Molton 1 sibling, 0 replies; 35+ messages in thread From: Ian Molton @ 2002-05-09 20:12 UTC (permalink / raw) To: john slee; +Cc: davem, dank, khttpd-users, linux-kernel On Thu, 9 May 2002 21:40:09 +1000 john slee <indigoid@higherplane.net> wrote: > > people who want tux are probably going to want some other related bits > and pieces. this is a distribution issue. remove khttpd (even if it > is suddenly maintained again) and let it and tux both be external > entities. seconded. ^ permalink raw reply [flat|nested] 35+ messages in thread
end of thread, other threads:[~2002-05-11 0:13 UTC | newest] Thread overview: 35+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2002-05-06 0:28 khttpd rotten? Dan Kegel 2002-05-06 2:14 ` David S. Miller 2002-05-06 2:39 ` Dan Kegel 2002-05-06 10:23 ` Christoph Hellwig 2002-05-06 11:28 ` [PATCH] " Dan Kegel 2002-05-06 17:23 ` Luigi Genoni 2002-05-09 9:49 ` David S. Miller 2002-05-09 10:09 ` Christoph Hellwig 2002-05-09 13:04 ` Luigi Genoni 2002-05-11 0:13 ` Ken Brownfield 2002-05-06 14:17 ` Tux in main kernel tree? (was khttpd rotten?) Roy Sigurd Karlsbakk 2002-05-06 16:08 ` Andy Carlson 2002-05-06 23:35 ` Anton Blanchard 2002-05-07 14:42 ` Alan Cox 2002-05-07 15:03 ` Andrea Arcangeli 2002-05-07 15:26 ` Alan Cox 2002-05-07 15:38 ` Andrea Arcangeli 2002-05-07 16:02 ` Luigi Genoni 2002-05-06 17:21 ` Dan Kegel 2002-05-06 18:42 ` John Stoffel 2002-05-06 19:07 ` Diego Calleja 2002-05-06 19:18 ` Cort Dougan 2002-05-06 20:47 ` Michael Rothwell 2002-05-09 11:20 ` Appications in kernelspace (was:Tux in main kernel tree?) Anders Peter Fugmann 2002-05-06 21:52 ` Tux in main kernel tree? (was khttpd rotten?) Paul Jakma 2002-05-09 11:28 ` john slee 2002-05-07 3:00 ` J Sloan 2002-05-09 11:40 ` khttpd rotten? john slee 2002-05-09 11:29 ` David S. Miller 2002-05-09 19:30 ` Andrew Morton 2002-05-09 19:35 ` David S. Miller 2002-05-09 19:39 ` Martin Dalecki 2002-05-10 10:20 ` Andi Kleen 2002-05-10 10:49 ` David S. Miller 2002-05-09 20:12 ` Ian Molton
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox