summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormartijn <martijn@martijnc.be>2016-03-20 13:22:09 -0700
committerCommit bot <commit-bot@chromium.org>2016-03-20 20:24:35 +0000
commit579658b7b5e5ef315ad4513574c669fc5363ea9d (patch)
tree74d50e5030d928328b1c3e90dec66a9147181ec8
parent43f18e9e7c90f40d6306f720791f60c1a09165dc (diff)
downloadchromium_src-579658b7b5e5ef315ad4513574c669fc5363ea9d.zip
chromium_src-579658b7b5e5ef315ad4513574c669fc5363ea9d.tar.gz
chromium_src-579658b7b5e5ef315ad4513574c669fc5363ea9d.tar.bz2
Migrate net/proxy/* to net::IPAddress.
This CL also moves the ParseCIDRBlock() implementation to ip_address.h. BUG=496258 Review URL: https://codereview.chromium.org/1810183002 Cr-Commit-Position: refs/heads/master@{#382225}
-rw-r--r--net/base/ip_address.cc33
-rw-r--r--net/base/ip_address.h14
-rw-r--r--net/base/ip_address_number.cc30
-rw-r--r--net/base/ip_address_number.h14
-rw-r--r--net/base/ip_address_number_unittest.cc120
-rw-r--r--net/base/ip_address_unittest.cc44
-rw-r--r--net/proxy/proxy_bypass_rules.cc19
-rw-r--r--net/proxy/proxy_resolver_v8.cc55
8 files changed, 149 insertions, 180 deletions
diff --git a/net/base/ip_address.cc b/net/base/ip_address.cc
index 606483b..42071e0 100644
--- a/net/base/ip_address.cc
+++ b/net/base/ip_address.cc
@@ -4,6 +4,9 @@
#include "net/base/ip_address.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_piece.h"
+#include "base/strings/string_split.h"
#include "net/base/ip_address_number.h"
#include "url/gurl.h"
#include "url/url_canon_ip.h"
@@ -139,6 +142,36 @@ bool IPAddressMatchesPrefix(const IPAddress& ip_address,
prefix_length_in_bits);
}
+bool ParseCIDRBlock(const std::string& cidr_literal,
+ IPAddress* ip_address,
+ size_t* prefix_length_in_bits) {
+ // We expect CIDR notation to match one of these two templates:
+ // <IPv4-literal> "/" <number of bits>
+ // <IPv6-literal> "/" <number of bits>
+
+ std::vector<base::StringPiece> parts = base::SplitStringPiece(
+ cidr_literal, "/", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
+ if (parts.size() != 2)
+ return false;
+
+ // Parse the IP address.
+ if (!ip_address->AssignFromIPLiteral(parts[0]))
+ return false;
+
+ // Parse the prefix length.
+ int number_of_bits = -1;
+ if (!base::StringToInt(parts[1], &number_of_bits))
+ return false;
+
+ // Make sure the prefix length is in a valid range.
+ if (number_of_bits < 0 ||
+ number_of_bits > static_cast<int>(ip_address->size() * 8))
+ return false;
+
+ *prefix_length_in_bits = static_cast<size_t>(number_of_bits);
+ return true;
+}
+
unsigned CommonPrefixLength(const IPAddress& a1, const IPAddress& a2) {
return CommonPrefixLength(a1.bytes(), a2.bytes());
}
diff --git a/net/base/ip_address.h b/net/base/ip_address.h
index f1f244e..91ce071 100644
--- a/net/base/ip_address.h
+++ b/net/base/ip_address.h
@@ -149,6 +149,20 @@ NET_EXPORT bool IPAddressMatchesPrefix(const IPAddress& ip_address,
const IPAddress& ip_prefix,
size_t prefix_length_in_bits);
+// Parses an IP block specifier from CIDR notation to an
+// (IP address, prefix length) pair. Returns true on success and fills
+// |*ip_address| with the numeric value of the IP address and sets
+// |*prefix_length_in_bits| with the length of the prefix.
+//
+// CIDR notation literals can use either IPv4 or IPv6 literals. Some examples:
+//
+// 10.10.3.1/20
+// a:b:c::/46
+// ::1/128
+NET_EXPORT bool ParseCIDRBlock(const std::string& cidr_literal,
+ IPAddress* ip_address,
+ size_t* prefix_length_in_bits);
+
// Returns number of matching initial bits between the addresses |a1| and |a2|.
unsigned CommonPrefixLength(const IPAddress& a1, const IPAddress& a2);
diff --git a/net/base/ip_address_number.cc b/net/base/ip_address_number.cc
index 80cd7e9..1c3090d 100644
--- a/net/base/ip_address_number.cc
+++ b/net/base/ip_address_number.cc
@@ -218,36 +218,6 @@ IPAddressNumber ConvertIPv4MappedToIPv4(const IPAddressNumber& address) {
address.end());
}
-bool ParseCIDRBlock(const std::string& cidr_literal,
- IPAddressNumber* ip_number,
- size_t* prefix_length_in_bits) {
- // We expect CIDR notation to match one of these two templates:
- // <IPv4-literal> "/" <number of bits>
- // <IPv6-literal> "/" <number of bits>
-
- std::vector<base::StringPiece> parts = base::SplitStringPiece(
- cidr_literal, "/", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
- if (parts.size() != 2)
- return false;
-
- // Parse the IP address.
- if (!ParseIPLiteralToNumber(parts[0], ip_number))
- return false;
-
- // Parse the prefix length.
- int number_of_bits = -1;
- if (!base::StringToInt(parts[1], &number_of_bits))
- return false;
-
- // Make sure the prefix length is in a valid range.
- if (number_of_bits < 0 ||
- number_of_bits > static_cast<int>(ip_number->size() * 8))
- return false;
-
- *prefix_length_in_bits = static_cast<size_t>(number_of_bits);
- return true;
-}
-
bool IPNumberMatchesPrefix(const IPAddressNumber& ip_number,
const IPAddressNumber& ip_prefix,
size_t prefix_length_in_bits) {
diff --git a/net/base/ip_address_number.h b/net/base/ip_address_number.h
index 80c524c..1f7a1e7 100644
--- a/net/base/ip_address_number.h
+++ b/net/base/ip_address_number.h
@@ -81,20 +81,6 @@ NET_EXPORT_PRIVATE bool IsIPv4Mapped(const IPAddressNumber& address);
NET_EXPORT_PRIVATE IPAddressNumber ConvertIPv4MappedToIPv4(
const IPAddressNumber& address);
-// Parses an IP block specifier from CIDR notation to an
-// (IP address, prefix length) pair. Returns true on success and fills
-// |*ip_number| with the numeric value of the IP address and sets
-// |*prefix_length_in_bits| with the length of the prefix.
-//
-// CIDR notation literals can use either IPv4 or IPv6 literals. Some examples:
-//
-// 10.10.3.1/20
-// a:b:c::/46
-// ::1/128
-NET_EXPORT bool ParseCIDRBlock(const std::string& cidr_literal,
- IPAddressNumber* ip_number,
- size_t* prefix_length_in_bits);
-
// Compares an IP address to see if it falls within the specified IP block.
// Returns true if it does, false otherwise.
//
diff --git a/net/base/ip_address_number_unittest.cc b/net/base/ip_address_number_unittest.cc
index 67d9f31..a0365f4 100644
--- a/net/base/ip_address_number_unittest.cc
+++ b/net/base/ip_address_number_unittest.cc
@@ -146,105 +146,29 @@ TEST(IpAddressNumberTest, ConvertIPv4MappedToIPv4) {
EXPECT_EQ(expected, result);
}
-// Test parsing invalid CIDR notation literals.
-TEST(IpAddressNumberTest, ParseCIDRBlock_Invalid) {
- const char* const bad_literals[] = {
- "foobar",
- "",
- "192.168.0.1",
- "::1",
- "/",
- "/1",
- "1",
- "192.168.1.1/-1",
- "192.168.1.1/33",
- "::1/-3",
- "a::3/129",
- "::1/x",
- "192.168.0.1//11"
- };
-
- for (size_t i = 0; i < arraysize(bad_literals); ++i) {
- IPAddressNumber ip_number;
- size_t prefix_length_in_bits;
-
- EXPECT_FALSE(ParseCIDRBlock(bad_literals[i],
- &ip_number,
- &prefix_length_in_bits));
- }
-}
-
-// Test parsing a valid CIDR notation literal.
-TEST(IpAddressNumberTest, ParseCIDRBlock_Valid) {
- IPAddressNumber ip_number;
- size_t prefix_length_in_bits;
-
- EXPECT_TRUE(ParseCIDRBlock("192.168.0.1/11",
- &ip_number,
- &prefix_length_in_bits));
-
- EXPECT_EQ("192,168,0,1", DumpIPNumber(ip_number));
- EXPECT_EQ(11u, prefix_length_in_bits);
-}
-
TEST(IpAddressNumberTest, IPNumberMatchesPrefix) {
struct {
const char* const cidr_literal;
+ size_t prefix_length_in_bits;
const char* const ip_literal;
bool expected_to_match;
} tests[] = {
- // IPv4 prefix with IPv4 inputs.
- {
- "10.10.1.32/27",
- "10.10.1.44",
- true
- },
- {
- "10.10.1.32/27",
- "10.10.1.90",
- false
- },
- {
- "10.10.1.32/27",
- "10.10.1.90",
- false
- },
-
- // IPv6 prefix with IPv6 inputs.
- {
- "2001:db8::/32",
- "2001:DB8:3:4::5",
- true
- },
- {
- "2001:db8::/32",
- "2001:c8::",
- false
- },
-
- // IPv6 prefix with IPv4 inputs.
- {
- "2001:db8::/33",
- "192.168.0.1",
- false
- },
- {
- "::ffff:192.168.0.1/112",
- "192.168.33.77",
- true
- },
-
- // IPv4 prefix with IPv6 inputs.
- {
- "10.11.33.44/16",
- "::ffff:0a0b:89",
- true
- },
- {
- "10.11.33.44/16",
- "::ffff:10.12.33.44",
- false
- },
+ // IPv4 prefix with IPv4 inputs.
+ {"10.10.1.32", 27, "10.10.1.44", true},
+ {"10.10.1.32", 27, "10.10.1.90", false},
+ {"10.10.1.32", 27, "10.10.1.90", false},
+
+ // IPv6 prefix with IPv6 inputs.
+ {"2001:db8::", 32, "2001:DB8:3:4::5", true},
+ {"2001:db8::", 32, "2001:c8::", false},
+
+ // IPv6 prefix with IPv4 inputs.
+ {"2001:db8::", 33, "192.168.0.1", false},
+ {"::ffff:192.168.0.1", 112, "192.168.33.77", true},
+
+ // IPv4 prefix with IPv6 inputs.
+ {"10.11.33.44", 16, "::ffff:0a0b:89", true},
+ {"10.11.33.44", 16, "::ffff:10.12.33.44", false},
};
for (size_t i = 0; i < arraysize(tests); ++i) {
SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]: %s, %s", i,
@@ -255,16 +179,12 @@ TEST(IpAddressNumberTest, IPNumberMatchesPrefix) {
EXPECT_TRUE(ParseIPLiteralToNumber(tests[i].ip_literal, &ip_number));
IPAddressNumber ip_prefix;
- size_t prefix_length_in_bits;
- EXPECT_TRUE(ParseCIDRBlock(tests[i].cidr_literal,
- &ip_prefix,
- &prefix_length_in_bits));
+ EXPECT_TRUE(ParseIPLiteralToNumber(tests[i].cidr_literal, &ip_prefix));
EXPECT_EQ(tests[i].expected_to_match,
- IPNumberMatchesPrefix(ip_number,
- ip_prefix,
- prefix_length_in_bits));
+ IPNumberMatchesPrefix(ip_number, ip_prefix,
+ tests[i].prefix_length_in_bits));
}
}
diff --git a/net/base/ip_address_unittest.cc b/net/base/ip_address_unittest.cc
index 2863c6b..d78f6c3 100644
--- a/net/base/ip_address_unittest.cc
+++ b/net/base/ip_address_unittest.cc
@@ -238,6 +238,50 @@ TEST(IPAddressTest, ConvertIPv4MappedIPv6ToIPv4) {
EXPECT_EQ(expected, result);
}
+// Test parsing invalid CIDR notation literals.
+TEST(IPAddressTest, ParseCIDRBlock_Invalid) {
+ const char* const bad_literals[] = {"foobar",
+ "",
+ "192.168.0.1",
+ "::1",
+ "/",
+ "/1",
+ "1",
+ "192.168.1.1/-1",
+ "192.168.1.1/33",
+ "::1/-3",
+ "a::3/129",
+ "::1/x",
+ "192.168.0.1//11"};
+
+ for (const auto& bad_literal : bad_literals) {
+ IPAddress ip_address;
+ size_t prefix_length_in_bits;
+
+ EXPECT_FALSE(
+ ParseCIDRBlock(bad_literal, &ip_address, &prefix_length_in_bits));
+ }
+}
+
+// Test parsing a valid CIDR notation literal.
+TEST(IPAddressTest, ParseCIDRBlock_Valid) {
+ IPAddress ip_address;
+ size_t prefix_length_in_bits;
+
+ EXPECT_TRUE(
+ ParseCIDRBlock("192.168.0.1/11", &ip_address, &prefix_length_in_bits));
+
+ EXPECT_EQ("192,168,0,1", DumpIPAddress(ip_address));
+ EXPECT_EQ(11u, prefix_length_in_bits);
+
+ EXPECT_TRUE(ParseCIDRBlock("::ffff:192.168.0.1/112", &ip_address,
+ &prefix_length_in_bits));
+
+ EXPECT_EQ("0,0,0,0,0,0,0,0,0,0,255,255,192,168,0,1",
+ DumpIPAddress(ip_address));
+ EXPECT_EQ(112u, prefix_length_in_bits);
+}
+
TEST(IPAddressTest, IPAddressStartsWith) {
IPAddress ipv4_address(192, 168, 10, 5);
diff --git a/net/proxy/proxy_bypass_rules.cc b/net/proxy/proxy_bypass_rules.cc
index e74d9e6..64a23c9 100644
--- a/net/proxy/proxy_bypass_rules.cc
+++ b/net/proxy/proxy_bypass_rules.cc
@@ -12,7 +12,7 @@
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "net/base/host_port_pair.h"
-#include "net/base/ip_address_number.h"
+#include "net/base/ip_address.h"
#include "net/base/url_util.h"
namespace net {
@@ -84,13 +84,12 @@ class BypassIPBlockRule : public ProxyBypassRules::Rule {
// |ip_prefix| + |prefix_length| define the IP block to match.
BypassIPBlockRule(const std::string& description,
const std::string& optional_scheme,
- const IPAddressNumber& ip_prefix,
+ const IPAddress& ip_prefix,
size_t prefix_length_in_bits)
: description_(description),
optional_scheme_(optional_scheme),
ip_prefix_(ip_prefix),
- prefix_length_in_bits_(prefix_length_in_bits) {
- }
+ prefix_length_in_bits_(prefix_length_in_bits) {}
bool Matches(const GURL& url) const override {
if (!url.HostIsIPAddress())
@@ -100,13 +99,13 @@ class BypassIPBlockRule : public ProxyBypassRules::Rule {
return false; // Didn't match scheme expectation.
// Parse the input IP literal to a number.
- IPAddressNumber ip_number;
- if (!ParseIPLiteralToNumber(url.HostNoBrackets(), &ip_number))
+ IPAddress ip_address;
+ if (!ip_address.AssignFromIPLiteral(url.HostNoBrackets()))
return false;
// Test if it has the expected prefix.
- return IPNumberMatchesPrefix(ip_number, ip_prefix_,
- prefix_length_in_bits_);
+ return IPAddressMatchesPrefix(ip_address, ip_prefix_,
+ prefix_length_in_bits_);
}
std::string ToString() const override { return description_; }
@@ -121,7 +120,7 @@ class BypassIPBlockRule : public ProxyBypassRules::Rule {
private:
const std::string description_;
const std::string optional_scheme_;
- const IPAddressNumber ip_prefix_;
+ const IPAddress ip_prefix_;
const size_t prefix_length_in_bits_;
};
@@ -284,7 +283,7 @@ bool ProxyBypassRules::AddRuleFromStringInternal(
// If there is a forward slash in the input, it is probably a CIDR style
// mask.
if (raw.find('/') != std::string::npos) {
- IPAddressNumber ip_prefix;
+ IPAddress ip_prefix;
size_t prefix_length_in_bits;
if (!ParseCIDRBlock(raw, &ip_prefix, &prefix_length_in_bits))
diff --git a/net/proxy/proxy_resolver_v8.cc b/net/proxy/proxy_resolver_v8.cc
index 80ae06b..a0c9717 100644
--- a/net/proxy/proxy_resolver_v8.cc
+++ b/net/proxy/proxy_resolver_v8.cc
@@ -21,7 +21,7 @@
#include "gin/array_buffer.h"
#include "gin/public/isolate_holder.h"
#include "gin/v8_initializer.h"
-#include "net/base/ip_address_number.h"
+#include "net/base/ip_address.h"
#include "net/base/net_errors.h"
#include "net/proxy/proxy_info.h"
#include "net/proxy/proxy_resolver_script.h"
@@ -244,26 +244,29 @@ bool GetHostnameArgument(const v8::FunctionCallbackInfo<v8::Value>& args,
return success;
}
-// Wrapper for passing around IP address strings and IPAddressNumber objects.
-struct IPAddress {
- IPAddress(const std::string& ip_string, const IPAddressNumber& ip_number)
- : string_value(ip_string),
- ip_address_number(ip_number) {
- }
+// Wrapper around an IP address that stores the original string as well as a
+// corresponding parsed IPAddress.
+
+// This struct is used as a helper for sorting IP address strings - the IP
+// literal is parsed just once and used as the sorting key, while also
+// preserving the original IP literal string.
+struct IPAddressSortingEntry {
+ IPAddressSortingEntry(const std::string& ip_string,
+ const IPAddress& ip_address)
+ : string_value(ip_string), ip_address(ip_address) {}
// Used for sorting IP addresses in ascending order in SortIpAddressList().
- // IP6 addresses are placed ahead of IPv4 addresses.
- bool operator<(const IPAddress& rhs) const {
- const IPAddressNumber& ip1 = this->ip_address_number;
- const IPAddressNumber& ip2 = rhs.ip_address_number;
+ // IPv6 addresses are placed ahead of IPv4 addresses.
+ bool operator<(const IPAddressSortingEntry& rhs) const {
+ const IPAddress& ip1 = this->ip_address;
+ const IPAddress& ip2 = rhs.ip_address;
if (ip1.size() != ip2.size())
return ip1.size() > ip2.size(); // IPv6 before IPv4.
- DCHECK(ip1.size() == ip2.size());
- return memcmp(&ip1[0], &ip2[0], ip1.size()) < 0; // Ascending order.
+ return ip1 < ip2; // Ascending order.
}
std::string string_value;
- IPAddressNumber ip_address_number;
+ IPAddress ip_address;
};
// Handler for "sortIpAddressList(IpAddressList)". |ip_address_list| is a
@@ -284,13 +287,13 @@ bool SortIpAddressList(const std::string& ip_address_list,
return false;
// Split-up IP addresses and store them in a vector.
- std::vector<IPAddress> ip_vector;
- IPAddressNumber ip_num;
+ std::vector<IPAddressSortingEntry> ip_vector;
+ IPAddress ip_address;
base::StringTokenizer str_tok(cleaned_ip_address_list, ";");
while (str_tok.GetNext()) {
- if (!ParseIPLiteralToNumber(str_tok.token(), &ip_num))
+ if (!ip_address.AssignFromIPLiteral(str_tok.token()))
return false;
- ip_vector.push_back(IPAddress(str_tok.token(), ip_num));
+ ip_vector.push_back(IPAddressSortingEntry(str_tok.token(), ip_address));
}
if (ip_vector.empty()) // Can happen if we have something like
@@ -320,11 +323,11 @@ bool SortIpAddressList(const std::string& ip_address_list,
// format, or if an address and prefix of different types are used (e.g. IPv6
// address and IPv4 prefix).
bool IsInNetEx(const std::string& ip_address, const std::string& ip_prefix) {
- IPAddressNumber address;
- if (!ParseIPLiteralToNumber(ip_address, &address))
+ IPAddress address;
+ if (!address.AssignFromIPLiteral(ip_address))
return false;
- IPAddressNumber prefix;
+ IPAddress prefix;
size_t prefix_length_in_bits;
if (!ParseCIDRBlock(ip_prefix, &prefix, &prefix_length_in_bits))
return false;
@@ -333,10 +336,10 @@ bool IsInNetEx(const std::string& ip_address, const std::string& ip_prefix) {
if (address.size() != prefix.size())
return false;
- DCHECK((address.size() == 4 && prefix.size() == 4) ||
- (address.size() == 16 && prefix.size() == 16));
+ DCHECK((address.IsIPv4() && prefix.IsIPv4()) ||
+ (address.IsIPv6() && prefix.IsIPv6()));
- return IPNumberMatchesPrefix(address, prefix, prefix_length_in_bits);
+ return IPAddressMatchesPrefix(address, prefix, prefix_length_in_bits);
}
// Consider only single component domains like 'foo' as plain host names.
@@ -346,8 +349,8 @@ bool IsPlainHostName(const std::string& hostname_utf8) {
// IPv6 literals might not contain any periods, however are not considered
// plain host names.
- IPAddressNumber unused;
- return !ParseIPLiteralToNumber(hostname_utf8, &unused);
+ IPAddress unused;
+ return !unused.AssignFromIPLiteral(hostname_utf8);
}
// All instances of ProxyResolverV8 share the same v8::Isolate. This isolate is