Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(878)

Unified Diff: net/dns/address_sorter_win.cc

Issue 10442098: [net/dns] Resolve AF_UNSPEC on dual-stacked systems. Sort addresses according to RFC3484. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Working AddressSorterWin + measurements. Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/dns/address_sorter_win.cc
diff --git a/net/dns/address_sorter_win.cc b/net/dns/address_sorter_win.cc
new file mode 100644
index 0000000000000000000000000000000000000000..248788d4aa2463fb2c49f0a7e0c15d39cf70b54e
--- /dev/null
+++ b/net/dns/address_sorter_win.cc
@@ -0,0 +1,81 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/dns/address_sorter.h"
+
+#include <winsock2.h>
+
+#include "base/logging.h"
+#include "net/base/address_list.h"
+#include "net/base/ip_endpoint.h"
+
+namespace net {
+
+namespace {
+
+class AddressSorterWin : public AddressSorter {
+ public:
+ AddressSorterWin() {}
+
+ virtual ~AddressSorterWin() {}
+
+ virtual bool Sort(AddressList* list) const OVERRIDE {
+ // TODO(szym): Windows XP does not like V4MAPPED IPv6 addresses.
+ size_t heap_size = sizeof(SOCKET_ADDRESS_LIST) +
+ list->size() * (sizeof(SOCKET_ADDRESS) + sizeof(SOCKADDR_STORAGE));
+ scoped_ptr_malloc<SOCKET_ADDRESS_LIST> heap_in(
+ reinterpret_cast<SOCKET_ADDRESS_LIST*>(malloc(heap_size)));
+
+ SOCKET_ADDRESS_LIST* sort_list = heap_in.get();
+ sort_list->iAddressCount = list->size();
+ SOCKADDR_STORAGE* storage = reinterpret_cast<SOCKADDR_STORAGE*>(
+ sort_list->Address + sort_list->iAddressCount);
+
+ for (size_t i = 0; i < list->size(); ++i) {
+ IPEndPoint& ipe = (*list)[i];
+ // Addresses must be sockaddr_in6.
+ if (ipe.GetFamily() == AF_INET) {
+ ipe = IPEndPoint(ConvertIPv4NumberToIPv6Number(ipe.address()),
+ ipe.port());
+ }
+
+ struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(storage + i);
+ socklen_t addr_len = sizeof(SOCKADDR_STORAGE);
+ bool result = ipe.ToSockAddr(addr, &addr_len);
+ DCHECK(result);
+ sort_list->Address[i].lpSockaddr = addr;
+ sort_list->Address[i].iSockaddrLength = addr_len;
+ }
+
+ SOCKET sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
mmenke 2012/06/07 18:32:34 I believe we technically need to call closesocket
+ DCHECK_NE(INVALID_SOCKET, sock);
+ DWORD result_size = 0;
+ int result = WSAIoctl(sock, SIO_ADDRESS_LIST_SORT, sort_list, heap_size,
+ sort_list, heap_size, &result_size, NULL, NULL);
mmenke 2012/06/07 18:32:34 I do wonder about doing this on the IO thread. Su
+ if (result == SOCKET_ERROR) {
+ printf("FAILED %d\n", WSAGetLastError());
mmenke 2012/06/07 18:32:34 You could make a NetLog entry or something here, i
+ return false; // Unsorted.
+ }
+ list->clear();
+ for (int i = 0; i < sort_list->iAddressCount; ++i) {
+ IPEndPoint endpoint;
+ endpoint.FromSockAddr(sort_list->Address[i].lpSockaddr,
+ sort_list->Address[i].iSockaddrLength);
+ list->push_back(endpoint);
+ }
+ return true;
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(AddressSorterWin);
+};
+
+} // namespace
+
+// static
+scoped_ptr<AddressSorter> AddressSorter::CreateAddressSorter() {
+ return scoped_ptr<AddressSorter>(new AddressSorterWin());
+}
+
+} // namespace net
+

Powered by Google App Engine
This is Rietveld 408576698