| 2965 | } |
| 2966 | |
| 2967 | std::vector<AddedNodeInfo> CConnman::GetAddedNodeInfo(bool include_connected) const |
| 2968 | { |
| 2969 | AssertLockNotHeld(m_nodes_mutex); |
| 2970 | |
| 2971 | std::vector<AddedNodeInfo> ret; |
| 2972 | |
| 2973 | std::list<AddedNodeParams> lAddresses(0); |
| 2974 | { |
| 2975 | LOCK(m_added_nodes_mutex); |
| 2976 | ret.reserve(m_added_node_params.size()); |
| 2977 | std::copy(m_added_node_params.cbegin(), m_added_node_params.cend(), std::back_inserter(lAddresses)); |
| 2978 | } |
| 2979 | |
| 2980 | |
| 2981 | // Build a map of all already connected addresses (by IP:port and by name) to inbound/outbound and resolved CService |
| 2982 | std::map<CService, bool> mapConnected; |
| 2983 | std::map<std::string, std::pair<bool, CService>> mapConnectedByName; |
| 2984 | { |
| 2985 | LOCK(m_nodes_mutex); |
| 2986 | for (const CNode* pnode : m_nodes) { |
| 2987 | if (pnode->addr.IsValid()) { |
| 2988 | mapConnected[pnode->addr] = pnode->IsInboundConn(); |
| 2989 | } |
| 2990 | std::string addrName{pnode->m_addr_name}; |
| 2991 | if (!addrName.empty()) { |
| 2992 | mapConnectedByName[std::move(addrName)] = std::make_pair(pnode->IsInboundConn(), static_cast<const CService&>(pnode->addr)); |
| 2993 | } |
| 2994 | } |
| 2995 | } |
| 2996 | |
| 2997 | for (const auto& addr : lAddresses) { |
| 2998 | CService service{MaybeFlipIPv6toCJDNS(LookupNumeric(addr.m_added_node, GetDefaultPort(addr.m_added_node)))}; |
| 2999 | AddedNodeInfo addedNode{addr, CService(), false, false}; |
| 3000 | if (service.IsValid()) { |
| 3001 | // strAddNode is an IP:port |
| 3002 | auto it = mapConnected.find(service); |
| 3003 | if (it != mapConnected.end()) { |
| 3004 | if (!include_connected) { |
| 3005 | continue; |
| 3006 | } |
| 3007 | addedNode.resolvedAddress = service; |
| 3008 | addedNode.fConnected = true; |
| 3009 | addedNode.fInbound = it->second; |
| 3010 | } |
| 3011 | } else { |
| 3012 | // strAddNode is a name |
| 3013 | auto it = mapConnectedByName.find(addr.m_added_node); |
| 3014 | if (it != mapConnectedByName.end()) { |
| 3015 | if (!include_connected) { |
| 3016 | continue; |
| 3017 | } |
| 3018 | addedNode.resolvedAddress = it->second.second; |
| 3019 | addedNode.fConnected = true; |
| 3020 | addedNode.fInbound = it->second.first; |
| 3021 | } |
| 3022 | } |
| 3023 | ret.emplace_back(std::move(addedNode)); |
| 3024 | } |