// File: /workspace/github_cpp_makefile_star2_O3/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, %rbx
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 0x1c33(%rip), %rsi      # 0x4040
leaq 0x8(%rsp), %rcx
callq 0x2200
cmpl $-0x1, %eax
je 0x24f7
movq 0x8(%rsp), %r15
testq %r15, %r15
je 0x2505
movl 0x4(%r15), %edi
movl 0x8(%r15), %esi
movl 0xc(%r15), %edx
callq 0x2060
cmpl $-0x1, %eax
je 0x24b9
movl %eax, %ebp
movq (%rbx), %rsi
movq 0x8(%rbx), %rdx
subq %rsi, %rdx
movq 0x18(%r15), %r8
movl 0x10(%r15), %r9d
movl %ebp, %edi
movl $0x20000000, %ecx       # imm = 0x20000000
callq 0x2050
cmpq $-0x1, %rax
jne 0x24e0
callq 0x2040
cmpl $0x4, (%rax)
je 0x2491
movq %rax, %r14
movq 0x18(%r15), %rsi
movl 0x10(%r15), %edx
movl %ebp, %edi
callq 0x2160
cmpl $-0x1, %eax
jne 0x24cd
cmpl $0x4, (%r14)
jne 0x24b2
movl %ebp, %edi
callq 0x2290
movl 0x4(%r15), %edi
movl 0x8(%r15), %esi
movl 0xc(%r15), %edx
callq 0x2060
movl %eax, %ebp
cmpl $-0x1, %eax
jne 0x2446
jmp 0x24b9
movl %ebp, %edi
callq 0x2290
movq 0x28(%r15), %r15
testq %r15, %r15
jne 0x242e
movq 0x8(%rsp), %rdi
jmp 0x2507
movq (%rbx), %rsi
movq 0x8(%rbx), %rdx
subq %rsi, %rdx
movl %ebp, %edi
xorl %ecx, %ecx
callq 0x20f0
movq 0x8(%rsp), %rdi
callq 0x2210
movl %ebp, %eax
addq $0x48, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1b48(%rip), %rdi      # 0x4046
callq 0x2531
jmp 0x2527
xorl %edi, %edi
callq 0x2210
movq 0x3add(%rip), %rdi      # 0x5ff0
leaq 0x1b38(%rip), %rsi      # 0x4052
callq 0x21a0
movq %rax, %rdi
callq 0x20e0
movl $0x1, %edi
callq 0x21f0