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

 

Introduction

Documentation

Support

Miscellaneous