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