Fix bssl handling of buffered read data.

If the peer sends us one record that exceeds buffer, the socket will no
longer flag as readable, because data has been consumed, but SSL_read
should still be called to drain data. bssl would instead not notice and
only surface the data later on.

This can (currently) be reproduced by sending "HEAD / HTTP/1.1" to
www.google.com.

Change-Id: I73cdbe104ba6be56fc033429999e630f0eb852d8
Reviewed-on: https://boringssl-review.googlesource.com/28166
Commit-Queue: Steven Valdez <svaldez@google.com>
Reviewed-by: Steven Valdez <svaldez@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/tool/transport_common.cc b/tool/transport_common.cc
index f1b03ab..1e9b72f 100644
--- a/tool/transport_common.cc
+++ b/tool/transport_common.cc
@@ -699,28 +699,30 @@
     }
 
     if (socket_ready) {
-      uint8_t buffer[512];
-      int ssl_ret = SSL_read(ssl, buffer, sizeof(buffer));
+      for (;;) {
+        uint8_t buffer[512];
+        int ssl_ret = SSL_read(ssl, buffer, sizeof(buffer));
 
-      if (ssl_ret < 0) {
-        int ssl_err = SSL_get_error(ssl, ssl_ret);
-        if (ssl_err == SSL_ERROR_WANT_READ) {
-          continue;
+        if (ssl_ret < 0) {
+          int ssl_err = SSL_get_error(ssl, ssl_ret);
+          if (ssl_err == SSL_ERROR_WANT_READ) {
+            break;
+          }
+          PrintSSLError(stderr, "Error while reading", ssl_err, ssl_ret);
+          return false;
+        } else if (ssl_ret == 0) {
+          return true;
         }
-        PrintSSLError(stderr, "Error while reading", ssl_err, ssl_ret);
-        return false;
-      } else if (ssl_ret == 0) {
-        return true;
-      }
 
-      ssize_t n;
-      do {
-        n = BORINGSSL_WRITE(1, buffer, ssl_ret);
-      } while (n == -1 && errno == EINTR);
+        ssize_t n;
+        do {
+          n = BORINGSSL_WRITE(1, buffer, ssl_ret);
+        } while (n == -1 && errno == EINTR);
 
-      if (n != ssl_ret) {
-        fprintf(stderr, "Short write to stderr.\n");
-        return false;
+        if (n != ssl_ret) {
+          fprintf(stderr, "Short write to stderr.\n");
+          return false;
+        }
       }
     }
   }