/* lookup the digest of a given peer */ lookup_t peerDigestLookup(peer * p, request_t * request) { #if USE_CACHE_DIGESTS const cache_key *key = request ? storeKeyPublicByRequest(request) : NULL; assert(p); assert(request); debug(15, 5) ("peerDigestLookup: peer %s\n", p->name); /* does the peeer have a valid digest? */ if (!p->digest) { debug(15, 5) ("peerDigestLookup: gone!\n"); return LOOKUP_NONE; } else if (!peerHTTPOkay(p, request)) { debug(15, 5) ("peerDigestLookup: !peerHTTPOkay\n"); return LOOKUP_NONE; } else if (!p->digest->flags.needed) { debug(15, 5) ("peerDigestLookup: note need\n"); peerDigestNeeded(p->digest); return LOOKUP_NONE; } else if (!p->digest->flags.usable) { debug(15, 5) ("peerDigestLookup: !ready && %srequested\n", p->digest->flags.requested ? "" : "!"); return LOOKUP_NONE; } debug(15, 5) ("peerDigestLookup: OK to lookup peer %s\n", p->name); assert(p->digest->cd); /* does digest predict a hit? */ if (!cacheDigestTest(p->digest->cd, key)) return LOOKUP_MISS; debug(15, 5) ("peerDigestLookup: peer %s says HIT!\n", p->name); return LOOKUP_HIT; #endif return LOOKUP_NONE; }
peer * getRoundRobinParent(request_t * request) { peer *p; peer *q = NULL; for (p = Config.peers; p; p = p->next) { if (!p->options.roundrobin) continue; if (neighborType(p, request) != PEER_PARENT) continue; if (!peerHTTPOkay(p, request)) continue; if (p->weight == 0) continue; if (q) { if (p->weight == q->weight) { if (q->rr_count < p->rr_count) continue; } else if ((double) q->rr_count / q->weight < (double) p->rr_count / p->weight) { continue; } } q = p; } if (q) q->rr_count++; debug(15, 3) ("getRoundRobinParent: returning %s\n", q ? q->host : "NULL"); return q; }
/* ignoreMulticastReply * * * We want to ignore replies from multicast peers if the * * cache_host_domain rules would normally prevent the peer * * from being used */ static int ignoreMulticastReply(peer * p, MemObject * mem) { if (p == NULL) return 0; if (!p->options.mcast_responder) return 0; if (peerHTTPOkay(p, mem->request)) return 0; return 1; }
/* * XXX DW thinks this function is equivalent to/redundant with * getFirstUpParent(). peerHTTPOkay() only returns true if the * peer is UP anyway, so this function would not return a * DOWN parent. */ peer * getAnyParent(request_t * request) { peer *p = NULL; for (p = Config.peers; p; p = p->next) { if (neighborType(p, request) != PEER_PARENT) continue; if (!peerHTTPOkay(p, request)) continue; debug(15, 3) ("getAnyParent: returning %s\n", p->name); return p; } debug(15, 3) ("getAnyParent: returning NULL\n"); return NULL; }
peer * getFirstUpParent(request_t * request) { peer *p = NULL; for (p = Config.peers; p; p = p->next) { if (!neighborUp(p)) continue; if (neighborType(p, request) != PEER_PARENT) continue; if (!peerHTTPOkay(p, request)) continue; break; } debug(15, 3) ("getFirstUpParent: returning %s\n", p ? p->name : "NULL"); return p; }
peer * getSingleParent(request_t * request) { peer *p = NULL; peer *q = NULL; for (q = Config.peers; q; q = q->next) { if (!peerHTTPOkay(q, request)) continue; if (neighborType(q, request) != PEER_PARENT) return NULL; /* oops, found SIBLING */ if (p) return NULL; /* oops, found second parent */ p = q; } if (p != NULL && !p->options.no_query) return NULL; debug(15, 3) ("getSingleParent: returning %s\n", p ? p->name : "NULL"); return p; }
peer * netdbClosestParent(request_t * request) { #if USE_ICMP peer *p = NULL; netdbEntry *n; const ipcache_addrs *ia; net_db_peer *h; int i; n = netdbLookupHost(request->host); if (NULL == n) { /* try IP addr */ ia = ipcache_gethostbyname(request->host, 0); if (NULL != ia) n = netdbLookupAddr(ia->in_addrs[ia->cur]); } if (NULL == n) return NULL; if (0 == n->n_peers) return NULL; n->last_use_time = squid_curtime; /* * Find the parent with the least RTT to the origin server. * Make sure we don't return a parent who is farther away than * we are. Note, the n->peers list is pre-sorted by RTT. */ for (i = 0; i < n->n_peers; i++) { h = &n->peers[i]; if (n->rtt > 0) if (n->rtt < h->rtt) break; p = peerFindByName(h->peername); if (NULL == p) /* not found */ continue; if (neighborType(p, request) != PEER_PARENT) continue; if (!peerHTTPOkay(p, request)) /* not allowed */ continue; return p; } #endif return NULL; }
peer * peerUserHashSelectParent(request_t * request) { int k; const char *c; peer *p = NULL; peer *tp; unsigned int user_hash = 0; unsigned int combined_hash; double score; double high_score = 0; const char *key = NULL; if (request->auth_user_request) key = authenticateUserRequestUsername(request->auth_user_request); if (!key) return NULL; /* calculate hash key */ debug(39, 2) ("peerUserHashSelectParent: Calculating hash for %s\n", key); for (c = key; *c != 0; c++) user_hash += ROTATE_LEFT(user_hash, 19) + *c; /* select peer */ for (k = 0; k < n_userhash_peers; k++) { tp = userhash_peers[k]; combined_hash = (user_hash ^ tp->userhash.hash); combined_hash += combined_hash * 0x62531965; combined_hash = ROTATE_LEFT(combined_hash, 21); score = combined_hash * tp->userhash.load_multiplier; debug(39, 3) ("peerUserHashSelectParent: %s combined_hash %u score %.0f\n", tp->name, combined_hash, score); if ((score > high_score) && peerHTTPOkay(tp, request)) { p = tp; high_score = score; } } if (p) debug(39, 2) ("peerUserHashSelectParent: selected %s\n", p->name); return p; }
peer * peerSourceHashSelectParent(request_t * request) { int k; const char *c; peer *p = NULL; peer *tp; unsigned int user_hash = 0; unsigned int combined_hash; double score; double high_score = 0; char *key = NULL; key = inet_ntoa(request->client_addr); /* calculate hash key */ debug(39, 2) ("peerSourceHashSelectParent: Calculating hash for %s\n", key); for (c = key; *c != 0; c++) user_hash += ROTATE_LEFT(user_hash, 19) + *c; /* select peer */ for (k = 0; k < n_sourcehash_peers; k++) { tp = sourcehash_peers[k]; combined_hash = (user_hash ^ tp->sourcehash.hash); combined_hash += combined_hash * 0x62531965; combined_hash = ROTATE_LEFT(combined_hash, 21); score = combined_hash * tp->sourcehash.load_multiplier; debug(39, 3) ("peerSourceHashSelectParent: %s combined_hash %u score %.0f\n", tp->host, combined_hash, score); if ((score > high_score) && peerHTTPOkay(tp, request)) { p = tp; high_score = score; } } if (p) debug(39, 2) ("peerSourceHashSelectParent: selected %s\n", p->host); return p; }