// File: yuryu[P]tfoecho/server.cpp
// Function: open_socket(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&)
int open_socket(const std::string &port)
{
    struct addrinfo hint, *res;
    
    std::memset(&hint, 0, sizeof(hint));
    hint.ai_family = AF_UNSPEC;
    hint.ai_socktype = SOCK_STREAM;
    hint.ai_flags = AI_PASSIVE | AI_NUMERICSERV;
    int e = getaddrinfo(nullptr, port.c_str(), &hint, &res);
    if( e != 0 )
    {
        std::cerr << "getaddrinfo: " << gai_strerror(e) << std::endl;
        std::exit(EXIT_FAILURE);
    }
    
    int sock;
    struct addrinfo *rp;
    for( rp = res; rp != nullptr; rp = rp->ai_next )
    {
        sock = socket(rp->ai_family, rp->ai_socktype | SOCK_NONBLOCK, rp->ai_protocol);
        if( sock == -1 ) continue;
        if( bind(sock, rp->ai_addr, rp->ai_addrlen) == 0 ) break;
        close(sock);
    }
    if( rp == nullptr )
    {
        std::cerr << "Couldn't bind." << std::endl;
        std::exit(EXIT_FAILURE);
    }
    int protocol = rp->ai_protocol;
    freeaddrinfo(res);
    
    const int qlen = TFO_QLEN;
    e = setsockopt(sock, protocol, TCP_FASTOPEN, &qlen, sizeof(qlen));
    if( e == -1 )
    {
        close(sock);
        cerror("setsockopt");
        std::exit(EXIT_FAILURE);
    }
    if( listen(sock, LISTEN_QLEN) == -1 )
    {
        close(sock);
        cerror("listen");
        std::exit(EXIT_FAILURE);
    }
    return sock;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x8(%rbp)
leaq -0x38(%rbp), %rdi
xorl %esi, %esi
movl $0x30, %edx
callq 0x2110
movl $0x0, -0x34(%rbp)
movl $0x1, -0x30(%rbp)
movl $0x401, -0x38(%rbp)     # imm = 0x401
movq -0x8(%rbp), %rdi
callq 0x20c0
movq %rax, %rsi
xorl %eax, %eax
movl %eax, %edi
leaq -0x38(%rbp), %rdx
leaq -0x40(%rbp), %rcx
callq 0x2200
movl %eax, -0x44(%rbp)
cmpl $0x0, -0x44(%rbp)
je 0x24bb
movq 0x3b72(%rip), %rdi      # 0x5ff0
leaq 0x1b7f(%rip), %rsi      # 0x4004
callq 0x2190
movq %rax, -0x60(%rbp)
movl -0x44(%rbp), %edi
callq 0x2260
movq -0x60(%rbp), %rdi
movq %rax, %rsi
callq 0x2190
movq %rax, %rdi
movq 0x3b1c(%rip), %rsi      # 0x5fc8
callq 0x21c0
movl $0x1, %edi
callq 0x21f0
movq -0x40(%rbp), %rax
movq %rax, -0x50(%rbp)
cmpq $0x0, -0x50(%rbp)
je 0x2529
movq -0x50(%rbp), %rax
movl 0x4(%rax), %edi
movq -0x50(%rbp), %rax
movl 0x8(%rax), %esi
orl $0x800, %esi            # imm = 0x800
movq -0x50(%rbp), %rax
movl 0xc(%rax), %edx
callq 0x2060
movl %eax, -0x48(%rbp)
cmpl $-0x1, -0x48(%rbp)
jne 0x24f5
jmp 0x251b
movl -0x48(%rbp), %edi
movq -0x50(%rbp), %rax
movq 0x18(%rax), %rsi
movq -0x50(%rbp), %rax
movl 0x10(%rax), %edx
callq 0x2040
cmpl $0x0, %eax
jne 0x2513
jmp 0x2529
movl -0x48(%rbp), %edi
callq 0x22d0
movq -0x50(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x50(%rbp)
jmp 0x24c3
cmpq $0x0, -0x50(%rbp)
jne 0x255c
movq 0x3ab9(%rip), %rdi      # 0x5ff0
leaq 0x1ad4(%rip), %rsi      # 0x4012
callq 0x2190
movq %rax, %rdi
movq 0x3a7b(%rip), %rsi      # 0x5fc8
callq 0x21c0
movl $0x1, %edi
callq 0x21f0
movq -0x50(%rbp), %rax
movl 0xc(%rax), %eax
movl %eax, -0x54(%rbp)
movq -0x40(%rbp), %rdi
callq 0x2210
movl $0x80, -0x58(%rbp)
movl -0x48(%rbp), %edi
movl -0x54(%rbp), %esi
movl $0x17, %edx
leaq -0x58(%rbp), %rcx
movl $0x4, %r8d
callq 0x22b0
movl %eax, -0x44(%rbp)
cmpl $-0x1, -0x44(%rbp)
jne 0x25b7
movl -0x48(%rbp), %edi
callq 0x22d0
leaq 0x1a79(%rip), %rdi      # 0x4021
callq 0x25f0
movl $0x1, %edi
callq 0x21f0
movl -0x48(%rbp), %edi
movl $0x80, %esi
callq 0x21e0
cmpl $-0x1, %eax
jne 0x25e7
movl -0x48(%rbp), %edi
callq 0x22d0
leaq 0x1a54(%rip), %rdi      # 0x402c
callq 0x25f0
movl $0x1, %edi
callq 0x21f0
movl -0x48(%rbp), %eax
addq $0x60, %rsp
popq %rbp
retq