~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/net/khttpd/userspace.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2 
  3 kHTTPd -- the next generation
  4 
  5 Pass connections to userspace-daemons
  6 
  7 */
  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)
 12  *      any later version.
 13  *
 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.
 18  *
 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.
 22  *
 23  ****************************************************************/
 24 
 25 /*
 26 
 27 Purpose:
 28 
 29 Userspace() hands all requests in the queue to the userspace-daemon, if
 30 such beast exists.
 31 
 32 Return value:
 33         The number of requests that changed status
 34 */
 35 #include <linux/kernel.h>
 36 
 37 #include <linux/errno.h>
 38 #include <linux/malloc.h>
 39 #include <linux/net.h>
 40 #include <linux/sched.h>
 41 #include <linux/skbuff.h>
 42 #include <linux/smp_lock.h>
 43 #include <linux/un.h>
 44 #include <linux/unistd.h>
 45 #include <linux/wait.h>
 46 
 47 #include <net/ip.h>
 48 #include <net/sock.h>
 49 #include <net/tcp.h>
 50 
 51 #include <asm/atomic.h>
 52 #include <asm/semaphore.h>
 53 #include <asm/processor.h>
 54 #include <asm/uaccess.h>
 55 
 56 #include <linux/file.h>
 57 
 58 
 59 #include "structure.h"
 60 #include "prototypes.h"
 61 #include "sysctl.h"
 62 
 63 /* prototypes of local, static functions */
 64 static int AddSocketToAcceptQueue(struct socket *sock,const int Port);
 65 
 66 
 67 int Userspace(const int CPUNR)
 68 {
 69         struct http_request *CurrentRequest,**Prev,*Next;
 70         
 71         EnterFunction("Userspace");
 72 
 73         
 74 
 75         
 76         CurrentRequest = threadinfo[CPUNR].UserspaceQueue;
 77         Prev = &(threadinfo[CPUNR].UserspaceQueue);
 78         
 79         while (CurrentRequest!=NULL)
 80         {
 81 
 82                 /* Clean-up the waitqueue of the socket.. Bad things happen if
 83                    this is forgotten. */
 84                 if (CurrentRequest->sock!=NULL)
 85                 {
 86                         if ((CurrentRequest->sock!=NULL)&&(CurrentRequest->sock->sk!=NULL))
 87                         {
 88                                 remove_wait_queue(CurrentRequest->sock->sk->sleep,&(CurrentRequest->sleep));
 89                         }
 90                 } 
 91                 
 92 
 93                 if  (AddSocketToAcceptQueue(CurrentRequest->sock,sysctl_khttpd_clientport)>=0)
 94                 {
 95                         
 96                         (*Prev) = CurrentRequest->Next;
 97                         Next = CurrentRequest->Next;
 98                         
 99                         
100                         sock_release(CurrentRequest->sock);
101                         CurrentRequest->sock = NULL;     /* We no longer own it */
102                         
103                         CleanUpRequest(CurrentRequest); 
104                                 
105                         CurrentRequest = Next;
106                         continue;
107                 
108                 }
109                 else /* No userspace-daemon present, or other problems with it */
110                 {
111                         (*Prev) = CurrentRequest->Next;
112                         Next = CurrentRequest->Next;
113                         
114                         Send403(CurrentRequest->sock); /* Sorry, no go... */
115                         
116                         CleanUpRequest(CurrentRequest); 
117                                 
118                         CurrentRequest = Next;
119                         continue;
120                 
121                 }
122 
123                 
124                 Prev = &(CurrentRequest->Next); 
125                 CurrentRequest = CurrentRequest->Next;
126         }
127         
128         LeaveFunction("Userspace");
129         return 0;
130 }
131 
132 void StopUserspace(const int CPUNR)
133 {
134         struct http_request *CurrentRequest,*Next;
135         
136         EnterFunction("StopUserspace");
137         CurrentRequest = threadinfo[CPUNR].UserspaceQueue;
138 
139         while (CurrentRequest!=NULL)
140         {
141                 Next= CurrentRequest->Next;
142                 CleanUpRequest(CurrentRequest);
143                 CurrentRequest=Next;            
144         }
145         threadinfo[CPUNR].UserspaceQueue = NULL;
146         
147         LeaveFunction("StopUserspace");
148 }
149 
150 
151 /* 
152    "FindUserspace" returns the struct sock of the userspace-daemon, so that we can
153    "drop" our request in the accept-queue 
154 */
155 
156 static struct sock *FindUserspace(const unsigned short Port)
157 {
158         struct sock *sk;
159 
160         EnterFunction("FindUserspace");
161 
162         local_bh_disable();
163         sk = tcp_v4_lookup_listener(INADDR_ANY,Port,0);
164         local_bh_enable();
165         return sk;
166 }
167 
168 static void dummy_destructor(struct open_request *req)
169 {
170 }
171 
172 static struct or_calltable Dummy = 
173 {
174         0,
175         NULL,
176         NULL,
177         &dummy_destructor,
178         NULL
179 };
180 
181 static int AddSocketToAcceptQueue(struct socket *sock,const int Port)
182 {
183         struct open_request *req;
184         struct sock *sk, *nsk;
185         
186         EnterFunction("AddSocketToAcceptQueue");
187 
188         
189         sk = FindUserspace((unsigned short)Port);       
190         
191         if (sk==NULL)   /* No userspace-daemon found */
192         {
193                 return -1;
194         }
195         
196         lock_sock(sk);
197 
198         if (sk->state != TCP_LISTEN || tcp_acceptq_is_full(sk))
199         {
200                 release_sock(sk);
201                 sock_put(sk);
202                 return -1;
203         }
204 
205         req = tcp_openreq_alloc();
206         
207         if (req==NULL)
208         {       
209                 release_sock(sk);
210                 sock_put(sk);
211                 return -1;
212         }
213         
214         nsk = sock->sk;
215         sock->sk = NULL;
216         sock->state = SS_UNCONNECTED;
217 
218         req->class      = &Dummy;
219         write_lock_bh(&nsk->callback_lock);
220         nsk->socket = NULL;
221         nsk->sleep  = NULL;
222         write_unlock_bh(&nsk->callback_lock);
223 
224         tcp_acceptq_queue(sk, req, nsk);        
225 
226         sk->data_ready(sk, 0);
227 
228         release_sock(sk);
229         sock_put(sk);
230 
231         LeaveFunction("AddSocketToAcceptQueue");
232                 
233         return +1;      
234         
235         
236         
237 }
238 
239 void InitUserspace(const int CPUNR)
240 {
241 }
242 
243 
244 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.