Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1s sleep when fd >= FD_SETSIZE #7240

Closed
mswaanen opened this issue Jun 11, 2021 · 0 comments
Closed

1s sleep when fd >= FD_SETSIZE #7240

mswaanen opened this issue Jun 11, 2021 · 0 comments

Comments

@mswaanen
Copy link
Contributor

I did this

Upgraded from v7.74 to v7.77

I expected the following

I expected no change

curl/libcurl version

curl 7.77.0 (x86_64-pc-linux-gnu) libcurl/7.77.0 
Release-Date: 2021-05-26

operating system

Linux #1 SMP Mon Apr 26 20:57:08 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

steps to reproduce

#include <fcntl.h>
#include <unistd.h>
#include <curl/curl.h>

static int opensocket_cb(void *clientp, curlsocktype purpose, struct curl_sockaddr *address) {
    int fd;
    int relocated;

    fd = socket(address->family, address->socktype, address->protocol);    
    printf("opensocket_cb: fd=%d\n", fd);
    relocated = fcntl(fd, F_DUPFD, FD_SETSIZE);  // Smaller than FD_SETSIZE works fine
    printf("opensocket_cb: relocated=%d\n", relocated);
    close(fd);

    return relocated;
}

int main() {
    CURL *curl;
    CURLcode res;

    curl = curl_easy_init();
    curl_easy_setopt(curl, CURLOPT_URL, "http://ifconfig.co/ip");
    curl_easy_setopt(curl, CURLOPT_OPENSOCKETFUNCTION, opensocket_cb);

    res = curl_easy_perform(curl);
    printf("res: %d\n", res);

    return 0;
}

Result:

> time ./breakcurl
opensocket_cb: fd=3
opensocket_cb: relocated=1024
54.240.197.234
res: 0

real    0m1.205s
user    0m0.004s
sys     0m0.000s

strace snippet:

1985  06:04:21.249430 sendto(1024, "GET /ip HTTP/1.1\r\nHost: ifconfig"..., 52, MSG_NOSIGNAL, NULL, 0) = 52
1985  06:04:21.249505 poll([{fd=1024, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 0 (Timeout)
1985  06:04:21.249540 rt_sigaction(SIGPIPE, {sa_handler=SIG_IGN, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fbbde128c90}, NULL, 8) = 0
1985  06:04:21.249576 poll([{fd=4, events=POLLIN}], 1, 1000) = 0 (Timeout)

same strace snippet with relocated = fcntl(fd, F_DUPFD, FD_SETSIZE - 1):

3221  06:07:32.037018 sendto(1023, "GET /ip HTTP/1.1\r\nHost: ifconfig"..., 52, MSG_NOSIGNAL, NULL, 0) = 52
3221  06:07:32.037066 poll([{fd=1023, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 0 (Timeout)
3221  06:07:32.037096 rt_sigaction(SIGPIPE, {sa_handler=SIG_IGN, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7ff35927fc90}, NULL, 8) = 0
3221  06:07:32.037128 poll([{fd=1023, events=POLLIN}, {fd=4, events=POLLIN}], 2, 186) = 1 ([{fd=1023, revents=POLLIN}])
mswaanen added a commit to mswaanen/curl that referenced this issue Jun 11, 2021
FD_SETSIZE is irrelevant when using poll. So ensuring that the file
descriptor is smaller than FD_SETSIZE in VALID_SOCK, can cause
multi_wait to ignore perfectly valid file descriptors and simply wait
for 1s to avoid hammering the CPU in a busy loop.
@bagder bagder closed this as completed in d293bf4 Jun 11, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.

1 participant