ServiceRep.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2019 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 "adaptation/Answer.h"
13 #include "adaptation/icap/Config.h"
18 #include "base/TextException.h"
19 #include "comm/Connection.h"
20 #include "ConfigParser.h"
21 #include "Debug.h"
22 #include "fde.h"
23 #include "globals.h"
24 #include "HttpReply.h"
25 #include "ip/tools.h"
26 #include "SquidConfig.h"
27 #include "SquidTime.h"
28 
29 #define DEFAULT_ICAP_PORT 1344
30 #define DEFAULT_ICAPS_PORT 11344
31 
33 
35  AsyncJob("Adaptation::Icap::ServiceRep"), Adaptation::Service(svcCfg),
36  theOptions(NULL), theOptionsFetcher(0), theLastUpdate(0),
37  theBusyConns(0),
38  theAllWaiters(0),
39  connOverloadReported(false),
40  theIdleConns(NULL),
41  isSuspended(0), notifying(false),
42  updateScheduled(false),
43  wasAnnouncedUp(true), // do not announce an "up" service at startup
44  isDetached(false)
45 {
47  theIdleConns = new IdleConnList("ICAP Service", NULL);
48 }
49 
51 {
53  delete theIdleConns;
55  delete theOptions;
56  });
57 }
58 
59 void
61 {
63 
64  // use /etc/services or default port if needed
65  const bool have_port = cfg().port >= 0;
66  if (!have_port) {
67  struct servent *serv;
68  if (cfg().protocol.caseCmp("icaps") == 0)
69  serv = getservbyname("icaps", "tcp");
70  else
71  serv = getservbyname("icap", "tcp");
72 
73  if (serv) {
74  writeableCfg().port = htons(serv->s_port);
75  } else {
77  }
78  }
79 
80  if (cfg().protocol.caseCmp("icaps") == 0)
82 
83  if (cfg().secure.encryptTransport) {
84  debugs(3, DBG_IMPORTANT, "Initializing service " << cfg().resource << " SSL context");
86  }
87 
88  if (!cfg().connectionEncryption.configured())
89  writeableCfg().connectionEncryption.defaultTo(cfg().secure.encryptTransport);
90 
93 }
94 
96 {
97  const int failures = theSessionFailures.count(1);
98  debugs(93,4, HERE << " failure " << failures << " out of " <<
99  TheConfig.service_failure_limit << " allowed in " <<
100  TheConfig.oldest_service_failure << "sec " << status());
101 
102  if (isSuspended)
103  return;
104 
105  if (TheConfig.service_failure_limit >= 0 &&
106  failures > TheConfig.service_failure_limit)
107  suspend("too many failures");
108 
109  // TODO: Should bypass setting affect how much Squid tries to talk to
110  // the ICAP service that is currently unusable and is likely to remain
111  // so for some time? The current code says "no". Perhaps the answer
112  // should be configurable.
113 }
114 
115 // returns a persistent or brand new connection; negative int on failures
117 Adaptation::Icap::ServiceRep::getConnection(bool retriableXact, bool &reused)
118 {
119  Comm::ConnectionPointer connection;
120 
121  /* 2011-06-17: rousskov:
122  * There are two things that happen at the same time in pop(). Both are important.
123  * 1) Ensure that we can use a pconn for this transaction.
124  * 2) Ensure that the number of idle pconns does not grow without bounds.
125  *
126  * Both happen in the beginning of the transaction. Both are dictated by real-world problems.
127  * retriable means you can repeat the request if you suspect the first try failed due to a pconn race.
128  * HTTP and ICAP rules prohibit the use of pconns for non-retriable requests.
129  *
130  * If there are zero idle connections, (2) is irrelevant. (2) is only relevant when there are many
131  * idle connections and we should not open more connections without closing some idle ones,
132  * or instead of just opening a new connection and leaving idle connections as is.
133  * In other words, (2) tells us to close one FD for each new one we open due to retriable.
134  */
135  if (retriableXact)
136  connection = theIdleConns->pop();
137  else
138  theIdleConns->closeN(1);
139 
140  reused = Comm::IsConnOpen(connection);
141  ++theBusyConns;
142  debugs(93,3, HERE << "got connection: " << connection);
143  return connection;
144 }
145 
146 // pools connection if it is reusable or closes it
147 void Adaptation::Icap::ServiceRep::putConnection(const Comm::ConnectionPointer &conn, bool isReusable, bool sendReset, const char *comment)
148 {
149  Must(Comm::IsConnOpen(conn));
150  // do not pool an idle connection if we owe connections
151  if (isReusable && excessConnections() == 0) {
152  debugs(93, 3, HERE << "pushing pconn" << comment);
153  commUnsetConnTimeout(conn);
154  theIdleConns->push(conn);
155  } else {
156  debugs(93, 3, HERE << (sendReset ? "RST" : "FIN") << "-closing " <<
157  comment);
158  // comm_close called from Connection::close will clear timeout
159  // TODO: add "bool sendReset = false" to Connection::close()?
160  if (sendReset)
161  comm_reset_close(conn);
162  else
163  conn->close();
164  }
165 
166  Must(theBusyConns > 0);
167  --theBusyConns;
168  // a connection slot released. Check if there are waiters....
169  busyCheckpoint();
170 }
171 
172 // a wrapper to avoid exposing theIdleConns
174 {
175  Must(Comm::IsConnOpen(conn));
176  fd_table[conn->fd].noteUse(); // pconn re-use, albeit not via PconnPool API
177 }
178 
180 {
181  debugs(93, 3, HERE << "Connection failed: " << comment);
182  --theBusyConns;
183 }
184 
186 {
187  if (cfg().maxConn >= 0)
189  else if (theOptions && theOptions->max_connections >= 0)
191  else {
192  theMaxConnections = -1;
193  return;
194  }
195 
196  if (::Config.workers > 1 )
197  theMaxConnections /= ::Config.workers;
198 }
199 
201 {
202  if (theMaxConnections < 0)
203  return -1;
204 
205  // we are available if we can open or reuse connections
206  // in other words, if we will not create debt
207  int available = max(0, theMaxConnections - theBusyConns);
208 
209  if (!available && !connOverloadReported) {
210  debugs(93, DBG_IMPORTANT, "WARNING: ICAP Max-Connections limit " <<
211  "exceeded for service " << cfg().uri << ". Open connections now: " <<
212  theBusyConns + theIdleConns->count() << ", including " <<
213  theIdleConns->count() << " idle persistent connections.");
214  connOverloadReported = true;
215  }
216 
217  if (cfg().onOverload == srvForce)
218  return -1;
219 
220  return available;
221 }
222 
223 // The number of connections which excess the Max-Connections limit
225 {
226  if (theMaxConnections < 0)
227  return 0;
228 
229  // Waiters affect the number of needed connections but a needed
230  // connection may still be excessive from Max-Connections p.o.v.
231  // so we should not account for waiting transaction needs here.
232  const int debt = theBusyConns + theIdleConns->count() - theMaxConnections;
233  if (debt > 0)
234  return debt;
235  else
236  return 0;
237 }
238 
240 {
241  --theAllWaiters;
242 
243  // in case the notified transaction did not take the connection slot
244  busyCheckpoint();
245 }
246 
247 // called when a connection slot may become available
249 {
250  if (theNotificationWaiters.empty()) // nobody is waiting for a slot
251  return;
252 
253  int freed = 0;
254  int available = availableConnections();
255 
256  if (available < 0) {
257  // It is possible to have waiters when no limit on connections exist in
258  // case of reconfigure or because new Options received.
259  // In this case, notify all waiting transactions.
260  freed = theNotificationWaiters.size();
261  } else {
262  // avoid notifying more waiters than there will be available slots
263  const int notifiedWaiters = theAllWaiters - theNotificationWaiters.size();
264  freed = available - notifiedWaiters;
265  }
266 
267  debugs(93,7, HERE << "Available connections: " << available <<
268  " freed slots: " << freed <<
269  " waiting in queue: " << theNotificationWaiters.size());
270 
271  while (freed > 0 && !theNotificationWaiters.empty()) {
272  Client i = theNotificationWaiters.front();
273  theNotificationWaiters.pop_front();
275  i.callback = NULL;
276  --freed;
277  }
278 }
279 
281 {
282  if (isSuspended) {
283  debugs(93,4, HERE << "keeping suspended, also for " << reason);
284  } else {
285  isSuspended = reason;
286  debugs(93, DBG_IMPORTANT, "suspending ICAP service for " << reason);
288  announceStatusChange("suspended", true);
289  }
290 }
291 
293 {
294  return theLastUpdate != 0;
295 }
296 
298 {
299  return theOptions && theOptions->valid() && theOptions->fresh();
300 }
301 
303 {
304  return !isSuspended && hasOptions();
305 }
306 
308 {
309  Must(up());
310  int available = availableConnections();
311  if (available < 0)
312  return true;
313  else
314  return (available - theAllWaiters > 0);
315 }
316 
318 {
319  Must(up());
320 
321  int available = availableConnections();
322  return (available != 0); // it is -1 (no limit) or has available slots
323 }
324 
326 {
327  Must(hasOptions());
329 }
330 
331 bool Adaptation::Icap::ServiceRep::wantsPreview(const SBuf &urlPath, size_t &wantedSize) const
332 {
333  Must(hasOptions());
334 
335  if (theOptions->preview < 0)
336  return false;
337 
339  return false;
340 
341  wantedSize = theOptions->preview;
342 
343  return true;
344 }
345 
347 {
348  Must(hasOptions());
349  return true; // in the future, we may have ACLs to prevent 204s
350 }
351 
353 {
354  Must(hasOptions());
355  if (theOptions->allow206)
356  return true; // in the future, we may have ACLs to prevent 206s
357  return false;
358 }
359 
360 static
362 {
364  Must(service);
365  service->noteTimeToUpdate();
366 }
367 
369 {
370  if (!detached())
371  updateScheduled = false;
372 
373  if (detached() || theOptionsFetcher.set()) {
374  debugs(93,5, HERE << "ignores options update " << status());
375  return;
376  }
377 
378  debugs(93,5, HERE << "performs a regular options update " << status());
380 }
381 
382 #if 0
383 static
384 void Adaptation::Icap::ServiceRep_noteTimeToNotify(void *data)
385 {
387  Must(service);
388  service->noteTimeToNotify();
389 }
390 #endif
391 
393 {
394  Must(!notifying);
395  notifying = true;
396  debugs(93,7, HERE << "notifies " << theClients.size() << " clients " <<
397  status());
398 
399  // note: we must notify even if we are invalidated
400 
401  Pointer us = NULL;
402 
403  while (!theClients.empty()) {
404  Client i = theClients.back();
405  theClients.pop_back();
407  i.callback = 0;
408  }
409 
410  notifying = false;
411 }
412 
414 {
415  debugs(93,8, "ICAPServiceRep::callWhenAvailable");
416  Must(cb!=NULL);
417  Must(up());
418  Must(!theIdleConns->count()); // or we should not be waiting
419 
420  Client i;
421  i.service = Pointer(this);
422  i.callback = cb;
423  if (priority)
424  theNotificationWaiters.push_front(i);
425  else
426  theNotificationWaiters.push_back(i);
427 
428  busyCheckpoint();
429 }
430 
432 {
433  Must(cb!=NULL);
434 
435  debugs(93,5, HERE << "Adaptation::Icap::Service is asked to call " << *cb <<
436  " when ready " << status());
437 
438  Must(!broken()); // we do not wait for a broken service
439 
440  Client i;
441  i.service = Pointer(this); // TODO: is this really needed?
442  i.callback = cb;
443  theClients.push_back(i);
444 
446  return; // do nothing, we will be picked up in noteTimeToNotify()
447 
448  if (needNewOptions())
450  else
452 }
453 
455 {
456  debugs(93,7, HERE << "will notify " << theClients.size() << " clients");
458 }
459 
461 {
462  return !detached() && !up();
463 }
464 
466 {
467  debugs(93,8, HERE << "changes options from " << theOptions << " to " <<
468  newOptions << ' ' << status());
469 
470  delete theOptions;
471  theOptions = newOptions;
473  isSuspended = 0;
475 
476  checkOptions();
477  announceStatusChange("down after an options fetch failure", true);
478 }
479 
481 {
482  if (theOptions == NULL)
483  return;
484 
485  if (!theOptions->valid()) {
486  debugs(93, DBG_IMPORTANT, "WARNING: Squid got an invalid ICAP OPTIONS response " <<
487  "from service " << cfg().uri << "; error: " << theOptions->error);
488  return;
489  }
490 
491  /*
492  * Issue a warning if the ICAP server returned methods in the
493  * options response that don't match the method from squid.conf.
494  */
495 
496  if (!theOptions->methods.empty()) {
497  bool method_found = false;
498  String method_list;
499  std::vector <ICAP::Method>::iterator iter = theOptions->methods.begin();
500 
501  while (iter != theOptions->methods.end()) {
502 
503  if (*iter == cfg().method) {
504  method_found = true;
505  break;
506  }
507 
508  method_list.append(ICAP::methodStr(*iter));
509  method_list.append(" ", 1);
510  ++iter;
511  }
512 
513  if (!method_found) {
514  debugs(93, DBG_IMPORTANT, "WARNING: Squid is configured to use ICAP method " <<
515  cfg().methodStr() <<
516  " for service " << cfg().uri <<
517  " but OPTIONS response declares the methods are " << method_list);
518  }
519  }
520 
521  /*
522  * Check the ICAP server's date header for clock skew
523  */
524  const int skew = (int)(theOptions->timestamp() - squid_curtime);
525  if (abs(skew) > theOptions->ttl()) {
526  // TODO: If skew is negative, the option will be considered down
527  // because of stale options. We should probably change this.
528  debugs(93, DBG_IMPORTANT, "ICAP service's clock is skewed by " << skew <<
529  " seconds: " << cfg().uri);
530  }
531 }
532 
533 void Adaptation::Icap::ServiceRep::announceStatusChange(const char *downPhrase, bool important) const
534 {
535  if (wasAnnouncedUp == up()) // no significant changes to announce
536  return;
537 
538  const char *what = cfg().bypass ? "optional" : "essential";
539  const char *state = wasAnnouncedUp ? downPhrase : "up";
540  const int level = important ? 1 :2;
541  debugs(93,level, what << " ICAP service is " << state << ": " <<
542  cfg().uri << ' ' << status());
543 
545 }
546 
547 // we are receiving ICAP OPTIONS response headers here or NULL on failures
549 {
552 
553  if (answer.kind == Answer::akError) {
554  debugs(93,3, HERE << "failed to fetch options " << status());
555  handleNewOptions(0);
556  return;
557  }
558 
559  Must(answer.kind == Answer::akForward); // no akBlock for OPTIONS requests
560  const Http::Message *msg = answer.message.getRaw();
561  Must(msg);
562 
563  debugs(93,5, HERE << "is interpreting new options " << status());
564 
565  Adaptation::Icap::Options *newOptions = NULL;
566  if (const HttpReply *r = dynamic_cast<const HttpReply*>(msg)) {
567  newOptions = new Adaptation::Icap::Options;
568  newOptions->configure(r);
569  } else {
570  debugs(93, DBG_IMPORTANT, "ICAP service got wrong options message " << status());
571  }
572 
573  handleNewOptions(newOptions);
574 }
575 
576 // we (a) must keep trying to get OPTIONS and (b) are RefCounted so we
577 // must keep our job alive (XXX: until nobody needs us)
578 void Adaptation::Icap::ServiceRep::callException(const std::exception &e)
579 {
581  debugs(93,2, "ICAP probably failed to fetch options (" << e.what() <<
582  ")" << status());
583  handleNewOptions(0);
584 }
585 
587 {
588  // new options may be NULL
589  changeOptions(newOptions);
590 
591  debugs(93,3, HERE << "got new options and is now " << status());
592 
594 
595  // XXX: this whole feature bases on the false assumption a service only has one IP
597  const int excess = excessConnections();
598  // if we owe connections and have idle pconns, close the latter
599  if (excess && theIdleConns->count() > 0) {
600  const int n = min(excess, theIdleConns->count());
601  debugs(93,5, HERE << "closing " << n << " pconns to relief debt");
602  theIdleConns->closeN(n);
603  }
604 
606 }
607 
609 {
611  debugs(93,6, HERE << "will get new options " << status());
612 
613  // XXX: "this" here is "self"; works until refcounting API changes
616  // TODO: timeout in case Adaptation::Icap::OptXact never calls us back?
617  // Such a timeout should probably be a generic AsyncStart feature.
618 }
619 
621 {
622  if (updateScheduled) {
623  debugs(93,7, HERE << "reschedules update");
624  // XXX: check whether the event is there because AR saw
625  // an unreproducible eventDelete assertion on 2007/06/18
628  else
629  debugs(93, DBG_IMPORTANT, "XXX: ICAP service lost an update event.");
630  updateScheduled = false;
631  }
632 
633  debugs(93,7, HERE << "raw OPTIONS fetch at " << when << " or in " <<
634  (when - squid_curtime) << " sec");
635  debugs(93,9, HERE << "last fetched at " << theLastUpdate << " or " <<
636  (squid_curtime - theLastUpdate) << " sec ago");
637 
638  /* adjust update time to prevent too-frequent updates */
639 
640  if (when < squid_curtime)
641  when = squid_curtime;
642 
643  // XXX: move hard-coded constants from here to Adaptation::Icap::TheConfig
644  const int minUpdateGap = 30; // seconds
645  if (when < theLastUpdate + minUpdateGap)
646  when = theLastUpdate + minUpdateGap;
647 
648  const int delay = when - squid_curtime;
649  debugs(93,5, HERE << "will fetch OPTIONS in " << delay << " sec");
650 
651  eventAdd("Adaptation::Icap::ServiceRep::noteTimeToUpdate",
652  &ServiceRep_noteTimeToUpdate, this, delay, 0, true);
653  updateScheduled = true;
654 }
655 
656 // returns absolute time when OPTIONS should be fetched
657 time_t
659 {
660  if (theOptions && theOptions->valid()) {
661  const time_t expire = theOptions->expire();
662  debugs(93,7, HERE << "options expire on " << expire << " >= " << squid_curtime);
663 
664  // conservative estimate of how long the OPTIONS transaction will take
665  // XXX: move hard-coded constants from here to Adaptation::Icap::TheConfig
666  const int expectedWait = 20; // seconds
667 
668  // Unknown or invalid (too small) expiration times should not happen.
669  // Adaptation::Icap::Options should use the default TTL, and ICAP servers should not
670  // send invalid TTLs, but bugs and attacks happen.
671  if (expire < expectedWait)
672  return squid_curtime;
673  else
674  return expire - expectedWait; // before the current options expire
675  }
676 
677  // use revival delay as "expiration" time for a service w/o valid options
679 }
680 
684 {
685  return new Adaptation::Icap::ModXactLauncher(virgin, cause, alp, this);
686 }
687 
688 // returns a temporary string depicting service status, for debugging
690 {
691  static MemBuf buf;
692 
693  buf.reset();
694  buf.append("[", 1);
695 
696  if (up())
697  buf.append("up", 2);
698  else {
699  buf.append("down", 4);
700  if (isSuspended)
701  buf.append(",susp", 5);
702 
703  if (!theOptions)
704  buf.append(",!opt", 5);
705  else if (!theOptions->valid())
706  buf.append(",!valid", 7);
707  else if (!theOptions->fresh())
708  buf.append(",stale", 6);
709  }
710 
711  if (detached())
712  buf.append(",detached", 9);
713 
714  if (theOptionsFetcher.set())
715  buf.append(",fetch", 6);
716 
717  if (notifying)
718  buf.append(",notif", 6);
719 
720  if (const int failures = theSessionFailures.remembered())
721  buf.appendf(",fail%d", failures);
722 
723  buf.append("]", 1);
724  buf.terminate();
725 
726  return buf.content();
727 }
728 
730 {
731  debugs(93,3, HERE << "detaching ICAP service: " << cfg().uri <<
732  ' ' << status());
733  isDetached = true;
734 }
735 
737 {
738  return isDetached;
739 }
740 
743  Parent(xact, aHandler)
744 {
745  theService = &xact->service();
746  theService->noteNewWaiter();
747 }
748 
750 {
751  theService = aConnWaiter.theService;
752  theService->noteNewWaiter();
753 }
754 
756 {
757  theService->noteGoneWaiter();
758 }
759 
summarizes adaptation service answer for the noteAdaptationAnswer() API
Definition: Answer.h:22
ServiceConfig & writeableCfg()
Definition: Service.h:62
#define fd_table
Definition: fde.h:157
void configure(const HttpReply *reply)
Definition: Options.cc:85
CbcPointer< Initiate > initiateAdaptation(Initiate *x)
< starts freshly created initiate and returns a safe pointer to it
Definition: Initiator.cc:23
void putConnection(const Comm::ConnectionPointer &conn, bool isReusable, bool sendReset, const char *comment)
Definition: ServiceRep.cc:147
virtual bool detached() const
whether detached() was called
Definition: ServiceRep.cc:736
#define CallJobHere(debugSection, debugLevel, job, Class, method)
Definition: AsyncJobCalls.h:57
virtual void append(const char *c, int sz)
Definition: MemBuf.cc:216
bool availableForOld() const
a transaction notified about connection slot availability may start communicating with the service ...
Definition: ServiceRep.cc:317
time_t optionsFetchTime() const
Definition: ServiceRep.cc:658
Definition: SBuf.h:86
time_t oldest_service_failure
Definition: Config.h:55
Http::MessagePointer message
HTTP request or response to forward.
Definition: Answer.h:39
int i
Definition: membanger.c:49
const char * error
Definition: Options.h:48
int theMaxConnections
the maximum allowed connections to the service
Definition: ServiceRep.h:139
bool valid() const
Definition: Options.cc:63
void changeOptions(Options *newOptions)
Definition: ServiceRep.cc:465
bool wantsUrl(const SBuf &urlPath) const
Definition: ServiceRep.cc:325
bool encryptTransport
whether transport encryption (TLS/SSL) is to be used on connections to the peer
Definition: PeerOptions.h:128
bool initiated(const CbcPointer< AsyncJob > &job) const
Must(initiated(initiate)) instead of Must(initiate.set()), for clarity.
Definition: Initiator.h:52
Config TheConfig
Definition: Config.cc:19
const char * methodStr(Method)
Definition: Elements.cc:15
void handleNewOptions(Options *newOptions)
Definition: ServiceRep.cc:586
ServiceRep::Pointer theService
Definition: ServiceRep.h:198
#define Must(condition)
Like assert() but throws an exception instead of aborting the process.
Definition: TextException.h:69
TransferKind transferKind(const SBuf &urlPath) const
Definition: Options.cc:47
int conn
the current server connection FD
Definition: Transport.cc:26
void closeN(size_t count)
Definition: pconn.cc:113
void callWhenAvailable(AsyncCall::Pointer &cb, bool priority=false)
Definition: ServiceRep.cc:413
#define DEFAULT_ICAP_PORT
Definition: ServiceRep.cc:29
A const & max(A const &lhs, A const &rhs)
void append(char const *buf, int len)
Definition: String.cc:161
const char * status() const
internal cleanup; do not call directly
Definition: ServiceRep.cc:689
IdleConnList * theIdleConns
idle persistent connection pool
Definition: ServiceRep.h:142
time_t squid_curtime
Definition: stub_time.cc:17
ConnWaiterDialer(const CbcPointer< Adaptation::Icap::ModXact > &xact, Adaptation::Icap::ConnWaiterDialer::Parent::Method aHandler)
Definition: ServiceRep.cc:741
no adapted message will come; see bypassable
Definition: Answer.h:29
void suspend(const char *reason)
Definition: ServiceRep.cc:280
#define SWALLOW_EXCEPTIONS(code)
Definition: TextException.h:73
bool availableForNew() const
a new transaction may start communicating with the service
Definition: ServiceRep.cc:307
void noteConnectionUse(const Comm::ConnectionPointer &conn)
Definition: ServiceRep.cc:173
virtual Initiate * makeXactLauncher(Http::Message *virginHeader, HttpRequest *virginCause, AccessLogEntry::Pointer &alp)
Definition: ServiceRep.cc:682
virtual bool probed() const
Definition: ServiceRep.cc:292
static void ServiceRep_noteTimeToUpdate(void *data)
Definition: ServiceRep.cc:361
int count() const
Definition: pconn.h:63
RefCount< ServiceRep > Pointer
Definition: ServiceRep.h:65
ServiceRep & service()
Definition: Xaction.cc:123
int service_revival_delay
Definition: Config.h:56
int count(int howMany)
count fresh, return #events remembered
bool IsConnOpen(const Comm::ConnectionPointer &conn)
Definition: Connection.cc:24
void callWhenReady(AsyncCall::Pointer &cb)
Definition: ServiceRep.cc:431
void const char HLPCB void * data
Definition: stub_helper.cc:16
struct servent * getservbyname()
int commUnsetConnTimeout(const Comm::ConnectionPointer &conn)
Definition: comm.cc:578
virtual bool up() const
Definition: ServiceRep.cc:302
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Debug.h:124
int eventFind(EVH *func, void *arg)
Definition: event.cc:155
#define true
Definition: GnuRegex.c:234
#define DBG_IMPORTANT
Definition: Debug.h:46
void noteConnectionFailed(const char *comment)
Definition: ServiceRep.cc:179
void reset()
Definition: MemBuf.cc:132
virtual void noteAdaptationAnswer(const Answer &answer)
Definition: ServiceRep.cc:548
void push(const Comm::ConnectionPointer &conn)
Pass control of the connection to the idle list.
Definition: pconn.cc:168
common parts of HttpRequest and HttpReply
Definition: Message.h:25
Comm::ConnectionPointer pop()
get first conn which is not pending read fd.
Definition: pconn.cc:213
CBDATA_NAMESPACED_CLASS_INIT(Adaptation::Icap, ServiceRep)
bool fresh() const
Definition: Options.cc:68
Comm::ConnectionPointer getConnection(bool isRetriable, bool &isReused)
Definition: ServiceRep.cc:117
Security::ContextPointer createClientContext(bool setOptions)
generate a security client-context from these configured options
Definition: PeerOptions.cc:275
void clear()
forgets all events
int service_failure_limit
Definition: Config.h:54
#define DEFAULT_ICAPS_PORT
Definition: ServiceRep.cc:30
void(ModXact ::* Method)()
Definition: AsyncJobCalls.h:92
char * content()
start of the added data
Definition: MemBuf.h:41
int remembered() const
possibly stale #events
Definition: FadingCounter.h:26
void const char * buf
Definition: stub_helper.cc:16
std::ostream & HERE(std::ostream &s)
Definition: Debug.h:153
CbcPointer< Adaptation::Initiate > theOptionsFetcher
Definition: ServiceRep.h:129
void eventDelete(EVH *func, void *arg)
Definition: event.cc:131
bool connOverloadReported
whether we reported exceeding theMaxConnections
Definition: ServiceRep.h:141
virtual void callException(const std::exception &e)
called when the job throws during an async call
Definition: ServiceRep.cc:578
Security::PeerOptions secure
Definition: ServiceConfig.h:53
int excessConnections() const
The number of connections which excess the Max-Connections limit.
Definition: ServiceRep.cc:224
bool SIGHDLR int STUB void int
Definition: stub_tools.cc:68
Security::ContextPointer sslContext
Definition: ServiceRep.h:113
void configure(double horizonSeconds)
0=remember nothing; -1=forget nothing; new value triggers clear()
void eventAdd(const char *name, EVH *func, void *arg, double when, int weight, bool cbdata)
Definition: event.cc:109
void comm_reset_close(const Comm::ConnectionPointer &conn)
Definition: comm.cc:792
virtual void finalize()
Definition: Service.cc:26
SrvBehaviour onOverload
how to handle Max-Connections feature
Definition: ServiceConfig.h:48
#define ScheduleCallHere(call)
Definition: AsyncCall.h:166
virtual bool broken() const
Definition: Service.cc:30
Kind kind
the type of the answer
Definition: Answer.h:42
forward the supplied adapted HTTP message
Definition: Answer.h:27
ServiceRep(const ServiceConfigPointer &aConfig)
Definition: ServiceRep.cc:34
std::vector< ICAP::Method > methods
Definition: Options.h:51
C * getRaw() const
Definition: RefCount.h:74
void appendf(const char *fmt,...) PRINTF_FORMAT_ARG2
Append operation with printf-style arguments.
Definition: Packable.h:61
std::map< OptionName, const Option *, OptionNameCmp > Options
name:option map
Definition: Options.h:159
bool wantsPreview(const SBuf &urlPath, size_t &wantedSize) const
Definition: ServiceRep.cc:331
Definition: MemBuf.h:23
time_t expire() const
Definition: Options.cc:79
const ServiceConfig & cfg() const
Definition: Service.h:51
void announceStatusChange(const char *downPhrase, bool important) const
Definition: ServiceRep.cc:533
FadingCounter theSessionFailures
Definition: ServiceRep.h:144
bool set() const
was set but may be invalid
Definition: CbcPointer.h:40
void scheduleUpdate(time_t when)
Definition: ServiceRep.cc:620
std::deque< Client > theNotificationWaiters
Definition: ServiceRep.h:134
void noteGoneWaiter()
An xaction is not waiting any more for service to be available.
Definition: ServiceRep.cc:239
#define NULL
Definition: types.h:166
int caseCmp(char const *) const
Definition: String.cc:299
A const & min(A const &lhs, A const &rhs)
void setMaxConnections()
Set the maximum allowed connections for the service.
Definition: ServiceRep.cc:185
#define false
Definition: GnuRegex.c:233
time_t timestamp() const
Definition: Options.h:42
void defaultTo(bool beSet)
enables or disables the option; updating to &#39;implicit&#39; state
Definition: YesNoNone.h:59
long maxConn
maximum number of concurrent service transactions
Definition: ServiceConfig.h:47
void clearAdaptation(CbcPointer< Initiate > &x)
clears the pointer (does not call announceInitiatorAbort)
Definition: Initiator.cc:32
void terminate()
Definition: MemBuf.cc:250
YesNoNone connectionEncryption
whether this service uses only secure connections
Definition: ServiceConfig.h:54

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors