You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by ji...@apache.org on 2014/06/06 20:40:19 UTC

[1/2] git commit: Allowed net::IP to be created from a dot decimal string.

Repository: mesos
Updated Branches:
  refs/heads/master 3541b8194 -> 559ea1114


Allowed net::IP to be created from a dot decimal string.

Review: https://reviews.apache.org/r/22294


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/6904de9e
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/6904de9e
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/6904de9e

Branch: refs/heads/master
Commit: 6904de9e55b8feb25adc50a01d5a9ba16cda35ea
Parents: 3541b81
Author: Jie Yu <yu...@gmail.com>
Authored: Thu Jun 5 17:07:11 2014 -0700
Committer: Jie Yu <yu...@gmail.com>
Committed: Fri Jun 6 11:38:15 2014 -0700

----------------------------------------------------------------------
 .../3rdparty/stout/include/stout/net.hpp        | 89 ++++++++++++++++++--
 .../3rdparty/stout/tests/net_tests.cpp          | 38 ++++++++-
 2 files changed, 116 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/6904de9e/3rdparty/libprocess/3rdparty/stout/include/stout/net.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/net.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/net.hpp
index 97a09a1..97215af 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/net.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/net.hpp
@@ -54,6 +54,7 @@
 #include "os.hpp"
 #include "result.hpp"
 #include "stringify.hpp"
+#include "strings.hpp"
 #include "try.hpp"
 
 
@@ -309,14 +310,25 @@ inline Result<MAC> mac(const std::string& name)
 class IP
 {
 public:
-  // Constructs an IP from the given IP address (in host order).
+  // Creates an IP from the given string that has the dot-decimal
+  // format (with or without subnet prefix). For example:
+  //   10.0.0.1/8
+  //   192.168.1.100/24
+  //   172.158.1.23
+  static Try<IP> fromDotDecimal(const std::string& value);
+
+  // Creates an IP from the given IP address (in host order) and the
+  // given netmask (in host order). Returns error if the netmask is
+  // not valid (e.g., not contiguous).
+  static Try<IP> fromAddressNetmask(uint32_t address, uint32_t netmask);
+
+  // Creates an IP from a 32-bit address (in host order) and a subnet
+  // prefix (within [0,32]). Returns error if the prefix is not valid.
+  static Try<IP> fromAddressPrefix(uint32_t address, size_t prefix);
+
+  // Constructs an IP with the given IP address (in host order).
   explicit IP(uint32_t _address) : address_(_address) {}
 
-  // Constructs an IP from the given IP address and the given netmask
-  // (all in host order).
-  IP(uint32_t _address, uint32_t _netmask)
-    : address_(_address), netmask_(_netmask) {}
-
   // Returns the IP address (in host order).
   uint32_t address() const { return address_; }
 
@@ -334,7 +346,7 @@ public:
 
     size_t value = 0;
     while (mask != 0) {
-      value += mask & 0x1;
+      value += mask & 1;
       mask >>= 1;
     }
 
@@ -352,6 +364,11 @@ public:
   }
 
 private:
+  // Constructs an IP with the given IP address (in host order) and
+  // the given netmask (in host order).
+  IP(uint32_t _address, uint32_t _netmask)
+    : address_(_address), netmask_(_netmask) {}
+
   // IP address (in host order).
   uint32_t address_;
 
@@ -360,6 +377,53 @@ private:
 };
 
 
+inline Try<IP> IP::fromDotDecimal(const std::string& value)
+{
+  std::vector<std::string> tokens = strings::split(value, "/");
+
+  if (tokens.size() > 2) {
+    return Error("More than one '/' detected");
+  }
+
+  struct in_addr in;
+  if (inet_aton(tokens[0].c_str(), &in) == 0) {
+    return Error("Failed to parse the IP address");
+  }
+
+  // Parse the subnet prefix if specified.
+  if (tokens.size() == 2) {
+    Try<size_t> prefix = numify<size_t>(tokens[1]);
+    if (prefix.isError()) {
+      return Error("Subnet prefix is not a number");
+    }
+
+    return fromAddressPrefix(ntohl(in.s_addr), prefix.get());
+  }
+
+  return IP(ntohl(in.s_addr));
+}
+
+
+inline Try<IP> IP::fromAddressNetmask(uint32_t address, uint32_t netmask)
+{
+  if (((~netmask + 1) & (~netmask)) != 0) {
+    return Error("Netmask is not valid");
+  }
+
+  return IP(address, netmask);
+}
+
+
+inline Try<IP> IP::fromAddressPrefix(uint32_t address, size_t prefix)
+{
+  if (prefix > 32) {
+    return Error("Subnet prefix is larger than 32");
+  }
+
+  return IP(address, (0xffffffff << (32 - prefix)));
+}
+
+
 // Returns the string representation of the given IP address using the
 // canonical dot-decimal form with prefix. For example: "10.0.0.1/8".
 inline std::ostream& operator << (std::ostream& stream, const IP& ip)
@@ -421,10 +485,17 @@ inline Result<IP> ip(const std::string& name)
             ifa->ifa_netmask->sa_family == AF_INET) {
           struct sockaddr_in* netmask = (struct sockaddr_in*) ifa->ifa_netmask;
 
-          IP ip(ntohl(addr->sin_addr.s_addr), ntohl(netmask->sin_addr.s_addr));
+          Try<IP> ip = IP::fromAddressNetmask(
+              ntohl(addr->sin_addr.s_addr),
+              ntohl(netmask->sin_addr.s_addr));
 
           freeifaddrs(ifaddr);
-          return ip;
+
+          if (ip.isError()) {
+            return Error(ip.error());
+          }
+
+          return ip.get();
         }
 
         // Note that this is the case where net mask is not specified.

