Messages in this thread Patch in this message |  | | Date | Mon, 6 May 2002 11:23:00 +0100 | From | Christoph Hellwig <> | Subject | Re: khttpd rotten? |
| |
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/
|  |