diff options
author | phajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-20 18:50:38 +0000 |
---|---|---|
committer | phajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-20 18:50:38 +0000 |
commit | ac9eec64de86f3d3a290a1a8b9321260cff7ed23 (patch) | |
tree | aac041c6ddaec400b6e2b6d3d982935aa7f69a9c /net/base | |
parent | 8c1ae5ec4d47638315096f54819793484383c91f (diff) | |
download | chromium_src-ac9eec64de86f3d3a290a1a8b9321260cff7ed23.zip chromium_src-ac9eec64de86f3d3a290a1a8b9321260cff7ed23.tar.gz chromium_src-ac9eec64de86f3d3a290a1a8b9321260cff7ed23.tar.bz2 |
Really connect to the same server in FTP network transaction.
Also create necessary infrastructure to know the address
a client socket is connected to.
TEST=Covered by net_unittests.
BUG=35670
Review URL: http://codereview.chromium.org/598071
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@39559 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/base')
-rw-r--r-- | net/base/address_list.cc | 42 | ||||
-rw-r--r-- | net/base/address_list.h | 10 | ||||
-rw-r--r-- | net/base/address_list_unittest.cc | 64 | ||||
-rw-r--r-- | net/base/nss_memio.c | 10 | ||||
-rw-r--r-- | net/base/nss_memio.h | 7 |
5 files changed, 113 insertions, 20 deletions
diff --git a/net/base/address_list.cc b/net/base/address_list.cc index 93ec009..d1624be 100644 --- a/net/base/address_list.cc +++ b/net/base/address_list.cc @@ -13,9 +13,12 @@ namespace net { namespace { -// Make a deep copy of |info|. This copy should be deleted using +// 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) { +struct addrinfo* CreateCopyOfAddrinfo(const struct addrinfo* info, + bool recursive) { struct addrinfo* copy = new addrinfo; // Copy all the fields (some of these are pointers, we will fix that next). @@ -37,8 +40,10 @@ struct addrinfo* CreateCopyOfAddrinfo(const struct addrinfo* info) { } // Recursive copy. - if (info->ai_next) - copy->ai_next = CreateCopyOfAddrinfo(info->ai_next); + if (recursive && info->ai_next) + copy->ai_next = CreateCopyOfAddrinfo(info->ai_next, recursive); + else + copy->ai_next = NULL; return copy; } @@ -81,7 +86,8 @@ uint16* GetPortField(const struct addrinfo* info) { // Assign the port for all addresses in the list. void SetPortRecursive(struct addrinfo* info, int port) { uint16* port_field = GetPortField(info); - *port_field = htons(port); + if (port_field) + *port_field = htons(port); // Assign recursively. if (info->ai_next) @@ -94,8 +100,25 @@ void AddressList::Adopt(struct addrinfo* head) { data_ = new Data(head, true /*is_system_created*/); } -void AddressList::Copy(const struct addrinfo* head) { - data_ = new Data(CreateCopyOfAddrinfo(head), false /*is_system_created*/); +void AddressList::Copy(const struct addrinfo* head, bool recursive) { + data_ = new Data(CreateCopyOfAddrinfo(head, recursive), + false /*is_system_created*/); +} + +void AddressList::Append(const struct addrinfo* 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; + } + + // 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); } void AddressList::SetPort(int port) { @@ -104,6 +127,9 @@ void AddressList::SetPort(int port) { int AddressList::GetPort() const { uint16* port_field = GetPortField(data_->head); + if (!port_field) + return -1; + return ntohs(*port_field); } @@ -113,7 +139,7 @@ void AddressList::SetFrom(const AddressList& src, int port) { *this = src; } else { // Otherwise we need to make a copy in order to change the port number. - Copy(src.head()); + Copy(src.head(), true); SetPort(port); } } diff --git a/net/base/address_list.h b/net/base/address_list.h index 3087472..b477987 100644 --- a/net/base/address_list.h +++ b/net/base/address_list.h @@ -23,8 +23,14 @@ class AddressList { // object. void Adopt(struct addrinfo* head); - // Copies the given addrinfo rather than adopting it. - void Copy(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); + + // Appends a copy of |head| and all its linked addrinfos to the stored + // addrinfo. + 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). diff --git a/net/base/address_list_unittest.cc b/net/base/address_list_unittest.cc index d440c15..dbd0f24 100644 --- a/net/base/address_list_unittest.cc +++ b/net/base/address_list_unittest.cc @@ -7,6 +7,7 @@ #include "base/string_util.h" #include "net/base/host_resolver_proc.h" #include "net/base/net_util.h" +#include "net/base/sys_addrinfo.h" #if defined(OS_WIN) #include "net/base/winsock_init.h" #endif @@ -15,20 +16,28 @@ namespace { // Use getaddrinfo() to allocate an addrinfo structure. -void CreateAddressList(net::AddressList* addrlist, int port) { +void CreateAddressList(const std::string& hostname, + net::AddressList* addrlist, int port) { #if defined(OS_WIN) net::EnsureWinsockInit(); #endif - int rv = SystemHostResolverProc("192.168.1.1", + int rv = SystemHostResolverProc(hostname, net::ADDRESS_FAMILY_UNSPECIFIED, addrlist); EXPECT_EQ(0, rv); addrlist->SetPort(port); } +void CreateLongAddressList(net::AddressList* addrlist, int port) { + CreateAddressList("192.168.1.1", addrlist, port); + net::AddressList second_list; + CreateAddressList("192.168.1.2", &second_list, port); + addrlist->Append(second_list.head()); +} + TEST(AddressListTest, GetPort) { net::AddressList addrlist; - CreateAddressList(&addrlist, 81); + CreateAddressList("192.168.1.1", &addrlist, 81); EXPECT_EQ(81, addrlist.GetPort()); addrlist.SetPort(83); @@ -37,7 +46,7 @@ TEST(AddressListTest, GetPort) { TEST(AddressListTest, Assignment) { net::AddressList addrlist1; - CreateAddressList(&addrlist1, 85); + CreateAddressList("192.168.1.1", &addrlist1, 85); EXPECT_EQ(85, addrlist1.GetPort()); // Should reference the same data as addrlist1 -- so when we change addrlist1 @@ -50,13 +59,15 @@ TEST(AddressListTest, Assignment) { EXPECT_EQ(80, addrlist2.GetPort()); } -TEST(AddressListTest, Copy) { +TEST(AddressListTest, CopyRecursive) { net::AddressList addrlist1; - CreateAddressList(&addrlist1, 85); + CreateLongAddressList(&addrlist1, 85); EXPECT_EQ(85, addrlist1.GetPort()); net::AddressList addrlist2; - addrlist2.Copy(addrlist1.head()); + addrlist2.Copy(addrlist1.head(), true); + + ASSERT_TRUE(addrlist2.head()->ai_next != NULL); // addrlist1 is the same as addrlist2 at this point. EXPECT_EQ(85, addrlist1.GetPort()); @@ -70,4 +81,43 @@ TEST(AddressListTest, Copy) { EXPECT_EQ(90, addrlist2.GetPort()); } +TEST(AddressListTest, CopyNonRecursive) { + net::AddressList addrlist1; + CreateLongAddressList(&addrlist1, 85); + EXPECT_EQ(85, addrlist1.GetPort()); + + net::AddressList addrlist2; + addrlist2.Copy(addrlist1.head(), false); + + ASSERT_TRUE(addrlist2.head()->ai_next == NULL); + + // addrlist1 is the same as addrlist2 at this point. + EXPECT_EQ(85, addrlist1.GetPort()); + EXPECT_EQ(85, addrlist2.GetPort()); + + // Changes to addrlist1 are not reflected in addrlist2. + addrlist1.SetPort(70); + addrlist2.SetPort(90); + + EXPECT_EQ(70, addrlist1.GetPort()); + EXPECT_EQ(90, addrlist2.GetPort()); +} + +TEST(AddressListTest, Append) { + net::AddressList addrlist1; + CreateAddressList("192.168.1.1", &addrlist1, 11); + EXPECT_EQ(11, addrlist1.GetPort()); + net::AddressList addrlist2; + CreateAddressList("192.168.1.2", &addrlist2, 12); + EXPECT_EQ(12, addrlist2.GetPort()); + + ASSERT_TRUE(addrlist1.head()->ai_next == NULL); + addrlist1.Append(addrlist2.head()); + ASSERT_TRUE(addrlist1.head()->ai_next != NULL); + + net::AddressList addrlist3; + addrlist3.Copy(addrlist1.head()->ai_next, false); + EXPECT_EQ(12, addrlist3.GetPort()); +} + } // namespace diff --git a/net/base/nss_memio.c b/net/base/nss_memio.c index 341cfee..6796882 100644 --- a/net/base/nss_memio.c +++ b/net/base/nss_memio.c @@ -359,11 +359,17 @@ PRFileDesc *memio_CreateIOLayer(int bufsize) return fd; } -void memio_SetPeerName(PRFileDesc *fd, const PRNetAddr *peername) +void memio_SetPeerName(PRFileDesc *fd, const struct sockaddr *peername, + size_t peername_len) { PRFileDesc *memiofd = PR_GetIdentitiesLayer(fd, memio_identity); struct PRFilePrivate *secret = memiofd->secret; - secret->peername = *peername; + size_t len; + + memset(&secret->peername, 0, sizeof(secret->peername)); + PR_ASSERT(peername_len <= sizeof(secret->peername)); + len = PR_MIN(peername_len, sizeof(secret->peername)); + memcpy(&secret->peername, peername, len); } memio_Private *memio_GetSecret(PRFileDesc *fd) diff --git a/net/base/nss_memio.h b/net/base/nss_memio.h index 0bee53e..a9e6e22 100644 --- a/net/base/nss_memio.h +++ b/net/base/nss_memio.h @@ -6,12 +6,16 @@ #ifndef __MEMIO_H #define __MEMIO_H +#include <stddef.h> + #ifdef __cplusplus extern "C" { #endif #include "prio.h" +struct sockaddr; + /* Opaque structure. Really just a more typesafe alias for PRFilePrivate. */ struct memio_Private; typedef struct memio_Private memio_Private; @@ -38,7 +42,8 @@ typedef struct memio_Private memio_Private; PRFileDesc *memio_CreateIOLayer(int bufsize); /* Must call before trying to make an ssl connection */ -void memio_SetPeerName(PRFileDesc *fd, const PRNetAddr *peername); +void memio_SetPeerName(PRFileDesc *fd, const struct sockaddr *peername, + size_t peername_len); /* Return a private pointer needed by the following * four functions. (We could have passed a PRFileDesc to |