http://git-wip-us.apache.org/repos/asf/mesos/blob/6904de9e/3rdparty/libprocess/3rdparty/stout/tests/net_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/tests/net_tests.cpp b/3rdparty/libprocess/3rdparty/stout/tests/net_tests.cpp
index 988b18f..425132e 100644
--- a/3rdparty/libprocess/3rdparty/stout/tests/net_tests.cpp
+++ b/3rdparty/libprocess/3rdparty/stout/tests/net_tests.cpp
@@ -94,9 +94,43 @@ TEST(NetTest, ip)
 
 TEST(NetTest, ConstructIP)
 {
+  EXPECT_SOME(net::IP::fromDotDecimal("127.0.0.1"));
+  EXPECT_SOME(net::IP::fromDotDecimal("10.135.0.1/8"));
+  EXPECT_SOME(net::IP::fromDotDecimal("192.168.1.1/16"));
+  EXPECT_SOME(net::IP::fromDotDecimal("01.02.03.04"));
+  EXPECT_SOME(net::IP::fromDotDecimal("172.39.13.123/31"));
+
+  EXPECT_ERROR(net::IP::fromDotDecimal("123.1.1.2//23"));
+  EXPECT_ERROR(net::IP::fromDotDecimal("121.2.3.5/23/"));
+  EXPECT_ERROR(net::IP::fromDotDecimal("12.32.3.5/123"));
+  EXPECT_ERROR(net::IP::fromDotDecimal("12.32.3.a/16"));
+  EXPECT_ERROR(net::IP::fromDotDecimal("hello world"));
+  EXPECT_ERROR(net::IP::fromDotDecimal("hello moto/8"));
+
+  EXPECT_SOME(net::IP::fromAddressNetmask(0x12345678, 0xffff0000));
+  EXPECT_SOME(net::IP::fromAddressNetmask(0x12345678, 0xf0000000));
+  EXPECT_SOME(net::IP::fromAddressNetmask(0x12345678, 0xffffffff));
+  EXPECT_SOME(net::IP::fromAddressNetmask(0x12345678, 0));
+
+  EXPECT_ERROR(net::IP::fromAddressNetmask(0x087654321, 0xff));
+  EXPECT_ERROR(net::IP::fromAddressNetmask(0x087654321, 0xff00ff00));
+
+  EXPECT_SOME(net::IP::fromAddressPrefix(0x12345678, 16));
+  EXPECT_SOME(net::IP::fromAddressPrefix(0x12345678, 32));
+  EXPECT_SOME(net::IP::fromAddressPrefix(0x12345678, 0));
+
+  EXPECT_ERROR(net::IP::fromAddressPrefix(0x12345678, 123));
+
   uint32_t address = 0x01020304;
   uint32_t netmask = 0xff000000;
 
-  EXPECT_EQ("1.2.3.4", stringify(net::IP(address)));
-  EXPECT_EQ("1.2.3.4/8", stringify(net::IP(address, netmask)));
+  Try<net::IP> ip1 = net::IP::fromAddressNetmask(address, netmask);
+  ASSERT_SOME(ip1);
+  EXPECT_EQ(address, ip1.get().address());
+  EXPECT_SOME_EQ(netmask, ip1.get().netmask());
+  EXPECT_EQ("1.2.3.4/8", stringify(ip1.get()));
+
+  Try<net::IP> ip2 = net::IP::fromDotDecimal(stringify(ip1.get()));
+  ASSERT_SOME(ip2);
+  EXPECT_EQ(ip1.get(), ip2.get());
 }


[2/2] git commit: Used the new net::IP interfaces.

Posted by ji...@apache.org.
Used the new net::IP interfaces.

Review: https://reviews.apache.org/r/22295


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/559ea111
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/559ea111
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/559ea111

Branch: refs/heads/master
Commit: 559ea11140abad92341a3ee45f295c8d8deb70fe
Parents: 6904de9
Author: Jie Yu <yu...@gmail.com>
Authored: Thu Jun 5 17:07:55 2014 -0700
Committer: Jie Yu <yu...@gmail.com>
Committed: Fri Jun 6 11:39:31 2014 -0700

----------------------------------------------------------------------
 src/linux/routing/route.cpp | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/559ea111/src/linux/routing/route.cpp
----------------------------------------------------------------------
diff --git a/src/linux/routing/route.cpp b/src/linux/routing/route.cpp
index 234027e..00d41fa 100644
--- a/src/linux/routing/route.cpp
+++ b/src/linux/routing/route.cpp
@@ -82,11 +82,16 @@ Try<vector<Rule> > table()
       if (dst != NULL && nl_addr_get_len(dst) != 0) {
         struct in_addr* addr = (struct in_addr*) nl_addr_get_binary_addr(dst);
 
-        // Calculate the netmask based on the prefix length.
-        CHECK_GE(32u, nl_addr_get_prefixlen(dst));
-        uint32_t netmask = 0xffffffff << (32 - nl_addr_get_prefixlen(dst));
+        Try<net::IP> ip = net::IP::fromAddressPrefix(
+            ntohl(addr->s_addr),
+            nl_addr_get_prefixlen(dst));
 
-        destination = net::IP(ntohl(addr->s_addr), netmask);
+        if (ip.isError()) {
+          return Error(
+              "Invalid IP format from the routing table: " + ip.error());
+        }
+
+        destination = ip.get();
       }
 
       // Get the default gateway if exists.