// File: NovaGL[P]HarmonyHubControl/csocket.cpp
// Function: csocket::connect(char const*, unsigned int)
int csocket::connect( const char* remoteHost, unsigned int remotePort )
{
    if ( m_socketState != CLOSED ) 
    {
        return ERROR_INAPPROPRIATE_STATE;
    }

    struct hostent *pHostEnt = NULL;
    int status = resolveHost(remoteHost, &pHostEnt);
    if (status == FAILURE || !pHostEnt) 
    {
        return FAILURE;
    }

    m_strRemoteHost = remoteHost;
    m_remotePort = remotePort;

    m_remoteSocketAddr.sin_family = pHostEnt->h_addrtype;
    memcpy((char *) &m_remoteSocketAddr.sin_addr.s_addr,
        pHostEnt->h_addr_list[0], 
        pHostEnt->h_length);

    m_remoteSocketAddr.sin_port = htons(m_remotePort);


#ifdef _WIN32
    m_socket = WSASocket(AF_INET, SOCK_STREAM, 
        IPPROTO_TCP, 0 , 0 , 0);

    if (m_socket == INVALID_SOCKET)
    {
        return FAILURE;
    }
#else
    m_socket = socket(AF_INET, SOCK_STREAM, 0);
#endif

    if (m_socket < 0) 
    {
        return FAILURE;
    }

    m_localSocketAddr.sin_family = AF_INET;

    m_localSocketAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    
    int         iRecvTimeout = 1;
    setsockopt(m_socket, SOL_SOCKET, SO_RCVTIMEO, 
        (char*) &iRecvTimeout, sizeof(iRecvTimeout) );

    m_localSocketAddr.sin_port = htons(0);

    status = bind( m_socket, 
        (const sockaddr*)&(m_localSocketAddr),  
        sizeof(struct sockaddr) );

    if (status < 0) 
    {
        return FAILURE;
    }

#ifdef _WIN32 
    int set = 1;
    setsockopt(m_socket, IPPROTO_TCP, TCP_NODELAY,  (char*) &set, sizeof(set) );
#endif

    m_remoteSocketAddr.sin_family = pHostEnt->h_addrtype;

    memcpy(&(m_remoteSocketAddr.sin_addr), 
                pHostEnt->h_addr, 
                pHostEnt->h_length);

    m_remoteSocketAddr.sin_port = htons( m_remotePort );

    status = ::connect(m_socket, 
                    (const sockaddr*)&(m_remoteSocketAddr), 
                    sizeof(m_remoteSocketAddr)  );

    if (status < 0) 
    {
        return FAILURE;
    }

    m_socketState = CONNECTED;

    return SUCCESS;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x70(%rbp)
cmpl $0x0, 0x2c(%rax)
je 0x14c20
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x14e40
movq $0x0, -0x28(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x80(%rbp)
leaq -0x51(%rbp), %rdi
movq %rdi, -0x78(%rbp)
callq 0x35f0
movq -0x80(%rbp), %rsi
movq -0x78(%rbp), %rdx
leaq -0x50(%rbp), %rdi
callq 0x8b50
jmp 0x14c50
leaq -0x50(%rbp), %rdi
leaq -0x28(%rbp), %rsi
callq 0x14b30
movl %eax, -0x84(%rbp)
jmp 0x14c65
leaq -0x50(%rbp), %rdi
callq 0x3698
leaq -0x51(%rbp), %rdi
callq 0x33f0
movl -0x84(%rbp), %eax
movl %eax, -0x2c(%rbp)
cmpl $0x1, -0x2c(%rbp)
je 0x14c8d
cmpq $0x0, -0x28(%rbp)
jne 0x14cca
movl $0x1, -0x4(%rbp)
jmp 0x14e40
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0x14cbc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x50(%rbp), %rdi
callq 0x3698
leaq -0x51(%rbp), %rdi
callq 0x33f0
jmp 0x14e4c
movq -0x70(%rbp), %rdi
movq -0x18(%rbp), %rsi
addq $0x30, %rdi
callq 0x34c0
movq -0x70(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, 0x50(%rdi)
movq -0x28(%rbp), %rax
movl 0x10(%rax), %eax
movw %ax, 0x1c(%rdi)
addq $0x1c, %rdi
addq $0x4, %rdi
movq -0x28(%rbp), %rax
movq 0x18(%rax), %rax
movq (%rax), %rsi
movq -0x28(%rbp), %rax
movslq 0x14(%rax), %rdx
callq 0x32f0
movq -0x70(%rbp), %rax
movl 0x50(%rax), %eax
movzwl %ax, %edi
callq 0x3080
movw %ax, %cx
movq -0x70(%rbp), %rax
movw %cx, 0x1e(%rax)
movl $0x2, %edi
movl $0x1, %esi
xorl %edx, %edx
callq 0x3130
movl %eax, %ecx
movq -0x70(%rbp), %rax
movl %ecx, 0x8(%rax)
cmpl $0x0, 0x8(%rax)
jge 0x14d56
movl $0x1, -0x4(%rbp)
jmp 0x14e40
movq -0x70(%rbp), %rax
movw $0x2, 0xc(%rax)
xorl %edi, %edi
callq 0x32b0
movl %eax, %ecx
movq -0x70(%rbp), %rax
movl %ecx, 0x10(%rax)
movl $0x1, -0x68(%rbp)
movl 0x8(%rax), %edi
movl $0x1, %esi
movl $0x14, %edx
leaq -0x68(%rbp), %rcx
movl $0x4, %r8d
callq 0x3600
xorl %edi, %edi
callq 0x3080
movq -0x70(%rbp), %rsi
movw %ax, 0xe(%rsi)
movl 0x8(%rsi), %edi
addq $0xc, %rsi
movl $0x10, %edx
callq 0x30a0
movl %eax, -0x2c(%rbp)
cmpl $0x0, -0x2c(%rbp)
jge 0x14dc5
movl $0x1, -0x4(%rbp)
jmp 0x14e40
movq -0x70(%rbp), %rdi
movq -0x28(%rbp), %rax
movl 0x10(%rax), %eax
movw %ax, 0x1c(%rdi)
addq $0x1c, %rdi
addq $0x4, %rdi
movq -0x28(%rbp), %rax
movq 0x18(%rax), %rax
movq (%rax), %rsi
movq -0x28(%rbp), %rax
movslq 0x14(%rax), %rdx
callq 0x32f0
movq -0x70(%rbp), %rax
movl 0x50(%rax), %eax
movzwl %ax, %edi
callq 0x3080
movq -0x70(%rbp), %rsi
movw %ax, 0x1e(%rsi)
movl 0x8(%rsi), %edi
addq $0x1c, %rsi
movl $0x10, %edx
callq 0x3300
movl %eax, -0x2c(%rbp)
cmpl $0x0, -0x2c(%rbp)
jge 0x14e2e
movl $0x1, -0x4(%rbp)
jmp 0x14e40
movq -0x70(%rbp), %rax
movl $0x1, 0x2c(%rax)
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x90, %rsp
popq %rbp
retq
movq -0x60(%rbp), %rdi
callq 0x35e0
nopw %cs:(%rax,%rax)