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

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors