diff --git a/ZeroTierUI/mainwindow.cpp b/ZeroTierUI/mainwindow.cpp index 1b3f57cd5..ffb27af12 100644 --- a/ZeroTierUI/mainwindow.cpp +++ b/ZeroTierUI/mainwindow.cpp @@ -121,7 +121,8 @@ MainWindow::MainWindow(QWidget *parent) : ui->bottomContainerWidget->setVisible(false); ui->networkListWidget->setVisible(false); - this->pollServiceTimerId = this->startTimer(1000); + this->firstTimerTick = true; + this->pollServiceTimerId = this->startTimer(200); this->cyclesSinceResponseFromService = 0; } @@ -133,15 +134,19 @@ MainWindow::~MainWindow() mainWindow = (MainWindow *)0; } -void MainWindow::timerEvent(QTimerEvent *event) +void MainWindow::timerEvent(QTimerEvent *event) // event can be null since code also calls this directly { - event->accept(); - if (this->isHidden()) return; - if (pollServiceTimerId < 0) + if (this->pollServiceTimerId < 0) return; + if (this->firstTimerTick) { + this->firstTimerTick = false; + this->killTimer(this->pollServiceTimerId); + this->pollServiceTimerId = this->startTimer(1500); + } + if (!zeroTierClient) { std::string authToken; if (!ZeroTier::Utils::readFile(ZeroTier::Node::LocalClient::authTokenDefaultUserPath().c_str(),authToken)) { diff --git a/ZeroTierUI/mainwindow.h b/ZeroTierUI/mainwindow.h index 92cfabf1a..c4bb72ae7 100644 --- a/ZeroTierUI/mainwindow.h +++ b/ZeroTierUI/mainwindow.h @@ -86,6 +86,7 @@ private: QString myAddress; QString myStatus; QString myVersion; + bool firstTimerTick; int pollServiceTimerId; unsigned int numPeers; unsigned int cyclesSinceResponseFromService; diff --git a/ZeroTierUI/stylesheet.css b/ZeroTierUI/stylesheet.css index 9639f2b53..31904df54 100644 --- a/ZeroTierUI/stylesheet.css +++ b/ZeroTierUI/stylesheet.css @@ -64,6 +64,9 @@ QListWidget.ipAddressList::item { } QListWidget.ipAddressList::item:selected { background: transparent; + border-top: 0; + border-left: 0; + border-right: 0; border-bottom: 1px solid transparent; } QListWidget.ipAddressList::item:hover { diff --git a/node/EthernetTap.cpp b/node/EthernetTap.cpp index c6decba8c..b669c489c 100644 --- a/node/EthernetTap.cpp +++ b/node/EthernetTap.cpp @@ -336,8 +336,6 @@ EthernetTap::EthernetTap( } } - whack(); // turns on IPv6 on OSX - ::pipe(_shutdownSignalPipe); _thread = Thread::start(this); @@ -378,7 +376,7 @@ EthernetTap::~EthernetTap() #endif // __APPLE__ } -#ifdef __APPLE__ +/* void EthernetTap::whack() { const char *ipconfig = UNIX_COMMANDS[ZT_MAC_IPCONFIG_COMMAND]; @@ -393,9 +391,7 @@ void EthernetTap::whack() } } } -#else -void EthernetTap::whack() {} -#endif // __APPLE__ / !__APPLE__ +*/ void EthernetTap::setDisplayName(const char *dn) { @@ -979,7 +975,8 @@ EthernetTap::EthernetTap( _arg(arg), _tap(INVALID_HANDLE_VALUE), _injectSemaphore(INVALID_HANDLE_VALUE), - _run(true) + _run(true), + _initialized(false) { char subkeyName[4096]; char subkeyClass[4096]; @@ -1203,11 +1200,15 @@ EthernetTap::EthernetTap( // Start background thread that actually performs I/O _injectSemaphore = CreateSemaphore(NULL,0,1,NULL); _thread = Thread::start(this); + + // Certain functions can now work (e.g. ips()) + _initialized = true; } EthernetTap::~EthernetTap() { _run = false; + ReleaseSemaphore(_injectSemaphore,1,NULL); Thread::join(_thread); CloseHandle(_tap); @@ -1237,12 +1238,10 @@ EthernetTap::~EthernetTap() } } -void EthernetTap::whack() -{ -} - void EthernetTap::setDisplayName(const char *dn) { + if (!_initialized) + return; HKEY ifp; if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,(std::string("SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\") + _myDeviceInstanceId).c_str(),0,KEY_READ|KEY_WRITE,&ifp) == ERROR_SUCCESS) { RegSetKeyValueA(ifp,"Connection","Name",REG_SZ,(LPCVOID)dn,(DWORD)(strlen(dn)+1)); @@ -1252,6 +1251,8 @@ void EthernetTap::setDisplayName(const char *dn) bool EthernetTap::addIP(const InetAddress &ip) { + if (!_initialized) + return false; if (!ip.netmaskBits()) // sanity check... netmask of 0.0.0.0 is WUT? return false; @@ -1299,6 +1300,8 @@ bool EthernetTap::addIP(const InetAddress &ip) bool EthernetTap::removeIP(const InetAddress &ip) { + if (!_initialized) + return false; try { MIB_UNICASTIPADDRESS_TABLE *ipt = (MIB_UNICASTIPADDRESS_TABLE *)0; std::pair ifidx = _findAdapterByGuid(_deviceGuid); @@ -1339,6 +1342,9 @@ std::set EthernetTap::ips() const static const InetAddress linkLocalLoopback("fe80::1",64); // what is this and why does Windows assign it? std::set addrs; + if (!_initialized) + return addrs; + try { MIB_UNICASTIPADDRESS_TABLE *ipt = (MIB_UNICASTIPADDRESS_TABLE *)0; std::pair ifidx = _findAdapterByGuid(_deviceGuid); @@ -1369,6 +1375,8 @@ std::set EthernetTap::ips() const void EthernetTap::put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len) { + if (!_initialized) + return; if (len > (ZT_IF_MTU)) return; @@ -1398,6 +1406,9 @@ std::string EthernetTap::persistentId() const bool EthernetTap::updateMulticastGroups(std::set &groups) { + if (!_initialized) + return false; + std::set newGroups; // Ensure that groups are added for each IP... this handles the MAC:ADI @@ -1456,7 +1467,7 @@ void EthernetTap::threadMain() HANDLE wait4[3]; wait4[0] = _injectSemaphore; wait4[1] = _tapOvlRead.hEvent; - wait4[2] = _tapOvlWrite.hEvent; + wait4[2] = _tapOvlWrite.hEvent; // only included if writeInProgress is true ReadFile(_tap,_tapReadBuf,sizeof(_tapReadBuf),NULL,&_tapOvlRead); bool writeInProgress = false; diff --git a/node/EthernetTap.hpp b/node/EthernetTap.hpp index 15e7aedef..799885db5 100644 --- a/node/EthernetTap.hpp +++ b/node/EthernetTap.hpp @@ -94,11 +94,6 @@ public: */ ~EthernetTap(); - /** - * Perform OS dependent actions on network configuration change detection - */ - void whack(); - /** * Set the user display name for this connection * @@ -245,6 +240,7 @@ private: std::queue< std::pair< Array,unsigned int > > _injectPending; Mutex _injectPending_m; volatile bool _run; + volatile bool _initialized; #endif }; diff --git a/node/Network.cpp b/node/Network.cpp index 37d93b998..8ba597ba4 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -46,6 +46,7 @@ const char *Network::statusString(const Status s) throw() { switch(s) { + case NETWORK_INITIALIZING: return "INITIALIZING"; case NETWORK_WAITING_FOR_FIRST_AUTOCONF: return "WAITING_FOR_FIRST_AUTOCONF"; case NETWORK_OK: return "OK"; case NETWORK_ACCESS_DENIED: return "ACCESS_DENIED"; @@ -56,6 +57,8 @@ const char *Network::statusString(const Status s) Network::~Network() { + Thread::join(_setupThread); + std::string devPersistentId(_tap->persistentId()); delete _tap; @@ -73,46 +76,50 @@ Network::~Network() SharedPtr Network::newInstance(const RuntimeEnvironment *renv,uint64_t id) { - // Tag to identify tap device -- used on some OSes like Windows - char tag[32]; - Utils::snprintf(tag,sizeof(tag),"%.16llx",(unsigned long long)id); + /* We construct Network via a static method to ensure that it is immediately + * wrapped in a SharedPtr<>. Otherwise if there is traffic on the Ethernet + * tap device, a SharedPtr<> wrap can occur in the Ethernet frame handler + * that then causes the Network instance to be deleted before it is finished + * being constructed. C++ edge cases, how I love thee. */ - // We construct Network via a static method to ensure that it is immediately - // wrapped in a SharedPtr<>. Otherwise if there is traffic on the Ethernet - // tap device, a SharedPtr<> wrap can occur in the Ethernet frame handler - // that then causes the Network instance to be deleted before it is finished - // being constructed. C++ edge cases, how I love thee. SharedPtr nw(new Network()); nw->_id = id; - nw->_ready = false; // disable handling of Ethernet frames during construct + nw->_mac = renv->identity.address().toMAC(); nw->_r = renv; - nw->_tap = new EthernetTap(renv,tag,renv->identity.address().toMAC(),ZT_IF_MTU,&_CBhandleTapData,nw.ptr()); + nw->_tap = (EthernetTap *)0; nw->_lastConfigUpdate = 0; - nw->_status = NETWORK_WAITING_FOR_FIRST_AUTOCONF; nw->_destroyOnDelete = false; + nw->_netconfFailure = NETCONF_FAILURE_NONE; + if (nw->controller() == renv->identity.address()) // netconf masters can't really join networks throw std::runtime_error("cannot join a network for which I am the netconf master"); - nw->_restoreState(); - nw->_ready = true; // enable handling of Ethernet frames - nw->requestConfiguration(); + + nw->_setupThread = Thread::start(nw.ptr()); return nw; } -void Network::setConfiguration(const Dictionary &conf,bool saveToDisk) +bool Network::setConfiguration(const Dictionary &conf,bool saveToDisk) { + Mutex::Lock _l(_lock); + + EthernetTap *t = _tap; + if (!t) { + TRACE("BUG: setConfiguration() called while tap is null!"); + return false; // can't accept config in initialization state + } + try { SharedPtr newConfig(new NetworkConfig(conf)); if ((newConfig->networkId() == _id)&&(newConfig->issuedTo() == _r->identity.address())) { - Mutex::Lock _l(_lock); _config = newConfig; if (newConfig->staticIps().size()) - _tap->setIps(newConfig->staticIps()); - _tap->setDisplayName((std::string("ZeroTier One [") + newConfig->name() + "]").c_str()); + t->setIps(newConfig->staticIps()); + t->setDisplayName((std::string("ZeroTier One [") + newConfig->name() + "]").c_str()); _lastConfigUpdate = Utils::now(); - _status = NETWORK_OK; + _netconfFailure = NETCONF_FAILURE_NONE; if (saveToDisk) { std::string confPath(_r->homePath + ZT_PATH_SEPARATOR_S + "networks.d" + ZT_PATH_SEPARATOR_S + idString() + ".conf"); @@ -122,6 +129,8 @@ void Network::setConfiguration(const Dictionary &conf,bool saveToDisk) Utils::lockDownFile(confPath.c_str(),false); } } + + return true; } else { LOG("ignored invalid configuration for network %.16llx (configuration contains mismatched network ID or issued-to address)",(unsigned long long)_id); } @@ -130,10 +139,15 @@ void Network::setConfiguration(const Dictionary &conf,bool saveToDisk) } catch ( ... ) { LOG("ignored invalid configuration for network %.16llx (unknown exception)",(unsigned long long)_id); } + + return false; } void Network::requestConfiguration() { + if (!_tap) + return; // don't bother requesting until we are initialized + if (controller() == _r->identity.address()) { // netconf master cannot be a member of its own nets LOG("unable to request network configuration for network %.16llx: I am the network master, cannot query self",(unsigned long long)_id); @@ -190,6 +204,7 @@ bool Network::isAllowed(const Address &peer) const void Network::clean() { Mutex::Lock _l(_lock); + if ((_config)&&(_config->isOpen())) { // Open (public) networks do not track certs or cert pushes at all. _membershipCertificates.clear(); @@ -215,7 +230,7 @@ void Network::clean() void Network::_CBhandleTapData(void *arg,const MAC &from,const MAC &to,unsigned int etherType,const Buffer<4096> &data) { - if (!((Network *)arg)->isUp()) + if (((Network *)arg)->status() != NETWORK_OK) return; const RuntimeEnvironment *_r = ((Network *)arg)->_r; @@ -250,6 +265,31 @@ void Network::_pushMembershipCertificate(const Address &peer,bool force,uint64_t } } +void Network::threadMain() +{ + try { + // Setup thread -- this exits when tap is constructed. It's here + // because opening the tap can take some time on some platforms. + char tag[32]; + Utils::snprintf(tag,sizeof(tag),"%.16llx",(unsigned long long)_id); + _tap = new EthernetTap(_r,tag,_mac,ZT_IF_MTU,&_CBhandleTapData,this); + } catch (std::exception &exc) { + LOG("network %.16llx failed to initialize: %s",_id,exc.what()); + _netconfFailure = NETCONF_FAILURE_INIT_FAILED; + } catch ( ... ) { + LOG("network %.16llx failed to initialize: unknown error",_id); + _netconfFailure = NETCONF_FAILURE_INIT_FAILED; + } + + try { + _restoreState(); + requestConfiguration(); + } catch ( ... ) { + TRACE("BUG: exception in network setup thread in _restoreState() or requestConfiguration()!"); + _lastConfigUpdate = 0; // call requestConfiguration() again + } +} + void Network::_restoreState() { if (!_id) diff --git a/node/Network.hpp b/node/Network.hpp index f41e75021..af51e3682 100644 --- a/node/Network.hpp +++ b/node/Network.hpp @@ -53,6 +53,7 @@ #include "BandwidthAccount.hpp" #include "NetworkConfig.hpp" #include "CertificateOfMembership.hpp" +#include "Thread.hpp" namespace ZeroTier { @@ -91,6 +92,9 @@ private: * If there is no saved state, a dummy .conf is created on disk to remember * this network across restarts. * + * This can be a time consuming operation on some platforms (cough Windows + * cough). + * * @param renv Runtime environment * @param id Network ID * @return Reference counted pointer to new network @@ -109,10 +113,12 @@ public: */ enum Status { + NETWORK_INITIALIZING, NETWORK_WAITING_FOR_FIRST_AUTOCONF, NETWORK_OK, NETWORK_ACCESS_DENIED, - NETWORK_NOT_FOUND + NETWORK_NOT_FOUND, + NETWORK_INITIALIZATION_FAILED }; /** @@ -127,11 +133,6 @@ public: */ inline uint64_t id() const throw() { return _id; } - /** - * @return Ethernet tap - */ - inline EthernetTap &tap() throw() { return *_tap; } - /** * @return Address of network's controlling node */ @@ -155,7 +156,10 @@ public: inline bool updateMulticastGroups() { Mutex::Lock _l(_lock); - return _tap->updateMulticastGroups(_multicastGroups); + EthernetTap *t = _tap; + if (t) + return _tap->updateMulticastGroups(_multicastGroups); + return false; } /** @@ -173,10 +177,34 @@ public: * This is called by PacketDecoder when an update comes over the wire, or * internally when an old config is reloaded from disk. * + * This also cancels any netconf failure flags. + * + * The network can't accept configuration when in INITIALIZATION state, + * and so in that state this will just return false. + * * @param conf Configuration in key/value dictionary form * @param saveToDisk IF true (default), write config to disk + * @return True if configuration was accepted */ - void setConfiguration(const Dictionary &conf,bool saveToDisk = true); + bool setConfiguration(const Dictionary &conf,bool saveToDisk = true); + + /** + * Set netconf failure to 'access denied'. + */ + inline void setAccessDenied() + { + Mutex::Lock _l(_lock); + _netconfFailure = NETCONF_FAILURE_ACCESS_DENIED; + } + + /** + * Set netconf failure to 'not found'. + */ + inline void setNotFound() + { + Mutex::Lock _l(_lock); + _netconfFailure = NETCONF_FAILURE_NOT_FOUND; + } /** * Causes this network to request an updated configuration from its master node now @@ -223,16 +251,6 @@ public: */ inline uint64_t lastConfigUpdate() const throw() { return _lastConfigUpdate; } - /** - * Force this network's status to a particular state based on config reply - */ - inline void forceStatusTo(const Status s) - throw() - { - Mutex::Lock _l(_lock); - _status = s; - } - /** * @return Status of this network */ @@ -240,17 +258,20 @@ public: throw() { Mutex::Lock _l(_lock); - return _status; - } - - /** - * @return True if this network is in "OK" status and can accept traffic from us - */ - inline bool isUp() const - throw() - { - Mutex::Lock _l(_lock); - return ((_config)&&(_status == NETWORK_OK)&&(_ready)); + if (_tap) { + switch(_netconfFailure) { + case NETCONF_FAILURE_ACCESS_DENIED: + return NETWORK_ACCESS_DENIED; + case NETCONF_FAILURE_NOT_FOUND: + return NETWORK_NOT_FOUND; + case NETCONF_FAILURE_NONE: + if (_lastConfigUpdate > 0) + return NETWORK_OK; + else return NETWORK_WAITING_FOR_FIRST_AUTOCONF; + } + } else if (_netconfFailure == NETCONF_FAILURE_INIT_FAILED) + return NETWORK_INITIALIZATION_FAILED; + else return NETWORK_INITIALIZING; } /** @@ -307,6 +328,73 @@ public: return _config; } + /** + * Thread main method; do not call elsewhere + */ + void threadMain() + throw(); + + /** + * Inject a frame into tap (if it's created) + * + * @param from Origin MAC + * @param to Destination MC + * @param etherType Ethernet frame type + * @param data Frame data + * @param len Frame length + */ + inline void tapPut(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len) + { + EthernetTap *t = _tap; + if (t) + t->put(from,to,etherType,data,len); + } + + /** + * Inject a frame into tap with local MAC as destination MAC (if it's created) + * + * @param from Origin MAC + * @param etherType Ethernet frame type + * @param data Frame data + * @param len Frame length + */ + inline void tapPut(const MAC &from,unsigned int etherType,const void *data,unsigned int len) + { + EthernetTap *t = _tap; + if (t) + t->put(from,t->mac(),etherType,data,len); + } + + /** + * @return Tap device name or empty string if still initializing + */ + inline std::string tapDeviceName() const + { + EthernetTap *t = _tap; + if (t) + return t->deviceName(); + else return std::string(); + } + + /** + * @return Ethernet MAC address for this network's local interface + */ + inline const MAC &mac() const + { + return _mac; + } + + /** + * @return Set of currently assigned IP addresses + */ + inline std::set ips() const + { + EthernetTap *t = _tap; + if (t) + return t->ips(); + return std::set(); + } + private: static void _CBhandleTapData(void *arg,const MAC &from,const MAC &to,unsigned int etherType,const Buffer<4096> &data); @@ -315,22 +403,23 @@ private: void _dumpMulticastCerts(); uint64_t _id; - + MAC _mac; const RuntimeEnvironment *_r; - - EthernetTap *_tap; + EthernetTap *volatile _tap; std::set _multicastGroups; - std::map< std::pair,BandwidthAccount > _multicastRateAccounts; std::map _membershipCertificates; std::map _lastPushedMembershipCertificate; SharedPtr _config; - volatile uint64_t _lastConfigUpdate; - volatile Status _status; volatile bool _destroyOnDelete; - volatile bool _ready; - + volatile enum { + NETCONF_FAILURE_NONE, + NETCONF_FAILURE_ACCESS_DENIED, + NETCONF_FAILURE_NOT_FOUND, + NETCONF_FAILURE_INIT_FAILED + } _netconfFailure; + Thread _setupThread; Mutex _lock; AtomicCounter __refCount; diff --git a/node/Node.cpp b/node/Node.cpp index 71f3e0871..b1c7e820f 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -545,7 +545,6 @@ Node::ReasonForTermination Node::run() LOG("netconf fingerprint change: %.16llx != %.16llx, resyncing with network",networkConfigurationFingerprint,fp); networkConfigurationFingerprint = fp; resynchronize = true; - _r->nc->whackAllTaps(); // call whack() on all tap devices -- hack, might go away } } diff --git a/node/NodeConfig.cpp b/node/NodeConfig.cpp index eb0802a4a..acdcd49d8 100644 --- a/node/NodeConfig.cpp +++ b/node/NodeConfig.cpp @@ -115,14 +115,6 @@ NodeConfig::~NodeConfig() { } -void NodeConfig::whackAllTaps() -{ - std::vector< SharedPtr > nwlist; - Mutex::Lock _l(_networks_m); - for(std::map< uint64_t,SharedPtr >::const_iterator n(_networks.begin());n!=_networks.end();++n) - n->second->tap().whack(); -} - void NodeConfig::clean() { Mutex::Lock _l(_networks_m); @@ -205,7 +197,7 @@ std::vector NodeConfig::execute(const char *command) _P("200 listnetworks "); for(std::map< uint64_t,SharedPtr >::const_iterator nw(_networks.begin());nw!=_networks.end();++nw) { std::string tmp; - std::set ips(nw->second->tap().ips()); + std::set ips(nw->second->ips()); for(std::set::iterator i(ips.begin());i!=ips.end();++i) { if (tmp.length()) tmp.push_back(','); @@ -219,13 +211,14 @@ std::vector NodeConfig::execute(const char *command) age = 0; age /= 1000; + std::string dn(nw->second->tapDeviceName()); _P("200 listnetworks %.16llx %s %s %lld %s %s %s", (unsigned long long)nw->first, ((nconf) ? nconf->name().c_str() : "?"), Network::statusString(nw->second->status()), age, ((nconf) ? (nconf->isOpen() ? "public" : "private") : "?"), - nw->second->tap().deviceName().c_str(), + (dn.length() > 0) ? dn.c_str() : "?", ((tmp.length() > 0) ? tmp.c_str() : "-")); } } else if (cmd[0] == "join") { diff --git a/node/NodeConfig.hpp b/node/NodeConfig.hpp index 2612cf6aa..b26d180be 100644 --- a/node/NodeConfig.hpp +++ b/node/NodeConfig.hpp @@ -90,11 +90,6 @@ public: return nwlist; } - /** - * Call whack() on all networks' tap devices - */ - void whackAllTaps(); - /** * Perform cleanup and possibly update saved state */ @@ -117,8 +112,11 @@ public: { std::set tapDevs; Mutex::Lock _l(_networks_m); - for(std::map< uint64_t,SharedPtr >::const_iterator n(_networks.begin());n!=_networks.end();++n) - tapDevs.insert(n->second->tap().deviceName()); + for(std::map< uint64_t,SharedPtr >::const_iterator n(_networks.begin());n!=_networks.end();++n) { + std::string dn(n->second->tapDeviceName()); + if (dn.length()) + tapDevs.insert(dn); + } return tapDevs; } diff --git a/node/PacketDecoder.cpp b/node/PacketDecoder.cpp index 4869bca50..410e273ed 100644 --- a/node/PacketDecoder.cpp +++ b/node/PacketDecoder.cpp @@ -139,7 +139,7 @@ bool PacketDecoder::_doERROR(const RuntimeEnvironment *_r,const SharedPtr } else if (inReVerb == Packet::VERB_NETWORK_CONFIG_REQUEST) { SharedPtr network(_r->nc->network(at(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD))); if ((network)&&(network->controller() == source())) - network->forceStatusTo(Network::NETWORK_NOT_FOUND); + network->setNotFound(); } break; case Packet::ERROR_IDENTITY_COLLISION: @@ -154,7 +154,7 @@ bool PacketDecoder::_doERROR(const RuntimeEnvironment *_r,const SharedPtr case Packet::ERROR_NETWORK_ACCESS_DENIED_: { SharedPtr network(_r->nc->network(at(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD))); if ((network)&&(network->controller() == source())) - network->forceStatusTo(Network::NETWORK_ACCESS_DENIED); + network->setAccessDenied(); } break; default: break; @@ -416,7 +416,7 @@ bool PacketDecoder::_doFRAME(const RuntimeEnvironment *_r,const SharedPtr unsigned int etherType = at(ZT_PROTO_VERB_FRAME_IDX_ETHERTYPE); if (size() > ZT_PROTO_VERB_FRAME_IDX_PAYLOAD) { if (network->config()->permitsEtherType(etherType)) { - network->tap().put(source().toMAC(),network->tap().mac(),etherType,data() + ZT_PROTO_VERB_FRAME_IDX_PAYLOAD,size() - ZT_PROTO_VERB_FRAME_IDX_PAYLOAD); + network->tapPut(source().toMAC(),etherType,data() + ZT_PROTO_VERB_FRAME_IDX_PAYLOAD,size() - ZT_PROTO_VERB_FRAME_IDX_PAYLOAD); } else { TRACE("dropped FRAME from %s: ethernet type %u not allowed on network %.16llx",source().toString().c_str(),etherType,(unsigned long long)network->id()); return true; @@ -677,7 +677,7 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared TRACE("dropped MULTICAST_FRAME from %s(%s): rate limits exceeded for sender %s",source().toString().c_str(),_remoteAddress.toString().c_str(),origin.toString().c_str()); return true; } else { - network->tap().put(sourceMac,dest.mac(),etherType,frame,frameLen); + network->tapPut(sourceMac,dest.mac(),etherType,frame,frameLen); } } } diff --git a/node/Switch.cpp b/node/Switch.cpp index 5473402d3..cf3580df2 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -86,12 +86,11 @@ void Switch::onLocalEthernet(const SharedPtr &network,const MAC &from,c if (!nconf) return; - if (to == network->tap().mac()) { - LOG("%s: frame received from self, ignoring (bridge loop? OS bug?)",network->tap().deviceName().c_str()); + if (to == network->mac()) { + LOG("%s: frame received from self, ignoring (bridge loop? OS bug?)",network->tapDeviceName().c_str()); return; } - - if (from != network->tap().mac()) { + if (from != network->mac()) { LOG("ignored tap: %s -> %s %s (bridging not supported)",from.toString().c_str(),to.toString().c_str(),etherTypeName(etherType)); return; }