Chromium Code Reviews| Index: net/base/network_interfaces_win.cc |
| diff --git a/net/base/network_interfaces_win.cc b/net/base/network_interfaces_win.cc |
| index e2f53caab9f060cd55fb56190a4fad1b8ccdfa76..0554dcc61eb7a2c4335754b92e03057615651fc3 100644 |
| --- a/net/base/network_interfaces_win.cc |
| +++ b/net/base/network_interfaces_win.cc |
| @@ -24,6 +24,11 @@ namespace net { |
| namespace { |
| +// Max number of times to retry GetAdaptersAddresses due to |
| +// ERROR_BUFFER_OVERFLOW. If GetAdaptersAddresses returns this indefinitely |
| +// due to some Windows bug, we don't want to be stuck in an endless loop. |
| +const int MAX_GETADAPTERSADDRESSES_TRIES = 100; |
|
pauljensen
2016/06/20 11:32:49
100 seems like a lot. I imagine 10 should be plen
pauljensen
2016/06/20 11:32:49
how about moving this constant into the function?
Taylor_Brandstetter
2016/06/21 17:06:04
Done.
Taylor_Brandstetter
2016/06/21 17:06:05
Done. I thought to make it a large number so that
|
| + |
| // Converts Windows defined types to NetworkInterfaceType. |
| NetworkChangeNotifier::ConnectionType GetNetworkInterfaceType(DWORD ifType) { |
| NetworkChangeNotifier::ConnectionType type = |
| @@ -197,20 +202,28 @@ bool GetNetworkListImpl(NetworkInterfaceList* networks, |
| } // namespace internal |
| bool GetNetworkList(NetworkInterfaceList* networks, int policy) { |
| - ULONG len = 0; |
| + // Use an initial buffer size of 15KB, as recommended by MSDN. |
|
pauljensen
2016/06/20 11:32:49
can you provide a link to this recommendation?
Taylor_Brandstetter
2016/06/21 17:06:04
Done.
|
| + ULONG len = 15360; |
|
pauljensen
2016/06/21 20:32:05
Actually I think Windows may want you to use 15000
Taylor_Brandstetter
2016/06/21 20:45:18
Done, good catch.
|
| ULONG flags = 0; |
| // GetAdaptersAddresses() may require IO operations. |
| base::ThreadRestrictions::AssertIOAllowed(); |
| - ULONG result = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, NULL, &len); |
| - if (result != ERROR_BUFFER_OVERFLOW) { |
| + // Call GetAdaptersAddresses in a loop, because the required size may |
| + // increase between successive calls, resulting in ERROR_BUFFER_OVERFLOW |
| + // multiple times. |
| + std::unique_ptr<char[]> buf; |
|
pauljensen
2016/06/20 11:32:49
can we type this as IP_ADAPTER_ADDRESSES*?
Taylor_Brandstetter
2016/06/21 17:06:05
I think that may be confusing, because the buffer'
pauljensen
2016/06/21 17:20:10
I assume IP_ADAPTER_ADDRESSES is POD so it's silly
Taylor_Brandstetter
2016/06/21 19:50:51
Well... It depends on your definition of POD. It c
pauljensen
2016/06/21 20:32:04
I think the POD definition is pretty clear; isn't
|
| + IP_ADAPTER_ADDRESSES* adapters; |
| + ULONG result; |
| + int tries = 0; |
| + do { |
| + buf.reset(new char[len]); |
|
pauljensen
2016/06/20 11:32:49
it would be nice if the first 15k buffer could be
Taylor_Brandstetter
2016/06/21 17:06:04
Done.
|
| + adapters = reinterpret_cast<IP_ADAPTER_ADDRESSES*>(buf.get()); |
| + result = GetAdaptersAddresses(AF_UNSPEC, flags, nullptr, adapters, &len); |
| + } while (result == ERROR_BUFFER_OVERFLOW && |
| + ++tries < MAX_GETADAPTERSADDRESSES_TRIES); |
| + if (result == ERROR_NO_DATA) { |
| // There are 0 networks. |
| return true; |
| - } |
| - std::unique_ptr<char[]> buf(new char[len]); |
| - IP_ADAPTER_ADDRESSES* adapters = |
| - reinterpret_cast<IP_ADAPTER_ADDRESSES*>(buf.get()); |
| - result = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapters, &len); |
| - if (result != NO_ERROR) { |
| + } else if (result != NO_ERROR) { |
| LOG(ERROR) << "GetAdaptersAddresses failed: " << result; |
| return false; |
| } |