aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/curl/curl.h8
-rw-r--r--lib/connect.c29
-rw-r--r--lib/connect.h3
-rw-r--r--lib/ftp.c18
-rw-r--r--lib/hostip6.c2
-rw-r--r--lib/http_proxy.c3
-rw-r--r--lib/setup_once.h1
-rw-r--r--lib/transfer.c2
-rw-r--r--lib/url.c24
-rw-r--r--lib/urldata.h6
10 files changed, 71 insertions, 25 deletions
diff --git a/include/curl/curl.h b/include/curl/curl.h
index 09f305466..e4fbfdf89 100644
--- a/include/curl/curl.h
+++ b/include/curl/curl.h
@@ -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;
diff --git a/lib/connect.c b/lib/connect.c
index 732fc6721..2802c5d61 100644
--- a/lib/connect.c
+++ b/lib/connect.c
@@ -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);
+}
diff --git a/lib/connect.h b/lib/connect.h
index 0720085c2..3df9d970e 100644
--- a/lib/connect.h
+++ b/lib/connect.h
@@ -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
diff --git a/lib/ftp.c b/lib/ftp.c
index a0e928087..0cf19a882 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -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;
}
diff --git a/lib/hostip6.c b/lib/hostip6.c
index b847f5953..b944401c5 100644
--- a/lib/hostip6.c
+++ b/lib/hostip6.c
@@ -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;
diff --git a/lib/http_proxy.c b/lib/http_proxy.c
index 523f4aea8..08ca1006f 100644
--- a/lib/http_proxy.c
+++ b/lib/http_proxy.c
@@ -37,6 +37,7 @@
#include "rawstr.h"
#include "progress.h"
#include "non-ascii.h"
+#include "connect.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
@@ -482,7 +483,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
if(closeConnection && data->req.newurl) {
/* Connection closed by server. Don't use it anymore */
- sclose(conn->sock[sockindex]);
+ Curl_closesocket(conn, conn->sock[sockindex]);
conn->sock[sockindex] = CURL_SOCKET_BAD;
break;
}
diff --git a/lib/setup_once.h b/lib/setup_once.h
index 1b6fde527..b449807db 100644
--- a/lib/setup_once.h
+++ b/lib/setup_once.h
@@ -240,7 +240,6 @@ struct timeval {
# define sclose(x) close((x))
#endif
-
/*
* Uppercase macro versions of ANSI/ISO is*() functions/macros which
* avoid negative number inputs with argument byte codes > 127.
diff --git a/lib/transfer.c b/lib/transfer.c
index ddbbe529b..59d4792fd 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -2185,7 +2185,7 @@ static CURLcode Curl_do_perform(struct SessionHandle *data)
if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET]) {
/* if we failed anywhere, we must clean up the secondary socket if
it was used */
- sclose(conn->sock[SECONDARYSOCKET]);
+ Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
}
}
diff --git a/lib/url.c b/lib/url.c
index 038a02d43..b0b2d8f13 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -2232,6 +2232,21 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
data->set.opensocket_client = va_arg(param, void *);
break;
+ case CURLOPT_CLOSESOCKETFUNCTION:
+ /*
+ * close socket callback function: called instead of close()
+ * when shutting down a connection
+ */
+ data->set.fclosesocket = va_arg(param, curl_closesocket_callback);
+ break;
+
+ case CURLOPT_CLOSESOCKETDATA:
+ /*
+ * socket callback data pointer. Might be NULL.
+ */
+ data->set.closesocket_client = va_arg(param, void *);
+ break;
+
case CURLOPT_SSL_SESSIONID_CACHE:
data->set.ssl.sessionid = (bool)(0 != va_arg(param, long));
break;
@@ -2524,9 +2539,9 @@ static void conn_free(struct connectdata *conn)
/* close possibly still open sockets */
if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET])
- sclose(conn->sock[SECONDARYSOCKET]);
+ Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET])
- sclose(conn->sock[FIRSTSOCKET]);
+ Curl_closesocket(conn, conn->sock[FIRSTSOCKET]);
Curl_safefree(conn->user);
Curl_safefree(conn->passwd);
@@ -3538,6 +3553,11 @@ static struct connectdata *allocate_conn(struct SessionHandle *data)
conn->localportrange = data->set.localportrange;
conn->localport = data->set.localport;
+ /* the close socket stuff needs to be copied to the connection struct as
+ it may live on without (this specific) SessionHandle */
+ conn->fclosesocket = data->set.fclosesocket;
+ conn->closesocket_client = data->set.closesocket_client;
+
return conn;
error:
diff --git a/lib/urldata.h b/lib/urldata.h
index f4b4bcc6c..6d0de89af 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -737,6 +737,9 @@ struct connectdata {
and a HTTP proxy may in fact respond using chunked encoding */
struct Curl_chunker chunk;
+ curl_closesocket_callback fclosesocket; /* function closing the socket(s) */
+ void *closesocket_client;
+
bool inuse; /* This is a marker for the connection cache logic. If this is
TRUE this handle is being used by an easy handle and cannot
be used by any other easy handle without careful
@@ -1369,6 +1372,9 @@ struct UserDefined {
the address and opening the
socket */
void* opensocket_client;
+ curl_closesocket_callback fclosesocket; /* function for closing the
+ socket */
+ void* closesocket_client;
void *seek_client; /* pointer to pass to the seek callback */
/* the 3 curl_conv_callback functions below are used on non-ASCII hosts */