aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJay Satiro <raysatiro@yahoo.com>2016-05-11 21:21:15 -0400
committerJay Satiro <raysatiro@yahoo.com>2016-05-11 21:21:15 -0400
commit2968c839672dc01c45727b161bf1c72d6b804212 (patch)
treea6869f0e43640cfd20b0e0290d04d60f01a2eae8
parent856baf5a46e9d5fb71950a648ac6d1600838584d (diff)
openssl: stricter connection check function
- In the case of recv error, limit returning 'connection still in place' to EINPROGRESS, EAGAIN and EWOULDBLOCK. This is an improvement on the parent commit which changed the openssl connection check to use recv MSG_PEEK instead of SSL_peek. Ref: https://github.com/curl/curl/commit/856baf5#comments
-rw-r--r--lib/vtls/openssl.c43
1 files changed, 36 insertions, 7 deletions
diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c
index 7f7406544..af3c502a7 100644
--- a/lib/vtls/openssl.c
+++ b/lib/vtls/openssl.c
@@ -750,7 +750,7 @@ void Curl_ossl_cleanup(void)
}
/*
- * This function uses SSL_peek to determine connection status.
+ * This function is used to determine connection status.
*
* Return codes:
* 1 means the connection is still in place
@@ -759,17 +759,46 @@ void Curl_ossl_cleanup(void)
*/
int Curl_ossl_check_cxn(struct connectdata *conn)
{
+ /* SSL_peek takes data out of the raw recv buffer without peeking so we use
+ recv MSG_PEEK instead. Bug #795 */
#ifdef MSG_PEEK
char buf;
- if(recv((RECV_TYPE_ARG1)conn->sock[FIRSTSOCKET], (RECV_TYPE_ARG2)&buf,
- (RECV_TYPE_ARG3)1, (RECV_TYPE_ARG4)MSG_PEEK) == 0) {
+ int nread;
+ nread = recv((RECV_TYPE_ARG1)conn->sock[FIRSTSOCKET], (RECV_TYPE_ARG2)&buf,
+ (RECV_TYPE_ARG3)1, (RECV_TYPE_ARG4)MSG_PEEK);
+ if(nread == 0)
return 0; /* connection has been closed */
- }
- else
+ else if(nread == 1)
return 1; /* connection still in place */
-#else
- return -1; /* connection status unknown */
+ else if(nread == -1) {
+ int err = SOCKERRNO;
+ if(err == EINPROGRESS ||
+#if defined(EAGAIN) && (EAGAIN != EWOULDBLOCK)
+ err == EAGAIN ||
+#endif
+ err == EWOULDBLOCK)
+ return 1; /* connection still in place */
+ if(err == ECONNRESET ||
+#ifdef ECONNABORTED
+ err == ECONNABORTED ||
+#endif
+#ifdef ENETDOWN
+ err == ENETDOWN ||
#endif
+#ifdef ENETRESET
+ err == ENETRESET ||
+#endif
+#ifdef ESHUTDOWN
+ err == ESHUTDOWN ||
+#endif
+#ifdef ETIMEDOUT
+ err == ETIMEDOUT ||
+#endif
+ err == ENOTCONN)
+ return 0; /* connection has been closed */
+ }
+#endif
+ return -1; /* connection status unknown */
}
/* Selects an OpenSSL crypto engine