3 kHTTPd -- the next generation
5 Pass connections to userspace-daemons
8 /****************************************************************
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2, or (at your option)
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 ****************************************************************/
29 Userspace() hands all requests in the queue to the userspace-daemon, if
33 The number of requests that changed status
35 #include <linux/kernel.h>
37 #include <linux/errno.h>
38 #include <linux/slab.h>
39 #include <linux/net.h>
40 #include <linux/sched.h>
41 #include <linux/skbuff.h>
42 #include <linux/smp_lock.h>
44 #include <linux/unistd.h>
45 #include <linux/wait.h>
51 #include <asm/atomic.h>
52 #include <asm/semaphore.h>
53 #include <asm/processor.h>
54 #include <asm/uaccess.h>
56 #include <linux/file.h>
59 #include "structure.h"
60 #include "prototypes.h"
63 /* prototypes of local, static functions */
64 static int AddSocketToAcceptQueue(struct socket *sock,const int Port);
67 int Userspace(const int CPUNR)
69 struct http_request *CurrentRequest,**Prev,*Next;
71 EnterFunction("Userspace");
76 CurrentRequest = threadinfo[CPUNR].UserspaceQueue;
77 Prev = &(threadinfo[CPUNR].UserspaceQueue);
79 while (CurrentRequest!=NULL)
82 /* Clean-up the waitqueue of the socket.. Bad things happen if
84 if (CurrentRequest->sock!=NULL)
86 if ((CurrentRequest->sock!=NULL)&&(CurrentRequest->sock->sk!=NULL))
88 remove_wait_queue(CurrentRequest->sock->sk->sleep,&(CurrentRequest->sleep));
93 if (AddSocketToAcceptQueue(CurrentRequest->sock,sysctl_khttpd_clientport)>=0)
96 (*Prev) = CurrentRequest->Next;
97 Next = CurrentRequest->Next;
100 sock_release(CurrentRequest->sock);
101 CurrentRequest->sock = NULL; /* We no longer own it */
103 CleanUpRequest(CurrentRequest);
105 CurrentRequest = Next;
109 else /* No userspace-daemon present, or other problems with it */
111 (*Prev) = CurrentRequest->Next;
112 Next = CurrentRequest->Next;
114 Send403(CurrentRequest->sock); /* Sorry, no go... */
116 CleanUpRequest(CurrentRequest);
118 CurrentRequest = Next;
124 Prev = &(CurrentRequest->Next);
125 CurrentRequest = CurrentRequest->Next;
128 LeaveFunction("Userspace");
132 void StopUserspace(const int CPUNR)
134 struct http_request *CurrentRequest,*Next;
136 EnterFunction("StopUserspace");
137 CurrentRequest = threadinfo[CPUNR].UserspaceQueue;
139 while (CurrentRequest!=NULL)
141 Next= CurrentRequest->Next;
142 CleanUpRequest(CurrentRequest);
145 threadinfo[CPUNR].UserspaceQueue = NULL;
147 LeaveFunction("StopUserspace");
152 "FindUserspace" returns the struct sock of the userspace-daemon, so that we can
153 "drop" our request in the accept-queue
156 static struct sock *FindUserspace(const unsigned short Port)
160 EnterFunction("FindUserspace");
163 sk = tcp_v4_lookup_listener(INADDR_ANY,Port,0);
168 static void dummy_destructor(struct open_request *req)
172 static struct or_calltable Dummy =
181 static int AddSocketToAcceptQueue(struct socket *sock,const int Port)
183 struct open_request *req;
184 struct sock *sk, *nsk;
186 EnterFunction("AddSocketToAcceptQueue");
189 sk = FindUserspace((unsigned short)Port);
191 if (sk==NULL) /* No userspace-daemon found */
198 if (sk->state != TCP_LISTEN || tcp_acceptq_is_full(sk))
205 req = tcp_openreq_alloc();
216 sock->state = SS_UNCONNECTED;
219 write_lock_bh(&nsk->callback_lock);
222 write_unlock_bh(&nsk->callback_lock);
224 tcp_acceptq_queue(sk, req, nsk);
226 sk->data_ready(sk, 0);
231 LeaveFunction("AddSocketToAcceptQueue");
239 void InitUserspace(const int CPUNR)