userspace.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:5k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2. kHTTPd -- the next generation
  3. Pass connections to userspace-daemons
  4. */
  5. /****************************************************************
  6.  * This program is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation; either version 2, or (at your option)
  9.  * any later version.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program; if not, write to the Free Software
  18.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  *
  20.  ****************************************************************/
  21. /*
  22. Purpose:
  23. Userspace() hands all requests in the queue to the userspace-daemon, if
  24. such beast exists.
  25. Return value:
  26. The number of requests that changed status
  27. */
  28. #include <linux/kernel.h>
  29. #include <linux/errno.h>
  30. #include <linux/slab.h>
  31. #include <linux/net.h>
  32. #include <linux/sched.h>
  33. #include <linux/skbuff.h>
  34. #include <linux/smp_lock.h>
  35. #include <linux/un.h>
  36. #include <linux/unistd.h>
  37. #include <linux/wait.h>
  38. #include <net/ip.h>
  39. #include <net/sock.h>
  40. #include <net/tcp.h>
  41. #include <asm/atomic.h>
  42. #include <asm/semaphore.h>
  43. #include <asm/processor.h>
  44. #include <asm/uaccess.h>
  45. #include <linux/file.h>
  46. #include "structure.h"
  47. #include "prototypes.h"
  48. #include "sysctl.h"
  49. /* prototypes of local, static functions */
  50. static int AddSocketToAcceptQueue(struct socket *sock,const int Port);
  51. int Userspace(const int CPUNR)
  52. {
  53. struct http_request *CurrentRequest,**Prev,*Next;
  54. EnterFunction("Userspace");
  55. CurrentRequest = threadinfo[CPUNR].UserspaceQueue;
  56. Prev = &(threadinfo[CPUNR].UserspaceQueue);
  57. while (CurrentRequest!=NULL)
  58. {
  59. /* Clean-up the waitqueue of the socket.. Bad things happen if
  60.    this is forgotten. */
  61. if (CurrentRequest->sock!=NULL)
  62. {
  63. if ((CurrentRequest->sock!=NULL)&&(CurrentRequest->sock->sk!=NULL))
  64. {
  65. remove_wait_queue(CurrentRequest->sock->sk->sleep,&(CurrentRequest->sleep));
  66. }
  67. if  (AddSocketToAcceptQueue(CurrentRequest->sock,sysctl_khttpd_clientport)>=0)
  68. {
  69. (*Prev) = CurrentRequest->Next;
  70. Next = CurrentRequest->Next;
  71. sock_release(CurrentRequest->sock);
  72. CurrentRequest->sock = NULL;  /* We no longer own it */
  73. CleanUpRequest(CurrentRequest); 
  74. CurrentRequest = Next;
  75. continue;
  76. }
  77. else /* No userspace-daemon present, or other problems with it */
  78. {
  79. (*Prev) = CurrentRequest->Next;
  80. Next = CurrentRequest->Next;
  81. Send403(CurrentRequest->sock); /* Sorry, no go... */
  82. CleanUpRequest(CurrentRequest); 
  83. CurrentRequest = Next;
  84. continue;
  85. }
  86. Prev = &(CurrentRequest->Next);
  87. CurrentRequest = CurrentRequest->Next;
  88. }
  89. LeaveFunction("Userspace");
  90. return 0;
  91. }
  92. void StopUserspace(const int CPUNR)
  93. {
  94. struct http_request *CurrentRequest,*Next;
  95. EnterFunction("StopUserspace");
  96. CurrentRequest = threadinfo[CPUNR].UserspaceQueue;
  97. while (CurrentRequest!=NULL)
  98. {
  99. Next= CurrentRequest->Next;
  100. CleanUpRequest(CurrentRequest);
  101. CurrentRequest=Next;
  102. }
  103. threadinfo[CPUNR].UserspaceQueue = NULL;
  104. LeaveFunction("StopUserspace");
  105. }
  106. /* 
  107.    "FindUserspace" returns the struct sock of the userspace-daemon, so that we can
  108.    "drop" our request in the accept-queue 
  109. */
  110. static struct sock *FindUserspace(const unsigned short Port)
  111. {
  112. struct sock *sk;
  113. EnterFunction("FindUserspace");
  114. local_bh_disable();
  115. sk = tcp_v4_lookup_listener(INADDR_ANY,Port,0);
  116. local_bh_enable();
  117. return sk;
  118. }
  119. static void dummy_destructor(struct open_request *req)
  120. {
  121. }
  122. static struct or_calltable Dummy = 
  123. {
  124. 0,
  125.   NULL,
  126.   NULL,
  127.   &dummy_destructor,
  128.   NULL
  129. };
  130. static int AddSocketToAcceptQueue(struct socket *sock,const int Port)
  131. {
  132. struct open_request *req;
  133. struct sock *sk, *nsk;
  134. EnterFunction("AddSocketToAcceptQueue");
  135. sk = FindUserspace((unsigned short)Port);
  136. if (sk==NULL)   /* No userspace-daemon found */
  137. {
  138. return -1;
  139. }
  140. lock_sock(sk);
  141. if (sk->state != TCP_LISTEN || tcp_acceptq_is_full(sk))
  142. {
  143. release_sock(sk);
  144. sock_put(sk);
  145. return -1;
  146. }
  147. req = tcp_openreq_alloc();
  148. if (req==NULL)
  149. {
  150. release_sock(sk);
  151. sock_put(sk);
  152. return -1;
  153. }
  154. nsk = sock->sk;
  155. sock->sk = NULL;
  156. sock->state = SS_UNCONNECTED;
  157. req->class = &Dummy;
  158. write_lock_bh(&nsk->callback_lock);
  159. nsk->socket = NULL;
  160.         nsk->sleep  = NULL;
  161. write_unlock_bh(&nsk->callback_lock);
  162. tcp_acceptq_queue(sk, req, nsk);
  163. sk->data_ready(sk, 0);
  164. release_sock(sk);
  165. sock_put(sk);
  166. LeaveFunction("AddSocketToAcceptQueue");
  167. return +1;
  168. }
  169. void InitUserspace(const int CPUNR)
  170. {
  171. }