// File: /workspace/github_cpp_makefile_star2_O2/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 %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0x48, %rsp
movl %esi, %ebx
movq %rdi, %r14
pushq $0x2
popq %rdi
leaq 0x20(%rsp), %rdx
movq %r14, %rsi
callq 0x2520
testl %eax, %eax
jle 0x1d6ba
andq $0x0, 0x14(%rsp)
rolw $0x8, %bx
movw $0x2, 0xc(%rsp)
movw %bx, 0xe(%rsp)
movl 0x20(%rsp), %eax
movl %eax, 0x10(%rsp)
pushq $0x2
popq %rdi
pushq $0x1
popq %rsi
pushq $0x6
popq %rdx
callq 0x2070
movl %eax, %ebx
testl %eax, %eax
js 0x1d6d0
leaq 0x38(%rsp), %r14
movq $0x3, (%r14)
andq $0x0, 0x8(%r14)
pushq $0x1
popq %r15
pushq $0x14
popq %rdx
pushq $0x10
popq %rbp
movl %ebx, %edi
movl %r15d, %esi
movq %r14, %rcx
movl %ebp, %r8d
callq 0x24e0
movq $0x5, (%r14)
andq $0x0, 0x8(%r14)
pushq $0x15
popq %rdx
movl %ebx, %edi
movl %r15d, %esi
movq %r14, %rcx
movl %ebp, %r8d
callq 0x24e0
leaq 0x1c(%rsp), %rcx
movl $0x1, (%rcx)
pushq $0x6
popq %rsi
pushq $0x4
popq %r14
movl %ebx, %edi
movl %r15d, %edx
movl %r14d, %r8d
callq 0x24e0
pushq $0x3
popq %rsi
movl %ebx, %edi
xorl %eax, %eax
callq 0x2170
orl $0x800, %eax            # imm = 0x800
movslq %eax, %rdx
movl %ebx, %edi
movl %r14d, %esi
xorl %eax, %eax
callq 0x2170
leaq 0xc(%rsp), %rsi
movl %ebx, %edi
movl %ebp, %edx
callq 0x2200
testl %eax, %eax
jns 0x1d6e7
callq 0x2030
movq %rax, %r14
movl (%rax), %esi
leaq 0xf925(%rip), %rdi      # 0x2cf9d
xorl %eax, %eax
callq 0x2040
pushq $0x1
popq %rdi
callq 0x21b0
leaq 0xc(%rsp), %rsi
pushq $0x10
popq %rdx
movl %ebx, %edi
callq 0x2200
testl %eax, %eax
jns 0x1d6e7
movl (%r14), %esi
leaq 0xf8f9(%rip), %rdi      # 0x2cf9d
xorl %eax, %eax
callq 0x2040
cmpl $0x24, (%r14)
je 0x1d6e7
movl %ebx, %edi
callq 0x2550
jmp 0x1d6cb
leaq 0xf88e(%rip), %rdi      # 0x2cf4f
movq %r14, %rsi
xorl %eax, %eax
callq 0x2040
pushq $-0x1
popq %rbx
jmp 0x1d6e7
callq 0x2030
movl (%rax), %edx
leaq 0xf895(%rip), %rdi      # 0x2cf73
movl %ebx, %esi
xorl %eax, %eax
callq 0x2040
movl %ebx, %eax
addq $0x48, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq