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

Unified Diff: net/base/ip_address.cc

Issue 1408803010: Add IPAddress class as a replacement for the IPAddressNumber typedef. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Comments eroman Created 5 years, 1 month 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 side-by-side diff with in-line comments
Download patch
Index: net/base/ip_address.cc
diff --git a/net/base/ip_address.cc b/net/base/ip_address.cc
new file mode 100644
index 0000000000000000000000000000000000000000..16aa7501db144116df5bed02d437adaa689e5cc3
--- /dev/null
+++ b/net/base/ip_address.cc
@@ -0,0 +1,120 @@
+// Copyright (c) 2015 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/ip_address.h"
+
+#include "net/base/ip_address_number.h"
+#include "url/gurl.h"
+#include "url/url_canon_ip.h"
+
+namespace net {
+
+namespace {
+const unsigned char kIPv4MappedPrefix[] = {0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0xFF, 0xFF};
+}
+
+const size_t IPAddress::kIPv4AddressSize = 4;
+const size_t IPAddress::kIPv6AddressSize = 16;
+
+IPAddress::IPAddress() {}
+
+IPAddress::~IPAddress() {}
+
+IPAddress::IPAddress(const uint8_t* address, size_t address_len)
+ : ip_address_(std::vector<uint8_t>(address, address + address_len)) {}
+
+bool IPAddress::IsIPv4() const {
+ return ip_address_.size() == kIPv4AddressSize;
+}
+
+bool IPAddress::IsIPv6() const {
+ return ip_address_.size() == kIPv6AddressSize;
+}
+
+// Don't compare IPv4 and IPv6 addresses (they have different range
+// reservations). Keep separate reservation arrays for each IP type, and
+// consolidate adjacent reserved ranges within a reservation array when
+// possible.
+// Sources for info:
+// www.iana.org/assignments/ipv4-address-space/ipv4-address-space.xhtml
+// www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml
+// They're formatted here with the prefix as the last element. For example:
+// 10.0.0.0/8 becomes 10,0,0,0,8 and fec0::/10 becomes 0xfe,0xc0,0,0,0...,10.
+bool IPAddress::IsReserved() const {
+ return IsIPAddressReserved(ip_address_);
+}
+
+bool IPAddress::IsIPv4Mapped() const {
+ if (!IsIPv6())
+ return false;
+ return std::equal(ip_address_.begin(),
+ ip_address_.begin() + arraysize(kIPv4MappedPrefix),
+ kIPv4MappedPrefix);
+}
+
+std::string IPAddress::ToString() const {
+ std::string str;
+ url::StdStringCanonOutput output(&str);
+
+ if (IsIPv4()) {
+ url::AppendIPv4Address(&ip_address_.front(), &output);
+ } else if (IsIPv6()) {
+ url::AppendIPv6Address(&ip_address_.front(), &output);
+ } else {
+ size_t address_len = ip_address_.size();
eroman 2015/11/30 22:12:33 I suggest removing this temporary variable, and ju
martijnc 2015/12/01 22:09:34 Done.
+ CHECK(false) << "Invalid IP address with length: " << address_len;
+ }
+
+ output.Complete();
+ return str;
+}
+
+// static
+bool IPAddress::FromIPLiteral(const base::StringPiece& ip_literal,
+ IPAddress* ip_address) {
+ std::vector<unsigned char> ip;
+
+ // |ip_literal| could be either a IPv4 or an IPv6 literal. If it contains
+ // a colon however, it must be an IPv6 address.
+ if (ip_literal.find(':') != base::StringPiece::npos) {
+ // GURL expects IPv6 hostnames to be surrounded with brackets.
+ std::string host_brackets = "[";
+ ip_literal.AppendToString(&host_brackets);
+ host_brackets.push_back(']');
+ url::Component host_comp(0, host_brackets.size());
+
+ // Try parsing the hostname as an IPv6 literal.
+ ip.resize(16); // 128 bits.
+ bool result =
+ url::IPv6AddressToNumber(host_brackets.data(), host_comp, &(ip)[0]);
+ ip_address->ip_address_ = ip;
eroman 2015/11/30 22:12:33 (1) only replace ip_address_ on success (2) use st
martijnc 2015/12/01 22:09:34 Done.
+ return result;
+ }
+
+ // Otherwise the string is an IPv4 address.
+ ip.resize(4); // 32 bits.
+ url::Component host_comp(0, ip_literal.size());
+ int num_components;
+ url::CanonHostInfo::Family family = url::IPv4AddressToNumber(
+ ip_literal.data(), host_comp, &(ip)[0], &num_components);
+
+ ip_address->ip_address_ = ip;
eroman 2015/11/30 22:12:33 same thing here.
martijnc 2015/12/01 22:09:34 Done.
+ return family == url::CanonHostInfo::IPV4;
+}
+
+bool IPAddress::operator==(const IPAddress& that) const {
+ return ip_address_ == that.ip_address_;
+}
+
+bool IPAddress::operator<(const IPAddress& that) const {
+ // Sort IPv4 before IPv6.
+ if (ip_address_.size() != that.ip_address_.size()) {
+ return ip_address_.size() < that.ip_address_.size();
+ }
+
+ return ip_address_ < that.ip_address_;
+}
+
+} // namespace net

Powered by Google App Engine
This is Rietveld 408576698