aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2014-05-20 10:32:23 +0200
committerDaniel Stenberg <daniel@haxx.se>2014-05-22 00:34:10 +0200
commitdf13f8e8c2199b572f19d295e5c59e7502204b3a (patch)
treeb664dc79f3de9d810f13dd01decbd0b03fcb06b5
parent491767418bd3e69867d48c2f9b4ea58f7112a879 (diff)
bits.close: introduce connection close tracking
Make all code use connclose() and connkeep() when changing the "close state" for a connection. These two macros take a string argument with an explanation, and debug builds of curl will include that in the debug output. Helps tracking connection re-use/close issues.
-rw-r--r--lib/asyn-ares.c4
-rw-r--r--lib/asyn-thread.c2
-rw-r--r--lib/connect.c17
-rw-r--r--lib/connect.h19
-rw-r--r--lib/ftp.c14
-rw-r--r--lib/http.c25
-rw-r--r--lib/http_proxy.c2
-rw-r--r--lib/imap.c4
-rw-r--r--lib/ldap.c2
-rw-r--r--lib/multi.c10
-rw-r--r--lib/openldap.c7
-rw-r--r--lib/pop3.c4
-rw-r--r--lib/smtp.c4
-rw-r--r--lib/ssh.c4
-rw-r--r--lib/tftp.c6
-rw-r--r--lib/transfer.c6
-rw-r--r--lib/url.c2
-rw-r--r--lib/urldata.h1
18 files changed, 85 insertions, 48 deletions
diff --git a/lib/asyn-ares.c b/lib/asyn-ares.c
index 94ee76735..d651c252d 100644
--- a/lib/asyn-ares.c
+++ b/lib/asyn-ares.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -421,7 +421,7 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
cleaning up this connection properly.
TODO: remove this action from here, it is not a name resolver decision.
*/
- conn->bits.close = TRUE;
+ connclose(conn, "c-ares resolve failed");
return rc;
}
diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c
index c72c06431..a0f436614 100644
--- a/lib/asyn-thread.c
+++ b/lib/asyn-thread.c
@@ -446,7 +446,7 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
destroy_async_data(&conn->async);
if(!conn->async.dns)
- conn->bits.close = TRUE;
+ connclose(conn, "asynch resolve failed");
return (rc);
}
diff --git a/lib/connect.c b/lib/connect.c
index ca6e3466c..de78c33e2 100644
--- a/lib/connect.c
+++ b/lib/connect.c
@@ -1321,3 +1321,20 @@ CURLcode Curl_socket(struct connectdata *conn,
return CURLE_OK;
}
+
+#ifdef CURLDEBUG
+/*
+ * Curl_conncontrol() is used to set the conn->bits.close bit on or off. It
+ * MUST be called with the connclose() or connclose() macros with a stated
+ * reason. The reason is only shown in debug builds but helps to figure out
+ * decision paths when connections are or aren't re-used as expected.
+ */
+void Curl_conncontrol(struct connectdata *conn, bool closeit,
+ const char *reason)
+{
+ infof(conn->data, "Marked for [%s]: %s\n", closeit?"closure":"keep alive",
+ reason);
+ conn->bits.close = closeit; /* the only place in the source code that should
+ assign this bit */
+}
+#endif
diff --git a/lib/connect.h b/lib/connect.h
index 89653f70a..7bc391bef 100644
--- a/lib/connect.h
+++ b/lib/connect.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -102,4 +102,21 @@ CURLcode Curl_socket(struct connectdata *conn,
struct Curl_sockaddr_ex *addr,
curl_socket_t *sockfd);
+#ifdef CURLDEBUG
+/*
+ * Curl_connclose() sets the bit.close bit to TRUE with an explanation.
+ * Nothing else.
+ */
+void Curl_conncontrol(struct connectdata *conn,
+ bool closeit,
+ const char *reason);
+#define connclose(x,y) Curl_conncontrol(x,TRUE, y)
+#define connkeep(x,y) Curl_conncontrol(x, FALSE, y)
+#else /* if !CURLDEBUG */
+
+#define connclose(x,y) (x)->bits.close = TRUE
+#define connkeep(x,y) (x)->bits.close = FALSE
+
+#endif
+
#endif /* HEADER_CURL_CONNECT_H */
diff --git a/lib/ftp.c b/lib/ftp.c
index cadec10f5..4c4396abb 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -3164,7 +3164,7 @@ static CURLcode ftp_connect(struct connectdata *conn,
*done = FALSE; /* default to not done yet */
/* We always support persistent connections on ftp */
- conn->bits.close = FALSE;
+ connkeep(conn, "FTP default");
pp->response_time = RESP_TIMEOUT; /* set default response time-out */
pp->statemach_act = ftp_statemach_act;
@@ -3248,7 +3248,7 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
ftpc->ctl_valid = FALSE;
ftpc->cwdfail = TRUE; /* set this TRUE to prevent us to remember the
current path, as this connection is going */
- conn->bits.close = TRUE; /* marked for closure */
+ connclose(conn, "FTP ended with bad error code");
result = status; /* use the already set error code */
break;
}
@@ -3272,7 +3272,7 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
if(!result)
result = CURLE_OUT_OF_MEMORY;
ftpc->ctl_valid = FALSE; /* mark control connection as bad */
- conn->bits.close = TRUE; /* mark for connection closure */
+ connclose(conn, "FTP: out of memory!"); /* mark for connection closure */
ftpc->prevpath = NULL; /* no path remembering */
}
else {
@@ -3315,7 +3315,7 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
failf(data, "Failure sending ABOR command: %s",
curl_easy_strerror(result));
ftpc->ctl_valid = FALSE; /* mark control connection as bad */
- conn->bits.close = TRUE; /* mark for connection closure */
+ connclose(conn, "ABOR command failed"); /* connection closure */
}
}
@@ -3354,7 +3354,7 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
if(!nread && (CURLE_OPERATION_TIMEDOUT == result)) {
failf(data, "control connection looks dead");
ftpc->ctl_valid = FALSE; /* mark control connection as bad */
- conn->bits.close = TRUE; /* mark for closure */
+ connclose(conn, "Timeout or similar in FTP DONE operation"); /* close */
}
if(result)
@@ -3364,7 +3364,7 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
/* we have just sent ABOR and there is no reliable way to check if it was
* successful or not; we have to close the connection now */
infof(data, "partial download completed, closing connection\n");
- conn->bits.close = TRUE; /* mark for closure */
+ connclose(conn, "Partial download with no ability to check");
return result;
}
@@ -4133,7 +4133,7 @@ static CURLcode ftp_quit(struct connectdata *conn)
failf(conn->data, "Failure sending QUIT command: %s",
curl_easy_strerror(result));
conn->proto.ftpc.ctl_valid = FALSE; /* mark control connection as bad */
- conn->bits.close = TRUE; /* mark for connection closure */
+ connclose(conn, "QUIT command failed"); /* mark for connection closure */
state(conn, FTP_STOP);
return result;
}
diff --git a/lib/http.c b/lib/http.c
index 7dde8212e..cfdaaddfc 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -76,6 +76,7 @@
#include "bundles.h"
#include "pipeline.h"
#include "http2.h"
+#include "connect.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
@@ -449,7 +450,7 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
/* This is not NTLM or many bytes left to send: close
*/
- conn->bits.close = TRUE;
+ connclose(conn, "Mid-auth HTTP and much data left to send");
data->req.size = 0; /* don't download any more than 0 bytes */
/* There still is data left to send, but this connection is marked for
@@ -1337,7 +1338,7 @@ CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
/* We default to persistent connections. We set this already in this connect
function to make the re-use checks properly be able to check this bit. */
- conn->bits.close = FALSE;
+ connkeep(conn, "HTTP default");
/* the CONNECT procedure might not have been completed */
result = Curl_proxy_connect(conn);
@@ -1382,8 +1383,8 @@ static CURLcode https_connecting(struct connectdata *conn, bool *done)
/* perform SSL initialization for this socket */
result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, done);
if(result)
- conn->bits.close = TRUE; /* a failed connection is marked for closure
- to prevent (bad) re-use or similar */
+ connclose(conn, "Failed HTTPS connection");
+
return result;
}
#endif
@@ -3016,7 +3017,7 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
signal the end of the document. */
infof(data, "no chunk, no close, no size. Assume close to "
"signal end\n");
- conn->bits.close = TRUE;
+ connclose(conn, "HTTP: No end-of-message indicator");
}
}
@@ -3085,7 +3086,7 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
*/
if(!k->upload_done) {
infof(data, "HTTP error before end of send, stop sending\n");
- conn->bits.close = TRUE; /* close after this */
+ connclose(conn, "Stop sending data before everything sent");
k->upload_done = TRUE;
k->keepon &= ~KEEP_SEND; /* don't send */
if(data->state.expect100header)
@@ -3280,7 +3281,7 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
we get one of those fancy headers that tell us the
server keeps it open for us! */
infof(data, "HTTP 1.0, assume close after body\n");
- conn->bits.close = TRUE;
+ connclose(conn, "HTTP/1.0 close after body");
}
else if(conn->httpversion >= 11 &&
!conn->bits.close) {
@@ -3355,7 +3356,7 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
/* Negative Content-Length is really odd, and we know it
happens for example when older Apache servers send large
files */
- conn->bits.close = TRUE;
+ connclose(conn, "negative content-length");
infof(data, "Negative content-length: %" CURL_FORMAT_CURL_OFF_T
", closing after transfer\n", contentlength);
}
@@ -3393,7 +3394,7 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
* connection will be kept alive for our pleasure.
* Default action for 1.0 is to close.
*/
- conn->bits.close = FALSE; /* don't close when done */
+ connkeep(conn, "Proxy-Connection keep-alive"); /* don't close */
infof(data, "HTTP/1.0 proxy connection set to keep alive!\n");
}
else if((conn->httpversion == 11) &&
@@ -3404,7 +3405,7 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
* We get a HTTP/1.1 response from a proxy and it says it'll
* close down after this transfer.
*/
- conn->bits.close = TRUE; /* close when done */
+ connclose(conn, "Proxy-Connection: asked to close after done");
infof(data, "HTTP/1.1 proxy connection set close!\n");
}
else if((conn->httpversion == 10) &&
@@ -3415,7 +3416,7 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
* pleasure. Default action for 1.0 is to close.
*
* [RFC2068, section 19.7.1] */
- conn->bits.close = FALSE; /* don't close when done */
+ connkeep(conn, "Connection keep-alive");
infof(data, "HTTP/1.0 connection set to keep alive!\n");
}
else if(Curl_compareheader(k->p, "Connection:", "close")) {
@@ -3425,7 +3426,7 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
* the connection will close when this request has been
* served.
*/
- conn->bits.close = TRUE; /* close when done */
+ connclose(conn, "Connection: close used");
}
else if(checkprefix("Transfer-Encoding:", k->p)) {
/* One or more encodings. We check for chunked and/or a compression
diff --git a/lib/http_proxy.c b/lib/http_proxy.c
index 0ee1a73d5..a98c68c1c 100644
--- a/lib/http_proxy.c
+++ b/lib/http_proxy.c
@@ -69,7 +69,7 @@ CURLcode Curl_proxy_connect(struct connectdata *conn)
prot_save = conn->data->req.protop;
memset(&http_proxy, 0, sizeof(http_proxy));
conn->data->req.protop = &http_proxy;
- conn->bits.close = FALSE;
+ connkeep(conn, "HTTP proxy CONNECT");
result = Curl_proxyCONNECT(conn, FIRSTSOCKET,
conn->host.name, conn->remote_port);
conn->data->req.protop = prot_save;
diff --git a/lib/imap.c b/lib/imap.c
index 713060352..0570ecc8d 100644
--- a/lib/imap.c
+++ b/lib/imap.c
@@ -1881,7 +1881,7 @@ static CURLcode imap_connect(struct connectdata *conn, bool *done)
*done = FALSE; /* default to not done yet */
/* We always support persistent connections in IMAP */
- conn->bits.close = FALSE;
+ connkeep(conn, "IMAP default");
/* Set the default response time-out */
pp->response_time = RESP_TIMEOUT;
@@ -1938,7 +1938,7 @@ static CURLcode imap_done(struct connectdata *conn, CURLcode status,
return CURLE_OK;
if(status) {
- conn->bits.close = TRUE; /* marked for closure */
+ connclose(conn, "IMAP done with bad status"); /* marked for closure */
result = status; /* use the already set error code */
}
else if(!data->set.connect_only && !imap->custom &&
diff --git a/lib/ldap.c b/lib/ldap.c
index 4c987898b..bbeeb6ee9 100644
--- a/lib/ldap.c
+++ b/lib/ldap.c
@@ -466,7 +466,7 @@ quit:
/* no data to transfer */
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
- conn->bits.close = TRUE;
+ connclose(conn, "LDAP connection always disable re-use");
return status;
}
diff --git a/lib/multi.c b/lib/multi.c
index 72fde7439..1fb341ca6 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -515,7 +515,7 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
/* If the handle is in a pipeline and has started sending off its
request but not received its response yet, we need to close
connection. */
- data->easy_conn->bits.close = TRUE;
+ connclose(data->easy_conn, "Removed with partial response");
/* Set connection owner so that Curl_done() closes it.
We can sefely do this here since connection is killed. */
data->easy_conn->data = easy;
@@ -1011,7 +1011,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
/* Force the connection closed because the server could continue to
send us stuff at any time. (The disconnect_conn logic used below
doesn't work at this point). */
- data->easy_conn->bits.close = TRUE;
+ connclose(data->easy_conn, "Disconnected with pending data");
data->result = CURLE_OPERATION_TIMEDOUT;
multistate(data, CURLM_STATE_COMPLETED);
break;
@@ -1239,7 +1239,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
case CURLM_STATE_DO:
if(data->set.connect_only) {
/* keep connection open for application to use the socket */
- data->easy_conn->bits.close = FALSE;
+ connkeep(data->easy_conn, "CONNECT_ONLY");
multistate(data, CURLM_STATE_DONE);
data->result = CURLE_OK;
result = CURLM_CALL_MULTI_PERFORM;
@@ -1525,7 +1525,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
*/
if(!(data->easy_conn->handler->flags & PROTOPT_DUAL))
- data->easy_conn->bits.close = TRUE;
+ connclose(data->easy_conn, "Transfer returned error");
Curl_posttransfer(data);
Curl_done(&data->easy_conn, data->result, FALSE);
@@ -1705,7 +1705,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
/* aborted due to progress callback return code must close the
connection */
data->result = CURLE_ABORTED_BY_CALLBACK;
- data->easy_conn->bits.close = TRUE;
+ connclose(data->easy_conn, "Aborted by callback");
/* if not yet in DONE state, go there, otherwise COMPLETED */
multistate(data, (data->mstate < CURLM_STATE_DONE)?
diff --git a/lib/openldap.c b/lib/openldap.c
index 2af14bab1..df8d93889 100644
--- a/lib/openldap.c
+++ b/lib/openldap.c
@@ -6,7 +6,7 @@
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2010, 2013, Howard Chu, <hyc@openldap.org>
- * Copyright (C) 2011 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2011 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -46,6 +46,7 @@
#include "curl_ldap.h"
#include "curl_memory.h"
#include "curl_base64.h"
+#include "connect.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
@@ -175,7 +176,7 @@ static CURLcode ldap_setup(struct connectdata *conn)
return CURLE_OUT_OF_MEMORY;
li->proto = proto;
conn->proto.generic = li;
- conn->bits.close = FALSE;
+ connkeep(conn, "OpenLDAP default");
/* TODO:
* - provide option to choose SASL Binds instead of Simple
*/
@@ -349,7 +350,7 @@ static CURLcode ldap_do(struct connectdata *conn, bool *done)
int msgid;
struct SessionHandle *data=conn->data;
- conn->bits.close = FALSE;
+ connkeep(conn, "OpenLDAP do");
infof(data, "LDAP local: %s\n", data->change.url);
diff --git a/lib/pop3.c b/lib/pop3.c
index 964804b30..314567e3f 100644
--- a/lib/pop3.c
+++ b/lib/pop3.c
@@ -1547,7 +1547,7 @@ static CURLcode pop3_connect(struct connectdata *conn, bool *done)
*done = FALSE; /* default to not done yet */
/* We always support persistent connections in POP3 */
- conn->bits.close = FALSE;
+ connkeep(conn, "POP3 default");
/* Set the default response time-out */
pp->response_time = RESP_TIMEOUT;
@@ -1601,7 +1601,7 @@ static CURLcode pop3_done(struct connectdata *conn, CURLcode status,
return CURLE_OK;
if(status) {
- conn->bits.close = TRUE; /* marked for closure */
+ connclose(conn, "POP3 done with bad status");
result = status; /* use the already set error code */
}
diff --git a/lib/smtp.c b/lib/smtp.c
index 762a8d16a..5938c3ff4 100644
--- a/lib/smtp.c
+++ b/lib/smtp.c
@@ -1588,7 +1588,7 @@ static CURLcode smtp_connect(struct connectdata *conn, bool *done)
*done = FALSE; /* default to not done yet */
/* We always support persistent connections in SMTP */
- conn->bits.close = FALSE;
+ connkeep(conn, "SMTP default");
/* Set the default response time-out */
pp->response_time = RESP_TIMEOUT;
@@ -1650,7 +1650,7 @@ static CURLcode smtp_done(struct connectdata *conn, CURLcode status,
return CURLE_OK;
if(status) {
- conn->bits.close = TRUE; /* marked for closure */
+ connclose(conn, "SMTP done with bad status"); /* marked for closure */
result = status; /* use the already set error code */
}
else if(!data->set.connect_only && data->set.upload && data->set.mail_rcpt) {
diff --git a/lib/ssh.c b/lib/ssh.c
index 5e18ca722..b248b43a0 100644
--- a/lib/ssh.c
+++ b/lib/ssh.c
@@ -2544,7 +2544,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
memset(sshc, 0, sizeof(struct ssh_conn));
- conn->bits.close = TRUE;
+ connclose(conn, "SSH session free");
sshc->state = SSH_SESSION_FREE; /* current */
sshc->nextstate = SSH_NO_STATE;
state(conn, SSH_STOP);
@@ -2747,7 +2747,7 @@ static CURLcode ssh_connect(struct connectdata *conn, bool *done)
/* We default to persistent connections. We set this already in this connect
function to make the re-use checks properly be able to check this bit. */
- conn->bits.close = FALSE;
+ connkeep(conn, "SSH default");
if(conn->handler->protocol & CURLPROTO_SCP) {
conn->recv[FIRSTSOCKET] = scp_recv;
diff --git a/lib/tftp.c b/lib/tftp.c
index d19f48029..e499c4516 100644
--- a/lib/tftp.c
+++ b/lib/tftp.c
@@ -974,9 +974,9 @@ static CURLcode tftp_connect(struct connectdata *conn, bool *done)
return CURLE_OUT_OF_MEMORY;
}
- conn->bits.close = TRUE; /* we don't keep TFTP connections up bascially
- because there's none or very little gain for UDP
- */
+ /* we don't keep TFTP connections up bascially because there's none or very
+ * little gain for UDP */
+ connclose(conn, "TFTP");
state->conn = conn;
state->sockfd = state->conn->sock[FIRSTSOCKET];
diff --git a/lib/transfer.c b/lib/transfer.c
index c1cdde60b..e0f613bd0 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -569,7 +569,7 @@ static CURLcode readwrite_data(struct SessionHandle *data,
infof(data, "Simulate a HTTP 304 response!\n");
/* we abort the transfer before it is completed == we ruin the
re-use ability. Close the connection */
- conn->bits.close = TRUE;
+ connclose(conn, "Simulated 304 handling");
return CURLE_OK;
}
} /* we have a time condition */
@@ -1818,7 +1818,7 @@ Curl_reconnect_request(struct connectdata **connp)
infof(data, "Re-used connection seems dead, get a new one\n");
- conn->bits.close = TRUE; /* enforce close of this connection */
+ connclose(conn, "Reconnect dead connection"); /* enforce close */
result = Curl_done(&conn, result, FALSE); /* we are so done with this */
/* conn may no longer be a good pointer, clear it to avoid mistakes by
@@ -1891,7 +1891,7 @@ CURLcode Curl_retry_request(struct connectdata *conn,
if(!*url)
return CURLE_OUT_OF_MEMORY;
- conn->bits.close = TRUE; /* close this connection */
+ connclose(conn, "retry"); /* close this connection */
conn->bits.retry = TRUE; /* mark this as a connection we're about
to retry. Marking it this way should
prevent i.e HTTP transfers to return
diff --git a/lib/url.c b/lib/url.c
index b0aade1bf..7d2592bf9 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -3590,7 +3590,7 @@ static struct connectdata *allocate_conn(struct SessionHandle *data)
/* Default protocol-independent behavior doesn't support persistent
connections, so we set this to force-close. Protocols that support
this need to set this to FALSE in their "curl_do" functions. */
- conn->bits.close = TRUE;
+ connclose(conn, "Default to force-close");
/* Store creation time to help future close decision making */
conn->created = Curl_tvnow();
diff --git a/lib/urldata.h b/lib/urldata.h
index 640cbb1c6..648187642 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -475,6 +475,7 @@ struct negotiatedata {
* Boolean values that concerns this connection.
*/
struct ConnectBits {
+ /* always modify bits.close with the connclose() and connkeep() macros! */
bool close; /* if set, we close the connection after this request */
bool reuse; /* if set, this is a re-used connection */
bool proxy; /* if set, this transfer is done through a proxy - any type */