/*
Curl busyloop PoC written by Harry Sintonen <sintonen@iki.fi>
Public Domain
My current understanding is that the socket will report as having
data to receive and thus curl_multi_poll() will always return
immediately. The socket will be added to the pollset by the
Curl_ssl_adjust_pollset() since OpenSSL reports SSL_ERROR_WANT_READ.
curl_multi_perform() sees the connection paused and does nothing
-> Busyloop
Largely based on https://curl.se/libcurl/c/multi-app.html
*/
#include <stdio.h>
#include <string.h>
#include <curl/curl.h>
#define HANDLECOUNT 1
size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata)
{
return CURL_WRITEFUNC_PAUSE;
}
int sockopt_callback(void *clientp,
curl_socket_t curlfd,
curlsocktype purpose)
{
const int newsize = 32768;
int rc = 0;
rc |= setsockopt(curlfd, SOL_SOCKET, SO_RCVBUF, &newsize, sizeof(newsize));
rc |= setsockopt(curlfd, SOL_SOCKET, SO_SNDBUF, &newsize, sizeof(newsize));
return rc ? CURL_SOCKOPT_ERROR : CURL_SOCKOPT_OK;
}
int main(void)
{
CURL *curl[HANDLECOUNT];
CURLM *multi;
int i;
curl_global_init(CURL_GLOBAL_ALL);
for(i = 0; i < HANDLECOUNT; i++) {
curl[i] = curl_easy_init();
//curl_easy_setopt(curl[i], CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_easy_setopt(curl[i], CURLOPT_BUFFERSIZE, 32 * 1024);
curl_easy_setopt(curl[i], CURLOPT_SOCKOPTFUNCTION, sockopt_callback);
curl_easy_setopt(curl[0], CURLOPT_URL, "https://curl.se/download/curl-8.20.0.tar.xz");
curl_easy_setopt(curl[0], CURLOPT_WRITEFUNCTION, write_callback);
}
multi = curl_multi_init();
if(multi) {
int still_running = 1; /* keep number of running handles */
for(i = 0; i < HANDLECOUNT; i++)
curl_multi_add_handle(multi, curl[i]);
while(still_running) {
CURLMcode mresult = curl_multi_perform(multi, &still_running);
//printf("mresult %d still_running %d\n", mresult, still_running);
if (mresult)
break;
if(still_running) {
mresult = curl_multi_poll(multi, NULL, 0, 1000, NULL);
//printf("curl_multi_poll mresult %d\n", mresult);
}
if(mresult)
break;
}
for(i = 0; i < HANDLECOUNT; i++)
curl_multi_remove_handle(multi, curl[i]);
curl_multi_cleanup(multi);
}
for(i = 0; i < HANDLECOUNT; i++)
curl_easy_cleanup(curl[i]);
curl_global_cleanup();
return 0;
}
Application not hanging with 100% single core CPU load.
curl 8.21.0-DEV (x86_64-pc-linux-gnu) libcurl/8.21.0-DEV OpenSSL/3.6.2 zlib/1.3.2 brotli/1.2.0 zstd/1.5.7 libidn2/2.3.8 libpsl/0.21.5 nghttp2/1.69.0 OpenLDAP/2.6.10
I did this
I expected the following
Application not hanging with 100% single core CPU load.
curl/libcurl version
curl 8.20.0
and curl git master
curl 8.21.0-DEV (x86_64-pc-linux-gnu) libcurl/8.21.0-DEV OpenSSL/3.6.2 zlib/1.3.2 brotli/1.2.0 zstd/1.5.7 libidn2/2.3.8 libpsl/0.21.5 nghttp2/1.69.0 OpenLDAP/2.6.10
operating system
Any