Commit b5d170b5 authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

CLOSESOCKETFUNCTION: added

Introduced the initial setup to allow closesocket callbacks by making
sure sclose() is only ever called from one place in the libcurl source
and still run all test cases fine.
parent d4e00090
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -341,6 +341,9 @@ typedef curl_socket_t
                            curlsocktype purpose,
                            struct curl_sockaddr *address);

typedef void
(*curl_closesocket_callback)(void *clientp, curl_socket_t item);

typedef enum {
  CURLIOE_OK,            /* I/O operation successful */
  CURLIOE_UNKNOWNCMD,    /* command was unknown to callback */
@@ -1475,6 +1478,11 @@ typedef enum {
  */
  CINIT(TRANSFER_ENCODING, LONG, 207),

  /* Callback function for closing socket (instead of close(2)). The callback
     should have type curl_closesocket_callback */
  CINIT(CLOSESOCKETFUNCTION, FUNCTIONPOINT, 208),
  CINIT(CLOSESOCKETDATA, OBJECTPOINT, 209),

  CURLOPT_LASTENTRY /* the last unused */
} CURLoption;

+21 −8
Original line number Diff line number Diff line
@@ -510,7 +510,7 @@ static CURLcode trynextip(struct connectdata *conn,
  *connected = FALSE;

  if(sockindex != FIRSTSOCKET) {
    sclose(fd_to_close);
    Curl_closesocket(conn, fd_to_close);
    return CURLE_COULDNT_CONNECT; /* no next */
  }

@@ -525,12 +525,12 @@ static CURLcode trynextip(struct connectdata *conn,
      /* store the new socket descriptor */
      conn->sock[sockindex] = sockfd;
      conn->ip_addr = ai;
      sclose(fd_to_close);
      Curl_closesocket(conn, fd_to_close);
      return CURLE_OK;
    }
    ai = ai->ai_next;
  }
  sclose(fd_to_close);
  Curl_closesocket(conn, fd_to_close);
  return CURLE_COULDNT_CONNECT;
}

@@ -905,7 +905,7 @@ singleipconnect(struct connectdata *conn,
    error = ERRNO;
    failf(data, "sa_addr inet_ntop() failed with errno %d: %s",
          error, Curl_strerror(conn, error));
    sclose(sockfd);
    Curl_closesocket(conn, sockfd);
    return CURLE_OK;
  }
  memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
@@ -934,7 +934,7 @@ singleipconnect(struct connectdata *conn,
    if(error == CURL_SOCKOPT_ALREADY_CONNECTED)
      isconnected = TRUE;
    else if(error) {
      sclose(sockfd); /* close the socket and bail out */
      Curl_closesocket(conn, sockfd); /* close the socket and bail out */
      return CURLE_ABORTED_BY_CALLBACK;
    }
  }
@@ -942,7 +942,7 @@ singleipconnect(struct connectdata *conn,
  /* possibly bind the local end to an IP, interface or port */
  res = bindlocal(conn, sockfd, addr.family);
  if(res) {
    sclose(sockfd); /* close socket and bail out */
    Curl_closesocket(conn, sockfd); /* close socket and bail out */
    return res;
  }

@@ -976,7 +976,7 @@ singleipconnect(struct connectdata *conn,
#endif
      rc = waitconnect(conn, sockfd, timeout_ms);
      if(WAITCONN_ABORTED == rc) {
        sclose(sockfd);
        Curl_closesocket(conn, sockfd);
        return CURLE_ABORTED_BY_CALLBACK;
      }
      break;
@@ -1017,7 +1017,7 @@ singleipconnect(struct connectdata *conn,
  }

  /* connect failed or timed out */
  sclose(sockfd);
  Curl_closesocket(conn, sockfd);

  return CURLE_OK;
}
@@ -1163,3 +1163,16 @@ curl_socket_t Curl_getconnectinfo(struct SessionHandle *data,

  return sockfd;
}

/*
 * Close a socket.
 *
 * 'conn' can be NULL, beware!
 */
int Curl_closesocket(struct connectdata *conn,
                     curl_socket_t sock)
{
  (void)conn;

  return sclose(sock);
}
+1 −2
Original line number Diff line number Diff line
@@ -68,7 +68,6 @@ void Curl_sndbufset(curl_socket_t sockfd);
#endif

void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd);

void Curl_persistconninfo(struct connectdata *conn);

int Curl_closesocket(struct connectdata *conn, curl_socket_t sock);
#endif
+9 −9
Original line number Diff line number Diff line
@@ -357,7 +357,7 @@ static CURLcode AllowServerConnect(struct connectdata *conn)

        s=accept(sock, (struct sockaddr *) &add, &size);
      }
      sclose(sock); /* close the first socket */
      Curl_closesocket(conn, sock); /* close the first socket */

      if(CURL_SOCKET_BAD == s) {
        failf(data, "Error accept()ing server connect");
@@ -912,7 +912,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
        if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) {
          failf(data, "getsockname() failed: %s",
                Curl_strerror(conn, SOCKERRNO) );
          sclose(portsock);
          Curl_closesocket(conn, portsock);
          return CURLE_FTP_PORT_FAILED;
        }
        port = port_min;
@@ -921,7 +921,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
      else if(error != EADDRINUSE && error != EACCES) {
        failf(data, "bind(port=%hu) failed: %s", port,
              Curl_strerror(conn, error) );
        sclose(portsock);
        Curl_closesocket(conn, portsock);
        return CURLE_FTP_PORT_FAILED;
      }
    }
@@ -934,7 +934,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
  /* maybe all ports were in use already*/
  if(port > port_max) {
    failf(data, "bind() failed, we ran out of ports!");
    sclose(portsock);
    Curl_closesocket(conn, portsock);
    return CURLE_FTP_PORT_FAILED;
  }

@@ -944,7 +944,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
  if(getsockname(portsock, (struct sockaddr *)sa, &sslen)) {
    failf(data, "getsockname() failed: %s",
          Curl_strerror(conn, SOCKERRNO) );
    sclose(portsock);
    Curl_closesocket(conn, portsock);
    return CURLE_FTP_PORT_FAILED;
  }

@@ -952,7 +952,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,

  if(listen(portsock, 1)) {
    failf(data, "socket failure: %s", Curl_strerror(conn, SOCKERRNO));
    sclose(portsock);
    Curl_closesocket(conn, portsock);
    return CURLE_FTP_PORT_FAILED;
  }

@@ -1038,7 +1038,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
     the cleanup function will close it in case we fail before the true
     secondary stuff is made */
  if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET])
    sclose(conn->sock[SECONDARYSOCKET]);
    Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
  conn->sock[SECONDARYSOCKET] = portsock;

  /* this tcpconnect assignment below is a hackish work-around to make the
@@ -3100,7 +3100,7 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
         still requested to use SSL */
    }
    if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET]) {
      sclose(conn->sock[SECONDARYSOCKET]);
      Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
      conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
    }
  }
@@ -4080,7 +4080,7 @@ static CURLcode ftp_dophase_done(struct connectdata *conn,

  if(result && (conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD)) {
    /* Failure detected, close the second socket if it was created already */
    sclose(conn->sock[SECONDARYSOCKET]);
    Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
    conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
    return result;
  }
+1 −1
Original line number Diff line number Diff line
@@ -125,7 +125,7 @@ bool Curl_ipv6works(void)
      ipv6_works = 0;
    else {
      ipv6_works = 1;
      sclose(s);
      Curl_closesocket(NULL, s);
    }
  }
  return (ipv6_works>0)?TRUE:FALSE;
Loading