Apache server establishes a TCP connection with the client(browser) before serving requests.
Apache puts it's socket into LISTEN state using listen() system call.
TCP three-way handshake between client and server, can be briefed as follows:
1) Client end
Client sends SYN
Client moves into SYN SENT state
2) Server end
Kernel hands SYN to Server
Kernel sends SYN/ACK to the client
Server moves to SYN RCVD state
Connections in SYN RCVD state are added to SYN QUEUE(incomplete connection queue)
3) Client end
Client sends ACK
In the server end, the kernel passes connection into the server's accept() method.
Apache puts it's socket into LISTEN state using listen() system call.
TCP three-way handshake between client and server, can be briefed as follows:
1) Client end
Client sends SYN
Client moves into SYN SENT state
2) Server end
Kernel hands SYN to Server
Kernel sends SYN/ACK to the client
Server moves to SYN RCVD state
Connections in SYN RCVD state are added to SYN QUEUE(incomplete connection queue)
3) Client end
Client sends ACK
TCP Connection is ESTABLISHED. In the server end, once the ACK packet is received from the client, the connections in the SYN QUEUE(incomplete connection queue) are moved to the ACCEPT QUEUE. Apache will use the accept() system call to consume connections from the ACCEPT QUEUE.
Once the tcp connection is established between client and server, now the first http request data is passed from client to server
In the server end, the kernel passes connection into the server's accept() method.
The Kernel accepts up to /proc/sys/net/ipv4/tcp_max_syn_backlog (default 1024) requests to be in SYN_RCVD state(SYN QUEUE) - incomplete connections. Maximal number of remembered connection requests, which still did not receive an acknowledgement from connecting client. For each SYN requests received, it sends back SYN/ACK and awaits an ACK from the client. If the server, does not receive an ACK from the client, it retries sending SYN/ACK - /proc/sys/net/ipv4/tcp_synack_retries times (default 5 in linux), before dropping the connection. Once all the retries are failed, the client will get a RST packet from the server.
So at server end, we basically deal with two queues in Linux TCP implementation
So at server end, we basically deal with two queues in Linux TCP implementation
- Incomplete connection queue(SYN QUEUE - Connections in SYN RCVD state)
- Accept Queue(Connections in ESTABLISHED state)
If the Accept Queue is full, then the kernel will impose a limit on the rate at which SYN packets are accepted. If too many SYN packets are received, some of them will be dropped.
It is the job of the application(Apache, in this case) to empty the Accept Queue(completed connection queue) by calling the accept() system call.
Apache will accept() up to 'MaxClients' simultaneous client connections. The kernel will queue up to lower of either of the following - /proc/sys/net/core/somaxconn (default 128) or 'ListenBackLog' (default 511) -additional established connections. somaxconn is the Limit of socket listen() backlog. Going by the default values of /proc/sys/net/core/somaxconn (default 128) and 'ListenBackLog' (default 511), the kernel shall queue upto 128 established connections since 128 is lower than 511. Above this limit, the kernel will drop additional SYN packets.
How to limit simultaneous connections per client?
Apache does not have an in-built mechanism to limit simultaneous connections per client. So by using tools such as iptables,it can be achieved.
Reference:
http://www.cyberciti.biz/files/linux-kernel/Documentation/networking/ip-sysctl.txt
http://veithen.github.io/2014/01/01/how-tcp-backlog-works-in-linux.html
Reference:
http://www.cyberciti.biz/files/linux-kernel/Documentation/networking/ip-sysctl.txt
http://veithen.github.io/2014/01/01/how-tcp-backlog-works-in-linux.html