Xaction.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 93 ICAP (RFC 3507) Client */
10 
11 #include "squid.h"
12 #include "acl/FilledChecklist.h"
13 #include "adaptation/icap/Config.h"
16 #include "base/JobWait.h"
17 #include "base/TextException.h"
18 #include "comm.h"
19 #include "comm/Connection.h"
20 #include "comm/ConnOpener.h"
21 #include "comm/Read.h"
22 #include "comm/Write.h"
23 #include "CommCalls.h"
24 #include "error/Detail.h"
25 #include "fde.h"
26 #include "FwdState.h"
27 #include "globals.h"
28 #include "HttpReply.h"
29 #include "icap_log.h"
30 #include "ipcache.h"
31 #include "pconn.h"
32 #include "security/PeerConnector.h"
33 #include "SquidConfig.h"
34 
36 class MyIcapAnswerDialer: public UnaryMemFunT<Adaptation::Icap::Xaction, Security::EncryptorAnswer, Security::EncryptorAnswer&>,
38 {
39 public:
40  MyIcapAnswerDialer(const JobPointer &aJob, Method aMethod):
41  UnaryMemFunT<Adaptation::Icap::Xaction, Security::EncryptorAnswer, Security::EncryptorAnswer&>(aJob, aMethod, Security::EncryptorAnswer()) {}
42 
43  /* Security::PeerConnector::CbDialer API */
44  virtual Security::EncryptorAnswer &answer() { return arg1; }
45 };
46 
47 namespace Ssl
48 {
52 public:
55  const Comm::ConnectionPointer &aServerConn,
56  AsyncCall::Pointer &aCallback,
57  AccessLogEntry::Pointer const &alp,
58  const time_t timeout = 0):
59  AsyncJob("Ssl::IcapPeerConnector"),
60  Security::PeerConnector(aServerConn, aCallback, alp, timeout), icapService(service) {}
61 
62  /* Security::PeerConnector API */
63  virtual bool initialize(Security::SessionPointer &);
64  virtual void noteNegotiationDone(ErrorState *error);
66  return icapService->sslContext;
67  }
68 
69 private:
70  /* Acl::ChecklistFiller API */
71  virtual void fillChecklist(ACLFilledChecklist &) const;
72 
74 };
75 } // namespace Ssl
76 
77 CBDATA_NAMESPACED_CLASS_INIT(Ssl, IcapPeerConnector);
78 
80  AsyncJob(aTypeName),
81  Adaptation::Initiate(aTypeName),
82  icapRequest(NULL),
83  icapReply(NULL),
84  attempts(0),
85  theService(aService),
86  commEof(false),
87  reuseConnection(true),
88  isRetriable(true),
89  isRepeatable(true),
90  ignoreLastWrite(false),
91  waitingForDns(false),
92  alep(new AccessLogEntry),
93  al(*alep)
94 {
95  debugs(93,3, typeName << " constructed, this=" << this <<
96  " [icapx" << id << ']'); // we should not call virtual status() here
97  const auto mx = MasterXaction::MakePortless<XactionInitiator::initAdaptation>();
98  icapRequest = new HttpRequest(mx);
101  memset(&icap_tio_start, 0, sizeof(icap_tio_start));
102  memset(&icap_tio_finish, 0, sizeof(icap_tio_finish));
103 }
104 
106 {
107  debugs(93,3, typeName << " destructed, this=" << this <<
108  " [icapx" << id << ']'); // we should not call virtual status() here
109  HTTPMSGUNLOCK(icapRequest);
110 }
111 
114 {
116  return nil;
117 }
118 
121 {
122  Must(theService != NULL);
123  return *theService;
124 }
125 
127 {
128  debugs(93,5, typeName << (isRetriable ? " from now on" : " still") <<
129  " cannot be retried " << status());
130  isRetriable = false;
131 }
132 
134 {
135  debugs(93,5, typeName << (isRepeatable ? " from now on" : " still") <<
136  " cannot be repeated because " << reason << status());
137  isRepeatable = false;
138 }
139 
141 {
143 }
144 
145 static void
147 {
148  Adaptation::Icap::Xaction *xa = static_cast<Adaptation::Icap::Xaction *>(data);
151  xa->dnsLookupDone(ia);
152 }
153 
154 // TODO: obey service-specific, OPTIONS-reported connection limit
155 void
157 {
158  Must(!haveConnection());
159 
160  Adaptation::Icap::ServiceRep &s = service();
161 
163  disableRetries(); // this will also safely drain pconn pool
164 
165  if (const auto pconn = s.getIdleConnection(isRetriable)) {
166  useTransportConnection(pconn);
167  return;
168  }
169 
170  disableRetries(); // we only retry pconn failures
171 
172  // Attempt to open a new connection...
173  debugs(93,3, typeName << " opens connection to " << s.cfg().host.termedBuf() << ":" << s.cfg().port);
174 
175  // Locate the Service IP(s) to open
176  assert(!waitingForDns);
177  waitingForDns = true; // before the possibly-synchronous ipcache_nbgethostbyname()
179 }
180 
181 void
183 {
184  assert(waitingForDns);
185  waitingForDns = false;
186 
187  Adaptation::Icap::ServiceRep &s = service();
188 
189  if (ia == NULL) {
190  debugs(44, DBG_IMPORTANT, "ERROR: ICAP: Unknown service host: " << s.cfg().host);
191 
192 #if WHEN_IPCACHE_NBGETHOSTBYNAME_USES_ASYNC_CALLS
193  dieOnConnectionFailure(); // throws
194 #else // take a step back into protected Async call dialing.
196 #endif
197  return;
198  }
199 
201  conn->remote = ia->current();
202  conn->remote.port(s.cfg().port);
203  getOutgoingAddress(nullptr, conn);
204 
205  // TODO: service bypass status may differ from that of a transaction
207  AsyncCall::Pointer callback = JobCallback(93, 3, ConnectDialer, this, Adaptation::Icap::Xaction::noteCommConnected);
208  const auto cs = new Comm::ConnOpener(conn, callback, TheConfig.connect_timeout(service().cfg().bypass));
209  cs->setHost(s.cfg().host.termedBuf());
210  transportWait.start(cs, callback);
211 }
212 
214 {
215  if (haveConnection()) {
216 
217  if (closer != NULL) {
218  comm_remove_close_handler(connection->fd, closer);
219  closer = NULL;
220  }
221 
222  commUnsetConnTimeout(connection);
223 
224  cancelRead(); // may not work
225 
226  if (reuseConnection && !doneWithIo()) {
227  //status() adds leading spaces.
228  debugs(93,5, "not reusing pconn due to pending I/O" << status());
229  reuseConnection = false;
230  }
231 
232  if (reuseConnection)
233  disableRetries();
234 
235  const bool reset = !reuseConnection &&
236  (al.icap.outcome == xoGone || al.icap.outcome == xoError);
237 
238  Adaptation::Icap::ServiceRep &s = service();
239  s.putConnection(connection, reuseConnection, reset, status());
240 
241  writer = NULL;
242  reader = NULL;
243  connection = NULL;
244  }
245 }
246 
249 {
250  transportWait.finish();
251 
252  if (io.flag != Comm::OK) {
253  dieOnConnectionFailure(); // throws
254  return;
255  }
256 
257  useTransportConnection(io.conn);
258 }
259 
262 void
264 {
266  assert(!connection);
267 
268  // If it is a reused connection and the TLS object is built
269  // we should not negotiate new TLS session
270  const auto &ssl = fd_table[conn->fd].ssl;
271  if (!ssl && service().cfg().secure.encryptTransport) {
272  // XXX: Exceptions orphan conn.
274  AsyncCall::Pointer callback = asyncCall(93, 4, "Adaptation::Icap::Xaction::handleSecuredPeer",
276 
277  const auto sslConnector = new Ssl::IcapPeerConnector(theService, conn, callback, masterLogEntry(), TheConfig.connect_timeout(service().cfg().bypass));
278 
279  encryptionWait.start(sslConnector, callback);
280  return;
281  }
282 
283  useIcapConnection(conn);
284 }
285 
287 void
289 {
290  assert(!connection);
291  assert(conn);
293  connection = conn;
294  service().noteConnectionUse(connection);
295 
297  closer = asyncCall(93, 5, "Adaptation::Icap::Xaction::noteCommClosed",
298  CloseDialer(this,&Adaptation::Icap::Xaction::noteCommClosed));
299  comm_add_close_handler(connection->fd, closer);
300 
301  startShoveling();
302 }
303 
305 {
306  debugs(93, 2, typeName <<
307  " failed to connect to " << service().cfg().uri);
308  service().noteConnectionFailed("failure");
309  static const auto d = MakeNamedErrorDetail("ICAP_XACT_START");
310  detailError(d);
311  throw TexcHere("cannot connect to the ICAP service");
312 }
313 
315 {
316  Must(haveConnection());
317 
318  // comm module will free the buffer
320  writer = JobCallback(93, 3,
322 
323  Comm::Write(connection, &buf, writer);
324  updateTimeout();
325 }
326 
328 {
329  Must(writer != NULL);
330  writer = NULL;
331 
332  if (ignoreLastWrite) {
333  // a hack due to comm inability to cancel a pending write
334  ignoreLastWrite = false;
335  debugs(93, 7, "ignoring last write; status: " << io.flag);
336  } else {
337  Must(io.flag == Comm::OK);
338  al.icap.bytesSent += io.size;
339  updateTimeout();
340  handleCommWrote(io.size);
341  }
342 }
343 
344 // communication timeout with the ICAP service
346 {
347  debugs(93, 2, typeName << " failed: timeout with " <<
348  theService->cfg().methodStr() << " " <<
349  theService->cfg().uri << status());
350  reuseConnection = false;
351  assert(haveConnection());
352  closeConnection();
353  throw TextException("timed out while talking to the ICAP service", Here());
354 }
355 
356 // unexpected connection close while talking to the ICAP service
358 {
359  if (connection) {
360  connection->noteClosure();
361  connection = nullptr;
362  }
363  closer = NULL;
364 
365  static const auto d = MakeNamedErrorDetail("ICAP_XACT_CLOSE");
366  detailError(d);
367  mustStop("ICAP service connection externally closed");
368 }
369 
370 void Adaptation::Icap::Xaction::callException(const std::exception &e)
371 {
372  setOutcome(xoError);
373  service().noteFailure();
375 }
376 
378 {
379  if (doneWithIo()) {
380  debugs(93, 5, typeName << " done with I/O" << status());
381  closeConnection();
382  }
383  Adaptation::Initiate::callEnd(); // may destroy us
384 }
385 
387 {
388  return !waitingForDns && !transportWait && !encryptionWait &&
389  !reader && !writer &&
391 }
392 
394 {
395  Must(haveConnection());
396 
397  if (reader != NULL || writer != NULL) {
398  // restart the timeout before each I/O
399  // XXX: why does Config.Timeout lacks a write timeout?
400  // TODO: service bypass status may differ from that of a transaction
403  commSetConnTimeout(connection, TheConfig.io_timeout(service().cfg().bypass), call);
404  } else {
405  // clear timeout when there is no I/O
406  // Do we need a lifetime timeout?
407  commUnsetConnTimeout(connection);
408  }
409 }
410 
412 {
413  Must(haveConnection());
414  Must(!reader);
415  Must(readBuf.length() < SQUID_TCP_SO_RCVBUF); // will expand later if needed
416 
418  reader = JobCallback(93, 3, Dialer, this, Adaptation::Icap::Xaction::noteCommRead);
419  Comm::Read(connection, reader);
420  updateTimeout();
421 }
422 
423 // comm module read a portion of the ICAP response for us
425 {
426  Must(reader != NULL);
427  reader = NULL;
428 
429  Must(io.flag == Comm::OK);
430 
431  // TODO: tune this better to expected message sizes
432  readBuf.reserveCapacity(SQUID_TCP_SO_RCVBUF);
433  // we are not asked to grow beyond the allowed maximum
434  Must(readBuf.length() < SQUID_TCP_SO_RCVBUF);
435  // now we can ensure that there is space to read new data,
436  // even if readBuf.spaceSize() currently returns zero.
437  readBuf.rawAppendStart(1);
438 
439  CommIoCbParams rd(this); // will be expanded with ReadNow results
440  rd.conn = io.conn;
441 
442  switch (Comm::ReadNow(rd, readBuf)) {
443  case Comm::INPROGRESS:
444  if (readBuf.isEmpty())
445  debugs(33, 2, io.conn << ": no data to process, " << xstrerr(rd.xerrno));
446  scheduleRead();
447  return;
448 
449  case Comm::OK:
450  al.icap.bytesRead += rd.size;
451 
452  updateTimeout();
453 
454  debugs(93, 3, "read " << rd.size << " bytes");
455 
456  disableRetries(); // because pconn did not fail
457 
458  /* Continue to process previously read data */
459  break;
460 
461  case Comm::ENDFILE: // close detected by 0-byte read
462  commEof = true;
463  reuseConnection = false;
464 
465  // detect a pconn race condition: eof on the first pconn read
466  if (!al.icap.bytesRead && retriable()) {
467  setOutcome(xoRace);
468  mustStop("pconn race");
469  return;
470  }
471 
472  break;
473 
474  // case Comm::COMM_ERROR:
475  default: // no other flags should ever occur
476  debugs(11, 2, io.conn << ": read failure: " << xstrerr(rd.xerrno));
477  mustStop("unknown ICAP I/O read error");
478  return;
479  }
480 
481  handleCommRead(io.size);
482 }
483 
485 {
486  if (reader != NULL) {
487  Must(haveConnection());
488  Comm::ReadCancel(connection->fd, reader);
489  reader = NULL;
490  }
491 }
492 
493 bool
495 {
496  debugs(93, 5, "have " << readBuf.length() << " head bytes to parse");
497 
499  // XXX: performance regression c_str() data copies
500  const char *buf = readBuf.c_str();
501  const bool parsed = msg->parse(buf, readBuf.length(), commEof, &error);
502  Must(parsed || !error); // success or need more data
503 
504  if (!parsed) { // need more data
505  Must(mayReadMore());
506  msg->reset();
507  return false;
508  }
509 
510  readBuf.consume(msg->hdr_sz);
511  return true;
512 }
513 
515 {
516  return !doneReading() && // will read more data
517  readBuf.length() < SQUID_TCP_SO_RCVBUF; // have space for more data
518 }
519 
521 {
522  return commEof;
523 }
524 
526 {
527  return !writer;
528 }
529 
531 {
532  return haveConnection() &&
533  !transportWait && !reader && !writer && // fast checks, some redundant
534  doneReading() && doneWriting();
535 }
536 
538 {
539  return connection != NULL && connection->isOpen();
540 }
541 
542 // initiator aborted
544 {
545 
546  if (theInitiator.set()) {
547  debugs(93,4, "Initiator gone before ICAP transaction ended");
548  clearInitiator();
549  static const auto d = MakeNamedErrorDetail("ICAP_INIT_GONE");
550  detailError(d);
551  setOutcome(xoGone);
552  mustStop("initiator aborted");
553  }
554 
555 }
556 
558 {
559  if (al.icap.outcome != xoUnknown) {
560  debugs(93, 3, "WARNING: resetting outcome: from " << al.icap.outcome << " to " << xo);
561  } else {
562  debugs(93, 4, xo);
563  }
564  al.icap.outcome = xo;
565 }
566 
567 // This 'last chance' method is called before a 'done' transaction is deleted.
568 // It is wrong to call virtual methods from a destructor. Besides, this call
569 // indicates that the transaction will terminate as planned.
571 {
572  // kids should sing first and then call the parent method.
573  if (transportWait || encryptionWait) {
574  service().noteConnectionFailed("abort");
575  }
576 
577  closeConnection(); // TODO: rename because we do not always close
578 
579  readBuf.clear();
580 
581  tellQueryAborted();
582 
583  maybeLog();
584 
586 }
587 
589 {
590  if (theInitiator.set()) {
591  Adaptation::Icap::XactAbortInfo abortInfo(icapRequest, icapReply.getRaw(),
592  retriable(), repeatable());
593  Launcher *launcher = dynamic_cast<Launcher*>(theInitiator.get());
594  // launcher may be nil if initiator is invalid
595  CallJobHere1(91,5, CbcPointer<Launcher>(launcher),
596  Launcher, noteXactAbort, abortInfo);
597  clearInitiator();
598  }
599 }
600 
602 {
603  if (IcapLogfileStatus == LOG_ENABLE) {
604  finalizeLogInfo();
605  icapLogLog(alep);
606  }
607 }
608 
610 {
611  //prepare log data
612  al.icp.opcode = ICP_INVALID;
613 
614  const Adaptation::Icap::ServiceRep &s = service();
615  al.icap.hostAddr = s.cfg().host.termedBuf();
616  al.icap.serviceName = s.cfg().key;
617  al.icap.reqUri = s.cfg().uri;
618 
619  tvSub(al.icap.ioTime, icap_tio_start, icap_tio_finish);
620  tvSub(al.icap.trTime, icap_tr_start, current_time);
621 
622  al.icap.request = icapRequest;
623  HTTPMSGLOCK(al.icap.request);
624  if (icapReply != NULL) {
625  al.icap.reply = icapReply.getRaw();
626  HTTPMSGLOCK(al.icap.reply);
627  al.icap.resStatus = icapReply->sline.status();
628  }
629 }
630 
631 // returns a temporary string depicting transaction status, for debugging
633 {
634  static MemBuf buf;
635  buf.reset();
636  buf.append(" [", 2);
637  fillPendingStatus(buf);
638  buf.append("/", 1);
639  fillDoneStatus(buf);
640  buf.appendf(" %s%u]", id.prefix(), id.value);
641  buf.terminate();
642 
643  return buf.content();
644 }
645 
647 {
648  if (haveConnection()) {
649  buf.appendf("FD %d", connection->fd);
650 
651  if (writer != NULL)
652  buf.append("w", 1);
653 
654  if (reader != NULL)
655  buf.append("r", 1);
656 
657  buf.append(";", 1);
658  }
659 
660  if (waitingForDns)
661  buf.append("D", 1);
662 }
663 
665 {
666  if (haveConnection() && commEof)
667  buf.appendf("Comm(%d)", connection->fd);
668 
669  if (stopReason != NULL)
670  buf.append("Stopped", 7);
671 }
672 
674 {
675  return false;
676 }
677 
678 bool
680 {
681  if (!Security::PeerConnector::initialize(serverSession))
682  return false;
683 
684  assert(!icapService->cfg().secure.sslDomain.isEmpty());
685 #if USE_OPENSSL
686  SBuf *host = new SBuf(icapService->cfg().secure.sslDomain);
687  SSL_set_ex_data(serverSession.get(), ssl_ex_index_server, host);
688  setClientSNI(serverSession.get(), host->c_str());
689 #endif
690 
691  Security::SetSessionResumeData(serverSession, icapService->sslSession);
692  return true;
693 }
694 
695 void
697 {
699  if (checklist.dst_peer_name.isEmpty())
700  checklist.dst_peer_name = icapService->cfg().secure.sslDomain;
701 }
702 
703 void
705 {
706  if (error)
707  return;
708 
709  const int fd = serverConnection()->fd;
710  Security::MaybeGetSessionResumeData(fd_table[fd].ssl, icapService->sslSession);
711 }
712 
713 void
715 {
716  encryptionWait.finish();
717 
718  assert(!answer.tunneled);
719  if (answer.error.get()) {
720  assert(!answer.conn);
721  // TODO: Refactor dieOnConnectionFailure() to be usable here as well.
722  debugs(93, 2, typeName <<
723  " TLS negotiation to " << service().cfg().uri << " failed");
724  service().noteConnectionFailed("failure");
725  static const auto d = MakeNamedErrorDetail("ICAP_XACT_SSL_START");
726  detailError(d);
727  throw TexcHere("cannot connect to the TLS ICAP service");
728  }
729 
730  debugs(93, 5, "TLS negotiation to " << service().cfg().uri << " complete");
731 
732  assert(answer.conn);
733 
734  // The socket could get closed while our callback was queued. Sync
735  // Connection. XXX: Connection::fd may already be stale/invalid here.
736  if (answer.conn->isOpen() && fd_table[answer.conn->fd].closing()) {
737  answer.conn->noteClosure();
738  service().noteConnectionFailed("external TLS connection closure");
739  static const auto d = MakeNamedErrorDetail("ICAP_XACT_SSL_CLOSE");
740  detailError(d);
741  throw TexcHere("external closure of the TLS ICAP service connection");
742  }
743 
744  useIcapConnection(answer.conn);
745 }
746 
void Read(const Comm::ConnectionPointer &conn, AsyncCall::Pointer &callback)
Definition: Read.cc:40
int hdr_sz
Definition: Message.h:82
PeerConnector(const Comm::ConnectionPointer &aServerConn, AsyncCall::Pointer &aCallback, const AccessLogEntryPointer &alp, const time_t timeout=0)
const char * xstrerr(int error)
Definition: xstrerror.cc:83
Cbc * get() const
a temporary valid raw Cbc pointer or NULL
Definition: CbcPointer.h:162
AsyncCall::Pointer comm_add_close_handler(int fd, CLCB *handler, void *data)
Definition: comm.cc:921
bool tunneled
whether we spliced the connections instead of negotiating encryption
const XactOutcome xoError
all kinds of transaction errors
Definition: Elements.cc:21
#define Here()
source code location of the caller
Definition: Here.h:15
void terminate()
Definition: MemBuf.cc:241
void appendf(const char *fmt,...) PRINTF_FORMAT_ARG2
Append operation with printf-style arguments.
Definition: Packable.h:61
void noteCommConnected(const CommConnectCbParams &io)
called when the connection attempt to an ICAP service completes (successfully or not)
Definition: Xaction.cc:248
common parts of HttpRequest and HttpReply
Definition: Message.h:26
A simple PeerConnector for Secure ICAP services. No SslBump capabilities.
Definition: Xaction.cc:50
std::shared_ptr< SSL_CTX > ContextPointer
Definition: Context.h:29
virtual bool initialize(Security::SessionPointer &)
void MaybeGetSessionResumeData(const Security::SessionPointer &, Security::SessionStatePointer &data)
Definition: Session.cc:225
virtual void fillDoneStatus(MemBuf &buf) const
Definition: Xaction.cc:664
Config TheConfig
Definition: Config.cc:19
virtual void callEnd()
called right after the called job method
Definition: AsyncJob.cc:137
@ scNone
Definition: StatusCode.h:21
const XactOutcome xoUnknown
initial value: outcome was not set
Definition: Elements.cc:18
bool isEmpty() const
Definition: SBuf.h:424
CbcPointer< ErrorState > error
problem details (nil on success)
void dnsLookupDone(const ipcache_addrs *ia)
Definition: Xaction.cc:182
Comm::Flag ReadNow(CommIoCbParams &params, SBuf &buf)
Definition: Read.cc:81
Xaction(const char *aTypeName, ServiceRep::Pointer &aService)
Definition: Xaction.cc:79
void error(char *format,...)
@ INPROGRESS
Definition: Flag.h:22
Definition: SBuf.h:87
virtual bool doneAll() const
whether positive goal has been reached
Definition: Xaction.cc:386
ServiceRep & service()
Definition: Xaction.cc:120
virtual void fillPendingStatus(MemBuf &buf) const
Definition: Xaction.cc:646
int commSetConnTimeout(const Comm::ConnectionPointer &conn, int timeout, AsyncCall::Pointer &callback)
Definition: comm.cc:563
void setOutcome(const XactOutcome &xo)
Definition: Xaction.cc:557
#define LOG_ENABLE
Definition: defines.h:62
virtual void fillChecklist(ACLFilledChecklist &) const
configure the given checklist (to reflect the current transaction state)
void useTransportConnection(const Comm::ConnectionPointer &)
Definition: Xaction.cc:263
virtual void append(const char *c, int sz)
Definition: MemBuf.cc:209
bool IsConnOpen(const Comm::ConnectionPointer &conn)
Definition: Connection.cc:27
@ OK
Definition: Flag.h:16
const Ip::Address & current() const
Definition: ipcache.h:59
void HTTPMSGUNLOCK(M *&a)
Definition: Message.h:150
static void icapLookupDnsResults(const ipcache_addrs *ia, const Dns::LookupDetails &, void *data)
Definition: Xaction.cc:146
void disableRepeats(const char *reason)
Definition: Xaction.cc:133
@ ENDFILE
Definition: Flag.h:27
StatusCode
Definition: StatusCode.h:20
bool haveConnection() const
Definition: Xaction.cc:537
int xerrno
The last errno to occur. non-zero if flag is Comm::COMM_ERROR.
Definition: CommCalls.h:88
const XactOutcome xoGone
initiator gone, will not continue
Definition: Elements.cc:19
void noteCommClosed(const CommCloseCbParams &io)
Definition: Xaction.cc:357
void noteCommWrote(const CommIoCbParams &io)
Definition: Xaction.cc:327
time_t connect_timeout(bool bypassable) const
Definition: Config.cc:41
#define TexcHere(msg)
legacy convenience macro; it is not difficult to type Here() now
Definition: TextException.h:59
const XactOutcome xoRace
ICAP server closed pconn when we started.
Definition: Elements.cc:20
void getOutgoingAddress(HttpRequest *request, const Comm::ConnectionPointer &conn)
Definition: FwdState.cc:1524
void noteCommRead(const CommIoCbParams &io)
Definition: Xaction.cc:424
void ReadCancel(int fd, AsyncCall::Pointer &callback)
Cancel the read pending on FD. No action if none pending.
Definition: Read.cc:219
@ ICP_INVALID
Definition: icp_opcode.h:15
Comm::ConnectionPointer conn
peer connection (secured on success)
struct timeval current_time
the current UNIX time in timeval {seconds, microseconds} format
Definition: gadgets.cc:17
#define NULL
Definition: types.h:166
virtual bool doneAll() const
whether positive goal has been reached
Definition: AsyncJob.cc:97
Comm::ConnectionPointer getIdleConnection(bool isRetriable)
Definition: ServiceRep.cc:117
CBDATA_CLASS(IcapPeerConnector)
void icapLogLog(AccessLogEntry::Pointer &al)
Definition: icap_log.cc:60
virtual void callEnd()
called right after the called job method
Definition: Xaction.cc:377
Adaptation::Icap::ServiceRep::Pointer icapService
Definition: Xaction.cc:73
#define true
Definition: GnuRegex.c:234
Definition: MemBuf.h:24
void ipcache_nbgethostbyname(const char *name, IPH *handler, void *handlerData)
Definition: ipcache.cc:599
Definition: Xaction.cc:48
void useIcapConnection(const Comm::ConnectionPointer &)
react to the availability of a fully-ready ICAP connection
Definition: Xaction.cc:288
Callback dialer API to allow PeerConnector to set the answer.
Definition: PeerConnector.h:57
virtual bool fillVirginHttpHeader(MemBuf &) const
Definition: Xaction.cc:673
#define CallJobHere(debugSection, debugLevel, job, Class, method)
Definition: AsyncJobCalls.h:58
bool doneWithIo() const
Definition: Xaction.cc:530
virtual Security::EncryptorAnswer & answer()
gives PeerConnector access to the in-dialer answer
Definition: Xaction.cc:44
Comm::ConnectionPointer conn
Definition: CommCalls.h:85
int conn
the current server connection FD
Definition: Transport.cc:26
#define assert(EX)
Definition: assert.h:19
char const * termedBuf() const
Definition: SquidString.h:92
SSL Connection
Definition: Session.h:45
MyIcapAnswerDialer(const JobPointer &aJob, Method aMethod)
Definition: Xaction.cc:40
void HTTPMSGLOCK(Http::Message *a)
Definition: Message.h:161
Comm::Flag flag
comm layer result status.
Definition: CommCalls.h:87
HttpRequest * icapRequest
sent (or at least created) ICAP request
Definition: Xaction.h:63
encapsulates DNS lookup results
Definition: LookupDetails.h:21
#define JobCallback(dbgSection, dbgLevel, Dialer, job, method)
Convenience macro to create a Dialer-based job callback.
Definition: AsyncJobCalls.h:69
const char * c_str()
Definition: SBuf.cc:516
void Write(const Comm::ConnectionPointer &conn, const char *buf, int size, AsyncCall::Pointer &callback, FREE *free_func)
Definition: Write.cc:33
int commUnsetConnTimeout(const Comm::ConnectionPointer &conn)
Definition: comm.cc:589
int IcapLogfileStatus
Definition: icap_log.cc:20
CBDATA_NAMESPACED_CLASS_INIT(Ssl, IcapPeerConnector)
virtual void callException(const std::exception &e)
called when the job throws during an async call
Definition: Xaction.cc:370
const char * typeName
kid (leaf) class name, for debugging
Definition: AsyncJob.h:80
time_t io_timeout(bool bypassable) const
Definition: Config.cc:49
virtual void reset()=0
int ssl_ex_index_server
#define fd_table
Definition: fde.h:189
bool mayReadMore() const
Definition: Xaction.cc:514
virtual void finalizeLogInfo()
Definition: Xaction.cc:609
virtual void noteInitiatorAborted()
Definition: Xaction.cc:543
std::shared_ptr< SSL > SessionPointer
Definition: Session.h:49
void handleSecuredPeer(Security::EncryptorAnswer &answer)
Definition: Xaction.cc:714
an std::runtime_error with thrower location info
Definition: TextException.h:21
char * content()
start of the added data
Definition: MemBuf.h:41
virtual void swanSong()
Definition: Initiate.cc:62
virtual void start()
called by AsyncStart; do not call directly
Definition: AsyncJob.cc:44
#define Must(condition)
Definition: TextException.h:71
#define DBG_IMPORTANT
Definition: Stream.h:41
virtual void noteNegotiationDone(ErrorState *error)
Definition: Xaction.cc:704
AsyncCall * asyncCall(int aDebugSection, int aDebugLevel, const char *aName, const Dialer &aDialer)
Definition: AsyncCall.h:154
void Controller::create() STUB void Controller Controller nil
void reset()
Definition: MemBuf.cc:129
virtual void swanSong()
Definition: Xaction.cc:570
void noteCommTimedout(const CommTimeoutCbParams &io)
Definition: Xaction.cc:345
virtual const char * status() const
internal cleanup; do not call directly
Definition: Xaction.cc:632
bool isOpen() const
Definition: Connection.h:99
const ServiceConfig & cfg() const
Definition: Service.h:51
void scheduleWrite(MemBuf &buf)
Definition: Xaction.cc:314
virtual void callException(const std::exception &e)
called when the job throws during an async call
Definition: AsyncJob.cc:128
Gives Security::PeerConnector access to Answer in the PeerPoolMgr callback dialer.
Definition: Xaction.cc:38
virtual void fillChecklist(ACLFilledChecklist &) const
configure the given checklist (to reflect the current transaction state)
Definition: Xaction.cc:696
IcapPeerConnector(Adaptation::Icap::ServiceRep::Pointer &service, const Comm::ConnectionPointer &aServerConn, AsyncCall::Pointer &aCallback, AccessLogEntry::Pointer const &alp, const time_t timeout=0)
Definition: Xaction.cc:53
virtual Security::ContextPointer getTlsContext()
Definition: Xaction.cc:65
#define false
Definition: GnuRegex.c:233
Network/connection security abstraction layer.
Definition: Connection.h:34
virtual bool initialize(Security::SessionPointer &)
Definition: Xaction.cc:679
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:196
virtual void start()
called by AsyncStart; do not call directly
Definition: Xaction.cc:140
virtual AccessLogEntry::Pointer masterLogEntry()
Definition: Xaction.cc:113
const char * XactOutcome
transaction result for logging
Definition: Elements.h:39
void comm_remove_close_handler(int fd, CLCB *handler, void *data)
Definition: comm.cc:950
virtual bool doneReading() const
Definition: Xaction.cc:520
void setClientSNI(SSL *ssl, const char *fqdn)
Definition: support.cc:1061
void tvSub(struct timeval &res, struct timeval const &t1, struct timeval const &t2)
Definition: gadgets.cc:58
bool parseHttpMsg(Http::Message *msg)
Definition: Xaction.cc:494
ErrorDetail::Pointer MakeNamedErrorDetail(const char *name)
Definition: Detail.cc:54
virtual bool doneWriting() const
Definition: Xaction.cc:525
void SetSessionResumeData(const Security::SessionPointer &, const Security::SessionStatePointer &)
Definition: Session.cc:246
#define CallJobHere1(debugSection, debugLevel, job, Class, method, arg1)
Definition: AsyncJobCalls.h:63
bool parse(const char *buf, const size_t sz, bool eol, Http::StatusCode *error)
Definition: Message.cc:79

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors