Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

What happens when a malicious client performs a slow TCP handshake? Does it affect the `accept()` call in a multithreaded server?

Let’s say I create a simple multithreaded TCP server like so:

int server_fd = socket(/* args */);

setsockopt(server_fd, /* other args... */);
bind(server_fd, /* other args... */);
listen(server_fd, backlog);

while (1) {
    int client_fd = accept(server_fd, /* other args... */);
    
    if (fork() == 0) {
        // handle client request
        close(client_fd);
        exit(0);
    }
}

A server like this should be able to handle many clients, but what happens if a malicious client performs the initial TCP handshake extremely slowly? During that, will the server still be able to accept other legitimate clients, or does the slow client prohibit that, as the call to accept() is blocking?

To clarify my question:
What does the call to accept() do under the hood? Does it simply take the next incoming socket and prepare it for communication by establishing a file descriptor, or is it actively communicating with the client to complete the handshake? Does the process of waiting for a TCP handshake affect other incoming connections?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

In common OS the TCP handshake is done by the OS kernel, which can handle multiple pending handshakes in parallel. Only once the TCP handshake is successful done it is put on the queue of established connections, where it can then be retrieved with accept.

Note that some user space TCP stacks or tiny TCP stacks like in embedded systems might behave differently.

Note also that contrary to the TCP handshake a TLS handshake (as in SSL_accept) is usually done in user space. Therefore with your multi-process or multi-threading design it should better be done after the fork, so that a slow or misbehaving peer does not block parallel TLS handshakes.

1 comments

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading