Index: net/base/net_util.cc |
=================================================================== |
--- net/base/net_util.cc (revision 85841) |
+++ net/base/net_util.cc (working copy) |
@@ -1120,6 +1120,14 @@ |
return url_string; |
} |
+char* do_strdup(const char* src) { |
+#if defined(OS_WIN) |
+ return _strdup(src); |
+#else |
+ return strdup(src); |
+#endif |
+} |
+ |
} // namespace |
const FormatUrlType kFormatUrlOmitNothing = 0; |
@@ -2182,6 +2190,51 @@ |
return true; |
} |
+struct addrinfo* CreateCopyOfAddrinfo(const struct addrinfo* info, |
+ bool recursive) { |
+ DCHECK(info); |
+ struct addrinfo* copy = new addrinfo; |
+ |
+ // Copy all the fields (some of these are pointers, we will fix that next). |
+ memcpy(copy, info, sizeof(addrinfo)); |
+ |
+ // ai_canonname is a NULL-terminated string. |
+ if (info->ai_canonname) { |
+ copy->ai_canonname = do_strdup(info->ai_canonname); |
+ } |
+ |
+ // ai_addr is a buffer of length ai_addrlen. |
+ if (info->ai_addr) { |
+ copy->ai_addr = reinterpret_cast<sockaddr *>(new char[info->ai_addrlen]); |
+ memcpy(copy->ai_addr, info->ai_addr, info->ai_addrlen); |
+ } |
+ |
+ // Recursive copy. |
+ if (recursive && info->ai_next) |
+ copy->ai_next = CreateCopyOfAddrinfo(info->ai_next, recursive); |
+ else |
+ copy->ai_next = NULL; |
+ |
+ return copy; |
+} |
+ |
+void FreeCopyOfAddrinfo(struct addrinfo* info) { |
+ DCHECK(info); |
+ if (info->ai_canonname) |
+ free(info->ai_canonname); // Allocated by strdup. |
+ |
+ if (info->ai_addr) |
+ delete [] reinterpret_cast<char*>(info->ai_addr); |
+ |
+ struct addrinfo* next = info->ai_next; |
+ |
+ delete info; |
+ |
+ // Recursive free. |
+ if (next) |
+ FreeCopyOfAddrinfo(next); |
+} |
+ |
// Returns the port field of the sockaddr in |info|. |
uint16* GetPortFieldFromAddrinfo(struct addrinfo* info) { |
const struct addrinfo* const_info = info; |