diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1999-10-09 00:00:47 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1999-10-09 00:00:47 +0000 |
commit | d6434e1042f3b0a6dfe1b1f615af369486f9b1fa (patch) | |
tree | e2be02f33984c48ec019c654051d27964e42c441 /net/khttpd/userspace.c | |
parent | 609d1e803baf519487233b765eb487f9ec227a18 (diff) |
Merge with 2.3.19.
Diffstat (limited to 'net/khttpd/userspace.c')
-rw-r--r-- | net/khttpd/userspace.c | 248 |
1 files changed, 248 insertions, 0 deletions
diff --git a/net/khttpd/userspace.c b/net/khttpd/userspace.c new file mode 100644 index 000000000..2acb27ff1 --- /dev/null +++ b/net/khttpd/userspace.c @@ -0,0 +1,248 @@ +/* + +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/malloc.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; + struct tcp_opt *tp; + + EnterFunction("AddSocketToAcceptQueue"); + + + sk = FindUserspace((unsigned short)Port); + + if (sk==NULL) /* No userspace-daemon found */ + { + return -1; + } + + lock_sock(sk); + + if (sk->state != TCP_LISTEN || + sk->ack_backlog > sk->max_ack_backlog) /* To many pending requests */ + { + release_sock(sk); + sock_put(sk); + return -1; + } + + req = tcp_openreq_alloc(); + + if (req==NULL) + { + release_sock(sk); + sock_put(sk); + return -1; + } + + req->sk = sock->sk; + sock->sk = NULL; + sock->state = SS_UNCONNECTED; + + req->class = &Dummy; + write_lock_irq(&req->sk->callback_lock); + req->sk->socket = NULL; + req->sk->sleep = NULL; + write_unlock_irq(&req->sk->callback_lock); + + tp =&(sk->tp_pinfo.af_tcp); + sk->ack_backlog++; + + tcp_synq_queue(tp,req); + + sk->data_ready(sk, 0); + + release_sock(sk); + sock_put(sk); + + LeaveFunction("AddSocketToAcceptQueue"); + + return +1; + + + +} + +void InitUserspace(const int CPUNR) +{ +} + + |