diff options
author | Adam Ierymenko <adam.ierymenko@gmail.com> | 2015-04-10 11:42:02 -0700 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@gmail.com> | 2015-04-10 11:42:02 -0700 |
commit | 7576911951781baf8730ee3e166cb6efc73322bf (patch) | |
tree | 33376b1334eb415cbecc4068eaeb6cf9ce4d4144 /attic | |
parent | 9e651b39e416171812d0dd3835a0cb9958aed264 (diff) | |
download | infinitytier-7576911951781baf8730ee3e166cb6efc73322bf.tar.gz infinitytier-7576911951781baf8730ee3e166cb6efc73322bf.zip |
Temporarily shelve testnet/ -- will resurrect self-contained testnet later perhaps, but probably will not by the time next version ships. Was mostly for debugging multicast anyway and that is now quite stable.
Diffstat (limited to 'attic')
-rw-r--r-- | attic/testnet/MTQ.hpp | 181 | ||||
-rw-r--r-- | attic/testnet/README.md | 36 | ||||
-rw-r--r-- | attic/testnet/SimNet.cpp | 68 | ||||
-rw-r--r-- | attic/testnet/SimNet.hpp | 71 | ||||
-rw-r--r-- | attic/testnet/SimNetSocketManager.cpp | 90 | ||||
-rw-r--r-- | attic/testnet/SimNetSocketManager.hpp | 124 | ||||
-rw-r--r-- | attic/testnet/TestEthernetTap.cpp | 150 | ||||
-rw-r--r-- | attic/testnet/TestEthernetTap.hpp | 124 | ||||
-rw-r--r-- | attic/testnet/TestEthernetTapFactory.cpp | 79 | ||||
-rw-r--r-- | attic/testnet/TestEthernetTapFactory.hpp | 91 |
10 files changed, 1014 insertions, 0 deletions
diff --git a/attic/testnet/MTQ.hpp b/attic/testnet/MTQ.hpp new file mode 100644 index 00000000..9f421188 --- /dev/null +++ b/attic/testnet/MTQ.hpp @@ -0,0 +1,181 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, Inc. 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_MTQ_HPP +#define ZT_MTQ_HPP + +#include <stdlib.h> +#include <stdint.h> + +#include <queue> + +#include "../node/Constants.hpp" +#include "../node/NonCopyable.hpp" +#include "../node/Utils.hpp" + +#ifdef __WINDOWS__ +#include <Windows.h> +#else +#include <time.h> +#include <pthread.h> +#endif + +namespace ZeroTier { + +/** + * A synchronized multithreaded FIFO queue + * + * This is designed for a use case where one thread pushes, the + * other pops. + */ +template<typename T> +class MTQ : NonCopyable +{ +public: + MTQ() + { +#ifdef __WINDOWS__ + _sem = CreateSemaphore(NULL,0,0x7fffffff,NULL); + InitializeCriticalSection(&_cs); +#else + pthread_mutex_init(&_mh,(const pthread_mutexattr_t *)0); + pthread_cond_init(&_cond,(const pthread_condattr_t *)0); +#endif + } + + ~MTQ() + { +#ifdef __WINDOWS__ + CloseHandle(_sem); + DeleteCriticalSection(&_cs); +#else + pthread_cond_destroy(&_cond); + pthread_mutex_destroy(&_mh); +#endif + } + + /** + * Push something onto the end of the FIFO and signal waiting thread(s) + * + * @param v Value to push + */ + inline void push(const T &v) + { +#ifdef __WINDOWS__ + EnterCriticalSection(&_cs); + try { + _q.push(v); + LeaveCriticalSection(&_cs); + ReleaseSemaphore(_sem,1,NULL); + } catch ( ... ) { + LeaveCriticalSection(&_cs); + throw; + } +#else + pthread_mutex_lock(const_cast <pthread_mutex_t *>(&_mh)); + try { + _q.push(v); + pthread_mutex_unlock(const_cast <pthread_mutex_t *>(&_mh)); + pthread_cond_signal(const_cast <pthread_cond_t *>(&_cond)); + } catch ( ... ) { + pthread_mutex_unlock(const_cast <pthread_mutex_t *>(&_mh)); + throw; + } +#endif + } + + /** + * Pop fron queue with optional timeout + * + * @param v Result parameter to set to next value + * @param ms Milliseconds timeout or 0 for none + * @return True if v was set to something, false on timeout + */ + inline bool pop(T &v,unsigned long ms = 0) + { +#ifdef __WINDOWS__ + if (ms > 0) + WaitForSingleObject(_sem,(DWORD)ms); + else WaitForSingleObject(_sem,INFINITE); + EnterCriticalSection(&_cs); + try { + if (_q.empty()) { + LeaveCriticalSection(&_cs); + return false; + } else { + v = _q.front(); + _q.pop(); + LeaveCriticalSection(&_cs); + return true; + } + } catch ( ... ) { + LeaveCriticalSection(&_cs); + throw; + } +#else + pthread_mutex_lock(const_cast <pthread_mutex_t *>(&_mh)); + try { + if (_q.empty()) { + if (ms > 0) { + uint64_t when = Utils::now() + (uint64_t)ms; + struct timespec ts; + ts.tv_sec = (unsigned long)(when / 1000); + ts.tv_nsec = (unsigned long)(when % 1000) * (unsigned long)1000000; + pthread_cond_timedwait(const_cast <pthread_cond_t *>(&_cond),const_cast <pthread_mutex_t *>(&_mh),&ts); + } else { + pthread_cond_wait(const_cast <pthread_cond_t *>(&_cond),const_cast <pthread_mutex_t *>(&_mh)); + } + if (_q.empty()) { + pthread_mutex_unlock(const_cast <pthread_mutex_t *>(&_mh)); + return false; + } + } + v = _q.front(); + _q.pop(); + pthread_mutex_unlock(const_cast <pthread_mutex_t *>(&_mh)); + return true; + } catch ( ... ) { + pthread_mutex_unlock(const_cast <pthread_mutex_t *>(&_mh)); + throw; + } +#endif + } + +private: + std::queue<T> _q; +#ifdef __WINDOWS__ + HANDLE _sem; + CRITICAL_SECTION _cs; +#else + pthread_cond_t _cond; + pthread_mutex_t _mh; +#endif +}; + +} // namespace ZeroTier + +#endif diff --git a/attic/testnet/README.md b/attic/testnet/README.md new file mode 100644 index 00000000..3d3b3b54 --- /dev/null +++ b/attic/testnet/README.md @@ -0,0 +1,36 @@ +Headless Test Network +====== + +The code in testnet.cpp (in base) and here in testnet/ is for running headless ZeroTier One test networks. + +To build, type (from base) "make testnet". This will build the *zerotier-testnet* binary. Then run it with a directory to use for temporary node home directory storage as a parameter, e.g. "./zerotier-testnet /tmp/zttestnet". + +Type **help** for help. + +Right now the testnet simulates a perfect IP network and allows you to perform unicast and multicast tests. This is useful for verifying the basic correctness of everything under ideal conditions, and for smoke testing. In the future support for NAT emulation, packet loss, and other test features will be added to make this a more full-blown test suite. + +When you start the testnet for the first time, no nodes will exist. You have to create some. First, create supernodes with **mksn**. Create as many as you want. Once you've created supernodes (you can only do this once per testnet) you can create regular nodes with **mkn**. + +Once everything is created use **list** to check the status. + +Each node will create a couple threads, so if your OS imposes a limit this might cause some of your virtual nodes to stick in *INITIALIZING* status as shown in the **list** command. If this happens you might want to blow away the contents of your temp directory and try again with fewer nodes. + +Each node will get a home at the test path you specified, so quitting with **quit** and re-entering will reload the same test network. + +Next you'll need to join your nodes to a virtual ZeroTier network. ZeroTier supports a built-in "fake" public network with the ID **ffffffffffffffff**. This network is for testing and is convenient to use here. It's also possible to set up the netconf-master within one of your test nodes, but doing so is beyond the scope of this doc (for now, but if your clever you can probably figure it out). Verify by doing **listnetworks**. + +Now you can send some packets. Try: + + unicast * * ffffffffffffffff 24 60 + +That will do a unicast all-to-all test and report results. At first latencies might seem high, especially for a headless fake IP network. If you try it again you'll see them drop to zero or nearly so, since everyone will have executed a peer to peer connection. + + multicast <some node's 10-digit ZT address> * ffffffffffffffff 24 60 + +This will send a multicast packet to ff:ff:ff:ff:ff:ff (broadcast) and report back who receives it. You should see multicast propagation limited to 32 nodes, since this is the setting for multicast limit on the fake test network (and the default if not overridden in netconf). Multicast will show the same "warm up" behavior as unicast. + +Typing just "." will execute the same testnet command again. + +The first 10-digit field of each response is the ZeroTier node doing the sending or receiving. A prefix of "----------" is used for general responses to make everything line up neatly on the screen. We recommend using a wide terminal emulator. + +Enjoy! diff --git a/attic/testnet/SimNet.cpp b/attic/testnet/SimNet.cpp new file mode 100644 index 00000000..c52c4fdf --- /dev/null +++ b/attic/testnet/SimNet.cpp @@ -0,0 +1,68 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, Inc. + * + * 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 "SimNet.hpp" + +#include "../node/Constants.hpp" +#include "../node/Utils.hpp" + +namespace ZeroTier { + +SimNet::SimNet() +{ +} + +SimNet::~SimNet() +{ +} + +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; + + SimNetSocketManager *sm = new SimNetSocketManager(); + sm->_sn = this; + sm->_address = addr; + _endpoints[addr] = sm; + return sm; +} + +SimNetSocketManager *SimNet::get(const InetAddress &addr) +{ + Mutex::Lock _l(_lock); + std::map< InetAddress,SimNetSocketManager * >::iterator ep(_endpoints.find(addr)); + if (ep == _endpoints.end()) + return (SimNetSocketManager *)0; + return ep->second; +} + +} // namespace ZeroTier diff --git a/attic/testnet/SimNet.hpp b/attic/testnet/SimNet.hpp new file mode 100644 index 00000000..554df754 --- /dev/null +++ b/attic/testnet/SimNet.hpp @@ -0,0 +1,71 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, Inc. + * + * 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_SIMNET_HPP +#define ZT_SIMNET_HPP + +#include <map> +#include <vector> + +#include "../node/Constants.hpp" +#include "../node/InetAddress.hpp" +#include "../node/Mutex.hpp" + +#include "SimNetSocketManager.hpp" + +#define ZT_SIMNET_MAX_TESTNET_SIZE 1048576 + +namespace ZeroTier { + +/** + * A simulated headless IP network for testing + */ +class SimNet +{ +public: + SimNet(); + ~SimNet(); + + /** + * @return New endpoint or NULL on failure + */ + SimNetSocketManager *newEndpoint(const InetAddress &addr); + + /** + * @param addr Address to look up + * @return Endpoint or NULL if none + */ + SimNetSocketManager *get(const InetAddress &addr); + +private: + std::map< InetAddress,SimNetSocketManager * > _endpoints; + Mutex _lock; +}; + +} // namespace ZeroTier + +#endif diff --git a/attic/testnet/SimNetSocketManager.cpp b/attic/testnet/SimNetSocketManager.cpp new file mode 100644 index 00000000..5b8b97a0 --- /dev/null +++ b/attic/testnet/SimNetSocketManager.cpp @@ -0,0 +1,90 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, Inc. + * + * 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 "SimNetSocketManager.hpp" +#include "SimNet.hpp" + +#include "../node/Constants.hpp" +#include "../node/Socket.hpp" + +namespace ZeroTier { + +class SimNetSocket : public Socket +{ +public: + SimNetSocket(SimNetSocketManager *sm) : + Socket(ZT_SOCKET_TYPE_UDP_V4), + _parent(sm) {} + + virtual bool send(const InetAddress &to,const void *msg,unsigned int msglen) + { + SimNetSocketManager *dest = _parent->net()->get(to); + if (dest) + dest->enqueue(_parent->address(),msg,msglen); + return true; // we emulate UDP, which has no delivery guarantee semantics + } + + SimNetSocketManager *_parent; +}; + +SimNetSocketManager::SimNetSocketManager() : + _sn((SimNet *)0), // initialized by SimNet + _mySocket(new SimNetSocket(this)) +{ +} + +SimNetSocketManager::~SimNetSocketManager() +{ +} + +bool SimNetSocketManager::send(const InetAddress &to,bool tcp,bool autoConnectTcp,const void *msg,unsigned int msglen) +{ + if (tcp) + return false; // we emulate UDP + SimNetSocketManager *dest = _sn->get(to); + if (dest) + dest->enqueue(_address,msg,msglen); + return true; // we emulate UDP, which has no delivery guarantee semantics +} + +void SimNetSocketManager::poll(unsigned long timeout,void (*handler)(const SharedPtr<Socket> &,void *,const InetAddress &,Buffer<ZT_SOCKET_MAX_MESSAGE_LEN> &),void *arg) +{ + std::pair< InetAddress,Buffer<ZT_SOCKET_MAX_MESSAGE_LEN> > msg; + if ((_inbox.pop(msg,timeout))&&(msg.second.size())) + handler(_mySocket,arg,msg.first,msg.second); +} + +void SimNetSocketManager::whack() +{ + _inbox.push(std::pair< InetAddress,Buffer<ZT_SOCKET_MAX_MESSAGE_LEN> >()); +} + +void SimNetSocketManager::closeTcpSockets() +{ +} + +} // namespace ZeroTier diff --git a/attic/testnet/SimNetSocketManager.hpp b/attic/testnet/SimNetSocketManager.hpp new file mode 100644 index 00000000..b32372bf --- /dev/null +++ b/attic/testnet/SimNetSocketManager.hpp @@ -0,0 +1,124 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, Inc. + * + * 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_SIMNETSOCKETMANAGER_HPP +#define ZT_SIMNETSOCKETMANAGER_HPP + +#include <map> +#include <utility> +#include <vector> + +#include "../node/Constants.hpp" +#include "../node/SocketManager.hpp" +#include "../node/Mutex.hpp" + +#include "MTQ.hpp" + +namespace ZeroTier { + +class SimNet; + +/** + * Socket manager for an IP endpoint in a simulated network + */ +class SimNetSocketManager : public SocketManager +{ + friend class SimNet; + +public: + struct TransferStats + { + TransferStats() : received(0),sent(0) {} + unsigned long long received; + unsigned long long sent; + }; + + SimNetSocketManager(); + virtual ~SimNetSocketManager(); + + /** + * @return IP address of this simulated endpoint + */ + inline const InetAddress &address() const { return _address; } + + /** + * @return Local endpoint stats + */ + inline const TransferStats &totals() const { return _totals; } + + /** + * @param peer Peer IP address + * @return Transfer stats for this peer + */ + inline TransferStats stats(const InetAddress &peer) const + { + Mutex::Lock _l(_stats_m); + std::map< InetAddress,TransferStats >::const_iterator s(_stats.find(peer)); + if (s == _stats.end()) + return TransferStats(); + return s->second; + } + + /** + * @return Network to which this endpoint belongs + */ + inline SimNet *net() const { return _sn; } + + /** + * Enqueue data from another endpoint to be picked up on next poll() + * + * @param from Originating endpoint address + * @param data Data + * @param len Length of data in bytes + */ + inline void enqueue(const InetAddress &from,const void *data,unsigned int len) + { + _inbox.push(std::pair< InetAddress,Buffer<ZT_SOCKET_MAX_MESSAGE_LEN> >(from,Buffer<ZT_SOCKET_MAX_MESSAGE_LEN>(data,len))); + } + + virtual bool send(const InetAddress &to,bool tcp,bool autoConnectTcp,const void *msg,unsigned int msglen); + virtual void poll(unsigned long timeout,void (*handler)(const SharedPtr<Socket> &,void *,const InetAddress &,Buffer<ZT_SOCKET_MAX_MESSAGE_LEN> &),void *arg); + virtual void whack(); + virtual void closeTcpSockets(); + +private: + // These are set by SimNet after object creation + SimNet *_sn; + InetAddress _address; + + SharedPtr<Socket> _mySocket; + TransferStats _totals; + + MTQ< std::pair< InetAddress,Buffer<ZT_SOCKET_MAX_MESSAGE_LEN> > > _inbox; + + std::map< InetAddress,TransferStats > _stats; + Mutex _stats_m; +}; + +} // namespace ZeroTier + +#endif diff --git a/attic/testnet/TestEthernetTap.cpp b/attic/testnet/TestEthernetTap.cpp new file mode 100644 index 00000000..9cd6df5d --- /dev/null +++ b/attic/testnet/TestEthernetTap.cpp @@ -0,0 +1,150 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, Inc. + * + * 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 "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 { + +TestEthernetTap::TestEthernetTap( + const MAC &mac, + unsigned int mtu, + unsigned int metric, + uint64_t nwid, + const char *desiredDevice, + const char *friendlyName, + void (*handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &), + void *arg) : + EthernetTap("TestEthernetTap",mac,mtu,metric), + _nwid(nwid), + _handler(handler), + _arg(arg), + _enabled(true) +{ + static volatile unsigned int testTapCounter = 0; + + char tmp[64]; + 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); +} + +TestEthernetTap::~TestEthernetTap() +{ + static const TestFrame zf; // use a static empty frame because of weirdo G++ warning bug... + _pq.push(zf); // empty frame terminates thread + Thread::join(_thread); +} + +void TestEthernetTap::setEnabled(bool en) +{ + _enabled = en; +} + +bool TestEthernetTap::enabled() const +{ + return _enabled; +} + +bool TestEthernetTap::addIP(const InetAddress &ip) +{ + return true; +} + +bool TestEthernetTap::removeIP(const InetAddress &ip) +{ + return true; +} + +std::set<InetAddress> TestEthernetTap::ips() const +{ + return std::set<InetAddress>(); +} + +void TestEthernetTap::put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len) +{ + _gq.push(TestFrame(from,to,data,etherType,len)); +} + +std::string TestEthernetTap::deviceName() const +{ + return _dev; +} + +void TestEthernetTap::setFriendlyName(const char *friendlyName) +{ +} + +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 > _mtu)) + return false; + _pq.push(TestFrame(from,to,data,etherType & 0xffff,len)); + return true; +} + +void TestEthernetTap::threadMain() + throw() +{ + TestFrame f; + for(;;) { + if (_pq.pop(f,0)) { + if (f.len) { + try { + _handler(_arg,f.from,f.to,f.etherType,Buffer<4096>(f.data,f.len)); + } catch ( ... ) {} + } else break; + } + } +} + +} // namespace ZeroTier diff --git a/attic/testnet/TestEthernetTap.hpp b/attic/testnet/TestEthernetTap.hpp new file mode 100644 index 00000000..28092118 --- /dev/null +++ b/attic/testnet/TestEthernetTap.hpp @@ -0,0 +1,124 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, Inc. + * + * 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_TESTETHERNETTAP_HPP +#define ZT_TESTETHERNETTAP_HPP + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <string> + +#include "../node/Constants.hpp" +#include "../node/EthernetTap.hpp" +#include "../node/Thread.hpp" +#include "../node/Mutex.hpp" + +#include "MTQ.hpp" + +namespace ZeroTier { + +class TestEthernetTapFactory; + +/** + * Dummy Ethernet tap + * + * This tap device prints the contents of packets it receives on stdout + * and also prints outgoing packets when they are injected. It does not + * connect to any real tap or other interface. It's useful for running + * test networks. + */ +class TestEthernetTap : public EthernetTap +{ +public: + struct TestFrame + { + TestFrame() : from(),to(),timestamp(0),etherType(0),len(0) {} + TestFrame(const MAC &f,const MAC &t,const void *d,unsigned int et,unsigned int l) : + from(f), + to(t), + timestamp(Utils::now()), + etherType(et), + len(l) + { + memcpy(data,d,l); + } + + MAC from; + MAC to; + uint64_t timestamp; + unsigned int etherType; + unsigned int len; + char data[4096]; + }; + + TestEthernetTap( + const MAC &mac, + unsigned int mtu, + unsigned int metric, + uint64_t nwid, + const char *desiredDevice, + const char *friendlyName, + void (*handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &), + void *arg); + + virtual ~TestEthernetTap(); + + virtual void setEnabled(bool en); + virtual bool enabled() const; + virtual bool addIP(const InetAddress &ip); + virtual bool removeIP(const InetAddress &ip); + virtual std::set<InetAddress> ips() const; + virtual void put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len); + 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 uint64_t nwid() const { return _nwid; } + inline bool getNextReceivedFrame(TestFrame &v,unsigned long timeout) { return _gq.pop(v,timeout); } + + void threadMain() + throw(); + +private: + uint64_t _nwid; + + void (*_handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &); + void *_arg; + Thread _thread; + std::string _dev; + volatile bool _enabled; + + MTQ<TestFrame> _pq; + MTQ<TestFrame> _gq; +}; + +} // namespace ZeroTier + +#endif diff --git a/attic/testnet/TestEthernetTapFactory.cpp b/attic/testnet/TestEthernetTapFactory.cpp new file mode 100644 index 00000000..dfc5919e --- /dev/null +++ b/attic/testnet/TestEthernetTapFactory.cpp @@ -0,0 +1,79 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, Inc. + * + * 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 "TestEthernetTapFactory.hpp" +#include "TestEthernetTap.hpp" + +namespace ZeroTier { + +TestEthernetTapFactory::TestEthernetTapFactory() +{ +} + +TestEthernetTapFactory::~TestEthernetTapFactory() +{ + Mutex::Lock _l1(_taps_m); + Mutex::Lock _l2(_tapsByMac_m); + Mutex::Lock _l3(_tapsByNwid_m); + for(std::set<EthernetTap *>::iterator t(_taps.begin());t!=_taps.end();++t) + delete *t; +} + +EthernetTap *TestEthernetTapFactory::open( + const MAC &mac, + unsigned int mtu, + unsigned int metric, + uint64_t nwid, + const char *desiredDevice, + const char *friendlyName, + void (*handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &), + void *arg) +{ + TestEthernetTap *tap = new TestEthernetTap(mac,mtu,metric,nwid,desiredDevice,friendlyName,handler,arg); + Mutex::Lock _l1(_taps_m); + Mutex::Lock _l2(_tapsByMac_m); + Mutex::Lock _l3(_tapsByNwid_m); + _taps.insert(tap); + _tapsByMac[mac] = tap; + _tapsByNwid[nwid] = tap; + return tap; +} + +void TestEthernetTapFactory::close(EthernetTap *tap,bool destroyPersistentDevices) +{ + Mutex::Lock _l1(_taps_m); + Mutex::Lock _l2(_tapsByMac_m); + Mutex::Lock _l3(_tapsByNwid_m); + if (!tap) + return; + _taps.erase(tap); + _tapsByMac.erase(tap->mac()); + _tapsByNwid.erase(((TestEthernetTap *)tap)->nwid()); + delete tap; +} + +} // namespace ZeroTier diff --git a/attic/testnet/TestEthernetTapFactory.hpp b/attic/testnet/TestEthernetTapFactory.hpp new file mode 100644 index 00000000..0ef1619a --- /dev/null +++ b/attic/testnet/TestEthernetTapFactory.hpp @@ -0,0 +1,91 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, Inc. + * + * 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_TESTETHERNETTAPFACTORY_HPP +#define ZT_TESTETHERNETTAPFACTORY_HPP + +#include <vector> +#include <string> +#include <set> + +#include "../node/EthernetTapFactory.hpp" +#include "../node/Mutex.hpp" +#include "../node/MAC.hpp" +#include "TestEthernetTap.hpp" + +namespace ZeroTier { + +class TestEthernetTapFactory : public EthernetTapFactory +{ +public: + TestEthernetTapFactory(); + virtual ~TestEthernetTapFactory(); + + virtual EthernetTap *open( + const MAC &mac, + unsigned int mtu, + unsigned int metric, + uint64_t nwid, + const char *desiredDevice, + const char *friendlyName, + void (*handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &), + void *arg); + + virtual void close(EthernetTap *tap,bool destroyPersistentDevices); + + inline TestEthernetTap *getByMac(const MAC &mac) const + { + Mutex::Lock _l(_tapsByMac_m); + std::map< MAC,TestEthernetTap * >::const_iterator t(_tapsByMac.find(mac)); + if (t == _tapsByMac.end()) + return (TestEthernetTap *)0; + return t->second; + } + + inline TestEthernetTap *getByNwid(uint64_t nwid) const + { + Mutex::Lock _l(_tapsByNwid_m); + std::map< uint64_t,TestEthernetTap * >::const_iterator t(_tapsByNwid.find(nwid)); + if (t == _tapsByNwid.end()) + return (TestEthernetTap *)0; + return t->second; + } + +private: + std::set< EthernetTap * > _taps; + Mutex _taps_m; + + std::map< MAC,TestEthernetTap * > _tapsByMac; + Mutex _tapsByMac_m; + + std::map< uint64_t,TestEthernetTap * > _tapsByNwid; + Mutex _tapsByNwid_m; +}; + +} // namespace ZeroTier + +#endif |