blob: b8401aea4602306b0d003bb6f2bbcc1f82529100 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/base/address_list.h"
#include <utility>
#include "base/bind.h"
#include "base/callback.h"
#include "base/logging.h"
#include "base/values.h"
#include "net/base/sys_addrinfo.h"
#include "net/log/net_log_capture_mode.h"
#if defined(STARBOARD)
#include "base/lazy_instance.h"
#include "base/command_line.h"
#endif
namespace net {
namespace {
std::unique_ptr<base::Value> NetLogAddressListCallback(
const AddressList* address_list,
NetLogCaptureMode capture_mode) {
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
std::unique_ptr<base::ListValue> list(new base::ListValue());
for (auto it = address_list->begin(); it != address_list->end(); ++it) {
list->AppendString(it->ToString());
}
dict->Set("address_list", std::move(list));
return std::move(dict);
}
} // namespace
AddressList::AddressList() = default;
AddressList::AddressList(const AddressList&) = default;
AddressList::~AddressList() = default;
AddressList::AddressList(const IPEndPoint& endpoint) {
push_back(endpoint);
}
// static
AddressList AddressList::CreateFromIPAddress(const IPAddress& address,
uint16_t port) {
return AddressList(IPEndPoint(address, port));
}
// static
AddressList AddressList::CreateFromIPAddressList(
const IPAddressList& addresses,
const std::string& canonical_name) {
AddressList list;
list.set_canonical_name(canonical_name);
for (auto iter = addresses.begin(); iter != addresses.end(); ++iter) {
list.push_back(IPEndPoint(*iter, 0));
}
return list;
}
#if defined(STARBOARD)
#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
namespace {
const char kResolveOnlyIpv6[] = "resolve_only_ipv6";
const char kResolveOnlyIpv4[] = "resolve_only_ipv4";
struct ResolveFilterFlags {
ResolveFilterFlags();
bool resolve_only_ipv6;
bool resolve_only_ipv4;
};
base::LazyInstance<ResolveFilterFlags>::Leaky g_resolve_filter_flags =
LAZY_INSTANCE_INITIALIZER;
ResolveFilterFlags::ResolveFilterFlags() {
resolve_only_ipv6 =
base::CommandLine::ForCurrentProcess()->HasSwitch(kResolveOnlyIpv6);
resolve_only_ipv4 =
base::CommandLine::ForCurrentProcess()->HasSwitch(kResolveOnlyIpv4);
DCHECK(!(resolve_only_ipv6 && resolve_only_ipv4));
}
} // namespace
#endif // defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
// static
AddressList AddressList::CreateFromSbSocketResolution(
const SbSocketResolution* resolution) {
DCHECK(resolution);
AddressList list;
for (int i = 0; i < resolution->address_count; ++i) {
#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
SbSocketAddressType address_type = resolution->addresses[i].type;
ResolveFilterFlags& flags = g_resolve_filter_flags.Get();
if ((flags.resolve_only_ipv6 && address_type != kSbSocketAddressTypeIpv6) ||
(flags.resolve_only_ipv4 && address_type != kSbSocketAddressTypeIpv4)) {
continue;
}
#endif // defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
IPEndPoint end_point;
if (end_point.FromSbSocketAddress(&resolution->addresses[i])) {
list.push_back(end_point);
continue;
}
DLOG(WARNING) << "Failure to convert resolution address #" << i;
}
return list;
}
#else // defined(STARBOARD)
// static
AddressList AddressList::CreateFromAddrinfo(const struct addrinfo* head) {
DCHECK(head);
AddressList list;
if (head->ai_canonname)
list.set_canonical_name(std::string(head->ai_canonname));
for (const struct addrinfo* ai = head; ai; ai = ai->ai_next) {
IPEndPoint ipe;
// NOTE: Ignoring non-INET* families.
if (ipe.FromSockAddr(ai->ai_addr, ai->ai_addrlen))
list.push_back(ipe);
else
DLOG(WARNING) << "Unknown family found in addrinfo: " << ai->ai_family;
}
return list;
}
#endif // defined(STARBOARD)
// static
AddressList AddressList::CopyWithPort(const AddressList& list, uint16_t port) {
AddressList out;
out.set_canonical_name(list.canonical_name());
for (size_t i = 0; i < list.size(); ++i)
out.push_back(IPEndPoint(list[i].address(), port));
return out;
}
void AddressList::SetDefaultCanonicalName() {
DCHECK(!empty());
set_canonical_name(front().ToStringWithoutPort());
}
NetLogParametersCallback AddressList::CreateNetLogCallback() const {
return base::Bind(&NetLogAddressListCallback, this);
}
} // namespace net