Commit 82245eaa authored by Isaac Boukris's avatar Isaac Boukris Committed by Michael Kaufmann
Browse files

Curl_getconnectinfo: avoid checking if the connection is closed

It doesn't benefit us much as the connection could get closed at
any time, and also by checking we lose the ability to determine
if the socket was closed by reading zero bytes.

Reported-by: Michael Kaufmann

Closes https://github.com/curl/curl/pull/1134
parent 6bc10516
Loading
Loading
Loading
Loading
+27 −18
Original line number Original line Diff line number Diff line
@@ -1247,29 +1247,38 @@ curl_socket_t Curl_getconnectinfo(struct Curl_easy *data,
      /* only store this if the caller cares for it */
      /* only store this if the caller cares for it */
      *connp = c;
      *connp = c;
    sockfd = c->sock[FIRSTSOCKET];
    sockfd = c->sock[FIRSTSOCKET];
    /* we have a socket connected, let's determine if the server shut down */
  }
    /* determine if ssl */
  else
    if(c->ssl[FIRSTSOCKET].use) {
    return CURL_SOCKET_BAD;

  return sockfd;
}

/*
 * Check if a connection seems to be alive.
 */
bool Curl_connalive(struct connectdata *conn)
{
  /* First determine if ssl */
  if(conn->ssl[FIRSTSOCKET].use) {
    /* use the SSL context */
    /* use the SSL context */
      if(!Curl_ssl_check_cxn(c))
    if(!Curl_ssl_check_cxn(conn))
        return CURL_SOCKET_BAD;   /* FIN received */
      return false;   /* FIN received */
  }
  }
/* Minix 3.1 doesn't support any flags on recv; just assume socket is OK */
/* Minix 3.1 doesn't support any flags on recv; just assume socket is OK */
#ifdef MSG_PEEK
#ifdef MSG_PEEK
    else if(sockfd != CURL_SOCKET_BAD) {
  else if(conn->sock[FIRSTSOCKET] == CURL_SOCKET_BAD)
    return false;
  else {
    /* use the socket */
    /* use the socket */
    char buf;
    char buf;
      if(recv((RECV_TYPE_ARG1)sockfd, (RECV_TYPE_ARG2)&buf,
    if(recv((RECV_TYPE_ARG1)conn->sock[FIRSTSOCKET], (RECV_TYPE_ARG2)&buf,
            (RECV_TYPE_ARG3)1, (RECV_TYPE_ARG4)MSG_PEEK) == 0) {
            (RECV_TYPE_ARG3)1, (RECV_TYPE_ARG4)MSG_PEEK) == 0) {
        return CURL_SOCKET_BAD;   /* FIN received */
      return false;   /* FIN received */
    }
    }
  }
  }
#endif
#endif
  }
  return true;
  else
    return CURL_SOCKET_BAD;

  return sockfd;
}
}


/*
/*
+5 −0
Original line number Original line Diff line number Diff line
@@ -52,6 +52,11 @@ time_t Curl_timeleft(struct Curl_easy *data,
curl_socket_t Curl_getconnectinfo(struct Curl_easy *data,
curl_socket_t Curl_getconnectinfo(struct Curl_easy *data,
                                  struct connectdata **connp);
                                  struct connectdata **connp);


/*
 * Check if a connection seems to be alive.
 */
bool Curl_connalive(struct connectdata *conn);

#ifdef USE_WINSOCK
#ifdef USE_WINSOCK
/* When you run a program that uses the Windows Sockets API, you may
/* When you run a program that uses the Windows Sockets API, you may
   experience slow performance when you copy data to a TCP server.
   experience slow performance when you copy data to a TCP server.
+4 −7
Original line number Original line Diff line number Diff line
@@ -140,7 +140,7 @@ static CURLcode rtsp_setup_connection(struct connectdata *conn)
 * want to block the application forever while receiving a stream. Therefore,
 * want to block the application forever while receiving a stream. Therefore,
 * we cannot assume that an RTSP socket is dead just because it is readable.
 * we cannot assume that an RTSP socket is dead just because it is readable.
 *
 *
 * Instead, if it is readable, run Curl_getconnectinfo() to peek at the socket
 * Instead, if it is readable, run Curl_connalive() to peek at the socket
 * and distinguish between closed and data.
 * and distinguish between closed and data.
 */
 */
bool Curl_rtsp_connisdead(struct connectdata *check)
bool Curl_rtsp_connisdead(struct connectdata *check)
@@ -157,12 +157,9 @@ bool Curl_rtsp_connisdead(struct connectdata *check)
    /* socket is in an error state */
    /* socket is in an error state */
    ret_val = TRUE;
    ret_val = TRUE;
  }
  }
  else if((sval & CURL_CSELECT_IN) && check->data) {
  else if(sval & CURL_CSELECT_IN) {
    /* readable with no error. could be closed or could be alive but we can
    /* readable with no error. could still be closed */
       only check if we have a proper Curl_easy for the connection */
    ret_val = !Curl_connalive(check);
    curl_socket_t connectinfo = Curl_getconnectinfo(check->data, &check);
    if(connectinfo != CURL_SOCKET_BAD)
      ret_val = FALSE;
  }
  }


  return ret_val;
  return ret_val;