// File: /workspace/github_cpp_makefile_star2_O2/theuni[P]libbtcnet/src/bareproxy.cpp
// Function: CBareProxy::writeproto(bufferevent*, CConnection const&)
bool CBareProxy::writeproto(bufferevent* bev, const CConnection& conn)
{
    bool resolve = conn.IsDNS() && conn.GetOptions().doResolve == CConnectionOptions::RESOLVE_ONLY;
    std::vector<uint8_t> vSocks5;
    vSocks5.push_back(0x05); // VER protocol version
    if (resolve) {
        vSocks5.push_back(0xf0); // CMD RESOLVE
    } else
        vSocks5.push_back(0x01); // CMD CONNECT
    vSocks5.push_back(0x00);     // RSV Reserved

    unsigned short port;

    if (conn.IsDNS() || conn.GetProxy().GetType() == CProxy::SOCKS5_FORCE_DOMAIN_TYPE) {
        const std::string& host = conn.GetHost();
        port = conn.GetPort();
        if (host.size() > 255)
            return false;
        vSocks5.push_back(0x03); // ATYP DOMAINNAME
        vSocks5.push_back(host.size());
        vSocks5.insert(vSocks5.end(), host.begin(), host.end());
        vSocks5.push_back((port >> 8) & 0xFF);
        vSocks5.push_back((port >> 0) & 0xFF);
    } else if (conn.GetProxy().GetType() == CProxy::SOCKS5) {
        sockaddr_storage sock;
        memset(&sock, 0, sizeof(sock));
        int socksize = sizeof(sock);
        conn.GetSockAddr(reinterpret_cast<sockaddr*>(&sock), &socksize);
        if (sock.ss_family == AF_INET6) {
            assert((size_t)socksize >= sizeof(sockaddr_in6));
            in6_addr addr = reinterpret_cast<sockaddr_in6*>(&sock)->sin6_addr;
            port = reinterpret_cast<sockaddr_in6*>(&sock)->sin6_port;
            vSocks5.push_back(0x04); // ATYP IPV6
            vSocks5.insert(vSocks5.end(), addr.s6_addr, addr.s6_addr + sizeof(addr.s6_addr));
            vSocks5.insert(vSocks5.end(), reinterpret_cast<unsigned char*>(&port), reinterpret_cast<unsigned char*>(&port) + sizeof(port));
            assert(vSocks5.size() == 22);
        } else if (sock.ss_family == AF_INET) {
            assert((size_t)socksize >= sizeof(sockaddr_in));
            in_addr addr = reinterpret_cast<sockaddr_in*>(&sock)->sin_addr;
            port = reinterpret_cast<sockaddr_in*>(&sock)->sin_port;
            vSocks5.push_back(0x01); // ATYP IPV4
            vSocks5.insert(vSocks5.end(), reinterpret_cast<unsigned char*>(&addr), reinterpret_cast<unsigned char*>(&addr) + sizeof(addr));
            vSocks5.insert(vSocks5.end(), reinterpret_cast<unsigned char*>(&port), reinterpret_cast<unsigned char*>(&port) + sizeof(port));
            assert(vSocks5.size() == 10);
        } else
            return false;
    } else
        return false;
    bufferevent_setwatermark(bev, EV_READ, 8, 0);
    bufferevent_write(bev, &vSocks5[0], vSocks5.size());
    return true;
}

// Assembly:
pushq %rbp
pushq %r14
pushq %rbx
subq $0xc0, %rsp
movq %rsi, %r14
movq %rdi, %rbx
movq %rsi, %rdi
callq 0x5d02
testb %al, %al
je 0xddc7
movq %r14, %rdi
callq 0x63e8
cmpl $0x2, 0x4(%rax)
sete %bpl
jmp 0xddc9
xorl %ebp, %ebp
leaq 0x10(%rsp), %rdi
andq $0x0, 0x10(%rdi)
xorps %xmm0, %xmm0
movaps %xmm0, (%rdi)
leaq 0x40(%rsp), %rsi
movb $0x5, (%rsi)
callq 0x73f2
leaq 0x40(%rsp), %rsi
testb %bpl, %bpl
je 0xddff
movb $-0x10, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x73f2
jmp 0xde0c
movb $0x1, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x73f2
leaq 0x40(%rsp), %rsi
movb $0x0, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x73f2
movq %r14, %rdi
callq 0x5d02
testb %al, %al
jne 0xde43
movq %r14, %rdi
callq 0x63e2
movq %rax, %rdi
callq 0x5cfa
cmpl $0x2, %eax
jne 0xdf1e
leaq 0x40(%rsp), %rdi
movq %r14, %rsi
callq 0x5d62
movq %r14, %rdi
callq 0x5e62
movw %ax, 0xc(%rsp)
cmpq $0x100, 0x48(%rsp)      # imm = 0x100
jae 0xdf0f
leaq 0x30(%rsp), %rsi
movb $0x3, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x73f2
movb 0x48(%rsp), %al
leaq 0x30(%rsp), %rsi
movb %al, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x73f2
leaq 0x10(%rsp), %rdi
movq 0x8(%rdi), %rsi
movq 0x40(%rsp), %rdx
movq 0x48(%rsp), %rcx
addq %rdx, %rcx
callq 0xe6ec
movb 0xd(%rsp), %al
leaq 0x30(%rsp), %rsi
movb %al, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x73f2
movb 0xc(%rsp), %al
leaq 0x30(%rsp), %rsi
movb %al, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x73f2
leaq 0x40(%rsp), %rdi
callq 0x41a0
pushq $0x2
popq %rsi
pushq $0x8
popq %rdx
movq %rbx, %rdi
xorl %ecx, %ecx
callq 0x40c0
movq 0x10(%rsp), %rsi
movq 0x18(%rsp), %rdx
subq %rsi, %rdx
movb $0x1, %bpl
movq %rbx, %rdi
callq 0x41f0
jmp 0xe01b
leaq 0x40(%rsp), %rdi
callq 0x41a0
jmp 0xe019
movq %r14, %rdi
callq 0x63e2
movq %rax, %rdi
callq 0x5cfa
cmpl $0x1, %eax
jne 0xe019
xorps %xmm0, %xmm0
leaq 0x40(%rsp), %rsi
movaps %xmm0, 0x70(%rsi)
movaps %xmm0, 0x60(%rsi)
movaps %xmm0, 0x50(%rsi)
movaps %xmm0, 0x40(%rsi)
movaps %xmm0, 0x30(%rsi)
movaps %xmm0, 0x20(%rsi)
movaps %xmm0, 0x10(%rsi)
movaps %xmm0, (%rsi)
leaq 0x2c(%rsp), %rdx
movl $0x80, (%rdx)
movq %r14, %rdi
callq 0x5d0a
movzwl 0x40(%rsp), %eax
cmpl $0x2, %eax
je 0xe033
cmpl $0xa, %eax
jne 0xe019
cmpl $0x1b, 0x2c(%rsp)
jbe 0xe0bf
movups 0x48(%rsp), %xmm0
movaps %xmm0, 0x30(%rsp)
movzwl 0x42(%rsp), %eax
movw %ax, 0xc(%rsp)
leaq 0xf(%rsp), %rsi
movb $0x4, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x73f2
leaq 0x10(%rsp), %rdi
movq 0x8(%rdi), %rsi
leaq 0x40(%rsp), %rcx
leaq 0x30(%rsp), %rdx
callq 0xe70c
leaq 0x10(%rsp), %rdi
movq 0x8(%rdi), %rsi
leaq 0xe(%rsp), %rcx
leaq 0xc(%rsp), %rdx
callq 0xe70c
movq 0x18(%rsp), %rax
subq 0x10(%rsp), %rax
cmpq $0x16, %rax
je 0xdee2
leaq 0x3fb4(%rip), %rdi      # 0x11fb8
leaq 0x3ef4(%rip), %rsi      # 0x11eff
leaq 0x3f5f(%rip), %rcx      # 0x11f71
pushq $0x5f
jmp 0xe0ef
xorl %ebp, %ebp
leaq 0x10(%rsp), %rdi
callq 0x4fd0
movl %ebp, %eax
addq $0xc0, %rsp
popq %rbx
popq %r14
popq %rbp
retq
cmpl $0xf, 0x2c(%rsp)
jbe 0xe0d8
movl 0x44(%rsp), %eax
movl %eax, 0x30(%rsp)
movzwl 0x42(%rsp), %eax
movw %ax, 0xc(%rsp)
leaq 0xf(%rsp), %rsi
movb $0x1, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x73f2
leaq 0x10(%rsp), %rdi
movq 0x8(%rdi), %rsi
leaq 0x34(%rsp), %rcx
leaq 0x30(%rsp), %rdx
callq 0xe70c
leaq 0x10(%rsp), %rdi
movq 0x8(%rdi), %rsi
leaq 0xe(%rsp), %rcx
leaq 0xc(%rsp), %rdx
callq 0xe70c
movq 0x18(%rsp), %rax
subq 0x10(%rsp), %rax
cmpq $0xa, %rax
je 0xdee2
leaq 0x3f48(%rip), %rdi      # 0x11ff5
leaq 0x3e4b(%rip), %rsi      # 0x11eff
leaq 0x3eb6(%rip), %rcx      # 0x11f71
pushq $0x67
jmp 0xe0ef
leaq 0x3e82(%rip), %rdi      # 0x11f48
leaq 0x3e32(%rip), %rsi      # 0x11eff
leaq 0x3e9d(%rip), %rcx      # 0x11f71
pushq $0x59
jmp 0xe0ef
leaq 0x3eee(%rip), %rdi      # 0x11fcd
leaq 0x3e19(%rip), %rsi      # 0x11eff
leaq 0x3e84(%rip), %rcx      # 0x11f71
pushq $0x61
popq %rdx
callq 0x4260
jmp 0xe126
jmp 0xe126
jmp 0xe126
jmp 0xe126
jmp 0xe126
jmp 0xe126
jmp 0xe126
jmp 0xe111
jmp 0xe111
jmp 0xe111
jmp 0xe111
jmp 0xe111
jmp 0xe126
jmp 0xe126
movq %rax, %rbx
leaq 0x40(%rsp), %rdi
callq 0x41a0
jmp 0xe129
jmp 0xe126
jmp 0xe126
jmp 0xe126
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x4fd0
movq %rbx, %rdi
callq 0x4660
nop