| 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;
|
|
|