/*
- * $Id: cache_cf.cc,v 1.217 1997/07/26 04:48:23 wessels Exp $
+ * $Id: cache_cf.cc,v 1.218 1997/08/25 02:17:45 wessels Exp $
*
* DEBUG: section 3 Configuration File Parsing
* AUTHOR: Harvest Derived
p->options |= NEIGHBOR_MCAST_RESPONDER;
} else if (!strncasecmp(token, "weight=", 7)) {
p->weight = atoi(token + 7);
+ } else if (!strncasecmp(token, "closest-only", 12)) {
+ p->options |= NEIGHBOR_CLOSEST_ONLY;
} else if (!strncasecmp(token, "ttl=", 4)) {
p->mcast.ttl = atoi(token + 4);
if (p->mcast.ttl < 0)
default
round-robin
multicast-responder
+ closest-only
use 'proxy-only' to specify that objects fetched
from this cache should not be saved locally.
not be sent directly to the peer, but ICP replies
will be accepted from it.
+ 'closest-only' indicates that, for ICP_OP_MISS
+ replies, we'll only forward CLOSEST_PARENT_MISSes
+ and never FIRST_PARENT_MISSes.
+
NOTE: non-ICP neighbors must be specified as 'parent'.
cache_host hostname type 3128 3130
#define HIER_MAX_DEFICIT 20
/* bitfields for peer->options */
-#define NEIGHBOR_PROXY_ONLY 0x01
-#define NEIGHBOR_NO_QUERY 0x02
-#define NEIGHBOR_DEFAULT_PARENT 0x04
-#define NEIGHBOR_ROUNDROBIN 0x08
-#define NEIGHBOR_MCAST_RESPONDER 0x10
+#define NEIGHBOR_PROXY_ONLY 0x01
+#define NEIGHBOR_NO_QUERY 0x02
+#define NEIGHBOR_DEFAULT_PARENT 0x04
+#define NEIGHBOR_ROUNDROBIN 0x08
+#define NEIGHBOR_MCAST_RESPONDER 0x10
+#define NEIGHBOR_CLOSEST_ONLY 0x20
#define ICP_FLAG_HIT_OBJ 0x80000000ul
#define ICP_FLAG_SRC_RTT 0x40000000ul
/*
- * $Id: neighbors.cc,v 1.156 1997/08/10 04:42:42 wessels Exp $
+ * $Id: neighbors.cc,v 1.157 1997/08/25 02:17:47 wessels Exp $
*
* DEBUG: section 15 Neighbor Routines
* AUTHOR: Harvest Derived
static void peerCountMcastPeersDone _PARAMS((void *data));
static void peerCountMcastPeersStart _PARAMS((void *data));
static void peerCountMcastPeersSchedule _PARAMS((peer * p, time_t when));
-static void peerCountHandleIcpReply _PARAMS((peer * p, peer_t type, icp_opcode op, void *data));
+static IRCB peerCountHandleIcpReply;
static icp_common_t echo_hdr;
static u_short echo_port;
}
if (entry->swap_status != NO_SWAP)
fatal_dump("neighborsUdpPing: bad swap_status");
- mem->w_rtt = 0;
- mem->e_pings_closest_parent = NULL;
- mem->p_rtt = 0;
mem->start_ping = current_time;
mem->icp_reply_callback = callback;
mem->ircb_data = callback_data;
/* if we reach here, source-ping reply is the first 'parent',
* so fetch directly from the source */
debug(15, 6) ("Source is the first to respond.\n");
- mem->icp_reply_callback(NULL, ntype, opcode, mem->ircb_data);
+ mem->icp_reply_callback(NULL, ntype, header, mem->ircb_data);
}
} else if (opcode == ICP_OP_MISS) {
if (p == NULL) {
} else if (ntype != PEER_PARENT) {
(void) 0; /* ignore MISS from non-parent */
} else {
- mem->icp_reply_callback(p, ntype, opcode, mem->ircb_data);
+ mem->icp_reply_callback(p, ntype, header, mem->ircb_data);
}
} else if (opcode == ICP_OP_HIT || opcode == ICP_OP_HIT_OBJ) {
if (p == NULL) {
debug(15, 1) ("Ignoring HIT from non-peer %s\n",
inet_ntoa(from->sin_addr));
} else {
- mem->icp_reply_callback(p, ntype, ICP_OP_HIT, mem->ircb_data);
+ header->opcode = ICP_OP_HIT;
+ mem->icp_reply_callback(p, ntype, header, mem->ircb_data);
}
} else if (opcode == ICP_OP_DECHO) {
if (p == NULL) {
debug_trap("neighborsUdpAck: Found non-ICP cache as SIBLING\n");
debug_trap("neighborsUdpAck: non-ICP neighbors must be a PARENT\n");
} else {
- mem->icp_reply_callback(p, ntype, opcode, mem->ircb_data);
+ mem->icp_reply_callback(p, ntype, header, mem->ircb_data);
}
} else if (opcode == ICP_OP_SECHO) {
if (p) {
} else if (!Config.onoff.source_ping) {
debug(15, 1) ("Unsolicited SECHO from %s\n", inet_ntoa(from->sin_addr));
} else {
- mem->icp_reply_callback(NULL, ntype, opcode, mem->ircb_data);
+ mem->icp_reply_callback(NULL, ntype, header, mem->ircb_data);
}
} else if (opcode == ICP_OP_DENIED) {
if (p == NULL) {
}
}
} else if (opcode == ICP_OP_MISS_NOFETCH) {
- mem->icp_reply_callback(p, ntype, opcode, mem->ircb_data);
+ mem->icp_reply_callback(p, ntype, header, mem->ircb_data);
} else {
debug(15, 0) ("neighborsUdpAck: Unexpected ICP reply: %s\n", opcode_d);
}
}
static void
-peerCountHandleIcpReply(peer * p, peer_t type, icp_opcode op, void *data)
+peerCountHandleIcpReply(peer * p, peer_t type, icp_common_t *hdr, void *data)
{
ps_state *psstate = data;
psstate->icp.n_recv++;
/*
- * $Id: peer_select.cc,v 1.25 1997/08/24 00:37:05 wessels Exp $
+ * $Id: peer_select.cc,v 1.26 1997/08/25 02:17:48 wessels Exp $
*
* DEBUG: section 44 Peer Selection Algorithm
* AUTHOR: Duane Wessels
static void peerSelectFoo _PARAMS((ps_state *));
static void peerPingTimeout _PARAMS((void *data));
static void peerSelectCallbackFail _PARAMS((ps_state * psstate));
-static void peerHandleIcpReply _PARAMS((peer * p, peer_t type, icp_opcode op, void *data));
+static IRCB peerHandleIcpReply;
static void peerSelectStateFree _PARAMS((ps_state * psstate));
+static void peerIcpParentMiss _PARAMS((peer *, icp_common_t *, ps_state *));
+static int peerCheckNetdbDirect _PARAMS((ps_state * psstate));
static void
peerSelectStateFree(ps_state * psstate)
/* XXX When this happens, the client request just hangs */
}
+static int
+peerCheckNetdbDirect(ps_state * psstate)
+{
+ peer *p = psstate->closest_parent_miss;
+ int myrtt;
+ int myhops;
+ if (p == NULL)
+ return 0;
+ myrtt = netdbHostRtt(psstate->request->host);
+debug(44, 3) ("peerCheckNetdbDirect: MY RTT = %d\n", myrtt);
+debug(44, 3) ("peerCheckNetdbDirect: closest_parent_miss RTT = %d\n",
+ psstate->icp.p_rtt);
+ if (myrtt && myrtt < psstate->icp.p_rtt)
+ return 1;
+ myhops = netdbHostHops(psstate->request->host);
+debug(44, 3) ("peerCheckNetdbDirect: MY hops = %d\n", myhops);
+debug(44, 3) ("peerCheckNetdbDirect: minimum_direct_hops = %d\n",
+ Config.minDirectHops);
+ if (myhops && myhops <= Config.minDirectHops)
+ return 1;
+ return 0;
+}
+
static void
peerSelectFoo(ps_state * psstate)
{
}
debug_trap("peerSelect: neighborsUdpPing returned 0");
}
- if ((p = psstate->first_parent_miss)) {
+ if (peerCheckNetdbDirect(psstate)) {
+ code = CLOSEST_DIRECT;
+ debug(44, 3) ("peerSelect: %s/%s\n", hier_strings[code], request->host);
+ hierarchyNote(&request->hier, code, &psstate->icp, request->host);
+ peerSelectCallback(psstate, NULL);
+ } else if ((p = psstate->closest_parent_miss)) {
+ code = CLOSEST_PARENT_MISS;
+ debug(44, 3) ("peerSelect: %s/%s\n", hier_strings[code], p->host);
+ hierarchyNote(&request->hier, code, &psstate->icp, p->host);
+ peerSelectCallback(psstate, p);
+ } else if ((p = psstate->first_parent_miss)) {
code = FIRST_PARENT_MISS;
debug(44, 3) ("peerSelect: %s/%s\n", hier_strings[code], p->host);
hierarchyNote(&request->hier, code, &psstate->icp, p->host);
memset(&PeerStats, '\0', sizeof(PeerStats));
}
+static void
+peerIcpParentMiss(peer * p, icp_common_t * header, ps_state * ps)
+{
+ int rtt;
+ int hops;
+ if (Config.onoff.query_icmp) {
+ if (BIT_TEST(header->flags, ICP_FLAG_SRC_RTT)) {
+ rtt = header->pad & 0xFFFF;
+ hops = (header->pad >> 16) & 0xFFFF;
+ if (rtt > 0 && rtt < 0xFFFF)
+ netdbUpdatePeer(ps->request, p, rtt, hops);
+ if (rtt && (ps->icp.p_rtt == 0 || rtt < ps->icp.p_rtt)) {
+ ps->closest_parent_miss = p;
+ ps->icp.p_rtt = rtt;
+ }
+ }
+ }
+ /* if closest-only is set, the don't allow FIRST_PARENT_MISS */
+ if (BIT_TEST(p->options, NEIGHBOR_CLOSEST_ONLY))
+ return;
+ /* set FIRST_MISS if thre is no CLOSEST parent */
+ if (ps->closest_parent_miss != NULL)
+ return;
+ rtt = tvSubMsec(ps->icp.start, current_time) / p->weight;
+ if (ps->icp.w_rtt == 0 || rtt < ps->icp.w_rtt) {
+ ps->first_parent_miss = p;
+ ps->icp.w_rtt = rtt;
+ }
+}
static void
-peerHandleIcpReply(peer * p, peer_t type, icp_opcode op, void *data)
+peerHandleIcpReply(peer * p, peer_t type, icp_common_t * header, void *data)
{
ps_state *psstate = data;
- int w_rtt;
+ icp_opcode op = header->opcode;
request_t *request = psstate->request;
debug(44, 3) ("peerHandleIcpReply: %s %s\n",
IcpOpcodeStr[op],
psstate->entry->url);
psstate->icp.n_recv++;
if (op == ICP_OP_MISS || op == ICP_OP_DECHO) {
- if (type == PEER_PARENT) {
- w_rtt = tvSubMsec(psstate->icp.start, current_time) / p->weight;
- if (psstate->icp.w_rtt == 0 || w_rtt < psstate->icp.w_rtt) {
- psstate->first_parent_miss = p;
- psstate->icp.w_rtt = w_rtt;
- }
- }
+ if (type == PEER_PARENT)
+ peerIcpParentMiss(p, header, psstate);
} else if (op == ICP_OP_HIT || op == ICP_OP_HIT_OBJ) {
hierarchyNote(&request->hier,
type == PEER_PARENT ? PARENT_HIT : SIBLING_HIT,
/*
- * $Id: store.cc,v 1.280 1997/08/10 05:05:33 wessels Exp $
+ * $Id: store.cc,v 1.281 1997/08/25 02:17:49 wessels Exp $
*
* DEBUG: section 20 Storeage Manager
* AUTHOR: Harvest Derived
RB->invalid++;
continue;
}
+ if (strncmp(url, "http://internal.squid", 21) == 0)
+ continue;
storeSwapFullPath(sfileno, swapfile);
if (x != 9) {
RB->invalid++;
debug(20, 1) ("MemObject->e_swap_buf: %p %s\n",
mem->e_swap_buf,
checkNullString(mem->e_swap_buf));
- debug(20, 1) ("MemObject->w_rtt: %d\n",
- mem->w_rtt);
- debug(20, 1) ("MemObject->e_pings_closest_parent: %p\n",
- mem->e_pings_closest_parent);
- debug(20, 1) ("MemObject->p_rtt: %d\n",
- mem->p_rtt);
debug(20, 1) ("MemObject->start_ping: %d.%06d\n",
mem->start_ping.tv_sec,
mem->start_ping.tv_usec);
int n_replies_expected;
int timeout;
int w_rtt;
+ int p_rtt;
};
struct _HierarchyLogEntry {
struct _MemObject {
mem_hdr *data;
char *e_swap_buf;
- int w_rtt; /* weighted RTT in msec */
- peer *e_pings_closest_parent; /* parent with best RTT to source */
- int p_rtt; /* parent's RTT to source */
int e_swap_buf_len;
unsigned char pending_list_size;
int e_current_len;
typedef unsigned int HASHHASH _PARAMS((const char *, unsigned int));
typedef void IDCB _PARAMS((void *));
typedef void IPH _PARAMS((const ipcache_addrs *, void *));
-typedef void IRCB _PARAMS((peer *, peer_t, icp_opcode, void *data));
+typedef void IRCB _PARAMS((peer *, peer_t, icp_common_t *, void *data));
typedef void PSC _PARAMS((peer *, void *));
typedef void RH _PARAMS((void *data, char *result));