bio.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 83 SSL accelerator support */
10 
11 #include "squid.h"
12 #include "base/IoManip.h"
13 #include "ssl/support.h"
14 
15 /* support.cc says this is needed */
16 #if USE_OPENSSL
17 
18 #include "base/Raw.h"
19 #include "comm.h"
20 #include "fd.h"
21 #include "fde.h"
22 #include "globals.h"
23 #include "ip/Address.h"
24 #include "parser/BinaryTokenizer.h"
25 #include "ssl/bio.h"
26 
27 #if _SQUID_WINDOWS_
28 extern int socket_read_method(int, char *, int);
29 extern int socket_write_method(int, const char *, int);
30 #endif
31 
32 /* BIO callbacks */
33 static int squid_bio_write(BIO *h, const char *buf, int num);
34 static int squid_bio_read(BIO *h, char *buf, int size);
35 static int squid_bio_puts(BIO *h, const char *str);
36 //static int squid_bio_gets(BIO *h, char *str, int size);
37 static long squid_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2);
38 static int squid_bio_create(BIO *h);
39 static int squid_bio_destroy(BIO *data);
40 /* SSL callbacks */
41 static void squid_ssl_info(const SSL *ssl, int where, int ret);
42 
43 #if HAVE_LIBCRYPTO_BIO_METH_NEW
44 static BIO_METHOD *SquidMethods = nullptr;
45 #else
46 static BIO_METHOD SquidMethods = {
49  BIO_TYPE_SOCKET,
50  "squid",
54  nullptr, // squid_bio_gets not supported
58  NULL // squid_callback_ctrl not supported
59 };
60 #endif
61 
62 BIO *
64 {
65 #if HAVE_LIBCRYPTO_BIO_METH_NEW
66  if (!SquidMethods) {
67  SquidMethods = BIO_meth_new(BIO_TYPE_SOCKET, "squid");
68  BIO_meth_set_write(SquidMethods, squid_bio_write);
69  BIO_meth_set_read(SquidMethods, squid_bio_read);
70  BIO_meth_set_puts(SquidMethods, squid_bio_puts);
71  BIO_meth_set_gets(SquidMethods, nullptr);
72  BIO_meth_set_ctrl(SquidMethods, squid_bio_ctrl);
73  BIO_meth_set_create(SquidMethods, squid_bio_create);
74  BIO_meth_set_destroy(SquidMethods, squid_bio_destroy);
75  }
76  BIO_METHOD *useMethod = SquidMethods;
77 #else
78  BIO_METHOD *useMethod = &SquidMethods;
79 #endif
80 
81  if (BIO *bio = BIO_new(useMethod)) {
82  BIO_int_ctrl(bio, BIO_C_SET_FD, type, fd);
83  return bio;
84  }
85  return nullptr;
86 }
87 
88 void
89 Ssl::Bio::Link(SSL *ssl, BIO *bio)
90 {
91  SSL_set_bio(ssl, bio, bio); // cannot fail
92  SSL_set_info_callback(ssl, &squid_ssl_info); // does not provide diagnostic
93 }
94 
95 Ssl::Bio::Bio(const int anFd): fd_(anFd)
96 {
97  debugs(83, 7, "Bio constructed, this=" << this << " FD " << fd_);
98 }
99 
101 {
102  debugs(83, 7, "Bio destructing, this=" << this << " FD " << fd_);
103 }
104 
105 int Ssl::Bio::write(const char *buf, int size, BIO *table)
106 {
107  errno = 0;
108 #if _SQUID_WINDOWS_
109  const int result = socket_write_method(fd_, buf, size);
110 #else
111  const int result = default_write_method(fd_, buf, size);
112 #endif
113  const int xerrno = errno;
114  debugs(83, 5, "FD " << fd_ << " wrote " << result << " <= " << size);
115 
116  BIO_clear_retry_flags(table);
117  if (result < 0) {
118  const bool ignoreError = ignoreErrno(xerrno) != 0;
119  debugs(83, 5, "error: " << xerrno << " ignored: " << ignoreError);
120  if (ignoreError)
121  BIO_set_retry_write(table);
122  }
123 
124  return result;
125 }
126 
127 int
128 Ssl::Bio::read(char *buf, int size, BIO *table)
129 {
130  errno = 0;
131 #if _SQUID_WINDOWS_
132  const int result = socket_read_method(fd_, buf, size);
133 #else
134  const int result = default_read_method(fd_, buf, size);
135 #endif
136  const int xerrno = errno;
137  debugs(83, 5, "FD " << fd_ << " read " << result << " <= " << size);
138 
139  BIO_clear_retry_flags(table);
140  if (result < 0) {
141  const bool ignoreError = ignoreErrno(xerrno) != 0;
142  debugs(83, 5, "error: " << xerrno << " ignored: " << ignoreError);
143  if (ignoreError)
144  BIO_set_retry_read(table);
145  }
146 
147  return result;
148 }
149 
152 void
153 Ssl::Bio::stateChanged(const SSL *ssl, int where, int)
154 {
155  // Here we can use (where & STATE) to check the current state.
156  // Many STATE values are possible, including: SSL_CB_CONNECT_LOOP,
157  // SSL_CB_ACCEPT_LOOP, SSL_CB_HANDSHAKE_START, and SSL_CB_HANDSHAKE_DONE.
158  // For example:
159  // if (where & SSL_CB_HANDSHAKE_START)
160  // debugs(83, 9, "Trying to establish the SSL connection");
161  // else if (where & SSL_CB_HANDSHAKE_DONE)
162  // debugs(83, 9, "SSL connection established");
163 
164  debugs(83, 7, "FD " << fd_ << " now: 0x" << asHex(where) << ' ' <<
165  SSL_state_string(ssl) << " (" << SSL_state_string_long(ssl) << ")");
166 }
167 
169  Bio(anFd),
170  holdRead_(false),
171  holdWrite_(false),
172  abortReason(nullptr)
173 {
174  renegotiations.configure(10*1000);
175 }
176 
177 void
178 Ssl::ClientBio::stateChanged(const SSL *ssl, int where, int ret)
179 {
180  Ssl::Bio::stateChanged(ssl, where, ret);
181  // detect client-initiated renegotiations DoS (CVE-2011-1473)
182  if (where & SSL_CB_HANDSHAKE_START) {
183  const int reneg = renegotiations.count(1);
184 
185  if (abortReason)
186  return; // already decided and informed the admin
187 
188  if (reneg > RenegotiationsLimit) {
189  abortReason = "renegotiate requests flood";
190  debugs(83, DBG_IMPORTANT, "Terminating TLS connection [from " << fd_table[fd_].ipaddr << "] due to " << abortReason << ". This connection received " <<
191  reneg << " renegotiate requests in the last " <<
192  RenegotiationsWindow << " seconds (and " <<
193  renegotiations.remembered() << " requests total).");
194  }
195  }
196 }
197 
198 int
199 Ssl::ClientBio::write(const char *buf, int size, BIO *table)
200 {
201  if (abortReason) {
202  debugs(83, 3, "BIO on FD " << fd_ << " is aborted");
203  BIO_clear_retry_flags(table);
204  return -1;
205  }
206 
207  if (holdWrite_) {
208  BIO_set_retry_write(table);
209  return 0;
210  }
211 
212  return Ssl::Bio::write(buf, size, table);
213 }
214 
215 int
216 Ssl::ClientBio::read(char *buf, int size, BIO *table)
217 {
218  if (abortReason) {
219  debugs(83, 3, "BIO on FD " << fd_ << " is aborted");
220  BIO_clear_retry_flags(table);
221  return -1;
222  }
223 
224  if (holdRead_) {
225  debugs(83, 7, "Hold flag is set, retry latter. (Hold " << size << "bytes)");
226  BIO_set_retry_read(table);
227  return -1;
228  }
229 
230  if (!rbuf.isEmpty()) {
231  int bytes = (size <= (int)rbuf.length() ? size : rbuf.length());
232  memcpy(buf, rbuf.rawContent(), bytes);
233  rbuf.consume(bytes);
234  return bytes;
235  } else
236  return Ssl::Bio::read(buf, size, table);
237 
238  return -1;
239 }
240 
242  Bio(anFd),
243  helloMsgSize(0),
244  helloBuild(false),
245  allowSplice(false),
246  allowBump(false),
247  holdWrite_(false),
248  record_(false),
249  parsedHandshake(false),
250  parseError(false),
251  bumpMode_(bumpNone),
252  rbufConsumePos(0),
253  parser_(Security::HandshakeParser::fromServer)
254 {
255 }
256 
257 void
258 Ssl::ServerBio::stateChanged(const SSL *ssl, int where, int ret)
259 {
260  Ssl::Bio::stateChanged(ssl, where, ret);
261 }
262 
263 void
265 {
266  clientTlsDetails = details;
267  clientSentHello = aHello;
268 };
269 
270 int
271 Ssl::ServerBio::read(char *buf, int size, BIO *table)
272 {
273  if (parsedHandshake) // done parsing TLS Hello
274  return readAndGive(buf, size, table);
275  else
276  return readAndParse(buf, size, table);
277 }
278 
280 int
281 Ssl::ServerBio::readAndGive(char *buf, const int size, BIO *table)
282 {
283  // If we have unused buffered bytes, give those bytes to OpenSSL now,
284  // before reading more. TODO: Read if we have buffered less than size?
285  if (rbufConsumePos < rbuf.length())
286  return giveBuffered(buf, size);
287 
288  if (record_) {
289  const int result = readAndBuffer(table);
290  if (result <= 0)
291  return result;
292  return giveBuffered(buf, size);
293  }
294 
295  return Ssl::Bio::read(buf, size, table);
296 }
297 
300 int
301 Ssl::ServerBio::readAndParse(char *buf, const int size, BIO *table)
302 {
303  const int result = readAndBuffer(table);
304  if (result <= 0)
305  return result;
306 
307  try {
308  if (!parser_.parseHello(rbuf)) {
309  // need more data to finish parsing
310  BIO_set_retry_read(table);
311  return -1;
312  }
313  parsedHandshake = true; // done parsing (successfully)
314  }
315  catch (const std::exception &ex) {
316  debugs(83, 2, "parsing error on FD " << fd_ << ": " << ex.what());
317  parsedHandshake = true; // done parsing (due to an error)
318  parseError = true;
319  }
320 
321  return giveBuffered(buf, size);
322 }
323 
326 int
328 {
329  char *space = rbuf.rawAppendStart(SQUID_TCP_SO_RCVBUF);
330  const int result = Ssl::Bio::read(space, SQUID_TCP_SO_RCVBUF, table);
331  if (result <= 0)
332  return result;
333 
334  rbuf.rawAppendFinish(space, result);
335  return result;
336 }
337 
340 int
341 Ssl::ServerBio::giveBuffered(char *buf, const int size)
342 {
343  if (rbuf.length() <= rbufConsumePos)
344  return -1; // buffered nothing yet
345 
346  const int unsent = rbuf.length() - rbufConsumePos;
347  const int bytes = (size <= unsent ? size : unsent);
348  memcpy(buf, rbuf.rawContent() + rbufConsumePos, bytes);
349  rbufConsumePos += bytes;
350  debugs(83, 7, bytes << "<=" << size << " bytes to OpenSSL");
351  return bytes;
352 }
353 
354 int
355 Ssl::ServerBio::write(const char *buf, int size, BIO *table)
356 {
357 
358  if (holdWrite_) {
359  debugs(83, 7, "postpone writing " << size << " bytes to SSL FD " << fd_);
360  BIO_set_retry_write(table);
361  return -1;
362  }
363 
364  if (!helloBuild && (bumpMode_ == Ssl::bumpPeek || bumpMode_ == Ssl::bumpStare)) {
365  // We have not seen any bytes, so the buffer must start with an
366  // OpenSSL-generated TLSPlaintext record containing, for example, a
367  // ClientHello or an alert message. We check these assumptions before we
368  // substitute that record/message with clientSentHello.
369  // TODO: Move these checks to where we actually rely on them.
370  debugs(83, 7, "to-server" << Raw("TLSPlaintext", buf, size).hex());
371  Must(size >= 2); // enough for version and content_type checks below
372  Must(buf[1] >= 3); // record's version.major; determines buf[0] meaning
373  Must(20 <= buf[0] && buf[0] <= 23); // valid TLSPlaintext.content_type
374 
375  //Hello message is the first message we write to server
376  assert(helloMsg.isEmpty());
377 
378  if (bumpMode_ == Ssl::bumpPeek) {
379  // we should not be here if we failed to parse the client-sent ClientHello
380  Must(!clientSentHello.isEmpty());
381  allowSplice = true;
382  // Replace OpenSSL-generated ClientHello with client-sent one.
383  helloMsg.append(clientSentHello);
384  debugs(83, 7, "FD " << fd_ << ": Using client-sent ClientHello for peek mode");
385  } else { /*Ssl::bumpStare*/
386  allowBump = true;
387  }
388 
389  // if we did not use the client-sent ClientHello, then use the OpenSSL-generated one
390  if (helloMsg.isEmpty())
391  helloMsg.append(buf, size);
392 
393  helloBuild = true;
394  helloMsgSize = helloMsg.length();
395 
396  if (allowSplice) {
397  // Do not write yet.....
398  BIO_set_retry_write(table);
399  return -1;
400  }
401  }
402 
403  if (!helloMsg.isEmpty()) {
404  debugs(83, 7, "buffered write for FD " << fd_);
405  int ret = Ssl::Bio::write(helloMsg.rawContent(), helloMsg.length(), table);
406  helloMsg.consume(ret);
407  if (!helloMsg.isEmpty()) {
408  // We need to retry sendind data.
409  // Say to openSSL to retry sending hello message
410  BIO_set_retry_write(table);
411  return -1;
412  }
413 
414  // Sending hello message complete. Do not send more data for now...
415  holdWrite_ = true;
416 
417  // spoof openSSL that we write what it ask us to write
418  return size;
419  } else
420  return Ssl::Bio::write(buf, size, table);
421 }
422 
423 void
425 {
426  if (!helloMsg.isEmpty()) {
427  int ret = Ssl::Bio::write(helloMsg.rawContent(), helloMsg.length(), table);
428  helloMsg.consume(ret);
429  }
430 }
431 
432 bool
434 {
435  return parser_.resumingSession;
436 }
437 
438 bool
440 {
441  return parser_.details->tlsSupportedVersion &&
442  Security::Tls1p3orLater(parser_.details->tlsSupportedVersion);
443 }
444 
446 static int
448 {
449 #if !HAVE_LIBCRYPTO_BIO_GET_INIT
450  bi->init = 0; // set when we store Bio object and socket fd (BIO_C_SET_FD)
451  bi->num = 0;
452  bi->flags = 0;
453 #else
454  // No need to set more, openSSL initialize BIO memory to zero.
455 #endif
456 
457  BIO_set_data(bi, nullptr);
458  return 1;
459 }
460 
462 static int
463 squid_bio_destroy(BIO *table)
464 {
465  delete static_cast<Ssl::Bio*>(BIO_get_data(table));
466  BIO_set_data(table, nullptr);
467  return 1;
468 }
469 
471 static int
472 squid_bio_write(BIO *table, const char *buf, int size)
473 {
474  Ssl::Bio *bio = static_cast<Ssl::Bio*>(BIO_get_data(table));
475  assert(bio);
476  return bio->write(buf, size, table);
477 }
478 
480 static int
481 squid_bio_read(BIO *table, char *buf, int size)
482 {
483  Ssl::Bio *bio = static_cast<Ssl::Bio*>(BIO_get_data(table));
484  assert(bio);
485  return bio->read(buf, size, table);
486 }
487 
489 static int
490 squid_bio_puts(BIO *table, const char *str)
491 {
492  assert(str);
493  return squid_bio_write(table, str, strlen(str));
494 }
495 
497 static long
498 squid_bio_ctrl(BIO *table, int cmd, long arg1, void *arg2)
499 {
500  debugs(83, 5, table << ' ' << cmd << '(' << arg1 << ", " << arg2 << ')');
501 
502  switch (cmd) {
503  case BIO_C_SET_FD: {
504  assert(arg2);
505  const int fd = *static_cast<int*>(arg2);
506  Ssl::Bio *bio;
507  if (arg1 == Security::Io::BIO_TO_SERVER)
508  bio = new Ssl::ServerBio(fd);
509  else
510  bio = new Ssl::ClientBio(fd);
511  assert(!BIO_get_data(table));
512  BIO_set_data(table, bio);
513  BIO_set_init(table, 1);
514  return 0;
515  }
516 
517  case BIO_C_GET_FD:
518  if (BIO_get_init(table)) {
519  Ssl::Bio *bio = static_cast<Ssl::Bio*>(BIO_get_data(table));
520  assert(bio);
521  if (arg2)
522  *static_cast<int*>(arg2) = bio->fd();
523  return bio->fd();
524  }
525  return -1;
526 
527  case BIO_CTRL_DUP:
528  // Should implemented if the SSL_dup openSSL API function
529  // used anywhere in squid.
530  return 0;
531 
532  case BIO_CTRL_FLUSH:
533  if (BIO_get_init(table)) {
534  Ssl::Bio *bio = static_cast<Ssl::Bio*>(BIO_get_data(table));
535  assert(bio);
536  bio->flush(table);
537  return 1;
538  }
539  return 0;
540 
541  /* we may also need to implement these:
542  case BIO_CTRL_RESET:
543  case BIO_C_FILE_SEEK:
544  case BIO_C_FILE_TELL:
545  case BIO_CTRL_INFO:
546  case BIO_CTRL_GET_CLOSE:
547  case BIO_CTRL_SET_CLOSE:
548  case BIO_CTRL_PENDING:
549  case BIO_CTRL_WPENDING:
550  */
551  default:
552  return 0;
553 
554  }
555 
556  return 0; /* NOTREACHED */
557 }
558 
560 static void
561 squid_ssl_info(const SSL *ssl, int where, int ret)
562 {
563  if (BIO *table = SSL_get_rbio(ssl)) {
564  if (Ssl::Bio *bio = static_cast<Ssl::Bio*>(BIO_get_data(table)))
565  bio->stateChanged(ssl, where, ret);
566  }
567 }
568 
569 void
571 {
572  // To increase the possibility for bumping after peek mode selection or
573  // splicing after stare mode selection it is good to set the
574  // SSL protocol version.
575  // The SSL_set_ssl_method is wrong here because it will restrict the
576  // permitted transport version to be identical to the version used in the
577  // ClientHello message.
578  // For example will prevent comunnicating with a tls1.0 server if the
579  // client sent and tlsv1.2 Hello message.
580 #if defined(TLSEXT_NAMETYPE_host_name)
581  if (!details->serverName.isEmpty()) {
582  SSL_set_tlsext_host_name(ssl, details->serverName.c_str());
583  }
584 #endif
585 
586  if (!details->ciphers.empty()) {
587  SBuf strCiphers;
588  for (auto cipherId: details->ciphers) {
589  unsigned char cbytes[3];
590  cbytes[0] = (cipherId >> 8) & 0xFF;
591  cbytes[1] = cipherId & 0xFF;
592  cbytes[2] = 0;
593  if (const auto c = SSL_CIPHER_find(ssl, cbytes)) {
594  if (!strCiphers.isEmpty())
595  strCiphers.append(":");
596  strCiphers.append(SSL_CIPHER_get_name(c));
597  }
598  }
599  if (!strCiphers.isEmpty())
600  SSL_set_cipher_list(ssl, strCiphers.c_str());
601  }
602 
603 #if defined(SSL_OP_NO_COMPRESSION) /* XXX: OpenSSL 0.9.8k lacks SSL_OP_NO_COMPRESSION */
604  if (!details->compressionSupported)
605  SSL_set_options(ssl, SSL_OP_NO_COMPRESSION);
606 #endif
607 
608 #if defined(SSL_OP_NO_TLSv1_3)
609  // avoid "inappropriate fallback" OpenSSL error messages
610  if (details->tlsSupportedVersion && Security::Tls1p2orEarlier(details->tlsSupportedVersion))
611  SSL_set_options(ssl, SSL_OP_NO_TLSv1_3);
612 #endif
613 
614 #if defined(TLSEXT_STATUSTYPE_ocsp)
615  if (details->tlsStatusRequest)
616  SSL_set_tlsext_status_type(ssl, TLSEXT_STATUSTYPE_ocsp);
617 #endif
618 
619 #if defined(TLSEXT_TYPE_application_layer_protocol_negotiation)
620  if (!details->tlsAppLayerProtoNeg.isEmpty()) {
621  if (bumpMode == Ssl::bumpPeek)
622  SSL_set_alpn_protos(ssl, (const unsigned char*)details->tlsAppLayerProtoNeg.rawContent(), details->tlsAppLayerProtoNeg.length());
623  else {
624  static const unsigned char supported_protos[] = {8, 'h','t','t', 'p', '/', '1', '.', '1'};
625  SSL_set_alpn_protos(ssl, supported_protos, sizeof(supported_protos));
626  }
627  }
628 #endif
629 }
630 
631 #endif // USE_OPENSSL
632 
@ bumpPeek
Definition: support.h:132
static void Link(SSL *ssl, BIO *bio)
Tells ssl connection to use BIO and monitor state via stateChanged()
Definition: bio.cc:89
static int squid_bio_create(BIO *h)
initializes BIO table after allocation
Definition: bio.cc:447
void setClientFeatures(Security::TlsDetails::Pointer const &details, SBuf const &hello)
Sets the random number to use in client SSL HELLO message.
Definition: bio.cc:264
int read(char *buf, int size, BIO *table) override
Definition: bio.cc:271
bool isEmpty() const
Definition: SBuf.h:435
void configure(double horizonSeconds)
0=remember nothing; -1=forget nothing; new value triggers clear()
void applyTlsDetailsToSSL(SSL *ssl, Security::TlsDetails::Pointer const &details, Ssl::BumpMode bumpMode)
Definition: bio.cc:570
const SSL_CIPHER * SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr)
Definition: openssl.h:139
virtual ~Bio()
Definition: bio.cc:100
Definition: SBuf.h:93
BumpMode
Definition: support.h:132
virtual void stateChanged(const SSL *ssl, int where, int ret)
Definition: bio.cc:153
ClientBio(const int anFd)
Definition: bio.cc:168
void stateChanged(const SSL *ssl, int where, int ret) override
Definition: bio.cc:178
int readAndGive(char *buf, const int size, BIO *table)
Read and give everything to OpenSSL.
Definition: bio.cc:281
void * BIO_get_data(BIO *table)
Definition: openssl.h:62
ServerBio(const int anFd)
Definition: bio.cc:241
@ BIO_TO_SERVER
Definition: forward.h:172
int BIO_get_init(BIO *table)
Definition: openssl.h:82
static BIO * Create(const int fd, Security::Io::Type type)
Definition: bio.cc:63
Definition: Raw.h:20
void BIO_set_data(BIO *table, void *data)
Definition: openssl.h:68
void flush(BIO *table) override
Definition: bio.cc:424
int size
Definition: ModDevPoll.cc:69
#define NULL
Definition: types.h:145
virtual int read(char *buf, int size, BIO *table)
Reads data from socket.
Definition: bio.cc:128
bool Tls1p2orEarlier(const AnyP::ProtocolVersion &p)
whether the given TLS/SSL protocol is TLS v1.2 or earlier, including SSL
Definition: Handshake.h:153
int default_read_method(int, char *, int)
Definition: fd.cc:129
int readAndBuffer(BIO *table)
Definition: bio.cc:327
virtual int write(const char *buf, int size, BIO *table)
Writes the given data to socket.
Definition: bio.cc:105
AsHex< Integer > asHex(const Integer n)
a helper to ease AsHex object creation
Definition: IoManip.h:169
static int squid_bio_puts(BIO *h, const char *str)
implements puts() via write()
Definition: bio.cc:490
#define assert(EX)
Definition: assert.h:17
static int squid_bio_destroy(BIO *data)
cleans BIO table before deallocation
Definition: bio.cc:463
bool resumingSession()
Definition: bio.cc:433
const char * c_str()
Definition: SBuf.cc:516
int default_write_method(int, const char *, int)
Definition: fd.cc:135
Bio(const int anFd)
Definition: bio.cc:95
SBuf & append(const SBuf &S)
Definition: SBuf.cc:185
bool Tls1p3orLater(const AnyP::ProtocolVersion &p)
whether the given TLS/SSL protocol is TLS v1.3 or later
Definition: Handshake.h:160
@ bumpStare
Definition: support.h:132
int ignoreErrno(int ierrno)
Definition: comm.cc:1422
#define fd_table
Definition: fde.h:189
BIO source and sink node, handling socket I/O and monitoring SSL state.
Definition: bio.h:33
static int squid_bio_read(BIO *h, char *buf, int size)
wrapper for Bio::read()
Definition: bio.cc:481
bool encryptedCertificates() const
Definition: bio.cc:439
const int fd_
the SSL socket we are reading and writing
Definition: bio.h:63
static long squid_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2)
other BIO manipulations (those without dedicated callbacks in BIO table)
Definition: bio.cc:498
FadingCounter renegotiations
client requested renegotiations limit control
Definition: bio.h:101
int read(char *buf, int size, BIO *table) override
Definition: bio.cc:216
static int squid_bio_write(BIO *h, const char *buf, int num)
wrapper for Bio::write()
Definition: bio.cc:472
int giveBuffered(char *buf, const int size)
Definition: bio.cc:341
@ bumpNone
Definition: support.h:132
void stateChanged(const SSL *ssl, int where, int ret) override
The ServerBio version of the Ssl::Bio::stateChanged method.
Definition: bio.cc:258
#define Must(condition)
Definition: TextException.h:75
#define DBG_IMPORTANT
Definition: Stream.h:38
static void squid_ssl_info(const SSL *ssl, int where, int ret)
wrapper for Bio::stateChanged()
Definition: bio.cc:561
int readAndParse(char *buf, const int size, BIO *table)
Definition: bio.cc:301
int write(const char *buf, int size, BIO *table) override
Definition: bio.cc:355
void BIO_set_init(BIO *table, int init)
Definition: openssl.h:74
Network/connection security abstraction layer.
Definition: Connection.h:33
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:192
const char * bumpMode(int bm)
Definition: support.h:144
static BIO_METHOD SquidMethods
Definition: bio.cc:48
virtual void flush(BIO *)
Definition: bio.h:47
int unsigned int
Definition: stub_fd.cc:19
int write(const char *buf, int size, BIO *table) override
The ClientBio version of the Ssl::Bio::write method.
Definition: bio.cc:199

 

Introduction

Documentation

Support

Miscellaneous