瀏覽代碼

Routing table base class.

Adam Ierymenko 11 年之前
父節點
當前提交
00f9305ad8
共有 3 個文件被更改,包括 127 次插入64 次删除
  1. 112 0
      node/RoutingTable.cpp
  2. 14 64
      node/RoutingTable.hpp
  3. 1 0
      objects.mk

+ 112 - 0
node/RoutingTable.cpp

@@ -0,0 +1,112 @@
+/*
+ * ZeroTier One - Global Peer to Peer Ethernet
+ * Copyright (C) 2011-2014  ZeroTier Networks LLC
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * --
+ *
+ * ZeroTier may be used and distributed under the terms of the GPLv3, which
+ * are available at: http://www.gnu.org/licenses/gpl-3.0.html
+ *
+ * If you would like to embed ZeroTier into a commercial application or
+ * redistribute it in a modified binary form, please contact ZeroTier Networks
+ * LLC. Start here: http://www.zerotier.com/
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "Constants.hpp"
+#include "RoutingTable.hpp"
+#include "Utils.hpp"
+
+namespace ZeroTier {
+
+std::string RoutingTable::Entry::toString() const
+{
+	char tmp[1024];
+	Utils::snprintf(tmp,sizeof(tmp),"%s %s %s %d",destination.toString().c_str(),((gateway) ? gateway.toIpString().c_str() : "(link)"),device,metric);
+	return std::string(tmp);
+}
+
+bool RoutingTable::Entry::operator==(const Entry &re) const
+{
+	return ((destination == re.destination)&&(gateway == re.gateway)&&(strcmp(device,re.device) == 0)&&(metric == re.metric));
+}
+
+bool RoutingTable::Entry::operator<(const Entry &re) const
+{
+	if (destination < re.destination)
+		return true;
+	else if (destination == re.destination) {
+		if (gateway < re.gateway)
+			return true;
+		else if (gateway == re.gateway) {
+			int tmp = (int)::strcmp(device,re.device);
+			if (tmp < 0)
+				return true;
+			else if (tmp == 0)
+				return (metric < re.metric);
+		}
+	}
+	return false;
+}
+
+RoutingTable::RoutingTable()
+{
+}
+
+RoutingTable::~RoutingTable()
+{
+}
+
+uint64_t RoutingTable::networkEnvironmentFingerprint(const std::vector<std::string> &ignoreInterfaces) const
+{
+	uint64_t fp = 0;
+	std::vector<Entry> rtab(get());
+	for(std::vector<Entry>::const_iterator re(rtab.begin());re!=rtab.end();++re) {
+		bool skip = false;
+		for(std::vector<std::string>::const_iterator ii(ignoreInterfaces.begin());ii!=ignoreInterfaces.end();++ii) {
+			if (*ii == re->device) {
+				skip = true;
+				break;
+			}
+		}
+		if (skip)
+			continue;
+		++fp;
+		if (re->destination.isV4()) {
+			fp = Utils::sdbmHash(re->destination.rawIpData(),4,fp);
+			fp = Utils::sdbmHash((uint16_t)re->destination.netmaskBits(),fp);
+		} else if (re->destination.isV6()) {
+			fp = Utils::sdbmHash(re->destination.rawIpData(),16,fp);
+			fp = Utils::sdbmHash((uint16_t)re->destination.netmaskBits(),fp);
+		}
+		if (re->gateway.isV4()) {
+			fp = Utils::sdbmHash(re->gateway.rawIpData(),4,fp);
+			fp = Utils::sdbmHash((uint16_t)re->gateway.netmaskBits(),fp);
+		} else if (re->gateway.isV6()) {
+			fp = Utils::sdbmHash(re->gateway.rawIpData(),16,fp);
+			fp = Utils::sdbmHash((uint16_t)re->gateway.netmaskBits(),fp);
+		}
+		fp = Utils::sdbmHash(re->device,fp);
+		fp = Utils::sdbmHash((uint32_t)re->metric,fp);
+	}
+	return fp;
+}
+
+} // namespace ZeroTier

+ 14 - 64
node/RoutingTable.hpp

@@ -28,16 +28,11 @@
 #ifndef ZT_ROUTINGTABLE_HPP
 #define ZT_ROUTINGTABLE_HPP
 
-#include <stdint.h>
-#include <string.h>
-#include <stdlib.h>
-
 #include <vector>
 #include <string>
 
 #include "InetAddress.hpp"
 #include "NonCopyable.hpp"
-#include "Utils.hpp"
 
 namespace ZeroTier {
 
@@ -53,90 +48,45 @@ public:
 		Entry() { device[0] = (char)0; }
 
 		InetAddress destination;
-		InetAddress gateway;
+		InetAddress gateway; // port/netmaskBits field not used, should be 0
 		char device[128];
 		int metric;
 
-		inline bool operator==(const Entry &re) const { return ((destination == re.destination)&&(gateway == re.gateway)&&(strcmp(device == re.device) == 0)&&(metric == re.metric)); }
+		std::string toString() const;
+
+		bool operator==(const Entry &re) const;
 		inline bool operator!=(const Entry &re) const { return (!(*this == re)); }
-		inline bool operator<(const Entry &re) const
-		{
-			if (destination < re.destination)
-				return true;
-			if (destination == re.destination) {
-				if (gateway < re.gateway)
-					return true;
-				if (gateway == re.gateway) {
-					int tmp = (int)::strcmp(device,re.device);
-					if (tmp < 0)
-						return true;
-					if (tmp == 0)
-						return (metric < re.metric);
-				}
-			}
-			return false;
-		}
+		bool operator<(const Entry &re) const;
 		inline bool operator>(const Entry &re) const { return (re < *this); }
 		inline bool operator<=(const Entry &re) const { return (!(re < *this)); }
 		inline bool operator>=(const Entry &re) const { return (!(*this < re)); }
 	};
 
-	SystemNetworkStack() {}
-	virtual ~SystemNetworkStack() {}
+	RoutingTable();
+	virtual ~RoutingTable();
 
 	/**
-	 * @return All routing table entries sorted in order of destination address / netmask
+	 * @return Sorted routing table entries
 	 */
