cache.c
上传用户:sddyfurun
上传日期:2007-01-04
资源大小:525k
文件大小:6k
源码类别:

代理服务器

开发平台:

Unix_Linux

  1. /* Copyright (c) 1995,1996,1997 NEC Corporation.  All rights reserved.       */
  2. /*                                                                           */
  3. /* The redistribution, use and modification in source or binary forms of     */
  4. /* this software is subject to the conditions set forth in the copyright     */
  5. /* document ("Copyright") included with this distribution.                   */
  6. /*
  7.  * $Id: cache.c,v 1.30.2.1 1997/08/29 21:13:46 wlu Exp $
  8.  */
  9. #include "socks5p.h"
  10. #include "buffer.h"
  11. #include "addr.h"
  12. #include "wrap.h"
  13. #include "cache.h"
  14. #include "log.h"
  15. #include "msg.h"
  16. static fd_set sset;
  17. static int initialized = 0;
  18. lsSocksInfo *lsConList = NULL;          /* all current lib connections      */
  19. lsSocksInfo *lsLastCon = NULL;          /* pointer to the proxy connect     */
  20. static void lsProxyCacheDelete(lsProxyInfo **pp, S5IOHandle rfd) {
  21.     lsProxyInfo *n, *p = *pp;
  22.     
  23.     for (n = p?p->next:NULL; p ; p = n, n = n?n->next:NULL) {
  24. if (--(p->refcount) > 0) continue;
  25. if (p->cinfo.fd == rfd) p->cinfo.fd = S5InvalidIOHandle;
  26. S5BufCleanContext(&p->cinfo);
  27. free(p);
  28.     }
  29.     
  30.     *pp = NULL;
  31. }
  32. void lsProxyCacheDel(lsSocksInfo *pcon, lsProxyInfo *r) {
  33.     lsProxyInfo *p, *q;
  34.     
  35.     if (pcon == NULL || pcon->pri == NULL || r == NULL) return;
  36.     
  37.     p = NULL;
  38.     if (pcon->pri == r) {
  39. q = pcon->pri;
  40. pcon->pri = q->next;
  41.     } else {
  42. for (p = q = pcon->pri; q; p = q, q = q->next)
  43.     if (q == r) break;
  44. if (q == NULL) return;
  45.     }
  46.     if (pcon->cur == q) pcon->cur = pcon->pri;
  47.     if (p) p->next = q->next;
  48.     if (q->cinfo.fd == pcon->fd) q->cinfo.fd = S5InvalidIOHandle;
  49.     S5BufCleanContext(&q->cinfo);
  50.     free(q);
  51.     return;
  52. }
  53. void lsProxyCacheClean(lsSocksInfo *pcon) {
  54.     lsProxyInfo *p, *q;
  55.     
  56.     if (pcon == NULL)                    return;
  57.     if (pcon->status == CON_ESTABLISHED) return;
  58.     
  59.     for (p = q = pcon->pri; p; ) {
  60. if (S5IOCheck(p->cinfo.fd) >= 0) {
  61.     q = p;
  62.     p = q->next;
  63. } else if (p == q) {
  64.     pcon->pri = p->next;
  65.     S5BufCleanContext(&p->cinfo);
  66.     if (pcon->cur == p) pcon->cur = NULL;
  67.     free(p);
  68.     
  69.     p = q = pcon->pri;
  70. } else {
  71.     q->next = p->next;
  72.     S5BufCleanContext(&p->cinfo);
  73.     if (pcon->cur == p) pcon->cur = NULL;
  74.     free(p);
  75.     
  76.     p = q->next;
  77. }
  78.     }
  79.     if (pcon->cur == NULL) pcon->cur = pcon->pri;
  80. }
  81. lsProxyInfo *lsProxyCacheFind(const lsSocksInfo *pcon, const S5NetAddr *na, u_char how, int checkport) {
  82.     lsProxyInfo *p;
  83.     
  84.     if (!na) {
  85. if (pcon) return pcon->cur?pcon->cur:pcon->pri;
  86. return NULL;
  87.     }
  88.     if (na->sa.sa_family == AF_INET) {
  89. if (na->sin.sin_addr.s_addr == INVALIDADDR) {
  90.     return NULL;
  91. }
  92.     
  93. for (p = pcon?pcon->pri:NULL; p; p = p->next) {
  94.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Checking %d (%s:%d)", p->how, ADDRANDPORT(&p->prxyin));
  95.     if (p->how                            != how)                     continue;
  96.     if (p->prxyin.sin.sin_family          != na->sin.sin_family)      continue;
  97.     if (p->prxyin.sin.sin_addr.s_addr     != na->sin.sin_addr.s_addr) continue;
  98.     if (checkport && p->prxyin.sin.sin_port != na->sin.sin_port)      continue;
  99.     return p;
  100. }
  101.     }
  102.     
  103.     return NULL;
  104. }
  105. lsProxyInfo *lsProxyCacheAdd(lsSocksInfo *pcon, const S5NetAddr *na, u_char how) {
  106.     lsProxyInfo *pri;
  107.     pri = (lsProxyInfo *)calloc(1, sizeof(lsProxyInfo));
  108.     if (!pri) return NULL;
  109.     pri->next = pcon->pri;
  110.     pcon->pri = pri;
  111.     pri->refcount = pri->next?pri->next->refcount:1;
  112.     pri->how      = how;
  113.     S5BufSetupContext(&pri->cinfo);
  114.     if (pcon->cmd != SOCKS_UDP) pri->cinfo.fd = pcon->fd;
  115.     if (na) {
  116. lsAddrCopy(&pri->prxyin, na, lsAddrSize(na));
  117.     } else {
  118. pri->prxyin.sin.sin_family      = AF_INET;
  119. pri->prxyin.sin.sin_port        = INVALIDPORT;
  120. pri->prxyin.sin.sin_addr.s_addr = INVALIDADDR;
  121.     }
  122.     
  123.     return pcon->cur = pri;
  124. }
  125. int lsConnectionDel(S5IOHandle fd) {
  126.     lsSocksInfo *n, *p, *q;
  127.     
  128.     if (!initialized || (fd == S5InvalidIOHandle) || !FD_ISSET(fd, &sset)) {
  129. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(15), 0, "lsConnectionDel: No connection found ");
  130. return -1;
  131.     }
  132.     FD_CLR(fd, &sset);
  133.     
  134.     /* get rid of all the matches, really? it should have only one match otherwise */    
  135.     /* lsConnectionFind() will have trouble             */
  136.     p = NULL;
  137.     if (lsConList->fd == fd) {
  138. q = lsConList;
  139. lsConList = q->next;
  140.     } else {
  141. for (p = q = lsConList; q; p = q, q = q->next)
  142.     if (q->fd == fd) break;
  143. if (q == NULL) return -1;
  144.     }
  145.     if (lsLastCon == q) {
  146. lsLastCon = NULL;
  147. for (n = lsConList; n; n = n->next) {
  148.     if (n->cmd != SOCKS_CONNECT) continue;
  149.     if (n == q) continue;
  150.     if (!n->pri || (n->pri->how == DIRECT)) continue;
  151.     lsLastCon = n;
  152.     break;
  153. }
  154.     }
  155.     if (p) p->next = q->next;
  156.     lsProxyCacheDelete(&q->pri, q->fd);
  157.     free(q);
  158.     return 0;
  159. }
  160. lsSocksInfo *lsConnectionAdd(S5IOHandle fd) {
  161.     lsSocksInfo *p = NULL;
  162.     
  163.     if (!initialized) {
  164. FD_ZERO(&sset);
  165. initialized = 1;
  166. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "lsConnectionAdd: fdset cleared");
  167.     }
  168.     if ((p = (lsSocksInfo *)calloc(1, sizeof(lsSocksInfo))) == NULL) {
  169. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "lsConnectionAdd: calloc - out of memory");
  170. return NULL;
  171.     }
  172.     p->status  = CON_NOTESTABLISHED;
  173.     p->next    = lsConList;
  174.     p->fd      = fd;
  175.     p->afd     = S5InvalidIOHandle;
  176.     lsConList  = p;
  177.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "lsConnectionAdd: fdset added fd #%d", fd);
  178.     FD_SET(fd, &sset);
  179.     return p;
  180. }
  181. int lsConnectionCached(S5IOHandle fd) {
  182.     lsSocksInfo *p;
  183.     if (!initialized || (fd == S5InvalidIOHandle) || !FD_ISSET(fd, &sset)) return 0;
  184.     for (p = lsConList; p != NULL; p = p->next)
  185. if (p->fd == fd) return 1;
  186.     FD_CLR(fd, &sset);
  187.     return 0;
  188. }
  189. lsSocksInfo *lsConnectionFind(S5IOHandle fd) {
  190.     lsSocksInfo *p;
  191.     
  192.     if (!initialized || (fd == S5InvalidIOHandle) || !FD_ISSET(fd, &sset)) return NULL;
  193.     
  194.     for (p = lsConList; p != NULL; p = p->next) {
  195. if (p->fd != fd) continue;
  196. return p;
  197.     }
  198.     FD_CLR(fd, &sset);
  199.     return NULL;
  200. }