// File: /workspace/github_c_makefile_star2_O0/TimeToogo[P]ff-proxy/client/c/client.c
// Function: ff_client_send_request
uint8_t ff_client_send_request(struct ff_client_config *config, struct ff_client_packet *packets, uint32_t packets_count)
{
    uint8_t ret;
    int err;
    int sockfd = 0;
    struct addrinfo hints;
    struct addrinfo *res = NULL;
    int sent_length = 0;
    int chunk_length = 0;
    char ip_string[INET6_ADDRSTRLEN + 1] = {0};

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_DGRAM;
    err = getaddrinfo(config->ip_address, config->port, &hints, &res);
    if (err)
    {
        ff_log(FF_FATAL, "Failed to perform DNS lookup for host: %s", config->ip_address);
        goto error;
    }

    ff_log(FF_DEBUG, "Creating socket");
    sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);

    if (sockfd < 0)
    {
        ff_log(FF_FATAL, "Failed to create socket");
        goto error;
    }

    if (res->ai_family == AF_INET)
    {
        inet_ntop(AF_INET, &((struct sockaddr_in *)res->ai_addr)->sin_addr, ip_string, INET_ADDRSTRLEN);
    }
    else
    {
        inet_ntop(AF_INET6, &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, ip_string, INET6_ADDRSTRLEN);
    }
    ff_log(FF_INFO, "Sending request to %s%s%s:%s",
           strchr(ip_string, ':') ? "[" : "", ip_string, strchr(ip_string, ':') ? "]" : "", config->port);

    int flag = true;
    if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag)) < 0)
    {
        ff_log(FF_WARNING, "Failed to set socket option (errno: %d)", errno);
    }


    for (uint16_t i = 0; i < packets_count; i++)
    {
        ff_log(
            FF_INFO, "sending packet %d byte range [%d, %d]", 
            i, 0, (int)packets[i].length
        );
        chunk_length = sendto(
            sockfd, 
            packets[i].value, 
            (int)packets[i].length, 
            0, 
            res->ai_addr, 
            res->ai_addrlen
        );

        if (chunk_length <= 0)
        {
            printf("errno: %d\n", errno);
            ff_log(FF_FATAL, "Failed to send UDP datagrams during byte range %d - %hu", 0, packets[i].length);
            goto error;
        }

        sent_length += chunk_length;
    }

    ff_log(FF_DEBUG, "Finished sending %d bytes", sent_length);
    goto done;

done:
    ret = 0;
    goto cleanup;

error:
    ret = EXIT_FAILURE;
    goto cleanup;

cleanup:
    if (res != NULL)
    {
        freeaddrinfo(res);
    }

    if (close(sockfd))
    {
        ff_log(FF_WARNING, "Failed to close socket");
    }

    return ret;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movl $0x0, -0x20(%rbp)
