From 4fbb098daa349a663015426d1210f1b59d0478c4 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Thu, 23 Oct 2014 16:46:09 -0700 Subject: [PATCH] Testnet work... getting there! --- control/NodeControlService.cpp | 18 -- make-mac.mk | 9 +- node/Node.cpp | 16 -- node/Node.hpp | 17 -- testnet.cpp | 362 +++++++++++++++++++++++++++++ testnet/SimNet.cpp | 43 +--- testnet/SimNet.hpp | 15 +- testnet/SimNetSocketManager.cpp | 17 +- testnet/SimNetSocketManager.hpp | 7 +- testnet/TestEthernetTapFactory.cpp | 8 - testnet/TestEthernetTapFactory.hpp | 35 --- 11 files changed, 398 insertions(+), 149 deletions(-) create mode 100644 testnet.cpp diff --git a/control/NodeControlService.cpp b/control/NodeControlService.cpp index 604c09178..c4edc1323 100644 --- a/control/NodeControlService.cpp +++ b/control/NodeControlService.cpp @@ -120,7 +120,6 @@ void NodeControlService::_doCommand(IpcConnection *ipcc,const char *commandLine) ipcc->printf("200 help leave "ZT_EOL_S); ipcc->printf("200 help terminate []"ZT_EOL_S); ipcc->printf("200 help updatecheck"ZT_EOL_S); - //ipcc->printf("200 help inject "); } 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()); } diff --git a/make-mac.mk b/make-mac.mk index 3868b7cf9..2eced36f9 100644 --- a/make-mac.mk +++ b/make-mac.mk @@ -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 diff --git a/node/Node.cpp b/node/Node.cpp index 5990b83a3..07f6637b7 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -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(RR->nc->network(nwid)); - if (network) - return network->tapInjectPacketFromHost(MAC(from,6),MAC(to,6),etherType,data,len); - return false; -} - class _VersionStringMaker { public: diff --git a/node/Node.hpp b/node/Node.hpp index 1b338b220..75bc7a8ba 100644 --- a/node/Node.hpp +++ b/node/Node.hpp @@ -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(); diff --git a/testnet.cpp b/testnet.cpp new file mode 100644 index 000000000..df70e40e0 --- /dev/null +++ b/testnet.cpp @@ -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 . + * + * -- + * + * 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 +#include +#include + +#include +#include +#include + +#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 +#else +#include +#include +#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
initSupernodes() +{ + Dictionary supernodes; + std::vector< std::pair > snids; + std::map dir(Utils::listDirectory(basePath.c_str())); + + for(std::map::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(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
newNodes; + + for(std::vector< std::pair >::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
scanForNewNodes() +{ + std::vector
newNodes; + std::map dir(Utils::listDirectory(basePath.c_str())); + + for(std::map::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 &cmd) +{ + printf("---------- help"ZT_EOL_S); + printf("---------- mksn "ZT_EOL_S); + printf("---------- mkn "ZT_EOL_S); + printf("---------- list"ZT_EOL_S); + printf("---------- join
"ZT_EOL_S); + printf("---------- leave
"ZT_EOL_S); + printf("---------- listnetworks
"ZT_EOL_S); + printf("---------- listpeers
"ZT_EOL_S); + printf("---------- alltoall"ZT_EOL_S); + printf("---------- quit"ZT_EOL_S) +} + +static void doMKSN(const std::vector &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 nodes(initSupernodes()); + for(std::vector
::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 &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 &cmd) +{ +} + +static void doJoin(const std::vector &cmd) +{ +} + +static void doLeave(const std::vector &cmd) +{ +} + +static void doListNetworks(const std::vector &cmd) +{ +} + +static void doListPeers(const std::vector &cmd) +{ +} + +static void doAllToAll(const std::vector &cmd) +{ +} + +int main(int argc,char **argv) +{ + char linebuf[1024]; + + if (argc <= 1) { + fprintf(stderr,"Usage: %s "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
snodes(initSupernodes()); + if (snodes.empty()) { + printf("---------- no existing network found; use 'mksn' to create one."ZT_EOL_S); + } else { + for(std::vector
::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
nodes(scanForNewNodes()); + for(std::vector
::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 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; +} diff --git a/testnet/SimNet.cpp b/testnet/SimNet.cpp index a644a9bcf..3349d5c24 100644 --- a/testnet/SimNet.cpp +++ b/testnet/SimNet.cpp @@ -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 SimNet::all() -{ - std::vector 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 diff --git a/testnet/SimNet.hpp b/testnet/SimNet.hpp index 6f7c5c118..4fdd69399 100644 --- a/testnet/SimNet.hpp +++ b/testnet/SimNet.hpp @@ -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 all(); - private: - std::map< InetAddress,SimNetSocketManager > _endpoints; - CMWC4096 _prng; + std::map< InetAddress,SimNetSocketManager * > _endpoints; Mutex _lock; }; diff --git a/testnet/SimNetSocketManager.cpp b/testnet/SimNetSocketManager.cpp index f6f241843..c75c864f8 100644 --- a/testnet/SimNetSocketManager.cpp +++ b/testnet/SimNetSocketManager.cpp @@ -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 &,void *,const InetAddress &,Buffer &),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(); } } } diff --git a/testnet/SimNetSocketManager.hpp b/testnet/SimNetSocketManager.hpp index 031cbd0c2..69f49556a 100644 --- a/testnet/SimNetSocketManager.hpp +++ b/testnet/SimNetSocketManager.hpp @@ -32,7 +32,7 @@ #include #include -#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; } /** diff --git a/testnet/TestEthernetTapFactory.cpp b/testnet/TestEthernetTapFactory.cpp index c4a8a9889..836f586e3 100644 --- a/testnet/TestEthernetTapFactory.cpp +++ b/testnet/TestEthernetTapFactory.cpp @@ -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()); diff --git a/testnet/TestEthernetTapFactory.hpp b/testnet/TestEthernetTapFactory.hpp index 5327b844a..57d195d27 100644 --- a/testnet/TestEthernetTapFactory.hpp +++ b/testnet/TestEthernetTapFactory.hpp @@ -68,45 +68,10 @@ public: return t->second; } - inline SharedPtr getByDevice(const std::string &dev) const - { - Mutex::Lock _l(_tapsByDevice_m); - std::map< std::string,SharedPtr >::const_iterator t(_tapsByDevice.find(dev)); - if (t == _tapsByDevice.end()) - return SharedPtr(); - return t->second; - } - - inline SharedPtr getFirst() const - { - Mutex::Lock _l(_taps_m); - if (_taps.empty()) - return SharedPtr(); - return *(_taps.begin()); - } - - inline SharedPtr getRandom() const - { - Mutex::Lock _l(_taps_m); - Mutex::Lock _l2(_prng_m); - if (_taps.empty()) - return SharedPtr(); - unsigned int x = (const_cast(&_prng))->next32() % (unsigned int)_taps.size(); - unsigned int i = 0; - for(std::set< SharedPtr >::const_iterator t(_taps.begin());t!=_taps.end();++t) { - if (i++ == x) - return *t; - } - return SharedPtr(); // never reached - } - private: std::set< SharedPtr > _taps; Mutex _taps_m; - std::map > _tapsByDevice; - Mutex _tapsByDevice_m; - std::map > _tapsByMac; Mutex _tapsByMac_m;