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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/dns/address_sorter.h"
6
7 #include <winsock2.h>
8
9 #include "base/logging.h"
10 #include "net/base/address_list.h"
11 #include "net/base/ip_endpoint.h"
12
13 namespace net {
14
15 namespace {
16
17 class AddressSorterWin : public AddressSorter {
18 public:
19 AddressSorterWin() {}
20
21 virtual ~AddressSorterWin() {}
22
23 virtual bool Sort(AddressList* list) const OVERRIDE {
24 // TODO(szym): Windows XP does not like V4MAPPED IPv6 addresses.
25 size_t heap_size = sizeof(SOCKET_ADDRESS_LIST) +
26 list->size() * (sizeof(SOCKET_ADDRESS) + sizeof(SOCKADDR_STORAGE));
27 scoped_ptr_malloc<SOCKET_ADDRESS_LIST> heap_in(
28 reinterpret_cast<SOCKET_ADDRESS_LIST*>(malloc(heap_size)));
29
30 SOCKET_ADDRESS_LIST* sort_list = heap_in.get();
31 sort_list->iAddressCount = list->size();
32 SOCKADDR_STORAGE* storage = reinterpret_cast<SOCKADDR_STORAGE*>(
33 sort_list->Address + sort_list->iAddressCount);
34
35 for (size_t i = 0; i < list->size(); ++i) {
36 IPEndPoint& ipe = (*list)[i];
37 // Addresses must be sockaddr_in6.
38 if (ipe.GetFamily() == AF_INET) {
39 ipe = IPEndPoint(ConvertIPv4NumberToIPv6Number(ipe.address()),
40 ipe.port());
41 }
42
43 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(storage + i);
44 socklen_t addr_len = sizeof(SOCKADDR_STORAGE);
45 bool result = ipe.ToSockAddr(addr, &addr_len);
46 DCHECK(result);
47 sort_list->Address[i].lpSockaddr = addr;
48 sort_list->Address[i].iSockaddrLength = addr_len;
49 }
50
51 SOCKET sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
mmenke 2012/06/07 18:32:34 I believe we technically need to call closesocket
52 DCHECK_NE(INVALID_SOCKET, sock);
53 DWORD result_size = 0;
54 int result = WSAIoctl(sock, SIO_ADDRESS_LIST_SORT, sort_list, heap_size,
55 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
56 if (result == SOCKET_ERROR) {
57 printf("FAILED %d\n", WSAGetLastError());
mmenke 2012/06/07 18:32:34 You could make a NetLog entry or something here, i
58 return false; // Unsorted.
59 }
60 list->clear();
61 for (int i = 0; i < sort_list->iAddressCount; ++i) {
62 IPEndPoint endpoint;
63 endpoint.FromSockAddr(sort_list->Address[i].lpSockaddr,
64 sort_list->Address[i].iSockaddrLength);
65 list->push_back(endpoint);
66 }
67 return true;
68 }
69
70 DISALLOW_COPY_AND_ASSIGN(AddressSorterWin);
71 };
72
73 } // namespace
74
75 // static
76 scoped_ptr<AddressSorter> AddressSorter::CreateAddressSorter() {
77 return scoped_ptr<AddressSorter>(new AddressSorterWin());
78 }
79
80 } // namespace net
81
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698