| 891 | } |
| 892 | |
| 893 | void AddrManImpl::ResolveCollisions_() |
| 894 | { |
| 895 | AssertLockHeld(cs); |
| 896 | |
| 897 | for (std::set<nid_type>::iterator it = m_tried_collisions.begin(); it != m_tried_collisions.end();) { |
| 898 | nid_type id_new = *it; |
| 899 | |
| 900 | bool erase_collision = false; |
| 901 | |
| 902 | // If id_new not found in mapInfo remove it from m_tried_collisions |
| 903 | if (!mapInfo.contains(id_new)) { |
| 904 | erase_collision = true; |
| 905 | } else { |
| 906 | AddrInfo& info_new = mapInfo[id_new]; |
| 907 | |
| 908 | // Which tried bucket to move the entry to. |
| 909 | int tried_bucket = info_new.GetTriedBucket(nKey, m_netgroupman); |
| 910 | int tried_bucket_pos = info_new.GetBucketPosition(nKey, false, tried_bucket); |
| 911 | if (!info_new.IsValid()) { // id_new may no longer map to a valid address |
| 912 | erase_collision = true; |
| 913 | } else if (vvTried[tried_bucket][tried_bucket_pos] != -1) { // The position in the tried bucket is not empty |
| 914 | |
| 915 | // Get the to-be-evicted address that is being tested |
| 916 | nid_type id_old = vvTried[tried_bucket][tried_bucket_pos]; |
| 917 | AddrInfo& info_old = mapInfo[id_old]; |
| 918 | |
| 919 | const auto current_time{Now<NodeSeconds>()}; |
| 920 | |
| 921 | // Has successfully connected in last X hours |
| 922 | if (current_time - info_old.m_last_success < ADDRMAN_REPLACEMENT) { |
| 923 | erase_collision = true; |
| 924 | } else if (current_time - info_old.m_last_try < ADDRMAN_REPLACEMENT) { // attempted to connect and failed in last X hours |
| 925 | |
| 926 | // Give address at least 60 seconds to successfully connect |
| 927 | if (current_time - info_old.m_last_try > 60s) { |
| 928 | LogDebug(BCLog::ADDRMAN, "Replacing %s with %s in tried table\n", info_old.ToStringAddrPort(), info_new.ToStringAddrPort()); |
| 929 | |
| 930 | // Replaces an existing address already in the tried table with the new address |
| 931 | Good_(info_new, false, current_time); |
| 932 | erase_collision = true; |
| 933 | } |
| 934 | } else if (current_time - info_new.m_last_success > ADDRMAN_TEST_WINDOW) { |
| 935 | // If the collision hasn't resolved in some reasonable amount of time, |
| 936 | // just evict the old entry -- we must not be able to |
| 937 | // connect to it for some reason. |
| 938 | LogDebug(BCLog::ADDRMAN, "Unable to test; replacing %s with %s in tried table anyway\n", info_old.ToStringAddrPort(), info_new.ToStringAddrPort()); |
| 939 | Good_(info_new, false, current_time); |
| 940 | erase_collision = true; |
| 941 | } |
| 942 | } else { // Collision is not actually a collision anymore |
| 943 | Good_(info_new, false, Now<NodeSeconds>()); |
| 944 | erase_collision = true; |
| 945 | } |
| 946 | } |
| 947 | |
| 948 | if (erase_collision) { |
| 949 | m_tried_collisions.erase(it++); |
| 950 | } else { |
nothing calls this directly
no test coverage detected