| 842 | } |
| 843 | |
| 844 | void AddrManImpl::ResolveCollisions_() |
| 845 | { |
| 846 | AssertLockHeld(cs); |
| 847 | |
| 848 | for (std::set<nid_type>::iterator it = m_tried_collisions.begin(); it != m_tried_collisions.end();) { |
| 849 | nid_type id_new = *it; |
| 850 | |
| 851 | bool erase_collision = false; |
| 852 | |
| 853 | // If id_new not found in mapInfo remove it from m_tried_collisions |
| 854 | if (mapInfo.count(id_new) != 1) { |
| 855 | erase_collision = true; |
| 856 | } else { |
| 857 | AddrInfo& info_new = mapInfo[id_new]; |
| 858 | |
| 859 | // Which tried bucket to move the entry to. |
| 860 | int tried_bucket = info_new.GetTriedBucket(nKey, m_asmap); |
| 861 | int tried_bucket_pos = info_new.GetBucketPosition(nKey, false, tried_bucket); |
| 862 | if (!info_new.IsValid()) { // id_new may no longer map to a valid address |
| 863 | erase_collision = true; |
| 864 | } else if (vvTried[tried_bucket][tried_bucket_pos] != -1) { // The position in the tried bucket is not empty |
| 865 | |
| 866 | // Get the to-be-evicted address that is being tested |
| 867 | nid_type id_old = vvTried[tried_bucket][tried_bucket_pos]; |
| 868 | AddrInfo& info_old = mapInfo[id_old]; |
| 869 | |
| 870 | // Has successfully connected in last X hours |
| 871 | if (GetAdjustedTime() - info_old.nLastSuccess < ADDRMAN_REPLACEMENT_HOURS*(60*60)) { |
| 872 | erase_collision = true; |
| 873 | } else if (GetAdjustedTime() - info_old.nLastTry < ADDRMAN_REPLACEMENT_HOURS*(60*60)) { // attempted to connect and failed in last X hours |
| 874 | |
| 875 | // Give address at least 60 seconds to successfully connect |
| 876 | if (GetAdjustedTime() - info_old.nLastTry > 60) { |
| 877 | LogPrint(BCLog::ADDRMAN, "Replacing %s with %s in tried table\n", info_old.ToString(), info_new.ToString()); |
| 878 | |
| 879 | // Replaces an existing address already in the tried table with the new address |
| 880 | Good_(info_new, false, GetAdjustedTime()); |
| 881 | erase_collision = true; |
| 882 | } |
| 883 | } else if (GetAdjustedTime() - info_new.nLastSuccess > ADDRMAN_TEST_WINDOW) { |
| 884 | // If the collision hasn't resolved in some reasonable amount of time, |
| 885 | // just evict the old entry -- we must not be able to |
| 886 | // connect to it for some reason. |
| 887 | LogPrint(BCLog::ADDRMAN, "Unable to test; replacing %s with %s in tried table anyway\n", info_old.ToString(), info_new.ToString()); |
| 888 | Good_(info_new, false, GetAdjustedTime()); |
| 889 | erase_collision = true; |
| 890 | } |
| 891 | } else { // Collision is not actually a collision anymore |
| 892 | Good_(info_new, false, GetAdjustedTime()); |
| 893 | erase_collision = true; |
| 894 | } |
| 895 | } |
| 896 | |
| 897 | if (erase_collision) { |
| 898 | m_tried_collisions.erase(it++); |
| 899 | } else { |
| 900 | it++; |
| 901 | } |
nothing calls this directly
no test coverage detected