1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/address_list.h" 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <stdlib.h> 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/logging.h" 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_util.h" 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/sys_addrinfo.h" 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace net { 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace { 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochchar* do_strdup(const char* src) { 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN) 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return _strdup(src); 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return strdup(src); 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Assign the port for all addresses in the list. 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid SetPortRecursive(struct addrinfo* info, int port) { 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint16* port_field = GetPortFieldFromAddrinfo(info); 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (port_field) 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *port_field = htons(port); 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Assign recursively. 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (info->ai_next) 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SetPortRecursive(info->ai_next, port); 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstruct AddressList::Data : public base::RefCountedThreadSafe<Data> { 393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Data(struct addrinfo* ai, bool is_system_created); 403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick struct addrinfo* head; 413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Indicates which free function to use for |head|. 433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bool is_system_created; 443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick private: 463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick friend class base::RefCountedThreadSafe<Data>; 473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ~Data(); 493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}; 503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 513345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickAddressList::AddressList() { 523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 543345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickAddressList::AddressList(const IPAddressNumber& address, int port, 553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bool canonicalize_name) { 563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick struct addrinfo* ai = new addrinfo; 573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick memset(ai, 0, sizeof(addrinfo)); 583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ai->ai_socktype = SOCK_STREAM; 593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick switch (address.size()) { 613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case 4: { 623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ai->ai_family = AF_INET; 633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const size_t sockaddr_in_size = sizeof(struct sockaddr_in); 643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ai->ai_addrlen = sockaddr_in_size; 653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick struct sockaddr_in* addr = reinterpret_cast<struct sockaddr_in*>( 673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new char[sockaddr_in_size]); 683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick memset(addr, 0, sockaddr_in_size); 693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick addr->sin_family = AF_INET; 703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick memcpy(&addr->sin_addr, &address[0], 4); 713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ai->ai_addr = reinterpret_cast<struct sockaddr*>(addr); 723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case 16: { 753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ai->ai_family = AF_INET6; 763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const size_t sockaddr_in6_size = sizeof(struct sockaddr_in6); 773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ai->ai_addrlen = sockaddr_in6_size; 783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick struct sockaddr_in6* addr6 = reinterpret_cast<struct sockaddr_in6*>( 803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new char[sockaddr_in6_size]); 813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick memset(addr6, 0, sockaddr_in6_size); 823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick addr6->sin6_family = AF_INET6; 833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick memcpy(&addr6->sin6_addr, &address[0], 16); 843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ai->ai_addr = reinterpret_cast<struct sockaddr*>(addr6); 853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick default: { 883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NOTREACHED() << "Bad IP address"; 893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (canonicalize_name) { 943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string name = NetAddressToString(ai); 953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ai->ai_canonname = do_strdup(name.c_str()); 963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick data_ = new Data(ai, false /*is_system_created*/); 983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SetPort(port); 993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 10172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenAddressList::AddressList(const AddressList& addresslist) 10272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen : data_(addresslist.data_) { 10372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 10472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 10572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenAddressList::~AddressList() { 10672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 10772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 10872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenAddressList& AddressList::operator=(const AddressList& addresslist) { 10972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen data_ = addresslist.data_; 11072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return *this; 11172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 11272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid AddressList::Adopt(struct addrinfo* head) { 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data_ = new Data(head, true /*is_system_created*/); 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AddressList::Copy(const struct addrinfo* head, bool recursive) { 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_ = new Data(CreateCopyOfAddrinfo(head, recursive), 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch false /*is_system_created*/); 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AddressList::Append(const struct addrinfo* head) { 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(head); 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct addrinfo* new_head; 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (data_->is_system_created) { 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_head = CreateCopyOfAddrinfo(data_->head, true); 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_ = new Data(new_head, false /*is_system_created*/); 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_head = data_->head; 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Find the end of current linked list and append new data there. 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct addrinfo* copy_ptr = new_head; 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (copy_ptr->ai_next) 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch copy_ptr = copy_ptr->ai_next; 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch copy_ptr->ai_next = CreateCopyOfAddrinfo(head, true); 136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Only the head of the list should have a canonname. Strip any 138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // canonical name in the appended data. 139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen copy_ptr = copy_ptr->ai_next; 140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen while (copy_ptr) { 141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (copy_ptr->ai_canonname) { 142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen free(copy_ptr->ai_canonname); 143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen copy_ptr->ai_canonname = NULL; 144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 145ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen copy_ptr = copy_ptr->ai_next; 146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid AddressList::SetPort(int port) { 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SetPortRecursive(data_->head, port); 151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint AddressList::GetPort() const { 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return GetPortFromAddrinfo(data_->head); 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid AddressList::SetFrom(const AddressList& src, int port) { 158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (src.GetPort() == port) { 159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We can reference the data from |src| directly. 160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *this = src; 161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Otherwise we need to make a copy in order to change the port number. 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Copy(src.head(), true); 164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SetPort(port); 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 16872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool AddressList::GetCanonicalName(std::string* canonical_name) const { 16972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(canonical_name); 17072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!data_ || !data_->head->ai_canonname) 17172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 17272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen canonical_name->assign(data_->head->ai_canonname); 17372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return true; 17472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 17572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid AddressList::Reset() { 177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data_ = NULL; 178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst struct addrinfo* AddressList::head() const { 181dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!data_) 182dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return NULL; 1833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return data_->head; 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1863345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickAddressList::AddressList(Data* data) : data_(data) {} 187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 188dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// static 189dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenAddressList* AddressList::CreateAddressListFromSockaddr( 190dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const struct sockaddr* address, 191dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen socklen_t address_length, 192dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen int socket_type, 193dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen int protocol) { 194dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Do sanity checking on socket_type and protocol. 195dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(socket_type == SOCK_DGRAM || socket_type == SOCK_STREAM); 196dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(protocol == IPPROTO_TCP || protocol == IPPROTO_UDP); 197dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 198dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen struct addrinfo* ai = new addrinfo; 199dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen memset(ai, 0, sizeof(addrinfo)); 200dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen switch (address_length) { 201dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen case sizeof(struct sockaddr_in): 202dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen { 203dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const struct sockaddr_in* sin = 204dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen reinterpret_cast<const struct sockaddr_in*>(address); 205dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ai->ai_family = sin->sin_family; 206dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK_EQ(AF_INET, ai->ai_family); 207dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 208dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen break; 209dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen case sizeof(struct sockaddr_in6): 210dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen { 211dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const struct sockaddr_in6* sin6 = 212dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen reinterpret_cast<const struct sockaddr_in6*>(address); 213dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ai->ai_family = sin6->sin6_family; 214dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK_EQ(AF_INET6, ai->ai_family); 215dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 216dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen break; 217dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen default: 218dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NOTREACHED() << "Bad IP address"; 219dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen break; 220dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 221dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ai->ai_socktype = socket_type; 222dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ai->ai_protocol = protocol; 223dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ai->ai_addrlen = address_length; 224dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ai->ai_addr = reinterpret_cast<struct sockaddr*>(new char[address_length]); 225dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen memcpy(ai->ai_addr, address, address_length); 226dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return new AddressList(new Data(ai, false /*is_system_created*/)); 227dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 228dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 229dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochAddressList::Data::Data(struct addrinfo* ai, bool is_system_created) 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : head(ai), is_system_created(is_system_created) { 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(head); 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottAddressList::Data::~Data() { 236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Call either freeaddrinfo(head), or FreeCopyOfAddrinfo(head), depending on 237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // who created the data. 238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (is_system_created) 239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott freeaddrinfo(head); 240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott else 241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen FreeCopyOfAddrinfo(head); 242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace net 245