| 244 | } |
| 245 | |
| 246 | std::optional<CService> GetLocalAddrForPeer(CNode &node) { |
| 247 | CService addrLocal{GetLocalAddress(node.addr)}; |
| 248 | if (gArgs.GetBoolArg("-addrmantest", false)) { |
| 249 | // use IPv4 loopback during addrmantest |
| 250 | addrLocal = CService(LookupNumeric("127.0.0.1", GetListenPort())); |
| 251 | } |
| 252 | // If discovery is enabled, sometimes give our peer the address it |
| 253 | // tells us that it sees us as in case it has a better idea of our |
| 254 | // address than we do. |
| 255 | FastRandomContext rng; |
| 256 | if (IsPeerAddrLocalGood(&node) && |
| 257 | (!addrLocal.IsRoutable() || |
| 258 | rng.randbits((GetnScore(addrLocal) > LOCAL_MANUAL) ? 3 : 1) == 0)) { |
| 259 | if (node.IsInboundConn()) { |
| 260 | // For inbound connections, assume both the address and the port |
| 261 | // as seen from the peer. |
| 262 | addrLocal = CService{node.GetAddrLocal()}; |
| 263 | } else { |
| 264 | // For outbound connections, assume just the address as seen from |
| 265 | // the peer and leave the port in `addrLocal` as returned by |
| 266 | // `GetLocalAddress()` above. The peer has no way to observe our |
| 267 | // listening port when we have initiated the connection. |
| 268 | addrLocal.SetIP(node.GetAddrLocal()); |
| 269 | } |
| 270 | } |
| 271 | if (addrLocal.IsRoutable() || gArgs.GetBoolArg("-addrmantest", false)) { |
| 272 | LogPrint(BCLog::NET, "Advertising address %s to peer=%d\n", |
| 273 | addrLocal.ToStringAddrPort(), node.GetId()); |
| 274 | return addrLocal; |
| 275 | } |
| 276 | // Address is unroutable. Don't advertise. |
| 277 | return std::nullopt; |
| 278 | } |
| 279 | |
| 280 | // Learn a new local address. |
| 281 | bool AddLocal(const CService &addr, int nScore) { |