// File: 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:
subq $0x68, %rsp
movq %rdi, 0x58(%rsp)
movl %esi, 0x54(%rsp)
movq 0x58(%rsp), %rsi
leaq 0x40(%rsp), %rdx
movl $0x2, %edi
callq 0x2520
cmpl $0x0, %eax
jg 0x362c6
movq 0x58(%rsp), %rsi
leaq 0x2bb3d(%rip), %rdi     # 0x61def
movb $0x0, %al
callq 0x2040
movl $0xffffffff, 0x64(%rsp) # imm = 0xFFFFFFFF
jmp 0x36499
leaq 0x30(%rsp), %rdi
xorl %esi, %esi
movl $0x10, %edx
callq 0x2170
movw $0x2, 0x30(%rsp)
movl 0x54(%rsp), %eax
movzwl %ax, %edi
callq 0x2050
movw %ax, 0x32(%rsp)
movl 0x40(%rsp), %eax
movl %eax, 0x34(%rsp)
movl $0x2, %edi
movl $0x1, %esi
movl $0x6, %edx
callq 0x2080
movl %eax, 0x2c(%rsp)
cmpl $0x0, 0x2c(%rsp)
jge 0x36342
movl 0x2c(%rsp), %eax
movl %eax, (%rsp)
callq 0x2030
movl (%rsp), %esi
movl (%rax), %edx
leaq 0x2bae5(%rip), %rdi     # 0x61e13
movb $0x0, %al
callq 0x2040
movl 0x2c(%rsp), %eax
movl %eax, 0x64(%rsp)
jmp 0x36499
movq $0x3, 0x18(%rsp)
movq $0x0, 0x20(%rsp)
movl 0x2c(%rsp), %edi
movl $0x1, %esi
movl $0x14, %edx
leaq 0x18(%rsp), %rcx
movl $0x10, %r8d
callq 0x24e0
movq $0x5, 0x18(%rsp)
movq $0x0, 0x20(%rsp)
movl 0x2c(%rsp), %edi
movl $0x1, %esi
movl $0x15, %edx
leaq 0x18(%rsp), %rcx
movl $0x10, %r8d
callq 0x24e0
movl $0x1, 0x14(%rsp)
movl 0x2c(%rsp), %edi
movl $0x6, %esi
movl $0x1, %edx
leaq 0x14(%rsp), %rcx
movl $0x4, %r8d
callq 0x24e0
movl 0x2c(%rsp), %edi
movl $0x3, %esi
movb $0x0, %al
callq 0x2190
cltq
movq %rax, 0x8(%rsp)
movq 0x8(%rsp), %rax
orq $0x800, %rax            # imm = 0x800
movq %rax, 0x8(%rsp)
movl 0x2c(%rsp), %edi
movq 0x8(%rsp), %rdx
movl $0x4, %esi
movb $0x0, %al
callq 0x2190
movl $0x3, 0x4(%rsp)
movl 0x2c(%rsp), %edi
leaq 0x30(%rsp), %rsi
movl $0x10, %edx
callq 0x2230
cmpl $0x0, %eax
jge 0x36491
callq 0x2030
movl (%rax), %esi
leaq 0x2ba0b(%rip), %rdi     # 0x61e3d
movb $0x0, %al
callq 0x2040
movl $0x1, %edi
callq 0x21e0
movl 0x2c(%rsp), %edi
leaq 0x30(%rsp), %rsi
movl $0x10, %edx
callq 0x2230
cmpl $0x0, %eax
jge 0x3648f
callq 0x2030
movl (%rax), %esi
leaq 0x2b9d4(%rip), %rdi     # 0x61e3d
movb $0x0, %al
callq 0x2040
callq 0x2030
cmpl $0x24, (%rax)
je 0x3648d
movl 0x2c(%rsp), %edi
callq 0x2540
movl $0xffffffff, 0x64(%rsp) # imm = 0xFFFFFFFF
jmp 0x36499
jmp 0x3648f
jmp 0x36491
movl 0x2c(%rsp), %eax
movl %eax, 0x64(%rsp)
movl 0x64(%rsp), %eax
addq $0x68, %rsp
retq
nopw %cs:(%rax,%rax)