summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-12 02:02:40 +0000
committereroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-12 02:02:40 +0000
commitfe89ea7e351d304ca379125329018f5b96a2aded (patch)
treef4a0a43fc9e626d3a8e015a363ebbab635154e4e
parent1870d5cfa5ca359b44a32322c225cca1b2818e91 (diff)
downloadchromium_src-fe89ea7e351d304ca379125329018f5b96a2aded.zip
chromium_src-fe89ea7e351d304ca379125329018f5b96a2aded.tar.gz
chromium_src-fe89ea7e351d304ca379125329018f5b96a2aded.tar.bz2
Miscelaneous cleanups to AddressList to make it harder to mis-use.
- Removed all destructive non-const member functions -- these were dangerous since if you called them without first making a copy of the AddressList, it could mutate earlier copies. - Made AddressList::Data::head const, so new code added to AddressList cannot inadvertently introduce such dangerous mutations (won't compile). - Moved the non-trivial constructors and assign methods into factory methods (for added readability) - Removed the bool parameter from Copy (for added readability). Review URL: http://codereview.chromium.org/6880302 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@85090 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--content/browser/renderer_host/p2p/socket_host_tcp.cc3
-rw-r--r--content/browser/renderer_host/p2p/socket_host_test_utils.h4
-rw-r--r--jingle/glue/pseudotcp_adapter.cc2
-rw-r--r--jingle/notifier/base/chrome_async_socket_unittest.cc4
-rw-r--r--net/base/address_list.cc107
-rw-r--r--net/base/address_list.h65
-rw-r--r--net/base/address_list_unittest.cc71
-rw-r--r--net/base/host_resolver_impl.cc42
-rw-r--r--net/base/host_resolver_proc.cc4
-rw-r--r--net/base/mock_host_resolver.cc4
-rw-r--r--net/base/net_util.cc12
-rw-r--r--net/base/net_util.h6
-rw-r--r--net/http/http_auth_handler_negotiate.cc4
-rw-r--r--net/proxy/proxy_resolver_js_bindings_unittest.cc18
-rw-r--r--net/socket/ssl_server_socket_unittest.cc2
-rw-r--r--net/socket/tcp_client_socket_libevent.cc4
-rw-r--r--net/socket/tcp_client_socket_win.cc2
-rw-r--r--net/socket/tcp_server_socket_libevent.cc2
-rw-r--r--net/socket/tcp_server_socket_unittest.cc17
-rw-r--r--net/socket/tcp_server_socket_win.cc2
-rw-r--r--net/socket/transport_client_socket_pool.cc2
-rw-r--r--net/socket/transport_client_socket_pool_unittest.cc18
-rw-r--r--net/socket_stream/socket_stream.cc2
-rw-r--r--net/websockets/websocket_job.cc2
-rw-r--r--net/websockets/websocket_job_unittest.cc2
-rw-r--r--remoting/jingle_glue/ssl_socket_adapter.cc4
26 files changed, 236 insertions, 169 deletions
diff --git a/content/browser/renderer_host/p2p/socket_host_tcp.cc b/content/browser/renderer_host/p2p/socket_host_tcp.cc
index 1e5d48b..8d824b3 100644
--- a/content/browser/renderer_host/p2p/socket_host_tcp.cc
+++ b/content/browser/renderer_host/p2p/socket_host_tcp.cc
@@ -56,7 +56,8 @@ bool P2PSocketHostTcp::Init(const net::IPEndPoint& local_address,
remote_address_ = remote_address;
state_ = STATE_CONNECTING;
socket_.reset(new net::TCPClientSocket(
- net::AddressList(remote_address.address(), remote_address.port(), false),
+ net::AddressList::CreateFromIPAddress(
+ remote_address.address(), remote_address.port()),
NULL, net::NetLog::Source()));
int result = socket_->Connect(&connect_callback_);
if (result != net::ERR_IO_PENDING) {
diff --git a/content/browser/renderer_host/p2p/socket_host_test_utils.h b/content/browser/renderer_host/p2p/socket_host_test_utils.h
index 2c8eb22..bc829fd 100644
--- a/content/browser/renderer_host/p2p/socket_host_test_utils.h
+++ b/content/browser/renderer_host/p2p/socket_host_test_utils.h
@@ -178,8 +178,8 @@ bool FakeSocket::IsConnectedAndIdle() const {
}
int FakeSocket::GetPeerAddress(net::AddressList* address) const {
- *address = net::AddressList(peer_address_.address(),
- peer_address_.port(), false);
+ *address = net::AddressList::CreateFromIPAddress(peer_address_.address(),
+ peer_address_.port());
return net::OK;
}
diff --git a/jingle/glue/pseudotcp_adapter.cc b/jingle/glue/pseudotcp_adapter.cc
index 61a50a9..6ea9fbd 100644
--- a/jingle/glue/pseudotcp_adapter.cc
+++ b/jingle/glue/pseudotcp_adapter.cc
@@ -152,7 +152,7 @@ int PseudoTcpAdapter::GetPeerAddress(net::AddressList* address) const {
// We actually don't know the peer address. Returning so the upper layers
// won't complain.
net::IPAddressNumber ip_address(4);
- *address = net::AddressList(ip_address, 0, false);
+ *address = net::AddressList::CreateFromIPAddress(ip_address, 0);
return net::OK;
}
diff --git a/jingle/notifier/base/chrome_async_socket_unittest.cc b/jingle/notifier/base/chrome_async_socket_unittest.cc
index f834d9d..53a2028 100644
--- a/jingle/notifier/base/chrome_async_socket_unittest.cc
+++ b/jingle/notifier/base/chrome_async_socket_unittest.cc
@@ -116,8 +116,8 @@ net::IPAddressNumber Uint32ToIPAddressNumber(uint32 ip) {
net::AddressList SocketAddressToAddressList(
const talk_base::SocketAddress& address) {
DCHECK_NE(address.ip(), 0U);
- return net::AddressList(Uint32ToIPAddressNumber(address.ip()),
- address.port(), false);
+ return net::AddressList::CreateFromIPAddress(
+ Uint32ToIPAddressNumber(address.ip()), address.port());
}
class MockXmppClientSocketFactory : public ResolvingClientSocketFactory {
diff --git a/net/base/address_list.cc b/net/base/address_list.cc
index 1804736..70b94b2 100644
--- a/net/base/address_list.cc
+++ b/net/base/address_list.cc
@@ -22,22 +22,16 @@ char* do_strdup(const char* src) {
#endif
}
-// Assign the port for all addresses in the list.
-void SetPortRecursive(struct addrinfo* info, int port) {
- uint16* port_field = GetPortFieldFromAddrinfo(info);
- if (port_field)
- *port_field = htons(port);
-
- // Assign recursively.
- if (info->ai_next)
- SetPortRecursive(info->ai_next, port);
-}
-
} // namespace
struct AddressList::Data : public base::RefCountedThreadSafe<Data> {
Data(struct addrinfo* ai, bool is_system_created);
- struct addrinfo* head;
+
+ // 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;
@@ -51,8 +45,18 @@ struct AddressList::Data : public base::RefCountedThreadSafe<Data> {
AddressList::AddressList() {
}
-AddressList::AddressList(const IPAddressNumber& address, int port,
- bool canonicalize_name) {
+// static
+AddressList AddressList::CreateFromIPAddress(
+ const IPAddressNumber& address,
+ uint16 port) {
+ return CreateFromIPAddressWithCname(address, port, false);
+}
+
+// static
+AddressList AddressList::CreateFromIPAddressWithCname(
+ const IPAddressNumber& address,
+ uint16 port,
+ bool canonicalize_name) {
struct addrinfo* ai = new addrinfo;
memset(ai, 0, sizeof(addrinfo));
ai->ai_socktype = SOCK_STREAM;
@@ -94,8 +98,8 @@ AddressList::AddressList(const IPAddressNumber& address, int port,
std::string name = NetAddressToString(ai);
ai->ai_canonname = do_strdup(name.c_str());
}
- data_ = new Data(ai, false /*is_system_created*/);
- SetPort(port);
+ SetPortForAllAddrinfos(ai, port);
+ return AddressList(new Data(ai, false /*is_system_created*/));
}
AddressList::AddressList(const AddressList& addresslist)
@@ -110,24 +114,30 @@ AddressList& AddressList::operator=(const AddressList& addresslist) {
return *this;
}
-void AddressList::Adopt(struct addrinfo* head) {
- data_ = new Data(head, true /*is_system_created*/);
+// static
+AddressList AddressList::CreateByAdoptingFromSystem(struct addrinfo* head) {
+ return AddressList(new Data(head, true /*is_system_created*/));
}
-void AddressList::Copy(const struct addrinfo* head, bool recursive) {
- data_ = new Data(CreateCopyOfAddrinfo(head, recursive),
- false /*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*/));
}
void AddressList::Append(const struct addrinfo* head) {
DCHECK(head);
- struct addrinfo* new_head;
- if (data_->is_system_created) {
- new_head = CreateCopyOfAddrinfo(data_->head, true);
- data_ = new Data(new_head, false /*is_system_created*/);
- } else {
- new_head = data_->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)
@@ -146,25 +156,18 @@ void AddressList::Append(const struct addrinfo* head) {
}
}
-void AddressList::SetPort(int port) {
- SetPortRecursive(data_->head, port);
+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*/);
}
-int AddressList::GetPort() const {
+uint16 AddressList::GetPort() const {
return GetPortFromAddrinfo(data_->head);
}
-void AddressList::SetFrom(const AddressList& src, int port) {
- if (src.GetPort() == port) {
- // We can reference the data from |src| directly.
- *this = src;
- } else {
- // Otherwise we need to make a copy in order to change the port number.
- Copy(src.head(), true);
- SetPort(port);
- }
-}
-
bool AddressList::GetCanonicalName(std::string* canonical_name) const {
DCHECK(canonical_name);
if (!data_ || !data_->head->ai_canonname)
@@ -173,10 +176,6 @@ bool AddressList::GetCanonicalName(std::string* canonical_name) const {
return true;
}
-void AddressList::Reset() {
- data_ = NULL;
-}
-
const struct addrinfo* AddressList::head() const {
if (!data_)
return NULL;
@@ -186,7 +185,7 @@ const struct addrinfo* AddressList::head() const {
AddressList::AddressList(Data* data) : data_(data) {}
// static
-AddressList* AddressList::CreateAddressListFromSockaddr(
+AddressList AddressList::CreateFromSockaddr(
const struct sockaddr* address,
socklen_t address_length,
int socket_type,
@@ -223,7 +222,7 @@ AddressList* AddressList::CreateAddressListFromSockaddr(
ai->ai_addrlen = address_length;
ai->ai_addr = reinterpret_cast<struct sockaddr*>(new char[address_length]);
memcpy(ai->ai_addr, address, address_length);
- return new AddressList(new Data(ai, false /*is_system_created*/));
+ return AddressList(new Data(ai, false /*is_system_created*/));
}
@@ -233,12 +232,16 @@ AddressList::Data::Data(struct addrinfo* ai, bool is_system_created)
}
AddressList::Data::~Data() {
- // Call either freeaddrinfo(head), or FreeCopyOfAddrinfo(head), depending on
- // who created the 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(head);
+ freeaddrinfo(mutable_head);
else
- FreeCopyOfAddrinfo(head);
+ FreeCopyOfAddrinfo(mutable_head);
}
} // namespace net
diff --git a/net/base/address_list.h b/net/base/address_list.h
index 0efd77f..1ac4e0e 100644
--- a/net/base/address_list.h
+++ b/net/base/address_list.h
@@ -11,6 +11,8 @@
#include "base/memory/ref_counted.h"
#include "net/base/net_util.h"
+// TODO(eroman): Fix the declaration + definition ordering to match style guide.
+
struct addrinfo;
namespace net {
@@ -19,46 +21,55 @@ namespace net {
// class is designed to be copied around by value.
class AddressList {
public:
- // Constructs an empty address list.
+ // Constructs an invalid address list. Should not call any methods on this
+ // other than assignment.
AddressList();
- // Constructs an address list for a single IP literal. If
+ // Creates an address list for a single IP literal.
+ static AddressList CreateFromIPAddress(
+ const IPAddressNumber& address,
+ uint16 port);
+
+ // Creates an address list for a single IP literal. If
// |canonicalize_name| is true, fill the ai_canonname field with the
// canonicalized IP address.
- AddressList(const IPAddressNumber& address, int port, bool canonicalize_name);
+ static AddressList CreateFromIPAddressWithCname(
+ const IPAddressNumber& address,
+ uint16 port,
+ bool canonicalize_name);
AddressList(const AddressList& addresslist);
~AddressList();
AddressList& operator=(const AddressList& addresslist);
- // Adopt the given addrinfo list (assumed to have been created by
+ // Adopts the given addrinfo list (assumed to have been created by
// the system, e.g. returned by getaddrinfo()) in place of the
// existing one if any. This hands over responsibility for freeing
// the addrinfo list to the AddressList object.
- void Adopt(struct addrinfo* head);
+ static AddressList CreateByAdoptingFromSystem(struct addrinfo* head);
+
+ // Creates a new address list with a copy of |head|. This includes the
+ // entire linked list.
+ static AddressList CreateByCopying(const struct addrinfo* head);
- // Copies the given addrinfo rather than adopting it. If |recursive| is true,
- // all linked struct addrinfos will be copied as well. Otherwise only the head
- // will be copied, and the rest of linked entries will be ignored.
- void Copy(const struct addrinfo* head, bool recursive);
+ // Creates a new address list wich has a single address, |head|. If there
+ // are other addresses in |head| they will be ignored.
+ static AddressList CreateByCopyingFirstAddress(const struct addrinfo* head);
// Appends a copy of |head| and all its linked addrinfos to the stored
- // addrinfo.
+ // addrinfo. Note that this will cause a reallocation of the linked list,
+ // which invalidates the head pointer.
void Append(const struct addrinfo* head);
// Sets the port of all addresses in the list to |port| (that is the
- // sin[6]_port field for the sockaddrs).
- void SetPort(int port);
+ // sin[6]_port field for the sockaddrs). Note that this will cause a
+ // reallocation of the linked list, which invalidates the head pointer.
+ void SetPort(uint16 port);
// Retrieves the port number of the first sockaddr in the list. (If SetPort()
// was previously used on this list, then all the addresses will have this
// same port number.)
- int GetPort() const;
-
- // Sets the address to match |src|, and have each sockaddr's port be |port|.
- // If |src| already has the desired port this operation is cheap (just adds
- // a reference to |src|'s data.) Otherwise we will make a copy.
- void SetFrom(const AddressList& src, int port);
+ uint16 GetPort() const;
// Gets the canonical name for the address.
// If the canonical name exists, |*canonical_name| is filled in with the
@@ -67,18 +78,22 @@ class AddressList {
// |canonical_name| must be a non-null value.
bool GetCanonicalName(std::string* canonical_name) const;
- // Clears all data from this address list. This leaves the list in the same
- // empty state as when first constructed.
- void Reset();
-
- // Get access to the head of the addrinfo list.
+ // Gets access to the head of the addrinfo list.
+ //
+ // IMPORTANT: Callers SHOULD NOT mutate the addrinfo chain, since under the
+ // hood this data might be shared by other AddressLists, which
+ // might even be running on other threads.
+ //
+ // Additionally, non-const methods like SetPort() and Append() can
+ // cause the head to be reallocated, so do not cache the return
+ // value of head() across such calls.
const struct addrinfo* head() const;
- // Constructs an address list for a single socket address.
+ // Creates an address list for a single socket address.
// |address| the sockaddr to copy.
// |socket_type| is either SOCK_STREAM or SOCK_DGRAM.
// |protocol| is either IPPROTO_TCP or IPPROTO_UDP.
- static AddressList* CreateAddressListFromSockaddr(
+ static AddressList CreateFromSockaddr(
const struct sockaddr* address,
socklen_t address_length,
int socket_type,
diff --git a/net/base/address_list_unittest.cc b/net/base/address_list_unittest.cc
index 03417e6..1409258 100644
--- a/net/base/address_list_unittest.cc
+++ b/net/base/address_list_unittest.cc
@@ -17,6 +17,12 @@
namespace net {
namespace {
+void MutableSetPort(uint16 port, AddressList* addrlist) {
+ struct addrinfo* mutable_head =
+ const_cast<struct addrinfo*>(addrlist->head());
+ SetPortForAllAddrinfos(mutable_head, port);
+}
+
// Use getaddrinfo() to allocate an addrinfo structure.
int CreateAddressList(const std::string& hostname, int port,
AddressList* addrlist) {
@@ -28,7 +34,7 @@ int CreateAddressList(const std::string& hostname, int port,
0,
addrlist, NULL);
if (rv == 0)
- addrlist->SetPort(port);
+ MutableSetPort(port, addrlist);
return rv;
}
@@ -44,10 +50,25 @@ TEST(AddressListTest, GetPort) {
EXPECT_EQ(0, CreateAddressList("192.168.1.1", 81, &addrlist));
EXPECT_EQ(81, addrlist.GetPort());
- addrlist.SetPort(83);
+ MutableSetPort(83, &addrlist);
EXPECT_EQ(83, addrlist.GetPort());
}
+TEST(AddressListTest, SetPortMakesCopy) {
+ AddressList addrlist1;
+ EXPECT_EQ(0, CreateAddressList("192.168.1.1", 85, &addrlist1));
+ EXPECT_EQ(85, addrlist1.GetPort());
+
+ AddressList addrlist2 = addrlist1;
+ EXPECT_EQ(85, addrlist2.GetPort());
+
+ // addrlist1 should not be affected by the assignment to
+ // addrlist2.
+ addrlist1.SetPort(80);
+ EXPECT_EQ(80, addrlist1.GetPort());
+ EXPECT_EQ(85, addrlist2.GetPort());
+}
+
TEST(AddressListTest, Assignment) {
AddressList addrlist1;
EXPECT_EQ(0, CreateAddressList("192.168.1.1", 85, &addrlist1));
@@ -58,7 +79,7 @@ TEST(AddressListTest, Assignment) {
AddressList addrlist2 = addrlist1;
EXPECT_EQ(85, addrlist2.GetPort());
- addrlist1.SetPort(80);
+ MutableSetPort(80, &addrlist1);
EXPECT_EQ(80, addrlist1.GetPort());
EXPECT_EQ(80, addrlist2.GetPort());
}
@@ -68,8 +89,8 @@ TEST(AddressListTest, CopyRecursive) {
CreateLongAddressList(&addrlist1, 85);
EXPECT_EQ(85, addrlist1.GetPort());
- AddressList addrlist2;
- addrlist2.Copy(addrlist1.head(), true);
+ AddressList addrlist2 =
+ AddressList::CreateByCopying(addrlist1.head());
ASSERT_TRUE(addrlist2.head()->ai_next != NULL);
@@ -78,8 +99,8 @@ TEST(AddressListTest, CopyRecursive) {
EXPECT_EQ(85, addrlist2.GetPort());
// Changes to addrlist1 are not reflected in addrlist2.
- addrlist1.SetPort(70);
- addrlist2.SetPort(90);
+ MutableSetPort(70, &addrlist1);
+ MutableSetPort(90, &addrlist2);
EXPECT_EQ(70, addrlist1.GetPort());
EXPECT_EQ(90, addrlist2.GetPort());
@@ -90,8 +111,8 @@ TEST(AddressListTest, CopyNonRecursive) {
CreateLongAddressList(&addrlist1, 85);
EXPECT_EQ(85, addrlist1.GetPort());
- AddressList addrlist2;
- addrlist2.Copy(addrlist1.head(), false);
+ AddressList addrlist2 =
+ AddressList::CreateByCopyingFirstAddress(addrlist1.head());
ASSERT_TRUE(addrlist2.head()->ai_next == NULL);
@@ -100,8 +121,8 @@ TEST(AddressListTest, CopyNonRecursive) {
EXPECT_EQ(85, addrlist2.GetPort());
// Changes to addrlist1 are not reflected in addrlist2.
- addrlist1.SetPort(70);
- addrlist2.SetPort(90);
+ MutableSetPort(70, &addrlist1);
+ MutableSetPort(90, &addrlist2);
EXPECT_EQ(70, addrlist1.GetPort());
EXPECT_EQ(90, addrlist2.GetPort());
@@ -119,8 +140,8 @@ TEST(AddressListTest, Append) {
addrlist1.Append(addrlist2.head());
ASSERT_TRUE(addrlist1.head()->ai_next != NULL);
- AddressList addrlist3;
- addrlist3.Copy(addrlist1.head()->ai_next, false);
+ AddressList addrlist3 =
+ AddressList::CreateByCopyingFirstAddress(addrlist1.head()->ai_next);
EXPECT_EQ(12, addrlist3.GetPort());
}
@@ -142,8 +163,7 @@ TEST(AddressListTest, Canonical) {
// Copy the addrinfo struct into an AddressList object and
// make sure it seems correct.
- AddressList addrlist1;
- addrlist1.Copy(&ai, true);
+ AddressList addrlist1 = AddressList::CreateByCopying(&ai);
const struct addrinfo* addrinfo1 = addrlist1.head();
EXPECT_TRUE(addrinfo1 != NULL);
EXPECT_TRUE(addrinfo1->ai_next == NULL);
@@ -152,8 +172,7 @@ TEST(AddressListTest, Canonical) {
EXPECT_EQ("canonical.bar.com", canon_name1);
// Copy the AddressList to another one.
- AddressList addrlist2;
- addrlist2.Copy(addrinfo1, true);
+ AddressList addrlist2 = AddressList::CreateByCopying(addrinfo1);
const struct addrinfo* addrinfo2 = addrlist2.head();
EXPECT_TRUE(addrinfo2 != NULL);
EXPECT_TRUE(addrinfo2->ai_next == NULL);
@@ -167,8 +186,7 @@ TEST(AddressListTest, Canonical) {
// Make sure that GetCanonicalName correctly returns false
// when ai_canonname is NULL.
ai.ai_canonname = NULL;
- AddressList addrlist_no_canon;
- addrlist_no_canon.Copy(&ai, true);
+ AddressList addrlist_no_canon = AddressList::CreateByCopying(&ai);
std::string canon_name3 = "blah";
EXPECT_FALSE(addrlist_no_canon.GetCanonicalName(&canon_name3));
EXPECT_EQ("blah", canon_name3);
@@ -199,7 +217,8 @@ TEST(AddressListTest, IPLiteralConstructor) {
IPAddressNumber ip_number;
ParseIPLiteralToNumber(tests[i].ip_address, &ip_number);
- AddressList test_list(ip_number, 80, true);
+ AddressList test_list = AddressList::CreateFromIPAddressWithCname(
+ ip_number, 80, true);
const struct addrinfo* test_ai = test_list.head();
EXPECT_EQ(good_ai->ai_family, test_ai->ai_family);
@@ -238,12 +257,12 @@ TEST(AddressListTest, AddressFromAddrInfo) {
ASSERT_EQ(0, rv);
const struct addrinfo* good_ai = expected_list.head();
- scoped_ptr<AddressList> test_list(
- AddressList::CreateAddressListFromSockaddr(good_ai->ai_addr,
- good_ai->ai_addrlen,
- SOCK_STREAM,
- IPPROTO_TCP));
- const struct addrinfo* test_ai = test_list->head();
+ AddressList test_list =
+ AddressList::CreateFromSockaddr(good_ai->ai_addr,
+ good_ai->ai_addrlen,
+ SOCK_STREAM,
+ IPPROTO_TCP);
+ const struct addrinfo* test_ai = test_list.head();
EXPECT_EQ(good_ai->ai_family, test_ai->ai_family);
EXPECT_EQ(good_ai->ai_addrlen, test_ai->ai_addrlen);
diff --git a/net/base/host_resolver_impl.cc b/net/base/host_resolver_impl.cc
index 008fd14..371692a 100644
--- a/net/base/host_resolver_impl.cc
+++ b/net/base/host_resolver_impl.cc
@@ -44,6 +44,30 @@ namespace net {
namespace {
+// Helper to create an AddressList that has a particular port. It has an
+// optimization to avoid allocating a new address linked list when the
+// port is already what we want.
+AddressList CreateAddressListUsingPort(const AddressList& src, int port) {
+ if (src.GetPort() == port)
+ return src;
+
+ AddressList out = src;
+ out.SetPort(port);
+ return out;
+}
+
+// Helper to mutate the linked list contained by AddressList to the given
+// port. Note that in general this is dangerous since the AddressList's
+// data might be shared (and you should use AddressList::SetPort).
+//
+// However since we allocated the AddressList ourselves we can safely
+// do this optimization and avoid reallocating the list.
+void MutableSetPort(int port, AddressList* addrlist) {
+ struct addrinfo* mutable_head =
+ const_cast<struct addrinfo*>(addrlist->head());
+ SetPortForAllAddrinfos(mutable_head, port);
+}
+
// We use a separate histogram name for each platform to facilitate the
// display of error codes by their symbolic name (since each platform has
// different mappings).
@@ -279,7 +303,7 @@ class HostResolverImpl::Request {
void OnComplete(int error, const AddressList& addrlist) {
if (error == OK)
- addresses_->SetFrom(addrlist, port());
+ *addresses_ = CreateAddressListUsingPort(addrlist, port());
CompletionCallback* callback = callback_;
MarkAsCancelled();
callback->Run(error);
@@ -590,7 +614,7 @@ class HostResolverImpl::Job
// Use the port number of the first request.
if (error == OK)
- results_.SetPort(requests_[0]->port());
+ MutableSetPort(requests_[0]->port(), &results_);
resolver_->OnJobComplete(this, error, os_error, results_);
}
@@ -1090,9 +1114,9 @@ int HostResolverImpl::Resolve(const RequestInfo& info,
if (ip_number.size() == 16 && ipv6_disabled) {
net_error = ERR_NAME_NOT_RESOLVED;
} else {
- AddressList result(ip_number, info.port(),
- (key.host_resolver_flags & HOST_RESOLVER_CANONNAME));
- *addresses = result;
+ *addresses = AddressList::CreateFromIPAddressWithCname(
+ ip_number, info.port(),
+ (key.host_resolver_flags & HOST_RESOLVER_CANONNAME));
}
// Update the net log and notify registered observers.
OnFinishRequest(source_net_log, request_net_log, request_id, info,
@@ -1107,8 +1131,10 @@ int HostResolverImpl::Resolve(const RequestInfo& info,
if (cache_entry) {
request_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CACHE_HIT, NULL);
int net_error = cache_entry->error;
- if (net_error == OK)
- addresses->SetFrom(cache_entry->addrlist, info.port());
+ if (net_error == OK) {
+ *addresses = CreateAddressListUsingPort(
+ cache_entry->addrlist, info.port());
+ }
// Update the net log and notify registered observers.
OnFinishRequest(source_net_log, request_net_log, request_id, info,
@@ -1137,7 +1163,7 @@ int HostResolverImpl::Resolve(const RequestInfo& info,
effective_resolver_proc(), key.hostname, key.address_family,
key.host_resolver_flags, &addrlist, &os_error);
if (error == OK) {
- addrlist.SetPort(info.port());
+ MutableSetPort(info.port(), &addrlist);
*addresses = addrlist;
}
diff --git a/net/base/host_resolver_proc.cc b/net/base/host_resolver_proc.cc
index b1230fa..30f453f 100644
--- a/net/base/host_resolver_proc.cc
+++ b/net/base/host_resolver_proc.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.
@@ -256,7 +256,7 @@ int SystemHostResolverProc(const std::string& host,
return ERR_NAME_NOT_RESOLVED;
}
- addrlist->Adopt(ai);
+ *addrlist = AddressList::CreateByAdoptingFromSystem(ai);
return OK;
}
diff --git a/net/base/mock_host_resolver.cc b/net/base/mock_host_resolver.cc
index 1f1c4cd..cd14eff 100644
--- a/net/base/mock_host_resolver.cc
+++ b/net/base/mock_host_resolver.cc
@@ -41,12 +41,12 @@ int CreateIPAddressList(const std::string& host_list,
return ERR_UNEXPECTED;
}
- AddressList result(ip_number, -1, false);
+ AddressList result = AddressList::CreateFromIPAddress(ip_number, -1);
struct addrinfo* ai = const_cast<struct addrinfo*>(result.head());
if (index == 0)
ai->ai_canonname = do_strdup(canonical_name.c_str());
if (!addrlist->head())
- addrlist->Copy(result.head(), false);
+ *addrlist = AddressList::CreateByCopyingFirstAddress(result.head());
else
addrlist->Append(result.head());
}
diff --git a/net/base/net_util.cc b/net/base/net_util.cc
index e97cb7f..059184a 100644
--- a/net/base/net_util.cc
+++ b/net/base/net_util.cc
@@ -2143,7 +2143,7 @@ const uint16* GetPortFieldFromAddrinfo(const struct addrinfo* info) {
return GetPortFieldFromSockaddr(address, info->ai_addrlen);
}
-int GetPortFromAddrinfo(const struct addrinfo* info) {
+uint16 GetPortFromAddrinfo(const struct addrinfo* info) {
const uint16* port_field = GetPortFieldFromAddrinfo(info);
if (!port_field)
return -1;
@@ -2175,6 +2175,16 @@ int GetPortFromSockaddr(const struct sockaddr* address, socklen_t address_len) {
return ntohs(*port_field);
}
+// Assign |port| to each address in the linked list starting from |head|.
+void SetPortForAllAddrinfos(struct addrinfo* head, uint16 port) {
+ DCHECK(head);
+ for (struct addrinfo* ai = head; ai; ai = ai->ai_next) {
+ uint16* port_field = GetPortFieldFromAddrinfo(ai);
+ if (port_field)
+ *port_field = htons(port);
+ }
+}
+
bool IsLocalhost(const std::string& host) {
if (host == "localhost" ||
host == "localhost.localdomain" ||
diff --git a/net/base/net_util.h b/net/base/net_util.h
index fa7733e..93cd423 100644
--- a/net/base/net_util.h
+++ b/net/base/net_util.h
@@ -417,7 +417,7 @@ const uint16* GetPortFieldFromAddrinfo(const struct addrinfo* info);
uint16* GetPortFieldFromAddrinfo(struct addrinfo* info);
// Returns the value of |info's| port (in host byte ordering).
-int GetPortFromAddrinfo(const struct addrinfo* info);
+uint16 GetPortFromAddrinfo(const struct addrinfo* info);
// Same except for struct sockaddr.
const uint16* GetPortFieldFromSockaddr(const struct sockaddr* address,
@@ -425,6 +425,10 @@ const uint16* GetPortFieldFromSockaddr(const struct sockaddr* address,
int GetPortFromSockaddr(const struct sockaddr* address,
socklen_t address_len);
+// Sets every addrinfo in the linked list |head| as having a port field of
+// |port|.
+void SetPortForAllAddrinfos(struct addrinfo* head, uint16 port);
+
// Returns true if |host| is one of the names (e.g. "localhost") or IP
// addresses (IPv4 127.0.0.0/8 or IPv6 ::1) that indicate a loopback.
//
diff --git a/net/http/http_auth_handler_negotiate.cc b/net/http/http_auth_handler_negotiate.cc
index a96902d..1edb429 100644
--- a/net/http/http_auth_handler_negotiate.cc
+++ b/net/http/http_auth_handler_negotiate.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.
@@ -302,7 +302,7 @@ int HttpAuthHandlerNegotiate::DoResolveCanonicalNameComplete(int rv) {
next_state_ = STATE_GENERATE_AUTH_TOKEN;
spn_ = CreateSPN(address_list_, origin_);
- address_list_.Reset();
+ address_list_ = AddressList();
return rv;
}
diff --git a/net/proxy/proxy_resolver_js_bindings_unittest.cc b/net/proxy/proxy_resolver_js_bindings_unittest.cc
index e4b309d..3355adb 100644
--- a/net/proxy/proxy_resolver_js_bindings_unittest.cc
+++ b/net/proxy/proxy_resolver_js_bindings_unittest.cc
@@ -60,26 +60,14 @@ class MockHostResolverWithMultipleResults : public HostResolver {
return result;
}
- // Builds an AddressList that is |ip_literal| + |address_list|.
+ // Builds an AddressList that is |ip_literal| + |orig_list|.
// |orig_list| must not be empty.
AddressList PrependAddressToList(const char* ip_literal,
const AddressList& orig_list) {
// Build an addrinfo for |ip_literal|.
AddressList result = ResolveIPLiteral(ip_literal);
-
- struct addrinfo* result_head = const_cast<struct addrinfo*>(result.head());
-
- // Temporarily append |orig_list| to |result|.
- result_head->ai_next = const_cast<struct addrinfo*>(orig_list.head());
-
- // Make a copy of the concatenated list.
- AddressList concatenated;
- concatenated.Copy(result.head(), true);
-
- // Restore |result| (so it is freed properly).
- result_head->ai_next = NULL;
-
- return concatenated;
+ result.Append(orig_list.head());
+ return result;
}
};
diff --git a/net/socket/ssl_server_socket_unittest.cc b/net/socket/ssl_server_socket_unittest.cc
index b3d1040..5e08ffe 100644
--- a/net/socket/ssl_server_socket_unittest.cc
+++ b/net/socket/ssl_server_socket_unittest.cc
@@ -146,7 +146,7 @@ class FakeSocket : public StreamSocket {
virtual int GetPeerAddress(AddressList* address) const {
net::IPAddressNumber ip_address(4);
- *address = net::AddressList(ip_address, 0, false);
+ *address = net::AddressList::CreateFromIPAddress(ip_address, 0 /*port*/);
return net::OK;
}
diff --git a/net/socket/tcp_client_socket_libevent.cc b/net/socket/tcp_client_socket_libevent.cc
index d386bae..6e0cb1c 100644
--- a/net/socket/tcp_client_socket_libevent.cc
+++ b/net/socket/tcp_client_socket_libevent.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.
@@ -615,7 +615,7 @@ int TCPClientSocketLibevent::GetPeerAddress(AddressList* address) const {
DCHECK(address);
if (!IsConnected())
return ERR_SOCKET_NOT_CONNECTED;
- address->Copy(current_ai_, false);
+ *address = AddressList::CreateByCopyingFirstAddress(current_ai_);
return OK;
}
diff --git a/net/socket/tcp_client_socket_win.cc b/net/socket/tcp_client_socket_win.cc
index de5ff61..469fffd 100644
--- a/net/socket/tcp_client_socket_win.cc
+++ b/net/socket/tcp_client_socket_win.cc
@@ -468,7 +468,7 @@ int TCPClientSocketWin::GetPeerAddress(AddressList* address) const {
DCHECK(address);
if (!IsConnected())
return ERR_SOCKET_NOT_CONNECTED;
- address->Copy(current_ai_, false);
+ *address = AddressList::CreateByCopyingFirstAddress(current_ai_);
return OK;
}
diff --git a/net/socket/tcp_server_socket_libevent.cc b/net/socket/tcp_server_socket_libevent.cc
index b065261..daedbf5 100644
--- a/net/socket/tcp_server_socket_libevent.cc
+++ b/net/socket/tcp_server_socket_libevent.cc
@@ -159,7 +159,7 @@ int TCPServerSocketLibevent::AcceptInternal(
return ERR_FAILED;
}
TCPClientSocket* tcp_socket = new TCPClientSocket(
- AddressList(address.address(), address.port(), false),
+ AddressList::CreateFromIPAddress(address.address(), address.port()),
net_log_.net_log(), net_log_.source());
tcp_socket->AdoptSocket(result);
socket->reset(tcp_socket);
diff --git a/net/socket/tcp_server_socket_unittest.cc b/net/socket/tcp_server_socket_unittest.cc
index 45297fe..d4abe9d 100644
--- a/net/socket/tcp_server_socket_unittest.cc
+++ b/net/socket/tcp_server_socket_unittest.cc
@@ -50,14 +50,18 @@ class TCPServerSocketTest : public PlatformTest {
return endpoint;
}
+ AddressList local_address_list() const {
+ return AddressList::CreateFromIPAddress(
+ local_address_.address(), local_address_.port());
+ }
+
TCPServerSocket socket_;
IPEndPoint local_address_;
};
TEST_F(TCPServerSocketTest, Accept) {
TestCompletionCallback connect_callback;
- TCPClientSocket connecting_socket(AddressList(local_address_.address(),
- local_address_.port(), false),
+ TCPClientSocket connecting_socket(local_address_list(),
NULL, NetLog::Source());
connecting_socket.Connect(&connect_callback);
@@ -85,8 +89,7 @@ TEST_F(TCPServerSocketTest, AcceptAsync) {
ASSERT_EQ(ERR_IO_PENDING, socket_.Accept(&accepted_socket, &accept_callback));
TestCompletionCallback connect_callback;
- TCPClientSocket connecting_socket(AddressList(local_address_.address(),
- local_address_.port(), false),
+ TCPClientSocket connecting_socket(local_address_list(),
NULL, NetLog::Source());
connecting_socket.Connect(&connect_callback);
@@ -109,14 +112,12 @@ TEST_F(TCPServerSocketTest, Accept2Connections) {
socket_.Accept(&accepted_socket, &accept_callback));
TestCompletionCallback connect_callback;
- TCPClientSocket connecting_socket(AddressList(local_address_.address(),
- local_address_.port(), false),
+ TCPClientSocket connecting_socket(local_address_list(),
NULL, NetLog::Source());
connecting_socket.Connect(&connect_callback);
TestCompletionCallback connect_callback2;
- TCPClientSocket connecting_socket2(AddressList(local_address_.address(),
- local_address_.port(), false),
+ TCPClientSocket connecting_socket2(local_address_list(),
NULL, NetLog::Source());
connecting_socket2.Connect(&connect_callback2);
diff --git a/net/socket/tcp_server_socket_win.cc b/net/socket/tcp_server_socket_win.cc
index bae18f2..a850a8a 100644
--- a/net/socket/tcp_server_socket_win.cc
+++ b/net/socket/tcp_server_socket_win.cc
@@ -143,7 +143,7 @@ int TCPServerSocketWin::AcceptInternal(scoped_ptr<StreamSocket>* socket) {
return ERR_FAILED;
}
TCPClientSocket* tcp_socket = new TCPClientSocket(
- AddressList(address.address(), address.port(), false),
+ AddressList::CreateFromIPAddress(address.address(), address.port()),
net_log_.net_log(), net_log_.source());
tcp_socket->AdoptSocket(result);
socket->reset(tcp_socket);
diff --git a/net/socket/transport_client_socket_pool.cc b/net/socket/transport_client_socket_pool.cc
index c35a934..76ade36 100644
--- a/net/socket/transport_client_socket_pool.cc
+++ b/net/socket/transport_client_socket_pool.cc
@@ -119,7 +119,7 @@ void TransportConnectJob::MakeAddrListStartWithIPv4(AddressList* addrlist) {
}
head->ai_canonname = canonname;
- addrlist->Copy(head, true);
+ *addrlist = AddressList::CreateByCopying(head);
FreeCopyOfAddrinfo(head);
}
diff --git a/net/socket/transport_client_socket_pool_unittest.cc b/net/socket/transport_client_socket_pool_unittest.cc
index 2fee5ea..49c42de 100644
--- a/net/socket/transport_client_socket_pool_unittest.cc
+++ b/net/socket/transport_client_socket_pool_unittest.cc
@@ -359,19 +359,19 @@ class TransportClientSocketPoolTest : public testing::Test {
TEST(TransportConnectJobTest, MakeAddrListStartWithIPv4) {
IPAddressNumber ip_number;
ASSERT_TRUE(ParseIPLiteralToNumber("192.168.1.1", &ip_number));
- AddressList addrlist_v4_1(ip_number, 80, false);
+ AddressList addrlist_v4_1 = AddressList::CreateFromIPAddress(ip_number, 80);
ASSERT_TRUE(ParseIPLiteralToNumber("192.168.1.2", &ip_number));
- AddressList addrlist_v4_2(ip_number, 80, false);
+ AddressList addrlist_v4_2 = AddressList::CreateFromIPAddress(ip_number, 80);
ASSERT_TRUE(ParseIPLiteralToNumber("2001:4860:b006::64", &ip_number));
- AddressList addrlist_v6_1(ip_number, 80, false);
+ AddressList addrlist_v6_1 = AddressList::CreateFromIPAddress(ip_number, 80);
ASSERT_TRUE(ParseIPLiteralToNumber("2001:4860:b006::66", &ip_number));
- AddressList addrlist_v6_2(ip_number, 80, false);
+ AddressList addrlist_v6_2 = AddressList::CreateFromIPAddress(ip_number, 80);
AddressList addrlist;
const struct addrinfo* ai;
// Test 1: IPv4 only. Expect no change.
- addrlist.Copy(addrlist_v4_1.head(), true);
+ addrlist = addrlist_v4_1;
addrlist.Append(addrlist_v4_2.head());
TransportConnectJob::MakeAddrListStartWithIPv4(&addrlist);
ai = addrlist.head();
@@ -381,7 +381,7 @@ TEST(TransportConnectJobTest, MakeAddrListStartWithIPv4) {
EXPECT_TRUE(ai->ai_next == NULL);
// Test 2: IPv6 only. Expect no change.
- addrlist.Copy(addrlist_v6_1.head(), true);
+ addrlist = addrlist_v6_1;
addrlist.Append(addrlist_v6_2.head());
TransportConnectJob::MakeAddrListStartWithIPv4(&addrlist);
ai = addrlist.head();
@@ -391,7 +391,7 @@ TEST(TransportConnectJobTest, MakeAddrListStartWithIPv4) {
EXPECT_TRUE(ai->ai_next == NULL);
// Test 3: IPv4 then IPv6. Expect no change.
- addrlist.Copy(addrlist_v4_1.head(), true);
+ addrlist = addrlist_v4_1;
addrlist.Append(addrlist_v4_2.head());
addrlist.Append(addrlist_v6_1.head());
addrlist.Append(addrlist_v6_2.head());
@@ -407,7 +407,7 @@ TEST(TransportConnectJobTest, MakeAddrListStartWithIPv4) {
EXPECT_TRUE(ai->ai_next == NULL);
// Test 4: IPv6, IPv4, IPv6, IPv4. Expect first IPv6 moved to the end.
- addrlist.Copy(addrlist_v6_1.head(), true);
+ addrlist = addrlist_v6_1;
addrlist.Append(addrlist_v4_1.head());
addrlist.Append(addrlist_v6_2.head());
addrlist.Append(addrlist_v4_2.head());
@@ -423,7 +423,7 @@ TEST(TransportConnectJobTest, MakeAddrListStartWithIPv4) {
EXPECT_TRUE(ai->ai_next == NULL);
// Test 5: IPv6, IPv6, IPv4, IPv4. Expect first two IPv6's moved to the end.
- addrlist.Copy(addrlist_v6_1.head(), true);
+ addrlist = addrlist_v6_1;
addrlist.Append(addrlist_v6_2.head());
addrlist.Append(addrlist_v4_1.head());
addrlist.Append(addrlist_v4_2.head());
diff --git a/net/socket_stream/socket_stream.cc b/net/socket_stream/socket_stream.cc
index d440664..a36603f 100644
--- a/net/socket_stream/socket_stream.cc
+++ b/net/socket_stream/socket_stream.cc
@@ -252,7 +252,7 @@ SocketStream::~SocketStream() {
}
void SocketStream::CopyAddrInfo(struct addrinfo* head) {
- addresses_.Copy(head, true);
+ addresses_ = AddressList::CreateByCopying(head);
}
void SocketStream::DoClose() {
diff --git a/net/websockets/websocket_job.cc b/net/websockets/websocket_job.cc
index f90d55f..d0d3910 100644
--- a/net/websockets/websocket_job.cc
+++ b/net/websockets/websocket_job.cc
@@ -164,7 +164,7 @@ int WebSocketJob::OnStartOpenConnection(
SocketStream* socket, CompletionCallback* callback) {
DCHECK(!callback_);
state_ = CONNECTING;
- addresses_.Copy(socket->address_list().head(), true);
+ addresses_ = socket->address_list();
WebSocketThrottle::GetInstance()->PutInQueue(this);
if (!waiting_)
return OK;
diff --git a/net/websockets/websocket_job_unittest.cc b/net/websockets/websocket_job_unittest.cc
index eb4bca1..0a77bc3 100644
--- a/net/websockets/websocket_job_unittest.cc
+++ b/net/websockets/websocket_job_unittest.cc
@@ -202,7 +202,7 @@ class WebSocketJobTest : public PlatformTest {
memcpy(&sa_in.sin_addr, "\x7f\0\0\1", 4);
addr.ai_addr = reinterpret_cast<sockaddr*>(&sa_in);
addr.ai_next = NULL;
- websocket_->addresses_.Copy(&addr, true);
+ websocket_->addresses_ = AddressList::CreateByCopying(&addr);
WebSocketThrottle::GetInstance()->PutInQueue(websocket_);
}
WebSocketJob::State GetWebSocketJobState() {
diff --git a/remoting/jingle_glue/ssl_socket_adapter.cc b/remoting/jingle_glue/ssl_socket_adapter.cc
index 51273f5..1111929 100644
--- a/remoting/jingle_glue/ssl_socket_adapter.cc
+++ b/remoting/jingle_glue/ssl_socket_adapter.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.
@@ -273,7 +273,7 @@ int TransportSocket::GetPeerAddress(net::AddressList* address) const {
ai.ai_addr = reinterpret_cast<struct sockaddr*>(&ipv4addr);
ai.ai_addrlen = sizeof(ipv4addr);
- address->Copy(&ai, false);
+ *address = net::AddressList::CreateByCopyingFirstAddress(&ai);
return net::OK;
}