⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 icp_v2.c

📁 -
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * $Id: icp_v2.c,v 1.58 1999/01/29 21:28:13 wessels Exp $ * * DEBUG: section 12    Internet Cache Protocol * AUTHOR: Duane Wessels * * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/ * ---------------------------------------------------------- * *  Squid is the result of efforts by numerous individuals from the *  Internet community.  Development is led by Duane Wessels of the *  National Laboratory for Applied Network Research and funded by the *  National Science Foundation.  Squid is Copyrighted (C) 1998 by *  Duane Wessels and the University of California San Diego.  Please *  see the COPYRIGHT file for full details.  Squid incorporates *  software developed and/or copyrighted by other sources.  Please see *  the CREDITS file for full details. * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. *   *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. *   *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. * */#include "squid.h"static void icpLogIcp(struct in_addr, log_type, int, const char *, int);static void icpHandleIcpV2(int, struct sockaddr_in, char *, int);static void icpCount(void *, int, size_t, int);/* * IcpQueueHead is global so comm_incoming() knows whether or not * to call icpUdpSendQueue. */static icpUdpData *IcpQueueTail = NULL;static voidicpLogIcp(struct in_addr caddr, log_type logcode, int len, const char *url, int delay){    AccessLogEntry al;    if (LOG_TAG_NONE == logcode)	return;    if (LOG_ICP_QUERY == logcode)	return;    clientdbUpdate(caddr, logcode, PROTO_ICP, len);    if (!Config.onoff.log_udp)	return;    memset(&al, '\0', sizeof(al));    al.icp.opcode = ICP_QUERY;    al.url = url;    al.cache.caddr = caddr;    al.cache.size = len;    al.cache.code = logcode;    al.cache.msec = delay;    accessLogLog(&al);}voidicpUdpSendQueue(int fd, void *unused){    icpUdpData *q;    int x;    int delay;    while ((q = IcpQueueHead) != NULL) {	delay = tvSubUsec(q->queue_time, current_time);	/* increment delay to prevent looping */	x = icpUdpSend(fd, &q->address, q->msg, q->logcode, ++delay);	IcpQueueHead = q->next;	safe_free(q);	if (x < 0)	    break;    }}void *icpCreateMessage(    icp_opcode opcode,    int flags,    const char *url,    int reqnum,    int pad){    char *buf = NULL;    icp_common_t *headerp = NULL;    char *urloffset = NULL;    int buf_len;    buf_len = sizeof(icp_common_t) + strlen(url) + 1;    if (opcode == ICP_QUERY)	buf_len += sizeof(u_num32);    buf = xcalloc(buf_len, 1);    headerp = (icp_common_t *) (void *) buf;    headerp->opcode = (char) opcode;    headerp->version = ICP_VERSION_CURRENT;    headerp->length = (u_short) htons(buf_len);    headerp->reqnum = htonl(reqnum);    headerp->flags = htonl(flags);    headerp->pad = htonl(pad);    headerp->shostid = theOutICPAddr.s_addr;    urloffset = buf + sizeof(icp_common_t);    if (opcode == ICP_QUERY)	urloffset += sizeof(u_num32);    xmemcpy(urloffset, url, strlen(url));    return buf;}inticpUdpSend(int fd,    const struct sockaddr_in *to,    icp_common_t * msg,    log_type logcode,    int delay){    icpUdpData *queue;    int x;    int len;    len = (int) ntohs(msg->length);    debug(12, 5) ("icpUdpSend: FD %d sending %s, %d bytes to %s:%d\n",	fd,	icp_opcode_str[msg->opcode],	len,	inet_ntoa(to->sin_addr),	ntohs(to->sin_port));    x = comm_udp_sendto(fd, to, sizeof(*to), msg, len);    if (x >= 0) {	/* successfully written */	icpLogIcp(to->sin_addr, logcode, len, (char *) (msg + 1), delay);	icpCount(msg, SENT, (size_t) len, delay);	safe_free(msg);    } else if (0 == delay) {	/* send failed, but queue it */	queue = xcalloc(1, sizeof(icpUdpData));	queue->address = *to;	queue->msg = msg;	queue->len = (int) ntohs(msg->length);	queue->queue_time = current_time;	queue->logcode = logcode;	if (IcpQueueHead == NULL) {	    IcpQueueHead = queue;	    IcpQueueTail = queue;	} else if (IcpQueueTail == IcpQueueHead) {	    IcpQueueTail = queue;	    IcpQueueHead->next = queue;	} else {	    IcpQueueTail->next = queue;	    IcpQueueTail = queue;	}	commSetSelect(fd, COMM_SELECT_WRITE, icpUdpSendQueue, NULL, 0);	Counter.icp.replies_queued++;    } else {	/* don't queue it */	Counter.icp.replies_dropped++;    }    return x;}inticpCheckUdpHit(StoreEntry * e, request_t * request){    if (e == NULL)	return 0;    if (!storeEntryValidToSend(e))	return 0;    if (Config.onoff.icp_hit_stale)	return 1;    if (refreshCheckICP(e, request))	return 0;    return 1;}static voidicpHandleIcpV2(int fd, struct sockaddr_in from, char *buf, int len){    icp_common_t header;    StoreEntry *entry = NULL;    char *url = NULL;    const cache_key *key;    request_t *icp_request = NULL;    int allow = 0;    aclCheck_t checklist;    icp_common_t *reply;    int src_rtt = 0;    u_num32 flags = 0;    int rtt = 0;    int hops = 0;    xmemcpy(&header, buf, sizeof(icp_common_t));    /*     * Only these fields need to be converted     */    header.length = ntohs(header.length);    header.reqnum = ntohl(header.reqnum);    header.flags = ntohl(header.flags);    header.pad = ntohl(header.pad);    switch (header.opcode) {    case ICP_QUERY:	/* We have a valid packet */	url = buf + sizeof(icp_common_t) + sizeof(u_num32);	if (strpbrk(url, w_space)) {	    url = rfc1738_escape(url);	    reply = icpCreateMessage(ICP_ERR, 0, url, header.reqnum, 0);	    icpUdpSend(fd, &from, reply, LOG_UDP_INVALID, 0);	    break;	}	if ((icp_request = urlParse(METHOD_GET, url)) == NULL) {	    reply = icpCreateMessage(ICP_ERR, 0, url, header.reqnum, 0);	    icpUdpSend(fd, &from, reply, LOG_UDP_INVALID, 0);	    break;	}	checklist.src_addr = from.sin_addr;	checklist.my_addr = no_addr;	checklist.request = icp_request;	allow = aclCheckFast(Config.accessList.icp, &checklist);	if (!allow) {	    debug(12, 2) ("icpHandleIcpV2: Access Denied for %s by %s.\n",		inet_ntoa(from.sin_addr), AclMatchedName);	    if (clientdbCutoffDenied(from.sin_addr)) {		/*		 * count this DENIED query in the clientdb, even though		 * we're not sending an ICP reply...		 */		clientdbUpdate(from.sin_addr, LOG_UDP_DENIED, PROTO_ICP, 0);	    } else {		reply = icpCreateMessage(ICP_DENIED, 0, url, header.reqnum, 0);		icpUdpSend(fd, &from, reply, LOG_UDP_DENIED, 0);	    }	    break;	}	if (header.flags & ICP_FLAG_SRC_RTT) {	    rtt = netdbHostRtt(icp_request->host);	    hops = netdbHostHops(icp_request->host);	    src_rtt = ((hops & 0xFFFF) << 16) | (rtt & 0xFFFF);	    if (rtt)		flags |= ICP_FLAG_SRC_RTT;	}	/* The peer is allowed to use this cache */	entry = storeGetPublic(url, METHOD_GET);	debug(12, 5) ("icpHandleIcpV2: OPCODE %s\n", icp_opcode_str[header.opcode]);	if (icpCheckUdpHit(entry, icp_request)) {	    reply = icpCreateMessage(ICP_HIT, flags, url, header.reqnum, src_rtt);	    icpUdpSend(fd, &from, reply, LOG_UDP_HIT, 0);	    break;	}	if (Config.onoff.test_reachability && rtt == 0) {	    if ((rtt = netdbHostRtt(icp_request->host)) == 0)		netdbPingSite(icp_request->host);	}	/* if store is rebuilding, return a UDP_HIT, but not a MISS */	if (store_rebuilding && opt_reload_hit_only) {	    reply = icpCreateMessage(ICP_MISS_NOFETCH, flags, url, header.reqnum, src_rtt);	    icpUdpSend(fd, &from, reply, LOG_UDP_MISS_NOFETCH, 0);	} else if (hit_only_mode_until > squid_curtime) {	    reply = icpCreateMessage(ICP_MISS_NOFETCH, flags, url, header.reqnum, src_rtt);	    icpUdpSend(fd, &from, reply, LOG_UDP_MISS_NOFETCH, 0);	} else if (Config.onoff.test_reachability && rtt == 0) {	    reply = icpCreateMessage(ICP_MISS_NOFETCH, flags, url, header.reqnum, src_rtt);	    icpUdpSend(fd, &from, reply, LOG_UDP_MISS_NOFETCH, 0);	} else {	    reply = icpCreateMessage(ICP_MISS, flags, url, header.reqnum, src_rtt);	    icpUdpSend(fd, &from, reply, LOG_UDP_MISS, 0);	}	break;    case ICP_HIT:#if ALLOW_SOURCE_PING    case ICP_SECHO:#endif    case ICP_DECHO:    case ICP_MISS:    case ICP_DENIED:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -