icp_v3.c
上传用户:liugui
上传日期:2007-01-04
资源大小:822k
文件大小:5k
源码类别:

代理服务器

开发平台:

Unix_Linux

  1. /*
  2.  * $Id: icp_v3.c,v 1.28 1999/01/29 21:28:14 wessels Exp $
  3.  *
  4.  * DEBUG: section 12    Internet Cache Protocol
  5.  * AUTHOR: Duane Wessels
  6.  *
  7.  * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
  8.  * ----------------------------------------------------------
  9.  *
  10.  *  Squid is the result of efforts by numerous individuals from the
  11.  *  Internet community.  Development is led by Duane Wessels of the
  12.  *  National Laboratory for Applied Network Research and funded by the
  13.  *  National Science Foundation.  Squid is Copyrighted (C) 1998 by
  14.  *  Duane Wessels and the University of California San Diego.  Please
  15.  *  see the COPYRIGHT file for full details.  Squid incorporates
  16.  *  software developed and/or copyrighted by other sources.  Please see
  17.  *  the CREDITS file for full details.
  18.  *
  19.  *  This program is free software; you can redistribute it and/or modify
  20.  *  it under the terms of the GNU General Public License as published by
  21.  *  the Free Software Foundation; either version 2 of the License, or
  22.  *  (at your option) any later version.
  23.  *  
  24.  *  This program is distributed in the hope that it will be useful,
  25.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  26.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  27.  *  GNU General Public License for more details.
  28.  *  
  29.  *  You should have received a copy of the GNU General Public License
  30.  *  along with this program; if not, write to the Free Software
  31.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
  32.  *
  33.  */
  34. #include "squid.h"
  35. /* Currently Harvest cached-2.x uses ICP_VERSION_3 */
  36. void
  37. icpHandleIcpV3(int fd, struct sockaddr_in from, char *buf, int len)
  38. {
  39.     icp_common_t header;
  40.     icp_common_t *reply;
  41.     StoreEntry *entry = NULL;
  42.     char *url = NULL;
  43.     const cache_key *key;
  44.     request_t *icp_request = NULL;
  45.     int allow = 0;
  46.     aclCheck_t checklist;
  47.     xmemcpy(&header, buf, sizeof(icp_common_t));
  48.     /*
  49.      * Only these fields need to be converted
  50.      */
  51.     header.length = ntohs(header.length);
  52.     header.reqnum = ntohl(header.reqnum);
  53.     header.flags = ntohl(header.flags);
  54.     header.pad = ntohl(header.pad);
  55.     switch (header.opcode) {
  56.     case ICP_QUERY:
  57. /* We have a valid packet */
  58. url = buf + sizeof(icp_common_t) + sizeof(u_num32);
  59. if (strpbrk(url, w_space)) {
  60.     url = rfc1738_escape(url);
  61.     reply = icpCreateMessage(ICP_ERR, 0, url, header.reqnum, 0);
  62.     icpUdpSend(fd, &from, reply, LOG_UDP_INVALID, 0);
  63.     break;
  64. }
  65. if ((icp_request = urlParse(METHOD_GET, url)) == NULL) {
  66.     reply = icpCreateMessage(ICP_ERR, 0, url, header.reqnum, 0);
  67.     icpUdpSend(fd, &from, reply, LOG_UDP_INVALID, 0);
  68.     break;
  69. }
  70. checklist.src_addr = from.sin_addr;
  71. checklist.my_addr = no_addr;
  72. checklist.request = icp_request;
  73. allow = aclCheckFast(Config.accessList.icp, &checklist);
  74. if (!allow) {
  75.     debug(12, 2) ("icpHandleIcpV3: Access Denied for %s by %s.n",
  76. inet_ntoa(from.sin_addr), AclMatchedName);
  77.     if (clientdbCutoffDenied(from.sin_addr)) {
  78. /*
  79.  * count this DENIED query in the clientdb, even though
  80.  * we're not sending an ICP reply...
  81.  */
  82. clientdbUpdate(from.sin_addr, LOG_UDP_DENIED, PROTO_ICP, 0);
  83.     } else {
  84. reply = icpCreateMessage(ICP_DENIED, 0, url, header.reqnum, 0);
  85. icpUdpSend(fd, &from, reply, LOG_UDP_DENIED, 0);
  86.     }
  87.     break;
  88. }
  89. /* The peer is allowed to use this cache */
  90. entry = storeGetPublic(url, METHOD_GET);
  91. debug(12, 5) ("icpHandleIcpV3: OPCODE %sn",
  92.     icp_opcode_str[header.opcode]);
  93. if (icpCheckUdpHit(entry, icp_request)) {
  94.     reply = icpCreateMessage(ICP_HIT, 0, url, header.reqnum, 0);
  95.     icpUdpSend(fd, &from, reply, LOG_UDP_HIT, 0);
  96.     break;
  97. }
  98. /* if store is rebuilding, return a UDP_HIT, but not a MISS */
  99. if (opt_reload_hit_only && store_rebuilding) {
  100.     reply = icpCreateMessage(ICP_MISS_NOFETCH, 0, url, header.reqnum, 0);
  101.     icpUdpSend(fd, &from, reply, LOG_UDP_MISS_NOFETCH, 0);
  102. } else if (hit_only_mode_until > squid_curtime) {
  103.     reply = icpCreateMessage(ICP_MISS_NOFETCH, 0, url, header.reqnum, 0);
  104.     icpUdpSend(fd, &from, reply, LOG_UDP_MISS_NOFETCH, 0);
  105. } else {
  106.     reply = icpCreateMessage(ICP_MISS, 0, url, header.reqnum, 0);
  107.     icpUdpSend(fd, &from, reply, LOG_UDP_MISS, 0);
  108. }
  109. break;
  110.     case ICP_HIT:
  111. #if ALLOW_SOURCE_PING
  112.     case ICP_SECHO:
  113. #endif
  114.     case ICP_DECHO:
  115.     case ICP_MISS:
  116.     case ICP_DENIED:
  117.     case ICP_MISS_NOFETCH:
  118. if (neighbors_do_private_keys && header.reqnum == 0) {
  119.     debug(12, 0) ("icpHandleIcpV3: Neighbor %s returned reqnum = 0n",
  120. inet_ntoa(from.sin_addr));
  121.     debug(12, 0) ("icpHandleIcpV3: Disabling use of private keysn");
  122.     neighbors_do_private_keys = 0;
  123. }
  124. url = buf + sizeof(icp_common_t);
  125. debug(12, 3) ("icpHandleIcpV3: %s from %s for '%s'n",
  126.     icp_opcode_str[header.opcode],
  127.     inet_ntoa(from.sin_addr),
  128.     url);
  129. key = icpGetCacheKey(url, (int) header.reqnum);
  130. /* call neighborsUdpAck even if ping_status != PING_WAITING */
  131. neighborsUdpAck(key, &header, &from);
  132. break;
  133.     case ICP_INVALID:
  134.     case ICP_ERR:
  135. break;
  136.     default:
  137. debug(12, 0) ("icpHandleIcpV3: UNKNOWN OPCODE: %d from %sn",
  138.     header.opcode, inet_ntoa(from.sin_addr));
  139. break;
  140.     }
  141.     if (icp_request)
  142. requestDestroy(icp_request);
  143. }