| 233 | } |
| 234 | |
| 235 | std::optional<CAddress> GetLocalAddrForPeer(CNode *pnode) |
| 236 | { |
| 237 | CAddress addrLocal = GetLocalAddress(&pnode->addr, pnode->GetLocalServices()); |
| 238 | if (gArgs.GetBoolArg("-addrmantest", false)) { |
| 239 | // use IPv4 loopback during addrmantest |
| 240 | addrLocal = CAddress(CService(LookupNumeric("127.0.0.1", GetListenPort())), pnode->GetLocalServices()); |
| 241 | } |
| 242 | // If discovery is enabled, sometimes give our peer the address it |
| 243 | // tells us that it sees us as in case it has a better idea of our |
| 244 | // address than we do. |
| 245 | FastRandomContext rng; |
| 246 | if (IsPeerAddrLocalGood(pnode) && (!addrLocal.IsRoutable() || |
| 247 | rng.randbits((GetnScore(addrLocal) > LOCAL_MANUAL) ? 3 : 1) == 0)) |
| 248 | { |
| 249 | if (pnode->IsInboundConn()) { |
| 250 | // For inbound connections, assume both the address and the port |
| 251 | // as seen from the peer. |
| 252 | addrLocal = CAddress{pnode->GetAddrLocal(), addrLocal.nServices, addrLocal.nTime}; |
| 253 | } else { |
| 254 | // For outbound connections, assume just the address as seen from |
| 255 | // the peer and leave the port in `addrLocal` as returned by |
| 256 | // `GetLocalAddress()` above. The peer has no way to observe our |
| 257 | // listening port when we have initiated the connection. |
| 258 | addrLocal.SetIP(pnode->GetAddrLocal()); |
| 259 | } |
| 260 | } |
| 261 | if (addrLocal.IsRoutable() || gArgs.GetBoolArg("-addrmantest", false)) |
| 262 | { |
| 263 | LogPrint(BCLog::NET, "Advertising address %s to peer=%d\n", addrLocal.ToString(), pnode->GetId()); |
| 264 | return addrLocal; |
| 265 | } |
| 266 | // Address is unroutable. Don't advertise. |
| 267 | return std::nullopt; |
| 268 | } |
| 269 | |
| 270 | /** |
| 271 | * If an IPv6 address belongs to the address range used by the CJDNS network and |