AsyncSSLSocket getRawBytes fix
authorHeng Hong Lee <henghonglee@fb.com>
Tue, 23 Aug 2016 23:31:17 +0000 (16:31 -0700)
committerFacebook Github Bot <facebook-github-bot-bot@fb.com>
Tue, 23 Aug 2016 23:39:55 +0000 (16:39 -0700)
Summary:
While adding logging around our socket and looking into `AsyncSSLSocket` it seems like the data that is actually written into the socket is not correctly attributed.  I
added logs and printed out what happens on the socket layer, P56563098 in this paste you can see that the `[fishhook]` logs are actually those added in D3698728.

Those are the actual bytes written onto the socket, in the paste, the bytes that are written by the AsyncSocket::bioWrite method are
the ones that actually get written onto the socket. some of the bytes written into the bio comes from bf_buff.c and bss_mem.c which are not eventually attributed to a
socket message and will be incorrectly counted when getRawBytesWritten/Read invoked on AsyncSSLSocket.cpp

Unfortunately/Fortunately this issue is not symmetrical and does not manifest in the getRawBytesReceived in AsyncSSLSocket, reading the bio for read bytes
correctly attributes the actual number of bytes written on the socket. moreover, pulling the asyncsocket data for getRawBytesRead doesnt give the full read bytes on
wire because SSL_connect and SSL_read dont return the number of bytes they read but return the number of bytes without the TLS bytes used.

siyengar seems like a right person to look at this. so adding him here.

Would love to discuss more about this and am open to iterating more on this solution

Reviewed By: knekritz

Differential Revision: D3698744

fbshipit-source-id: 541aa478778b9607f51db194fcbfe28bd23c737f

folly/io/async/AsyncSSLSocket.cpp

index 5efa402e7e7001684307fc192c43554ee4decaef..05553068b34ce56149bf917ac1f29a9f82ee6fef 100644 (file)
@@ -417,10 +417,19 @@ void AsyncSSLSocket::setEorTracking(bool track) {
 }
 
 size_t AsyncSSLSocket::getRawBytesWritten() const {
+  // The bio(s) in the write path are in a chain
+  // each bio flushes to the next and finally written into the socket
+  // to get the rawBytesWritten on the socket,
+  // get the write bytes of the last bio
   BIO *b;
   if (!ssl_ || !(b = SSL_get_wbio(ssl_))) {
     return 0;
   }
+  BIO* next = BIO_next(b);
+  while (next != NULL) {
+    b = next;
+    next = BIO_next(b);
+  }
 
   return BIO_number_written(b);
 }