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