Skip to content

Don't insert a node into the splay tree twice#18005

Closed
dvdzhuang wants to merge 1 commit intocurl:masterfrom
dvdzhuang:dont-insert-twice
Closed

Don't insert a node into the splay tree twice#18005
dvdzhuang wants to merge 1 commit intocurl:masterfrom
dvdzhuang:dont-insert-twice

Conversation

@dvdzhuang
Copy link
Contributor

Specific to multiplexing with PIPEWAIT enabled - when a pending handle times out before its corresponding connecting handle, its timenode is erroneously inserted twice into the multi handle splay tree. This can lead to infinite loops or invalid accesses.

Here is a simple program that consistently reproduces the issue for me:

#include <string>
#include <curl/curl.h>

void makeReq(CURLM* multi, int timeoutMs)
{
    CURL* easy = curl_easy_init();
    curl_easy_setopt(easy, CURLOPT_TIMEOUT_MS, timeoutMs);
    curl_easy_setopt(easy, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2);
    curl_easy_setopt(easy, CURLOPT_PIPEWAIT, 1L);
    // any URL that is guaranteed to time out will work
    std::string url = "http://192.168.1.8:9001/code/" + std::to_string(timeoutMs);
    curl_easy_setopt(easy, CURLOPT_URL, url.c_str());
    curl_easy_setopt(easy, CURLOPT_CUSTOMREQUEST, "GET");
    curl_easy_setopt(easy, CURLOPT_TCP_KEEPALIVE, 1L);
    curl_easy_setopt(easy, CURLOPT_TCP_KEEPIDLE, 60L);
    curl_easy_setopt(easy, CURLOPT_TCP_KEEPINTVL, 60L);
    curl_multi_add_handle(multi, easy);
}

int main()
{
    CURLM* multi = curl_multi_init();
    makeReq(multi, 500);
    makeReq(multi, 300);

    int running;
    do
    {
        curl_multi_perform(multi, &running);
    }
    while (running);
}

To verify the duplicate insert, I was running with these changes locally: master...dvdzhuang:curl:checksplaytree

I was thinking that it might be good to have some strong guarantee that the node passed to Curl_splayinsert has a zeroed out time key but would like to know your thoughts. Thanks!

@bagder bagder requested a review from icing July 23, 2025 21:26
@bagder bagder closed this in 0122cc1 Jul 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments