Chromium Code Reviews| Index: net/base/address_list.cc |
| diff --git a/net/base/address_list.cc b/net/base/address_list.cc |
| index 4aee12c0f156acab26d33db4de4122dc15e933d5..1aadb539ebb0a0f5a10a1a705b41b8eaa09e7c57 100644 |
| --- a/net/base/address_list.cc |
| +++ b/net/base/address_list.cc |
| @@ -4,283 +4,59 @@ |
| #include "net/base/address_list.h" |
| -#include <stdlib.h> |
| +#include <string> |
| #include "base/logging.h" |
| -#include "base/string_util.h" |
| #include "net/base/net_util.h" |
| #include "net/base/sys_addrinfo.h" |
| namespace net { |
| -namespace { |
| +AddressList::AddressList() {} |
| -struct addrinfo* CreateAddrInfo(const IPAddressNumber& address, |
| - bool canonicalize_name) { |
| - struct addrinfo* ai = new addrinfo; |
| - memset(ai, 0, sizeof(addrinfo)); |
| - ai->ai_socktype = SOCK_STREAM; |
| +AddressList::~AddressList() {} |
| - switch (address.size()) { |
| - case kIPv4AddressSize: { |
| - ai->ai_family = AF_INET; |
| - const size_t sockaddr_in_size = sizeof(struct sockaddr_in); |
| - ai->ai_addrlen = sockaddr_in_size; |
| - |
| - struct sockaddr_in* addr = reinterpret_cast<struct sockaddr_in*>( |
| - new char[sockaddr_in_size]); |
| - memset(addr, 0, sockaddr_in_size); |
| - addr->sin_family = AF_INET; |
| -#if defined(SIN6_LEN) |
| - addr->sin_len = sockaddr_in_size; |
| -#endif |
| - memcpy(&addr->sin_addr, &address[0], kIPv4AddressSize); |
|
eroman
2012/05/04 01:08:41
awzum how much code is getting deleted from this f
|
| - ai->ai_addr = reinterpret_cast<struct sockaddr*>(addr); |
| - break; |
| - } |
| - case kIPv6AddressSize: { |
| - ai->ai_family = AF_INET6; |
| - const size_t sockaddr_in6_size = sizeof(struct sockaddr_in6); |
| - ai->ai_addrlen = sockaddr_in6_size; |
| - |
| - struct sockaddr_in6* addr6 = reinterpret_cast<struct sockaddr_in6*>( |
| - new char[sockaddr_in6_size]); |
| - memset(addr6, 0, sockaddr_in6_size); |
| - addr6->sin6_family = AF_INET6; |
| -#if defined(SIN6_LEN) |
| - addr6->sin6_len = sockaddr_in6_size; |
| -#endif |
| - memcpy(&addr6->sin6_addr, &address[0], kIPv6AddressSize); |
| - ai->ai_addr = reinterpret_cast<struct sockaddr*>(addr6); |
| - break; |
| - } |
| - default: { |
| - NOTREACHED() << "Bad IP address"; |
| - break; |
| - } |
| - } |
| - |
| - if (canonicalize_name) { |
| - std::string name = NetAddressToString(ai); |
| - ai->ai_canonname = base::strdup(name.c_str()); |
| - } |
| - return ai; |
| -} |
| - |
| -} // namespace |
| - |
| -struct AddressList::Data : public base::RefCountedThreadSafe<Data> { |
| - Data(struct addrinfo* ai, bool is_system_created); |
| - |
| - // This variable is const since it should NOT be mutated. Since |
| - // Data is reference counted, this |head| could be shared by multiple |
| - // instances of AddressList, hence we need to be careful not to mutate |
| - // it from any one instance. |
| - const struct addrinfo * const head; |
| - |
| - // Indicates which free function to use for |head|. |
| - bool is_system_created; |
| - |
| - private: |
| - friend class base::RefCountedThreadSafe<Data>; |
| - |
| - ~Data(); |
| -}; |
| - |
| -AddressList::AddressList() { |
| -} |
| - |
| -AddressList::AddressList(const AddressList& addresslist) |
| - : data_(addresslist.data_) { |
| +AddressList::AddressList(const IPEndPoint& endpoint) { |
| + push_back(endpoint); |
| } |
| -AddressList::~AddressList() { |
| -} |
| - |
| -AddressList& AddressList::operator=(const AddressList& addresslist) { |
| - data_ = addresslist.data_; |
| - return *this; |
| +// static |
| +AddressList AddressList::CreateFromIPAddress(const IPAddressNumber& address, |
| + uint16 port) { |
| + return AddressList(IPEndPoint(address, port)); |
| } |
| // static |
| AddressList AddressList::CreateFromIPAddressList( |
| const IPAddressList& addresses, |
| const std::string& canonical_name) { |
| - DCHECK(!addresses.empty()); |
| - struct addrinfo* head = NULL; |
| - struct addrinfo* next = NULL; |
| - |
| - for (IPAddressList::const_iterator it = addresses.begin(); |
| - it != addresses.end(); ++it) { |
| - if (head == NULL) { |
| - head = next = CreateAddrInfo(*it, false); |
| - if (!canonical_name.empty()) { |
| - head->ai_canonname = base::strdup(canonical_name.c_str()); |
| - } |
| - } else { |
| - next->ai_next = CreateAddrInfo(*it, false); |
| - next = next->ai_next; |
| - } |
| + AddressList list; |
| + list.set_canonical_name(canonical_name); |
| + for (IPAddressList::const_iterator iter = addresses.begin(); |
| + iter != addresses.end(); ++iter) { |
| + list.push_back(IPEndPoint(*iter, 0)); |
| } |
| - |
| - return AddressList(new Data(head, false)); |
| -} |
| - |
| -// static |
| -AddressList AddressList::CreateFromIPAddress( |
| - const IPAddressNumber& address, |
| - uint16 port) { |
| - return CreateFromIPAddressWithCname(address, port, false); |
| + return list; |
| } |
| // static |
| -AddressList AddressList::CreateFromIPAddressWithCname( |
| - const IPAddressNumber& address, |
| - uint16 port, |
| - bool canonicalize_name) { |
| - struct addrinfo* ai = CreateAddrInfo(address, canonicalize_name); |
| - |
| - SetPortForAllAddrinfos(ai, port); |
| - return AddressList(new Data(ai, false /*is_system_created*/)); |
| -} |
| - |
| - |
| -// static |
| -AddressList AddressList::CreateByAdoptingFromSystem(struct addrinfo* head) { |
| - return AddressList(new Data(head, true /*is_system_created*/)); |
| -} |
| - |
| -// static |
| -AddressList AddressList::CreateByCopying(const struct addrinfo* head) { |
| - return AddressList(new Data(CreateCopyOfAddrinfo(head, true /*recursive*/), |
| - false /*is_system_created*/)); |
| -} |
| - |
| -// static |
| -AddressList AddressList::CreateByCopyingFirstAddress( |
| - const struct addrinfo* head) { |
| - return AddressList(new Data(CreateCopyOfAddrinfo(head, false /*recursive*/), |
| - false /*is_system_created*/)); |
| -} |
| - |
| -// static |
| -AddressList AddressList::CreateFromSockaddr( |
| - const struct sockaddr* address, |
| - socklen_t address_length, |
| - int socket_type, |
| - int protocol) { |
| - // Do sanity checking on socket_type and protocol. |
| - DCHECK(socket_type == SOCK_DGRAM || socket_type == SOCK_STREAM); |
| - DCHECK(protocol == IPPROTO_TCP || protocol == IPPROTO_UDP); |
| - |
| - struct addrinfo* ai = new addrinfo; |
| - memset(ai, 0, sizeof(addrinfo)); |
| - switch (address_length) { |
| - case sizeof(struct sockaddr_in): |
| - { |
| - const struct sockaddr_in* sin = |
| - reinterpret_cast<const struct sockaddr_in*>(address); |
| - ai->ai_family = sin->sin_family; |
| - DCHECK_EQ(AF_INET, ai->ai_family); |
| - } |
| - break; |
| - case sizeof(struct sockaddr_in6): |
| - { |
| - const struct sockaddr_in6* sin6 = |
| - reinterpret_cast<const struct sockaddr_in6*>(address); |
| - ai->ai_family = sin6->sin6_family; |
| - DCHECK_EQ(AF_INET6, ai->ai_family); |
| - } |
| - break; |
| - default: |
| - NOTREACHED() << "Bad IP address"; |
| - break; |
| - } |
| - ai->ai_socktype = socket_type; |
| - ai->ai_protocol = protocol; |
| - ai->ai_addrlen = address_length; |
| - ai->ai_addr = reinterpret_cast<struct sockaddr*>(new char[address_length]); |
| - memcpy(ai->ai_addr, address, address_length); |
| - return AddressList(new Data(ai, false /*is_system_created*/)); |
| -} |
| - |
| -void AddressList::Append(const struct addrinfo* head) { |
| +AddressList AddressList::CreateFromAddrinfo(const struct addrinfo* head) { |
| DCHECK(head); |
| - // Always create a copy, since the Data might be shared across instances. |
| - struct addrinfo* new_head = CreateCopyOfAddrinfo(data_->head, true); |
| - data_ = new Data(new_head, false /*is_system_created*/); |
| - |
| - // Find the end of current linked list and append new data there. |
| - struct addrinfo* copy_ptr = new_head; |
| - while (copy_ptr->ai_next) |
| - copy_ptr = copy_ptr->ai_next; |
| - copy_ptr->ai_next = CreateCopyOfAddrinfo(head, true); |
| - |
| - // Only the head of the list should have a canonname. Strip any |
| - // canonical name in the appended data. |
| - copy_ptr = copy_ptr->ai_next; |
| - while (copy_ptr) { |
| - if (copy_ptr->ai_canonname) { |
| - free(copy_ptr->ai_canonname); |
| - copy_ptr->ai_canonname = NULL; |
| - } |
| - copy_ptr = copy_ptr->ai_next; |
| + AddressList list; |
| + if (head->ai_canonname) |
| + list.set_canonical_name(std::string(head->ai_canonname)); |
| + for (const struct addrinfo* ai = head; ai; ai = ai->ai_next) { |
| + IPEndPoint ipe; |
| + // NOTE: Ignoring non-INET* families. |
|
eroman
2012/05/04 01:08:41
Not likely an issue, but might be good to add a wa
|
| + if (ipe.FromSockAddr(ai->ai_addr, ai->ai_addrlen)) |
| + list.push_back(ipe); |
| } |
| + return list; |
| } |
| -void AddressList::SetPort(uint16 port) { |
| - // NOTE: we need to be careful not to mutate the reference-counted data, |
| - // since it might be shared by other AddressLists. |
| - struct addrinfo* head = CreateCopyOfAddrinfo(data_->head, true); |
| - SetPortForAllAddrinfos(head, port); |
| - data_ = new Data(head, false /*is_system_created*/); |
| -} |
| - |
| -uint16 AddressList::GetPort() const { |
| - return GetPortFromAddrinfo(data_->head); |
| -} |
| - |
| -bool AddressList::GetCanonicalName(std::string* canonical_name) const { |
| - DCHECK(canonical_name); |
| - if (!data_ || !data_->head->ai_canonname) |
| - return false; |
| - canonical_name->assign(data_->head->ai_canonname); |
| - return true; |
| -} |
| - |
| -const struct addrinfo* AddressList::head() const { |
| - if (!data_) |
| - return NULL; |
| - return data_->head; |
| -} |
| - |
| -AddressList::AddressList(Data* data) : data_(data) {} |
| - |
| -AddressList::Data::Data(struct addrinfo* ai, bool is_system_created) |
| - : head(ai), is_system_created(is_system_created) { |
| - DCHECK(head); |
| -} |
| - |
| -AddressList::Data::~Data() { |
| - // Casting away the const is safe, since upon destruction we know that |
| - // no one holds a reference to the data any more. |
| - struct addrinfo* mutable_head = const_cast<struct addrinfo*>(head); |
| - |
| - // Call either freeaddrinfo(head), or FreeMyAddrinfo(head), depending who |
| - // created the data. |
| - if (is_system_created) |
| - freeaddrinfo(mutable_head); |
| - else |
| - FreeCopyOfAddrinfo(mutable_head); |
| -} |
| - |
| -AddressList CreateAddressListUsingPort(const AddressList& src, int port) { |
| - if (src.GetPort() == port) |
| - return src; |
| - |
| - AddressList out = src; |
| - out.SetPort(port); |
| - return out; |
| +void AddressList::SetDefaultCanonicalName() { |
| + DCHECK(!empty()); |
| + set_canonical_name(front().ToStringWithoutPort()); |
| } |
| } // namespace net |