icp_v2.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2022 The Squid Software Foundation and contributors
3  *
4  * Squid software is distributed under GPLv2+ license and includes
5  * contributions from numerous individuals and organizations.
6  * Please see the COPYING and CONTRIBUTORS files for details.
7  */
8 
9 /* DEBUG: section 12 Internet Cache Protocol (ICP) */
10 
16 #include "squid.h"
17 #include "AccessLogEntry.h"
18 #include "acl/Acl.h"
19 #include "acl/FilledChecklist.h"
20 #include "client_db.h"
21 #include "comm.h"
22 #include "comm/Connection.h"
23 #include "comm/Loops.h"
24 #include "comm/UdpOpenDialer.h"
25 #include "fd.h"
26 #include "HttpRequest.h"
27 #include "icmp/net_db.h"
28 #include "ICP.h"
29 #include "ip/Address.h"
30 #include "ip/tools.h"
31 #include "ipcache.h"
32 #include "md5.h"
33 #include "multicast.h"
34 #include "neighbors.h"
35 #include "refresh.h"
36 #include "rfc1738.h"
37 #include "SquidConfig.h"
38 #include "StatCounters.h"
39 #include "Store.h"
40 #include "store_key_md5.h"
41 #include "tools.h"
42 #include "wordlist.h"
43 
44 #include <cerrno>
45 
48 public:
50  icp_common_t *msg = nullptr;
51  DelayedUdpSend *next = nullptr;
53  struct timeval queue_time = {};
54 };
55 
56 static void icpIncomingConnectionOpened(const Comm::ConnectionPointer &conn, int errNo);
57 
59 static void icpLogIcp(const Ip::Address &, const LogTags_ot, int, const char *, const int, AccessLogEntryPointer &);
60 
62 static void icpHandleIcpV2(int, Ip::Address &, char *, int);
63 
65 static void icpCount(void *, int, size_t, int);
66 
68 
69 static int icpUdpSend(int fd, const Ip::Address &to, icp_common_t * msg, int delay, AccessLogEntryPointer al);
70 
71 static void
72 icpSyncAle(AccessLogEntryPointer &al, const Ip::Address &caddr, const char *url, int len, int delay)
73 {
74  if (!al)
75  al = new AccessLogEntry();
76  al->icp.opcode = ICP_QUERY;
77  al->cache.caddr = caddr;
78  al->url = url;
79  al->setVirginUrlForMissingRequest(al->url);
80  // XXX: move to use icp.clientReply instead
81  al->http.clientReplySz.payloadData = len;
82  al->cache.start_time = current_time;
83  al->cache.start_time.tv_sec -= delay;
84  al->cache.trTime.tv_sec = delay;
85  al->cache.trTime.tv_usec = 0;
86 }
87 
96 
101 
102 /* icp_common_t */
104  opcode(ICP_INVALID), version(0), length(0), reqnum(0),
105  flags(0), pad(0), shostid(0)
106 {}
107 
108 icp_common_t::icp_common_t(char *buf, unsigned int len) :
109  opcode(ICP_INVALID), version(0), reqnum(0), flags(0), pad(0), shostid(0)
110 {
111  if (len < sizeof(icp_common_t)) {
112  /* mark as invalid */
113  length = len + 1;
114  return;
115  }
116 
117  memcpy(this, buf, sizeof(icp_common_t));
118  /*
119  * Convert network order sensitive fields
120  */
121  length = ntohs(length);
122  reqnum = ntohl(reqnum);
123  flags = ntohl(flags);
124  pad = ntohl(pad);
125 }
126 
129 {
130  if (opcode > static_cast<char>(icp_opcode::ICP_END))
131  return ICP_INVALID;
132 
133  return static_cast<icp_opcode>(opcode);
134 }
135 
136 /* ICPState */
137 
139  header(aHeader),
140  request(aRequest),
141  fd(-1),
142  url(NULL)
143 {
145 }
146 
148 {
149  safe_free(url);
151 }
152 
153 bool
155 {
156  const auto e = storeGetPublic(url, Http::METHOD_GET);
157 
158  const auto hit = e && confirmAndPrepHit(*e);
159 
160  if (e)
161  e->abandon(__FUNCTION__);
162 
163  return hit;
164 }
165 
166 bool
168 {
169  if (!e.validToSend())
170  return false;
171 
173  return false;
174 
175  if (e.hittingRequiresCollapsing() && !startCollapsingOn(e, false))
176  return false;
177 
178  return true;
179 }
180 
181 LogTags *
183 {
184  // calling icpSyncAle(LOG_TAG_NONE) here would not change cache.code
185  if (!al)
186  al = new AccessLogEntry();
187  return &al->cache.code;
188 }
189 
190 void
192 {
193  checklist.setRequest(request);
194  icpSyncAle(al, from, url, 0, 0);
195  checklist.al = al;
196 }
197 
198 /* End ICPState */
199 
200 /* ICP2State */
201 
203 class ICP2State: public ICPState
204 {
205 
206 public:
207  ICP2State(icp_common_t & aHeader, HttpRequest *aRequest):
208  ICPState(aHeader, aRequest),rtt(0),src_rtt(0),flags(0) {}
209 
210  ~ICP2State();
211 
212  int rtt;
213  int src_rtt;
214  uint32_t flags;
215 };
216 
218 {}
219 
220 /* End ICP2State */
221 
223 static void
224 icpLogIcp(const Ip::Address &caddr, const LogTags_ot logcode, const int len, const char *url, int delay, AccessLogEntry::Pointer &al)
225 {
226  assert(logcode != LOG_TAG_NONE);
227 
228  // Optimization: No premature (ALE creation in) icpSyncAle().
229  if (al) {
230  icpSyncAle(al, caddr, url, len, delay);
231  al->cache.code.update(logcode);
232  }
233 
234  if (logcode == LOG_ICP_QUERY)
235  return; // we never log queries
236 
237  if (!Config.onoff.log_udp) {
238  clientdbUpdate(caddr, al ? al->cache.code : LogTags(logcode), AnyP::PROTO_ICP, len);
239  return;
240  }
241 
242  if (!al) {
243  // The above attempt to optimize ALE creation has failed. We do need it.
244  icpSyncAle(al, caddr, url, len, delay);
245  al->cache.code.update(logcode);
246  }
247  clientdbUpdate(caddr, al->cache.code, AnyP::PROTO_ICP, len);
248  accessLogLog(al, NULL);
249 }
250 
252 static void
253 icpUdpSendQueue(int fd, void *)
254 {
255  DelayedUdpSend *q;
256 
257  while ((q = IcpQueueHead) != NULL) {
258  int delay = tvSubUsec(q->queue_time, current_time);
259  /* increment delay to prevent looping */
260  const int x = icpUdpSend(fd, q->address, q->msg, ++delay, q->ale);
261  IcpQueueHead = q->next;
262  delete q;
263 
264  if (x < 0)
265  break;
266  }
267 }
268 
269 icp_common_t *
271  icp_opcode opcode,
272  int flags,
273  const char *url,
274  int reqnum,
275  int pad)
276 {
277  char *buf = NULL;
278  icp_common_t *headerp = NULL;
279  char *urloffset = NULL;
280  int buf_len;
281  buf_len = sizeof(icp_common_t) + strlen(url) + 1;
282 
283  if (opcode == ICP_QUERY)
284  buf_len += sizeof(uint32_t);
285 
286  buf = (char *) xcalloc(buf_len, 1);
287 
288  headerp = (icp_common_t *) (void *) buf;
289 
290  headerp->opcode = (char) opcode;
291 
292  headerp->version = ICP_VERSION_CURRENT;
293 
294  headerp->length = (uint16_t) htons(buf_len);
295 
296  headerp->reqnum = htonl(reqnum);
297 
298  headerp->flags = htonl(flags);
299 
300  headerp->pad = htonl(pad);
301 
302  headerp->shostid = 0;
303 
304  urloffset = buf + sizeof(icp_common_t);
305 
306  if (opcode == ICP_QUERY)
307  urloffset += sizeof(uint32_t);
308 
309  memcpy(urloffset, url, strlen(url));
310 
311  return (icp_common_t *)buf;
312 }
313 
314 // TODO: Move retries to icpCreateAndSend(); the other caller does not retry.
317 static int
318 icpUdpSend(int fd,
319  const Ip::Address &to,
320  icp_common_t * msg,
321  int delay,
323 {
324  int x;
325  int len;
326  len = (int) ntohs(msg->length);
327  debugs(12, 5, "icpUdpSend: FD " << fd << " sending " <<
328  icp_opcode_str[msg->opcode] << ", " << len << " bytes to " << to);
329 
330  x = comm_udp_sendto(fd, to, msg, len);
331 
332  if (x >= 0) {
333  /* successfully written */
334  const auto logcode = icpLogFromICPCode(static_cast<icp_opcode>(msg->opcode));
335  icpLogIcp(to, logcode, len, (char *) (msg + 1), delay, al);
336  icpCount(msg, SENT, (size_t) len, delay);
337  safe_free(msg);
338  } else if (0 == delay) {
339  /* send failed, but queue it */
340  const auto queue = new DelayedUdpSend();
341  queue->address = to;
342  queue->msg = msg;
343  queue->queue_time = current_time;
344  queue->ale = al;
345 
346  if (IcpQueueHead == NULL) {
347  IcpQueueHead = queue;
348  IcpQueueTail = queue;
349  } else if (IcpQueueTail == IcpQueueHead) {
350  IcpQueueTail = queue;
351  IcpQueueHead->next = queue;
352  } else {
353  IcpQueueTail->next = queue;
354  IcpQueueTail = queue;
355  }
356 
359  } else {
360  /* don't queue it */
361  // XXX: safe_free(msg)
363  }
364 
365  return x;
366 }
367 
376 {
377  /* if store is rebuilding, return a UDP_MISS_NOFETCH */
378 
381  return ICP_MISS_NOFETCH;
382  }
383 
384  return ICP_ERR;
385 }
386 
387 static LogTags_ot
389 {
390  if (opcode == ICP_ERR)
391  return LOG_UDP_INVALID;
392 
393  if (opcode == ICP_DENIED)
394  return LOG_UDP_DENIED;
395 
396  if (opcode == ICP_HIT)
397  return LOG_UDP_HIT;
398 
399  if (opcode == ICP_MISS)
400  return LOG_UDP_MISS;
401 
402  if (opcode == ICP_MISS_NOFETCH)
403  return LOG_UDP_MISS_NOFETCH;
404 
405  if (opcode == ICP_DECHO)
406  return LOG_ICP_QUERY;
407 
408  if (opcode == ICP_QUERY)
409  return LOG_ICP_QUERY;
410 
411  fatal("expected ICP opcode\n");
412 
413  return LOG_UDP_INVALID;
414 }
415 
416 void
417 icpCreateAndSend(icp_opcode opcode, int flags, char const *url, int reqnum, int pad, int fd, const Ip::Address &from, AccessLogEntry::Pointer al)
418 {
419  // update potentially shared ALE ASAP; the ICP query itself may be delayed
420  if (al)
421  al->cache.code.update(icpLogFromICPCode(opcode));
422  icp_common_t *reply = icp_common_t::CreateMessage(opcode, flags, url, reqnum, pad);
423  icpUdpSend(fd, from, reply, 0, al);
424 }
425 
426 void
427 icpDenyAccess(Ip::Address &from, char *url, int reqnum, int fd)
428 {
429  debugs(12, 2, "icpDenyAccess: Access Denied for " << from << " by " << AclMatchedName << ".");
430 
431  if (clientdbCutoffDenied(from)) {
432  /*
433  * count this DENIED query in the clientdb, even though
434  * we're not sending an ICP reply...
435  */
437  } else {
438  icpCreateAndSend(ICP_DENIED, 0, url, reqnum, 0, fd, from, nullptr);
439  }
440 }
441 
442 bool
444 {
445  /* absent any explicit rules, we deny all */
446  if (!Config.accessList.icp)
447  return false;
448 
449  ACLFilledChecklist checklist(Config.accessList.icp, icp_request, NULL);
450  checklist.src_addr = from;
451  checklist.my_addr.setNoAddr();
452  return checklist.fastCheck().allowed();
453 }
454 
455 HttpRequest *
456 icpGetRequest(char *url, int reqnum, int fd, Ip::Address &from)
457 {
458  if (strpbrk(url, w_space)) {
459  url = rfc1738_escape(url);
460  icpCreateAndSend(ICP_ERR, 0, rfc1738_escape(url), reqnum, 0, fd, from, nullptr);
461  return NULL;
462  }
463 
464  const auto mx = MasterXaction::MakePortless<XactionInitiator::initIcp>();
465  auto *result = HttpRequest::FromUrlXXX(url, mx);
466  if (!result)
467  icpCreateAndSend(ICP_ERR, 0, url, reqnum, 0, fd, from, nullptr);
468 
469  return result;
470 
471 }
472 
473 static void
474 doV2Query(int fd, Ip::Address &from, char *buf, icp_common_t header)
475 {
476  int rtt = 0;
477  int src_rtt = 0;
478  uint32_t flags = 0;
479  /* We have a valid packet */
480  char *url = buf + sizeof(icp_common_t) + sizeof(uint32_t);
481  HttpRequest *icp_request = icpGetRequest(url, header.reqnum, fd, from);
482 
483  if (!icp_request)
484  return;
485 
486  HTTPMSGLOCK(icp_request);
487 
488  if (!icpAccessAllowed(from, icp_request)) {
489  icpDenyAccess(from, url, header.reqnum, fd);
490  HTTPMSGUNLOCK(icp_request);
491  return;
492  }
493 #if USE_ICMP
494  if (header.flags & ICP_FLAG_SRC_RTT) {
495  rtt = netdbHostRtt(icp_request->url.host());
496  int hops = netdbHostHops(icp_request->url.host());
497  src_rtt = ((hops & 0xFFFF) << 16) | (rtt & 0xFFFF);
498 
499  if (rtt)
500  flags |= ICP_FLAG_SRC_RTT;
501  }
502 #endif /* USE_ICMP */
503 
504  /* The peer is allowed to use this cache */
505  ICP2State state(header, icp_request);
506  state.fd = fd;
507  state.from = from;
508  state.url = xstrdup(url);
509  state.flags = flags;
510  state.rtt = rtt;
511  state.src_rtt = src_rtt;
512 
513  icp_opcode codeToSend;
514 
515  if (state.isHit()) {
516  codeToSend = ICP_HIT;
517  } else {
518 #if USE_ICMP
519  if (Config.onoff.test_reachability && state.rtt == 0) {
520  if ((state.rtt = netdbHostRtt(state.request->url.host())) == 0)
521  netdbPingSite(state.request->url.host());
522  }
523 #endif /* USE_ICMP */
524 
525  if (icpGetCommonOpcode() != ICP_ERR)
526  codeToSend = icpGetCommonOpcode();
527  else if (Config.onoff.test_reachability && rtt == 0)
528  codeToSend = ICP_MISS_NOFETCH;
529  else
530  codeToSend = ICP_MISS;
531  }
532 
533  icpCreateAndSend(codeToSend, flags, url, header.reqnum, src_rtt, fd, from, state.al);
534 
535  HTTPMSGUNLOCK(icp_request);
536 }
537 
538 void
540 {
541  if (neighbors_do_private_keys && reqnum == 0) {
542  debugs(12, DBG_CRITICAL, "icpHandleIcpV2: Neighbor " << from << " returned reqnum = 0");
543  debugs(12, DBG_CRITICAL, "icpHandleIcpV2: Disabling use of private keys");
545  }
546 
547  char *url = buf + sizeof(icp_common_t);
548  debugs(12, 3, "icpHandleIcpV2: " << icp_opcode_str[opcode] << " from " << from << " for '" << url << "'");
549 
550  const cache_key *key = icpGetCacheKey(url, (int) reqnum);
551  /* call neighborsUdpAck even if ping_status != PING_WAITING */
552  neighborsUdpAck(key, this, from);
553 }
554 
555 static void
556 icpHandleIcpV2(int fd, Ip::Address &from, char *buf, int len)
557 {
558  if (len <= 0) {
559  debugs(12, 3, "icpHandleIcpV2: ICP message is too small");
560  return;
561  }
562 
563  icp_common_t header(buf, len);
564  /*
565  * Length field should match the number of bytes read
566  */
567 
568  if (len != header.length) {
569  debugs(12, 3, "icpHandleIcpV2: ICP message is too small");
570  return;
571  }
572 
573  debugs(12, 5, "OPCODE " << icp_opcode_str[header.getOpCode()] << '=' << uint8_t(header.opcode));
574 
575  switch (header.opcode) {
576 
577  case ICP_QUERY:
578  /* We have a valid packet */
579  doV2Query(fd, from, buf, header);
580  break;
581 
582  case ICP_HIT:
583 
584  case ICP_DECHO:
585 
586  case ICP_MISS:
587 
588  case ICP_DENIED:
589 
590  case ICP_MISS_NOFETCH:
591  header.handleReply(buf, from);
592  break;
593 
594  case ICP_INVALID:
595 
596  case ICP_ERR:
597  break;
598 
599  default:
600  debugs(12, DBG_CRITICAL, "ERROR: icpHandleIcpV2: Unknown opcode: " << header.opcode << " from " << from);
601 
602  break;
603  }
604 }
605 
606 #ifdef ICP_PKT_DUMP
607 static void
608 icpPktDump(icp_common_t * pkt)
609 {
610  Ip::Address a;
611 
612  debugs(12, 9, "opcode: " << std::setw(3) << pkt->opcode << " " << icp_opcode_str[pkt->opcode]);
613  debugs(12, 9, "version: "<< std::left << std::setw(8) << pkt->version);
614  debugs(12, 9, "length: "<< std::left << std::setw(8) << ntohs(pkt->length));
615  debugs(12, 9, "reqnum: "<< std::left << std::setw(8) << ntohl(pkt->reqnum));
616  debugs(12, 9, "flags: "<< std::left << std::hex << std::setw(8) << ntohl(pkt->flags));
617  a = (struct in_addr)pkt->shostid;
618  debugs(12, 9, "shostid: " << a );
619  debugs(12, 9, "payload: " << (char *) pkt + sizeof(icp_common_t));
620 }
621 
622 #endif
623 
624 void
625 icpHandleUdp(int sock, void *)
626 {
627  int *N = &incoming_sockets_accepted;
628 
629  Ip::Address from;
630  LOCAL_ARRAY(char, buf, SQUID_UDP_SO_RCVBUF);
631  int len;
632  int icp_version;
633  int max = INCOMING_UDP_MAX;
635 
636  while (max) {
637  --max;
638  len = comm_udp_recvfrom(sock,
639  buf,
641  0,
642  from);
643 
644  if (len == 0)
645  break;
646 
647  if (len < 0) {
648  int xerrno = errno;
649  if (ignoreErrno(xerrno))
650  break;
651 
652 #if _SQUID_LINUX_
653  /* Some Linux systems seem to set the FD for reading and then
654  * return ECONNREFUSED when sendto() fails and generates an ICMP
655  * port unreachable message. */
656  /* or maybe an EHOSTUNREACH "No route to host" message */
657  if (xerrno != ECONNREFUSED && xerrno != EHOSTUNREACH)
658 #endif
659  debugs(50, DBG_IMPORTANT, "icpHandleUdp: FD " << sock << " recvfrom: " << xstrerr(xerrno));
660 
661  break;
662  }
663 
664  ++(*N);
665  icpCount(buf, RECV, (size_t) len, 0);
666  buf[len] = '\0';
667  debugs(12, 4, "icpHandleUdp: FD " << sock << ": received " <<
668  (unsigned long int)len << " bytes from " << from);
669 
670 #ifdef ICP_PACKET_DUMP
671 
672  icpPktDump(buf);
673 #endif
674 
675  if ((size_t) len < sizeof(icp_common_t)) {
676  debugs(12, 4, "icpHandleUdp: Ignoring too-small UDP packet");
677  break;
678  }
679 
680  icp_version = (int) buf[1]; /* cheat! */
681 
682  if (icpOutgoingConn->local == from)
683  // ignore ICP packets which loop back (multicast usually)
684  debugs(12, 4, "icpHandleUdp: Ignoring UDP packet sent by myself");
685  else if (icp_version == ICP_VERSION_2)
686  icpHandleIcpV2(sock, from, buf, len);
687  else if (icp_version == ICP_VERSION_3)
688  icpHandleIcpV3(sock, from, buf, len);
689  else
690  debugs(12, DBG_IMPORTANT, "WARNING: Unused ICP version " << icp_version <<
691  " received from " << from);
692  }
693 }
694 
695 void
697 {
698  uint16_t port;
699 
700  if ((port = Config.Port.icp) <= 0)
701  return;
702 
705  icpIncomingConn->local.port(port);
706 
707  if (!Ip::EnableIpv6 && !icpIncomingConn->local.setIPv4()) {
708  debugs(12, DBG_CRITICAL, "ERROR: IPv6 is disabled. " << icpIncomingConn->local << " is not an IPv4 address.");
709  fatal("ICP port cannot be opened.");
710  }
711  /* split-stack for now requires default IPv4-only ICP */
712  if (Ip::EnableIpv6&IPV6_SPECIAL_SPLITSTACK && icpIncomingConn->local.isAnyAddr()) {
713  icpIncomingConn->local.setIPv4();
714  }
715 
716  AsyncCall::Pointer call = asyncCall(12, 2,
717  "icpIncomingConnectionOpened",
719 
720  Ipc::StartListening(SOCK_DGRAM,
721  IPPROTO_UDP,
723  Ipc::fdnInIcpSocket, call);
724 
725  if ( !Config.Addrs.udp_outgoing.isNoAddr() ) {
728  icpOutgoingConn->local.port(port);
729 
730  if (!Ip::EnableIpv6 && !icpOutgoingConn->local.setIPv4()) {
731  debugs(49, DBG_CRITICAL, "ERROR: IPv6 is disabled. " << icpOutgoingConn->local << " is not an IPv4 address.");
732  fatal("ICP port cannot be opened.");
733  }
734  /* split-stack for now requires default IPv4-only ICP */
735  if (Ip::EnableIpv6&IPV6_SPECIAL_SPLITSTACK && icpOutgoingConn->local.isAnyAddr()) {
736  icpOutgoingConn->local.setIPv4();
737  }
738 
739  enter_suid();
740  comm_open_listener(SOCK_DGRAM, IPPROTO_UDP, icpOutgoingConn, "Outgoing ICP Port");
741  leave_suid();
742 
744  fatal("Cannot open Outgoing ICP Port");
745 
746  debugs(12, DBG_CRITICAL, "Sending ICP messages from " << icpOutgoingConn->local);
747 
749  fd_note(icpOutgoingConn->fd, "Outgoing ICP socket");
750  }
751 }
752 
753 static void
755 {
756  if (!Comm::IsConnOpen(conn))
757  fatal("Cannot open ICP Port");
758 
760 
761  for (const wordlist *s = Config.mcast_group_list; s; s = s->next)
762  ipcache_nbgethostbyname(s->key, mcastJoinGroups, NULL); // XXX: pass the conn for mcastJoinGroups usage.
763 
764  debugs(12, DBG_IMPORTANT, "Accepting ICP messages on " << conn->local);
765 
766  fd_note(conn->fd, "Incoming ICP port");
767 
770  debugs(12, DBG_IMPORTANT, "Sending ICP messages from " << icpOutgoingConn->local);
771  }
772 }
773 
778 void
780 {
782  return;
783 
784  debugs(12, DBG_IMPORTANT, "Stop receiving ICP on " << icpIncomingConn->local);
785 
791 
799 
801 }
802 
803 void
805 {
807 
808  if (icpOutgoingConn != NULL) {
809  debugs(12, DBG_IMPORTANT, "Stop sending ICP from " << icpOutgoingConn->local);
811  }
812 }
813 
814 static void
815 icpCount(void *buf, int which, size_t len, int delay)
816 {
817  icp_common_t *icp = (icp_common_t *) buf;
818 
819  if (len < sizeof(*icp))
820  return;
821 
822  if (SENT == which) {
824  statCounter.icp.kbytes_sent += len;
825 
826  if (ICP_QUERY == icp->opcode) {
829  } else {
832  /* this is the sent-reply service time */
834  }
835 
836  if (ICP_HIT == icp->opcode)
838  } else if (RECV == which) {
840  statCounter.icp.kbytes_recv += len;
841 
842  if (ICP_QUERY == icp->opcode) {
845  } else {
848  /* statCounter.icp.querySvcTime set in clientUpdateCounters */
849  }
850 
851  if (ICP_HIT == icp->opcode)
853  }
854 }
855 
856 #define N_QUERIED_KEYS 8192
857 #define N_QUERIED_KEYS_MASK 8191
859 
860 int
862 {
863  static int reqnum = 0;
864 
865  if (++reqnum < 0)
866  reqnum = 1;
867 
869 
870  return reqnum;
871 }
872 
873 const cache_key *
874 icpGetCacheKey(const char *url, int reqnum)
875 {
876  if (neighbors_do_private_keys && reqnum)
877  return queried_keys[reqnum & N_QUERIED_KEYS_MASK];
878 
879  return storeKeyPublic(url, Http::METHOD_GET);
880 }
881 
AccessLogEntryPointer al
Definition: ICP.h:77
void fatal(const char *message)
Definition: fatal.cc:28
const char * xstrerr(int error)
Definition: xstrerror.cc:83
void icpHandleIcpV3(int, Ip::Address &, char *, int)
Definition: icp_v3.cc:71
bool icpAccessAllowed(Ip::Address &from, HttpRequest *icp_request)
Definition: icp_v2.cc:443
char * url
Definition: ICP.h:76
uint32_t reqnum
Definition: ICP.h:44
AccessLogEntryPointer ale
sender's master transaction summary
Definition: icp_v2.cc:52
void * xcalloc(size_t n, size_t sz)
Definition: xalloc.cc:71
icp_common_t * msg
ICP message with network byte order fields.
Definition: icp_v2.cc:50
int incoming_sockets_accepted
#define DBG_CRITICAL
Definition: Stream.h:40
@ ICP_ERR
Definition: icp_opcode.h:19
struct SquidConfig::@97 Port
int replies_dropped
Definition: StatCounters.h:75
AnyP::Uri url
the request URI
Definition: HttpRequest.h:115
Ip::Address udp_incoming
Definition: SquidConfig.h:240
Ip::Address src_addr
#define LOCAL_ARRAY(type, name, size)
Definition: squid.h:75
ByteCounter r_kbytes_recv
Definition: StatCounters.h:81
unsigned char cache_key
Store key.
Definition: forward.h:29
void fd_note(int fd, const char *s)
Definition: fd.cc:216
virtual LogTags * loggingTags() const override
Definition: icp_v2.cc:182
void icpDenyAccess(Ip::Address &from, char *url, int reqnum, int fd)
Definition: icp_v2.cc:427
const cache_key * storeKeyPublic(const char *url, const HttpRequestMethod &method, const KeyScope keyScope)
struct SquidConfig::@105 Addrs
int fd
Definition: ICP.h:73
IPH mcastJoinGroups
unsigned short icp
Definition: SquidConfig.h:139
static void icpUdpSendQueue(int fd, void *)
Definition: icp_v2.cc:253
ICPState(icp_common_t &aHeader, HttpRequest *aRequest)
Definition: icp_v2.cc:138
int comm_udp_sendto(int fd, const Ip::Address &to_addr, const void *buf, int len)
Definition: comm.cc:890
int refreshCheckICP(const StoreEntry *entry, HttpRequest *request)
Definition: refresh.cc:587
StatHist replySvcTime
Definition: StatCounters.h:83
int replies_queued
Definition: StatCounters.h:74
Comm::ConnectionPointer icpOutgoingConn
Definition: icp_v2.cc:100
#define xstrdup
@ ICP_DECHO
Definition: icp_opcode.h:26
void clientdbUpdate(const Ip::Address &addr, const LogTags &ltype, AnyP::ProtocolType p, size_t size)
Definition: client_db.cc:138
int test_reachability
Definition: SquidConfig.h:294
struct timeval queue_time
queuing timestamp
Definition: icp_v2.cc:53
static void icpHandleIcpV2(int, Ip::Address &, char *, int)
Definition: icp_v2.cc:556
AccessLogEntry::Pointer al
info for the future access.log, and external ACL
Acl::Answer const & fastCheck()
Definition: Checklist.cc:332
bool IsConnOpen(const Comm::ConnectionPointer &conn)
Definition: Connection.cc:27
void accessLogLog(const AccessLogEntryPointer &, ACLChecklist *)
Definition: access_log.cc:147
#define rfc1738_escape(x)
Definition: rfc1738.h:52
void icpCreateAndSend(icp_opcode opcode, int flags, char const *url, int reqnum, int pad, int fd, const Ip::Address &from, AccessLogEntry::Pointer al)
Definition: icp_v2.cc:417
void HTTPMSGUNLOCK(M *&a)
Definition: Message.h:150
int netdbHostRtt(const char *host)
Definition: net_db.cc:1055
time_t hit_only_mode_until
HttpRequest * request
Definition: ICP.h:72
#define w_space
static int port
Definition: ldap_backend.cc:69
static void icpCount(void *, int, size_t, int)
Definition: icp_v2.cc:815
A const & max(A const &lhs, A const &rhs)
int clientdbCutoffDenied(const Ip::Address &addr)
Definition: client_db.cc:209
ByteCounter kbytes_sent
Definition: StatCounters.h:76
@ fdnInIcpSocket
Definition: FdNotes.h:24
unsigned short length
Definition: ICP.h:42
HttpRequest * icpGetRequest(char *url, int reqnum, int fd, Ip::Address &from)
Definition: icp_v2.cc:456
#define ICP_FLAG_SRC_RTT
Definition: defines.h:41
int validToSend() const
Definition: store.cc:1331
void comm_open_listener(int sock_type, int proto, Comm::ConnectionPointer &conn, const char *note)
Definition: comm.cc:233
dials a UDP port-opened call
Definition: UdpOpenDialer.h:20
@ ICP_MISS_NOFETCH
Definition: icp_opcode.h:36
const char * AclMatchedName
Definition: Acl.cc:29
void leave_suid(void)
Definition: tools.cc:556
#define SQUID_MD5_DIGEST_LENGTH
Definition: md5.h:66
@ ICP_INVALID
Definition: icp_opcode.h:15
#define INCOMING_UDP_MAX
Definition: Loops.h:50
uint32_t shostid
Definition: ICP.h:48
unsigned char opcode
Definition: ICP.h:38
struct timeval current_time
the current UNIX time in timeval {seconds, microseconds} format
Definition: gadgets.cc:17
DelayedUdpSend * next
invasive FIFO queue of delayed ICP messages
Definition: icp_v2.cc:51
#define NULL
Definition: types.h:166
uint32_t flags
Definition: icp_v2.cc:214
@ LOG_UDP_HIT
Definition: LogTags.h:57
Ip::Address from
Definition: ICP.h:75
void StartListening(int sock_type, int proto, const Comm::ConnectionPointer &listenConn, FdNoteId fdNote, AsyncCall::Pointer &callback)
#define SQUID_UDP_SO_RCVBUF
Definition: squid.h:55
void setNoAddr()
Definition: Address.cc:292
ICP2State(icp_common_t &aHeader, HttpRequest *aRequest)
Definition: icp_v2.cc:207
@ RECV
Definition: enums.h:176
int rtt
Definition: icp_v2.cc:212
void neighborsUdpAck(const cache_key *key, icp_common_t *header, const Ip::Address &from)
Definition: neighbors.cc:1011
@ LOG_TAG_NONE
Definition: LogTags.h:38
icp_opcode icpGetCommonOpcode()
Definition: icp_v2.cc:375
virtual ~ICPState()
Definition: icp_v2.cc:147
void ipcache_nbgethostbyname(const char *name, IPH *handler, void *handlerData)
Definition: ipcache.cc:599
bool isHit() const
whether the cache contains the requested entry
Definition: icp_v2.cc:154
const cache_key * icpGetCacheKey(const char *url, int reqnum)
Definition: icp_v2.cc:874
Ip::Address udp_outgoing
Definition: SquidConfig.h:241
static DelayedUdpSend * IcpQueueTail
Definition: icp_v2.cc:95
void icpHandleUdp(int sock, void *)
Definition: icp_v2.cc:625
static LogTags_ot icpLogFromICPCode(icp_opcode)
Definition: icp_v2.cc:388
~ICP2State()
Definition: icp_v2.cc:217
#define safe_free(x)
Definition: xalloc.h:73
void icpConnectionShutdown(void)
Definition: icp_v2.cc:779
static void doV2Query(int fd, Ip::Address &from, char *buf, icp_common_t header)
Definition: icp_v2.cc:474
void count(double val)
Definition: StatHist.cc:55
cache_key * storeKeyCopy(cache_key *dst, const cache_key *src)
int neighbors_do_private_keys
int conn
the current server connection FD
Definition: Transport.cc:26
virtual void fillChecklist(ACLFilledChecklist &) const override
configure the given checklist (to reflect the current transaction state)
Definition: icp_v2.cc:191
@ LOG_UDP_INVALID
Definition: LogTags.h:60
#define assert(EX)
Definition: assert.h:19
SSL Connection
Definition: Session.h:45
class AccessLogEntry::CacheDetails cache
#define IPV6_SPECIAL_SPLITSTACK
Definition: tools.h:22
static void icpSyncAle(AccessLogEntryPointer &al, const Ip::Address &caddr, const char *url, int len, int delay)
Definition: icp_v2.cc:72
static int version
@ ICP_HIT
Definition: icp_opcode.h:17
void HTTPMSGLOCK(Http::Message *a)
Definition: Message.h:161
#define COMM_SELECT_READ
Definition: defines.h:24
icp_opcode getOpCode() const
Definition: icp_v2.cc:128
static int store_dirs_rebuilding
the number of cache_dirs being rebuilt; TODO: move to Disks::Rebuilding
Definition: Controller.h:139
time_t squid_curtime
Definition: stub_libtime.cc:20
bool isNoAddr() const
Definition: Address.cc:284
Comm::ConnectionPointer icpIncomingConn
Definition: icp_v2.cc:98
wordlist * next
Definition: wordlist.h:33
#define ICP_VERSION_3
Definition: defines.h:45
int tvSubUsec(struct timeval t1, struct timeval t2)
Definition: gadgets.cc:37
bool startCollapsingOn(const StoreEntry &, const bool doingRevalidation) const
Definition: store_client.cc:65
int ignoreErrno(int ierrno)
Definition: comm.cc:1412
static void icpLogIcp(const Ip::Address &, const LogTags_ot, int, const char *, const int, AccessLogEntryPointer &)
updates ALE (if any) and logs the transaction (if needed)
Definition: icp_v2.cc:224
Ip::Address address
remote peer (which may not be a cache_peer)
Definition: icp_v2.cc:49
@ ICP_QUERY
Definition: icp_opcode.h:16
@ ICP_MISS
Definition: icp_opcode.h:18
int opt_reload_hit_only
unsigned char version
Definition: ICP.h:40
void icpOpenPorts(void)
Definition: icp_v2.cc:696
struct SquidConfig::@111 accessList
struct StatCounters::@129 icp
int netdbHostHops(const char *host)
Definition: net_db.cc:1039
bool allowed() const
Definition: Acl.h:149
uint32_t pad
Definition: ICP.h:46
wordlist * mcast_group_list
Definition: SquidConfig.h:251
a delayed icpUdpSend() call
Definition: icp_v2.cc:47
struct SquidConfig::@110 onoff
@ SENT
Definition: enums.h:175
ByteCounter q_kbytes_sent
Definition: StatCounters.h:77
void SetSelect(int, unsigned int, PF *, void *, time_t)
Mark an FD to be watched for its IO status.
Definition: ModDevPoll.cc:223
#define N_QUERIED_KEYS
Definition: icp_v2.cc:856
void setRequest(HttpRequest *)
configure client request-related fields for the first time
void icpClosePorts(void)
Definition: icp_v2.cc:804
void handleReply(char *buf, Ip::Address &from)
Definition: icp_v2.cc:539
static HttpRequest * FromUrlXXX(const char *url, const MasterXaction::Pointer &, const HttpRequestMethod &method=Http::METHOD_GET)
Definition: HttpRequest.cc:529
ByteCounter q_kbytes_recv
Definition: StatCounters.h:80
static int icpUdpSend(int fd, const Ip::Address &to, icp_common_t *msg, int delay, AccessLogEntryPointer al)
Definition: icp_v2.cc:318
icp_common_t()
Definition: icp_v2.cc:103
void enter_suid(void)
Definition: tools.cc:620
LogTags_ot
Definition: LogTags.h:37
#define DBG_IMPORTANT
Definition: Stream.h:41
AsyncCall * asyncCall(int aDebugSection, int aDebugLevel, const char *aName, const Dialer &aDialer)
Definition: AsyncCall.h:154
@ ICP_END
Definition: icp_opcode.h:39
StoreEntry * storeGetPublic(const char *uri, const HttpRequestMethod &method)
Definition: store.cc:479
static cache_key queried_keys[N_QUERIED_KEYS][SQUID_MD5_DIGEST_LENGTH]
Definition: icp_v2.cc:858
static void icpIncomingConnectionOpened(const Comm::ConnectionPointer &conn, int errNo)
Definition: icp_v2.cc:754
@ ICP_DENIED
Definition: icp_opcode.h:37
static icp_common_t * CreateMessage(icp_opcode opcode, int flags, const char *url, int reqnum, int pad)
Definition: icp_v2.cc:270
int comm_udp_recvfrom(int fd, void *buf, size_t len, int flags, Ip::Address &from)
Definition: comm.cc:122
bool hittingRequiresCollapsing() const
whether this entry can feed collapsed requests and only them
Definition: Store.h:214
@ LOG_UDP_MISS_NOFETCH
Definition: LogTags.h:61
uint32_t flags
Definition: ICP.h:45
#define ICP_VERSION_2
Definition: defines.h:44
#define ICP_VERSION_CURRENT
Definition: defines.h:46
icp_opcode
Definition: icp_opcode.h:13
@ METHOD_GET
Definition: MethodType.h:25
@ LOG_UDP_DENIED
Definition: LogTags.h:59
int EnableIpv6
Whether IPv6 is supported and type of support.
Definition: tools.h:25
#define N_QUERIED_KEYS_MASK
Definition: icp_v2.cc:857
void host(const char *src)
Definition: Uri.cc:99
void netdbPingSite(const char *hostname)
Definition: net_db.cc:907
struct _request * request(char *urlin)
Definition: tcp-banger2.c:291
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:196
ByteCounter kbytes_recv
Definition: StatCounters.h:79
#define COMM_SELECT_WRITE
Definition: defines.h:25
Definition: ICP.h:62
int src_rtt
Definition: icp_v2.cc:213
int icpSetCacheKey(const cache_key *key)
Definition: icp_v2.cc:861
@ PROTO_ICP
Definition: ProtocolType.h:33
const char * icp_opcode_str[]
@ LOG_ICP_QUERY
Definition: LogTags.h:62
class SquidConfig Config
Definition: SquidConfig.cc:12
int unsigned int
Definition: stub_fd.cc:19
StatCounters statCounter
Definition: StatCounters.cc:12
@ LOG_UDP_MISS
Definition: LogTags.h:58
int icp_hit_stale
Definition: SquidConfig.h:288
ByteCounter r_kbytes_sent
Definition: StatCounters.h:78
static DelayedUdpSend * IcpQueueHead
Definition: icp_v2.cc:93
bool confirmAndPrepHit(const StoreEntry &) const
either confirms and starts processing a cache hit or returns false
Definition: icp_v2.cc:167

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors