]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Fix bugs and polish peek-and-splice
authorChristos Tsantilas <chtsanti@users.sourceforge.net>
Fri, 8 Aug 2014 16:05:07 +0000 (19:05 +0300)
committerChristos Tsantilas <chtsanti@users.sourceforge.net>
Fri, 8 Aug 2014 16:05:07 +0000 (19:05 +0300)
This patch:
  - Add test in configure script to check if OpenSSL hacks can be supported.
    These tests enable the SQUID_USE_OPENSSL_HELLO_OVERWRITE_HACK in autoconf.h
  - Fixes peek-and splice related documentation , the step1, step2, step3 names
    now used instead of the SslBump[1,2,3] as bumping steps
  - Many fixes in bio subsystem:
     * investigate the Ssl::Bio::sslFeatures::applyToSSL method to configure
       and SSL object the features included in sslFeatures object
     * rename Ssl::ClientBio::headerState to Ssl::ClientBio::helloState
     * rename Ssl::ClientBio::headerSize to Ssl::ClientBio::helloSize
     * investigate the Ssl::ClientBio::HelloReadState enum to describe
       the ssl hello message read state
     * Ssl::ServerBio::write should return the size of the data the openSSL
       ask from us to write to server, else it abort SSL connection with error
     * Do not overwrite openSSL SSL object with client hello on Peek mode if
       we can not support web client SSL features. This is causes problems
       and openSSL may abort the connection with error.
       The adjustSSL function does not need the "force" parameter any more.
     * If SQUID_USE_OPENSSL_HELLO_OVERWRITE_HACK is not defined adjustSSL
       return always false.
     * document bio related classes
  - TunnelStateData::logTag_ptr:
      * try to set TunnelStateData::logTag_ptr when peek and splice mode is used
      * the TunnelStateData::logTag_ptr is not initialized in constructure
      * Do not use TunnelStateData::logTag_ptr if it is not defined for a reason
  - Try to set delay pools settings inside switchToTunnel when peek-and-splice
    mode is used
  - Remove unsused code inside switchToTunnel method (tunnel.cc file)
  - Other minor changes

acinclude/lib-checks.m4
configure.ac
src/cf.data.pre
src/external_acl.cc
src/ssl/PeerConnector.cc
src/ssl/bio.cc
src/ssl/bio.h
src/tunnel.cc

index 2bf98ee0aab651ad1137d10d01bab909f343fb2e..6e43151863c2731ffd0ec9ee883715d770554714 100644 (file)
@@ -277,3 +277,45 @@ AC_DEFUN([SQUID_CHECK_OPENSSL_TXTDB],[
 
 SQUID_STATE_ROLLBACK(check_TXTDB)
 ])
+
+dnl Check if we can rewrite the hello message stored in SSL openSSL object
+dnl The tests are very basic, just check if the required SSL members exist
+dnl in SSL structure.
+AC_DEFUN([SQUID_CHECK_OPENSSL_HELLO_OVERWRITE_HACK],[
+  AH_TEMPLATE(SQUID_USE_OPENSSL_HELLO_OVERWRITE_HACK, "Define to 1 if hello message can be overwritten in SSL struct")
+  SQUID_STATE_SAVE(check_openSSL_overwrite_hack)
+  AC_MSG_CHECKING(whether hello message can be overwritten in SSL struct)
+
+  AC_COMPILE_IFELSE([
+  AC_LANG_PROGRAM(
+    [
+     #include <openssl/ssl.h>
+     #include <openssl/err.h>
+     #include <assert.h>
+    ],
+    [
+    SSL *ssl;
+    char *random, *msg;
+    memcpy(ssl->s3->client_random, random, SSL3_RANDOM_SIZE);
+    SSL3_BUFFER *wb=&(ssl->s3->wbuf);
+    assert(wb->len == 0);
+    memcpy(wb->buf, msg, 0);
+    assert(wb->left == 0);
+    memcpy(ssl->init_buf->data, msg, 0);
+    ssl->init_num = 0;
+    ssl->s3->wpend_ret = 0;
+    ssl->s3->wpend_tot = 0;
+    ])
+  ],
+  [
+   AC_DEFINE(SQUID_USE_OPENSSL_HELLO_OVERWRITE_HACK, 1)
+   AC_MSG_RESULT([yes])
+  ],
+  [
+   AC_MSG_RESULT([no])
+  ],
+  [])
+
+SQUID_STATE_ROLLBACK(check_openSSL_overwrite_hack)
+]
+)
index db550d339336b2256b43c1e2deb96912343761b0..e747d3ef609377cf62f69ef9182e29fc12381167 100644 (file)
@@ -1336,6 +1336,7 @@ if test "x$with_openssl" = "xyes"; then
     SQUID_CHECK_OPENSSL_GETCERTIFICATE_WORKS
     SQUID_CHECK_OPENSSL_CONST_SSL_METHOD
     SQUID_CHECK_OPENSSL_TXTDB
+    SQUID_CHECK_OPENSSL_HELLO_OVERWRITE_HACK
   fi
   if test "x$SSLLIB" = "x"; then
     AC_MSG_ERROR([Required OpenSSL library not found])
index 157c43e030814e35f0f6ac67e772258c2747b937..0e6a078faf3b8d809aee9d866bb28ac8e55bc315 100644 (file)
@@ -1101,9 +1101,9 @@ IF USE_OPENSSL
          # At each SslBump step, Squid evaluates ssl_bump directives to find
          # the next bumping action (e.g., peek or splice). Valid SslBump step
          # values and the corresponding ssl_bump evaluation moments are:
-         #   SslBump1: After getting TCP-level and HTTP CONNECT info.
-         #   SslBump2: After getting SSL Client Hello info.
-         #   SslBump3: After getting SSL Server Hello info.
+         #   step1: After getting TCP-level and HTTP CONNECT info.
+         #   step2: After getting SSL Client Hello info.
+         #   step3: After getting SSL Server Hello info.
 ENDIF
        acl aclname any-of acl1 acl2 ...
          # match any one of the acls [fast or slow]
@@ -2415,13 +2415,13 @@ DOC_START
                mimicked server certificate, with the client.
 
            peek
-               Receive client (step SslBump1) or server (step SslBump2)
+               Receive client (step step1) or server (step step2)
                certificate while preserving the possibility of splicing the
                connection. Peeking at the server certificate (during step 2)
                usually precludes bumping of the connection at step 3.
 
            stare
-               Receive client (step SslBump1) or server (step SslBump2)
+               Receive client (step step1) or server (step step2)
                certificate while preserving the possibility of bumping the
                connection. Staring at the server certificate (during step 2)
                usually precludes splicing of the connection at step 3.
@@ -2429,7 +2429,7 @@ DOC_START
            terminate
                Close client and server connections.
 
-       Backward compatibility actions available at step SslBump1:
+       Backward compatibility actions available at step step1:
 
            client-first
                Bump the connection. Establish a secure connection with the
