struct cf_socket_ctx *ctx = cf->ctx;
if(ctx && CURL_SOCKET_BAD != ctx->sock) {
- if(ctx->active) {
- /* We share our socket at cf->conn->sock[cf->sockindex] when active.
- * If it is no longer there, someone has stolen (and hopefully
- * closed it) and we just forget about it.
- */
- if(ctx->sock == cf->conn->sock[cf->sockindex]) {
- CURL_TRC_CF(data, cf, "cf_socket_close(%" CURL_FORMAT_SOCKET_T
- ", active)", ctx->sock);
- socket_close(data, cf->conn, !ctx->accepted, ctx->sock);
- cf->conn->sock[cf->sockindex] = CURL_SOCKET_BAD;
- }
- else {
- CURL_TRC_CF(data, cf, "cf_socket_close(%" CURL_FORMAT_SOCKET_T
- ") no longer at conn->sock[], discarding", ctx->sock);
- /* TODO: we do not want this to happen. Need to check which
- * code is messing with conn->sock[cf->sockindex] */
- }
- ctx->sock = CURL_SOCKET_BAD;
- if(cf->sockindex == FIRSTSOCKET)
- cf->conn->remote_addr = NULL;
- }
- else {
- /* this is our local socket, we did never publish it */
- CURL_TRC_CF(data, cf, "cf_socket_close(%" CURL_FORMAT_SOCKET_T
- ", not active)", ctx->sock);
- socket_close(data, cf->conn, !ctx->accepted, ctx->sock);
- ctx->sock = CURL_SOCKET_BAD;
- }
+ CURL_TRC_CF(data, cf, "cf_socket_close(%" CURL_FORMAT_SOCKET_T
+ ")", ctx->sock);
+ if(ctx->sock == cf->conn->sock[cf->sockindex])
+ cf->conn->sock[cf->sockindex] = CURL_SOCKET_BAD;
+ socket_close(data, cf->conn, !ctx->accepted, ctx->sock);
+ ctx->sock = CURL_SOCKET_BAD;
+ if(ctx->active && cf->sockindex == FIRSTSOCKET)
+ cf->conn->remote_addr = NULL;
Curl_bufq_reset(&ctx->recvbuf);
ctx->active = FALSE;
ctx->buffer_recv = FALSE;
case CF_CTRL_DATA_SETUP:
Curl_persistconninfo(data, cf->conn, ctx->l_ip, ctx->l_port);
break;
+ case CF_CTRL_FORGET_SOCKET:
+ ctx->sock = CURL_SOCKET_BAD;
+ break;
}
return CURLE_OK;
}
return data->conn? data->conn->sock[sockindex] : CURL_SOCKET_BAD;
}
+void Curl_conn_forget_socket(struct Curl_easy *data, int sockindex)
+{
+ if(data->conn) {
+ struct Curl_cfilter *cf = data->conn->cfilter[sockindex];
+ if(cf)
+ (void)Curl_conn_cf_cntrl(cf, data, TRUE,
+ CF_CTRL_FORGET_SOCKET, 0, NULL);
+ fake_sclose(data->conn->sock[sockindex]);
+ data->conn->sock[sockindex] = CURL_SOCKET_BAD;
+ }
+}
+
static CURLcode cf_cntrl_all(struct connectdata *conn,
struct Curl_easy *data,
bool ignore_result,
#define CF_CTRL_DATA_DONE_SEND 8 /* 0 NULL ignored */
/* update conn info at connection and data */
#define CF_CTRL_CONN_INFO_UPDATE (256+0) /* 0 NULL ignored */
+#define CF_CTRL_FORGET_SOCKET (256+1) /* 0 NULL ignored */
/**
* Handle event/control for the filter.
*/
curl_socket_t Curl_conn_get_socket(struct Curl_easy *data, int sockindex);
+/**
+ * Tell filters to forget about the soket at sockindex.
+ */
+void Curl_conn_forget_socket(struct Curl_easy *data, int sockindex);
+
/**
* Adjust the pollset for the filter chain startgin at `cf`.
*/
ssh_disconnect(sshc->ssh_session);
if(!ssh_version(SSH_VERSION_INT(0, 10, 0))) {
/* conn->sock[FIRSTSOCKET] is closed by ssh_disconnect behind our back,
- explicitly mark it as closed with the memdebug macro. This libssh
+ tell the connection to forget about it. This libssh
bug is fixed in 0.10.0. */
- fake_sclose(conn->sock[FIRSTSOCKET]);
- conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD;
+ Curl_conn_forget_socket(data, FIRSTSOCKET);
}
SSH_STRING_FREE_CHAR(sshc->homedir);