diff options
Diffstat (limited to 'net/base')
-rw-r--r-- | net/base/address_list.cc | 58 | ||||
-rw-r--r-- | net/base/net_util.cc | 53 | ||||
-rw-r--r-- | net/base/net_util.h | 10 |
3 files changed, 67 insertions, 54 deletions
diff --git a/net/base/address_list.cc b/net/base/address_list.cc index 83df606..1804736 100644 --- a/net/base/address_list.cc +++ b/net/base/address_list.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -22,56 +22,6 @@ char* do_strdup(const char* src) { #endif } -// Make a copy of |info| (the dynamically-allocated parts are copied as well). -// If |recursive| is true, chained entries via ai_next are copied too. -// Copy returned by this function should be deleted using -// DeleteCopyOfAddrinfo(), and NOT freeaddrinfo(). -struct addrinfo* CreateCopyOfAddrinfo(const struct addrinfo* info, - bool recursive) { - DCHECK(info); - struct addrinfo* copy = new addrinfo; - - // Copy all the fields (some of these are pointers, we will fix that next). - memcpy(copy, info, sizeof(addrinfo)); - - // ai_canonname is a NULL-terminated string. - if (info->ai_canonname) { - copy->ai_canonname = do_strdup(info->ai_canonname); - } - - // ai_addr is a buffer of length ai_addrlen. - if (info->ai_addr) { - copy->ai_addr = reinterpret_cast<sockaddr *>(new char[info->ai_addrlen]); - memcpy(copy->ai_addr, info->ai_addr, info->ai_addrlen); - } - - // Recursive copy. - if (recursive && info->ai_next) - copy->ai_next = CreateCopyOfAddrinfo(info->ai_next, recursive); - else - copy->ai_next = NULL; - - return copy; -} - -// Free an addrinfo that was created by CreateCopyOfAddrinfo(). -void FreeMyAddrinfo(struct addrinfo* info) { - DCHECK(info); - if (info->ai_canonname) - free(info->ai_canonname); // Allocated by strdup. - - if (info->ai_addr) - delete [] reinterpret_cast<char*>(info->ai_addr); - - struct addrinfo* next = info->ai_next; - - delete info; - - // Recursive free. - if (next) - FreeMyAddrinfo(next); -} - // Assign the port for all addresses in the list. void SetPortRecursive(struct addrinfo* info, int port) { uint16* port_field = GetPortFieldFromAddrinfo(info); @@ -283,12 +233,12 @@ AddressList::Data::Data(struct addrinfo* ai, bool is_system_created) } AddressList::Data::~Data() { - // Call either freeaddrinfo(head), or FreeMyAddrinfo(head), depending who - // created the data. + // Call either freeaddrinfo(head), or FreeCopyOfAddrinfo(head), depending on + // who created the data. if (is_system_created) freeaddrinfo(head); else - FreeMyAddrinfo(head); + FreeCopyOfAddrinfo(head); } } // namespace net diff --git a/net/base/net_util.cc b/net/base/net_util.cc index 5c7aab4..e97cb7f 100644 --- a/net/base/net_util.cc +++ b/net/base/net_util.cc @@ -911,6 +911,14 @@ void AppendFormattedComponent(const std::string& spec, } } +char* do_strdup(const char* src) { +#if defined(OS_WIN) + return _strdup(src); +#else + return strdup(src); +#endif +} + } // namespace const FormatUrlType kFormatUrlOmitNothing = 0; @@ -2075,6 +2083,51 @@ bool IPNumberMatchesPrefix(const IPAddressNumber& ip_number, return true; } +struct addrinfo* CreateCopyOfAddrinfo(const struct addrinfo* info, + bool recursive) { + DCHECK(info); + struct addrinfo* copy = new addrinfo; + + // Copy all the fields (some of these are pointers, we will fix that next). + memcpy(copy, info, sizeof(addrinfo)); + + // ai_canonname is a NULL-terminated string. + if (info->ai_canonname) { + copy->ai_canonname = do_strdup(info->ai_canonname); + } + + // ai_addr is a buffer of length ai_addrlen. + if (info->ai_addr) { + copy->ai_addr = reinterpret_cast<sockaddr *>(new char[info->ai_addrlen]); + memcpy(copy->ai_addr, info->ai_addr, info->ai_addrlen); + } + + // Recursive copy. + if (recursive && info->ai_next) + copy->ai_next = CreateCopyOfAddrinfo(info->ai_next, recursive); + else + copy->ai_next = NULL; + + return copy; +} + +void FreeCopyOfAddrinfo(struct addrinfo* info) { + DCHECK(info); + if (info->ai_canonname) + free(info->ai_canonname); // Allocated by strdup. + + if (info->ai_addr) + delete [] reinterpret_cast<char*>(info->ai_addr); + + struct addrinfo* next = info->ai_next; + + delete info; + + // Recursive free. + if (next) + FreeCopyOfAddrinfo(next); +} + // Returns the port field of the sockaddr in |info|. uint16* GetPortFieldFromAddrinfo(struct addrinfo* info) { const struct addrinfo* const_info = info; diff --git a/net/base/net_util.h b/net/base/net_util.h index 3f36182..fa7733e 100644 --- a/net/base/net_util.h +++ b/net/base/net_util.h @@ -402,6 +402,16 @@ bool IPNumberMatchesPrefix(const IPAddressNumber& ip_number, const IPAddressNumber& ip_prefix, size_t prefix_length_in_bits); +// Makes a copy of |info|. The dynamically-allocated parts are copied as well. +// If |recursive| is true, chained entries via ai_next are copied too. +// The copy returned by this function should be freed using +// FreeCopyOfAddrinfo(), and NOT freeaddrinfo(). +struct addrinfo* CreateCopyOfAddrinfo(const struct addrinfo* info, + bool recursive); + +// Frees an addrinfo that was created by CreateCopyOfAddrinfo(). +void FreeCopyOfAddrinfo(struct addrinfo* info); + // Returns the port field of the sockaddr in |info|. const uint16* GetPortFieldFromAddrinfo(const struct addrinfo* info); uint16* GetPortFieldFromAddrinfo(struct addrinfo* info); |