diff options
| -rw-r--r-- | lib/vtls/openssl.c | 43 | 
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  | 
