]> granicus.if.org Git - curl/commitdiff
TLS: SSL_peek is not a const operation
authorAnders Bakken <agbakken@gmail.com>
Tue, 10 May 2016 19:49:33 +0000 (12:49 -0700)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 10 May 2016 22:06:40 +0000 (00:06 +0200)
Calling SSL_peek can cause bytes to be read from the raw socket which in
turn can upset the select machinery that determines whether there's data
available on the socket.

Since Curl_ossl_check_cxn only tries to determine whether the socket is
alive and doesn't actually need to see the bytes SSL_peek seems like
the wrong function to call.

We're able to occasionally reproduce a connect timeout due to this
bug. What happens is that Curl doesn't know to call SSL_connect again
after the peek happens since data is buffered in the SSL buffer and thus
select won't fire for this socket.

Closes #795

lib/vtls/openssl.c

index 823dcebbc9fe899dd8fe80288ff5e1e3024e3bb2..7f7406544e1c74ce1138f77be2b70485dadcd098 100644 (file)
@@ -759,17 +759,17 @@ void Curl_ossl_cleanup(void)
  */
 int Curl_ossl_check_cxn(struct connectdata *conn)
 {
-  int rc;
+#ifdef MSG_PEEK
   char buf;
-
-  rc = SSL_peek(conn->ssl[FIRSTSOCKET].handle, (void*)&buf, 1);
-  if(rc > 0)
-    return 1; /* connection still in place */
-
-  if(rc == 0)
+  if(recv((RECV_TYPE_ARG1)conn->sock[FIRSTSOCKET], (RECV_TYPE_ARG2)&buf,
+          (RECV_TYPE_ARG3)1, (RECV_TYPE_ARG4)MSG_PEEK) == 0) {
     return 0; /* connection has been closed */
-
+  }
+  else
+    return 1; /* connection still in place */
+#else
   return -1; /* connection status unknown */
+#endif
 }
 
 /* Selects an OpenSSL crypto engine