-	virtual std::vector<Entry> routingTable() const = 0;
+	virtual std::vector<Entry> get() const = 0;
 
 	/**
 	 * Add or update a routing table entry
 	 *
 	 * @param re Entry to add/update
-	 * @return True if successful
+	 * @return True if change successful (or unchanged)
 	 */
-	virtual bool addUpdateRoute(const Entry &re) = 0;
+	virtual bool set(const Entry &re) = 0;
 
 	/**
 	 * Compute a 64-bit value that hashes the current state of the network environment
 	 *
+	 * This shouldn't be overridden -- uses get() to get underlying routing table.
+	 *
 	 * @param ignoreInterfaces Names of interfaces to exclude from fingerprint (e.g. my own)
 	 * @return Integer CRC-type fingerprint of current network environment
 	 */
-	inline uint64_t networkEnvironmentFingerprint(const std::vector<std::string> &ignoreInterfaces) const
-	{
-		uint64_t fp = 0;
-		std::vector<Entry> rtab(routingTable());
-		for(std::vector<Entry>::const_iterator re(rtab.begin());re!=rtab.end();++re) {
-			bool skip = false;
-			for(std::vector<std::string>::const_iterator ii(ignoreInterfaces.begin());ii!=ignoreInterfaces.end();++ii) {
-				if (*ii == re->interface.device) {
-					skip = true;
-					break;
-				}
-			}
-			if (skip)
-				continue;
-			++fp;
-			if (re->destination.isV4()) {
-				fp = Utils::sdbmHash(re->destination.rawIpData(),4,fp);
-				fp = Utils::sdbmHash((uint16_t)re->destination.netmaskBits(),fp);
-			} else if (re->destination.isV6()) {
-				fp = Utils::sdbmHash(re->destination.rawIpData(),16,fp);
-				fp = Utils::sdbmHash((uint16_t)re->destination.netmaskBits(),fp);
-			}
-			if (re->gateway.isV4()) {
-				fp = Utils::sdbmHash(re->gateway.rawIpData(),4,fp);
-				fp = Utils::sdbmHash((uint16_t)re->gateway.netmaskBits(),fp);
-			} else if (re->gateway.isV6()) {
-				fp = Utils::sdbmHash(re->gateway.rawIpData(),16,fp);
-				fp = Utils::sdbmHash((uint16_t)re->gateway.netmaskBits(),fp);
-			}
-			fp = Utils::sdbmHash(re->device,fp);
-			fp = Utils::sdbmHash((uint32_t)re->metric,fp);
-		}
-		return fp;
-	}
+	uint64_t networkEnvironmentFingerprint(const std::vector<std::string> &ignoreInterfaces) const;
 };
 
 } // namespace ZeroTier

+ 1 - 0
objects.mk

@@ -19,6 +19,7 @@ OBJS=\
 	node/PacketDecoder.o \
 	node/Peer.o \
 	node/Poly1305.o \
+	node/RoutingTable.o \
 	node/Salsa20.o \
 	node/Service.o \
 	node/SocketManager.o \