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

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors