Search code examples
clinuxnetwork-programmingtcpoperating-system

How to set TCP socket options to let it send ACK/RST in handshaking?


I notice that HAProxy's probing mechanism is like:

Client -> [SYN]     -> Server
Client <- [ACK/SYN] <- Server
Client -> [ACK/RST] -> Server

After browsing the source codes of HAProxy, I think they are not modifying the network stack behavior and achieve that in user-mode. So I guess that's a trick of socket options. Could you please give me some hints of it?


Solution

  • I replicated described behavior with TCP Fast Open. When connect() is used, TCP client(who you marked as Server) will wait for SYN-ACK and reply with ACK.

    Here is my example:

    #include <unistd.h>
    #include <arpa/inet.h>
        
    int main() {
            int sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    
            struct sockaddr_in sai;
            sai.sin_family = AF_INET;
            sai.sin_port = htons(1234);
            sai.sin_addr.s_addr = inet_addr("127.0.0.1");
    
            struct linger sl;
            sl.l_onoff = 1;         /* non-zero value enables linger option in kernel */
            sl.l_linger = 0;        /* timeout interval in seconds */
            setsockopt(sock, SOL_SOCKET, SO_LINGER, &sl, sizeof(sl));
    
            int ret = sendto(sock, NULL, 0, MSG_FASTOPEN | MSG_MORE, &sai, sizeof(sai));
            if(ret == -1) {
                    //Probing or TFO failed
                    //If TFO failed, try connect()
            }
            close(sock);
    }