MCPcopy Create free account
hub / github.com/bitcoin/bitcoin / GetLocalAddresses

Function GetLocalAddresses

src/common/netif.cpp:320–383  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

318}
319
320std::vector<CNetAddr> GetLocalAddresses()
321{
322 std::vector<CNetAddr> addresses;
323#ifdef WIN32
324 DWORD status = 0;
325 constexpr size_t MAX_ADAPTER_ADDR_SIZE = 4 * 1000 * 1000; // Absolute maximum size of adapter addresses structure we're willing to handle, as a precaution.
326 std::vector<std::byte> out_buf(15000, {}); // Start with 15KB allocation as recommended in GetAdaptersAddresses documentation.
327 while (true) {
328 ULONG out_buf_len = out_buf.size();
329 status = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME,
330 nullptr, reinterpret_cast<PIP_ADAPTER_ADDRESSES>(out_buf.data()), &out_buf_len);
331 if (status == ERROR_BUFFER_OVERFLOW && out_buf.size() < MAX_ADAPTER_ADDR_SIZE) {
332 // If status == ERROR_BUFFER_OVERFLOW, out_buf_len will contain the needed size.
333 // Unfortunately, this cannot be fully relied on, because another process may have added interfaces.
334 // So to avoid getting stuck due to a race condition, double the buffer size at least
335 // once before retrying (but only up to the maximum allowed size).
336 out_buf.resize(std::min(std::max<size_t>(out_buf_len, out_buf.size()) * 2, MAX_ADAPTER_ADDR_SIZE));
337 } else {
338 break;
339 }
340 }
341
342 if (status != NO_ERROR) {
343 // This includes ERROR_NO_DATA if there are no addresses and thus there's not even one PIP_ADAPTER_ADDRESSES
344 // record in the returned structure.
345 LogError("Could not get local adapter addresses: %s\n", NetworkErrorString(status));
346 return addresses;
347 }
348
349 // Iterate over network adapters.
350 for (PIP_ADAPTER_ADDRESSES cur_adapter = reinterpret_cast<PIP_ADAPTER_ADDRESSES>(out_buf.data());
351 cur_adapter != nullptr; cur_adapter = cur_adapter->Next) {
352 if (cur_adapter->OperStatus != IfOperStatusUp) continue;
353 if (cur_adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK) continue;
354
355 // Iterate over unicast addresses for adapter, the only address type we're interested in.
356 for (PIP_ADAPTER_UNICAST_ADDRESS cur_address = cur_adapter->FirstUnicastAddress;
357 cur_address != nullptr; cur_address = cur_address->Next) {
358 // "The IP address is a cluster address and should not be used by most applications."
359 if ((cur_address->Flags & IP_ADAPTER_ADDRESS_TRANSIENT) != 0) continue;
360
361 if (std::optional<CNetAddr> addr = FromSockAddr(cur_address->Address.lpSockaddr, static_cast<socklen_t>(cur_address->Address.iSockaddrLength))) {
362 addresses.push_back(*addr);
363 }
364 }
365 }
366#elif defined(HAVE_IFADDRS)
367 struct ifaddrs* myaddrs;
368 if (getifaddrs(&myaddrs) == 0) {
369 for (struct ifaddrs* ifa = myaddrs; ifa != nullptr; ifa = ifa->ifa_next)
370 {
371 if (ifa->ifa_addr == nullptr) continue;
372 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
373 if ((ifa->ifa_flags & IFF_LOOPBACK) != 0) continue;
374
375 if (std::optional<CNetAddr> addr = FromSockAddr(ifa->ifa_addr, std::nullopt)) {
376 addresses.push_back(*addr);
377 }

Callers 2

ProcessPCPFunction · 0.85
DiscoverFunction · 0.85

Calls 6

NetworkErrorStringFunction · 0.85
FromSockAddrFunction · 0.85
sizeMethod · 0.45
dataMethod · 0.45
resizeMethod · 0.45
push_backMethod · 0.45

Tested by

no test coverage detected