diff options
author | eroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-12 02:02:40 +0000 |
---|---|---|
committer | eroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-12 02:02:40 +0000 |
commit | fe89ea7e351d304ca379125329018f5b96a2aded (patch) | |
tree | f4a0a43fc9e626d3a8e015a363ebbab635154e4e | |
parent | 1870d5cfa5ca359b44a32322c225cca1b2818e91 (diff) | |
download | chromium_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
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; } |