blob: 7eefb30c70e447ff606b486b4952b45363509518 [file] [log] [blame]
// Copyright (c) 2016 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/third_party/quic/platform/impl/quic_ip_address_impl.h"
#include "build/build_config.h"
#include "net/base/address_family.h"
#include "net/third_party/quic/platform/api/quic_bug_tracker.h"
#if defined(OS_WIN)
#include <winsock2.h>
#include <ws2bth.h>
#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
#include <netinet/in.h>
#include "starboard/types.h"
#endif
using std::string;
namespace quic {
QuicIpAddressImpl QuicIpAddressImpl::Loopback4() {
return QuicIpAddressImpl(net::IPAddress::IPv4Localhost());
}
QuicIpAddressImpl QuicIpAddressImpl::Loopback6() {
return QuicIpAddressImpl(net::IPAddress::IPv6Localhost());
}
QuicIpAddressImpl QuicIpAddressImpl::Any4() {
return QuicIpAddressImpl(net::IPAddress::IPv4AllZeros());
}
QuicIpAddressImpl QuicIpAddressImpl::Any6() {
return QuicIpAddressImpl(net::IPAddress::IPv6AllZeros());
}
QuicIpAddressImpl::QuicIpAddressImpl(const net::IPAddress& addr)
: ip_address_(addr) {}
bool operator==(QuicIpAddressImpl lhs, QuicIpAddressImpl rhs) {
return lhs.ip_address_ == rhs.ip_address_;
}
bool operator!=(QuicIpAddressImpl lhs, QuicIpAddressImpl rhs) {
return !(lhs == rhs);
}
bool QuicIpAddressImpl::IsInitialized() const {
return net::GetAddressFamily(ip_address_) != net::ADDRESS_FAMILY_UNSPECIFIED;
}
IpAddressFamily QuicIpAddressImpl::address_family() const {
switch (net::GetAddressFamily(ip_address_)) {
case net::ADDRESS_FAMILY_IPV4:
return IpAddressFamily::IP_V4;
case net::ADDRESS_FAMILY_IPV6:
return IpAddressFamily::IP_V6;
case net::ADDRESS_FAMILY_UNSPECIFIED:
break;
default:
QUIC_BUG << "Invalid address family "
<< net::GetAddressFamily(ip_address_);
}
return IpAddressFamily::IP_UNSPEC;
}
#if !defined(STARBOARD)
int QuicIpAddressImpl::AddressFamilyToInt() const {
switch (ip_address_.size()) {
case net::IPAddress::kIPv4AddressSize:
return AF_INET;
case net::IPAddress::kIPv6AddressSize:
return AF_INET6;
default:
NOTREACHED() << "Bad IP address";
return AF_UNSPEC;
}
}
#endif
string QuicIpAddressImpl::ToPackedString() const {
return net::IPAddressToPackedString(ip_address_);
}
string QuicIpAddressImpl::ToString() const {
if (!IsInitialized()) {
return "Uninitialized address";
}
return ip_address_.ToString();
}
QuicIpAddressImpl QuicIpAddressImpl::Normalized() const {
if (ip_address_.IsIPv4MappedIPv6()) {
return QuicIpAddressImpl(ConvertIPv4MappedIPv6ToIPv4(ip_address_));
}
return QuicIpAddressImpl(ip_address_);
}
QuicIpAddressImpl QuicIpAddressImpl::DualStacked() const {
if (ip_address_.IsIPv4()) {
return QuicIpAddressImpl(ConvertIPv4ToIPv4MappedIPv6(ip_address_));
}
return QuicIpAddressImpl(ip_address_);
}
bool QuicIpAddressImpl::FromPackedString(const char* data, size_t length) {
if (length != net::IPAddress::kIPv4AddressSize &&
length != net::IPAddress::kIPv6AddressSize) {
QUIC_BUG << "Invalid packed IP address of length " << length;
return false;
}
ip_address_ = net::IPAddress(reinterpret_cast<const uint8_t*>(data), length);
return true;
}
bool QuicIpAddressImpl::FromString(string str) {
return ip_address_.AssignFromIPLiteral(str);
}
bool QuicIpAddressImpl::IsIPv4() const {
return ip_address_.IsIPv4();
}
bool QuicIpAddressImpl::IsIPv6() const {
return ip_address_.IsIPv6();
}
bool QuicIpAddressImpl::InSameSubnet(const QuicIpAddressImpl& other,
int subnet_length) {
return net::IPAddressMatchesPrefix(ip_address_, other.ip_address(),
subnet_length);
}
} // namespace quic