// File: /workspace/github_cpp_makefile_star2_O2/yuryu[P]tfoecho/client.cpp
// Function: getsock(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::vector<char, std::allocator<char>> const&)
int getsock(const std::string &server_addr, const std::vector<char> &msg_to_send)
{
    struct addrinfo hint, *res;
    
    std::memset(&hint, 0, sizeof(hint));
    hint.ai_family = AF_UNSPEC;
    hint.ai_socktype = SOCK_STREAM;
    
    int e = getaddrinfo(server_addr.c_str(), SERVER_PORT, &hint, &res);
    if( e == -1 )
    {
        cerror("getaddrinfo");
        std::exit(EXIT_FAILURE);
    }
    int sock;
    struct addrinfo *rp; 
    for( rp = res; rp != nullptr; rp = rp->ai_next )
    {
        // Need to create the socket again when EINTR is returned
redo:
        sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
        if( sock == -1 )
            continue;
        ssize_t r = sendto(sock, &msg_to_send[0], msg_to_send.size(),
                MSG_FASTOPEN, rp->ai_addr, rp->ai_addrlen);
        if( r == -1 && errno == EINTR )
        {
            close(sock);
            goto redo;
        }
        // Exit the loop when sendto succeeded
        if( r != -1 )
            break;
        // Try without TCP FastOpen
        r = connect(sock, rp->ai_addr, rp->ai_addrlen);
        if( r == -1 && errno == EINTR )
        {
            close(sock);
            goto redo;
        }
        if( r != -1 )
        {
            ssize_t sent;
            do
            {
                sent = send(sock, &msg_to_send[0], msg_to_send.size(), 0);
            } while( sent == -1 && sent == EINTR );
            // Success
            if( r != -1 )
                break;
        }
        close(sock);
    }
    freeaddrinfo(res);
    if( rp == nullptr )
    {
        std::cerr << "Couldn't get a socket." << std::endl;
        std::exit(EXIT_FAILURE);
    }
    return sock;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0x48, %rsp
movq %rsi, %r14
xorps %xmm0, %xmm0
leaq 0x10(%rsp), %rdx
movaps %xmm0, (%rdx)
movaps %xmm0, 0x10(%rdx)
movaps %xmm0, 0x20(%rdx)
movl $0x1, 0x8(%rdx)
movq (%rdi), %rdi
leaq 0x1c47(%rip), %rsi      # 0x4004
leaq 0x8(%rsp), %rbx
movq %rbx, %rcx
callq 0x21d0
cmpl $-0x1, %eax
je 0x2486
movq (%rbx), %rbx
testq %rbx, %rbx
je 0x246a
movl 0x4(%rbx), %edi
movl 0x8(%rbx), %esi
movl 0xc(%rbx), %edx
callq 0x2050
movl %eax, %ebp
cmpl $-0x1, %eax
je 0x244e
movq (%r14), %rsi
movq 0x8(%r14), %rdx
subq %rsi, %rdx
movq 0x18(%rbx), %r8
movl 0x10(%rbx), %r9d
movl %ebp, %edi
movl $0x20000000, %ecx       # imm = 0x20000000
callq 0x2040
cmpq $-0x1, %rax
jne 0x246a
callq 0x2030
cmpl $0x4, (%rax)
je 0x243e
movq %rax, %r15
movq 0x18(%rbx), %rsi
movl 0x10(%rbx), %edx
movl %ebp, %edi
callq 0x2150
cmpl $-0x1, %eax
jne 0x2457
cmpl $0x4, (%r15)
jne 0x2447
movl %ebp, %edi
callq 0x2250
jmp 0x23df
movl %ebp, %edi
callq 0x2250
addq $0x28, %rbx
jmp 0x23d3
movq (%r14), %rsi
movq 0x8(%r14), %rdx
subq %rsi, %rdx
movl %ebp, %edi
xorl %ecx, %ecx
callq 0x20f0
movq 0x8(%rsp), %rdi
callq 0x21e0
testq %rbx, %rbx
je 0x2494
movl %ebp, %eax
addq $0x48, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1b7d(%rip), %rdi      # 0x400a
callq 0x24b7
jmp 0x24af
movq 0x3b55(%rip), %rdi      # 0x5ff0
leaq 0x1b74(%rip), %rsi      # 0x4016
callq 0x2180
movq %rax, %rdi
callq 0x20e0
pushq $0x1
popq %rdi
callq 0x21c0