// File: /workspace/github_cpp_makefile_star2_O2/theuni[P]libbtcnet/src/bareproxy.cpp
// Function: CBareProxy::read_final(bufferevent*, void*)
void CBareProxy::read_final(bufferevent* bev, void* ctx)
{
    CBareProxy* data = static_cast<CBareProxy*>(ctx);
    const CConnection& conn = data->m_proxy_connection;
    evbuffer* input = bufferevent_get_input(bev);
    size_t len = evbuffer_get_length(input);
    int result;
    assert(len >= 8);
    char pchRet2[5] = {};
    result = evbuffer_copyout(input, pchRet2, sizeof(pchRet2));
    assert(result == sizeof(pchRet2));
    (void)result;
    if (pchRet2[0] != 0x05 || pchRet2[1] != 0x00) {
        data->ProxyFailure(0);
        return;
    }
    size_t needSize = 6;
    size_t addrsize;
    int sockaddr_size;
    bool ip = true;
    sockaddr_storage addr;
    memset(&addr, 0, sizeof(addr));
    void* writeip = nullptr;
    switch (pchRet2[3]) {
    case 0x01:
        addrsize = 4;
        addr.ss_family = AF_INET;
        sockaddr_size = sizeof(sockaddr_in);
        reinterpret_cast<sockaddr_in*>(&addr)->sin_port = htons(conn.GetPort());
        writeip = &(reinterpret_cast<sockaddr_in*>(&addr)->sin_addr);
        break;
    case 0x04:
        addrsize = 16;
        addr.ss_family = AF_INET6;
        sockaddr_size = sizeof(sockaddr_in6);
        reinterpret_cast<sockaddr_in6*>(&addr)->sin6_port = htons(conn.GetPort());
        writeip = &(reinterpret_cast<sockaddr_in6*>(&addr)->sin6_addr);
        break;
    case 0x03:
        addrsize = pchRet2[4];
        needSize += 1;
        ip = false;
        sockaddr_size = 0;
        break;
    default:
        data->ProxyFailure(0);
        return;
    }

    needSize += addrsize;

    if (len < needSize) {
        bufferevent_setwatermark(bev, EV_READ, needSize, 0);
        return;
    }

    if (ip) {
        result = evbuffer_drain(input, 4);
        assert(result == 0);
        (void)result;
        result = evbuffer_remove(input, writeip, addrsize);
        assert(result == (int)addrsize);
        (void)result;
        // Throw this away.
        char port[2] = {};
        result = evbuffer_remove(input, port, sizeof(port));
        assert(result == sizeof(port));
        (void)result;
    } else {
        result = evbuffer_drain(input, 5 + addrsize + 2);
        assert(result == 0);
        (void)result;
    }

    CConnection ret = conn;
    if (ip && conn.IsDNS() && conn.GetOptions().doResolve == CConnectionOptions::RESOLVE_ONLY)
        ret = CConnection(conn.GetOptions(), conn.GetNetConfig(), conn.GetProxy(), reinterpret_cast<sockaddr*>(&addr), sockaddr_size);
    data->OnProxySuccess(std::move(data->m_bev), std::move(ret));
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x658, %rsp            # imm = 0x658
movq %rsi, %rbx
movq %rdi, %r12
movq 0x8(%rsi), %r14
callq 0x4270
movq %rax, %r15
movq %rax, %rdi
callq 0x43b0
cmpq $0x7, %rax
jbe 0xe58e
movq %rax, %r13
leaq 0x40(%rsp), %rsi
movb $0x0, 0x4(%rsi)
andl $0x0, (%rsi)
pushq $0x5
popq %rdx
movq %r15, %rdi
callq 0x4060
cmpl $0x5, %eax
jne 0xe5ad
cmpb $0x5, 0x40(%rsp)
jne 0xe32c
cmpb $0x0, 0x41(%rsp)
jne 0xe32c
xorps %xmm0, %xmm0
movaps %xmm0, 0xf0(%rsp)
movaps %xmm0, 0xe0(%rsp)
movaps %xmm0, 0xd0(%rsp)
movaps %xmm0, 0xc0(%rsp)
movaps %xmm0, 0xb0(%rsp)
movaps %xmm0, 0xa0(%rsp)
movaps %xmm0, 0x90(%rsp)
movaps %xmm0, 0x80(%rsp)
movzbl 0x43(%rsp), %eax
cmpl $0x1, %eax
je 0xe389
cmpl $0x3, %eax
je 0xe33b
cmpl $0x4, %eax
jne 0xe32c
leaq 0x88(%rsp), %rax
movq %rax, 0x48(%rsp)
pushq $0x1c
popq %rax
movl %eax, 0x3c(%rsp)
pushq $0x10
popq %rbp
movw $0xa, %ax
jmp 0xe3a4
movq %rbx, %rdi
xorl %esi, %esi
callq 0xdd70
jmp 0xe57c
movsbq 0x44(%rsp), %rdx
addq $0x7, %rdx
cmpq %rdx, %r13
jb 0xe3c9
movq %r15, %rdi
movq %rdx, %rsi
callq 0x43f0
movl $0x0, 0x3c(%rsp)
movl $0x0, %ebp
testl %eax, %eax
je 0xe429
leaq 0x258d(%rip), %rdi      # 0x108fe
leaq 0x3b87(%rip), %rsi      # 0x11eff
leaq 0x3c94(%rip), %rcx      # 0x12013
movl $0xc9, %edx
callq 0x4260
leaq 0x84(%rsp), %rax
movq %rax, 0x48(%rsp)
pushq $0x10
popq %rax
movl %eax, 0x3c(%rsp)
pushq $0x4
popq %rbp
movw $0x2, %ax
movw %ax, 0x80(%rsp)
movq %r14, %rdi
callq 0x5e62
rolw $0x8, %ax
movw %ax, 0x82(%rsp)
leaq 0x6(%rbp), %rdx
cmpq %rdx, %r13
jae 0xe3db
pushq $0x2
popq %rsi
movq %r12, %rdi
xorl %ecx, %ecx
callq 0x40c0
jmp 0xe57c
pushq $0x4
popq %rsi
movq %r15, %rdi
callq 0x43f0
testl %eax, %eax
jne 0xe5cc
movq %r15, %rdi
movq 0x48(%rsp), %rsi
movq %rbp, %rdx
callq 0x4440
cmpl %ebp, %eax
jne 0xe5eb
leaq 0x1f0(%rsp), %rsi
andw $0x0, (%rsi)
pushq $0x2
popq %rdx
movq %r15, %rdi
callq 0x4440
cmpl $0x2, %eax
jne 0xe60a
movb $0x1, %bpl
leaq 0x1f0(%rsp), %rdi
movq %r14, %rsi
callq 0x6bee
testb %bpl, %bpl
je 0xe537
movq %r14, %rdi
callq 0x5d02
testb %al, %al
je 0xe537
movq %r14, %rdi
callq 0x63e8
cmpl $0x2, 0x4(%rax)
jne 0xe537
movq %r14, %rdi
callq 0x63e8
movups (%rax), %xmm0
movups 0x10(%rax), %xmm1
movups 0x1c(%rax), %xmm2
movups %xmm2, 0x6c(%rsp)
movaps %xmm1, 0x60(%rsp)
movaps %xmm0, 0x50(%rsp)
movq %r14, %rdi
callq 0x63f0
leaq 0x108(%rsp), %rdi
movq %rax, %rsi
callq 0x4e9a
movq %r14, %rdi
callq 0x63e2
leaq 0x140(%rsp), %rdi
movq %rax, %rsi
callq 0x6cda
movups 0x6c(%rsp), %xmm0
movups %xmm0, 0x1c(%rsp)
movaps 0x50(%rsp), %xmm0
movaps 0x60(%rsp), %xmm1
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
leaq 0x4e0(%rsp), %rdi
leaq 0x108(%rsp), %rsi
leaq 0x140(%rsp), %rdx
leaq 0x80(%rsp), %rcx
movl 0x3c(%rsp), %r8d
callq 0x6236
leaq 0x1f0(%rsp), %rdi
leaq 0x4e0(%rsp), %r14
movq %r14, %rsi
callq 0xe72c
movq %r14, %rdi
callq 0x4d22
leaq 0x140(%rsp), %rdi
callq 0x4d44
leaq 0x118(%rsp), %rdi
callq 0x4fd0
leaq 0x10(%rbx), %r14
leaq 0x368(%rsp), %r15
leaq 0x1f0(%rsp), %rsi
movq %r15, %rdi
callq 0x9720
movq (%rbx), %rax
movq %rbx, %rdi
movq %r14, %rsi
movq %r15, %rdx
callq *0x18(%rax)
leaq 0x368(%rsp), %rdi
callq 0x4d22
leaq 0x1f0(%rsp), %rdi
callq 0x4d22
addq $0x658, %rsp            # imm = 0x658
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x3a75(%rip), %rdi      # 0x1200a
leaq 0x3963(%rip), %rsi      # 0x11eff
leaq 0x3a70(%rip), %rcx      # 0x12013
movl $0x8a, %edx
callq 0x4260
leaq 0x3a99(%rip), %rdi      # 0x1204d
leaq 0x3944(%rip), %rsi      # 0x11eff
leaq 0x3a51(%rip), %rcx      # 0x12013
movl $0x8d, %edx
callq 0x4260
leaq 0x232b(%rip), %rdi      # 0x108fe
leaq 0x3925(%rip), %rsi      # 0x11eff
leaq 0x3a32(%rip), %rcx      # 0x12013
movl $0xbd, %edx
callq 0x4260
leaq 0x3a75(%rip), %rdi      # 0x12067
leaq 0x3906(%rip), %rsi      # 0x11eff
leaq 0x3a13(%rip), %rcx      # 0x12013
movl $0xc0, %edx
callq 0x4260
leaq 0x3a6e(%rip), %rdi      # 0x1207f
leaq 0x38e7(%rip), %rsi      # 0x11eff
leaq 0x39f4(%rip), %rcx      # 0x12013
movl $0xc5, %edx
callq 0x4260
movq %rax, %rbx
leaq 0x140(%rsp), %rdi
callq 0x4d44
jmp 0xe63e
movq %rax, %rbx
leaq 0x118(%rsp), %rdi
callq 0x4fd0
jmp 0xe664
jmp 0xe64f
movq %rax, %rbx
jmp 0xe664
movq %rax, %rbx
leaq 0x368(%rsp), %rdi
callq 0x4d22
leaq 0x1f0(%rsp), %rdi
callq 0x4d22
movq %rbx, %rdi
callq 0x4660
nop