index e70b1295f0b8191467f7237788ba6ba842975c50..0021c9392e7975dffcbfb7bd43fc9a872f4483fb 100644 (file)
@@ -565,7 +565,7 @@ dump_externalAclHelper(StoreEntry * sentry, const char *name, const external_acl
                 DUMP_EXT_ACL_TYPE_FMT(EXT_ACL_USER_CERTCHAIN_RAW, " %%USER_CERTCHAIN_RAW");
                 DUMP_EXT_ACL_TYPE_FMT(EXT_ACL_USER_CERT, " %%USER_CERT_%s", format->header);
                 DUMP_EXT_ACL_TYPE_FMT(EXT_ACL_USER_CA_CERT, " %%USER_CA_CERT_%s", format->header);
-                DUMP_EXT_ACL_TYPE_FMT(SSL_CLIENT_SNI, "ssl::>sni");
+                DUMP_EXT_ACL_TYPE_FMT(SSL_CLIENT_SNI, "%%ssl::>sni");
                 DUMP_EXT_ACL_TYPE_FMT(SSL_SERVER_CERT_SUBJECT, "%%ssl::<cert_subject");
                 DUMP_EXT_ACL_TYPE_FMT(SSL_SERVER_CERT_ISSUER, "%%ssl::<cert_issuer");
 #endif
index d6b2e0135af82810e0b60f89fc2acc54c0eab55c..b4a73f164d2c41943b528d5155d2504e89a0a84a 100644 (file)
@@ -147,17 +147,7 @@ Ssl::PeerConnector::initializeSsl()
         Ssl::ClientBio *clnBio = static_cast<Ssl::ClientBio *>(b->ptr);
         const Ssl::Bio::sslFeatures &features = clnBio->getFeatures();
         if (features.sslVersion != -1) {
-            SSL_set_ssl_method(ssl, Ssl::method(features.toSquidSSLVersion()));
-#ifdef TLSEXT_NAMETYPE_host_name
-            if (!features.serverName.empty())
-                SSL_set_tlsext_host_name(ssl, features.serverName.c_str());
-#endif
-            if (!features.clientRequestedCiphers.empty())
-                SSL_set_cipher_list(ssl, features.clientRequestedCiphers.c_str());
-#ifdef SSL_OP_NO_COMPRESSION /* XXX: OpenSSL 0.9.8k lacks SSL_OP_NO_COMPRESSION */
-            if (features.compressMethod == 0)
-                SSL_set_options(ssl, SSL_OP_NO_COMPRESSION);
-#endif
+            features.applyToSSL(ssl);
             // Should we allow it for all protocols?
             if (features.sslVersion >= 3) {
                 b = SSL_get_rbio(ssl);
@@ -326,12 +316,10 @@ Ssl::PeerConnector::checkForPeekAndSplice(bool checkDone, Ssl::BumpMode peekMode
     if (peekMode < Ssl::bumpSplice)
         peekMode = Ssl::bumpBump;
 
-#if 1 || SSL_BUMP_FORCE_PEEK_OR_SPLICE 
     if (peekMode == Ssl::bumpSplice && !srvBio->canSplice())
         peekMode = Ssl::bumpPeek;
     else if (peekMode == Ssl::bumpBump && !srvBio->canBump())
         peekMode = Ssl::bumpSplice;
-#endif
 
     if (peekMode == Ssl::bumpTerminate || peekMode == Ssl::bumpErr) {
         comm_close(serverConn->fd);
@@ -519,7 +507,7 @@ Ssl::PeerConnector::handleNegotiateError(const int ret)
         // occure in the next SSL_connect call, and we will fail again.
 #if 1
         if ((request->clientConnectionManager->sslBumpMode == Ssl::bumpPeek  || request->clientConnectionManager->sslBumpMode == Ssl::bumpStare) && srvBio->holdWrite()) {
-            debugs(81, DBG_IMPORTANT, "fwdNegotiateSSL: Error but, hold write on SSL connection on FD " << fd);
+            debugs(81, DBG_IMPORTANT, "fwdNegotiateSSL: Error ("  << ERR_error_string(ssl_lib_error, NULL) <<  ") but, hold write on SSL connection on FD " << fd);
             checkForPeekAndSplice(false, Ssl::bumpNone);
             return;
         }
index 691739709152f3880c1bbfd05c612aea9b4f8406..450270781d4cc868df659d4f371385f3987093c3 100644 (file)
@@ -190,7 +190,7 @@ const char *objToString(unsigned char const *bytes, int len)
 int
 Ssl::ClientBio::read(char *buf, int size, BIO *table)
 {
-    if (headerState < 2) {
+    if (helloState < atHelloReceived) {
 
         if (rbuf.isNull())
             rbuf.init(1024, 16384);
@@ -207,7 +207,7 @@ Ssl::ClientBio::read(char *buf, int size, BIO *table)
         debugs(83, 7, "rbuf size: " << rbuf.contentSize());
     }
 
-    if (headerState == 0) {
+    if (helloState == atHelloNone) {
 
         const unsigned char *head = (const unsigned char *)rbuf.content();
         const char *s = objToString(head, rbuf.contentSize());
@@ -219,34 +219,34 @@ Ssl::ClientBio::read(char *buf, int size, BIO *table)
 
         if (head[0] == 0x16) {
             debugs(83, 7, "SSL version 3 handshake message");
-            headerBytes = (head[3] << 8) + head[4];
-            debugs(83, 7, "SSL Header Size: " << headerBytes);
-            headerBytes +=5;
+            helloSize = (head[3] << 8) + head[4];
+            debugs(83, 7, "SSL Header Size: " << helloSize);
+            helloSize +=5;
 #ifdef DO_SSLV23
         } else if ((head[0] & 0x80) && head[2] == 0x01 && head[3] == 0x03) { 
             debugs(83, 7, "SSL version 2 handshake message with v3 support");
-            headerBytes = head[1];
-            headerBytes +=5;
+            helloSize = head[1];
+            helloSize +=5;
 #endif
         }else {
             debugs(83, 7, "Not an SSL acceptable handshake message (SSLv2 message?)");
             return -1;
         }
 
-        headerState = 1; //Next state
+        helloState = atHelloStarted; //Next state
     }
 
-    if (headerState == 1) {
+    if (helloState == atHelloStarted) {
         const unsigned char *head = (const unsigned char *)rbuf.content();
         const char *s = objToString(head, rbuf.contentSize());
         debugs(83, 7, "SSL Header: " << s);
 
-        if (headerBytes > rbuf.contentSize()) {
+        if (helloSize > rbuf.contentSize()) {
             BIO_set_retry_read(table);
             return -1;
         }
         features.get((const unsigned char *)rbuf.content());
-        headerState = 2;
+        helloState = atHelloReceived;
     }
 
     if (holdRead_) {
@@ -255,7 +255,7 @@ Ssl::ClientBio::read(char *buf, int size, BIO *table)
         return -1;
     }
 
-    if (headerState >=2) {
+    if (helloState == atHelloReceived) {
         if (rbuf.hasContent()) {
             int bytes = (size <= rbuf.contentSize() ? size : rbuf.contentSize());
             memcpy(buf, rbuf.content(), bytes);
@@ -305,18 +305,31 @@ Ssl::ServerBio::read(char *buf, int size, BIO *table)
     return bytes;
 }
 
-bool
-adjustSSL(SSL *ssl, Ssl::Bio::sslFeatures &features, bool force)
+
+// This function makes the required checks to examine if the client hello message 
+// can be compatible with the features provided by OpenSSL toolkit.
+// If the features are compatible and can be supported it tries to rewrite SSL
+// structure members, to replace the hello message created by openSSL, with the 
+// web client SSL hello message.
+// This is mostly possible in the cases where the web client uses openSSL library
+// similar with this one used by squid.
+static bool
+adjustSSL(SSL *ssl, Ssl::Bio::sslFeatures &features)
 {
-    bool fail = false;
+#if SQUID_USE_OPENSSL_HELLO_OVERWRITE_HACK
+    if (!ssl->s3) {
+        debugs(83, 5, "No SSLv3 data found!");
+        return false;
+    }
+
     // If the client supports compression but our context does not support
     // we can not adjust.
     if (features.compressMethod && ssl->ctx->comp_methods == NULL) {
         debugs(83, 5, "Client Hello Data supports compression, but we do not!");
-        fail = true;
+        return false;
     }
 
-    //Check ciphers list
+    // Check ciphers list
     size_t token = 0;
     size_t end = 0;
     while (token != std::string::npos) {
@@ -336,14 +349,14 @@ adjustSSL(SSL *ssl, Ssl::Bio::sslFeatures &features, bool force)
       }
       if (!found) {
           debugs(83, 5, "Client Hello Data supports cipher '"<< cipher <<"' but we do not support it!");
-          fail = true;
+          return false;
       }
     }
 
 #if !defined(SSL_TLSEXT_HB_ENABLED)
     if (features.doHeartBeats) {
         debugs(83, 5, "Client Hello Data supports HeartBeats but we do not support!");
-        fail = true;
+        return false;
     }
 #endif
 
@@ -376,7 +389,7 @@ adjustSSL(SSL *ssl, Ssl::Bio::sslFeatures &features, bool force)
 #ifdef TLSEXT_TYPE_use_srtp
             TLSEXT_TYPE_use_srtp,
 #endif
-#if 1 //Allow 13172 Firefox supported extension for testing purposes
+#if 0 //Allow 13172 Firefox supported extension for testing purposes
             13172,
 #endif
             -1
@@ -390,26 +403,19 @@ adjustSSL(SSL *ssl, Ssl::Bio::sslFeatures &features, bool force)
         }
         if (!found) {
             debugs(83, 5, "Extension " << *it <<  " does not supported!");
-            fail = true ;
+            return false;
         }
     }
 
-    if (fail && !force)
+    SSL3_BUFFER *wb=&(ssl->s3->wbuf);
+    if (wb->len < (size_t)features.helloMessage.contentSize())
         return false;
 
-    if (fail) {
-        debugs(83, 5, "Hello Data are OK but can not be bumped any more!");
-    }
-        
-    debugs(83, 5, "Hello Data will be mimicked!");
+    debugs(83, 5, "OpenSSL SSL struct will be adjusted to mimic client hello data!");
 
     //Adjust ssl structure data.
-
     // We need to fix the random in SSL struct:
     memcpy(ssl->s3->client_random, features.client_random, SSL3_RANDOM_SIZE);
-
-    SSL3_BUFFER *wb=&(ssl->s3->wbuf);
-    assert(wb->len > (size_t)features.helloMessage.contentSize());
     memcpy(wb->buf, features.helloMessage.content(), features.helloMessage.contentSize());
     wb->left = features.helloMessage.contentSize();
 
@@ -421,7 +427,10 @@ adjustSSL(SSL *ssl, Ssl::Bio::sslFeatures &features, bool force)
     ssl->init_num = mainHelloSize;
     ssl->s3->wpend_ret = mainHelloSize;
     ssl->s3->wpend_tot = mainHelloSize;
-    return !fail;
+    return true;
+#else
+    return false;
+#endif
 }
 
 int
@@ -447,16 +456,16 @@ Ssl::ServerBio::write(const char *buf, int size, BIO *table)
             assert(!helloMsg.hasContent());
 
             SSL *ssl = fd_table[fd_].ssl;
-            if (featuresSet && ssl && ssl->s3) {
+            if (featuresSet && ssl) {
                 if (bumpMode_ == Ssl::bumpPeek) {
-                    if (adjustSSL(ssl, clientFeatures, true))
+                    if (adjustSSL(ssl, clientFeatures))
                         allowBump = true;
                     allowSplice = true;
                     helloMsg.append(clientFeatures.helloMessage.content(), clientFeatures.helloMessage.contentSize());
                     debugs(83, 7,  "SSL HELLO message for FD " << fd_ << ": Random number is adjusted for peek mode");
                 } else { /*Ssl::bumpStare*/
                     allowBump = true;
-                    if (adjustSSL(ssl, clientFeatures, false)) {
+                    if (adjustSSL(ssl, clientFeatures)) {
                         allowSplice = true;
                         helloMsg.append(clientFeatures.helloMessage.content(), clientFeatures.helloMessage.contentSize());
                         debugs(83, 7,  "SSL HELLO message for FD " << fd_ << ": Random number is adjusted for stare mode");
@@ -493,9 +502,8 @@ Ssl::ServerBio::write(const char *buf, int size, BIO *table)
         // Sending hello message complete. Do not send more data for now...
         holdWrite_ = true;
 
-        // The size should be less than the size of the hello message
-        //assert(size >= helloMsgSize);
-        return helloMsgSize;
+        // spoof openSSL that we write what it ask us to write
+        return size;
     } else
         return Ssl::Bio::write(buf, size, table);
 }
@@ -890,6 +898,30 @@ Ssl::Bio::sslFeatures::parseV23Hello(const unsigned char *hello)
 #endif
 }
 
+void
+Ssl::Bio::sslFeatures::applyToSSL(SSL *ssl) const
+{
+    // To increase the possibility for bumping after peek mode selection or
+    // splicing after stare mode selection it is good to set the 
+    // SSL protocol version.
+    // The SSL_set_ssl_method is not the correct method because it will strict
+    // SSL version which can be used to the SSL version used for client hello message.
+    // For example will prevent comunnicating with a tls1.0 server if the 
+    // client sent and tlsv1.2 Hello message.
+    //SSL_set_ssl_method(ssl, Ssl::method(features.toSquidSSLVersion()));
+#ifdef TLSEXT_NAMETYPE_host_name
+    if (!serverName.empty())
+        SSL_set_tlsext_host_name(ssl, serverName.c_str());
+#endif
+    if (!clientRequestedCiphers.empty())
+        SSL_set_cipher_list(ssl, clientRequestedCiphers.c_str());
+#ifdef SSL_OP_NO_COMPRESSION /* XXX: OpenSSL 0.9.8k lacks SSL_OP_NO_COMPRESSION */
+    if (compressMethod == 0)
+        SSL_set_options(ssl, SSL_OP_NO_COMPRESSION);
+#endif
+
+}
+
 std::ostream &
 Ssl::Bio::sslFeatures::print(std::ostream &os) const
 {
index fb90cd91e6bd12d356baa41664bbab7b3269c63a..e4f0d8cd32c825845ee98c570644c7bd47eb4a7b 100644 (file)
@@ -33,6 +33,8 @@ public:
         std::ostream & print(std::ostream &os) const;
         /// Converts to the internal squid SSL version form the sslVersion
         int toSquidSSLVersion() const;
+        /// Configure the SSL object with the SSL features of the sslFeatures object
+        void applyToSSL(SSL *ssl) const;
     public:
         int sslVersion; ///< The requested/used SSL version
         int compressMethod; ///< The requested/used compressed  method
@@ -80,9 +82,13 @@ protected:
 };
 
 /// BIO node to handle socket IO for squid client side
+/// If bumping is enabled  this Bio detects and analyses client hello message
+/// to retrieve the SSL features supported by the client
 class ClientBio: public Bio {
 public:
-    explicit ClientBio(const int anFd): Bio(anFd), holdRead_(false), holdWrite_(false), headerState(0), headerBytes(0) {}
+    /// The ssl hello message read states
+    typedef enum {atHelloNone = 0, atHelloStarted, atHelloReceived} HelloReadState;
+    explicit ClientBio(const int anFd): Bio(anFd), holdRead_(false), holdWrite_(false), helloState(atHelloNone), helloSize(0) {}
 
     /// The ClientBio version of the Ssl::Bio::stateChanged method
     /// When the client hello message retrieved, fill the 
@@ -108,11 +114,25 @@ private:
     Bio::sslFeatures features;
     bool holdRead_; ///< The read hold state of the bio.
     bool holdWrite_;  ///< The write hold state of the bio.
-    int headerState;
-    int headerBytes;
+    HelloReadState helloState; ///< The SSL hello read state
+    int helloSize; ///< The SSL hello message sent by client size
 };
 
 /// BIO node to handle socket IO for squid server side
+/// If bumping is enabled, analyses the SSL hello message sent by squid OpenSSL
+/// subsystem (step3 bumping step) against bumping mode:
+///   * Peek mode:  Send client hello message instead of the openSSL generated
+///                 hello message and normaly denies bumping and allow only 
+///                 splice or terminate the SSL connection
+///   * Stare mode: Sends the openSSL generated hello message and normaly
+///                 denies splicing and allow bump or terminate the SSL
+///                 connection
+///  If SQUID_USE_OPENSSL_HELLO_OVERWRITE_HACK is enabled also checks if the
+///  openSSL library features are compatible with the features reported in
+///  web client SSL hello message and if it is, overwrites the openSSL SSL
+///  object members to replace hello message with web client hello message.
+///  This is may allow bumping in peek mode and splicing in stare mode after
+///  the server hello message received.
 class ServerBio: public Bio {
 public:
     explicit ServerBio(const int anFd): Bio(anFd), featuresSet(false), helloMsgSize(0), helloBuild(false), allowSplice(false), allowBump(false), holdWrite_(false), record_(false), bumpMode_(bumpNone) {}
@@ -132,11 +152,17 @@ public:
     /// Sets the random number to use in client SSL HELLO message
     void setClientFeatures(const sslFeatures &features);
 
+    /// The write hold state
     bool holdWrite() const {return holdWrite_;}
+    /// Enables or disables the write hold state
     void holdWrite(bool h) {holdWrite_ = h;}
+    /// Enables or disables the input data recording, for internal analysis. 
     void recordInput(bool r) {record_ = r;}
+    /// Whether we can splice or not the SSL stream
     bool canSplice() {return allowSplice;}
+    /// Whether we can bump or not the SSL stream
     bool canBump() {return allowBump;}
+    /// The bumping mode
     void mode(Ssl::BumpMode m) {bumpMode_ = m;}
 private:
     /// A random number to use as "client random" in client hello message
@@ -145,10 +171,10 @@ private:
     MemBuf helloMsg; ///< Used to buffer output data.
     int helloMsgSize;
     bool helloBuild; ///< True if the client hello message sent to the server
-    bool allowSplice;
-    bool allowBump;
+    bool allowSplice; ///< True if the SSL stream can be spliced
+    bool allowBump;  ///< True if the SSL stream can be bumped
     bool holdWrite_;  ///< The write hold state of the bio.
-    bool record_;
+    bool record_; ///< If true the input data recorded to rbuf for internal use
     Ssl::BumpMode bumpMode_;
 };
 
index cf30ae80c68379f078c0846295a9d09e786a9a9d..6b105f348e118dd29a6c3c9376a9546e802c700b 100644 (file)
@@ -272,6 +272,7 @@ TunnelStateData::TunnelStateData() :
         http(),
         request(NULL),
         status_ptr(NULL),
+        logTag_ptr(NULL),
         connectRespBuf(NULL),
         connectReqWriting(false)
 {
@@ -719,7 +720,8 @@ tunnelStartShoveling(TunnelStateData *tunnelState)
 {
     assert(!tunnelState->waitingForConnectExchange());
     *tunnelState->status_ptr = Http::scOkay;
-    *tunnelState->logTag_ptr = LOG_TCP_TUNNEL;
+    if (tunnelState->logTag_ptr)
+        *tunnelState->logTag_ptr = LOG_TCP_TUNNEL;
     if (cbdataReferenceValid(tunnelState)) {
 
         // Shovel any payload already pushed into reply buffer by the server response
@@ -1119,15 +1121,27 @@ switchToTunnel(HttpRequest *request, int *status_ptr, Comm::ConnectionPointer &c
     ++statCounter.server.other.requests;
 
     tunnelState = new TunnelStateData;
-#if USE_DELAY_POOLS
-    //tunnelState->server.setDelayId(DelayId::DelayClient(http));
-#endif
     tunnelState->url = xstrdup(url);
     tunnelState->request = request;
     tunnelState->server.size_ptr = NULL;//????
     tunnelState->status_ptr = status_ptr;
     tunnelState->client.conn = clientConn;
 
+    ConnStateData *conn;
+    if ((conn = request->clientConnectionManager.get())) {
+        ClientSocketContext::Pointer context = conn->getCurrentContext();
+        if (context != NULL && context->http != NULL) {
+            tunnelState->logTag_ptr = &context->http->logType;
+
+#if USE_DELAY_POOLS
+            /* no point using the delayIsNoDelay stuff since tunnel is nice and simple */
+            if (srvConn->getPeer() && srvConn->getPeer()->options.no_delay)
+                tunnelState->server.setDelayId(DelayId::DelayClient(context->http));
+#endif
+        }
+    }
+
+
     comm_add_close_handler(tunnelState->client.conn->fd,
                            tunnelClientClosed,
                            tunnelState);
@@ -1138,13 +1152,6 @@ switchToTunnel(HttpRequest *request, int *status_ptr, Comm::ConnectionPointer &c
     fd_table[clientConn->fd].read_method = &default_read_method;
     fd_table[clientConn->fd].write_method = &default_write_method;
 
-//Server connection
-#if USE_DELAY_POOLS
-    /* no point using the delayIsNoDelay stuff since tunnel is nice and simple */
-//    if (conn->getPeer() && conn->getPeer()->options.no_delay)
-//        tunnelState->server.setDelayId(DelayId());
-#endif
-
     tunnelState->request->hier.note(srvConn, tunnelState->getHost());
 
     tunnelState->server.conn = srvConn;
@@ -1166,26 +1173,13 @@ switchToTunnel(HttpRequest *request, int *status_ptr, Comm::ConnectionPointer &c
     fd_table[srvConn->fd].read_method = &default_read_method;
     fd_table[srvConn->fd].write_method = &default_write_method;
 
-    ConnStateData *conn;
-    if ((conn = request->pinnedConnection()) && conn->serverBump() && conn->serverBump()->step == Ssl::bumpStep2) {
-        SSL *ssl = fd_table[clientConn->fd].ssl;
-        assert(ssl);
-        BIO *b = SSL_get_rbio(ssl);
-        Ssl::ClientBio *srvBio = static_cast<Ssl::ClientBio *>(b->ptr);
-        const MemBuf &buf = srvBio->rBufData();
+    SSL *ssl = fd_table[srvConn->fd].ssl;
+    assert(ssl);
+    BIO *b = SSL_get_rbio(ssl);
+    Ssl::ServerBio *srvBio = static_cast<Ssl::ServerBio *>(b->ptr);
+    const MemBuf &buf = srvBio->rBufData();
 
-        AsyncCall::Pointer call = commCbCall(5,5, "tunnelConnectedWriteDone",
-                                             CommIoCbPtrFun(tunnelConnectedWriteDone, tunnelState));
-        Comm::Write(tunnelState->server.conn, buf.content(), buf.contentSize(), call, NULL);
-    } else {
-        SSL *ssl = fd_table[srvConn->fd].ssl;
-        assert(ssl);
-        BIO *b = SSL_get_rbio(ssl);
-        Ssl::ServerBio *srvBio = static_cast<Ssl::ServerBio *>(b->ptr);
-        const MemBuf &buf = srvBio->rBufData();
-
-        AsyncCall::Pointer call = commCbCall(5,5, "tunnelConnectedWriteDone",
-                                             CommIoCbPtrFun(tunnelConnectedWriteDone, tunnelState));
-        Comm::Write(tunnelState->client.conn, buf.content(), buf.contentSize(), call, NULL);
-    }
+    AsyncCall::Pointer call = commCbCall(5,5, "tunnelConnectedWriteDone",
+                                         CommIoCbPtrFun(tunnelConnectedWriteDone, tunnelState));
+    Comm::Write(tunnelState->client.conn, buf.content(), buf.contentSize(), call, NULL);
 }