| Index: net/base/address_list.cc
|
| diff --git a/net/base/address_list.cc b/net/base/address_list.cc
|
| index 93ec009eafd014295c7947c868de61c3eef4d129..d1624be44463cc1df2ee447d97b40c625f4398bf 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);
|
| }
|
| }
|
|
|