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"
16#include "base/JobWait.h"
17#include "base/Optional.h"
18#include "base/TextException.h"
19#include "comm.h"
20#include "comm/Connection.h"
21#include "comm/ConnOpener.h"
22#include "comm/Read.h"
23#include "comm/Write.h"
24#include "CommCalls.h"
25#include "error/Detail.h"
26#include "fde.h"
27#include "FwdState.h"
28#include "globals.h"
29#include "HttpReply.h"
30#include "icap_log.h"
31#include "ipcache.h"
32#include "pconn.h"
34#include "SquidConfig.h"
35
37class MyIcapAnswerDialer: public UnaryMemFunT<Adaptation::Icap::Xaction, Security::EncryptorAnswer, Security::EncryptorAnswer&>,
39{
40public:
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
48namespace Ssl
49{
53public:
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 */
67 return icapService->sslContext;
68 }
69
70private:
71 /* Acl::ChecklistFiller API */
72 virtual void fillChecklist(ACLFilledChecklist &) const;
73
75};
76} // namespace Ssl
77
79
81 AsyncJob(aTypeName),
82 Adaptation::Initiate(aTypeName),
83 icapRequest(nullptr),
84 icapReply(nullptr),
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
98 const auto mx = MasterXaction::MakePortless<XactionInitiator::initAdaptation>();
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 != nullptr);
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
146static void
148{
149 Adaptation::Icap::Xaction *xa = static_cast<Adaptation::Icap::Xaction *>(data);
150 const auto &addr = ia ? Optional<Ip::Address>(ia->current()) : Optional<Ip::Address>();
152}
153
154// TODO: obey service-specific, OPTIONS-reported connection limit
155void
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
181void
183{
184 assert(waitingForDns);
185 waitingForDns = false;
186
187 Adaptation::Icap::ServiceRep &s = service();
188
189 if (!addr.has_value()) {
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 = addr.value();
202 conn->remote.port(s.cfg().port);
203 getOutgoingAddress(nullptr, conn);
204
205 // TODO: service bypass status may differ from that of a transaction
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 != nullptr) {
218 comm_remove_close_handler(connection->fd, closer);
219 closer = nullptr;
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 = nullptr;
242 reader = nullptr;
243 connection = nullptr;
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
262void
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
287void
289{
290 assert(!connection);
291 assert(conn);
293 connection = conn;
294 service().noteConnectionUse(connection);
295
297 closer = asyncCall(93, 5, "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 != nullptr);
330 writer = nullptr;
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 = nullptr;
364
365 static const auto d = MakeNamedErrorDetail("ICAP_XACT_CLOSE");
366 detailError(d);
367 mustStop("ICAP service connection externally closed");
368}
369
370void 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 != nullptr || writer != nullptr) {
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 != nullptr);
427 reader = nullptr;
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 != nullptr) {
487 Must(haveConnection());
488 Comm::ReadCancel(connection->fd, reader);
489 reader = nullptr;
490 }
491}
492
493bool
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 != nullptr && 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{
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 != nullptr) {
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 != nullptr)
652 buf.append("w", 1);
653
654 if (reader != nullptr)
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 != nullptr)
670 buf.append("Stopped", 7);
671}
672
674{
675 return false;
676}
677
678bool
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
695void
697{
699 if (checklist.dst_peer_name.isEmpty())
700 checklist.dst_peer_name = icapService->cfg().secure.sslDomain;
701}
702
703void
705{
706 if (error)
707 return;
708
709 const int fd = serverConnection()->fd;
710 Security::MaybeGetSessionResumeData(fd_table[fd].ssl, icapService->sslSession);
711}
712
713void
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
AsyncCall * asyncCall(int aDebugSection, int aDebugLevel, const char *aName, const Dialer &aDialer)
Definition: AsyncCall.h:154
#define JobCallback(dbgSection, dbgLevel, Dialer, job, method)
Convenience macro to create a Dialer-based job callback.
Definition: AsyncJobCalls.h:69
#define CallJobHere(debugSection, debugLevel, job, Class, method)
Definition: AsyncJobCalls.h:58
#define CallJobHere1(debugSection, debugLevel, job, Class, method, arg1)
Definition: AsyncJobCalls.h:63
ErrorDetail::Pointer MakeNamedErrorDetail(const char *name)
Definition: Detail.cc:54
void getOutgoingAddress(HttpRequest *request, const Comm::ConnectionPointer &conn)
Definition: FwdState.cc:1519
#define true
Definition: GnuRegex.c:241
#define false
Definition: GnuRegex.c:240
#define Here()
source code location of the caller
Definition: Here.h:15
#define TexcHere(msg)
legacy convenience macro; it is not difficult to type Here() now
Definition: TextException.h:59
#define Must(condition)
Definition: TextException.h:71
int conn
the current server connection FD
Definition: Transport.cc:26
static void icapLookupDnsResults(const ipcache_addrs *ia, const Dns::LookupDetails &, void *data)
Definition: Xaction.cc:147
CBDATA_NAMESPACED_CLASS_INIT(Ssl, IcapPeerConnector)
void error(char *format,...)
#define assert(EX)
Definition: assert.h:19
time_t io_timeout(bool bypassable) const
Definition: Config.cc:49
time_t connect_timeout(bool bypassable) const
Definition: Config.cc:41
Comm::ConnectionPointer getIdleConnection(bool isRetriable)
Definition: ServiceRep.cc:117
void handleSecuredPeer(Security::EncryptorAnswer &answer)
Definition: Xaction.cc:714
void noteCommConnected(const CommConnectCbParams &io)
called when the connection attempt to an ICAP service completes (successfully or not)
Definition: Xaction.cc:248
void noteCommWrote(const CommIoCbParams &io)
Definition: Xaction.cc:327
bool haveConnection() const
Definition: Xaction.cc:537
virtual void callEnd()
called right after the called job method
Definition: Xaction.cc:377
virtual bool fillVirginHttpHeader(MemBuf &) const
Definition: Xaction.cc:673
bool mayReadMore() const
Definition: Xaction.cc:514
void dnsLookupDone(Optional< Ip::Address >)
Definition: Xaction.cc:182
HttpRequest * icapRequest
sent (or at least created) ICAP request
Definition: Xaction.h:63
bool parseHttpMsg(Http::Message *msg)
Definition: Xaction.cc:494
void useTransportConnection(const Comm::ConnectionPointer &)
Definition: Xaction.cc:263
void useIcapConnection(const Comm::ConnectionPointer &)
react to the availability of a fully-ready ICAP connection
Definition: Xaction.cc:288
void noteCommClosed(const CommCloseCbParams &io)
Definition: Xaction.cc:357
virtual void noteInitiatorAborted()
Definition: Xaction.cc:543
virtual AccessLogEntry::Pointer masterLogEntry()
Definition: Xaction.cc:114
virtual bool doneReading() const
Definition: Xaction.cc:520
virtual bool doneAll() const
whether positive goal has been reached
Definition: Xaction.cc:386
virtual bool doneWriting() const
Definition: Xaction.cc:525
bool doneWithIo() const
Definition: Xaction.cc:530
virtual const char * status() const
internal cleanup; do not call directly
Definition: Xaction.cc:632
ServiceRep & service()
Definition: Xaction.cc:121
Xaction(const char *aTypeName, ServiceRep::Pointer &aService)
Definition: Xaction.cc:80
virtual void fillDoneStatus(MemBuf &buf) const
Definition: Xaction.cc:664
virtual void swanSong()
Definition: Xaction.cc:570
void disableRepeats(const char *reason)
Definition: Xaction.cc:134
virtual void start()
called by AsyncStart; do not call directly
Definition: Xaction.cc:141
void noteCommRead(const CommIoCbParams &io)
Definition: Xaction.cc:424
void scheduleWrite(MemBuf &buf)
Definition: Xaction.cc:314
virtual void fillPendingStatus(MemBuf &buf) const
Definition: Xaction.cc:646
virtual void callException(const std::exception &e)
called when the job throws during an async call
Definition: Xaction.cc:370
void setOutcome(const XactOutcome &xo)
Definition: Xaction.cc:557
void noteCommTimedout(const CommTimeoutCbParams &io)
Definition: Xaction.cc:345
virtual void finalizeLogInfo()
Definition: Xaction.cc:609
virtual void swanSong()
Definition: Initiate.cc:62
const ServiceConfig & cfg() const
Definition: Service.h:51
virtual bool doneAll() const
whether positive goal has been reached
Definition: AsyncJob.cc:97
virtual void start()
called by AsyncStart; do not call directly
Definition: AsyncJob.cc:44
virtual void callEnd()
called right after the called job method
Definition: AsyncJob.cc:137
const char * typeName
kid (leaf) class name, for debugging
Definition: AsyncJob.h:80
virtual void callException(const std::exception &e)
called when the job throws during an async call
Definition: AsyncJob.cc:128
Cbc * get() const
a temporary valid raw Cbc pointer or NULL
Definition: CbcPointer.h:162
int xerrno
The last errno to occur. non-zero if flag is Comm::COMM_ERROR.
Definition: CommCalls.h:88
Comm::Flag flag
comm layer result status.
Definition: CommCalls.h:87
Comm::ConnectionPointer conn
Definition: CommCalls.h:85
bool isOpen() const
Definition: Connection.h:101
const Ip::Address & current() const
Definition: ipcache.h:59
encapsulates DNS lookup results
Definition: LookupDetails.h:21
common parts of HttpRequest and HttpReply
Definition: Message.h:26
virtual void reset()=0
int hdr_sz
Definition: Message.h:81
bool parse(const char *buf, const size_t sz, bool eol, Http::StatusCode *error)
Definition: Message.cc:79
Definition: MemBuf.h:24
virtual void append(const char *c, int sz)
Definition: MemBuf.cc:209
char * content()
start of the added data
Definition: MemBuf.h:41
void reset()
Definition: MemBuf.cc:129
void terminate()
Definition: MemBuf.cc:241
Gives Security::PeerConnector access to Answer in the PeerPoolMgr callback dialer.
Definition: Xaction.cc:39
MyIcapAnswerDialer(const JobPointer &aJob, Method aMethod)
Definition: Xaction.cc:41
virtual Security::EncryptorAnswer & answer()
gives PeerConnector access to the in-dialer answer
Definition: Xaction.cc:45
(limited) std::optional replacement (until we upgrade to C++17)
Definition: Optional.h:30
const Value & value() const &
Definition: Optional.h:85
constexpr bool has_value() const noexcept
Definition: Optional.h:83
void appendf(const char *fmt,...) PRINTF_FORMAT_ARG2
Append operation with printf-style arguments.
Definition: Packable.h:61
Definition: SBuf.h:94
const char * c_str()
Definition: SBuf.cc:516
bool isEmpty() const
Definition: SBuf.h:431
CbcPointer< ErrorState > error
problem details (nil on success)
Comm::ConnectionPointer conn
peer connection (secured on success)
bool tunneled
whether we spliced the connections instead of negotiating encryption
Callback dialer API to allow PeerConnector to set the answer.
Definition: PeerConnector.h:57
virtual void fillChecklist(ACLFilledChecklist &) const
configure the given checklist (to reflect the current transaction state)
virtual bool initialize(Security::SessionPointer &)
PeerConnector(const Comm::ConnectionPointer &aServerConn, AsyncCall::Pointer &aCallback, const AccessLogEntryPointer &alp, const time_t timeout=0)
A simple PeerConnector for Secure ICAP services. No SslBump capabilities.
Definition: Xaction.cc:51
virtual void fillChecklist(ACLFilledChecklist &) const
configure the given checklist (to reflect the current transaction state)
Definition: Xaction.cc:696
virtual void noteNegotiationDone(ErrorState *error)
Definition: Xaction.cc:704
Adaptation::Icap::ServiceRep::Pointer icapService
Definition: Xaction.cc:74
CBDATA_CLASS(IcapPeerConnector)
virtual Security::ContextPointer getTlsContext()
Definition: Xaction.cc:66
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 bool initialize(Security::SessionPointer &)
Definition: Xaction.cc:679
char const * termedBuf() const
Definition: SquidString.h:92
an std::runtime_error with thrower location info
Definition: TextException.h:21
AsyncCall::Pointer comm_add_close_handler(int fd, CLCB *handler, void *data)
Definition: comm.cc:947
void comm_remove_close_handler(int fd, CLCB *handler, void *data)
Definition: comm.cc:976
int commSetConnTimeout(const Comm::ConnectionPointer &conn, int timeout, AsyncCall::Pointer &callback)
Definition: comm.cc:589
int commUnsetConnTimeout(const Comm::ConnectionPointer &conn)
Definition: comm.cc:615
#define DBG_IMPORTANT
Definition: Stream.h:41
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:196
#define LOG_ENABLE
Definition: defines.h:62
#define fd_table
Definition: fde.h:189
int ssl_ex_index_server
void ipcache_nbgethostbyname(const char *name, IPH *handler, void *handlerData)
Definition: ipcache.cc:599
@ ICP_INVALID
Definition: icp_opcode.h:15
void setClientSNI(SSL *ssl, const char *fqdn)
Definition: support.cc:1070
void HTTPMSGUNLOCK(M *&a)
Definition: Message.h:149
void HTTPMSGLOCK(Http::Message *a)
Definition: Message.h:160
void icapLogLog(AccessLogEntry::Pointer &al)
Definition: icap_log.cc:60
int IcapLogfileStatus
Definition: icap_log.cc:20
const XactOutcome xoGone
initiator gone, will not continue
Definition: Elements.cc:19
const XactOutcome xoRace
ICAP server closed pconn when we started.
Definition: Elements.cc:20
const XactOutcome xoError
all kinds of transaction errors
Definition: Elements.cc:21
Config TheConfig
Definition: Config.cc:19
const char * XactOutcome
transaction result for logging
Definition: Elements.h:39
const XactOutcome xoUnknown
initial value: outcome was not set
Definition: Elements.cc:18
void ReadCancel(int fd, AsyncCall::Pointer &callback)
Cancel the read pending on FD. No action if none pending.
Definition: Read.cc:219
void Read(const Comm::ConnectionPointer &conn, AsyncCall::Pointer &callback)
Definition: Read.cc:40
bool IsConnOpen(const Comm::ConnectionPointer &conn)
Definition: Connection.cc:27
void Write(const Comm::ConnectionPointer &conn, const char *buf, int size, AsyncCall::Pointer &callback, FREE *free_func)
Definition: Write.cc:33
@ OK
Definition: Flag.h:16
@ ENDFILE
Definition: Flag.h:27
@ INPROGRESS
Definition: Flag.h:22
Comm::Flag ReadNow(CommIoCbParams &params, SBuf &buf)
Definition: Read.cc:81
StatusCode
Definition: StatusCode.h:20
@ scNone
Definition: StatusCode.h:21
Network/connection security abstraction layer.
Definition: Connection.h:34
std::shared_ptr< SSL_CTX > ContextPointer
Definition: Context.h:29
SSL Connection
Definition: Session.h:45
void SetSessionResumeData(const Security::SessionPointer &, const Security::SessionStatePointer &)
Definition: Session.cc:246
std::shared_ptr< SSL > SessionPointer
Definition: Session.h:49
void MaybeGetSessionResumeData(const Security::SessionPointer &, Security::SessionStatePointer &data)
Definition: Session.cc:225
Definition: Xaction.cc:49
void Controller::create() STUB void Controller Controller nil
void tvSub(struct timeval &res, struct timeval const &t1, struct timeval const &t2)
Definition: gadgets.cc:58
struct timeval current_time
the current UNIX time in timeval {seconds, microseconds} format
Definition: gadgets.cc:17
const char * xstrerr(int error)
Definition: xstrerror.cc:83

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors