// File: tenup-coin[P]seeder/netbase.cpp
// Function: CNetAddr::GetReachabilityFrom(CNetAddr const*) const
int CNetAddr::GetReachabilityFrom(const CNetAddr *paddrPartner) const
{
    enum Reachability {
        REACH_UNREACHABLE,
        REACH_DEFAULT,
        REACH_TEREDO,
        REACH_IPV6_WEAK,
        REACH_IPV4,
        REACH_IPV6_STRONG,
        REACH_PRIVATE
    };

    if (!IsRoutable())
        return REACH_UNREACHABLE;

    int ourNet = GetExtNetwork(this);
    int theirNet = GetExtNetwork(paddrPartner);
    bool fTunnel = IsRFC3964() || IsRFC6052() || IsRFC6145();

    switch(theirNet) {
    case NET_IPV4:
        switch(ourNet) {
        default:       return REACH_DEFAULT;
        case NET_IPV4: return REACH_IPV4;
        }
    case NET_IPV6:
        switch(ourNet) {
        default:         return REACH_DEFAULT;
        case NET_TEREDO: return REACH_TEREDO;
        case NET_IPV4:   return REACH_IPV4;
        case NET_IPV6:   return fTunnel ? REACH_IPV6_WEAK : REACH_IPV6_STRONG; // only prefer giving our IPv6 address if it's not tunnelled
        }
    case NET_TOR:
        switch(ourNet) {
        default:         return REACH_DEFAULT;
        case NET_IPV4:   return REACH_IPV4; // Tor users can connect to IPv4 as well
        case NET_TOR:    return REACH_PRIVATE;
        }
    case NET_I2P:
        switch(ourNet) {
        default:         return REACH_DEFAULT;
        case NET_I2P:    return REACH_PRIVATE;
        }
    case NET_TEREDO:
        switch(ourNet) {
        default:          return REACH_DEFAULT;
        case NET_TEREDO:  return REACH_TEREDO;
        case NET_IPV6:    return REACH_IPV6_WEAK;
        case NET_IPV4:    return REACH_IPV4;
        }
    case NET_UNKNOWN:
    case NET_UNROUTABLE:
    default:
        switch(ourNet) {
        default:          return REACH_DEFAULT;
        case NET_TEREDO:  return REACH_TEREDO;
        case NET_IPV6:    return REACH_IPV6_WEAK;
        case NET_IPV4:    return REACH_IPV4;
        case NET_I2P:     return REACH_PRIVATE; // assume connections from unroutable addresses are
        case NET_TOR:     return REACH_PRIVATE; // either from Tor/I2P, or don't care about our address
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq -0x10(%rbp), %rdi
movq %rdi, -0x30(%rbp)
callq 0x13b40
testb $0x1, %al
jne 0x1439d
movl $0x0, -0x4(%rbp)
jmp 0x14596
movq -0x30(%rbp), %rdi
callq 0x145a0
movl %eax, -0x1c(%rbp)
movq -0x18(%rbp), %rdi
callq 0x145a0
movq -0x30(%rbp), %rdi
movl %eax, -0x20(%rbp)
callq 0x13820
movb %al, %cl
movb $0x1, %al
testb $0x1, %cl
movb %al, -0x31(%rbp)
jne 0x143eb
movq -0x30(%rbp), %rdi
callq 0x13870
movb %al, %cl
movb $0x1, %al
testb $0x1, %cl
movb %al, -0x31(%rbp)
jne 0x143eb
movq -0x30(%rbp), %rdi
callq 0x13980
movb %al, -0x31(%rbp)
movb -0x31(%rbp), %al
andb $0x1, %al
movb %al, -0x21(%rbp)
movl -0x20(%rbp), %eax
movq %rax, -0x40(%rbp)
subq $0x6, %rax
ja 0x1453e
movq -0x40(%rbp), %rax
leaq 0x1ee91(%rip), %rcx     # 0x332a0
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl -0x1c(%rbp), %eax
subl $0x1, %eax
je 0x1442e
jmp 0x14422
movl $0x1, -0x4(%rbp)
jmp 0x14596
movl $0x4, -0x4(%rbp)
jmp 0x14596
movl -0x1c(%rbp), %eax
movl %eax, -0x44(%rbp)
subl $0x1, %eax
je 0x14473
jmp 0x14447
movl -0x44(%rbp), %eax
subl $0x2, %eax
je 0x1447f
jmp 0x14451
movl -0x44(%rbp), %eax
subl $0x6, %eax
je 0x14467
jmp 0x1445b
movl $0x1, -0x4(%rbp)
jmp 0x14596
movl $0x2, -0x4(%rbp)
jmp 0x14596
movl $0x4, -0x4(%rbp)
jmp 0x14596
movb -0x21(%rbp), %dl
movl $0x5, %eax
movl $0x3, %ecx
testb $0x1, %dl
cmovnel %ecx, %eax
movl %eax, -0x4(%rbp)
jmp 0x14596
movl -0x1c(%rbp), %eax
movl %eax, -0x48(%rbp)
subl $0x1, %eax
je 0x144bd
jmp 0x144a7
movl -0x48(%rbp), %eax
subl $0x3, %eax
je 0x144c9
jmp 0x144b1
movl $0x1, -0x4(%rbp)
jmp 0x14596
movl $0x4, -0x4(%rbp)
jmp 0x14596
movl $0x6, -0x4(%rbp)
jmp 0x14596
movl -0x1c(%rbp), %eax
subl $0x4, %eax
je 0x144eb
jmp 0x144df
movl $0x1, -0x4(%rbp)
jmp 0x14596
movl $0x6, -0x4(%rbp)
jmp 0x14596
movl -0x1c(%rbp), %eax
movl %eax, -0x4c(%rbp)
subl $0x1, %eax
je 0x14533
jmp 0x14504
movl -0x4c(%rbp), %eax
subl $0x2, %eax
je 0x1452a
jmp 0x1450e
movl -0x4c(%rbp), %eax
subl $0x6, %eax
je 0x14521
jmp 0x14518
movl $0x1, -0x4(%rbp)
jmp 0x14596
movl $0x2, -0x4(%rbp)
jmp 0x14596
movl $0x3, -0x4(%rbp)
jmp 0x14596
movl $0x4, -0x4(%rbp)
jmp 0x14596
jmp 0x1453e
movl -0x1c(%rbp), %eax
decl %eax
movl %eax, %ecx
movq %rcx, -0x58(%rbp)
subl $0x5, %eax
ja 0x14562
movq -0x58(%rbp), %rax
leaq 0x1ed63(%rip), %rcx     # 0x332bc
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl $0x1, -0x4(%rbp)
jmp 0x14596
movl $0x2, -0x4(%rbp)
jmp 0x14596
movl $0x3, -0x4(%rbp)
jmp 0x14596
movl $0x4, -0x4(%rbp)
jmp 0x14596
movl $0x6, -0x4(%rbp)
jmp 0x14596
movl $0x6, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x60, %rsp
popq %rbp
retq
nop