// File: /workspace/github_cpp_makefile_star2_O3/Eba-M[P]E3DC-Control/SocketConnection.cpp
// Function: SocketConnect_noblock(char const*, int)
int SocketConnect_noblock(const char *cpIpAddress, int iPort) {

    unsigned char ucBuffer[sizeof(struct in6_addr)];

    if(inet_pton(AF_INET, cpIpAddress, ucBuffer) <= 0) {
        printf("IP address %s cannot be converted.\n", cpIpAddress);
        return -1;
    }

    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(iPort);
    server_addr.sin_addr = *((struct in_addr *) ucBuffer);

    int iSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(iSocket < 0) {
        printf("Cannot create socket. Error %i errno %i.\n", iSocket, errno);
        return iSocket;
    }

    // 3 secs receive timeout setup
    struct timeval tv;
    tv.tv_sec = 3;
    tv.tv_usec = 0;
    setsockopt(iSocket, SOL_SOCKET, SO_RCVTIMEO, (struct timeval *) &tv, sizeof(struct timeval));
    // send time out should never occur on normal OS configurations but just in case set the timeout to 5 seconds
    tv.tv_sec = 5;
    tv.tv_usec = 0;
    setsockopt(iSocket, SOL_SOCKET, SO_SNDTIMEO, (struct timeval *) &tv, sizeof(struct timeval));

    int enable = 1;
    setsockopt(iSocket, IPPROTO_TCP, TCP_NODELAY, (char *) &enable, sizeof(enable));

    long save_fd = fcntl( iSocket, F_GETFL );
    save_fd |= O_NONBLOCK;
    fcntl( iSocket, F_SETFL, save_fd );

    // wait 3 seconds for connection to get ready
    int iRetries = 3;
    if(connect(iSocket, (struct sockaddr *) &server_addr, sizeof(struct sockaddr)) < 0) {
        printf("Cannot connect to server. errno %i.\n", errno);
        sleep(1);
        if(connect(iSocket, (struct sockaddr *) &server_addr, sizeof(struct sockaddr)) < 0) {
            printf("Cannot connect to server. errno %i.\n", errno);
            if (errno != 36) {
            close(iSocket);
                return -1;}
            }
    }

    return iSocket;
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0x40, %rsp
movl %esi, %ebx
movq %rdi, %r14
leaq 0x20(%rsp), %rdx
movl $0x2, %edi
movq %r14, %rsi
callq 0x2500
testl %eax, %eax
jle 0x208cf
movq $0x0, 0x14(%rsp)
rolw $0x8, %bx
movw $0x2, 0xc(%rsp)
movw %bx, 0xe(%rsp)
movl 0x20(%rsp), %eax
movl %eax, 0x10(%rsp)
movl $0x2, %edi
movl $0x1, %esi
movl $0x6, %edx
callq 0x2070
movl %eax, %ebx
testl %eax, %eax
js 0x208e7
leaq 0x30(%rsp), %r14
movq $0x3, (%r14)
xorl %r15d, %r15d
movq %r15, 0x8(%r14)
movl %ebx, %edi
movl $0x1, %esi
movl $0x14, %edx
movq %r14, %rcx
movl $0x10, %r8d
callq 0x24b0
movq $0x5, (%r14)
movq %r15, 0x8(%r14)
movl %ebx, %edi
movl $0x1, %esi
movl $0x15, %edx
movq %r14, %rcx
movl $0x10, %r8d
callq 0x24b0
leaq 0x1c(%rsp), %rcx
movl $0x1, (%rcx)
movl %ebx, %edi
movl $0x6, %esi
movl $0x1, %edx
movl $0x4, %r8d
callq 0x24b0
movl %ebx, %edi
movl $0x3, %esi
xorl %eax, %eax
callq 0x2160
orl $0x800, %eax            # imm = 0x800
movslq %eax, %rdx
movl %ebx, %edi
movl $0x4, %esi
xorl %eax, %eax
callq 0x2160
leaq 0xc(%rsp), %rsi
movl %ebx, %edi
movl $0x10, %edx
callq 0x2200
testl %eax, %eax
jns 0x208fe
callq 0x2030
movq %rax, %r14
movl (%rax), %esi
leaq 0x118e4(%rip), %rdi     # 0x3216d
xorl %eax, %eax
callq 0x2040
movl $0x1, %edi
callq 0x21b0
leaq 0xc(%rsp), %rsi
movl %ebx, %edi
movl $0x10, %edx
callq 0x2200
testl %eax, %eax
jns 0x208fe
movl (%r14), %esi
leaq 0x118b4(%rip), %rdi     # 0x3216d
xorl %eax, %eax
callq 0x2040
cmpl $0x24, (%r14)
je 0x208fe
movl %ebx, %edi
callq 0x2520
jmp 0x208e0
leaq 0x11849(%rip), %rdi     # 0x3211f
movq %r14, %rsi
xorl %eax, %eax
callq 0x2040
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
jmp 0x208fe
callq 0x2030
movl (%rax), %edx
leaq 0x1184e(%rip), %rdi     # 0x32143
movl %ebx, %esi
xorl %eax, %eax
callq 0x2040
movl %ebx, %eax
addq $0x40, %rsp
popq %rbx
popq %r14
popq %r15
retq