Calculates a metric for how reachable (*this) is from a given partner */
| 834 | |
| 835 | /** Calculates a metric for how reachable (*this) is from a given partner */ |
| 836 | int32_t CNetAddr::GetReachabilityFrom(const CNetAddr* paddrPartner) const { |
| 837 | enum Reachability { |
| 838 | REACH_UNREACHABLE, |
| 839 | REACH_DEFAULT, |
| 840 | REACH_TEREDO, |
| 841 | REACH_IPV6_WEAK, |
| 842 | REACH_IPV4, |
| 843 | REACH_IPV6_STRONG, |
| 844 | REACH_PRIVATE |
| 845 | }; |
| 846 | |
| 847 | if (!IsRoutable()) |
| 848 | return REACH_UNREACHABLE; |
| 849 | |
| 850 | int32_t ourNet = GetExtNetwork(this); |
| 851 | int32_t theirNet = GetExtNetwork(paddrPartner); |
| 852 | bool fTunnel = IsRFC3964() || IsRFC6052() || IsRFC6145(); |
| 853 | |
| 854 | switch (theirNet) { |
| 855 | case NET_IPV4: |
| 856 | switch (ourNet) { |
| 857 | default: |
| 858 | return REACH_DEFAULT; |
| 859 | case NET_IPV4: |
| 860 | return REACH_IPV4; |
| 861 | } |
| 862 | case NET_IPV6: |
| 863 | switch (ourNet) { |
| 864 | default: |
| 865 | return REACH_DEFAULT; |
| 866 | case NET_TEREDO: |
| 867 | return REACH_TEREDO; |
| 868 | case NET_IPV4: |
| 869 | return REACH_IPV4; |
| 870 | case NET_IPV6: |
| 871 | return fTunnel ? REACH_IPV6_WEAK |
| 872 | : REACH_IPV6_STRONG; // only prefer giving our IPv6 address if it's not tunnelled |
| 873 | } |
| 874 | case NET_TOR: |
| 875 | switch (ourNet) { |
| 876 | default: |
| 877 | return REACH_DEFAULT; |
| 878 | case NET_IPV4: |
| 879 | return REACH_IPV4; // Tor users can connect to IPv4 as well |
| 880 | case NET_TOR: |
| 881 | return REACH_PRIVATE; |
| 882 | } |
| 883 | case NET_TEREDO: |
| 884 | switch (ourNet) { |
| 885 | default: |
| 886 | return REACH_DEFAULT; |
| 887 | case NET_TEREDO: |
| 888 | return REACH_TEREDO; |
| 889 | case NET_IPV6: |
| 890 | return REACH_IPV6_WEAK; |
| 891 | case NET_IPV4: |
| 892 | return REACH_IPV4; |
| 893 | } |
no test coverage detected