mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-04-07 19:24:13 +00:00
Testnet work... getting there!
This commit is contained in:
parent
0a195e7bc0
commit
4fbb098daa
@ -120,7 +120,6 @@ void NodeControlService::_doCommand(IpcConnection *ipcc,const char *commandLine)
|
||||
ipcc->printf("200 help leave <network ID>"ZT_EOL_S);
|
||||
ipcc->printf("200 help terminate [<reason>]"ZT_EOL_S);
|
||||
ipcc->printf("200 help updatecheck"ZT_EOL_S);
|
||||
//ipcc->printf("200 help inject <network ID> <from MAC> <to MAC> <ethertype(hex)> <string>");
|
||||
} else if (cmd[0] == "auth") {
|
||||
if ((cmd.size() > 1)&&(_authToken.length() > 0)&&(_authToken == cmd[1])) {
|
||||
Mutex::Lock _l(_connections_m);
|
||||
@ -240,23 +239,6 @@ void NodeControlService::_doCommand(IpcConnection *ipcc,const char *commandLine)
|
||||
} else {
|
||||
ipcc->printf("200 OK"ZT_EOL_S);
|
||||
}
|
||||
} else if (cmd[0] == "inject") {
|
||||
if (cmd.size() >= 6) {
|
||||
MAC from,to;
|
||||
unsigned char from2[6];
|
||||
unsigned char to2[6];
|
||||
from.fromString(cmd[2].c_str());
|
||||
to.fromString(cmd[3].c_str());
|
||||
from.copyTo(from2,6);
|
||||
to.copyTo(to2,6);
|
||||
if (_node->injectPacketFromHost(Utils::hexStrToU64(cmd[1].c_str()),from2,to2,Utils::hexStrToUInt(cmd[4].c_str()),cmd[5].c_str(),(unsigned int)cmd[5].length()+1)) {
|
||||
ipcc->printf("200 OK"ZT_EOL_S);
|
||||
} else {
|
||||
ipcc->printf("500 inject failed or not supported by this tap device"ZT_EOL_S);
|
||||
}
|
||||
} else {
|
||||
ipcc->printf("400 missing required arguments"ZT_EOL_S);
|
||||
}
|
||||
} else {
|
||||
ipcc->printf("404 %s No such command. Use 'help' for help."ZT_EOL_S,cmd[0].c_str());
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ CXXFLAGS=$(CFLAGS) -fno-rtti
|
||||
|
||||
include objects.mk
|
||||
OBJS+=osnet/BSDRoutingTable.o osnet/OSXEthernetTap.o osnet/OSXEthernetTapFactory.o
|
||||
TESTNET_OBJS=testnet/SimNet.o testnet/SimNetSocketManager.o testnet/TestEthernetTap.o testnet/TestEthernetTapFactory.o testnet/TestRoutingTable.o
|
||||
|
||||
all: one
|
||||
|
||||
@ -48,10 +49,14 @@ one: $(OBJS) main.o
|
||||
ln -sf zerotier-one zerotier-cli
|
||||
ln -sf zerotier-one zerotier-idtool
|
||||
|
||||
selftest: $(OBJS) selftest.o
|
||||
selftest: $(OBJS) sefltest.o
|
||||
$(CXX) $(CXXFLAGS) -o zerotier-selftest selftest.o $(OBJS) $(LIBS)
|
||||
$(STRIP) zerotier-selftest
|
||||
|
||||
testnet: $(OBJS) $(TESTNET_OBJS) testnet.o
|
||||
$(CXX) $(CXXFLAGS) -o zerotier-testnet testnet.o $(OBJS) $(TESTNET_OBJS) $(LIBS)
|
||||
$(STRIP) zerotier-testnet
|
||||
|
||||
# Requires that ../Qt be symlinked to the Qt root to use for UI build
|
||||
mac-ui: FORCE
|
||||
mkdir -p build-ZeroTierUI-release
|
||||
@ -62,7 +67,7 @@ mac-ui: FORCE
|
||||
$(CODESIGN) -vvv "build-ZeroTierUI-release/ZeroTier One.app"
|
||||
|
||||
clean:
|
||||
rm -rf *.dSYM main.o selftest.o build-* $(OBJS) zerotier-* ZeroTierOneInstaller-* "ZeroTier One.zip" "ZeroTier One.dmg"
|
||||
rm -rf *.dSYM testnet.o selftest.o build-* $(OBJS) $(TEST_OBJS) zerotier-* ZeroTierOneInstaller-* "ZeroTier One.zip" "ZeroTier One.dmg"
|
||||
|
||||
debug: FORCE
|
||||
make -j 4 ZT_DEBUG=1
|
||||
|
@ -1018,22 +1018,6 @@ bool Node::updateCheck()
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Node::injectPacketFromHost(uint64_t nwid,const unsigned char *from,const unsigned char *to,unsigned int etherType,const void *data,unsigned int len)
|
||||
{
|
||||
if (!running())
|
||||
return false;
|
||||
if ((!from)||(!to))
|
||||
return false;
|
||||
|
||||
_NodeImpl *impl = (_NodeImpl *)_impl;
|
||||
RuntimeEnvironment *RR = (RuntimeEnvironment *)&(impl->renv);
|
||||
|
||||
SharedPtr<Network> network(RR->nc->network(nwid));
|
||||
if (network)
|
||||
return network->tapInjectPacketFromHost(MAC(from,6),MAC(to,6),etherType,data,len);
|
||||
return false;
|
||||
}
|
||||
|
||||
class _VersionStringMaker
|
||||
{
|
||||
public:
|
||||
|
@ -226,23 +226,6 @@ public:
|
||||
bool updateCheck()
|
||||
throw();
|
||||
|
||||
/**
|
||||
* Inject a packet into a network's tap as if it came from the host
|
||||
*
|
||||
* This is primarily for debugging, and at the moment is only supported on
|
||||
* the test/dummy Ethernet tap implementation. Attempting to use it for real
|
||||
* devices will fail and return 'false.'
|
||||
*
|
||||
* @param nwid Network ID
|
||||
* @param from Source MAC address (must be 6 bytes in length)
|
||||
* @param to Destination MAC address (must be 6 bytes in length)
|
||||
* @param etherType Ethernet frame type
|
||||
* @param data Frame data
|
||||
* @param len Length of frame in bytes
|
||||
* @return True on success; false if not a member of network, injection not supported, or data too large
|
||||
*/
|
||||
bool injectPacketFromHost(uint64_t nwid,const unsigned char *from,const unsigned char *to,unsigned int etherType,const void *data,unsigned int len);
|
||||
|
||||
static const char *versionString() throw();
|
||||
static unsigned int versionMajor() throw();
|
||||
static unsigned int versionMinor() throw();
|
||||
|
362
testnet.cpp
Normal file
362
testnet.cpp
Normal file
@ -0,0 +1,362 @@
|
||||
/*
|
||||
* 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 <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "node/Constants.hpp"
|
||||
#include "node/Node.hpp"
|
||||
#include "node/Utils.hpp"
|
||||
#include "node/Address.hpp"
|
||||
#include "node/Identity.hpp"
|
||||
#include "node/Thread.hpp"
|
||||
#include "node/CMWC4096.hpp"
|
||||
|
||||
#include "testnet/SimNet.hpp"
|
||||
#include "testnet/SimNetSocketManager.hpp"
|
||||
#include "testnet/TestEthernetTap.hpp"
|
||||
#include "testnet/TestEthernetTapFactory.hpp"
|
||||
#include "testnet/TestRoutingTable.hpp"
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
using namespace ZeroTier;
|
||||
|
||||
class SimNode
|
||||
{
|
||||
public:
|
||||
SimNode(SimNet &net,const std::string &hp,const char *rootTopology,bool issn,const InetAddress &addr) :
|
||||
home(hp),
|
||||
tapFactory(),
|
||||
routingTable(),
|
||||
socketManager(net.newEndpoint(addr)),
|
||||
node(home.c_str(),&tapFactory,&routingTable,socketManager,false,rootTopology),
|
||||
reasonForTermination(Node::NODE_RUNNING),
|
||||
supernode(issn)
|
||||
{
|
||||
thread = Thread::start(this);
|
||||
}
|
||||
|
||||
~SimNode()
|
||||
{
|
||||
node.terminate(Node::NODE_NORMAL_TERMINATION,"SimNode shutdown");
|
||||
Thread::join(thread);
|
||||
}
|
||||
|
||||
void threadMain()
|
||||
throw()
|
||||
{
|
||||
reasonForTermination = node.run();
|
||||
}
|
||||
|
||||
std::string home;
|
||||
TestEthernetTapFactory tapFactory;
|
||||
TestRoutingTable routingTable;
|
||||
SimNetSocketManager *socketManager;
|
||||
Node node;
|
||||
Node::ReasonForTermination reasonForTermination;
|
||||
bool supernode;
|
||||
Thread thread;
|
||||
};
|
||||
|
||||
static std::string basePath;
|
||||
static SimNet net;
|
||||
static std::map< Address,SimNode * > nodes;
|
||||
static std::map< InetAddress,Address > usedIps;
|
||||
static CMWC4096 prng;
|
||||
static std::string rootTopology;
|
||||
|
||||
// Converts an address into a fake IP not already claimed.
|
||||
// Be sure to call only once, as this claims the IP before returning it.
|
||||
static InetAddress inetAddressFromZeroTierAddress(const Address &addr)
|
||||
{
|
||||
uint32_t ip = (uint32_t)(addr.toInt() & 0xffffffff);
|
||||
for(;;) {
|
||||
if (((ip >> 24) & 0xff) >= 240) {
|
||||
ip &= 0x00ffffff;
|
||||
ip |= (((ip >> 24) & 0xff) % 240) << 24;
|
||||
}
|
||||
if (((ip >> 24) & 0xff) == 0)
|
||||
ip |= 0x01000000;
|
||||
if (((ip & 0xff) == 0)||((ip & 0xff) == 255))
|
||||
ip ^= 0x00000001;
|
||||
InetAddress inaddr(Utils::hton(ip),9993);
|
||||
if (usedIps.find(inaddr) == usedIps.end()) {
|
||||
usedIps[inaddr] = addr;
|
||||
return inaddr;
|
||||
}
|
||||
++ip; // keep looking sequentially for an unclaimed IP
|
||||
}
|
||||
}
|
||||
|
||||
static Identity makeNodeHome(bool super)
|
||||
{
|
||||
Identity id;
|
||||
id.generate();
|
||||
|
||||
std::string path(basePath + ZT_PATH_SEPARATOR_S + (super ? "S" : "N") + id.address().toString());
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
CreateDirectoryA(path.c_str(),NULL);
|
||||
#else
|
||||
mkdir(path.c_str(),0700);
|
||||
#endif
|
||||
|
||||
if (!Utils::writeFile((path + ZT_PATH_SEPARATOR_S + "identity.secret"),id.toString(true)))
|
||||
return Identity();
|
||||
if (!Utils::writeFile((path + ZT_PATH_SEPARATOR_S + "identity.public"),id.toString(false)))
|
||||
return Identity();
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
// Instantiates supernodes by scanning for S########## subdirectories
|
||||
static std::vector<Address> initSupernodes()
|
||||
{
|
||||
Dictionary supernodes;
|
||||
std::vector< std::pair<Identity,InetAddress> > snids;
|
||||
std::map<std::string,bool> dir(Utils::listDirectory(basePath.c_str()));
|
||||
|
||||
for(std::map<std::string,bool>::iterator d(dir.begin());d!=dir.end();++d) {
|
||||
if ((d->first.length() == 11)&&(d->second)&&(d->first[0] == 'S')) {
|
||||
std::string idbuf;
|
||||
if (Utils::readFile((basePath + ZT_PATH_SEPARATOR_S + d->first + ZT_PATH_SEPARATOR_S + "identity.public").c_str(),idbuf)) {
|
||||
Identity id(idbuf);
|
||||
if (id) {
|
||||
InetAddress inaddr(inetAddressFromZeroTierAddress(id.address()));
|
||||
snids.push_back(std::pair<Identity,InetAddress>(id,inaddr));
|
||||
|
||||
Dictionary snd;
|
||||
snd["id"] = id.toString(false);
|
||||
snd["udp"] = inaddr.toString();
|
||||
snd["desc"] = id.address().toString();
|
||||
snd["dns"] = inaddr.toIpString();
|
||||
supernodes[id.address().toString()] = snd.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary rtd;
|
||||
rtd["supernodes"] = supernodes.toString();
|
||||
rtd["noupdate"] = "1";
|
||||
rootTopology = rtd.toString();
|
||||
|
||||
std::vector<Address> newNodes;
|
||||
|
||||
for(std::vector< std::pair<Identity,InetAddress> >::iterator i(snids.begin());i!=snids.end();++i) {
|
||||
SimNode *n = new SimNode(net,(basePath + ZT_PATH_SEPARATOR_S + "S" + i->first.address().toString()),rootTopology.c_str(),true,i->second);
|
||||
nodes[id.address()] = n;
|
||||
newNodes.push_back(id.address());
|
||||
}
|
||||
|
||||
return newNodes;
|
||||
}
|
||||
|
||||
// Instantiates any not-already-instantiated regular nodes
|
||||
static std::vector<Address> scanForNewNodes()
|
||||
{
|
||||
std::vector<Address> newNodes;
|
||||
std::map<std::string,bool> dir(Utils::listDirectory(basePath.c_str()));
|
||||
|
||||
for(std::map<std::string,bool>::iterator d(dir.begin());d!=dir.end();++d) {
|
||||
if ((d->first.length() == 11)&&(d->second)&&(d->first[0] == 'N')) {
|
||||
Address na(d->first.c_str() + 1);
|
||||
if (nodes.find(na) == nodes.end()) {
|
||||
InetAddress inaddr(inetAddressFromZeroTierAddress(na));
|
||||
|
||||
SimNode *n = new SimNode(net,(basePath + ZT_PATH_SEPARATOR_S + d->first),rootTopology.c_str(),false,inaddr);
|
||||
nodes[na] = n;
|
||||
|
||||
newNodes.push_back(na);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return newNodes;
|
||||
}
|
||||
|
||||
static void doHelp(const std::vector<std::string> &cmd)
|
||||
{
|
||||
printf("---------- help"ZT_EOL_S);
|
||||
printf("---------- mksn <number of supernodes>"ZT_EOL_S);
|
||||
printf("---------- mkn <number of normal nodes>"ZT_EOL_S);
|
||||
printf("---------- list"ZT_EOL_S);
|
||||
printf("---------- join <address/*> <network ID>"ZT_EOL_S);
|
||||
printf("---------- leave <address/*> <network ID>"ZT_EOL_S);
|
||||
printf("---------- listnetworks <address/*>"ZT_EOL_S);
|
||||
printf("---------- listpeers <address/*>"ZT_EOL_S);
|
||||
printf("---------- alltoall"ZT_EOL_S);
|
||||
printf("---------- quit"ZT_EOL_S)
|
||||
}
|
||||
|
||||
static void doMKSN(const std::vector<std::string> &cmd)
|
||||
{
|
||||
if (cmd.size() < 2) {
|
||||
doHelp(cmd);
|
||||
return;
|
||||
}
|
||||
if (nodes.size() > 0) {
|
||||
printf("---------- mksn error: mksn can only be called once (network already exists)"ZT_EOL_S,(unsigned int)nodes.size());
|
||||
return;
|
||||
}
|
||||
|
||||
int count = Utils::strToInt(cmd[1].c_str());
|
||||
for(int i=0;i<count;++i) {
|
||||
Identity id(makeNodeHome(true));
|
||||
printf("%s identity created"ZT_EOL_S,id.address().toString().c_str());
|
||||
}
|
||||
|
||||
std::vector<Address> nodes(initSupernodes());
|
||||
for(std::vector<Address>::iterator a(nodes.begin());a!=nodes.end();++a)
|
||||
printf("%s started (supernode)"ZT_EOL_S,a->toString().c_str());
|
||||
|
||||
printf("---------- root topology is: %s"ZT_EOL_S,rootTopology.c_str());
|
||||
}
|
||||
|
||||
static void doMKN(const std::vector<std::string> &cmd)
|
||||
{
|
||||
if (cmd.size() < 2) {
|
||||
doHelp(cmd);
|
||||
return;
|
||||
}
|
||||
if (nodes.size() == 0) {
|
||||
printf("---------- mkn error: use mksn to create supernodes first."ZT_EOL_S);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void doList(const std::vector<std::string> &cmd)
|
||||
{
|
||||
}
|
||||
|
||||
static void doJoin(const std::vector<std::string> &cmd)
|
||||
{
|
||||
}
|
||||
|
||||
static void doLeave(const std::vector<std::string> &cmd)
|
||||
{
|
||||
}
|
||||
|
||||
static void doListNetworks(const std::vector<std::string> &cmd)
|
||||
{
|
||||
}
|
||||
|
||||
static void doListPeers(const std::vector<std::string> &cmd)
|
||||
{
|
||||
}
|
||||
|
||||
static void doAllToAll(const std::vector<std::string> &cmd)
|
||||
{
|
||||
}
|
||||
|
||||
int main(int argc,char **argv)
|
||||
{
|
||||
char linebuf[1024];
|
||||
|
||||
if (argc <= 1) {
|
||||
fprintf(stderr,"Usage: %s <base path for temporary node home directories>"ZT_EOL_S,argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
basePath = argv[1];
|
||||
#ifdef __WINDOWS__
|
||||
CreateDirectoryA(basePath.c_str(),NULL);
|
||||
#else
|
||||
mkdir(basePath.c_str(),0700);
|
||||
#endif
|
||||
|
||||
printf("*** ZeroTier One Version %s -- Headless Network Simulator ***"ZT_EOL_S,Node::versionString());
|
||||
printf(ZT_EOL_S);
|
||||
|
||||
{
|
||||
printf("---------- scanning '%s' for existing network..."ZT_EOL_S);
|
||||
std::vector<Address> snodes(initSupernodes());
|
||||
if (snodes.empty()) {
|
||||
printf("---------- no existing network found; use 'mksn' to create one."ZT_EOL_S);
|
||||
} else {
|
||||
for(std::vector<Address>::iterator a(snodes.begin());a!=snodes.end();++a)
|
||||
printf("%s started (supernode)"ZT_EOL_S,a->toString().c_str());
|
||||
printf("---------- root topology is: %s"ZT_EOL_S,rootTopology.c_str());
|
||||
std::vector<Address> nodes(scanForNewNodes());
|
||||
for(std::vector<Address>::iterator a(nodes.begin());a!=nodes.end();++a)
|
||||
printf("%s started (normal peer)"ZT_EOL_S,a->toString().c_str());
|
||||
printf("---------- %u peers and %u supernodes loaded!"ZT_EOL_S,(unsigned int)nodes.size(),(unsigned int)snodes.size());
|
||||
}
|
||||
}
|
||||
printf(ZT_EOL_S);
|
||||
|
||||
printf("Type 'help' for help."ZT_EOL_S);
|
||||
printf(ZT_EOL_S);
|
||||
|
||||
for(;;) {
|
||||
printf(">> ");
|
||||
fflush(stdout);
|
||||
if (!fgets(linebuf,sizeof(linebuf),stdin))
|
||||
break;
|
||||
std::vector<std::string> cmd(Utils::split(linebuf," \r\n\t","\\","\""));
|
||||
if (cmd.size() == 0)
|
||||
continue;
|
||||
|
||||
if (cmd[0] == "quit")
|
||||
break;
|
||||
else if (cmd[0] == "help")
|
||||
doHelp(cmd);
|
||||
else if (cmd[0] == "mksn")
|
||||
doMKSN(cmd);
|
||||
else if (cmd[0] == "mkn")
|
||||
doMKN(cmd);
|
||||
else if (cmd[0] == "join")
|
||||
doJoin(cmd);
|
||||
else if (cmd[0] == "leave")
|
||||
doLeave(cmd);
|
||||
else if (cmd[0] == "listnetworks")
|
||||
doListNetworks(cmd);
|
||||
else if (cmd[0] == "listpeers")
|
||||
doListPeers(cmd);
|
||||
else if (cmd[0] == "alltoall")
|
||||
doAllToAll(cmd);
|
||||
else doHelp(cmd);
|
||||
}
|
||||
|
||||
for(std::map< Address,SimNode * >::iterator n(nodes.begin());n!=nodes.end();++n) {
|
||||
printf("%s shutting down..."ZT_EOL_S,n->first.toString().c_str());
|
||||
delete n->second;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -40,50 +40,29 @@ SimNet::~SimNet()
|
||||
{
|
||||
}
|
||||
|
||||
SimNetSocketManager *newEndpoint()
|
||||
SimNetSocketManager *SimNet::newEndpoint(const InetAddress &addr)
|
||||
{
|
||||
Mutex::Lock _l(_lock);
|
||||
|
||||
if (_endpoints.size() >= ZT_SIMNET_MAX_TESTNET_SIZE)
|
||||
return (SimNetSocketManager *)0;
|
||||
if (_endpoints.find(addr) != _endpoints.end())
|
||||
return (SimNetSocketManager *)0;
|
||||
|
||||
InetAddress fake;
|
||||
uint32_t ip = _prng.next32();
|
||||
for(;;) {
|
||||
++ip;
|
||||
ip &= 0x00ffffff;
|
||||
ip |= 0x0a000000; // 10.x.x.x
|
||||
if (((ip >> 16) & 0xff) == 0xff) ip ^= 0x00010000;
|
||||
if (((ip >> 8) & 0xff) == 0xff) ip ^= 0x00000100;
|
||||
if ((ip & 0xff) == 0xff) --ip;
|
||||
if ((ip & 0xff) == 0x00) ++ip;
|
||||
uint32_t ipn = Utils::hton(ip);
|
||||
fake.set(&ipn,4,8); // 10.x.x.x/8
|
||||
if (_endpoints.find(fake) == _endpoints.end()) {
|
||||
SimNetSocketManager *sm = &(_endpoints[fake]);
|
||||
sm->_sn = this;
|
||||
sm->_address = fake;
|
||||
return sm;
|
||||
}
|
||||
}
|
||||
SimNetSocketManager *sm = new SimNetSocketManager();
|
||||
sm->_sn = this;
|
||||
sm->_address = addr;
|
||||
_endpoints[addr] = sm;
|
||||
return sm;
|
||||
}
|
||||
|
||||
SimNetSocketManager *get(const InetAddress &addr)
|
||||
SimNetSocketManager *SimNet::get(const InetAddress &addr)
|
||||
{
|
||||
Mutex::Lock _l(_lock);
|
||||
std::map< InetAddress,SimNetSocketManager >::iterator ep(_endpoints.find(addr));
|
||||
std::map< InetAddress,SimNetSocketManager * >::iterator ep(_endpoints.find(addr));
|
||||
if (ep == _endpoints.end())
|
||||
return (SimNetSocketManager *)0;
|
||||
return &(ep->second);
|
||||
}
|
||||
|
||||
std::vector<SimNetSocketManager *> SimNet::all()
|
||||
{
|
||||
std::vector<SimNetSocketManager *> a;
|
||||
Mutex::Lock _l(_lock);
|
||||
for (std::map< InetAddress,SimNetSocketManager >::iterator ep(_endpoints.begin());ep!=_endpoints.end();++ep)
|
||||
a.push_back(&(ep->second));
|
||||
return a;
|
||||
return ep->second;
|
||||
}
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
@ -34,13 +34,12 @@
|
||||
#include "../node/Constants.hpp"
|
||||
#include "../node/InetAddress.hpp"
|
||||
#include "../node/Mutex.hpp"
|
||||
#include "../node/CMWC4096.hpp"
|
||||
|
||||
#include "SimNetSocketManager.hpp"
|
||||
|
||||
#define ZT_SIMNET_MAX_TESTNET_SIZE 1048576
|
||||
|
||||
namespcae ZeroTier {
|
||||
namespace ZeroTier {
|
||||
|
||||
/**
|
||||
* A simulated headless IP network for testing
|
||||
@ -52,9 +51,9 @@ public:
|
||||
~SimNet();
|
||||
|
||||
/**
|
||||
* @return New endpoint with random IP address
|
||||
* @return New endpoint or NULL on failure
|
||||
*/
|
||||
SimNetSocketManager *newEndpoint();
|
||||
SimNetSocketManager *newEndpoint(const InetAddress &addr);
|
||||
|
||||
/**
|
||||
* @param addr Address to look up
|
||||
@ -62,14 +61,8 @@ public:
|
||||
*/
|
||||
SimNetSocketManager *get(const InetAddress &addr);
|
||||
|
||||
/**
|
||||
* @return All socket managers (pointers remain safe while SimNet is running-- these aren't cleaned)
|
||||
*/
|
||||
std::vector<SimNetSocketManager *> all();
|
||||
|
||||
private:
|
||||
std::map< InetAddress,SimNetSocketManager > _endpoints;
|
||||
CMWC4096 _prng;
|
||||
std::map< InetAddress,SimNetSocketManager * > _endpoints;
|
||||
Mutex _lock;
|
||||
};
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
*/
|
||||
|
||||
#include "SimNetSocketManager.hpp"
|
||||
#include "SimNet.hpp"
|
||||
|
||||
#include "../node/Constants.hpp"
|
||||
#include "../node/Socket.hpp"
|
||||
@ -73,20 +74,20 @@ bool SimNetSocketManager::send(const InetAddress &to,bool tcp,bool autoConnectTc
|
||||
void SimNetSocketManager::poll(unsigned long timeout,void (*handler)(const SharedPtr<Socket> &,void *,const InetAddress &,Buffer<ZT_SOCKET_MAX_MESSAGE_LEN> &),void *arg)
|
||||
{
|
||||
{
|
||||
Mutex::Lock _l(_lock);
|
||||
while (!_queue.empty()) {
|
||||
handler(_mySocket,arg,_queue.front().first,_queue.front().second);
|
||||
_queue.pop();
|
||||
Mutex::Lock _l(_inbox_m);
|
||||
while (!_inbox.empty()) {
|
||||
handler(_mySocket,arg,_inbox.front().first,_inbox.front().second);
|
||||
_inbox.pop();
|
||||
}
|
||||
}
|
||||
if (timeout)
|
||||
_waitCond.wait(timeout);
|
||||
else _waitCond.wait();
|
||||
{
|
||||
Mutex::Lock _l(_lock);
|
||||
while (!_queue.empty()) {
|
||||
handler(_mySocket,arg,_queue.front().first,_queue.front().second);
|
||||
_queue.pop();
|
||||
Mutex::Lock _l(_inbox_m);
|
||||
while (!_inbox.empty()) {
|
||||
handler(_mySocket,arg,_inbox.front().first,_inbox.front().second);
|
||||
_inbox.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@
|
||||
#include <utility>
|
||||
#include <queue>
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "../node/Constants.hpp"
|
||||
#include "../node/SocketManager.hpp"
|
||||
#include "../node/Mutex.hpp"
|
||||
#include "../node/Condition.hpp"
|
||||
@ -76,7 +76,10 @@ public:
|
||||
inline TransferStats stats(const InetAddress &peer) const
|
||||
{
|
||||
Mutex::Lock _l(_stats_m);
|
||||
return _stats[peer];
|
||||
std::map< InetAddress,TransferStats >::const_iterator s(_stats.find(peer));
|
||||
if (s == _stats.end())
|
||||
return TransferStats();
|
||||
return s->second;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -53,10 +53,6 @@ EthernetTap *TestEthernetTapFactory::open(
|
||||
Mutex::Lock _l(_taps_m);
|
||||
_taps.insert(tap);
|
||||
}
|
||||
{
|
||||
Mutex::Lock _l(_tapsByDevice_m);
|
||||
_tapsByDevice[tap->deviceName()] = tap;
|
||||
}
|
||||
{
|
||||
Mutex::Lock _l(_tapsByMac_m);
|
||||
_tapsByMac[mac] = tap;
|
||||
@ -73,10 +69,6 @@ void TestEthernetTapFactory::close(EthernetTap *tap,bool destroyPersistentDevice
|
||||
Mutex::Lock _l(_taps_m);
|
||||
_taps.erase(tapp);
|
||||
}
|
||||
{
|
||||
Mutex::Lock _l(_tapsByDevice_m);
|
||||
_tapsByDevice.erase(tapp->deviceName());
|
||||
}
|
||||
{
|
||||
Mutex::Lock _l(_tapsByMac_m);
|
||||
_tapsByMac.erase(tapp->mac());
|
||||
|
@ -68,45 +68,10 @@ public:
|
||||
return t->second;
|
||||
}
|
||||
|
||||
inline SharedPtr<TestEthernetTap> getByDevice(const std::string &dev) const
|
||||
{
|
||||
Mutex::Lock _l(_tapsByDevice_m);
|
||||
std::map< std::string,SharedPtr<TestEthernetTap> >::const_iterator t(_tapsByDevice.find(dev));
|
||||
if (t == _tapsByDevice.end())
|
||||
return SharedPtr<TestEthernetTap>();
|
||||
return t->second;
|
||||
}
|
||||
|
||||
inline SharedPtr<TestEthernetTap> getFirst() const
|
||||
{
|
||||
Mutex::Lock _l(_taps_m);
|
||||
if (_taps.empty())
|
||||
return SharedPtr<TestEthernetTap>();
|
||||
return *(_taps.begin());
|
||||
}
|
||||
|
||||
inline SharedPtr<TestEthernetTap> getRandom() const
|
||||
{
|
||||
Mutex::Lock _l(_taps_m);
|
||||
Mutex::Lock _l2(_prng_m);
|
||||
if (_taps.empty())
|
||||
return SharedPtr<TestEthernetTap>();
|
||||
unsigned int x = (const_cast<CMWC4096 *>(&_prng))->next32() % (unsigned int)_taps.size();
|
||||
unsigned int i = 0;
|
||||
for(std::set< SharedPtr<TestEthernetTap> >::const_iterator t(_taps.begin());t!=_taps.end();++t) {
|
||||
if (i++ == x)
|
||||
return *t;
|
||||
}
|
||||
return SharedPtr<TestEthernetTap>(); // never reached
|
||||
}
|
||||
|
||||
private:
|
||||
std::set< SharedPtr<TestEthernetTap> > _taps;
|
||||
Mutex _taps_m;
|
||||
|
||||
std::map<std::string,SharedPtr<TestEthernetTap> > _tapsByDevice;
|
||||
Mutex _tapsByDevice_m;
|
||||
|
||||
std::map<MAC,SharedPtr<TestEthernetTap> > _tapsByMac;
|
||||
Mutex _tapsByMac_m;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user