shill: connection: Fix IP address comparison in FixGatewayReachability
CL:247030 inadvertently broke IP address comparison for
Connection::FixGatewayReachability, since now the |trusted_ip|
contains a prefix while the |peer| and |gateway| still do not.
To solve this, add a new comparison method for IPAddress objects
that does not consider the prefix, and use this for address
comparisons in Connection::FixGatewayReachability.
BUG=chromium:478267
TEST=Unit test + create an ipvanish account and connect
Change-Id: Id30e0cd15bb0171c7f438cf1e7f0087c75d55611
Originally-Reviewed-on: https://chromium-review.googlesource.com/268970
(cherry picked from commit 08e9305b5ffaccd5885f871d76a17b33dbcc474b)
Reviewed-on: https://chromium-review.googlesource.com/269164
Reviewed-by: Paul Stewart <pstew@chromium.org>
Commit-Queue: Paul Stewart <pstew@chromium.org>
Tested-by: Paul Stewart <pstew@chromium.org>
diff --git a/shill/connection.cc b/shill/connection.cc
index d6529ae..add970e 100644
--- a/shill/connection.cc
+++ b/shill/connection.cc
@@ -32,6 +32,8 @@
namespace Logging {
static auto kModuleLogScope = ScopeLogger::kConnection;
static string ObjectID(Connection *c) {
+ if (c == nullptr)
+ return "(connection)";
return c->interface_name();
}
}
@@ -395,20 +397,25 @@
IPAddress *peer,
IPAddress *gateway,
const IPAddress &trusted_ip) {
+ SLOG(nullptr, 2) << __func__
+ << " local " << local->ToString()
+ << ", peer " << peer->ToString()
+ << ", gateway " << gateway->ToString()
+ << ", trusted_ip " << trusted_ip.ToString();
if (!gateway->IsValid()) {
LOG(WARNING) << "No gateway address was provided for this connection.";
return false;
}
if (peer->IsValid()) {
- if (!gateway->Equals(*peer)) {
+ if (!gateway->HasSameAddressAs(*peer)) {
LOG(WARNING) << "Gateway address "
<< gateway->ToString()
<< " does not match peer address "
<< peer->ToString();
return false;
}
- if (gateway->Equals(trusted_ip)) {
+ if (gateway->HasSameAddressAs(trusted_ip)) {
// In order to send outgoing traffic in a point-to-point network,
// the gateway IP address isn't of significance. As opposed to
// broadcast networks, we never ARP for the gateway IP address,
diff --git a/shill/connection_unittest.cc b/shill/connection_unittest.cc
index f163f9a..506f9c9 100644
--- a/shill/connection_unittest.cc
+++ b/shill/connection_unittest.cc
@@ -867,7 +867,8 @@
// should be modified to allow routing to work correctly.
ASSERT_TRUE(gateway.SetAddressFromString(kUnreachableGateway));
ASSERT_TRUE(peer.SetAddressFromString(kUnreachableGateway));
- ASSERT_TRUE(trusted_ip.SetAddressFromString(kUnreachableGateway));
+ ASSERT_TRUE(trusted_ip.SetAddressAndPrefixFromString(
+ string(kUnreachableGateway) + "/32"));
EXPECT_TRUE(Connection::FixGatewayReachability(
&local, &peer, &gateway, trusted_ip));
EXPECT_TRUE(peer.IsDefault());
diff --git a/shill/net/ip_address.cc b/shill/net/ip_address.cc
index 035daa0..f5ff240 100644
--- a/shill/net/ip_address.cc
+++ b/shill/net/ip_address.cc
@@ -222,6 +222,15 @@
return out;
}
+bool IPAddress::Equals(const IPAddress &b) const {
+ return family_ == b.family_ && address_.Equals(b.address_) &&
+ prefix_ == b.prefix_;
+}
+
+bool IPAddress::HasSameAddressAs(const IPAddress &b) const {
+ return family_ == b.family_ && address_.Equals(b.address_);
+}
+
IPAddress IPAddress::MaskWith(const IPAddress &b) const {
CHECK(IsValid());
CHECK(b.IsValid());
diff --git a/shill/net/ip_address.h b/shill/net/ip_address.h
index 927544a..464902f 100644
--- a/shill/net/ip_address.h
+++ b/shill/net/ip_address.h
@@ -102,10 +102,11 @@
// Similar to IntoString, but returns by value. Convenient for logging.
std::string ToString() const;
- bool Equals(const IPAddress &b) const {
- return family_ == b.family_ && address_.Equals(b.address_) &&
- prefix_ == b.prefix_;
- }
+ // Returns whether |b| has the same family, address and prefix as |this|.
+ bool Equals(const IPAddress &b) const;
+
+ // Returns whether |b| has the same family and address as |this|.
+ bool HasSameAddressAs(const IPAddress &b) const;
// Perform an AND operation between the address data of |this| and that
// of |b|. Returns an IPAddress containing the result of the operation.
diff --git a/shill/net/ip_address_unittest.cc b/shill/net/ip_address_unittest.cc
index bc6f75e..234e609 100644
--- a/shill/net/ip_address_unittest.cc
+++ b/shill/net/ip_address_unittest.cc
@@ -147,6 +147,21 @@
EXPECT_TRUE(kAddress1.Equals(address.address()));
}
+TEST_F(IPAddressTest, HasSameAddressAs) {
+ const string kString1(kV4String1);
+ IPAddress address0(IPAddress::kFamilyIPv4);
+ EXPECT_TRUE(address0.SetAddressAndPrefixFromString(kString1 + "/0"));
+ IPAddress address1(IPAddress::kFamilyIPv4);
+ EXPECT_TRUE(address1.SetAddressAndPrefixFromString(kString1 + "/10"));
+ IPAddress address2(IPAddress::kFamilyIPv4);
+ EXPECT_TRUE(address2.SetAddressAndPrefixFromString(kString1 + "/0"));
+
+ EXPECT_FALSE(address0.Equals(address1));
+ EXPECT_TRUE(address0.Equals(address2));
+ EXPECT_TRUE(address0.HasSameAddressAs(address1));
+ EXPECT_TRUE(address0.HasSameAddressAs(address2));
+}
+
struct PrefixMapping {
PrefixMapping() : family(IPAddress::kFamilyUnknown), prefix(0) {}
PrefixMapping(IPAddress::Family family_in,