Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(117)

Side by Side Diff: net/base/address_list.cc

Issue 598071: Really connect to the same server in FTP network transaction. (Closed)
Patch Set: updates Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/base/address_list.h ('k') | net/base/address_list_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/base/address_list.h" 5 #include "net/base/address_list.h"
6 6
7 #include <stdlib.h> 7 #include <stdlib.h>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "net/base/sys_addrinfo.h" 10 #include "net/base/sys_addrinfo.h"
11 11
12 namespace net { 12 namespace net {
13 13
14 namespace { 14 namespace {
15 15
16 // Make a deep copy of |info|. This copy should be deleted using 16 // Make a copy of |info| (the dynamically-allocated parts are copied as well).
17 // If |recursive| is true, chained entries via ai_next are copied too.
18 // Copy returned by this function should be deleted using
17 // DeleteCopyOfAddrinfo(), and NOT freeaddrinfo(). 19 // DeleteCopyOfAddrinfo(), and NOT freeaddrinfo().
18 struct addrinfo* CreateCopyOfAddrinfo(const struct addrinfo* info) { 20 struct addrinfo* CreateCopyOfAddrinfo(const struct addrinfo* info,
21 bool recursive) {
19 struct addrinfo* copy = new addrinfo; 22 struct addrinfo* copy = new addrinfo;
20 23
21 // Copy all the fields (some of these are pointers, we will fix that next). 24 // Copy all the fields (some of these are pointers, we will fix that next).
22 memcpy(copy, info, sizeof(addrinfo)); 25 memcpy(copy, info, sizeof(addrinfo));
23 26
24 // ai_canonname is a NULL-terminated string. 27 // ai_canonname is a NULL-terminated string.
25 if (info->ai_canonname) { 28 if (info->ai_canonname) {
26 #ifdef OS_WIN 29 #ifdef OS_WIN
27 copy->ai_canonname = _strdup(info->ai_canonname); 30 copy->ai_canonname = _strdup(info->ai_canonname);
28 #else 31 #else
29 copy->ai_canonname = strdup(info->ai_canonname); 32 copy->ai_canonname = strdup(info->ai_canonname);
30 #endif 33 #endif
31 } 34 }
32 35
33 // ai_addr is a buffer of length ai_addrlen. 36 // ai_addr is a buffer of length ai_addrlen.
34 if (info->ai_addr) { 37 if (info->ai_addr) {
35 copy->ai_addr = reinterpret_cast<sockaddr *>(new char[info->ai_addrlen]); 38 copy->ai_addr = reinterpret_cast<sockaddr *>(new char[info->ai_addrlen]);
36 memcpy(copy->ai_addr, info->ai_addr, info->ai_addrlen); 39 memcpy(copy->ai_addr, info->ai_addr, info->ai_addrlen);
37 } 40 }
38 41
39 // Recursive copy. 42 // Recursive copy.
40 if (info->ai_next) 43 if (recursive && info->ai_next)
41 copy->ai_next = CreateCopyOfAddrinfo(info->ai_next); 44 copy->ai_next = CreateCopyOfAddrinfo(info->ai_next, recursive);
45 else
46 copy->ai_next = NULL;
42 47
43 return copy; 48 return copy;
44 } 49 }
45 50
46 // Free an addrinfo that was created by CreateCopyOfAddrinfo(). 51 // Free an addrinfo that was created by CreateCopyOfAddrinfo().
47 void FreeMyAddrinfo(struct addrinfo* info) { 52 void FreeMyAddrinfo(struct addrinfo* info) {
48 if (info->ai_canonname) 53 if (info->ai_canonname)
49 free(info->ai_canonname); // Allocated by strdup. 54 free(info->ai_canonname); // Allocated by strdup.
50 55
51 if (info->ai_addr) 56 if (info->ai_addr)
(...skipping 22 matching lines...) Expand all
74 return &sockaddr->sin6_port; 79 return &sockaddr->sin6_port;
75 } else { 80 } else {
76 NOTREACHED(); 81 NOTREACHED();
77 return NULL; 82 return NULL;
78 } 83 }
79 } 84 }
80 85
81 // Assign the port for all addresses in the list. 86 // Assign the port for all addresses in the list.
82 void SetPortRecursive(struct addrinfo* info, int port) { 87 void SetPortRecursive(struct addrinfo* info, int port) {
83 uint16* port_field = GetPortField(info); 88 uint16* port_field = GetPortField(info);
84 *port_field = htons(port); 89 if (port_field)
90 *port_field = htons(port);
85 91
86 // Assign recursively. 92 // Assign recursively.
87 if (info->ai_next) 93 if (info->ai_next)
88 SetPortRecursive(info->ai_next, port); 94 SetPortRecursive(info->ai_next, port);
89 } 95 }
90 96
91 } // namespace 97 } // namespace
92 98
93 void AddressList::Adopt(struct addrinfo* head) { 99 void AddressList::Adopt(struct addrinfo* head) {
94 data_ = new Data(head, true /*is_system_created*/); 100 data_ = new Data(head, true /*is_system_created*/);
95 } 101 }
96 102
97 void AddressList::Copy(const struct addrinfo* head) { 103 void AddressList::Copy(const struct addrinfo* head, bool recursive) {
98 data_ = new Data(CreateCopyOfAddrinfo(head), false /*is_system_created*/); 104 data_ = new Data(CreateCopyOfAddrinfo(head, recursive),
105 false /*is_system_created*/);
106 }
107
108 void AddressList::Append(const struct addrinfo* head) {
109 struct addrinfo* new_head;
110 if (data_->is_system_created) {
111 new_head = CreateCopyOfAddrinfo(data_->head, true);
112 data_ = new Data(new_head, false /*is_system_created*/);
113 } else {
114 new_head = data_->head;
115 }
116
117 // Find the end of current linked list and append new data there.
118 struct addrinfo* copy_ptr = new_head;
119 while (copy_ptr->ai_next)
120 copy_ptr = copy_ptr->ai_next;
121 copy_ptr->ai_next = CreateCopyOfAddrinfo(head, true);
99 } 122 }
100 123
101 void AddressList::SetPort(int port) { 124 void AddressList::SetPort(int port) {
102 SetPortRecursive(data_->head, port); 125 SetPortRecursive(data_->head, port);
103 } 126 }
104 127
105 int AddressList::GetPort() const { 128 int AddressList::GetPort() const {
106 uint16* port_field = GetPortField(data_->head); 129 uint16* port_field = GetPortField(data_->head);
130 if (!port_field)
131 return -1;
132
107 return ntohs(*port_field); 133 return ntohs(*port_field);
108 } 134 }
109 135
110 void AddressList::SetFrom(const AddressList& src, int port) { 136 void AddressList::SetFrom(const AddressList& src, int port) {
111 if (src.GetPort() == port) { 137 if (src.GetPort() == port) {
112 // We can reference the data from |src| directly. 138 // We can reference the data from |src| directly.
113 *this = src; 139 *this = src;
114 } else { 140 } else {
115 // Otherwise we need to make a copy in order to change the port number. 141 // Otherwise we need to make a copy in order to change the port number.
116 Copy(src.head()); 142 Copy(src.head(), true);
117 SetPort(port); 143 SetPort(port);
118 } 144 }
119 } 145 }
120 146
121 void AddressList::Reset() { 147 void AddressList::Reset() {
122 data_ = NULL; 148 data_ = NULL;
123 } 149 }
124 150
125 // static 151 // static
126 AddressList AddressList::CreateIPv6Address(unsigned char data[16]) { 152 AddressList AddressList::CreateIPv6Address(unsigned char data[16]) {
(...skipping 18 matching lines...) Expand all
145 AddressList::Data::~Data() { 171 AddressList::Data::~Data() {
146 // Call either freeaddrinfo(head), or FreeMyAddrinfo(head), depending who 172 // Call either freeaddrinfo(head), or FreeMyAddrinfo(head), depending who
147 // created the data. 173 // created the data.
148 if (is_system_created) 174 if (is_system_created)
149 freeaddrinfo(head); 175 freeaddrinfo(head);
150 else 176 else
151 FreeMyAddrinfo(head); 177 FreeMyAddrinfo(head);
152 } 178 }
153 179
154 } // namespace net 180 } // namespace net
OLDNEW
« no previous file with comments | « net/base/address_list.h ('k') | net/base/address_list_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698