// File: rellla[P]E3DC-Rscp/SocketConnection.cpp
// Function: SocketConnect(char const*, int)
int SocketConnect(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));


    // 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);
        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 0x22d0
cmpl $0x0, %eax
jg 0x1f516
movq 0x58(%rsp), %rsi
leaq 0x14b2(%rip), %rdi      # 0x209b4
movb $0x0, %al
callq 0x2040
movl $0xffffffff, 0x64(%rsp) # imm = 0xFFFFFFFF
jmp 0x1f66a
leaq 0x30(%rsp), %rdi
xorl %esi, %esi
movl $0x10, %edx
callq 0x20e0
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 0x2060
movl %eax, 0x2c(%rsp)
cmpl $0x0, 0x2c(%rsp)
jge 0x1f594
movl 0x2c(%rsp), %eax
movl %eax, 0xc(%rsp)
callq 0x2030
movl 0xc(%rsp), %esi
movl (%rax), %edx
leaq 0x1458(%rip), %rdi      # 0x209d8
movb $0x0, %al
callq 0x2040
movl 0x2c(%rsp), %eax
movl %eax, 0x64(%rsp)
jmp 0x1f66a
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 0x22b0
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 0x22b0
movl $0x1, 0x14(%rsp)
movl 0x2c(%rsp), %edi
movl $0x6, %esi
movl $0x1, %edx
leaq 0x14(%rsp), %rcx
movl $0x4, %r8d
callq 0x22b0
movl $0x3, 0x10(%rsp)
movl 0x2c(%rsp), %edi
leaq 0x30(%rsp), %rsi
movl $0x10, %edx
callq 0x2140
cmpl $0x0, %eax
jge 0x1f662
callq 0x2030
movl (%rax), %esi
leaq 0x13ba(%rip), %rdi      # 0x20a02
movb $0x0, %al
callq 0x2040
movl 0x2c(%rsp), %edi
callq 0x22e0
movl $0xffffffff, 0x64(%rsp) # imm = 0xFFFFFFFF
jmp 0x1f66a
movl 0x2c(%rsp), %eax
movl %eax, 0x64(%rsp)
movl 0x64(%rsp), %eax
addq $0x68, %rsp
retq
nopw %cs:(%rax,%rax)