address.c
上传用户:zm130024
上传日期:2007-01-04
资源大小:432k
文件大小:11k
源码类别:

代理服务器

开发平台:

Unix_Linux

  1. /*
  2.  * Copyright (c) 1997, 1998, 1999
  3.  *      Inferno Nettverk A/S, Norway.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. The above copyright notice, this list of conditions and the following
  9.  *    disclaimer must appear in all copies of the software, derivative works
  10.  *    or modified versions, and any portions thereof, aswell as in all
  11.  *    supporting documentation.
  12.  * 2. All advertising materials mentioning features or use of this software
  13.  *    must display the following acknowledgement:
  14.  *      This product includes software developed by
  15.  *      Inferno Nettverk A/S, Norway.
  16.  * 3. The name of the author may not be used to endorse or promote products
  17.  *    derived from this software without specific prior written permission.
  18.  *
  19.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  20.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  21.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  22.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  23.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  24.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  28.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29.  *
  30.  * Inferno Nettverk A/S requests users of this software to return to
  31.  *
  32.  *  Software Distribution Coordinator  or  sdc@inet.no
  33.  *  Inferno Nettverk A/S
  34.  *  Oslo Research Park
  35.  *  Gaustadal閑n 21
  36.  *  N-0349 Oslo
  37.  *  Norway
  38.  *
  39.  * any improvements or extensions that they make and grant Inferno Nettverk A/S
  40.  * the rights to redistribute these changes.
  41.  *
  42.  */
  43. #include "common.h"
  44. static const char rcsid[] =
  45. "$Id: address.c,v 1.75 1999/12/22 09:29:22 karls Exp $";
  46. __BEGIN_DECLS
  47. static struct socksfd_t socksfdinit;
  48. static int *dv;
  49. static unsigned int dc;
  50. static struct socksfd_t *socksfdv;
  51. static unsigned int socksfdc;
  52. static int
  53. socks_sigblock __P((sigset_t *oldmask));
  54. /*
  55.  * Blocks signals that can change socksfdv, writing the old
  56.  * signalmask to "oldmask".
  57.  * Returns:
  58.  * On success: 0
  59.  * On failure: -1
  60.  */
  61. __END_DECLS
  62. struct socksfd_t *
  63. socks_addaddr(clientfd, socksfd)
  64. unsigned int clientfd;
  65. struct socksfd_t *socksfd;
  66. {
  67. const char *function = "socks_addaddr()";
  68. #if 0 /* DEBUG */
  69. if (socksfd->state.command != -1 && !socksfd->state.system)
  70. slog(LOG_DEBUG, "%s: %d", function, clientfd);
  71. #endif
  72. SASSERTX(socksfd->state.command == -1
  73. ||  socksfd->state.command == SOCKS_BIND
  74. ||  socksfd->state.command == SOCKS_CONNECT
  75. ||  socksfd->state.command == SOCKS_UDPASSOCIATE);
  76. if (socks_addfd(clientfd) != 0)
  77. serrx(EXIT_FAILURE, "%s: %s", function, NOMEM);
  78. if (socksfdc < dc) { /* init/reallocate */
  79. sigset_t oldmask;
  80. if (socksfdinit.control == 0) { /* not initialized */
  81. socksfdinit.control = -1;
  82. /* other members have ok default value. */
  83. }
  84. if (socks_sigblock(&oldmask) != 0)
  85. return NULL;
  86. if ((socksfdv = (struct socksfd_t *)realloc(socksfdv,
  87. sizeof(*socksfdv) * dc)) == NULL)
  88. serrx(EXIT_FAILURE, "%s: %s", function, NOMEM);
  89. /* init new objects */
  90. while (socksfdc < dc)
  91. socksfdv[socksfdc++] = socksfdinit;
  92. if (sigprocmask(SIG_SETMASK, &oldmask, NULL) != 0)
  93. swarn("%s: sigprocmask()", function);
  94. }
  95. switch (socksfd->state.command) {
  96. case SOCKS_BIND:
  97. #if SOCKS_TRYHARDER
  98. if ((socksfd->state.lock = socks_mklock(SOCKS_LOCKFILE)) == -1)
  99. swarn("%s: socks_mklock()", function);
  100. #endif
  101. break;
  102. }
  103. socksfdv[clientfd] = *socksfd;
  104. socksfdv[clientfd].allocated = 1;
  105. return &socksfdv[clientfd];
  106. }
  107. struct socksfd_t *
  108. socks_getaddr(d)
  109. unsigned int d;
  110. {
  111. if (socks_isaddr(d))
  112. return &socksfdv[d];
  113. return NULL;
  114. }
  115. void
  116. socks_rmaddr(d)
  117. unsigned int d;
  118. {
  119. /* const char *function = "socks_rmaddr()";  */
  120. #if 0 /* DEBUG */
  121. if (!socks_isaddr(d)
  122. || (!socksfdv[d].state.command != -1 && !socksfdv[d].state.system))
  123. slog(LOG_DEBUG, "%s: %d", function, d);
  124. #endif
  125. if (!socks_isaddr(d))
  126. return;
  127. socks_rmfd(d);
  128. switch (socksfdv[d].state.version) {
  129. case MSPROXY_V2:
  130. if (socksfdv[d].control != -1)
  131. close(socksfdv[d].control);
  132. break;
  133. case SOCKS_V4:
  134. case SOCKS_V5:
  135. if (!socksfdv[d].state.system)
  136. switch (socksfdv[d].state.command) {
  137. case SOCKS_BIND:
  138. if (socksfdv[d].control != -1
  139. && d != (unsigned int)socksfdv[d].control)
  140. close(socksfdv[d].control);
  141. break;
  142. case SOCKS_CONNECT:
  143. break; /* no separate controlconnection. */
  144. case SOCKS_UDPASSOCIATE:
  145. if (socksfdv[d].control != -1)
  146. close(socksfdv[d].control);
  147. break;
  148. default:
  149. SERRX(socksfdv[d].state.command);
  150. }
  151. switch (socksfdv[d].state.command) {
  152. case SOCKS_BIND:
  153. #if SOCKS_TRYHARDER
  154. if (close(socksfdv[d].state.lock) != 0)
  155. swarn("socks_rmaddr()");
  156. #endif
  157. break;
  158. }
  159. }
  160. socksfdv[d] = socksfdinit;
  161. }
  162. int
  163. socks_isaddr(d)
  164. unsigned int d;
  165. {
  166. if (d < socksfdc && socksfdv[d].allocated)
  167. return 1;
  168. return 0;
  169. }
  170. int
  171. socks_addrisok(s)
  172. unsigned int s;
  173. {
  174. const char *function = "socks_addrisok()";
  175. const int errno_s = errno;
  176. int matched;
  177. sigset_t oldmask;
  178. if (socks_sigblock(&oldmask) != 0)
  179. return 0;
  180. matched = 0;
  181. do {
  182. struct socksfd_t *socksfd;
  183. struct sockaddr local;
  184. socklen_t locallen;
  185. locallen = sizeof(local);
  186. if (getsockname((int)s, &local, &locallen) != 0)
  187. break;
  188. socksfd = socks_getaddr(s);
  189. if (socksfd != NULL) {
  190. if (!sockaddrareeq(&local, &socksfd->local))
  191. break;
  192. /* check remote endpoint too? */
  193. matched = 1;
  194. }
  195. else { /* unknown descriptor.  Try to check whether it's a dup. */
  196. int duped;
  197. if ((duped = socks_addrmatch(&local, NULL, NULL)) != -1) {
  198. struct socksfd_t nsocksfd;
  199. socksfd = socksfddup(socks_getaddr((unsigned int)duped), &nsocksfd);
  200. if (socksfd == NULL) {
  201. swarn("%s: socksfddup()", function);
  202. break;
  203. }
  204. socks_addaddr(s, socksfd);
  205. matched = 1;
  206. }
  207. break;
  208. }
  209. /* CONSTCOND */
  210. } while (0);
  211. if (sigprocmask(SIG_SETMASK, &oldmask, NULL) != 0)
  212. swarn("%s: sigprocmask()", function);
  213. errno = errno_s;
  214. return matched;
  215. }
  216. int
  217. socks_addrcontrol(local, remote)
  218. const struct sockaddr *local;
  219. const struct sockaddr *remote;
  220. {
  221. unsigned int i;
  222. for (i = 0; i < socksfdc; ++i) {
  223. struct sockaddr localcontrol, remotecontrol;
  224. if (!socks_isaddr((unsigned int)i))
  225. continue;
  226. if (local != NULL) {
  227. socklen_t len = sizeof(localcontrol);
  228. if (getsockname(socksfdv[i].control, &localcontrol, &len) != 0)
  229. continue;
  230. if (!sockaddrareeq(local, &localcontrol))
  231. continue;
  232. }
  233. if (remote != NULL) {
  234. socklen_t len = sizeof(remotecontrol);
  235. if (getpeername(socksfdv[i].control, &remotecontrol, &len) != 0)
  236. continue;
  237. if (!sockaddrareeq(remote, &remotecontrol))
  238. continue;
  239. }
  240. return i;
  241. }
  242. return -1;
  243. }
  244. int
  245. socks_addrmatch(local, remote, state)
  246. const struct sockaddr *local;
  247. const struct sockaddr *remote;
  248. const struct socksstate_t *state;
  249. {
  250. unsigned int i;
  251. for (i = 0; i < socksfdc; ++i) {
  252. if (!socks_isaddr(i))
  253. continue;
  254. /*
  255.  * only compare fields that have a valid value in request to compare
  256.  * against.
  257.  */
  258. if (local != NULL)
  259. if (!sockaddrareeq(local, &socksfdv[i].local))
  260. continue;
  261. if (remote != NULL)
  262. if (!sockaddrareeq(remote, &socksfdv[i].remote))
  263. continue;
  264. if (state != NULL) {
  265. if (state->version != -1)
  266. if (state->version != socksfdv[i].state.version)
  267. continue;
  268. if (state->command != -1)
  269. if (state->command != socksfdv[i].state.command)
  270. continue;
  271. if (state->inprogress != -1)
  272. if (state->inprogress != socksfdv[i].state.inprogress)
  273. continue;
  274. if (state->acceptpending != -1)
  275. if (state->acceptpending != socksfdv[i].state.acceptpending)
  276. continue;
  277. }
  278. return i;
  279. }
  280. return -1;
  281. }
  282. int
  283. socks_addfd(d)
  284. unsigned int d;
  285. {
  286. const char *function = "socks_addfd()";
  287. if (d >= dc) { /* init/reallocate */
  288. sigset_t oldmask;
  289. int *newfdv;
  290. unsigned int newfdc;
  291. if (socks_sigblock(&oldmask) != 0)
  292. return -1;
  293. newfdc = MAX(d + 1, (unsigned int)getdtablesize());
  294. if ((newfdv = (int *)realloc(dv, sizeof(*dv) * newfdc)) == NULL)
  295. serrx(EXIT_FAILURE, "%s: %s", function, NOMEM);
  296. dv = newfdv;
  297. /* init all to -1, a illegal value for a d. */
  298. while (dc < newfdc)
  299. dv[dc++] = -1;
  300. if (sigprocmask(SIG_SETMASK, &oldmask, NULL) != 0)
  301. swarn("%s: sigprocmask()", function);
  302. }
  303. dv[d] = d;
  304. return 0;
  305. }
  306. int
  307. socks_isfd(d)
  308. unsigned int d;
  309. {
  310. if (d >= dc || dv[d] == -1)
  311. return 0;
  312. return 1;
  313. }
  314. void
  315. socks_rmfd(d)
  316. unsigned int d;
  317. {
  318. if (socks_isfd(d))
  319. dv[d] = -1;
  320. }
  321. struct socksfd_t *
  322. socksfddup(old, new)
  323. const struct socksfd_t *old;
  324. struct socksfd_t *new;
  325. {
  326. *new = *old; /* init most stuff. */
  327. switch (old->state.command) {
  328. case SOCKS_BIND:
  329. case SOCKS_UDPASSOCIATE:
  330. if ((new->control = socketoptdup(old->control)) == -1)
  331. return NULL;
  332. break;
  333. case SOCKS_CONNECT:
  334. /* only descriptor for connect is the one client has. */
  335. break;
  336. default:
  337. SERRX(old->state.command);
  338. }
  339. return new;
  340. }
  341. static int
  342. socks_sigblock(oldmask)
  343. sigset_t *oldmask;
  344. {
  345. const char *function = "socks_sigblock()";
  346. sigset_t newmask;
  347. /*
  348.  * block signals that might change socksfd.
  349.  */
  350. sigemptyset(&newmask);
  351. sigaddset(&newmask, SIGIO);
  352. sigaddset(&newmask, SIGCHLD);
  353. if (sigprocmask(SIG_BLOCK, &newmask, oldmask) != 0) {
  354. swarn("%s: sigprocmask()", function);
  355. return -1;
  356. }
  357. return 0;
  358. }
  359. #if 0
  360. void
  361. ccinit(void)
  362. {
  363. const char *function = "cc()";
  364. struct sigaction sigact;
  365. struct itimerval itimer;
  366. slog(LOG_DEBUG, function);
  367. if (sigaction(SIGALRM, NULL, &sigact) != 0) {
  368. swarn("%s: sigaction(SIGALRM)", function);
  369. return;
  370. }
  371. if (sigact.sa_handler != SIG_DFL
  372. &&  sigact.sa_handler != SIG_IGN) {
  373. swarnx("%s: could not install signalhandler for SIGALRM, already set",
  374. function);
  375. return;
  376. }
  377. sigemptyset(&sigact.sa_mask);
  378. sigact.sa_flags = SA_RESTART;
  379. sigact.sa_handler = cc_socksfdv;
  380. if (sigaction(SIGALRM, &sigact, NULL) != 0) {
  381. swarn("%s: sigaction(SIGALRM)", function);
  382. return;
  383. }
  384. itimer.it_interval.tv_sec = 1;
  385. itimer.it_interval.tv_usec = 0;
  386. itimer.it_value.tv_sec = 1;
  387. itimer.it_value.tv_usec = 1;
  388. if (setitimer(ITIMER_REAL, &itimer, NULL) != 0)
  389. swarn("%s: setitimer()", function);
  390. }
  391. #endif
  392. #if DIAGNOSTIC
  393. void
  394. cc_socksfdv(sig)
  395. int sig;
  396. {
  397. unsigned int i;
  398. for (i = 0; i < socksfdc; ++i) {
  399. if (!socksfdv[i].allocated)
  400. continue;
  401. if (socksfdv[i].state.system)
  402. SERRX(i);
  403. }
  404. }
  405. #endif /* DIAGNOSTIC */