movq $0x0, -0x58(%rbp)
movl $0x0, -0x5c(%rbp)
movl $0x0, -0x60(%rbp)
leaq -0x90(%rbp), %rdi
xorl %esi, %esi
movl $0x2f, %edx
callq 0x2100
leaq -0x50(%rbp), %rdi
xorl %esi, %esi
movl $0x30, %edx
callq 0x2100
movl $0x0, -0x4c(%rbp)
movl $0x2, -0x48(%rbp)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x8(%rbp), %rax
movq (%rax), %rsi
leaq -0x50(%rbp), %rdx
leaq -0x58(%rbp), %rcx
callq 0x2220
movl %eax, -0x1c(%rbp)
cmpl $0x0, -0x1c(%rbp)
je 0x2d89
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdx
movl $0x5, %edi
leaq 0x3387(%rip), %rsi      # 0x6104
movb $0x0, %al
callq 0x4480
jmp 0x3029
movl $0x1, %edi
leaq 0x3399(%rip), %rsi      # 0x612e
movb $0x0, %al
callq 0x4480
movq -0x58(%rbp), %rax
movl 0x4(%rax), %edi
movq -0x58(%rbp), %rax
movl 0x8(%rax), %esi
movq -0x58(%rbp), %rax
movl 0xc(%rax), %edx
callq 0x2090
movl %eax, -0x20(%rbp)
cmpl $0x0, -0x20(%rbp)
jge 0x2dd7
movl $0x5, %edi
leaq 0x3373(%rip), %rsi      # 0x613e
movb $0x0, %al
callq 0x4480
jmp 0x3029
movq -0x58(%rbp), %rax
cmpl $0x2, 0x4(%rax)
jne 0x2e05
movq -0x58(%rbp), %rax
movq 0x18(%rax), %rsi
addq $0x4, %rsi
leaq -0x90(%rbp), %rdx
movl $0x2, %edi
movl $0x10, %ecx
callq 0x21c0
jmp 0x2e27
movq -0x58(%rbp), %rax
movq 0x18(%rax), %rsi
addq $0x8, %rsi
leaq -0x90(%rbp), %rdx
movl $0xa, %edi
movl $0x2e, %ecx
callq 0x21c0
leaq -0x90(%rbp), %rdi
movl $0x3a, %esi
callq 0x20c0
movq %rax, %rdx
leaq 0x3507(%rip), %rax      # 0x6349
leaq 0x332a(%rip), %rcx      # 0x6173
cmpq $0x0, %rdx
cmovneq %rcx, %rax
movq %rax, -0xb0(%rbp)
leaq -0x90(%rbp), %rax
movq %rax, -0xa8(%rbp)
leaq -0x90(%rbp), %rdi
movl $0x3a, %esi
callq 0x20c0
movq -0xb0(%rbp), %rdx
movq -0xa8(%rbp), %rcx
movq %rax, %rsi
leaq 0x34ba(%rip), %r8       # 0x6349
leaq 0x332b(%rip), %rax      # 0x61c1
cmpq $0x0, %rsi
cmovneq %rax, %r8
movq -0x8(%rbp), %rax
movq (%rax), %r9
movl $0x2, %edi
leaq 0x32a5(%rip), %rsi      # 0x6156
movb $0x0, %al
callq 0x4480
movl $0x1, -0x94(%rbp)
movl -0x20(%rbp), %edi
movl $0x1, %esi
movl $0x2, %edx
leaq -0x94(%rbp), %rcx
movl $0x4, %r8d
callq 0x2300
cmpl $0x0, %eax
jge 0x2f00
callq 0x2030
movl (%rax), %edx
movl $0x3, %edi
leaq 0x327c(%rip), %rsi      # 0x6175
movb $0x0, %al
callq 0x4480
movw $0x0, -0x96(%rbp)
movzwl -0x96(%rbp), %eax
cmpl -0x14(%rbp), %eax
jae 0x300d
movzwl -0x96(%rbp), %edx
movq -0x10(%rbp), %rax
movzwl -0x96(%rbp), %ecx
shlq $0x4, %rcx
addq %rcx, %rax
movzwl 0x8(%rax), %r8d
movl $0x2, %edi
leaq 0x325a(%rip), %rsi      # 0x619d
xorl %ecx, %ecx
movb $0x0, %al
callq 0x4480
movl -0x20(%rbp), %edi
movq -0x10(%rbp), %rax
movzwl -0x96(%rbp), %ecx
shlq $0x4, %rcx
addq %rcx, %rax
movq (%rax), %rsi
movq -0x10(%rbp), %rax
movzwl -0x96(%rbp), %ecx
shlq $0x4, %rcx
addq %rcx, %rax
movzwl 0x8(%rax), %eax
movslq %eax, %rdx
movq -0x58(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0xa0(%rbp)
movq -0x58(%rbp), %rax
movl 0x10(%rax), %r9d
movq -0xa0(%rbp), %r8
xorl %ecx, %ecx
callq 0x2060
movl %eax, -0x60(%rbp)
cmpl $0x0, -0x60(%rbp)
jg 0x2fed
callq 0x2030
movl (%rax), %esi
leaq 0x320a(%rip), %rdi      # 0x61c3
movb $0x0, %al
callq 0x2040
movq -0x10(%rbp), %rax
movzwl -0x96(%rbp), %ecx
shlq $0x4, %rcx
addq %rcx, %rax
movzwl 0x8(%rax), %ecx
movl $0x5, %edi
leaq 0x31ec(%rip), %rsi      # 0x61ce
xorl %edx, %edx
movb $0x0, %al
callq 0x4480
jmp 0x3029
movl -0x60(%rbp), %eax
addl -0x5c(%rbp), %eax
movl %eax, -0x5c(%rbp)
movw -0x96(%rbp), %ax
addw $0x1, %ax
movw %ax, -0x96(%rbp)
jmp 0x2f09
movl -0x5c(%rbp), %edx
movl $0x1, %edi
leaq 0x31ea(%rip), %rsi      # 0x6206
movb $0x0, %al
callq 0x4480
movb $0x0, -0x15(%rbp)
jmp 0x302d
movb $0x1, -0x15(%rbp)
cmpq $0x0, -0x58(%rbp)
je 0x303d
movq -0x58(%rbp), %rdi
callq 0x2230
movl -0x20(%rbp), %edi
callq 0x2330
cmpl $0x0, %eax
je 0x305d
movl $0x3, %edi
leaq 0x31ca(%rip), %rsi      # 0x6220
movb $0x0, %al
callq 0x4480
movb -0x15(%rbp), %al
addq $0xb0, %rsp
popq %rbp
retq
nopl (%rax)