summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@gmail.com>2014-10-03 11:59:50 -0700
committerAdam Ierymenko <adam.ierymenko@gmail.com>2014-10-03 11:59:50 -0700
commit67aa23530b7e051709002b521aa6e93cb6350918 (patch)
tree35d9c8dbd1125279596949479b6e915908c3b358
parent2a58c3fb98c3ff06cf7f5255a13ba4d128f3ce49 (diff)
downloadinfinitytier-67aa23530b7e051709002b521aa6e93cb6350918.tar.gz
infinitytier-67aa23530b7e051709002b521aa6e93cb6350918.zip
More work on adding testnet and user-mode capabilities for local network simulation.
-rw-r--r--main.cpp37
-rw-r--r--node/Condition.hpp (renamed from testnet/Condition.hpp)8
-rw-r--r--node/EthernetTap.hpp15
-rw-r--r--node/Node.cpp23
-rw-r--r--node/Node.hpp4
-rw-r--r--objects.mk3
-rw-r--r--osnet/LinuxEthernetTap.cpp5
-rw-r--r--osnet/LinuxEthernetTap.hpp1
-rw-r--r--osnet/OSXEthernetTap.cpp5
-rw-r--r--osnet/OSXEthernetTap.hpp1
-rw-r--r--osnet/WindowsEthernetTap.cpp5
-rw-r--r--osnet/WindowsEthernetTap.hpp1
-rw-r--r--root-topology/local-testnet/root-topology (renamed from root-topology/testnet/root-topology)0
-rw-r--r--root-topology/local-testnet/supernodes/0b461c6c90 (renamed from root-topology/testnet/supernodes/0b461c6c90)0
-rw-r--r--root-topology/local-testnet/supernodes/36944299f2 (renamed from root-topology/testnet/supernodes/36944299f2)0
-rw-r--r--root-topology/local-testnet/supernodes/8fd313ab35 (renamed from root-topology/testnet/supernodes/8fd313ab35)0
-rw-r--r--root-topology/local-testnet/supernodes/ccc0fa2960 (renamed from root-topology/testnet/supernodes/ccc0fa2960)0
-rw-r--r--root-topology/local-testnet/template.dict (renamed from root-topology/testnet/template.dict)0
-rw-r--r--testnet/TestEthernetTap.cpp53
-rw-r--r--testnet/TestEthernetTap.hpp26
-rw-r--r--testnet/TestEthernetTapFactory.hpp3
-rw-r--r--testnet/TestRoutingTable.cpp50
-rw-r--r--testnet/TestRoutingTable.hpp50
-rw-r--r--testnet/local-testnet/sn0000/identity.public (renamed from testnet/nodes/sn0000/identity.public)0
-rw-r--r--testnet/local-testnet/sn0000/identity.secret (renamed from testnet/nodes/sn0000/identity.secret)0
-rw-r--r--testnet/local-testnet/sn0001/identity.public (renamed from testnet/nodes/sn0001/identity.public)0
-rw-r--r--testnet/local-testnet/sn0001/identity.secret (renamed from testnet/nodes/sn0001/identity.secret)0
-rw-r--r--testnet/local-testnet/sn0002/identity.public (renamed from testnet/nodes/sn0002/identity.public)0
-rw-r--r--testnet/local-testnet/sn0002/identity.secret (renamed from testnet/nodes/sn0002/identity.secret)0
-rw-r--r--testnet/local-testnet/sn0003/identity.public (renamed from testnet/nodes/sn0003/identity.public)0
-rw-r--r--testnet/local-testnet/sn0003/identity.secret (renamed from testnet/nodes/sn0003/identity.secret)0
31 files changed, 251 insertions, 39 deletions
diff --git a/main.cpp b/main.cpp
index e6fc1127..52f1eed0 100644
--- a/main.cpp
+++ b/main.cpp
@@ -75,6 +75,9 @@
#include "control/NodeControlClient.hpp"
#include "control/NodeControlService.hpp"
+#include "testnet/TestEthernetTapFactory.hpp"
+#include "testnet/TestRoutingTable.hpp"
+
#ifdef __WINDOWS__
#include "osnet/WindowsEthernetTapFactory.hpp"
#include "osnet/WindowsRoutingTable.hpp"
@@ -564,6 +567,8 @@ static void printHelp(const char *cn,FILE *out)
fprintf(out," -v - Show version"ZT_EOL_S);
fprintf(out," -p<port> - Port for UDP (default: 9993)"ZT_EOL_S);
fprintf(out," -t<port> - Port for TCP (default: disabled)"ZT_EOL_S);
+ fprintf(out," -T<path> - Override root topology, do not authenticate or update"ZT_EOL_S);
+ fprintf(out," -u - Do not require root, use dummy tap device"ZT_EOL_S);
#ifdef __UNIX_LIKE__
fprintf(out," -d - Fork and run as daemon (Unix-ish OSes)"ZT_EOL_S);
#endif
@@ -619,6 +624,8 @@ int main(int argc,char **argv)
unsigned int udpPort = ZT_DEFAULT_UDP_PORT;
unsigned int tcpPort = 0;
+ std::string overrideRootTopology;
+ bool userMode = false;
#ifdef __UNIX_LIKE__
bool runAsDaemon = false;
#endif
@@ -652,6 +659,20 @@ int main(int argc,char **argv)
runAsDaemon = true;
break;
#endif
+ case 'T':
+ if (argv[i][2]) {
+ if (!Utils::readFile(argv[i] + 2,overrideRootTopology)) {
+ fprintf(stderr,"%s: cannot read root topology from %s"ZT_EOL_S,argv[0],argv[i] + 2);
+ return 1;
+ }
+ } else {
+ printHelp(argv[0],stdout);
+ return 1;
+ }
+ break;
+ case 'u':
+ userMode = true;
+ break;
case 'v':
printf("%s"ZT_EOL_S,Node::versionString());
return 0;
@@ -728,7 +749,7 @@ int main(int argc,char **argv)
homeDir = ZT_DEFAULTS.defaultHomePath.c_str();
#ifdef __UNIX_LIKE__
- if (getuid() != 0) {
+ if ((!userMode)&&(getuid() != 0)) {
fprintf(stderr,"%s: must be run as root (uid 0)\n",argv[0]);
return 1;
}
@@ -758,17 +779,18 @@ int main(int argc,char **argv)
#endif // __UNIX_LIKE__
#ifdef __WINDOWS__
- _winPokeAHole();
if (winRunFromCommandLine) {
// Running in "interactive" mode (mostly for debugging)
- if (IsCurrentUserLocalAdministrator() != TRUE) {
+ if ((!userMode)&&(IsCurrentUserLocalAdministrator() != TRUE)) {
fprintf(stderr,"%s: must be run as a local administrator."ZT_EOL_S,argv[0]);
return 1;
}
+ _winPokeAHole();
SetConsoleCtrlHandler(&_winConsoleCtrlHandler,TRUE);
// continues on to ordinary command line execution code below...
} else {
// Running from service manager
+ _winPokeAHole();
ZeroTierOneService zt1Service;
if (CServiceBase::Run(zt1Service) == TRUE) {
return 0;
@@ -791,8 +813,13 @@ int main(int argc,char **argv)
// succeed unless something is wrong with the filesystem.
std::string authToken(NodeControlClient::getAuthToken((std::string(homeDir) + ZT_PATH_SEPARATOR_S + "authtoken.secret").c_str(),true));
- tapFactory = ZTCreatePlatformEthernetTapFactory;
- routingTable = ZTCreatePlatformRoutingTable;
+ if (userMode) {
+ tapFactory = new TestEthernetTapFactory();
+ routingTable = new TestRoutingTable();
+ } else {
+ tapFactory = ZTCreatePlatformEthernetTapFactory;
+ routingTable = ZTCreatePlatformRoutingTable;
+ }
node = new Node(homeDir,tapFactory,routingTable,udpPort,tcpPort,needsReset);
controlService = new NodeControlService(node,authToken.c_str());
diff --git a/testnet/Condition.hpp b/node/Condition.hpp
index 89d3a531..3895f4df 100644
--- a/testnet/Condition.hpp
+++ b/node/Condition.hpp
@@ -28,15 +28,15 @@
#ifndef ZT_CONDITION_HPP
#define ZT_CONDITION_HPP
-#include "../node/Constants.hpp"
-#include "../node/NonCopyable.hpp"
+#include "Constants.hpp"
+#include "NonCopyable.hpp"
#ifdef __WINDOWS__
#include <Windows.h>
#include <stdlib.h>
-#include "../node/Utils.hpp"
+#include "Utils.hpp"
namespace ZeroTier {
@@ -83,7 +83,7 @@ private:
#include <time.h>
#include <stdlib.h>
#include <pthread.h>
-#include "../node/Utils.hpp"
+#include "Utils.hpp"
namespace ZeroTier {
diff --git a/node/EthernetTap.hpp b/node/EthernetTap.hpp
index 0980d2c0..132e5c20 100644
--- a/node/EthernetTap.hpp
+++ b/node/EthernetTap.hpp
@@ -152,6 +152,21 @@ public:
*/
virtual bool updateMulticastGroups(std::set<MulticastGroup> &groups) = 0;
+ /**
+ * Inject a packet as if it was sent by the host, if supported
+ *
+ * This is for testing and is typically not supported by real TAP devices.
+ * It's implemented by TestEthernetTap in testnet.
+ *
+ * @param from Source MAC
+ * @param to Destination MAC
+ * @param etherType Ethernet frame type
+ * @param data Packet data
+ * @param len Packet length
+ * @return False if not supported or packet too large
+ */
+ virtual bool injectPacketFromHost(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len) = 0;
+
protected:
const char *_implName;
MAC _mac;
diff --git a/node/Node.cpp b/node/Node.cpp
index 6682ad25..fd1daab3 100644
--- a/node/Node.cpp
+++ b/node/Node.cpp
@@ -93,6 +93,7 @@ struct _NodeImpl
volatile bool running;
volatile bool resynchronize;
volatile bool disableRootTopologyUpdates;
+ std::string overrideRootTopology;
// This function performs final node tear-down
inline Node::ReasonForTermination terminate()
@@ -223,8 +224,8 @@ Node::Node(
RoutingTable *rt,
unsigned int udpPort,
unsigned int tcpPort,
- bool resetIdentity)
- throw() :
+ bool resetIdentity,
+ const char *overrideRootTopology) throw() :
_impl(new _NodeImpl)
{
_NodeImpl *impl = (_NodeImpl *)_impl;
@@ -260,7 +261,13 @@ Node::Node(
impl->started = false;
impl->running = false;
impl->resynchronize = false;
- impl->disableRootTopologyUpdates = false;
+
+ if (overrideRootTopology) {
+ impl->disableRootTopologyUpdates = true;
+ impl->overrideRootTopology = overrideRootTopology;
+ } else {
+ impl->disableRootTopologyUpdates = false;
+ }
}
Node::~Node()
@@ -403,7 +410,7 @@ Node::ReasonForTermination Node::run()
#endif
// Initialize root topology from defaults or root-toplogy file in home path on disk
- {
+ if (impl->overrideRootTopology.length() == 0) {
std::string rootTopologyPath(RR->homePath + ZT_PATH_SEPARATOR_S + "root-topology");
std::string rootTopology;
if (!Utils::readFile(rootTopologyPath.c_str(),rootTopology))
@@ -427,6 +434,14 @@ Node::ReasonForTermination Node::run()
} catch ( ... ) {
return impl->terminateBecause(Node::NODE_UNRECOVERABLE_ERROR,"invalid root-topology format");
}
+ } else {
+ try {
+ Dictionary rt(impl->overrideRootTopology);
+ RR->topology->setSupernodes(Dictionary(rt.get("supernodes","")));
+ impl->disableRootTopologyUpdates = true;
+ } catch ( ... ) {
+ return impl->terminateBecause(Node::NODE_UNRECOVERABLE_ERROR,"invalid root-topology format");
+ }
}
} catch (std::bad_alloc &exc) {
return impl->terminateBecause(Node::NODE_UNRECOVERABLE_ERROR,"memory allocation failure");
diff --git a/node/Node.hpp b/node/Node.hpp
index 32342349..858a3737 100644
--- a/node/Node.hpp
+++ b/node/Node.hpp
@@ -88,6 +88,7 @@ public:
* @param udpPort UDP port or 0 to disable
* @param tcpPort TCP port or 0 to disable
* @param resetIdentity If true, delete identity before starting and regenerate
+ * @param overrideRootTopology Override root topology with this dictionary (in string serialized format) and do not update (default: NULL for none)
*/
Node(
const char *hp,
@@ -95,7 +96,8 @@ public:
RoutingTable *rt,
unsigned int udpPort,
unsigned int tcpPort,
- bool resetIdentity) throw();
+ bool resetIdentity,
+ const char *overrideRootTopology = (const char *)0) throw();
~Node();
diff --git a/objects.mk b/objects.mk
index 9f049215..8c686744 100644
--- a/objects.mk
+++ b/objects.mk
@@ -4,6 +4,9 @@ OBJS=\
control/NodeControlClient.o \
control/NodeControlService.o \
ext/lz4/lz4.o \
+ testnet/TestEthernetTap.o \
+ testnet/TestEthernetTapFactory.o \
+ testnet/TestRoutingTable.o \
node/C25519.o \
node/CertificateOfMembership.o \
node/Defaults.o \
diff --git a/osnet/LinuxEthernetTap.cpp b/osnet/LinuxEthernetTap.cpp
index 1bd066c3..955048e7 100644
--- a/osnet/LinuxEthernetTap.cpp
+++ b/osnet/LinuxEthernetTap.cpp
@@ -361,6 +361,11 @@ bool LinuxEthernetTap::updateMulticastGroups(std::set<MulticastGroup> &groups)
return changed;
}
+bool LinuxEthernetTap::injectPacketFromHost(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len)
+{
+ return false;
+}
+
void LinuxEthernetTap::threadMain()
throw()
{
diff --git a/osnet/LinuxEthernetTap.hpp b/osnet/LinuxEthernetTap.hpp
index 0dfb504b..b34a64ef 100644
--- a/osnet/LinuxEthernetTap.hpp
+++ b/osnet/LinuxEthernetTap.hpp
@@ -65,6 +65,7 @@ public:
virtual std::string deviceName() const;
virtual void setFriendlyName(const char *friendlyName);
virtual bool updateMulticastGroups(std::set<MulticastGroup> &groups);
+ virtual bool injectPacketFromHost(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len);
void threadMain()
throw();
diff --git a/osnet/OSXEthernetTap.cpp b/osnet/OSXEthernetTap.cpp
index 6164358d..950877db 100644
--- a/osnet/OSXEthernetTap.cpp
+++ b/osnet/OSXEthernetTap.cpp
@@ -576,6 +576,11 @@ bool OSXEthernetTap::updateMulticastGroups(std::set<MulticastGroup> &groups)
return changed;
}
+bool OSXEthernetTap::injectPacketFromHost(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len)
+{
+ return false;
+}
+
void OSXEthernetTap::threadMain()
throw()
{
diff --git a/osnet/OSXEthernetTap.hpp b/osnet/OSXEthernetTap.hpp
index 3ac8df84..c9ee316c 100644
--- a/osnet/OSXEthernetTap.hpp
+++ b/osnet/OSXEthernetTap.hpp
@@ -69,6 +69,7 @@ public:
virtual std::string deviceName() const;
virtual void setFriendlyName(const char *friendlyName);
virtual bool updateMulticastGroups(std::set<MulticastGroup> &groups);
+ virtual bool injectPacketFromHost(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len);
void threadMain()
throw();
diff --git a/osnet/WindowsEthernetTap.cpp b/osnet/WindowsEthernetTap.cpp
index fb978071..e6c49f94 100644
--- a/osnet/WindowsEthernetTap.cpp
+++ b/osnet/WindowsEthernetTap.cpp
@@ -527,6 +527,11 @@ bool WindowsEthernetTap::updateMulticastGroups(std::set<MulticastGroup> &groups)
return changed;
}
+bool WindowsEthernetTap::injectPacketFromHost(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len)
+{
+ return false;
+}
+
void WindowsEthernetTap::threadMain()
throw()
{
diff --git a/osnet/WindowsEthernetTap.hpp b/osnet/WindowsEthernetTap.hpp
index e5f5e4b2..55e18c80 100644
--- a/osnet/WindowsEthernetTap.hpp
+++ b/osnet/WindowsEthernetTap.hpp
@@ -71,6 +71,7 @@ public:
virtual std::string deviceName() const;
virtual void setFriendlyName(const char *friendlyName);
virtual bool updateMulticastGroups(std::set<MulticastGroup> &groups);
+ virtual bool injectPacketFromHost(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len);
inline const NET_LUID &luid() const { return _deviceLuid; }
inline const GUID &guid() const { return _deviceGuid; }
diff --git a/root-topology/testnet/root-topology b/root-topology/local-testnet/root-topology
index 63d8144d..63d8144d 100644
--- a/root-topology/testnet/root-topology
+++ b/root-topology/local-testnet/root-topology
diff --git a/root-topology/testnet/supernodes/0b461c6c90 b/root-topology/local-testnet/supernodes/0b461c6c90
index fb91b4b7..fb91b4b7 100644
--- a/root-topology/testnet/supernodes/0b461c6c90
+++ b/root-topology/local-testnet/supernodes/0b461c6c90
diff --git a/root-topology/testnet/supernodes/36944299f2 b/root-topology/local-testnet/supernodes/36944299f2
index 6a484270..6a484270 100644
--- a/root-topology/testnet/supernodes/36944299f2
+++ b/root-topology/local-testnet/supernodes/36944299f2
diff --git a/root-topology/testnet/supernodes/8fd313ab35 b/root-topology/local-testnet/supernodes/8fd313ab35
index 12041787..12041787 100644
--- a/root-topology/testnet/supernodes/8fd313ab35
+++ b/root-topology/local-testnet/supernodes/8fd313ab35
diff --git a/root-topology/testnet/supernodes/ccc0fa2960 b/root-topology/local-testnet/supernodes/ccc0fa2960
index 371c975a..371c975a 100644
--- a/root-topology/testnet/supernodes/ccc0fa2960
+++ b/root-topology/local-testnet/supernodes/ccc0fa2960
diff --git a/root-topology/testnet/template.dict b/root-topology/local-testnet/template.dict
index 987fb91c..987fb91c 100644
--- a/root-topology/testnet/template.dict
+++ b/root-topology/local-testnet/template.dict
diff --git a/testnet/TestEthernetTap.cpp b/testnet/TestEthernetTap.cpp
index 421d6650..f3273d00 100644
--- a/testnet/TestEthernetTap.cpp
+++ b/testnet/TestEthernetTap.cpp
@@ -27,10 +27,23 @@
#include "TestEthernetTap.hpp"
#include "TestEthernetTapFactory.hpp"
+
+#include "../node/Constants.hpp"
#include "../node/Utils.hpp"
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef __WINDOWS__
+#include <process.h>
+#else
+#include <unistd.h>
+#endif
+
namespace ZeroTier {
+static Mutex printLock;
+
TestEthernetTap::TestEthernetTap(
TestEthernetTapFactory *parent,
const MAC &mac,
@@ -47,9 +60,19 @@ TestEthernetTap::TestEthernetTap(
_arg(arg),
_enabled(true)
{
+ static volatile unsigned int testTapCounter = 0;
+
char tmp[64];
- Utils::snprintf(tmp,sizeof(tmp),"%.16llx",(unsigned long long)nwid);
+ int pid = 0;
+#ifdef __UNIX_LIKE__
+ pid = (int)getpid();
+#endif
+#ifdef __WINDOWS__
+ pid = (int)_getpid();
+#endif
+ Utils::snprintf(tmp,sizeof(tmp),"test%dtap%d",pid,testTapCounter++);
_dev = tmp;
+
_thread = Thread::start(this);
}
@@ -57,7 +80,7 @@ TestEthernetTap::~TestEthernetTap()
{
{
Mutex::Lock _l(_pq_m);
- _pq.push(TestFrame()); // 0-length frame = exit
+ _pq.push(TestFrame()); // 0 length frame = exit
}
_pq_c.signal();
Thread::join(_thread);
@@ -90,9 +113,9 @@ std::set<InetAddress> TestEthernetTap::ips() const
void TestEthernetTap::put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len)
{
- static Mutex printLock;
Mutex::Lock _l(printLock);
- fprintf(stderr,"%s << %s %.4x %s"ZT_EOL_S,to.toString().c_str(),from.toString().c_str(),etherType,std::string((const char *)data,len).c_str());
+ fprintf(stdout,"[%s] %s << %s %.4x %s"ZT_EOL_S,_dev.c_str(),to.toString().c_str(),from.toString().c_str(),etherType,std::string((const char *)data,len).c_str());
+ fflush(stdout);
}
std::string TestEthernetTap::deviceName() const
@@ -109,6 +132,26 @@ bool TestEthernetTap::updateMulticastGroups(std::set<MulticastGroup> &groups)
return false;
}
+bool TestEthernetTap::injectPacketFromHost(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len)
+{
+ if ((len == 0)||(len > 2800))
+ return false;
+
+ {
+ Mutex::Lock _l(_pq_m);
+ _pq.push(TestFrame(from,to,data,etherType & 0xffff,len));
+ }
+ _pq_c.signal();
+
+ {
+ Mutex::Lock _l(printLock);
+ fprintf(stdout,"[%s] %s >> %s %.4x %s"ZT_EOL_S,_dev.c_str(),from.toString().c_str(),to.toString().c_str(),etherType,std::string((const char *)data,len).c_str());
+ fflush(stdout);
+ }
+
+ return true;
+}
+
void TestEthernetTap::threadMain()
throw()
{
@@ -126,7 +169,7 @@ void TestEthernetTap::threadMain()
}
if ((tf.len > 0)&&(_enabled))
- _handler(_arg,tf.from,tf.to,ZT_TEST_ETHERNET_ETHERTYPE,Buffer<4096>(tf.data,tf.len));
+ _handler(_arg,tf.from,tf.to,tf.etherType,Buffer<4096>(tf.data,tf.len));
_pq_c.wait();
}
diff --git a/testnet/TestEthernetTap.hpp b/testnet/TestEthernetTap.hpp
index c1e9c720..93eb4c5b 100644
--- a/testnet/TestEthernetTap.hpp
+++ b/testnet/TestEthernetTap.hpp
@@ -36,15 +36,13 @@
#include <queue>
#include <string>
+#include "../node/Constants.hpp"
+#include "../node/EthernetTap.hpp"
#include "../node/AtomicCounter.hpp"
#include "../node/SharedPtr.hpp"
-#include "../node/EthernetTap.hpp"
#include "../node/Thread.hpp"
#include "../node/Mutex.hpp"
-#include "Condition.hpp"
-
-// Ethernet frame type to use on fake testnet
-#define ZT_TEST_ETHERNET_ETHERTYPE 0xdead
+#include "../node/Condition.hpp"
namespace ZeroTier {
@@ -57,16 +55,18 @@ class TestEthernetTap : public EthernetTap
private:
struct TestFrame
{
- TestFrame() : len(0) {}
- TestFrame(const MAC &f,const MAC &t,const void *d,unsigned int l) :
+ TestFrame() : etherType(0),len(0) {}
+ TestFrame(const MAC &f,const MAC &t,const void *d,unsigned int et,unsigned int l) :
from(f),
to(t),
+ etherType(et),
len(l)
{
memcpy(data,d,l);
}
MAC from;
MAC to;
+ unsigned int etherType;
unsigned int len;
char data[4096];
};
@@ -94,21 +94,11 @@ public:
virtual std::string deviceName() const;
virtual void setFriendlyName(const char *friendlyName);
virtual bool updateMulticastGroups(std::set<MulticastGroup> &groups);
+ virtual bool injectPacketFromHost(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len);
void threadMain()
throw();
- inline void sendFromHost(const MAC &from,const MAC &to,const void *data,unsigned int len)
- {
- if (!len)
- return;
- {
- Mutex::Lock _l(_pq_m);
- _pq.push(TestFrame(from,to,data,len));
- }
- _pq_c.signal();
- }
-
private:
TestEthernetTapFactory *_parent;
diff --git a/testnet/TestEthernetTapFactory.hpp b/testnet/TestEthernetTapFactory.hpp
index caceec06..5327b844 100644
--- a/testnet/TestEthernetTapFactory.hpp
+++ b/testnet/TestEthernetTapFactory.hpp
@@ -37,11 +37,10 @@
#include "../node/Mutex.hpp"
#include "../node/MAC.hpp"
#include "../node/CMWC4096.hpp"
+#include "TestEthernetTap.hpp"
namespace ZeroTier {
-class TestEthernetTap;
-
class TestEthernetTapFactory : public EthernetTapFactory
{
public:
diff --git a/testnet/TestRoutingTable.cpp b/testnet/TestRoutingTable.cpp
new file mode 100644
index 00000000..8c132693
--- /dev/null
+++ b/testnet/TestRoutingTable.cpp
@@ -0,0 +1,50 @@
+/*
+ * 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 "TestRoutingTable.hpp"
+
+namespace ZeroTier {
+
+TestRoutingTable::TestRoutingTable()
+{
+}
+
+TestRoutingTable::~TestRoutingTable()
+{
+}
+
+std::vector<RoutingTable::Entry> TestRoutingTable::get(bool includeLinkLocal,bool includeLoopback) const
+{
+ return std::vector<RoutingTable::Entry>();
+}
+
+RoutingTable::Entry TestRoutingTable::set(const InetAddress &destination,const InetAddress &gateway,const char *device,int metric)
+{
+ return RoutingTable::Entry();
+}
+
+} // namespace ZeroTier
diff --git a/testnet/TestRoutingTable.hpp b/testnet/TestRoutingTable.hpp
new file mode 100644
index 00000000..98390201
--- /dev/null
+++ b/testnet/TestRoutingTable.hpp
@@ -0,0 +1,50 @@
+/*
+ * 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/
+ */
+
+#ifndef ZT_TESTROUTINGTABLE_HPP
+#define ZT_TESTROUTINGTABLE_HPP
+
+#include "../node/RoutingTable.hpp"
+
+namespace ZeroTier {
+
+/**
+ * Dummy routing table -- right now this just does nothing
+ */
+class TestRoutingTable : public RoutingTable
+{
+public:
+ TestRoutingTable();
+ virtual ~TestRoutingTable();
+
+ virtual std::vector<RoutingTable::Entry> get(bool includeLinkLocal = false,bool includeLoopback = false) const;
+ virtual RoutingTable::Entry set(const InetAddress &destination,const InetAddress &gateway,const char *device,int metric);
+};
+
+} // namespace ZeroTier
+
+#endif
diff --git a/testnet/nodes/sn0000/identity.public b/testnet/local-testnet/sn0000/identity.public
index 041c7479..041c7479 100644
--- a/testnet/nodes/sn0000/identity.public
+++ b/testnet/local-testnet/sn0000/identity.public
diff --git a/testnet/nodes/sn0000/identity.secret b/testnet/local-testnet/sn0000/identity.secret
index bc404424..bc404424 100644
--- a/testnet/nodes/sn0000/identity.secret
+++ b/testnet/local-testnet/sn0000/identity.secret
diff --git a/testnet/nodes/sn0001/identity.public b/testnet/local-testnet/sn0001/identity.public
index e65fcb04..e65fcb04 100644
--- a/testnet/nodes/sn0001/identity.public
+++ b/testnet/local-testnet/sn0001/identity.public
diff --git a/testnet/nodes/sn0001/identity.secret b/testnet/local-testnet/sn0001/identity.secret
index 5eb7b37d..5eb7b37d 100644
--- a/testnet/nodes/sn0001/identity.secret
+++ b/testnet/local-testnet/sn0001/identity.secret
diff --git a/testnet/nodes/sn0002/identity.public b/testnet/local-testnet/sn0002/identity.public
index 2cfe94c5..2cfe94c5 100644
--- a/testnet/nodes/sn0002/identity.public
+++ b/testnet/local-testnet/sn0002/identity.public
diff --git a/testnet/nodes/sn0002/identity.secret b/testnet/local-testnet/sn0002/identity.secret
index 265b070a..265b070a 100644
--- a/testnet/nodes/sn0002/identity.secret
+++ b/testnet/local-testnet/sn0002/identity.secret
diff --git a/testnet/nodes/sn0003/identity.public b/testnet/local-testnet/sn0003/identity.public
index cf6df640..cf6df640 100644
--- a/testnet/nodes/sn0003/identity.public
+++ b/testnet/local-testnet/sn0003/identity.public
diff --git a/testnet/nodes/sn0003/identity.secret b/testnet/local-testnet/sn0003/identity.secret
index cadafae1..cadafae1 100644
--- a/testnet/nodes/sn0003/identity.secret
+++ b/testnet/local-testnet/sn0003/identity.secret