mirror of
https://github.com/moparisthebest/curl
synced 2024-11-14 21:45:13 -05:00
connection_check: restore original conn->data after the check
- Save the original conn->data before it's changed to the specified data transfer for the connection check and then restore it afterwards. This is a follow-up to38d8e1b
2019-02-11. History: It was discovered a month ago that before checking whether to extract a dead connection that that connection should be associated with a "live" transfer for the check (ie original conn->data ignored and set to the passed in data). A fix was landed in54b201b
which did that and also cleared conn->data after the check. The original conn->data was not restored, so presumably it was thought that a valid conn->data was no longer needed. Several days later it was discovered that a valid conn->data was needed after the check and follow-up fix was landed inbbae24c
which partially reverted the original fix and attempted to limit the scope of when conn->data was changed to only when pruning dead connections. In that case conn->data was not cleared and the original conn->data not restored. A month later it was discovered that the original fix was somewhat correct; a "live" transfer is needed for the check in all cases because original conn->data could be null which could cause a bad deref at arbitrary points in the check. A fix was landed in38d8e1b
which expanded the scope to all cases. conn->data was not cleared and the original conn->data not restored. A day later it was discovered that not restoring the original conn->data may lead to busy loops in applications that use the event interface, and given this observation it's a pretty safe assumption that there is some code path that still needs the original conn->data. This commit is the follow-up fix for that, it restores the original conn->data after the connection check. Assisted-by: tholin@users.noreply.github.com Reported-by: tholin@users.noreply.github.com Fixes https://github.com/curl/curl/issues/3542 Closes #3559
This commit is contained in:
parent
49d73d40f6
commit
4015fae044
@ -964,8 +964,10 @@ static bool extract_if_dead(struct connectdata *conn,
|
|||||||
/* The protocol has a special method for checking the state of the
|
/* The protocol has a special method for checking the state of the
|
||||||
connection. Use it to check if the connection is dead. */
|
connection. Use it to check if the connection is dead. */
|
||||||
unsigned int state;
|
unsigned int state;
|
||||||
|
struct Curl_easy *olddata = conn->data;
|
||||||
conn->data = data; /* use this transfer for now */
|
conn->data = data; /* use this transfer for now */
|
||||||
state = conn->handler->connection_check(conn, CONNCHECK_ISDEAD);
|
state = conn->handler->connection_check(conn, CONNCHECK_ISDEAD);
|
||||||
|
conn->data = olddata;
|
||||||
dead = (state & CONNRESULT_DEAD);
|
dead = (state & CONNRESULT_DEAD);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -994,7 +996,6 @@ struct prunedead {
|
|||||||
static int call_extract_if_dead(struct connectdata *conn, void *param)
|
static int call_extract_if_dead(struct connectdata *conn, void *param)
|
||||||
{
|
{
|
||||||
struct prunedead *p = (struct prunedead *)param;
|
struct prunedead *p = (struct prunedead *)param;
|
||||||
conn->data = p->data; /* transfer to use for this check */
|
|
||||||
if(extract_if_dead(conn, p->data)) {
|
if(extract_if_dead(conn, p->data)) {
|
||||||
/* stop the iteration here, pass back the connection that was extracted */
|
/* stop the iteration here, pass back the connection that was extracted */
|
||||||
p->extracted = conn;
|
p->extracted = conn;
|
||||||
|
Loading…
Reference in New Issue
Block a user