From 3947807b1ffc844f62eeec7dd0fe552d280fe807 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Thu, 27 Aug 2015 15:36:13 -0700 Subject: A simple and fast Hashtable, tested but not yet integrated with anything. --- node/Hashtable.hpp | 252 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 252 insertions(+) create mode 100644 node/Hashtable.hpp (limited to 'node') diff --git a/node/Hashtable.hpp b/node/Hashtable.hpp new file mode 100644 index 00000000..bba1fa2b --- /dev/null +++ b/node/Hashtable.hpp @@ -0,0 +1,252 @@ +/* + * 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 . + * + * -- + * + * 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 + * + */ + +#ifndef ZT_HASHTABLE_HPP +#define ZT_HASHTABLE_HPP + +#include +#include +#include + +#include + +namespace ZeroTier { + +/** + * A minimal hash table implementation for the ZeroTier core + * + * This is not a drop-in replacement for STL containers, and has several + * limitations. It's designed to be small and fast for use in the + * ZeroTier core. + * + * Pairs of values can also be used as a key. In this case the first and + * second element of the pair's hash codes are XORed. + */ +template +class Hashtable +{ +private: + struct _Bucket + { + _Bucket(const K &k,const V &v) : + k(k), + v(v) {} + _Bucket *next; + K k; + V v; + }; + +public: + /** + * A simple forward iterator (different from STL) + * + * It's safe to erase the last key, but not others. Don't use set() since that + * may rehash and invalidate the iterator. Note the erasing the key will destroy + * the targets of the pointers returned by next(). + */ + class Iterator + { + public: + /** + * @param ht Hash table to iterate over + */ + Iterator(Hashtable &ht) : + _idx(0), + _ht(&ht), + _b(ht._t[0]) + { + } + + /** + * @param kptr Pointer to set to point to next key + * @param vptr Pointer to set to point to next value + * @return True if kptr and vptr are set, false if no more entries + */ + inline bool next(K *&kptr,V *&vptr) + { + for(;;) { + if (_b) { + kptr = &(_b->k); + vptr = &(_b->v); + _b = _b->next; + return true; + } + ++_idx; + if (_idx >= _ht->_bc) + return false; + _b = _ht->_t[_idx]; + } + } + + private: + unsigned long _idx; + Hashtable *_ht; + Hashtable::_Bucket *_b; + }; + friend class Hashtable::Iterator; + + /** + * @param bc Initial capacity in buckets (default: 128, must be nonzero) + */ + Hashtable(unsigned long bc = 128) : + _t(reinterpret_cast<_Bucket **>(::malloc(sizeof(_Bucket *) * bc))), + _bc(bc), + _s(0) + { + if (!_t) + throw std::bad_alloc(); + for(unsigned long i=0;inext; + delete b; + b = nb; + } + _t[i] = (_Bucket *)0; + } + _s = 0; + } + } + + /** + * @param k Key + * @return Pointer to value or NULL if not found + */ + inline V *get(const K &k) + { + _Bucket *b = _t[_hc(k) % _bc]; + while (b) { + if (b->k == k) + return &(b->v); + b = b->next; + } + return (V *)0; + } + inline const V *get(const K &k) const { return const_cast(this)->get(k); } + + /** + * @param k Key + * @return True if value was present + */ + inline bool erase(const K &k) + { + const unsigned long bidx = _hc(k) % _bc; + _Bucket *lastb = (_Bucket *)0; + _Bucket *b = _t[bidx]; + while (b) { + if (b->k == k) { + if (lastb) + lastb->next = b->next; + else _t[bidx] = b->next; + delete b; + --_s; + return true; + } + lastb = b; + b = b->next; + } + return false; + } + + /** + * @param k Key + * @param v Value + */ + inline void set(const K &k,const V &v) + { + if (_s >= _bc) { + const unsigned long nc = _bc * 2; + _Bucket **nt = reinterpret_cast<_Bucket **>(::malloc(sizeof(_Bucket *) * nc)); + if (nt) { + for(unsigned long i=0;inext; + const unsigned long nidx = _hc(b->k) % nc; + b->next = nt[nidx]; + nt[nidx] = b; + b = nb; + } + } + ::free(_t); + _t = nt; + _bc = nc; + } + } + const unsigned long bidx = _hc(k) % _bc; + _Bucket *const b = new _Bucket(k,v); + b->next = _t[bidx]; + _t[bidx] = b; + ++_s; + } + + /** + * @return Number of entries + */ + inline unsigned long size() const throw() { return _s; } + + /** + * @return True if table is empty + */ + inline bool empty() const throw() { return (_s == 0); } + +private: + template + static inline unsigned long _hc(const O &obj) + { + return obj.hashCode(); + } + static inline unsigned long _hc(const uint64_t i) + { + // NOTE: this is fine for network IDs, but might be bad for other kinds + // of IDs if they are not evenly or randomly distributed. + return (unsigned long)((i ^ (i >> 32)) * 2654435761ULL); + } + + _Bucket **_t; + unsigned long _bc; + unsigned long _s; +}; + +} // namespace ZeroTier + +#endif -- cgit v1.2.3 From b11ffc9635204f11daac4f20596dc4e3da687eee Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Thu, 27 Aug 2015 16:17:21 -0700 Subject: Integrate Hashtable into Multicaster, where @mwarning found heaviest std::map() overhead. --- node/Hashtable.hpp | 97 ++++++++++++++++++++++++++++++++++--------------- node/MAC.hpp | 2 + node/MulticastGroup.hpp | 2 + node/Multicaster.cpp | 56 +++++++++++++++------------- node/Multicaster.hpp | 17 ++++++++- 5 files changed, 117 insertions(+), 57 deletions(-) (limited to 'node') diff --git a/node/Hashtable.hpp b/node/Hashtable.hpp index bba1fa2b..c997d54f 100644 --- a/node/Hashtable.hpp +++ b/node/Hashtable.hpp @@ -19,7 +19,6 @@ * * 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 - * */ #ifndef ZT_HASHTABLE_HPP @@ -39,9 +38,6 @@ namespace ZeroTier { * This is not a drop-in replacement for STL containers, and has several * limitations. It's designed to be small and fast for use in the * ZeroTier core. - * - * Pairs of values can also be used as a key. In this case the first and - * second element of the pair's hash codes are XORed. */ template class Hashtable @@ -49,12 +45,11 @@ class Hashtable private: struct _Bucket { - _Bucket(const K &k,const V &v) : - k(k), - v(v) {} - _Bucket *next; + _Bucket(const K &k,const V &v) : k(k),v(v) {} + _Bucket(const K &k) : k(k),v() {} K k; V v; + _Bucket *next; }; public: @@ -188,35 +183,56 @@ public: /** * @param k Key * @param v Value + * @return Reference to value in table */ - inline void set(const K &k,const V &v) + inline V &set(const K &k,const V &v) { - if (_s >= _bc) { - const unsigned long nc = _bc * 2; - _Bucket **nt = reinterpret_cast<_Bucket **>(::malloc(sizeof(_Bucket *) * nc)); - if (nt) { - for(unsigned long i=0;inext; - const unsigned long nidx = _hc(b->k) % nc; - b->next = nt[nidx]; - nt[nidx] = b; - b = nb; - } - } - ::free(_t); - _t = nt; - _bc = nc; + const unsigned long bidx = _hc(k) % _bc; + + _Bucket *b = _t[bidx]; + while (b) { + if (b->k == k) { + b->v = v; + return b->v; } + b = b->next; } + + if (_s >= _bc) + _grow(); + + b = new _Bucket(k,v); + b->next = _t[bidx]; + _t[bidx] = b; + ++_s; + + return b->v; + } + + /** + * @param k Key + * @return Value, possibly newly created + */ + inline V &operator[](const K &k) + { const unsigned long bidx = _hc(k) % _bc; - _Bucket *const b = new _Bucket(k,v); + + _Bucket *b = _t[bidx]; + while (b) { + if (b->k == k) + return b->v; + b = b->next; + } + + if (_s >= _bc) + _grow(); + + b = new _Bucket(k); b->next = _t[bidx]; _t[bidx] = b; ++_s; + + return b->v; } /** @@ -242,6 +258,29 @@ private: return (unsigned long)((i ^ (i >> 32)) * 2654435761ULL); } + inline void _grow() + { + const unsigned long nc = _bc * 2; + _Bucket **nt = reinterpret_cast<_Bucket **>(::malloc(sizeof(_Bucket *) * nc)); + if (nt) { + for(unsigned long i=0;inext; + const unsigned long nidx = _hc(b->k) % nc; + b->next = nt[nidx]; + nt[nidx] = b; + b = nb; + } + } + ::free(_t); + _t = nt; + _bc = nc; + } + } + _Bucket **_t; unsigned long _bc; unsigned long _s; diff --git a/node/MAC.hpp b/node/MAC.hpp index 442a7a2e..619b7195 100644 --- a/node/MAC.hpp +++ b/node/MAC.hpp @@ -242,6 +242,8 @@ public: */ inline unsigned int size() const throw() { return 6; } + inline unsigned long hashCode() const throw() { return (unsigned long)_m; } + inline MAC &operator=(const MAC &m) throw() { diff --git a/node/MulticastGroup.hpp b/node/MulticastGroup.hpp index 61fb55f2..fad433b5 100644 --- a/node/MulticastGroup.hpp +++ b/node/MulticastGroup.hpp @@ -141,6 +141,8 @@ public: */ inline uint32_t adi() const throw() { return _adi; } + inline unsigned long hashCode() const throw() { return (_mac.hashCode() ^ (unsigned long)_adi); } + inline bool operator==(const MulticastGroup &g) const throw() { return ((_mac == g._mac)&&(_adi == g._adi)); } inline bool operator!=(const MulticastGroup &g) const throw() { return ((_mac != g._mac)||(_adi != g._adi)); } inline bool operator<(const MulticastGroup &g) const throw() diff --git a/node/Multicaster.cpp b/node/Multicaster.cpp index 489c170b..07792737 100644 --- a/node/Multicaster.cpp +++ b/node/Multicaster.cpp @@ -41,7 +41,9 @@ namespace ZeroTier { Multicaster::Multicaster(const RuntimeEnvironment *renv) : - RR(renv) + RR(renv), + _groups(1024), + _groups_m() { } @@ -54,7 +56,7 @@ void Multicaster::addMultiple(uint64_t now,uint64_t nwid,const MulticastGroup &m const unsigned char *p = (const unsigned char *)addresses; const unsigned char *e = p + (5 * count); Mutex::Lock _l(_groups_m); - MulticastGroupStatus &gs = _groups[std::pair(nwid,mg)]; + MulticastGroupStatus &gs = _groups[Multicaster::Key(nwid,mg)]; while (p != e) { _add(now,nwid,mg,gs,Address(p,5)); p += 5; @@ -64,11 +66,11 @@ void Multicaster::addMultiple(uint64_t now,uint64_t nwid,const MulticastGroup &m void Multicaster::remove(uint64_t nwid,const MulticastGroup &mg,const Address &member) { Mutex::Lock _l(_groups_m); - std::map< std::pair,MulticastGroupStatus >::iterator g(_groups.find(std::pair(nwid,mg))); - if (g != _groups.end()) { - for(std::vector::iterator m(g->second.members.begin());m!=g->second.members.end();++m) { + MulticastGroupStatus *s = _groups.get(Multicaster::Key(nwid,mg)); + if (s) { + for(std::vector::iterator m(s->members.begin());m!=s->members.end();++m) { if (m->address == member) { - g->second.members.erase(m); + s->members.erase(m); break; } } @@ -102,18 +104,18 @@ unsigned int Multicaster::gather(const Address &queryingPeer,uint64_t nwid,const Mutex::Lock _l(_groups_m); - std::map< std::pair,MulticastGroupStatus >::const_iterator gs(_groups.find(std::pair(nwid,mg))); - if ((gs != _groups.end())&&(!gs->second.members.empty())) { - totalKnown += (unsigned int)gs->second.members.size(); + const MulticastGroupStatus *s = _groups.get(Multicaster::Key(nwid,mg)); + if ((s)&&(!s->members.empty())) { + totalKnown += (unsigned int)s->members.size(); // Members are returned in random order so that repeated gather queries // will return different subsets of a large multicast group. k = 0; - while ((added < limit)&&(k < gs->second.members.size())&&((appendTo.size() + ZT_ADDRESS_LENGTH) <= ZT_UDP_DEFAULT_PAYLOAD_MTU)) { + while ((added < limit)&&(k < s->members.size())&&((appendTo.size() + ZT_ADDRESS_LENGTH) <= ZT_UDP_DEFAULT_PAYLOAD_MTU)) { rptr = (unsigned int)RR->node->prng(); restart_member_scan: - a = gs->second.members[rptr % (unsigned int)gs->second.members.size()].address.toInt(); + a = s->members[rptr % (unsigned int)s->members.size()].address.toInt(); for(i=0;i Multicaster::getMembers(uint64_t nwid,const MulticastGroup { std::vector
ls; Mutex::Lock _l(_groups_m); - std::map< std::pair,MulticastGroupStatus >::const_iterator gs(_groups.find(std::pair(nwid,mg))); - if (gs == _groups.end()) + const MulticastGroupStatus *s = _groups.get(Multicaster::Key(nwid,mg)); + if (!s) return ls; - for(std::vector::const_reverse_iterator m(gs->second.members.rbegin());m!=gs->second.members.rend();++m) { + for(std::vector::const_reverse_iterator m(s->members.rbegin());m!=s->members.rend();++m) { ls.push_back(m->address); if (ls.size() >= limit) break; @@ -173,7 +175,7 @@ void Multicaster::send( unsigned long *indexes = idxbuf; Mutex::Lock _l(_groups_m); - MulticastGroupStatus &gs = _groups[std::pair(nwid,mg)]; + MulticastGroupStatus &gs = _groups[Multicaster::Key(nwid,mg)]; if (!gs.members.empty()) { // Allocate a memory buffer if group is monstrous @@ -291,18 +293,22 @@ void Multicaster::send( void Multicaster::clean(uint64_t now) { Mutex::Lock _l(_groups_m); - for(std::map< std::pair,MulticastGroupStatus >::iterator mm(_groups.begin());mm!=_groups.end();) { - for(std::list::iterator tx(mm->second.txQueue.begin());tx!=mm->second.txQueue.end();) { + + Multicaster::Key *k = (Multicaster::Key *)0; + MulticastGroupStatus *s = (MulticastGroupStatus *)0; + Hashtable::Iterator mm(_groups); + while (mm.next(k,s)) { + for(std::list::iterator tx(s->txQueue.begin());tx!=s->txQueue.end();) { if ((tx->expired(now))||(tx->atLimit())) - mm->second.txQueue.erase(tx++); + s->txQueue.erase(tx++); else ++tx; } unsigned long count = 0; { - std::vector::iterator reader(mm->second.members.begin()); + std::vector::iterator reader(s->members.begin()); std::vector::iterator writer(reader); - while (reader != mm->second.members.end()) { + while (reader != s->members.end()) { if ((now - reader->timestamp) < ZT_MULTICAST_LIKE_EXPIRE) { *writer = *reader; ++writer; @@ -313,13 +319,11 @@ void Multicaster::clean(uint64_t now) } if (count) { - mm->second.members.resize(count); - ++mm; - } else if (mm->second.txQueue.empty()) { - _groups.erase(mm++); + s->members.resize(count); + } else if (s->txQueue.empty()) { + _groups.erase(*k); } else { - mm->second.members.clear(); - ++mm; + s->members.clear(); } } } diff --git a/node/Multicaster.hpp b/node/Multicaster.hpp index 0dd199f9..898c4db7 100644 --- a/node/Multicaster.hpp +++ b/node/Multicaster.hpp @@ -36,6 +36,7 @@ #include #include "Constants.hpp" +#include "Hashtable.hpp" #include "Address.hpp" #include "MAC.hpp" #include "MulticastGroup.hpp" @@ -56,6 +57,18 @@ class Packet; class Multicaster : NonCopyable { private: + struct Key + { + Key() : nwid(0),mg() {} + Key(uint64_t n,const MulticastGroup &g) : nwid(n),mg(g) {} + + uint64_t nwid; + MulticastGroup mg; + + inline bool operator==(const Key &k) const throw() { return ((nwid == k.nwid)&&(mg == k.mg)); } + inline unsigned long hashCode() const throw() { return (mg.hashCode() ^ (unsigned long)(nwid ^ (nwid >> 32))); } + }; + struct MulticastGroupMember { MulticastGroupMember() {} @@ -89,7 +102,7 @@ public: inline void add(uint64_t now,uint64_t nwid,const MulticastGroup &mg,const Address &member) { Mutex::Lock _l(_groups_m); - _add(now,nwid,mg,_groups[std::pair(nwid,mg)],member); + _add(now,nwid,mg,_groups[Multicaster::Key(nwid,mg)],member); } /** @@ -181,7 +194,7 @@ private: void _add(uint64_t now,uint64_t nwid,const MulticastGroup &mg,MulticastGroupStatus &gs,const Address &member); const RuntimeEnvironment *RR; - std::map< std::pair,MulticastGroupStatus > _groups; + Hashtable _groups; Mutex _groups_m; }; -- cgit v1.2.3 From da9a720c3fc2d69e35f393fbb96a716599ac0a6f Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Thu, 3 Sep 2015 17:33:06 -0700 Subject: Hash table bug fix, and add copy constructor and assignment operator for principle of least surprise. --- node/Hashtable.hpp | 74 +++++++++++++++++++++++++++++++++++++++++++++++++----- selftest.cpp | 39 ++++++++++++++++++++++++---- 2 files changed, 102 insertions(+), 11 deletions(-) (limited to 'node') diff --git a/node/Hashtable.hpp b/node/Hashtable.hpp index c997d54f..5076751d 100644 --- a/node/Hashtable.hpp +++ b/node/Hashtable.hpp @@ -29,6 +29,7 @@ #include #include +#include namespace ZeroTier { @@ -47,9 +48,11 @@ private: { _Bucket(const K &k,const V &v) : k(k),v(v) {} _Bucket(const K &k) : k(k),v() {} + _Bucket(const _Bucket &b) : k(b.k),v(b.v) {} + inline _Bucket &operator=(const _Bucket &b) { k = b.k; v = b.v; return *this; } K k; V v; - _Bucket *next; + _Bucket *next; // must be set manually for each _Bucket }; public: @@ -115,12 +118,47 @@ public: _t[i] = (_Bucket *)0; } + Hashtable(const Hashtable &ht) : + _t(reinterpret_cast<_Bucket **>(::malloc(sizeof(_Bucket *) * ht._bc))), + _bc(ht._bc), + _s(ht._s) + { + if (!_t) + throw std::bad_alloc(); + for(unsigned long i=0;i<_bc;++i) + _t[i] = (_Bucket *)0; + for(unsigned long i=0;i<_bc;++i) { + const _Bucket *b = ht._t[i]; + while (b) { + _Bucket *nb = new _Bucket(*b); + nb->next = _t[i]; + _t[i] = nb; + b = b->next; + } + } + } + ~Hashtable() { - clear(); + this->clear(); ::free(_t); } + inline Hashtable &operator=(const Hashtable &ht) + { + this->clear(); + if (ht._s) { + for(unsigned long i=0;iset(b->k,b->v); + b = b->next; + } + } + } + return *this; + } + /** * Erase all entries */ @@ -140,6 +178,24 @@ public: } } + /** + * @return Vector of all keys + */ + inline typename std::vector keys() + { + typename std::vector k; + if (_s) { + for(unsigned long i=0;i<_bc;++i) { + _Bucket *b = _t[i]; + while (b) { + k.push_back(b->k); + b = b->next; + } + } + } + return k; + } + /** * @param k Key * @return Pointer to value or NULL if not found @@ -187,7 +243,8 @@ public: */ inline V &set(const K &k,const V &v) { - const unsigned long bidx = _hc(k) % _bc; + const unsigned long h = _hc(k); + unsigned long bidx = h % _bc; _Bucket *b = _t[bidx]; while (b) { @@ -198,8 +255,10 @@ public: b = b->next; } - if (_s >= _bc) + if (_s >= _bc) { _grow(); + bidx = h % _bc; + } b = new _Bucket(k,v); b->next = _t[bidx]; @@ -215,7 +274,8 @@ public: */ inline V &operator[](const K &k) { - const unsigned long bidx = _hc(k) % _bc; + const unsigned long h = _hc(k); + unsigned long bidx = h % _bc; _Bucket *b = _t[bidx]; while (b) { @@ -224,8 +284,10 @@ public: b = b->next; } - if (_s >= _bc) + if (_s >= _bc) { _grow(); + bidx = h % _bc; + } b = new _Bucket(k); b->next = _t[bidx]; diff --git a/selftest.cpp b/selftest.cpp index 15afe52e..5e3b620b 100644 --- a/selftest.cpp +++ b/selftest.cpp @@ -581,31 +581,60 @@ static int testOther() { std::cout << "[other] Testing Hashtable... "; std::cout.flush(); { - Hashtable ht(128); + Hashtable ht; + Hashtable ht2; std::map ref; // assume std::map works correctly :) for(int x=0;x<2;++x) { for(int i=0;i<25000;++i) { uint64_t k = rand(); while ((k == 0)||(ref.count(k) > 0)) ++k; - std::string v; + std::string v("!"); for(int j=0;j<(int)(k % 64);++j) v.push_back("0123456789"[rand() % 10]); ht.set(k,v); ref[k] = v; } if (ht.size() != ref.size()) { - std::cout << "FAILED! (size mismatch)" << std::endl; + std::cout << "FAILED! (size mismatch, original)" << std::endl; + return -1; + } + ht2 = ht; + Hashtable ht3(ht2); + if (ht2.size() != ref.size()) { + std::cout << "FAILED! (size mismatch, assigned)" << std::endl; + return -1; + } + if (ht3.size() != ref.size()) { + std::cout << "FAILED! (size mismatch, copied)" << std::endl; return -1; } for(std::map::iterator i(ref.begin());i!=ref.end();++i) { std::string *v = ht.get(i->first); if (!v) { - std::cout << "FAILED! (key not found)" << std::endl; + std::cout << "FAILED! (key " << i->first << " not found, original)" << std::endl; + return -1; + } + if (*v != i->second) { + std::cout << "FAILED! (key " << i->first << " not equal, original)" << std::endl; + return -1; + } + v = ht2.get(i->first); + if (!v) { + std::cout << "FAILED! (key " << i->first << " not found, assigned)" << std::endl; + return -1; + } + if (*v != i->second) { + std::cout << "FAILED! (key " << i->first << " not equal, assigned)" << std::endl; + return -1; + } + v = ht3.get(i->first); + if (!v) { + std::cout << "FAILED! (key " << i->first << " not found, copied)" << std::endl; return -1; } if (*v != i->second) { - std::cout << "FAILED! (key not equal)" << std::endl; + std::cout << "FAILED! (key " << i->first << " not equal, copied)" << std::endl; return -1; } } -- cgit v1.2.3 From cfd101c9b85b20e5911445998a6f040089e3e414 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Fri, 4 Sep 2015 11:50:12 -0700 Subject: Add entries() to go with keys() for future use. --- node/Hashtable.hpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'node') diff --git a/node/Hashtable.hpp b/node/Hashtable.hpp index 5076751d..6f7541c4 100644 --- a/node/Hashtable.hpp +++ b/node/Hashtable.hpp @@ -30,6 +30,8 @@ #include #include +#include +#include namespace ZeroTier { @@ -196,6 +198,24 @@ public: return k; } + /** + * @return Vector of all entries (pairs of K,V) + */ + inline typename std::vector< std::pair > entries() + { + typename std::vector< std::pair > k; + if (_s) { + for(unsigned long i=0;i<_bc;++i) { + _Bucket *b = _t[i]; + while (b) { + k.push_back(std::pair(b->k,b->v)); + b = b->next; + } + } + } + return k; + } + /** * @param k Key * @return Pointer to value or NULL if not found -- cgit v1.2.3 From 3a959a7763b44ffcddce557167169150a28b9059 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Fri, 4 Sep 2015 12:14:21 -0700 Subject: Swap out std::map<> for Hashtable<> for main peer database in Topology. (ongoing std::map-ectomy) --- node/Address.hpp | 14 +++++++++++--- node/Hashtable.hpp | 6 ++++-- node/Node.cpp | 5 +++-- node/Topology.cpp | 18 ++++++++++-------- node/Topology.hpp | 14 +++++++++----- 5 files changed, 37 insertions(+), 20 deletions(-) (limited to 'node') diff --git a/node/Address.hpp b/node/Address.hpp index 137e4f4f..0b38ec62 100644 --- a/node/Address.hpp +++ b/node/Address.hpp @@ -166,6 +166,15 @@ public: return _a; } + /** + * @return Hash code for use with Hashtable + */ + inline unsigned long hashCode() const + throw() + { + return (unsigned long)_a; + } + /** * @return Hexadecimal string */ @@ -197,11 +206,11 @@ public: /** * Check if this address is reserved - * + * * The all-zero null address and any address beginning with 0xff are * reserved. (0xff is reserved for future use to designate possibly * longer addresses, addresses based on IPv6 innards, etc.) - * + * * @return True if address is reserved and may not be used */ inline bool isReserved() const @@ -230,4 +239,3 @@ private: } // namespace ZeroTier #endif - diff --git a/node/Hashtable.hpp b/node/Hashtable.hpp index 6f7541c4..84b5be0e 100644 --- a/node/Hashtable.hpp +++ b/node/Hashtable.hpp @@ -183,10 +183,11 @@ public: /** * @return Vector of all keys */ - inline typename std::vector keys() + inline typename std::vector keys() const { typename std::vector k; if (_s) { + k.reserve(_s); for(unsigned long i=0;i<_bc;++i) { _Bucket *b = _t[i]; while (b) { @@ -201,10 +202,11 @@ public: /** * @return Vector of all entries (pairs of K,V) */ - inline typename std::vector< std::pair > entries() + inline typename std::vector< std::pair > entries() const { typename std::vector< std::pair > k; if (_s) { + k.reserve(_s); for(unsigned long i=0;i<_bc;++i) { _Bucket *b = _t[i]; while (b) { diff --git a/node/Node.cpp b/node/Node.cpp index 534c085d..c8c50d66 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -355,7 +355,8 @@ void Node::status(ZT1_NodeStatus *status) const ZT1_PeerList *Node::peers() const { - std::map< Address,SharedPtr > peers(RR->topology->allPeers()); + std::vector< std::pair< Address,SharedPtr > > peers(RR->topology->allPeers()); + std::sort(peers.begin(),peers.end()); char *buf = (char *)::malloc(sizeof(ZT1_PeerList) + (sizeof(ZT1_Peer) * peers.size())); if (!buf) @@ -364,7 +365,7 @@ ZT1_PeerList *Node::peers() const pl->peers = (ZT1_Peer *)(buf + sizeof(ZT1_PeerList)); pl->peerCount = 0; - for(std::map< Address,SharedPtr >::iterator pi(peers.begin());pi!=peers.end();++pi) { + for(std::vector< std::pair< Address,SharedPtr > >::iterator pi(peers.begin());pi!=peers.end();++pi) { ZT1_Peer *p = &(pl->peers[pl->peerCount++]); p->address = pi->second->address().toInt(); p->lastUnicastFrame = pi->second->lastUnicastFrame(); diff --git a/node/Topology.cpp b/node/Topology.cpp index b255080e..25a92acd 100644 --- a/node/Topology.cpp +++ b/node/Topology.cpp @@ -103,7 +103,7 @@ SharedPtr Topology::addPeer(const SharedPtr &peer) const uint64_t now = RR->node->now(); Mutex::Lock _l(_lock); - SharedPtr p(_activePeers.insert(std::pair< Address,SharedPtr >(peer->address(),peer)).first->second); + SharedPtr &p = _activePeers.set(peer->address(),peer); p->use(now); _saveIdentity(p->identity()); @@ -160,9 +160,9 @@ SharedPtr Topology::getBestRoot(const Address *avoid,unsigned int avoidCou if (++sna == _rootAddresses.end()) sna = _rootAddresses.begin(); // wrap around at end if (*sna != RR->identity.address()) { // pick one other than us -- starting from me+1 in sorted set order - std::map< Address,SharedPtr >::const_iterator p(_activePeers.find(*sna)); - if ((p != _activePeers.end())&&(p->second->hasActiveDirectPath(now))) { - bestRoot = p->second; + SharedPtr *p = _activePeers.get(*sna); + if ((p)&&((*p)->hasActiveDirectPath(now))) { + bestRoot = *p; break; } } @@ -249,10 +249,12 @@ bool Topology::isRoot(const Identity &id) const void Topology::clean(uint64_t now) { Mutex::Lock _l(_lock); - for(std::map< Address,SharedPtr >::iterator p(_activePeers.begin());p!=_activePeers.end();) { - if (((now - p->second->lastUsed()) >= ZT_PEER_IN_MEMORY_EXPIRATION)&&(std::find(_rootAddresses.begin(),_rootAddresses.end(),p->first) == _rootAddresses.end())) { - _activePeers.erase(p++); - } else ++p; + Hashtable< Address,SharedPtr >::Iterator i(_activePeers); + Address *a = (Address *)0; + SharedPtr *p = (SharedPtr *)0; + while (i.next(a,p)) + if (((now - (*p)->lastUsed()) >= ZT_PEER_IN_MEMORY_EXPIRATION)&&(std::find(_rootAddresses.begin(),_rootAddresses.end(),*a) == _rootAddresses.end())) { + _activePeers.erase(*a); } } diff --git a/node/Topology.hpp b/node/Topology.hpp index 1c5cca00..3066b50c 100644 --- a/node/Topology.hpp +++ b/node/Topology.hpp @@ -44,6 +44,7 @@ #include "Mutex.hpp" #include "InetAddress.hpp" #include "Dictionary.hpp" +#include "Hashtable.hpp" namespace ZeroTier { @@ -163,17 +164,20 @@ public: inline void eachPeer(F f) { Mutex::Lock _l(_lock); - for(std::map< Address,SharedPtr >::const_iterator p(_activePeers.begin());p!=_activePeers.end();++p) - f(*this,p->second); + Hashtable< Address,SharedPtr >::Iterator i(_activePeers); + Address *a = (Address *)0; + SharedPtr *p = (SharedPtr *)0; + while (i.next(a,p)) + f(*this,*p); } /** * @return All currently active peers by address */ - inline std::map< Address,SharedPtr > allPeers() const + inline std::vector< std::pair< Address,SharedPtr > > allPeers() const { Mutex::Lock _l(_lock); - return _activePeers; + return _activePeers.entries(); } /** @@ -190,7 +194,7 @@ private: const RuntimeEnvironment *RR; - std::map< Address,SharedPtr > _activePeers; + Hashtable< Address,SharedPtr > _activePeers; std::map< Identity,std::vector > _roots; std::vector< Address > _rootAddresses; std::vector< SharedPtr > _rootPeers; -- cgit v1.2.3 From 7b8ce1605781f14d909e0aa099455b86d738c60a Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Fri, 4 Sep 2015 13:42:19 -0700 Subject: Another std::map<> dies. --- node/Hashtable.hpp | 35 +++++++++++++++++++++++++++++++++++ node/Network.cpp | 21 ++++++++++++--------- node/Network.hpp | 3 ++- node/Peer.hpp | 1 + 4 files changed, 50 insertions(+), 10 deletions(-) (limited to 'node') diff --git a/node/Hashtable.hpp b/node/Hashtable.hpp index 84b5be0e..59a57726 100644 --- a/node/Hashtable.hpp +++ b/node/Hashtable.hpp @@ -199,6 +199,26 @@ public: return k; } + /** + * Append all keys (in unspecified order) to the supplied vector or list + * + * @param v Vector, list, or other compliant container + * @tparam Type of V (generally inferred) + */ + template + inline void appendKeys(C &v) const + { + if (_s) { + for(unsigned long i=0;i<_bc;++i) { + _Bucket *b = _t[i]; + while (b) { + v.push_back(b->k); + b = b->next; + } + } + } + } + /** * @return Vector of all entries (pairs of K,V) */ @@ -234,6 +254,21 @@ public: } inline const V *get(const K &k) const { return const_cast(this)->get(k); } + /** + * @param k Key to check + * @return True if key is present + */ + inline bool contains(const K &k) const + { + _Bucket *b = _t[_hc(k) % _bc]; + while (b) { + if (b->k == k) + return true; + b = b->next; + } + return false; + } + /** * @param k Key * @return True if value was present diff --git a/node/Network.cpp b/node/Network.cpp index 39042fab..8317cad9 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -147,7 +147,7 @@ bool Network::subscribedToMulticastGroup(const MulticastGroup &mg,bool includeBr if (std::binary_search(_myMulticastGroups.begin(),_myMulticastGroups.end(),mg)) return true; else if (includeBridgedGroups) - return (_multicastGroupsBehindMe.find(mg) != _multicastGroupsBehindMe.end()); + return _multicastGroupsBehindMe.contains(mg); else return false; } @@ -373,10 +373,14 @@ void Network::clean() } // Clean learned multicast groups if we haven't heard from them in a while - for(std::map::iterator mg(_multicastGroupsBehindMe.begin());mg!=_multicastGroupsBehindMe.end();) { - if ((now - mg->second) > (ZT_MULTICAST_LIKE_EXPIRE * 2)) - _multicastGroupsBehindMe.erase(mg++); - else ++mg; + { + Hashtable< MulticastGroup,uint64_t >::Iterator i(_multicastGroupsBehindMe); + MulticastGroup *mg = (MulticastGroup *)0; + uint64_t *ts = (uint64_t *)0; + while (i.next(mg,ts)) { + if ((now - *ts) > (ZT_MULTICAST_LIKE_EXPIRE * 2)) + _multicastGroupsBehindMe.erase(*mg); + } } } @@ -408,8 +412,8 @@ void Network::learnBridgeRoute(const MAC &mac,const Address &addr) void Network::learnBridgedMulticastGroup(const MulticastGroup &mg,uint64_t now) { Mutex::Lock _l(_lock); - unsigned long tmp = (unsigned long)_multicastGroupsBehindMe.size(); - _multicastGroupsBehindMe[mg] = now; + const unsigned long tmp = (unsigned long)_multicastGroupsBehindMe.size(); + _multicastGroupsBehindMe.set(mg,now); if (tmp != _multicastGroupsBehindMe.size()) _announceMulticastGroups(); } @@ -510,8 +514,7 @@ std::vector Network::_allMulticastGroups() const std::vector mgs; mgs.reserve(_myMulticastGroups.size() + _multicastGroupsBehindMe.size() + 1); mgs.insert(mgs.end(),_myMulticastGroups.begin(),_myMulticastGroups.end()); - for(std::map< MulticastGroup,uint64_t >::const_iterator i(_multicastGroupsBehindMe.begin());i!=_multicastGroupsBehindMe.end();++i) - mgs.push_back(i->first); + _multicastGroupsBehindMe.appendKeys(mgs); if ((_config)&&(_config->enableBroadcast())) mgs.push_back(Network::BROADCAST); std::sort(mgs.begin(),mgs.end()); diff --git a/node/Network.hpp b/node/Network.hpp index d7320d46..47d2efc0 100644 --- a/node/Network.hpp +++ b/node/Network.hpp @@ -40,6 +40,7 @@ #include "Constants.hpp" #include "NonCopyable.hpp" +#include "Hashtable.hpp" #include "Address.hpp" #include "Mutex.hpp" #include "SharedPtr.hpp" @@ -359,7 +360,7 @@ private: volatile bool _portInitialized; std::vector< MulticastGroup > _myMulticastGroups; // multicast groups that we belong to including those behind us (updated periodically) - std::map< MulticastGroup,uint64_t > _multicastGroupsBehindMe; // multicast groups bridged to us and when we last saw activity on each + Hashtable< MulticastGroup,uint64_t > _multicastGroupsBehindMe; // multicast groups bridged to us and when we last saw activity on each std::map _remoteBridgeRoutes; // remote addresses where given MACs are reachable diff --git a/node/Peer.hpp b/node/Peer.hpp index 283e3f33..ef436cd9 100644 --- a/node/Peer.hpp +++ b/node/Peer.hpp @@ -40,6 +40,7 @@ #include "../include/ZeroTierOne.h" #include "RuntimeEnvironment.hpp" +#include "CertificateOfMembership.hpp" #include "RemotePath.hpp" #include "Address.hpp" #include "Utils.hpp" -- cgit v1.2.3 From d1341578d8dc7fd3e39b24dde1ac2dae4da7a632 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Fri, 4 Sep 2015 13:53:48 -0700 Subject: ... and another one! --- node/Network.cpp | 34 +++++++++++++++++++++++----------- node/Network.hpp | 14 +++++++------- 2 files changed, 30 insertions(+), 18 deletions(-) (limited to 'node') diff --git a/node/Network.cpp b/node/Network.cpp index 8317cad9..b0c2627b 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -389,22 +389,34 @@ void Network::learnBridgeRoute(const MAC &mac,const Address &addr) Mutex::Lock _l(_lock); _remoteBridgeRoutes[mac] = addr; - // If _remoteBridgeRoutes exceeds sanity limit, trim worst offenders until below -- denial of service circuit breaker + // Anti-DOS circuit breaker to prevent nodes from spamming us with absurd numbers of bridge routes while (_remoteBridgeRoutes.size() > ZT_MAX_BRIDGE_ROUTES) { - std::map counts; + Hashtable< Address,unsigned long > counts; Address maxAddr; unsigned long maxCount = 0; - for(std::map::iterator br(_remoteBridgeRoutes.begin());br!=_remoteBridgeRoutes.end();++br) { - unsigned long c = ++counts[br->second]; - if (c > maxCount) { - maxCount = c; - maxAddr = br->second; + + MAC *m = (MAC *)0; + Address *a = (Address *)0; + + // Find the address responsible for the most entries + { + Hashtable::Iterator i(_remoteBridgeRoutes); + while (i.next(m,a)) { + const unsigned long c = ++counts[*a]; + if (c > maxCount) { + maxCount = c; + maxAddr = *a; + } } } - for(std::map::iterator br(_remoteBridgeRoutes.begin());br!=_remoteBridgeRoutes.end();) { - if (br->second == maxAddr) - _remoteBridgeRoutes.erase(br++); - else ++br; + + // Kill this address from our table, since it's most likely spamming us + { + Hashtable::Iterator i(_remoteBridgeRoutes); + while (i.next(m,a)) { + if (*a == maxAddr) + _remoteBridgeRoutes.erase(*m); + } } } } diff --git a/node/Network.hpp b/node/Network.hpp index 47d2efc0..d8ffd612 100644 --- a/node/Network.hpp +++ b/node/Network.hpp @@ -298,10 +298,10 @@ public: inline Address findBridgeTo(const MAC &mac) const { Mutex::Lock _l(_lock); - std::map::const_iterator br(_remoteBridgeRoutes.find(mac)); - if (br == _remoteBridgeRoutes.end()) - return Address(); - return br->second; + const Address *const br = _remoteBridgeRoutes.get(mac); + if (br) + return *br; + return Address(); } /** @@ -359,10 +359,10 @@ private: volatile bool _enabled; volatile bool _portInitialized; - std::vector< MulticastGroup > _myMulticastGroups; // multicast groups that we belong to including those behind us (updated periodically) - Hashtable< MulticastGroup,uint64_t > _multicastGroupsBehindMe; // multicast groups bridged to us and when we last saw activity on each + std::vector< MulticastGroup > _myMulticastGroups; // multicast groups that we belong to (according to tap) + Hashtable< MulticastGroup,uint64_t > _multicastGroupsBehindMe; // multicast groups that seem to be behind us and when we last saw them (if we are a bridge) - std::map _remoteBridgeRoutes; // remote addresses where given MACs are reachable + Hashtable< MAC,Address > _remoteBridgeRoutes; // remote addresses where given MACs are reachable (for remote bridges) std::map _membershipCertificates; // Other members' certificates of membership std::map _lastPushedMembershipCertificate; // When did we last push our certificate to each remote member? -- cgit v1.2.3 From 307e44f7c84dccd402e33fec08029d824b46515d Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Fri, 4 Sep 2015 14:14:32 -0700 Subject: Two for one! (std::map removal) --- node/Network.cpp | 78 ++++++++++++++++++++++++++------------------------------ node/Network.hpp | 13 +++++++--- 2 files changed, 45 insertions(+), 46 deletions(-) (limited to 'node') diff --git a/node/Network.cpp b/node/Network.cpp index b0c2627b..331b37a2 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -92,7 +92,7 @@ Network::Network(const RuntimeEnvironment *renv,uint64_t nwid) : com.deserialize2(p,e); if (!com) break; - _membershipCertificates.insert(std::pair< Address,CertificateOfMembership >(com.issuedTo(),com)); + _certInfo[com.issuedTo()].com = com; } } } @@ -125,19 +125,22 @@ Network::~Network() clean(); - std::string buf("ZTMCD0"); Utils::snprintf(n,sizeof(n),"networks.d/%.16llx.mcerts",_id); - Mutex::Lock _l(_lock); - if ((!_config)||(_config->isPublic())||(_membershipCertificates.size() == 0)) { + Mutex::Lock _l(_lock); + if ((!_config)||(_config->isPublic())||(_certInfo.empty())) { RR->node->dataStoreDelete(n); - return; + } else { + std::string buf("ZTMCD0"); + Hashtable< Address,_RemoteMemberCertificateInfo >::Iterator i(_certInfo); + Address *a = (Address *)0; + _RemoteMemberCertificateInfo *ci = (_RemoteMemberCertificateInfo *)0; + while (i.next(a,ci)) { + if (ci->com) + ci->com.serialize2(buf); + } + RR->node->dataStorePut(n,buf,true); } - - for(std::map::iterator c(_membershipCertificates.begin());c!=_membershipCertificates.end();++c) - c->second.serialize2(buf); - - RR->node->dataStorePut(n,buf,true); } } @@ -284,11 +287,12 @@ bool Network::validateAndAddMembershipCertificate(const CertificateOfMembership return false; Mutex::Lock _l(_lock); - CertificateOfMembership &old = _membershipCertificates[cert.issuedTo()]; - // Nothing to do if the cert hasn't changed -- we get duplicates due to zealous cert pushing - if (old == cert) - return true; // but if it's a duplicate of one we already accepted, return is 'true' + { + const _RemoteMemberCertificateInfo *ci = _certInfo.get(cert.issuedTo()); + if ((ci)&&(ci->com == cert)) + return true; // we already have it + } // Check signature, log and return if cert is invalid if (cert.signedBy() != controller()) { @@ -322,9 +326,8 @@ bool Network::validateAndAddMembershipCertificate(const CertificateOfMembership } } - // If we made it past authentication, update cert - if (cert.revision() != old.revision()) - old = cert; + // If we made it past authentication, add or update cert in our cert info store + _certInfo[cert.issuedTo()].com = cert; return true; } @@ -333,9 +336,9 @@ bool Network::peerNeedsOurMembershipCertificate(const Address &to,uint64_t now) { Mutex::Lock _l(_lock); if ((_config)&&(!_config->isPublic())&&(_config->com())) { - uint64_t &lastPushed = _lastPushedMembershipCertificate[to]; - if ((now - lastPushed) > (ZT_NETWORK_AUTOCONF_DELAY / 2)) { - lastPushed = now; + _RemoteMemberCertificateInfo &ci = _certInfo[to]; + if ((now - ci.lastPushed) > (ZT_NETWORK_AUTOCONF_DELAY / 2)) { + ci.lastPushed = now; return true; } } @@ -352,23 +355,16 @@ void Network::clean() if ((_config)&&(_config->isPublic())) { // Open (public) networks do not track certs or cert pushes at all. - _membershipCertificates.clear(); - _lastPushedMembershipCertificate.clear(); + _certInfo.clear(); } else if (_config) { - // Clean certificates that are no longer valid from the cache. - for(std::map::iterator c=(_membershipCertificates.begin());c!=_membershipCertificates.end();) { - if (_config->com().agreesWith(c->second)) - ++c; - else _membershipCertificates.erase(c++); - } - - // Clean entries from the last pushed tracking map if they're so old as - // to be no longer relevant. - uint64_t forgetIfBefore = now - (ZT_PEER_ACTIVITY_TIMEOUT * 16); // arbitrary reasonable cutoff - for(std::map::iterator lp(_lastPushedMembershipCertificate.begin());lp!=_lastPushedMembershipCertificate.end();) { - if (lp->second < forgetIfBefore) - _lastPushedMembershipCertificate.erase(lp++); - else ++lp; + // Clean obsolete entries from private network cert info table + Hashtable< Address,_RemoteMemberCertificateInfo >::Iterator i(_certInfo); + Address *a = (Address *)0; + _RemoteMemberCertificateInfo *ci = (_RemoteMemberCertificateInfo *)0; + const uint64_t forgetIfBefore = now - (ZT_PEER_ACTIVITY_TIMEOUT * 16); // arbitrary reasonable cutoff + while (i.next(a,ci)) { + if ((ci->lastPushed < forgetIfBefore)&&(!ci->com.agreesWith(_config->com()))) + _certInfo.erase(*a); } } @@ -506,12 +502,10 @@ bool Network::_isAllowed(const Address &peer) const return false; if (_config->isPublic()) return true; - - std::map::const_iterator pc(_membershipCertificates.find(peer)); - if (pc == _membershipCertificates.end()) - return false; // no certificate on file - - return _config->com().agreesWith(pc->second); // is other cert valid against ours? + const _RemoteMemberCertificateInfo *ci = _certInfo.get(peer); + if (!ci) + return false; + return _config->com().agreesWith(ci->com); } catch (std::exception &exc) { TRACE("isAllowed() check failed for peer %s: unexpected exception: %s",peer.toString().c_str(),exc.what()); } catch ( ... ) { diff --git a/node/Network.hpp b/node/Network.hpp index d8ffd612..7f215555 100644 --- a/node/Network.hpp +++ b/node/Network.hpp @@ -347,6 +347,13 @@ public: inline bool operator>=(const Network &n) const throw() { return (_id >= n._id); } private: + struct _RemoteMemberCertificateInfo + { + _RemoteMemberCertificateInfo() : com(),lastPushed(0) {} + CertificateOfMembership com; // remote member's COM + uint64_t lastPushed; // when did we last push ours to them? + }; + ZT1_VirtualNetworkStatus _status() const; void _externalConfig(ZT1_VirtualNetworkConfig *ec) const; // assumes _lock is locked bool _isAllowed(const Address &peer) const; @@ -361,11 +368,9 @@ private: std::vector< MulticastGroup > _myMulticastGroups; // multicast groups that we belong to (according to tap) Hashtable< MulticastGroup,uint64_t > _multicastGroupsBehindMe; // multicast groups that seem to be behind us and when we last saw them (if we are a bridge) + Hashtable< MAC,Address > _remoteBridgeRoutes; // remote addresses where given MACs are reachable (for tracking devices behind remote bridges) - Hashtable< MAC,Address > _remoteBridgeRoutes; // remote addresses where given MACs are reachable (for remote bridges) - - std::map _membershipCertificates; // Other members' certificates of membership - std::map _lastPushedMembershipCertificate; // When did we last push our certificate to each remote member? + Hashtable< Address,_RemoteMemberCertificateInfo > _certInfo; SharedPtr _config; // Most recent network configuration, which is an immutable value-object volatile uint64_t _lastConfigUpdate; -- cgit v1.2.3 From f116c4b9c05e88130cb7f2970b616f7930c30c6c Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Fri, 4 Sep 2015 14:24:31 -0700 Subject: ... and another ... --- node/SelfAwareness.cpp | 37 ++++++++++++++----------------------- node/SelfAwareness.hpp | 14 +++++--------- 2 files changed, 19 insertions(+), 32 deletions(-) (limited to 'node') diff --git a/node/SelfAwareness.cpp b/node/SelfAwareness.cpp index 716cf7f3..7329322a 100644 --- a/node/SelfAwareness.cpp +++ b/node/SelfAwareness.cpp @@ -107,10 +107,14 @@ void SelfAwareness::iam(const Address &reporter,const InetAddress &reporterPhysi // Erase all entries (other than this one) for this scope to prevent thrashing // Note: we should probably not use 'entry' after this - for(std::map< PhySurfaceKey,PhySurfaceEntry >::iterator p(_phy.begin());p!=_phy.end();) { - if ((p->first.reporter != reporter)&&(p->first.scope == scope)) - _phy.erase(p++); - else ++p; + { + Hashtable< PhySurfaceKey,PhySurfaceEntry >::Iterator i(_phy); + PhySurfaceKey *k = (PhySurfaceKey *)0; + PhySurfaceEntry *e = (PhySurfaceEntry *)0; + while (i.next(k,e)) { + if ((k->reporter != reporter)&&(k->scope == scope)) + _phy.erase(*k); + } } _ResetWithinScope rset(RR,now,(InetAddress::IpScope)scope); @@ -140,26 +144,13 @@ void SelfAwareness::iam(const Address &reporter,const InetAddress &reporterPhysi void SelfAwareness::clean(uint64_t now) { Mutex::Lock _l(_phy_m); - for(std::map< PhySurfaceKey,PhySurfaceEntry >::iterator p(_phy.begin());p!=_phy.end();) { - if ((now - p->second.ts) >= ZT_SELFAWARENESS_ENTRY_TIMEOUT) - _phy.erase(p++); - else ++p; - } -} - -bool SelfAwareness::areGlobalIPv4PortsRandomized() const -{ - int port = 0; - Mutex::Lock _l(_phy_m); - for(std::map< PhySurfaceKey,PhySurfaceEntry >::const_iterator p(_phy.begin());p!=_phy.end();++p) { - if ((p->first.scope == InetAddress::IP_SCOPE_GLOBAL)&&(p->second.mySurface.ss_family == AF_INET)) { - const int tmp = (int)p->second.mySurface.port(); - if ((port)&&(tmp != port)) - return true; - else port = tmp; - } + Hashtable< PhySurfaceKey,PhySurfaceEntry >::Iterator i(_phy); + PhySurfaceKey *k = (PhySurfaceKey *)0; + PhySurfaceEntry *e = (PhySurfaceEntry *)0; + while (i.next(k,e)) { + if ((now - e->ts) >= ZT_SELFAWARENESS_ENTRY_TIMEOUT) + _phy.erase(*k); } - return false; } } // namespace ZeroTier diff --git a/node/SelfAwareness.hpp b/node/SelfAwareness.hpp index d3b79d18..3133553e 100644 --- a/node/SelfAwareness.hpp +++ b/node/SelfAwareness.hpp @@ -28,10 +28,9 @@ #ifndef ZT_SELFAWARENESS_HPP #define ZT_SELFAWARENESS_HPP -#include -#include - +#include "Constants.hpp" #include "InetAddress.hpp" +#include "Hashtable.hpp" #include "Address.hpp" #include "Mutex.hpp" @@ -66,17 +65,14 @@ public: */ void clean(uint64_t now); - /** - * @return True if our external (global scope) IPv4 ports appear to be randomized by a NAT device - */ - bool areGlobalIPv4PortsRandomized() const; - private: struct PhySurfaceKey { Address reporter; InetAddress::IpScope scope; + inline unsigned long hashCode() const throw() { return ((unsigned long)reporter.toInt() + (unsigned long)scope); } + PhySurfaceKey() : reporter(),scope(InetAddress::IP_SCOPE_NONE) {} PhySurfaceKey(const Address &r,InetAddress::IpScope s) : reporter(r),scope(s) {} inline bool operator<(const PhySurfaceKey &k) const throw() { return ((reporter < k.reporter) ? true : ((reporter == k.reporter) ? ((int)scope < (int)k.scope) : false)); } @@ -93,7 +89,7 @@ private: const RuntimeEnvironment *RR; - std::map< PhySurfaceKey,PhySurfaceEntry > _phy; + Hashtable< PhySurfaceKey,PhySurfaceEntry > _phy; Mutex _phy_m; }; -- cgit v1.2.3 From 0ab3e49be91ed7a8723c8b58750aef77c01e8d08 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Fri, 4 Sep 2015 14:44:22 -0700 Subject: Starting in on Switch... kill map in defrag queue, which will probably improve performance pretty decently under high load with lots of peers. --- node/Hashtable.hpp | 9 ++++++--- node/Switch.cpp | 49 ++++++++++++++++++++++++++----------------------- node/Switch.hpp | 4 +++- 3 files changed, 35 insertions(+), 27 deletions(-) (limited to 'node') diff --git a/node/Hashtable.hpp b/node/Hashtable.hpp index 59a57726..29c54838 100644 --- a/node/Hashtable.hpp +++ b/node/Hashtable.hpp @@ -372,9 +372,12 @@ private: } static inline unsigned long _hc(const uint64_t i) { - // NOTE: this is fine for network IDs, but might be bad for other kinds - // of IDs if they are not evenly or randomly distributed. - return (unsigned long)((i ^ (i >> 32)) * 2654435761ULL); + /* NOTE: this assumes that 'i' is evenly distributed, which is the case for + * packet IDs and network IDs -- the two use cases in ZT for uint64_t keys. + * These values are also greater than 0xffffffff so they'll map onto a full + * bucket count just fine no matter what happens. Normally you'd want to + * hash an integer key index in a hash table. */ + return (unsigned long)i; } inline void _grow() diff --git a/node/Switch.cpp b/node/Switch.cpp index 989f497a..3dcb7002 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -531,11 +531,14 @@ unsigned long Switch::doTimerTasks(uint64_t now) { // Time out packets that didn't get all their fragments. Mutex::Lock _l(_defragQueue_m); - for(std::map< uint64_t,DefragQueueEntry >::iterator i(_defragQueue.begin());i!=_defragQueue.end();) { - if ((now - i->second.creationTime) > ZT_FRAGMENTED_PACKET_RECEIVE_TIMEOUT) { + Hashtable< uint64_t,DefragQueueEntry >::Iterator i(_defragQueue); + uint64_t *packetId = (uint64_t *)0; + DefragQueueEntry *qe = (DefragQueueEntry *)0; + while (i.next(packetId,qe)) { + if ((now - qe->creationTime) > ZT_FRAGMENTED_PACKET_RECEIVE_TIMEOUT) { TRACE("incomplete fragmented packet %.16llx timed out, fragments discarded",i->first); - _defragQueue.erase(i++); - } else ++i; + _defragQueue.erase(*packetId); + } } } @@ -577,32 +580,31 @@ void Switch::_handleRemotePacketFragment(const InetAddress &fromAddr,const void // seeing a Packet::Fragment? Mutex::Lock _l(_defragQueue_m); - std::map< uint64_t,DefragQueueEntry >::iterator dqe(_defragQueue.find(pid)); + DefragQueueEntry &dq = _defragQueue[pid]; - if (dqe == _defragQueue.end()) { + if (!dq.creationTime) { // We received a Packet::Fragment without its head, so queue it and wait - DefragQueueEntry &dq = _defragQueue[pid]; dq.creationTime = RR->node->now(); dq.frags[fno - 1] = fragment; dq.totalFragments = tf; // total fragment count is known dq.haveFragments = 1 << fno; // we have only this fragment //TRACE("fragment (%u/%u) of %.16llx from %s",fno + 1,tf,pid,fromAddr.toString().c_str()); - } else if (!(dqe->second.haveFragments & (1 << fno))) { + } else if (!(dq.haveFragments & (1 << fno))) { // We have other fragments and maybe the head, so add this one and check - dqe->second.frags[fno - 1] = fragment; - dqe->second.totalFragments = tf; + dq.frags[fno - 1] = fragment; + dq.totalFragments = tf; //TRACE("fragment (%u/%u) of %.16llx from %s",fno + 1,tf,pid,fromAddr.toString().c_str()); - if (Utils::countBits(dqe->second.haveFragments |= (1 << fno)) == tf) { + if (Utils::countBits(dq.haveFragments |= (1 << fno)) == tf) { // We have all fragments -- assemble and process full Packet //TRACE("packet %.16llx is complete, assembling and processing...",pid); - SharedPtr packet(dqe->second.frag0); + SharedPtr packet(dq.frag0); for(unsigned int f=1;fappend(dqe->second.frags[f - 1].payload(),dqe->second.frags[f - 1].payloadLength()); - _defragQueue.erase(dqe); + packet->append(dq.frags[f - 1].payload(),dq.frags[f - 1].payloadLength()); + _defragQueue.erase(pid); // dq no longer valid after this if (!packet->tryDecode(RR)) { Mutex::Lock _l(_rxQueue_m); @@ -645,26 +647,27 @@ void Switch::_handleRemotePacketHead(const InetAddress &fromAddr,const void *dat uint64_t pid = packet->packetId(); Mutex::Lock _l(_defragQueue_m); - std::map< uint64_t,DefragQueueEntry >::iterator dqe(_defragQueue.find(pid)); + DefragQueueEntry &dq = _defragQueue[pid]; - if (dqe == _defragQueue.end()) { + if (!dq.creationTime) { // If we have no other fragments yet, create an entry and save the head - DefragQueueEntry &dq = _defragQueue[pid]; + dq.creationTime = RR->node->now(); dq.frag0 = packet; dq.totalFragments = 0; // 0 == unknown, waiting for Packet::Fragment dq.haveFragments = 1; // head is first bit (left to right) //TRACE("fragment (0/?) of %.16llx from %s",pid,fromAddr.toString().c_str()); - } else if (!(dqe->second.haveFragments & 1)) { + } else if (!(dq.haveFragments & 1)) { // If we have other fragments but no head, see if we are complete with the head - if ((dqe->second.totalFragments)&&(Utils::countBits(dqe->second.haveFragments |= 1) == dqe->second.totalFragments)) { + + if ((dq.totalFragments)&&(Utils::countBits(dq.haveFragments |= 1) == dq.totalFragments)) { // We have all fragments -- assemble and process full Packet //TRACE("packet %.16llx is complete, assembling and processing...",pid); // packet already contains head, so append fragments - for(unsigned int f=1;fsecond.totalFragments;++f) - packet->append(dqe->second.frags[f - 1].payload(),dqe->second.frags[f - 1].payloadLength()); - _defragQueue.erase(dqe); + for(unsigned int f=1;fappend(dq.frags[f - 1].payload(),dq.frags[f - 1].payloadLength()); + _defragQueue.erase(pid); // dq no longer valid after this if (!packet->tryDecode(RR)) { Mutex::Lock _l(_rxQueue_m); @@ -672,7 +675,7 @@ void Switch::_handleRemotePacketHead(const InetAddress &fromAddr,const void *dat } } else { // Still waiting on more fragments, so queue the head - dqe->second.frag0 = packet; + dq.frag0 = packet; } } // else this is a duplicate head, ignore } else { diff --git a/node/Switch.hpp b/node/Switch.hpp index ac85606e..a1b36014 100644 --- a/node/Switch.hpp +++ b/node/Switch.hpp @@ -45,6 +45,7 @@ #include "Network.hpp" #include "SharedPtr.hpp" #include "IncomingPacket.hpp" +#include "Hashtable.hpp" /* Ethernet frame types that might be relevant to us */ #define ZT_ETHERTYPE_IPV4 0x0800 @@ -199,13 +200,14 @@ private: // Packet defragmentation queue -- comes before RX queue in path struct DefragQueueEntry { + DefragQueueEntry() : creationTime(0),totalFragments(0),haveFragments(0) {} uint64_t creationTime; SharedPtr frag0; Packet::Fragment frags[ZT_MAX_PACKET_FRAGMENTS - 1]; unsigned int totalFragments; // 0 if only frag0 received, waiting for frags uint32_t haveFragments; // bit mask, LSB to MSB }; - std::map< uint64_t,DefragQueueEntry > _defragQueue; + Hashtable< uint64_t,DefragQueueEntry > _defragQueue; Mutex _defragQueue_m; // ZeroTier-layer RX queue of incoming packets in the process of being decoded -- cgit v1.2.3 From db0369e9b8e6bf49ce8ec8f7fe706004314d4548 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Fri, 4 Sep 2015 14:56:39 -0700 Subject: Remove way-overkill multimap from Switch. --- node/Switch.cpp | 27 ++++++++++++++------------- node/Switch.hpp | 8 +++++--- 2 files changed, 19 insertions(+), 16 deletions(-) (limited to 'node') diff --git a/node/Switch.cpp b/node/Switch.cpp index 3dcb7002..7d6f8094 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -291,7 +291,7 @@ void Switch::send(const Packet &packet,bool encrypt,uint64_t nwid) if (!_trySend(packet,encrypt,nwid)) { Mutex::Lock _l(_txQueue_m); - _txQueue.insert(std::pair< Address,TXQueueEntry >(packet.destination(),TXQueueEntry(RR->node->now(),packet,encrypt,nwid))); + _txQueue.push_back(TXQueueEntry(packet.destination(),RR->node->now(),packet,encrypt,nwid)); } } @@ -435,11 +435,12 @@ void Switch::doAnythingWaitingForPeer(const SharedPtr &peer) { // finish sending any packets waiting on peer's public key / identity Mutex::Lock _l(_txQueue_m); - std::pair< std::multimap< Address,TXQueueEntry >::iterator,std::multimap< Address,TXQueueEntry >::iterator > waitingTxQueueItems(_txQueue.equal_range(peer->address())); - for(std::multimap< Address,TXQueueEntry >::iterator txi(waitingTxQueueItems.first);txi!=waitingTxQueueItems.second;) { - if (_trySend(txi->second.packet,txi->second.encrypt,txi->second.nwid)) - _txQueue.erase(txi++); - else ++txi; + for(std::list< TXQueueEntry >::iterator txi(_txQueue.begin());txi!=_txQueue.end();) { + if (txi->dest == peer->address()) { + if (_trySend(txi->packet,txi->encrypt,txi->nwid)) + _txQueue.erase(txi++); + else ++txi; + } else ++txi; } } } @@ -509,13 +510,13 @@ unsigned long Switch::doTimerTasks(uint64_t now) { // Time out TX queue packets that never got WHOIS lookups or other info. Mutex::Lock _l(_txQueue_m); - for(std::multimap< Address,TXQueueEntry >::iterator i(_txQueue.begin());i!=_txQueue.end();) { - if (_trySend(i->second.packet,i->second.encrypt,i->second.nwid)) - _txQueue.erase(i++); - else if ((now - i->second.creationTime) > ZT_TRANSMIT_QUEUE_TIMEOUT) { - TRACE("TX %s -> %s timed out",i->second.packet.source().toString().c_str(),i->second.packet.destination().toString().c_str()); - _txQueue.erase(i++); - } else ++i; + for(std::list< TXQueueEntry >::iterator txi(_txQueue.begin());txi!=_txQueue.end();) { + if (_trySend(txi->packet,txi->encrypt,txi->nwid)) + _txQueue.erase(txi++); + else if ((now - txi->creationTime) > ZT_TRANSMIT_QUEUE_TIMEOUT) { + TRACE("TX %s -> %s timed out",txi->packet.source().toString().c_str(),txi->packet.destination().toString().c_str()); + _txQueue.erase(txi++); + } else ++txi; } } diff --git a/node/Switch.hpp b/node/Switch.hpp index a1b36014..0791681f 100644 --- a/node/Switch.hpp +++ b/node/Switch.hpp @@ -214,22 +214,24 @@ private: std::list< SharedPtr > _rxQueue; Mutex _rxQueue_m; - // ZeroTier-layer TX queue by destination ZeroTier address + // ZeroTier-layer TX queue entry struct TXQueueEntry { TXQueueEntry() {} - TXQueueEntry(uint64_t ct,const Packet &p,bool enc,uint64_t nw) : + TXQueueEntry(Address d,uint64_t ct,const Packet &p,bool enc,uint64_t nw) : + dest(d), creationTime(ct), nwid(nw), packet(p), encrypt(enc) {} + Address dest; uint64_t creationTime; uint64_t nwid; Packet packet; // unencrypted/unMAC'd packet -- this is done at send time bool encrypt; }; - std::multimap< Address,TXQueueEntry > _txQueue; + std::list< TXQueueEntry > _txQueue; Mutex _txQueue_m; // Tracks sending of VERB_RENDEZVOUS to relaying peers -- cgit v1.2.3 From 3dba016a9354d9c50743877988c8d928d25f7a2b Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Fri, 4 Sep 2015 15:21:22 -0700 Subject: Almost done... very few std::map<>s remaining in any spot that matters. --- node/Hashtable.hpp | 5 +++-- node/Switch.cpp | 38 ++++++++++++++++++-------------------- node/Switch.hpp | 19 ++++++++++++++++++- 3 files changed, 39 insertions(+), 23 deletions(-) (limited to 'node') diff --git a/node/Hashtable.hpp b/node/Hashtable.hpp index 29c54838..bcc111e3 100644 --- a/node/Hashtable.hpp +++ b/node/Hashtable.hpp @@ -39,8 +39,9 @@ namespace ZeroTier { * A minimal hash table implementation for the ZeroTier core * * This is not a drop-in replacement for STL containers, and has several - * limitations. It's designed to be small and fast for use in the - * ZeroTier core. + * limitations. Keys can be uint64_t or an object, and if the latter they + * must implement a method called hashCode() that returns an unsigned long + * value that is evenly distributed. */ template class Hashtable diff --git a/node/Switch.cpp b/node/Switch.cpp index 7d6f8094..d5ee3e23 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -309,31 +309,18 @@ bool Switch::unite(const Address &p1,const Address &p2,bool force) const uint64_t now = RR->node->now(); - std::pair cg(Peer::findCommonGround(*p1p,*p2p,now)); - if (!(cg.first)) - return false; - - if (cg.first.ipScope() != cg.second.ipScope()) - return false; - - // Addresses are sorted in key for last unite attempt map for order - // invariant lookup: (p1,p2) == (p2,p1) - Array uniteKey; - if (p1 >= p2) { - uniteKey[0] = p2; - uniteKey[1] = p1; - } else { - uniteKey[0] = p1; - uniteKey[1] = p2; - } { Mutex::Lock _l(_lastUniteAttempt_m); - std::map< Array< Address,2 >,uint64_t >::const_iterator e(_lastUniteAttempt.find(uniteKey)); - if ((!force)&&(e != _lastUniteAttempt.end())&&((now - e->second) < ZT_MIN_UNITE_INTERVAL)) + uint64_t &luts = _lastUniteAttempt[_LastUniteKey(p1,p2)]; + if (((now - luts) < ZT_MIN_UNITE_INTERVAL)&&(!force)) return false; - else _lastUniteAttempt[uniteKey] = now; + luts = now; } + std::pair cg(Peer::findCommonGround(*p1p,*p2p,now)); + if ((!(cg.first))||(cg.first.ipScope() != cg.second.ipScope())) + return false; + TRACE("unite: %s(%s) <> %s(%s)",p1.toString().c_str(),cg.second.toString().c_str(),p2.toString().c_str(),cg.first.toString().c_str()); /* Tell P1 where to find P2 and vice versa, sending the packets to P1 and @@ -543,6 +530,17 @@ unsigned long Switch::doTimerTasks(uint64_t now) } } + { // Remove really old last unite attempt entries to keep table size controlled + Mutex::Lock _l(_lastUniteAttempt_m); + Hashtable< _LastUniteKey,uint64_t >::Iterator i(_lastUniteAttempt); + _LastUniteKey *k = (_LastUniteKey *)0; + uint64_t *v = (uint64_t *)0; + while (i.next(k,v)) { + if ((now - *v) >= (ZT_MIN_UNITE_INTERVAL * 16)) + _lastUniteAttempt.erase(*k); + } + } + return nextDelay; } diff --git a/node/Switch.hpp b/node/Switch.hpp index 0791681f..2d83b70c 100644 --- a/node/Switch.hpp +++ b/node/Switch.hpp @@ -235,7 +235,24 @@ private: Mutex _txQueue_m; // Tracks sending of VERB_RENDEZVOUS to relaying peers - std::map< Array< Address,2 >,uint64_t > _lastUniteAttempt; // key is always sorted in ascending order, for set-like behavior + struct _LastUniteKey + { + _LastUniteKey() : x(0),y(0) {} + _LastUniteKey(const Address &a1,const Address &a2) + { + if (a1 > a2) { + x = a2.toInt(); + y = a1.toInt(); + } else { + x = a1.toInt(); + y = a2.toInt(); + } + } + inline unsigned long hashCode() const throw() { return ((unsigned long)x ^ (unsigned long)y); } + inline bool operator==(const _LastUniteKey &k) const throw() { return ((x == k.x)&&(y == k.y)); } + uint64_t x,y; + }; + Hashtable< _LastUniteKey,uint64_t > _lastUniteAttempt; // key is always sorted in ascending order, for set-like behavior Mutex _lastUniteAttempt_m; // Active attempts to contact remote peers, including state of multi-phase NAT traversal -- cgit v1.2.3 From 85b90f122a826510491e15a1bfd6c1fe75dfe069 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Fri, 4 Sep 2015 15:35:43 -0700 Subject: Final std::map<> from Switch, and add some smallish default values for hash size. --- node/Switch.cpp | 41 ++++++++++++++++++++++++----------------- node/Switch.hpp | 3 ++- 2 files changed, 26 insertions(+), 18 deletions(-) (limited to 'node') diff --git a/node/Switch.cpp b/node/Switch.cpp index d5ee3e23..995abef4 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -67,7 +67,10 @@ static const char *etherTypeName(const unsigned int etherType) Switch::Switch(const RuntimeEnvironment *renv) : RR(renv), - _lastBeaconResponse(0) + _lastBeaconResponse(0), + _outstandingWhoisRequests(32), + _defragQueue(32), + _lastUniteAttempt(8) // only really used on root servers and upstreams, and it'll grow there just fine { } @@ -389,10 +392,13 @@ void Switch::requestWhois(const Address &addr) bool inserted = false; { Mutex::Lock _l(_outstandingWhoisRequests_m); - std::pair< std::map< Address,WhoisRequest >::iterator,bool > entry(_outstandingWhoisRequests.insert(std::pair(addr,WhoisRequest()))); - if ((inserted = entry.second)) - entry.first->second.lastSent = RR->node->now(); - entry.first->second.retries = 0; // reset retry count if entry already existed + WhoisRequest &r = _outstandingWhoisRequests[addr]; + if (r.lastSent) { + r.retries = 0; // reset retry count if entry already existed, but keep waiting and retry again after normal timeout + } else { + r.lastSent = RR->node->now(); + inserted = true; + } } if (inserted) _sendWhoisRequest(addr,(const Address *)0,0); @@ -474,24 +480,25 @@ unsigned long Switch::doTimerTasks(uint64_t now) { // Retry outstanding WHOIS requests Mutex::Lock _l(_outstandingWhoisRequests_m); - for(std::map< Address,WhoisRequest >::iterator i(_outstandingWhoisRequests.begin());i!=_outstandingWhoisRequests.end();) { - unsigned long since = (unsigned long)(now - i->second.lastSent); + Hashtable< Address,WhoisRequest >::Iterator i(_outstandingWhoisRequests); + Address *a = (Address *)0; + WhoisRequest *r = (WhoisRequest *)0; + while (i.next(a,r)) { + const unsigned long since = (unsigned long)(now - r->lastSent); if (since >= ZT_WHOIS_RETRY_DELAY) { - if (i->second.retries >= ZT_MAX_WHOIS_RETRIES) { - TRACE("WHOIS %s timed out",i->first.toString().c_str()); - _outstandingWhoisRequests.erase(i++); - continue; + if (r->retries >= ZT_MAX_WHOIS_RETRIES) { + TRACE("WHOIS %s timed out",a->toString().c_str()); + _outstandingWhoisRequests.erase(*a); } else { - i->second.lastSent = now; - i->second.peersConsulted[i->second.retries] = _sendWhoisRequest(i->first,i->second.peersConsulted,i->second.retries); - ++i->second.retries; - TRACE("WHOIS %s (retry %u)",i->first.toString().c_str(),i->second.retries); + r->lastSent = now; + r->peersConsulted[r->retries] = _sendWhoisRequest(*a,r->peersConsulted,r->retries); + ++r->retries; + TRACE("WHOIS %s (retry %u)",a->toString().c_str(),r->retries); nextDelay = std::min(nextDelay,(unsigned long)ZT_WHOIS_RETRY_DELAY); } } else { nextDelay = std::min(nextDelay,ZT_WHOIS_RETRY_DELAY - since); } - ++i; } } @@ -524,7 +531,7 @@ unsigned long Switch::doTimerTasks(uint64_t now) DefragQueueEntry *qe = (DefragQueueEntry *)0; while (i.next(packetId,qe)) { if ((now - qe->creationTime) > ZT_FRAGMENTED_PACKET_RECEIVE_TIMEOUT) { - TRACE("incomplete fragmented packet %.16llx timed out, fragments discarded",i->first); + TRACE("incomplete fragmented packet %.16llx timed out, fragments discarded",*packetId); _defragQueue.erase(*packetId); } } diff --git a/node/Switch.hpp b/node/Switch.hpp index 2d83b70c..55e2c362 100644 --- a/node/Switch.hpp +++ b/node/Switch.hpp @@ -190,11 +190,12 @@ private: // Outsanding WHOIS requests and how many retries they've undergone struct WhoisRequest { + WhoisRequest() : lastSent(0),retries(0) {} uint64_t lastSent; Address peersConsulted[ZT_MAX_WHOIS_RETRIES]; // by retry unsigned int retries; // 0..ZT_MAX_WHOIS_RETRIES }; - std::map< Address,WhoisRequest > _outstandingWhoisRequests; + Hashtable< Address,WhoisRequest > _outstandingWhoisRequests; Mutex _outstandingWhoisRequests_m; // Packet defragmentation queue -- comes before RX queue in path -- cgit v1.2.3 From 0d386f1c3119b869197bafd5f2ad75ba2179850f Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Tue, 8 Sep 2015 11:35:55 -0700 Subject: Add a bit of useful testing instrumentation to SqliteNetworkController. --- controller/SqliteNetworkController.cpp | 43 +++++++++++++++++++++++++++++++--- controller/SqliteNetworkController.hpp | 1 - node/IncomingPacket.cpp | 4 ++-- node/Network.cpp | 2 +- node/NetworkController.hpp | 2 -- 5 files changed, 43 insertions(+), 9 deletions(-) (limited to 'node') diff --git a/controller/SqliteNetworkController.cpp b/controller/SqliteNetworkController.cpp index 2a004bda..6a786ce4 100644 --- a/controller/SqliteNetworkController.cpp +++ b/controller/SqliteNetworkController.cpp @@ -301,7 +301,7 @@ SqliteNetworkController::~SqliteNetworkController() } } -NetworkController::ResultCode SqliteNetworkController::doNetworkConfigRequest(const InetAddress &fromAddr,const Identity &signingId,const Identity &identity,uint64_t nwid,const Dictionary &metaData,uint64_t haveRevision,Dictionary &netconf) +NetworkController::ResultCode SqliteNetworkController::doNetworkConfigRequest(const InetAddress &fromAddr,const Identity &signingId,const Identity &identity,uint64_t nwid,const Dictionary &metaData,Dictionary &netconf) { // Decode some stuff from metaData const unsigned int clientMajorVersion = (unsigned int)metaData.getHexUInt(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MAJOR_VERSION,0); @@ -1355,8 +1355,44 @@ unsigned int SqliteNetworkController::_doCPGet( sqlite3_bind_text(_sGetMember2,1,nwids,16,SQLITE_STATIC); sqlite3_bind_text(_sGetMember2,2,addrs,10,SQLITE_STATIC); if (sqlite3_step(_sGetMember2) == SQLITE_ROW) { + const char *memberIdStr = (const char *)sqlite3_column_text(_sGetMember2,3); + + // If testSingingId is included in the URL or X-ZT1-TestSigningId in the headers + // and if it contains an identity with a secret portion, the resturned JSON + // will contain an extra field called _testConf. This will contain several + // fields that report the result of doNetworkConfigRequest() for this member. + std::string testFields; + { + Identity testOutputSigningId; + std::map::const_iterator sid(urlArgs.find("testSigningId")); + if (sid != urlArgs.end()) { + testOutputSigningId.fromString(sid->second.c_str()); + } else { + sid = headers.find("x-zt1-testsigningid"); + if (sid != headers.end()) + testOutputSigningId.fromString(sid->second.c_str()); + } + + if ((testOutputSigningId.hasPrivate())&&(memberIdStr)) { + Dictionary testNetconf; + NetworkController::ResultCode rc = this->doNetworkConfigRequest( + InetAddress(), + testOutputSigningId, + Identity(memberIdStr), + nwid, + Dictionary(), // TODO: allow passing of meta-data for testing + testNetconf); + char rcs[16]; + Utils::snprintf(rcs,sizeof(rcs),"%d",(int)rc); + testFields.append("\t\"_test\": {\n"); + testFields.append("\t\t\"resultCode\": "); testFields.append(rcs); testFields.append(",\n"); + testFields.append("\t\t\"result\": \""); testFields.append(_jsonEscape(testNetconf.toString().c_str()).c_str()); testFields.append("\""); + testFields.append("\t}\n"); + } + } + Utils::snprintf(json,sizeof(json), - "{\n" + "{\n%s" "\t\"nwid\": \"%s\",\n" "\t\"address\": \"%s\",\n" "\t\"controllerInstanceId\": \"%s\",\n" @@ -1366,6 +1402,7 @@ unsigned int SqliteNetworkController::_doCPGet( "\t\"clock\": %llu,\n" "\t\"identity\": \"%s\",\n" "\t\"ipAssignments\": [", + testFields.c_str(), nwids, addrs, _instanceId.c_str(), @@ -1373,7 +1410,7 @@ unsigned int SqliteNetworkController::_doCPGet( (sqlite3_column_int(_sGetMember2,1) > 0) ? "true" : "false", (unsigned long long)sqlite3_column_int64(_sGetMember2,2), (unsigned long long)OSUtils::now(), - _jsonEscape((const char *)sqlite3_column_text(_sGetMember2,3)).c_str()); + _jsonEscape(memberIdStr).c_str()); responseBody = json; sqlite3_reset(_sGetIpAssignmentsForNode2); diff --git a/controller/SqliteNetworkController.hpp b/controller/SqliteNetworkController.hpp index adfe0991..26a06968 100644 --- a/controller/SqliteNetworkController.hpp +++ b/controller/SqliteNetworkController.hpp @@ -54,7 +54,6 @@ public: const Identity &identity, uint64_t nwid, const Dictionary &metaData, - uint64_t haveRevision, Dictionary &netconf); unsigned int handleControlPlaneHttpGET( diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index b1fda8ef..fc79270b 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -662,7 +662,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons const uint64_t nwid = at(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_NETWORK_ID); const unsigned int metaDataLength = at(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT_LEN); const Dictionary metaData((const char *)field(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT,metaDataLength),metaDataLength); - const uint64_t haveRevision = ((ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT + metaDataLength + 8) <= size()) ? at(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT + metaDataLength) : 0ULL; + //const uint64_t haveRevision = ((ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT + metaDataLength + 8) <= size()) ? at(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT + metaDataLength) : 0ULL; const unsigned int h = hops(); const uint64_t pid = packetId(); @@ -670,7 +670,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons if (RR->localNetworkController) { Dictionary netconf; - switch(RR->localNetworkController->doNetworkConfigRequest((h > 0) ? InetAddress() : _remoteAddress,RR->identity,peer->identity(),nwid,metaData,haveRevision,netconf)) { + switch(RR->localNetworkController->doNetworkConfigRequest((h > 0) ? InetAddress() : _remoteAddress,RR->identity,peer->identity(),nwid,metaData,netconf)) { case NetworkController::NETCONF_QUERY_OK: { const std::string netconfStr(netconf.toString()); diff --git a/node/Network.cpp b/node/Network.cpp index 331b37a2..f8130d76 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -240,7 +240,7 @@ void Network::requestConfiguration() if (RR->localNetworkController) { SharedPtr nconf(config2()); Dictionary newconf; - switch(RR->localNetworkController->doNetworkConfigRequest(InetAddress(),RR->identity,RR->identity,_id,Dictionary(),(nconf) ? nconf->revision() : (uint64_t)0,newconf)) { + switch(RR->localNetworkController->doNetworkConfigRequest(InetAddress(),RR->identity,RR->identity,_id,Dictionary(),newconf)) { case NetworkController::NETCONF_QUERY_OK: this->setConfiguration(newconf,true); return; diff --git a/node/NetworkController.hpp b/node/NetworkController.hpp index ee481a62..cf327d7e 100644 --- a/node/NetworkController.hpp +++ b/node/NetworkController.hpp @@ -75,7 +75,6 @@ public: * @param identity Originating peer ZeroTier identity * @param nwid 64-bit network ID * @param metaData Meta-data bundled with request (empty if none) - * @param haveRevision Network revision ID sent by requesting peer or 0 if none * @param result Dictionary to receive resulting signed netconf on success * @return Returns NETCONF_QUERY_OK if result dictionary is valid, or an error code on error */ @@ -85,7 +84,6 @@ public: const Identity &identity, uint64_t nwid, const Dictionary &metaData, - uint64_t haveRevision, Dictionary &result) = 0; }; -- cgit v1.2.3 From c1a53a26536d2635118262f5f719795b2e70e5fa Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Fri, 11 Sep 2015 11:45:04 -0700 Subject: ARP cache and responder agent code for use in netcon and iOS. --- node/Hashtable.hpp | 5 ++ node/MAC.hpp | 6 +++ osdep/Arp.cpp | 134 +++++++++++++++++++++++++++++++++++++++++++++ osdep/Arp.hpp | 156 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 301 insertions(+) create mode 100644 osdep/Arp.cpp create mode 100644 osdep/Arp.hpp (limited to 'node') diff --git a/node/Hashtable.hpp b/node/Hashtable.hpp index bcc111e3..d2b85c15 100644 --- a/node/Hashtable.hpp +++ b/node/Hashtable.hpp @@ -380,6 +380,11 @@ private: * hash an integer key index in a hash table. */ return (unsigned long)i; } + static inline unsigned long _hc(const uint32_t i) + { + // In the uint32_t case we use a simple multiplier for hashing to ensure coverage + return ((unsigned long)i * (unsigned long)2654435761); + } inline void _grow() { diff --git a/node/MAC.hpp b/node/MAC.hpp index 619b7195..a9cd43cf 100644 --- a/node/MAC.hpp +++ b/node/MAC.hpp @@ -250,6 +250,12 @@ public: _m = m._m; return *this; } + inline MAC &operator=(const uint64_t m) + throw() + { + _m = m; + return *this; + } inline bool operator==(const MAC &m) const throw() { return (_m == m._m); } inline bool operator!=(const MAC &m) const throw() { return (_m != m._m); } diff --git a/osdep/Arp.cpp b/osdep/Arp.cpp new file mode 100644 index 00000000..f71dfb54 --- /dev/null +++ b/osdep/Arp.cpp @@ -0,0 +1,134 @@ +/* + * 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 . + * + * -- + * + * 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 "Arp.hpp" +#include "OSUtils.hpp" + +namespace ZeroTier { + +static const uint8_t ARP_REQUEST_HEADER[8] = { 0x00,0x01,0x08,0x00,0x06,0x04,0x00,0x01 }; +static const uint8_t ARP_RESPONSE_HEADER[8] = { 0x00,0x01,0x08,0x00,0x06,0x04,0x00,0x02 }; + +Arp::Arp() : + _cache(256), + _lastCleaned(OSUtils::now()) +{ +} + +void Arp::addLocal(uint32_t ip,const MAC &mac) +{ + _ArpEntry &e = _cache[ip]; + e.lastQuerySent = 0; // local IP + e.lastResponseReceived = 0; // local IP + e.mac = mac; + e.local = true; +} + +void Arp::remove(uint32_t ip) +{ + _cache.erase(ip); +} + +uint32_t Arp::processIncomingArp(const void *arp,unsigned int len,void *response,unsigned int &responseLen,MAC &responseDest) +{ + const uint64_t now = OSUtils::now(); + uint32_t ip = 0; + + responseLen = 0; + responseDest.zero(); + + if (len > 28) { + if (!memcmp(arp,ARP_REQUEST_HEADER,8)) { + // Respond to ARP requests for locally-known IPs + _ArpEntry *targetEntry = _cache.get(reinterpret_cast(arp)[6]); + if ((targetEntry)&&(targetEntry->local)) { + memcpy(response,ARP_RESPONSE_HEADER,8); + targetEntry->mac.copyTo(reinterpret_cast(response) + 8,6); + memcpy(reinterpret_cast(response) + 14,reinterpret_cast(arp) + 24,4); + memcpy(reinterpret_cast(response) + 18,reinterpret_cast(arp) + 8,10); + responseLen = 28; + responseDest.setTo(reinterpret_cast(arp) + 8,6); + } + } else if (!memcmp(arp,ARP_RESPONSE_HEADER,8)) { + // Learn cache entries for remote IPs from relevant ARP replies + uint32_t responseIp = 0; + memcpy(&responseIp,reinterpret_cast(arp) + 14,4); + _ArpEntry *queryEntry = _cache.get(responseIp); + if ((queryEntry)&&(!queryEntry->local)&&((now - queryEntry->lastQuerySent) <= ZT_ARP_QUERY_MAX_TTL)) { + queryEntry->lastResponseReceived = now; + queryEntry->mac.setTo(reinterpret_cast(arp) + 8,6); + ip = responseIp; + } + } + } + + if ((now - _lastCleaned) >= ZT_ARP_EXPIRE) { + _lastCleaned = now; + Hashtable< uint32_t,_ArpEntry >::Iterator i(_cache); + uint32_t *k = (uint32_t *)0; + _ArpEntry *v = (_ArpEntry *)0; + while (i.next(k,v)) { + if ((!v->local)&&((now - v->lastResponseReceived) >= ZT_ARP_EXPIRE)) + _cache.erase(*k); + } + } + + return ip; +} + +MAC Arp::query(const MAC &localMac,uint32_t ip,void *query,unsigned int &queryLen,MAC &queryDest) +{ + const uint64_t now = OSUtils::now(); + + _ArpEntry &e = _cache[ip]; + + if ( ((e.mac)&&((now - e.lastResponseReceived) >= (ZT_ARP_EXPIRE / 3))) || + ((!e.mac)&&((now - e.lastQuerySent) >= ZT_ARP_QUERY_INTERVAL)) ) { + e.lastQuerySent = now; + + uint8_t *q = reinterpret_cast(query); + memcpy(q,ARP_REQUEST_HEADER,8); q += 8; // ARP request header information, always the same + localMac.copyTo(q,6); q += 6; // sending host address + memset(q,0,10); q += 10; // sending IP and target media address are ignored in requests + memcpy(q,&ip,4); // target IP address for resolution (IP already in big-endian byte order) + queryLen = 28; + if (e.mac) + queryDest = e.mac; // confirmation query, send directly to address holder + else queryDest = (uint64_t)0xffffffffffffULL; // broadcast query + } else { + queryLen = 0; + queryDest.zero(); + } + + return e.mac; +} + +} // namespace ZeroTier diff --git a/osdep/Arp.hpp b/osdep/Arp.hpp new file mode 100644 index 00000000..b747cf85 --- /dev/null +++ b/osdep/Arp.hpp @@ -0,0 +1,156 @@ +/* + * 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 . + * + * -- + * + * 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_ARP_HPP +#define ZT_ARP_HPP + +#include + +#include + +#include "../node/Constants.hpp" +#include "../node/Hashtable.hpp" +#include "../node/MAC.hpp" + +/** + * Maximum possible ARP length + * + * ARPs are 28 bytes in length, but specify a 128 byte buffer since + * some weird extensions we may support in the future can pad them + * out to as long as 72 bytes. + */ +#define ZT_ARP_BUF_LENGTH 128 + +/** + * Minimum permitted interval between sending ARP queries for a given IP + */ +#define ZT_ARP_QUERY_INTERVAL 2000 + +/** + * Maximum time between query and response, otherwise responses are discarded to prevent poisoning + */ +#define ZT_ARP_QUERY_MAX_TTL 5000 + +/** + * ARP expiration time + */ +#define ZT_ARP_EXPIRE 600000 + +namespace ZeroTier { + +/** + * ARP cache and resolver + * + * To implement ARP: + * + * (1) Call processIncomingArp() on all ARP packets received and then always + * check responseLen after calling. If it is non-zero, send the contents + * of response to responseDest. + * + * (2) Call query() to look up IP addresses, and then check queryLen. If it + * is non-zero, send the contents of query to queryDest (usually broadcast). + * + * Note that either of these functions can technically generate a response or + * a query at any time, so their result parameters for sending ARPs should + * always be checked. + * + * This class is not thread-safe and must be guarded if used in multi-threaded + * code. + */ +class Arp +{ +public: + Arp(); + + /** + * Set a local IP entry that we should respond to ARPs for + * + * @param mac Our local MAC address + * @param ip IP in big-endian byte order (sin_addr.s_addr) + */ + void addLocal(uint32_t ip,const MAC &mac); + + /** + * Delete a local IP entry or a cached ARP entry + * + * @param ip IP in big-endian byte order (sin_addr.s_addr) + */ + void remove(uint32_t ip); + + /** + * Process ARP packets + * + * For ARP queries, a response is generated and responseLen is set to its + * frame payload length in bytes. + * + * For ARP responses, the cache is populated and the IP address entry that + * was learned is returned. + * + * @param arp ARP frame data + * @param len Length of ARP frame (usually 28) + * @param response Response buffer -- MUST be a minimum of ZT_ARP_BUF_LENGTH in size + * @param responseLen Response length, or set to 0 if no response + * @param responseDest Destination of response, or set to null if no response + * @return IP address learned or 0 if no new IPs in cache + */ + uint32_t processIncomingArp(const void *arp,unsigned int len,void *response,unsigned int &responseLen,MAC &responseDest); + + /** + * Get the MAC corresponding to an IP, generating a query if needed + * + * This returns a MAC for a remote IP. The local MAC is returned for local + * IPs as well. It may also generate a query if the IP is not known or the + * entry needs to be refreshed. In this case queryLen will be set to a + * non-zero value, so this should always be checked on return even if the + * MAC returned is non-null. + * + * @param localMac Local MAC address of host interface + * @param ip IP to look up + * @param query Buffer for generated query -- MUST be a minimum of ZT_ARP_BUF_LENGTH in size + * @param queryLen Length of generated query, or set to 0 if no query generated + * @param queryDest Destination of query, or set to null if no query generated + * @return MAC or 0 if no cached entry for this IP + */ + MAC query(const MAC &localMac,uint32_t ip,void *query,unsigned int &queryLen,MAC &queryDest); + +private: + struct _ArpEntry + { + _ArpEntry() : lastQuerySent(0),lastResponseReceived(0),mac(),local(false) {} + uint64_t lastQuerySent; // Time last query was sent or 0 for local IP + uint64_t lastResponseReceived; // Time of last ARP response or 0 for local IP + MAC mac; // MAC address of device responsible for IP or null if not known yet + bool local; // True if this is a local ARP entry + }; + + Hashtable< uint32_t,_ArpEntry > _cache; + uint64_t _lastCleaned; +}; + +} // namespace ZeroTier + +#endif -- cgit v1.2.3 From 36649663402c712126e0f64a1d6fc0ba4faf1ad1 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Thu, 17 Sep 2015 21:30:32 -0700 Subject: Generate local IPv6 addresses from network IDs and addresses. --- node/InetAddress.cpp | 26 ++++++++++++++++++++++++++ node/InetAddress.hpp | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) (limited to 'node') diff --git a/node/InetAddress.cpp b/node/InetAddress.cpp index 1942c4cd..e542f0d4 100644 --- a/node/InetAddress.cpp +++ b/node/InetAddress.cpp @@ -399,4 +399,30 @@ InetAddress InetAddress::makeIpv6LinkLocal(const MAC &mac) return InetAddress(sin6); } +InetAddress InetAddress::makeIpv6rfc4193(uint64_t nwid,uint64_t zeroTierAddress) + throw() +{ + InetAddress r; + struct sockaddr_in6 *const sin6 = reinterpret_cast(&r); + sin6->sin6_family = AF_INET6; + sin6->sin6_addr.s6_addr[0] = 0xfd; + sin6->sin6_addr.s6_addr[1] = (uint8_t)(nwid >> 56); + sin6->sin6_addr.s6_addr[2] = (uint8_t)(nwid >> 48); + sin6->sin6_addr.s6_addr[3] = (uint8_t)(nwid >> 40); + sin6->sin6_addr.s6_addr[4] = (uint8_t)(nwid >> 32); + sin6->sin6_addr.s6_addr[5] = (uint8_t)(nwid >> 24); + sin6->sin6_addr.s6_addr[6] = (uint8_t)(nwid >> 16); + sin6->sin6_addr.s6_addr[7] = (uint8_t)(nwid >> 8); + sin6->sin6_addr.s6_addr[8] = (uint8_t)nwid; + sin6->sin6_addr.s6_addr[9] = 0x99; + sin6->sin6_addr.s6_addr[10] = 0x93; + sin6->sin6_addr.s6_addr[11] = (uint8_t)(zeroTierAddress >> 32); + sin6->sin6_addr.s6_addr[12] = (uint8_t)(zeroTierAddress >> 24); + sin6->sin6_addr.s6_addr[13] = (uint8_t)(zeroTierAddress >> 16); + sin6->sin6_addr.s6_addr[14] = (uint8_t)(zeroTierAddress >> 8); + sin6->sin6_addr.s6_addr[15] = (uint8_t)zeroTierAddress; + sin6->sin6_port = Utils::hton((uint16_t)88); // /88 includes 0xfd + network ID, discriminating by device ID below that + return r; +} + } // namespace ZeroTier diff --git a/node/InetAddress.hpp b/node/InetAddress.hpp index e3537ce0..3c05d83b 100644 --- a/node/InetAddress.hpp +++ b/node/InetAddress.hpp @@ -375,6 +375,50 @@ struct InetAddress : public sockaddr_storage */ static InetAddress makeIpv6LinkLocal(const MAC &mac) throw(); + + /** + * Compute private IPv6 unicast address from network ID and ZeroTier address + * + * This generates a private unicast IPv6 address that is mostly compliant + * with the letter of RFC4193 and certainly compliant in spirit. + * + * RFC4193 specifies a format of: + * + * | 7 bits |1| 40 bits | 16 bits | 64 bits | + * | Prefix |L| Global ID | Subnet ID | Interface ID | + * + * The 'L' bit is set to 1, yielding an address beginning with 0xfd. Then + * the network ID is filled into the global ID, subnet ID, and first byte + * of the "interface ID" field. Since the first 40 bits of the network ID + * is the unique ZeroTier address of its controller, this makes a very + * good random global ID. Since network IDs have 24 more bits, we let it + * overflow into the interface ID. + * + * After that we pad with two bytes: 0x99, 0x93, namely the default ZeroTier + * port in hex. + * + * Finally we fill the remaining 40 bits of the interface ID field with + * the 40-bit unique ZeroTier device ID of the network member. + * + * This yields a valid RFC4193 address with a random global ID, a + * meaningful subnet ID, and a unique interface ID, all mappable back onto + * ZeroTier space. + * + * This in turn could allow us, on networks numbered this way, to emulate + * IPv6 NDP and eliminate all multicast. This could be beneficial for + * small devices and huge networks, e.g. IoT applications. + * + * The returned address is given an odd prefix length of /88, since within + * a given network only the last 40 bits (device ID) are variable. This + * is a bit unusual but as far as we know should not cause any problems with + * any non-braindead IPv6 stack. + * + * @param nwid 64-bit network ID + * @param zeroTierAddress 40-bit device address (in least significant 40 bits, highest 24 bits ignored) + * @return IPv6 private unicast address with /88 netmask + */ + static InetAddress makeIpv6rfc4193(uint64_t nwid,uint64_t zeroTierAddress) + throw(); }; } // namespace ZeroTier -- cgit v1.2.3 From d656e87395441b995d376c9174f3f0570cbf4396 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Tue, 22 Sep 2015 15:58:00 -0700 Subject: Send a random small payload for NAT keepalives, since zero byte packets seem to fail to keep associations alive behind some NATs. --- node/Peer.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'node') diff --git a/node/Peer.cpp b/node/Peer.cpp index c27afa8f..85874105 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -39,6 +39,9 @@ namespace ZeroTier { +// Used to send varying values for NAT keepalive +static uint32_t _natKeepaliveBuf = 0; + Peer::Peer(const Identity &myIdentity,const Identity &peerIdentity) throw(std::runtime_error) : _lastUsed(0), @@ -217,8 +220,9 @@ void Peer::doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now) attemptToContactAt(RR,bestPath->address(),now); bestPath->sent(now); } else if (((now - bestPath->lastSend()) >= ZT_NAT_KEEPALIVE_DELAY)&&(!bestPath->reliable())) { + _natKeepaliveBuf += (uint32_t)now * 2654435761; // tumble this around to send constantly varying (meaningless) payloads TRACE("NAT keepalive %s(%s)",_id.address().toString().c_str(),bestPath->address().toString().c_str()); - RR->node->putPacket(bestPath->address(),"",0); + RR->node->putPacket(bestPath->address(),&_natKeepaliveBuf,sizeof(_natKeepaliveBuf)); bestPath->sent(now); } } -- cgit v1.2.3 From 86996d4315743a8295d05ad2cea1139c32337d2d Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Wed, 23 Sep 2015 10:27:53 -0700 Subject: Eliminate compiler warning. --- node/Peer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'node') diff --git a/node/Peer.cpp b/node/Peer.cpp index 85874105..05b14da0 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -220,7 +220,7 @@ void Peer::doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now) attemptToContactAt(RR,bestPath->address(),now); bestPath->sent(now); } else if (((now - bestPath->lastSend()) >= ZT_NAT_KEEPALIVE_DELAY)&&(!bestPath->reliable())) { - _natKeepaliveBuf += (uint32_t)now * 2654435761; // tumble this around to send constantly varying (meaningless) payloads + _natKeepaliveBuf += (uint32_t)((now * 0x9e3779b1) >> 1); // tumble this around to send constantly varying (meaningless) payloads TRACE("NAT keepalive %s(%s)",_id.address().toString().c_str(),bestPath->address().toString().c_str()); RR->node->putPacket(bestPath->address(),&_natKeepaliveBuf,sizeof(_natKeepaliveBuf)); bestPath->sent(now); -- cgit v1.2.3 From 4464fa5d392dd930bf847c2dc1c5886398e5d8dd Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Wed, 23 Sep 2015 10:29:05 -0700 Subject: Eliminate another warning. --- node/Hashtable.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'node') diff --git a/node/Hashtable.hpp b/node/Hashtable.hpp index d2b85c15..beef1468 100644 --- a/node/Hashtable.hpp +++ b/node/Hashtable.hpp @@ -383,7 +383,7 @@ private: static inline unsigned long _hc(const uint32_t i) { // In the uint32_t case we use a simple multiplier for hashing to ensure coverage - return ((unsigned long)i * (unsigned long)2654435761); + return ((unsigned long)i * (unsigned long)0x9e3779b1); } inline void _grow() -- cgit v1.2.3 From 367ffde00cf6eecbca0f9fff391dcaf7faf72c6e Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Wed, 23 Sep 2015 13:49:56 -0700 Subject: Plumb through localInterfaceId to track local interfaces corresponding with remote addresses. --- include/ZeroTierOne.h | 88 ++++++++++++++++++++++++++++++++++--------------- node/IncomingPacket.cpp | 58 ++++++++++++++++---------------- node/IncomingPacket.hpp | 5 ++- node/Node.cpp | 8 +++-- node/Node.hpp | 5 ++- node/Peer.cpp | 21 ++++++------ node/Peer.hpp | 5 ++- node/RemotePath.hpp | 9 +++-- node/Switch.cpp | 27 ++++++++------- node/Switch.hpp | 14 +++++--- node/Topology.cpp | 2 +- service/OneService.cpp | 6 ++-- 12 files changed, 155 insertions(+), 93 deletions(-) (limited to 'node') diff --git a/include/ZeroTierOne.h b/include/ZeroTierOne.h index b8d14c5f..fd0b0d24 100644 --- a/include/ZeroTierOne.h +++ b/include/ZeroTierOne.h @@ -656,7 +656,12 @@ typedef void ZT1_Node; * on failure, and this results in the network being placed into the * PORT_ERROR state. */ -typedef int (*ZT1_VirtualNetworkConfigFunction)(ZT1_Node *,void *,uint64_t,enum ZT1_VirtualNetworkConfigOperation,const ZT1_VirtualNetworkConfig *); +typedef int (*ZT1_VirtualNetworkConfigFunction)( + ZT1_Node *, + void *, + uint64_t, + enum ZT1_VirtualNetworkConfigOperation, + const ZT1_VirtualNetworkConfig *); /** * Function to send a frame out to a virtual network port @@ -665,7 +670,16 @@ typedef int (*ZT1_VirtualNetworkConfigFunction)(ZT1_Node *,void *,uint64_t,enum * (5) destination MAC, (6) ethertype, (7) VLAN ID, (8) frame data, * (9) frame length. */ -typedef void (*ZT1_VirtualNetworkFrameFunction)(ZT1_Node *,void *,uint64_t,uint64_t,uint64_t,unsigned int,unsigned int,const void *,unsigned int); +typedef void (*ZT1_VirtualNetworkFrameFunction)( + ZT1_Node *, + void *, + uint64_t, + uint64_t, + uint64_t, + unsigned int, + unsigned int, + const void *, + unsigned int); /** * Callback for events @@ -676,7 +690,11 @@ typedef void (*ZT1_VirtualNetworkFrameFunction)(ZT1_Node *,void *,uint64_t,uint6 * whether it is present at all) is event type dependent. See the comments * in the definition of ZT1_Event. */ -typedef void (*ZT1_EventCallback)(ZT1_Node *,void *,enum ZT1_Event,const void *); +typedef void (*ZT1_EventCallback)( + ZT1_Node *, + void *, + enum ZT1_Event, + const void *); /** * Function to get an object from the data store @@ -698,7 +716,14 @@ typedef void (*ZT1_EventCallback)(ZT1_Node *,void *,enum ZT1_Event,const void *) * read. The caller may call the function multiple times to read the whole * object. */ -typedef long (*ZT1_DataStoreGetFunction)(ZT1_Node *,void *,const char *,void *,unsigned long,unsigned long,unsigned long *); +typedef long (*ZT1_DataStoreGetFunction)( + ZT1_Node *, + void *, + const char *, + void *, + unsigned long, + unsigned long, + unsigned long *); /** * Function to store an object in the data store @@ -716,19 +741,40 @@ typedef long (*ZT1_DataStoreGetFunction)(ZT1_Node *,void *,const char *,void *,u * If the data pointer is null, this must be interpreted as a delete * operation. */ -typedef int (*ZT1_DataStorePutFunction)(ZT1_Node *,void *,const char *,const void *,unsigned long,int); +typedef int (*ZT1_DataStorePutFunction)( + ZT1_Node *, + void *, + const char *, + const void *, + unsigned long, + int); /** * Function to send a ZeroTier packet out over the wire * - * Parameters: (1) node, (2) user ptr, (3) address, (4) packet data, - * (5) packet data length. + * Parameters: + * (1) Node + * (2) User pointer + * (3) Local interface ID, -1==unspcified/random + * (4) Remote address + * (5) Packet data + * (6) Packet length + * + * If you have only one local interface it is fine to ignore the local + * interface ID field. This is used to support different local interface + * endpoints and differentiation between them. * * The function must return zero on success and may return any error code * on failure. Note that success does not (of course) guarantee packet * delivery. It only means that the packet appears to have been sent. */ -typedef int (*ZT1_WirePacketSendFunction)(ZT1_Node *,void *,const struct sockaddr_storage *,const void *,unsigned int); +typedef int (*ZT1_WirePacketSendFunction)( + ZT1_Node *, /* Node */ + void *, /* User ptr */ + int, /* Local interface ID, -1 for unspecified/random */ + const struct sockaddr_storage *, /* Remote address */ + const void *, /* Packet data */ + unsigned int); /* Packet length */ /****************************************************************************/ /* C Node API */ @@ -747,7 +793,7 @@ typedef int (*ZT1_WirePacketSendFunction)(ZT1_Node *,void *,const struct sockadd * @param dataStorePutFunction Function called to put objects in persistent storage * @param virtualNetworkConfigFunction Function to be called when virtual LANs are created, deleted, or their config parameters change * @param eventCallback Function to receive status updates and non-fatal error notices - * @param overrideRootTopology If not NULL, must contain string-serialize root topology (for testing, default: NULL) + * @param overrideRootTopology Alternative root server topology or NULL for default (mostly for test/debug use) * @return OK (0) or error code if a fatal error condition has occurred */ enum ZT1_ResultCode ZT1_Node_new( @@ -760,11 +806,7 @@ enum ZT1_ResultCode ZT1_Node_new( ZT1_VirtualNetworkFrameFunction virtualNetworkFrameFunction, ZT1_VirtualNetworkConfigFunction virtualNetworkConfigFunction, ZT1_EventCallback eventCallback, - const char *overrideRootTopology -#ifdef __cplusplus - = (const char *)0 -#endif - ); + const char *overrideRootTopology); /** * Delete a node and free all resources it consumes @@ -781,6 +823,7 @@ void ZT1_Node_delete(ZT1_Node *node); * * @param node Node instance * @param now Current clock in milliseconds + * @param localInterfaceId Local interface ID on which packet was received (use 0 if only one interface or unsure) * @param remoteAddress Origin of packet * @param packetData Packet data * @param packetLength Packet length @@ -790,6 +833,7 @@ void ZT1_Node_delete(ZT1_Node *node); enum ZT1_ResultCode ZT1_Node_processWirePacket( ZT1_Node *node, uint64_t now, + const int localInterfaceId, const struct sockaddr_storage *remoteAddress, const void *packetData, unsigned int packetLength, @@ -882,14 +926,10 @@ enum ZT1_ResultCode ZT1_Node_leave(ZT1_Node *node,uint64_t nwid); * @param node Node instance * @param nwid 64-bit network ID * @param multicastGroup Ethernet multicast or broadcast MAC (least significant 48 bits) - * @param multicastAdi Multicast ADI (least significant 32 bits only, default: 0) + * @param multicastAdi Multicast ADI (least significant 32 bits only, use 0 if not needed) * @return OK (0) or error code if a fatal error condition has occurred */ -enum ZT1_ResultCode ZT1_Node_multicastSubscribe(ZT1_Node *node,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi -#ifdef __cplusplus - = 0 -#endif - ); +enum ZT1_ResultCode ZT1_Node_multicastSubscribe(ZT1_Node *node,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi); /** * Unsubscribe from an Ethernet multicast group (or all groups) @@ -902,14 +942,10 @@ enum ZT1_ResultCode ZT1_Node_multicastSubscribe(ZT1_Node *node,uint64_t nwid,uin * @param node Node instance * @param nwid 64-bit network ID * @param multicastGroup Ethernet multicast or broadcast MAC (least significant 48 bits) - * @param multicastAdi Multicast ADI (least significant 32 bits only, default: 0) + * @param multicastAdi Multicast ADI (least significant 32 bits only, use 0 if not needed) * @return OK (0) or error code if a fatal error condition has occurred */ -enum ZT1_ResultCode ZT1_Node_multicastUnsubscribe(ZT1_Node *node,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi -#ifdef __cplusplus - = 0 -#endif - ); +enum ZT1_ResultCode ZT1_Node_multicastUnsubscribe(ZT1_Node *node,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi); /** * Get this node's 40-bit ZeroTier address diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index fc79270b..e4861af7 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -69,7 +69,7 @@ bool IncomingPacket::tryDecode(const RuntimeEnvironment *RR) switch(verb()) { //case Packet::VERB_NOP: default: // ignore unknown verbs, but if they pass auth check they are "received" - peer->received(RR,_remoteAddress,hops(),packetId(),verb(),0,Packet::VERB_NOP); + peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),verb(),0,Packet::VERB_NOP); return true; case Packet::VERB_HELLO: return _doHELLO(RR); case Packet::VERB_ERROR: return _doERROR(RR,peer); @@ -144,7 +144,7 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,const SharedPtr Packet outp(peer->address(),RR->identity.address(),Packet::VERB_NETWORK_MEMBERSHIP_CERTIFICATE); nconf->com().serialize(outp); outp.armor(peer->key(),true); - RR->node->putPacket(_remoteAddress,outp.data(),outp.size()); + RR->node->putPacket(_localInterfaceId,_remoteAddress,outp.data(),outp.size()); } } } break; @@ -165,7 +165,7 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,const SharedPtr default: break; } - peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_ERROR,inRePacketId,inReVerb); + peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),Packet::VERB_ERROR,inRePacketId,inReVerb); } catch (std::exception &ex) { TRACE("dropped ERROR from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),ex.what()); } catch ( ... ) { @@ -231,7 +231,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR) outp.append(packetId()); outp.append((unsigned char)Packet::ERROR_IDENTITY_COLLISION); outp.armor(key,true); - RR->node->putPacket(_remoteAddress,outp.data(),outp.size()); + RR->node->putPacket(_localInterfaceId,_remoteAddress,outp.data(),outp.size()); } else { RR->node->postEvent(ZT1_EVENT_AUTHENTICATION_FAILURE,(const void *)&_remoteAddress); TRACE("rejected HELLO from %s(%s): packet failed authentication",id.address().toString().c_str(),_remoteAddress.toString().c_str()); @@ -278,7 +278,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR) // VALID -- continues here - peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_HELLO,0,Packet::VERB_NOP); + peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),Packet::VERB_HELLO,0,Packet::VERB_NOP); peer->setRemoteVersion(protoVersion,vMajor,vMinor,vRevision); bool trusted = false; @@ -316,7 +316,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR) } outp.armor(peer->key(),true); - RR->node->putPacket(_remoteAddress,outp.data(),outp.size()); + RR->node->putPacket(_localInterfaceId,_remoteAddress,outp.data(),outp.size()); } catch (std::exception &ex) { TRACE("dropped HELLO from %s(%s): %s",source().toString().c_str(),_remoteAddress.toString().c_str(),ex.what()); } catch ( ... ) { @@ -436,7 +436,7 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,const SharedPtr &p default: break; } - peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_OK,inRePacketId,inReVerb); + peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),Packet::VERB_OK,inRePacketId,inReVerb); } catch (std::exception &ex) { TRACE("dropped OK from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),ex.what()); } catch ( ... ) { @@ -456,7 +456,7 @@ bool IncomingPacket::_doWHOIS(const RuntimeEnvironment *RR,const SharedPtr outp.append(packetId()); queried->identity().serialize(outp,false); outp.armor(peer->key(),true); - RR->node->putPacket(_remoteAddress,outp.data(),outp.size()); + RR->node->putPacket(_localInterfaceId,_remoteAddress,outp.data(),outp.size()); } else { Packet outp(peer->address(),RR->identity.address(),Packet::VERB_ERROR); outp.append((unsigned char)Packet::VERB_WHOIS); @@ -464,12 +464,12 @@ bool IncomingPacket::_doWHOIS(const RuntimeEnvironment *RR,const SharedPtr outp.append((unsigned char)Packet::ERROR_OBJ_NOT_FOUND); outp.append(payload(),ZT_ADDRESS_LENGTH); outp.armor(peer->key(),true); - RR->node->putPacket(_remoteAddress,outp.data(),outp.size()); + RR->node->putPacket(_localInterfaceId,_remoteAddress,outp.data(),outp.size()); } } else { TRACE("dropped WHOIS from %s(%s): missing or invalid address",source().toString().c_str(),_remoteAddress.toString().c_str()); } - peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_WHOIS,0,Packet::VERB_NOP); + peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),Packet::VERB_WHOIS,0,Packet::VERB_NOP); } catch ( ... ) { TRACE("dropped WHOIS from %s(%s): unexpected exception",source().toString().c_str(),_remoteAddress.toString().c_str()); } @@ -487,8 +487,8 @@ bool IncomingPacket::_doRENDEZVOUS(const RuntimeEnvironment *RR,const SharedPtr< if ((port > 0)&&((addrlen == 4)||(addrlen == 16))) { InetAddress atAddr(field(ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRESS,addrlen),addrlen,port); TRACE("RENDEZVOUS from %s says %s might be at %s, starting NAT-t",peer->address().toString().c_str(),with.toString().c_str(),atAddr.toString().c_str()); - peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_RENDEZVOUS,0,Packet::VERB_NOP); - RR->sw->rendezvous(withPeer,atAddr); + peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),Packet::VERB_RENDEZVOUS,0,Packet::VERB_NOP); + RR->sw->rendezvous(withPeer,_localInterfaceId,atAddr); } else { TRACE("dropped corrupt RENDEZVOUS from %s(%s) (bad address or port)",peer->address().toString().c_str(),_remoteAddress.toString().c_str()); } @@ -525,7 +525,7 @@ bool IncomingPacket::_doFRAME(const RuntimeEnvironment *RR,const SharedPtr RR->node->putFrame(network->id(),MAC(peer->address(),network->id()),network->mac(),etherType,0,field(ZT_PROTO_VERB_FRAME_IDX_PAYLOAD,payloadLen),payloadLen); } - peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_FRAME,0,Packet::VERB_NOP); + peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),Packet::VERB_FRAME,0,Packet::VERB_NOP); } else { TRACE("dropped FRAME from %s(%s): we are not connected to network %.16llx",source().toString().c_str(),_remoteAddress.toString().c_str(),at(ZT_PROTO_VERB_FRAME_IDX_NETWORK_ID)); } @@ -602,7 +602,7 @@ bool IncomingPacket::_doEXT_FRAME(const RuntimeEnvironment *RR,const SharedPtr

node->putFrame(network->id(),from,to,etherType,0,field(comLen + ZT_PROTO_VERB_EXT_FRAME_IDX_PAYLOAD,payloadLen),payloadLen); } - peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_EXT_FRAME,0,Packet::VERB_NOP); + peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),Packet::VERB_EXT_FRAME,0,Packet::VERB_NOP); } else { TRACE("dropped EXT_FRAME from %s(%s): we are not connected to network %.16llx",source().toString().c_str(),_remoteAddress.toString().c_str(),at(ZT_PROTO_VERB_FRAME_IDX_NETWORK_ID)); } @@ -623,7 +623,7 @@ bool IncomingPacket::_doMULTICAST_LIKE(const RuntimeEnvironment *RR,const Shared for(unsigned int ptr=ZT_PACKET_IDX_PAYLOAD;ptrmc->add(now,at(ptr),MulticastGroup(MAC(field(ptr + 8,6),6),at(ptr + 14)),peer->address()); - peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_MULTICAST_LIKE,0,Packet::VERB_NOP); + peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),Packet::VERB_MULTICAST_LIKE,0,Packet::VERB_NOP); } catch (std::exception &ex) { TRACE("dropped MULTICAST_LIKE from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),ex.what()); } catch ( ... ) { @@ -647,7 +647,7 @@ bool IncomingPacket::_doNETWORK_MEMBERSHIP_CERTIFICATE(const RuntimeEnvironment } } - peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_NETWORK_MEMBERSHIP_CERTIFICATE,0,Packet::VERB_NOP); + peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),Packet::VERB_NETWORK_MEMBERSHIP_CERTIFICATE,0,Packet::VERB_NOP); } catch (std::exception &ex) { TRACE("dropped NETWORK_MEMBERSHIP_CERTIFICATE from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),ex.what()); } catch ( ... ) { @@ -666,7 +666,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons const unsigned int h = hops(); const uint64_t pid = packetId(); - peer->received(RR,_remoteAddress,h,pid,Packet::VERB_NETWORK_CONFIG_REQUEST,0,Packet::VERB_NOP); + peer->received(RR,_localInterfaceId,_remoteAddress,h,pid,Packet::VERB_NETWORK_CONFIG_REQUEST,0,Packet::VERB_NOP); if (RR->localNetworkController) { Dictionary netconf; @@ -688,7 +688,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons if (outp.size() > ZT_PROTO_MAX_PACKET_LENGTH) { TRACE("NETWORK_CONFIG_REQUEST failed: internal error: netconf size %u is too large",(unsigned int)netconfStr.length()); } else { - RR->node->putPacket(_remoteAddress,outp.data(),outp.size()); + RR->node->putPacket(_localInterfaceId,_remoteAddress,outp.data(),outp.size()); } } } break; @@ -700,7 +700,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons outp.append((unsigned char)Packet::ERROR_OBJ_NOT_FOUND); outp.append(nwid); outp.armor(peer->key(),true); - RR->node->putPacket(_remoteAddress,outp.data(),outp.size()); + RR->node->putPacket(_localInterfaceId,_remoteAddress,outp.data(),outp.size()); } break; case NetworkController::NETCONF_QUERY_ACCESS_DENIED: { @@ -710,7 +710,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons outp.append((unsigned char)Packet::ERROR_NETWORK_ACCESS_DENIED_); outp.append(nwid); outp.armor(peer->key(),true); - RR->node->putPacket(_remoteAddress,outp.data(),outp.size()); + RR->node->putPacket(_localInterfaceId,_remoteAddress,outp.data(),outp.size()); } break; case NetworkController::NETCONF_QUERY_INTERNAL_SERVER_ERROR: @@ -732,7 +732,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons outp.append((unsigned char)Packet::ERROR_UNSUPPORTED_OPERATION); outp.append(nwid); outp.armor(peer->key(),true); - RR->node->putPacket(_remoteAddress,outp.data(),outp.size()); + RR->node->putPacket(_localInterfaceId,_remoteAddress,outp.data(),outp.size()); } } catch (std::exception &exc) { TRACE("dropped NETWORK_CONFIG_REQUEST from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),exc.what()); @@ -753,7 +753,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REFRESH(const RuntimeEnvironment *RR,cons nw->requestConfiguration(); ptr += 8; } - peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_NETWORK_CONFIG_REFRESH,0,Packet::VERB_NOP); + peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),Packet::VERB_NETWORK_CONFIG_REFRESH,0,Packet::VERB_NOP); } catch (std::exception &exc) { TRACE("dropped NETWORK_CONFIG_REFRESH from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),exc.what()); } catch ( ... ) { @@ -780,11 +780,11 @@ bool IncomingPacket::_doMULTICAST_GATHER(const RuntimeEnvironment *RR,const Shar outp.append((uint32_t)mg.adi()); if (RR->mc->gather(peer->address(),nwid,mg,outp,gatherLimit)) { outp.armor(peer->key(),true); - RR->node->putPacket(_remoteAddress,outp.data(),outp.size()); + RR->node->putPacket(_localInterfaceId,_remoteAddress,outp.data(),outp.size()); } } - peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_MULTICAST_GATHER,0,Packet::VERB_NOP); + peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),Packet::VERB_MULTICAST_GATHER,0,Packet::VERB_NOP); } catch (std::exception &exc) { TRACE("dropped MULTICAST_GATHER from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),exc.what()); } catch ( ... ) { @@ -871,12 +871,12 @@ bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment *RR,const Share outp.append((unsigned char)0x02); // flag 0x02 = contains gather results if (RR->mc->gather(peer->address(),nwid,to,outp,gatherLimit)) { outp.armor(peer->key(),true); - RR->node->putPacket(_remoteAddress,outp.data(),outp.size()); + RR->node->putPacket(_localInterfaceId,_remoteAddress,outp.data(),outp.size()); } } } // else ignore -- not a member of this network - peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_MULTICAST_FRAME,0,Packet::VERB_NOP); + peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),Packet::VERB_MULTICAST_FRAME,0,Packet::VERB_NOP); } catch (std::exception &exc) { TRACE("dropped MULTICAST_FRAME from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),exc.what()); } catch ( ... ) { @@ -905,14 +905,14 @@ bool IncomingPacket::_doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,const Sha InetAddress a(field(ptr,4),4,at(ptr + 4)); if ( ((flags & (0x01 | 0x02)) == 0) && (Path::isAddressValidForPath(a)) ) { TRACE("attempting to contact %s at pushed direct path %s",peer->address().toString().c_str(),a.toString().c_str()); - peer->attemptToContactAt(RR,a,RR->node->now()); + peer->attemptToContactAt(RR,_localInterfaceId,a,RR->node->now()); } } break; case 6: { InetAddress a(field(ptr,16),16,at(ptr + 16)); if ( ((flags & (0x01 | 0x02)) == 0) && (Path::isAddressValidForPath(a)) ) { TRACE("attempting to contact %s at pushed direct path %s",peer->address().toString().c_str(),a.toString().c_str()); - peer->attemptToContactAt(RR,a,RR->node->now()); + peer->attemptToContactAt(RR,_localInterfaceId,a,RR->node->now()); } } break; } @@ -934,7 +934,7 @@ void IncomingPacket::_sendErrorNeedCertificate(const RuntimeEnvironment *RR,cons outp.append((unsigned char)Packet::ERROR_NEED_MEMBERSHIP_CERTIFICATE); outp.append(nwid); outp.armor(peer->key(),true); - RR->node->putPacket(_remoteAddress,outp.data(),outp.size()); + RR->node->putPacket(_localInterfaceId,_remoteAddress,outp.data(),outp.size()); } } // namespace ZeroTier diff --git a/node/IncomingPacket.hpp b/node/IncomingPacket.hpp index 3bf7737d..170ab7f9 100644 --- a/node/IncomingPacket.hpp +++ b/node/IncomingPacket.hpp @@ -72,14 +72,16 @@ public: * * @param data Packet data * @param len Packet length + * @param localInterfaceId Local interface ID * @param remoteAddress Address from which packet came * @param now Current time * @throws std::out_of_range Range error processing packet */ - IncomingPacket(const void *data,unsigned int len,const InetAddress &remoteAddress,uint64_t now) : + IncomingPacket(const void *data,unsigned int len,int localInterfaceId,const InetAddress &remoteAddress,uint64_t now) : Packet(data,len), _receiveTime(now), _remoteAddress(remoteAddress), + _localInterfaceId(localInterfaceId), __refCount() { } @@ -128,6 +130,7 @@ private: uint64_t _receiveTime; InetAddress _remoteAddress; + int _localInterfaceId; AtomicCounter __refCount; }; diff --git a/node/Node.cpp b/node/Node.cpp index c8c50d66..f9559ab4 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -157,13 +157,14 @@ Node::~Node() ZT1_ResultCode Node::processWirePacket( uint64_t now, + int localInterfaceId, const struct sockaddr_storage *remoteAddress, const void *packetData, unsigned int packetLength, volatile uint64_t *nextBackgroundTaskDeadline) { _now = now; - RR->sw->onRemotePacket(*(reinterpret_cast(remoteAddress)),packetData,packetLength); + RR->sw->onRemotePacket(localInterfaceId,*(reinterpret_cast(remoteAddress)),packetData,packetLength); return ZT1_RESULT_OK; } @@ -261,7 +262,7 @@ ZT1_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *next if (nr->second) { SharedPtr rp(RR->topology->getPeer(nr->first)); if ((rp)&&(!rp->hasActiveDirectPath(now))) - rp->attemptToContactAt(RR,nr->second,now); + rp->attemptToContactAt(RR,-1,nr->second,now); } } @@ -569,13 +570,14 @@ void ZT1_Node_delete(ZT1_Node *node) enum ZT1_ResultCode ZT1_Node_processWirePacket( ZT1_Node *node, uint64_t now, + int localInterfaceId, const struct sockaddr_storage *remoteAddress, const void *packetData, unsigned int packetLength, volatile uint64_t *nextBackgroundTaskDeadline) { try { - return reinterpret_cast(node)->processWirePacket(now,remoteAddress,packetData,packetLength,nextBackgroundTaskDeadline); + return reinterpret_cast(node)->processWirePacket(now,localInterfaceId,remoteAddress,packetData,packetLength,nextBackgroundTaskDeadline); } catch (std::bad_alloc &exc) { return ZT1_RESULT_FATAL_ERROR_OUT_OF_MEMORY; } catch ( ... ) { diff --git a/node/Node.hpp b/node/Node.hpp index 2a283eab..0e614e5a 100644 --- a/node/Node.hpp +++ b/node/Node.hpp @@ -80,6 +80,7 @@ public: ZT1_ResultCode processWirePacket( uint64_t now, + int localInterfaceId, const struct sockaddr_storage *remoteAddress, const void *packetData, unsigned int packetLength, @@ -119,16 +120,18 @@ public: /** * Enqueue a ZeroTier message to be sent * + * @param localInterfaceId Local interface ID, -1 for unspecified/random * @param addr Destination address * @param data Packet data * @param len Packet length * @return True if packet appears to have been sent */ - inline bool putPacket(const InetAddress &addr,const void *data,unsigned int len) + inline bool putPacket(int localInterfaceId,const InetAddress &addr,const void *data,unsigned int len) { return (_wirePacketSendFunction( reinterpret_cast(this), _uPtr, + localInterfaceId, reinterpret_cast(&addr), data, len) == 0); diff --git a/node/Peer.cpp b/node/Peer.cpp index 05b14da0..e966a9bf 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -64,6 +64,7 @@ Peer::Peer(const Identity &myIdentity,const Identity &peerIdentity) void Peer::received( const RuntimeEnvironment *RR, + int localInterfaceId, const InetAddress &remoteAddr, unsigned int hops, uint64_t packetId, @@ -81,7 +82,7 @@ void Peer::received( { unsigned int np = _numPaths; for(unsigned int p=0;preceived(now); _numPaths = np; pathIsConfirmed = true; @@ -119,7 +120,7 @@ void Peer::received( if ((now - _lastPathConfirmationSent) >= ZT_MIN_PATH_CONFIRMATION_INTERVAL) { _lastPathConfirmationSent = now; TRACE("got %s via unknown path %s(%s), confirming...",Packet::verbString(verb),_id.address().toString().c_str(),remoteAddr.toString().c_str()); - attemptToContactAt(RR,remoteAddr,now); + attemptToContactAt(RR,localInterfaceId,remoteAddr,now); } } } @@ -141,7 +142,7 @@ void Peer::received( for(std::vector::const_iterator mg(mgs.begin());mg!=mgs.end();++mg) { if ((outp.size() + 18) > ZT_UDP_DEFAULT_PAYLOAD_MTU) { outp.armor(_key,true); - RR->node->putPacket(remoteAddr,outp.data(),outp.size()); + RR->node->putPacket(localInterfaceId,remoteAddr,outp.data(),outp.size()); outp.reset(_id.address(),RR->identity.address(),Packet::VERB_MULTICAST_LIKE); } @@ -154,7 +155,7 @@ void Peer::received( } if (outp.size() > ZT_PROTO_MIN_PACKET_LENGTH) { outp.armor(_key,true); - RR->node->putPacket(remoteAddr,outp.data(),outp.size()); + RR->node->putPacket(localInterfaceId,remoteAddr,outp.data(),outp.size()); } } } @@ -180,7 +181,7 @@ RemotePath *Peer::getBestPath(uint64_t now) return bestPath; } -void Peer::attemptToContactAt(const RuntimeEnvironment *RR,const InetAddress &atAddress,uint64_t now) +void Peer::attemptToContactAt(const RuntimeEnvironment *RR,int localInterfaceId,const InetAddress &atAddress,uint64_t now) { Packet outp(_id.address(),RR->identity.address(),Packet::VERB_HELLO); outp.append((unsigned char)ZT_PROTO_VERSION); @@ -208,7 +209,7 @@ void Peer::attemptToContactAt(const RuntimeEnvironment *RR,const InetAddress &at } outp.armor(_key,false); // HELLO is sent in the clear - RR->node->putPacket(atAddress,outp.data(),outp.size()); + RR->node->putPacket(localInterfaceId,atAddress,outp.data(),outp.size()); } void Peer::doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now) @@ -217,12 +218,12 @@ void Peer::doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now) if (bestPath) { if ((now - bestPath->lastReceived()) >= ZT_PEER_DIRECT_PING_DELAY) { TRACE("PING %s(%s)",_id.address().toString().c_str(),bestPath->address().toString().c_str()); - attemptToContactAt(RR,bestPath->address(),now); + attemptToContactAt(RR,bestPath->localInterfaceId(),bestPath->address(),now); bestPath->sent(now); } else if (((now - bestPath->lastSend()) >= ZT_NAT_KEEPALIVE_DELAY)&&(!bestPath->reliable())) { _natKeepaliveBuf += (uint32_t)((now * 0x9e3779b1) >> 1); // tumble this around to send constantly varying (meaningless) payloads TRACE("NAT keepalive %s(%s)",_id.address().toString().c_str(),bestPath->address().toString().c_str()); - RR->node->putPacket(bestPath->address(),&_natKeepaliveBuf,sizeof(_natKeepaliveBuf)); + RR->node->putPacket(bestPath->localInterfaceId(),bestPath->address(),&_natKeepaliveBuf,sizeof(_natKeepaliveBuf)); bestPath->sent(now); } } @@ -354,7 +355,7 @@ bool Peer::resetWithinScope(const RuntimeEnvironment *RR,InetAddress::IpScope sc while (x < np) { if (_paths[x].address().ipScope() == scope) { if (_paths[x].fixed()) { - attemptToContactAt(RR,_paths[x].address(),now); + attemptToContactAt(RR,_paths[x].localInterfaceId(),_paths[x].address(),now); _paths[y++] = _paths[x]; // keep fixed paths } } else { diff --git a/node/Peer.hpp b/node/Peer.hpp index ef436cd9..b0f2b4e2 100644 --- a/node/Peer.hpp +++ b/node/Peer.hpp @@ -105,6 +105,7 @@ public: * and appears to be valid. * * @param RR Runtime environment + * @param localInterfaceId Local interface ID or -1 if unspecified * @param remoteAddr Internet address of sender * @param hops ZeroTier (not IP) hops * @param packetId Packet ID @@ -114,6 +115,7 @@ public: */ void received( const RuntimeEnvironment *RR, + int localInterfaceId, const InetAddress &remoteAddr, unsigned int hops, uint64_t packetId, @@ -155,10 +157,11 @@ public: * for NAT traversal and path verification. * * @param RR Runtime environment + * @param localInterfaceId Local interface ID or -1 for unspecified * @param atAddress Destination address * @param now Current time */ - void attemptToContactAt(const RuntimeEnvironment *RR,const InetAddress &atAddress,uint64_t now); + void attemptToContactAt(const RuntimeEnvironment *RR,int localInterfaceId,const InetAddress &atAddress,uint64_t now); /** * Send pings or keepalives depending on configured timeouts diff --git a/node/RemotePath.hpp b/node/RemotePath.hpp index 291943c9..a7ef141b 100644 --- a/node/RemotePath.hpp +++ b/node/RemotePath.hpp @@ -53,14 +53,18 @@ public: Path(), _lastSend(0), _lastReceived(0), + _localInterfaceId(-1), _fixed(false) {} - RemotePath(const InetAddress &addr,bool fixed) : + RemotePath(int localInterfaceId,const InetAddress &addr,bool fixed) : Path(addr,0,TRUST_NORMAL), _lastSend(0), _lastReceived(0), + _localInterfaceId(localInterfaceId), _fixed(fixed) {} + inline int localInterfaceId() const throw() { return _localInterfaceId; } + inline uint64_t lastSend() const throw() { return _lastSend; } inline uint64_t lastReceived() const throw() { return _lastReceived; } @@ -123,7 +127,7 @@ public: */ inline bool send(const RuntimeEnvironment *RR,const void *data,unsigned int len,uint64_t now) { - if (RR->node->putPacket(address(),data,len)) { + if (RR->node->putPacket(_localInterfaceId,address(),data,len)) { sent(now); RR->antiRec->logOutgoingZT(data,len); return true; @@ -134,6 +138,7 @@ public: private: uint64_t _lastSend; uint64_t _lastReceived; + int _localInterfaceId; bool _fixed; }; diff --git a/node/Switch.cpp b/node/Switch.cpp index 995abef4..0de94400 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -78,8 +78,11 @@ Switch::~Switch() { } -void Switch::onRemotePacket(const InetAddress &fromAddr,const void *data,unsigned int len) +void Switch::onRemotePacket(int localInterfaceId,const InetAddress &fromAddr,const void *data,unsigned int len) { + if (localInterfaceId < 0) + localInterfaceId = 0; + try { if (len == 13) { /* LEGACY: before VERB_PUSH_DIRECT_PATHS, peers used broadcast @@ -96,14 +99,14 @@ void Switch::onRemotePacket(const InetAddress &fromAddr,const void *data,unsigne _lastBeaconResponse = now; Packet outp(peer->address(),RR->identity.address(),Packet::VERB_NOP); outp.armor(peer->key(),false); - RR->node->putPacket(fromAddr,outp.data(),outp.size()); + RR->node->putPacket(localInterfaceId,fromAddr,outp.data(),outp.size()); } } } else if (len > ZT_PROTO_MIN_FRAGMENT_LENGTH) { if (((const unsigned char *)data)[ZT_PACKET_FRAGMENT_IDX_FRAGMENT_INDICATOR] == ZT_PACKET_FRAGMENT_INDICATOR) { - _handleRemotePacketFragment(fromAddr,data,len); + _handleRemotePacketFragment(localInterfaceId,fromAddr,data,len); } else if (len >= ZT_PROTO_MIN_PACKET_LENGTH) { - _handleRemotePacketHead(fromAddr,data,len); + _handleRemotePacketHead(localInterfaceId,fromAddr,data,len); } } } catch (std::exception &ex) { @@ -376,14 +379,14 @@ bool Switch::unite(const Address &p1,const Address &p2,bool force) return true; } -void Switch::rendezvous(const SharedPtr &peer,const InetAddress &atAddr) +void Switch::rendezvous(const SharedPtr &peer,int localInterfaceId,const InetAddress &atAddr) { TRACE("sending NAT-t message to %s(%s)",peer->address().toString().c_str(),atAddr.toString().c_str()); const uint64_t now = RR->node->now(); - peer->attemptToContactAt(RR,atAddr,now); + peer->attemptToContactAt(RR,localInterfaceId,atAddr,now); { Mutex::Lock _l(_contactQueue_m); - _contactQueue.push_back(ContactQueueEntry(peer,now + ZT_NAT_T_TACTICAL_ESCALATION_DELAY,atAddr)); + _contactQueue.push_back(ContactQueueEntry(peer,now + ZT_NAT_T_TACTICAL_ESCALATION_DELAY,localInterfaceId,atAddr)); } } @@ -453,14 +456,14 @@ unsigned long Switch::doTimerTasks(uint64_t now) } else { if (qi->strategyIteration == 0) { // First strategy: send packet directly to destination - qi->peer->attemptToContactAt(RR,qi->inaddr,now); + qi->peer->attemptToContactAt(RR,qi->localInterfaceId,qi->inaddr,now); } else if (qi->strategyIteration <= 4) { // Strategies 1-4: try escalating ports for symmetric NATs that remap sequentially InetAddress tmpaddr(qi->inaddr); int p = (int)qi->inaddr.port() + qi->strategyIteration; if (p < 0xffff) { tmpaddr.setPort((unsigned int)p); - qi->peer->attemptToContactAt(RR,tmpaddr,now); + qi->peer->attemptToContactAt(RR,qi->localInterfaceId,tmpaddr,now); } else qi->strategyIteration = 5; } else { // All strategies tried, expire entry @@ -551,7 +554,7 @@ unsigned long Switch::doTimerTasks(uint64_t now) return nextDelay; } -void Switch::_handleRemotePacketFragment(const InetAddress &fromAddr,const void *data,unsigned int len) +void Switch::_handleRemotePacketFragment(int localInterfaceId,const InetAddress &fromAddr,const void *data,unsigned int len) { Packet::Fragment fragment(data,len); Address destination(fragment.destination()); @@ -622,9 +625,9 @@ void Switch::_handleRemotePacketFragment(const InetAddress &fromAddr,const void } } -void Switch::_handleRemotePacketHead(const InetAddress &fromAddr,const void *data,unsigned int len) +void Switch::_handleRemotePacketHead(int localInterfaceId,const InetAddress &fromAddr,const void *data,unsigned int len) { - SharedPtr packet(new IncomingPacket(data,len,fromAddr,RR->node->now())); + SharedPtr packet(new IncomingPacket(data,len,localInterfaceId,fromAddr,RR->node->now())); Address source(packet->source()); Address destination(packet->destination()); diff --git a/node/Switch.hpp b/node/Switch.hpp index 55e2c362..a8d89f41 100644 --- a/node/Switch.hpp +++ b/node/Switch.hpp @@ -79,11 +79,12 @@ public: /** * Called when a packet is received from the real network * + * @param localInterfaceId Local interface ID or -1 for unspecified * @param fromAddr Internet IP address of origin * @param data Packet data * @param len Packet length */ - void onRemotePacket(const InetAddress &fromAddr,const void *data,unsigned int len); + void onRemotePacket(int localInterfaceId,const InetAddress &fromAddr,const void *data,unsigned int len); /** * Called when a packet comes from a local Ethernet tap @@ -140,9 +141,10 @@ public: * Attempt NAT traversal to peer at a given physical address * * @param peer Peer to contact + * @param localInterfaceId Local interface ID or -1 if unspecified * @param atAddr Address of peer */ - void rendezvous(const SharedPtr &peer,const InetAddress &atAddr); + void rendezvous(const SharedPtr &peer,int localInterfaceId,const InetAddress &atAddr); /** * Request WHOIS on a given address @@ -179,8 +181,8 @@ public: unsigned long doTimerTasks(uint64_t now); private: - void _handleRemotePacketFragment(const InetAddress &fromAddr,const void *data,unsigned int len); - void _handleRemotePacketHead(const InetAddress &fromAddr,const void *data,unsigned int len); + void _handleRemotePacketFragment(int localInterfaceId,const InetAddress &fromAddr,const void *data,unsigned int len); + void _handleRemotePacketHead(int localInterfaceId,const InetAddress &fromAddr,const void *data,unsigned int len); Address _sendWhoisRequest(const Address &addr,const Address *peersAlreadyConsulted,unsigned int numPeersAlreadyConsulted); bool _trySend(const Packet &packet,bool encrypt,uint64_t nwid); @@ -260,15 +262,17 @@ private: struct ContactQueueEntry { ContactQueueEntry() {} - ContactQueueEntry(const SharedPtr &p,uint64_t ft,const InetAddress &a) : + ContactQueueEntry(const SharedPtr &p,uint64_t ft,int liid,const InetAddress &a) : peer(p), fireAtTime(ft), inaddr(a), + localInterfaceId(liid), strategyIteration(0) {} SharedPtr peer; uint64_t fireAtTime; InetAddress inaddr; + int localInterfaceId; unsigned int strategyIteration; }; std::list _contactQueue; diff --git a/node/Topology.cpp b/node/Topology.cpp index 25a92acd..c63ed9f4 100644 --- a/node/Topology.cpp +++ b/node/Topology.cpp @@ -62,7 +62,7 @@ void Topology::setRootServers(const std::map< Identity,std::vector if (!p) p = SharedPtr(new Peer(RR->identity,i->first)); for(std::vector::const_iterator j(i->second.begin());j!=i->second.end();++j) - p->addPath(RemotePath(*j,true)); + p->addPath(RemotePath(0,*j,true)); p->use(now); _rootPeers.push_back(p); } diff --git a/service/OneService.cpp b/service/OneService.cpp index e8b8ba60..c2b4636f 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -344,7 +344,7 @@ static int SnodeVirtualNetworkConfigFunction(ZT1_Node *node,void *uptr,uint64_t static void SnodeEventCallback(ZT1_Node *node,void *uptr,enum ZT1_Event event,const void *metaData); static long SnodeDataStoreGetFunction(ZT1_Node *node,void *uptr,const char *name,void *buf,unsigned long bufSize,unsigned long readIndex,unsigned long *totalSize); static int SnodeDataStorePutFunction(ZT1_Node *node,void *uptr,const char *name,const void *data,unsigned long len,int secure); -static int SnodeWirePacketSendFunction(ZT1_Node *node,void *uptr,const struct sockaddr_storage *addr,const void *data,unsigned int len); +static int SnodeWirePacketSendFunction(ZT1_Node *node,void *uptr,int localInterfaceId,const struct sockaddr_storage *addr,const void *data,unsigned int len); static void SnodeVirtualNetworkFrameFunction(ZT1_Node *node,void *uptr,uint64_t nwid,uint64_t sourceMac,uint64_t destMac,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len); static void StapFrameHandler(void *uptr,uint64_t nwid,const MAC &from,const MAC &to,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len); @@ -727,6 +727,7 @@ public: _lastDirectReceiveFromGlobal = OSUtils::now(); ZT1_ResultCode rc = _node->processWirePacket( OSUtils::now(), + 0, (const struct sockaddr_storage *)from, // Phy<> uses sockaddr_storage, so it'll always be that big data, len, @@ -875,6 +876,7 @@ public: if (from) { ZT1_ResultCode rc = _node->processWirePacket( OSUtils::now(), + 0, reinterpret_cast(&from), data, plen, @@ -1288,7 +1290,7 @@ static long SnodeDataStoreGetFunction(ZT1_Node *node,void *uptr,const char *name { return reinterpret_cast(uptr)->nodeDataStoreGetFunction(name,buf,bufSize,readIndex,totalSize); } static int SnodeDataStorePutFunction(ZT1_Node *node,void *uptr,const char *name,const void *data,unsigned long len,int secure) { return reinterpret_cast(uptr)->nodeDataStorePutFunction(name,data,len,secure); } -static int SnodeWirePacketSendFunction(ZT1_Node *node,void *uptr,const struct sockaddr_storage *addr,const void *data,unsigned int len) +static int SnodeWirePacketSendFunction(ZT1_Node *node,void *uptr,int localInterfaceId,const struct sockaddr_storage *addr,const void *data,unsigned int len) { return reinterpret_cast(uptr)->nodeWirePacketSendFunction(addr,data,len); } static void SnodeVirtualNetworkFrameFunction(ZT1_Node *node,void *uptr,uint64_t nwid,uint64_t sourceMac,uint64_t destMac,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len) { reinterpret_cast(uptr)->nodeVirtualNetworkFrameFunction(nwid,sourceMac,destMac,etherType,vlanId,data,len); } -- cgit v1.2.3 From 2a527ea82e597759433d9bb3c8e884463c81fc2b Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Wed, 23 Sep 2015 14:01:41 -0700 Subject: Fix for timer jitter problem. --- node/Node.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'node') diff --git a/node/Node.cpp b/node/Node.cpp index f9559ab4..7aad54b8 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -233,7 +233,9 @@ ZT1_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *next _now = now; Mutex::Lock bl(_backgroundTasksLock); - if ((now - _lastPingCheck) >= ZT_PING_CHECK_INVERVAL) { + unsigned long timeUntilNextPingCheck = ZT_PING_CHECK_INVERVAL; + const uint64_t timeSinceLastPingCheck = now - _lastPingCheck; + if (timeSinceLastPingCheck >= ZT_PING_CHECK_INVERVAL) { try { _lastPingCheck = now; @@ -278,6 +280,8 @@ ZT1_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *next } catch ( ... ) { return ZT1_RESULT_FATAL_ERROR_INTERNAL; } + } else { + timeUntilNextPingCheck -= (unsigned long)timeSinceLastPingCheck; } if ((now - _lastHousekeepingRun) >= ZT_HOUSEKEEPING_PERIOD) { @@ -292,7 +296,7 @@ ZT1_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *next } try { - *nextBackgroundTaskDeadline = now + (uint64_t)std::max(std::min((unsigned long)ZT_PING_CHECK_INVERVAL,RR->sw->doTimerTasks(now)),(unsigned long)ZT_CORE_TIMER_TASK_GRANULARITY); + *nextBackgroundTaskDeadline = now + (uint64_t)std::max(std::min(timeUntilNextPingCheck,RR->sw->doTimerTasks(now)),(unsigned long)ZT_CORE_TIMER_TASK_GRANULARITY); } catch ( ... ) { return ZT1_RESULT_FATAL_ERROR_INTERNAL; } -- cgit v1.2.3 From a3ed5277ef1cb02096137750278e6a4910f5efeb Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Wed, 23 Sep 2015 14:09:27 -0700 Subject: Make sure ZT_NO_TYPE_PUNNING also obeyed here. --- node/SHA512.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'node') diff --git a/node/SHA512.cpp b/node/SHA512.cpp index 197d6323..ddff4839 100644 --- a/node/SHA512.cpp +++ b/node/SHA512.cpp @@ -48,10 +48,8 @@ Public domain. #define uint64 uint64_t -#define load_bigendian(x) Utils::ntoh(*((const uint64_t *)(x))) -#define store_bigendian(x,u) (*((uint64_t *)(x)) = Utils::hton((u))) +#ifdef ZT_NO_TYPE_PUNNING -#if 0 static uint64 load_bigendian(const unsigned char *x) { return @@ -77,7 +75,13 @@ static void store_bigendian(unsigned char *x,uint64 u) x[1] = u; u >>= 8; x[0] = u; } -#endif + +#else // !ZT_NO_TYPE_PUNNING + +#define load_bigendian(x) Utils::ntoh(*((const uint64_t *)(x))) +#define store_bigendian(x,u) (*((uint64_t *)(x)) = Utils::hton((u))) + +#endif // ZT_NO_TYPE_PUNNING #define SHR(x,c) ((x) >> (c)) #define ROTR(x,c) (((x) >> (c)) | ((x) << (64 - (c)))) -- cgit v1.2.3 From 0e5aac6a117c28fde63f4cdb94e6c9fc415ca098 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Wed, 23 Sep 2015 16:16:36 -0700 Subject: Prefer IPv6 paths if available. --- node/Path.hpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'node') diff --git a/node/Path.hpp b/node/Path.hpp index 0e53772d..1f947911 100644 --- a/node/Path.hpp +++ b/node/Path.hpp @@ -93,7 +93,16 @@ public: /** * @return Preference rank, higher == better */ - inline int preferenceRank() const throw() { return (int)_ipScope; } // IP scopes are in ascending rank order in InetAddress.hpp + inline int preferenceRank() const throw() + { + // First, since the scope enum values in InetAddress.hpp are in order of + // use preference rank, we take that. Then we multiple by two, yielding + // a sequence like 0, 2, 4, 6, etc. Then if it's IPv6 we add one. This + // makes IPv6 addresses of a given scope outrank IPv4 addresses of the + // same scope -- e.g. 1 outranks 0. This makes us prefer IPv6, but not + // if the address scope/class is of a fundamentally lower rank. + return ( ((int)_ipScope * 2) + ((_addr.ss_family == AF_INET6) ? 1 : 0) ); + } /** * @return Path trust level -- cgit v1.2.3 From f69454ec9879a0b0a424f743ca144d1123ef7e99 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Thu, 24 Sep 2015 16:21:36 -0700 Subject: (1) Make ZT_ naming convention consistent (get rid of ZT1_), (2) Make local interface a full sockaddr_storage instead of an int identifier, which turns out to be better for multi-homing and other uses. --- include/ZeroTierOne.h | 247 +++++++++++---------- java/CMakeLists.txt | 4 +- java/jni/Android.mk | 4 +- java/jni/ZT1_jnicache.cpp | 4 +- java/jni/ZT1_jnicache.h | 4 +- java/jni/ZT1_jniutils.cpp | 86 +++---- java/jni/ZT1_jniutils.h | 24 +- java/jni/com_zerotierone_sdk_Node.cpp | 164 +++++++------- .../src/com/zerotier/sdk/VirtualNetworkConfig.java | 2 +- node/Constants.hpp | 2 +- node/Defaults.cpp | 2 +- node/IncomingPacket.cpp | 72 +++--- node/IncomingPacket.hpp | 8 +- node/Network.cpp | 38 ++-- node/Network.hpp | 8 +- node/NetworkConfig.cpp | 6 +- node/Node.cpp | 214 +++++++++--------- node/Node.hpp | 70 +++--- node/Path.hpp | 2 +- node/Peer.cpp | 30 +-- node/Peer.hpp | 10 +- node/RemotePath.hpp | 12 +- node/Switch.cpp | 27 +-- node/Switch.hpp | 18 +- node/Topology.cpp | 2 +- one.cpp | 6 +- service/ControlPlane.cpp | 40 ++-- service/OneService.cpp | 136 ++++++------ windows/ZeroTierOne/ZeroTierOneService.cpp | 2 +- 29 files changed, 622 insertions(+), 622 deletions(-) (limited to 'node') diff --git a/include/ZeroTierOne.h b/include/ZeroTierOne.h index fd0b0d24..e8a19e33 100644 --- a/include/ZeroTierOne.h +++ b/include/ZeroTierOne.h @@ -26,8 +26,8 @@ */ /* - * This defines the external C API for ZeroTier One, the core network - * virtualization engine. + * This defines the external C API for ZeroTier's core network virtualization + * engine. */ #ifndef ZT_ZEROTIERONE_H @@ -56,9 +56,9 @@ extern "C" { /****************************************************************************/ /** - * Default port for the ZeroTier service + * Default UDP port for devices running a ZeroTier endpoint */ -#define ZT1_DEFAULT_PORT 9993 +#define ZT_DEFAULT_PORT 9993 /** * Maximum MTU for ZeroTier virtual networks @@ -83,37 +83,42 @@ extern "C" { * We use 2800, which leaves some room for other payload in other types of * messages such as multicast propagation or future support for bridging. */ -#define ZT1_MAX_MTU 2800 +#define ZT_MAX_MTU 2800 /** * Maximum length of network short name */ -#define ZT1_MAX_NETWORK_SHORT_NAME_LENGTH 255 +#define ZT_MAX_NETWORK_SHORT_NAME_LENGTH 255 /** * Maximum number of statically assigned IP addresses per network endpoint using ZT address management (not DHCP) */ -#define ZT1_MAX_ZT_ASSIGNED_ADDRESSES 16 +#define ZT_MAX_ZT_ASSIGNED_ADDRESSES 16 /** * Maximum number of multicast group subscriptions per network */ -#define ZT1_MAX_NETWORK_MULTICAST_SUBSCRIPTIONS 4096 +#define ZT_MAX_NETWORK_MULTICAST_SUBSCRIPTIONS 4096 /** * Maximum number of direct network paths to a given peer */ -#define ZT1_MAX_PEER_NETWORK_PATHS 4 +#define ZT_MAX_PEER_NETWORK_PATHS 4 /** * Feature flag: ZeroTier One was built to be thread-safe -- concurrent processXXX() calls are okay */ -#define ZT1_FEATURE_FLAG_THREAD_SAFE 0x00000001 +#define ZT_FEATURE_FLAG_THREAD_SAFE 0x00000001 /** * Feature flag: FIPS compliant build (not available yet, but reserved for future use if we ever do this) */ -#define ZT1_FEATURE_FLAG_FIPS 0x00000002 +#define ZT_FEATURE_FLAG_FIPS 0x00000002 + +/** + * A null/empty sockaddr (all zero) to signify an unspecified socket address + */ +extern const struct sockaddr_storage ZT_SOCKADDR_NULL; /****************************************************************************/ /* Structures and other types */ @@ -122,53 +127,53 @@ extern "C" { /** * Function return code: OK (0) or error results * - * Use ZT1_ResultCode_isFatal() to check for a fatal error. If a fatal error + * Use ZT_ResultCode_isFatal() to check for a fatal error. If a fatal error * occurs, the node should be considered to not be working correctly. These * indicate serious problems like an inaccessible data store or a compile * problem. */ -enum ZT1_ResultCode +enum ZT_ResultCode { /** * Operation completed normally */ - ZT1_RESULT_OK = 0, + ZT_RESULT_OK = 0, // Fatal errors (>0, <1000) /** * Ran out of memory */ - ZT1_RESULT_FATAL_ERROR_OUT_OF_MEMORY = 1, + ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY = 1, /** * Data store is not writable or has failed */ - ZT1_RESULT_FATAL_ERROR_DATA_STORE_FAILED = 2, + ZT_RESULT_FATAL_ERROR_DATA_STORE_FAILED = 2, /** * Internal error (e.g. unexpected exception indicating bug or build problem) */ - ZT1_RESULT_FATAL_ERROR_INTERNAL = 3, + ZT_RESULT_FATAL_ERROR_INTERNAL = 3, // Non-fatal errors (>1000) /** * Network ID not valid */ - ZT1_RESULT_ERROR_NETWORK_NOT_FOUND = 1000 + ZT_RESULT_ERROR_NETWORK_NOT_FOUND = 1000 }; /** * @param x Result code * @return True if result code indicates a fatal error */ -#define ZT1_ResultCode_isFatal(x) ((((int)(x)) > 0)&&(((int)(x)) < 1000)) +#define ZT_ResultCode_isFatal(x) ((((int)(x)) > 0)&&(((int)(x)) < 1000)) /** * Status codes sent to status update callback when things happen */ -enum ZT1_Event +enum ZT_Event { /** * Node has been initialized @@ -178,21 +183,21 @@ enum ZT1_Event * * Meta-data: none */ - ZT1_EVENT_UP = 0, + ZT_EVENT_UP = 0, /** * Node is offline -- network does not seem to be reachable by any available strategy * * Meta-data: none */ - ZT1_EVENT_OFFLINE = 1, + ZT_EVENT_OFFLINE = 1, /** * Node is online -- at least one upstream node appears reachable * * Meta-data: none */ - ZT1_EVENT_ONLINE = 2, + ZT_EVENT_ONLINE = 2, /** * Node is shutting down @@ -203,7 +208,7 @@ enum ZT1_Event * * Meta-data: none */ - ZT1_EVENT_DOWN = 3, + ZT_EVENT_DOWN = 3, /** * Your identity has collided with another node's ZeroTier address @@ -235,7 +240,7 @@ enum ZT1_Event * * Meta-data: none */ - ZT1_EVENT_FATAL_ERROR_IDENTITY_COLLISION = 4, + ZT_EVENT_FATAL_ERROR_IDENTITY_COLLISION = 4, /** * A more recent version was observed on the network @@ -246,21 +251,21 @@ enum ZT1_Event * * Meta-data: unsigned int[3], more recent version number */ - ZT1_EVENT_SAW_MORE_RECENT_VERSION = 5, + ZT_EVENT_SAW_MORE_RECENT_VERSION = 5, /** * A packet failed authentication * * Meta-data: struct sockaddr_storage containing origin address of packet */ - ZT1_EVENT_AUTHENTICATION_FAILURE = 6, + ZT_EVENT_AUTHENTICATION_FAILURE = 6, /** * A received packet was not valid * * Meta-data: struct sockaddr_storage containing origin address of packet */ - ZT1_EVENT_INVALID_PACKET = 7, + ZT_EVENT_INVALID_PACKET = 7, /** * Trace (debugging) message @@ -269,7 +274,7 @@ enum ZT1_Event * * Meta-data: C string, TRACE message */ - ZT1_EVENT_TRACE = 8 + ZT_EVENT_TRACE = 8 }; /** @@ -300,58 +305,58 @@ typedef struct * True if some kind of connectivity appears available */ int online; -} ZT1_NodeStatus; +} ZT_NodeStatus; /** * Virtual network status codes */ -enum ZT1_VirtualNetworkStatus +enum ZT_VirtualNetworkStatus { /** * Waiting for network configuration (also means revision == 0) */ - ZT1_NETWORK_STATUS_REQUESTING_CONFIGURATION = 0, + ZT_NETWORK_STATUS_REQUESTING_CONFIGURATION = 0, /** * Configuration received and we are authorized */ - ZT1_NETWORK_STATUS_OK = 1, + ZT_NETWORK_STATUS_OK = 1, /** * Netconf master told us 'nope' */ - ZT1_NETWORK_STATUS_ACCESS_DENIED = 2, + ZT_NETWORK_STATUS_ACCESS_DENIED = 2, /** * Netconf master exists, but this virtual network does not */ - ZT1_NETWORK_STATUS_NOT_FOUND = 3, + ZT_NETWORK_STATUS_NOT_FOUND = 3, /** * Initialization of network failed or other internal error */ - ZT1_NETWORK_STATUS_PORT_ERROR = 4, + ZT_NETWORK_STATUS_PORT_ERROR = 4, /** * ZeroTier One version too old */ - ZT1_NETWORK_STATUS_CLIENT_TOO_OLD = 5 + ZT_NETWORK_STATUS_CLIENT_TOO_OLD = 5 }; /** * Virtual network type codes */ -enum ZT1_VirtualNetworkType +enum ZT_VirtualNetworkType { /** * Private networks are authorized via certificates of membership */ - ZT1_NETWORK_TYPE_PRIVATE = 0, + ZT_NETWORK_TYPE_PRIVATE = 0, /** * Public networks have no access control -- they'll always be AUTHORIZED */ - ZT1_NETWORK_TYPE_PUBLIC = 1 + ZT_NETWORK_TYPE_PUBLIC = 1 }; /** @@ -368,32 +373,32 @@ typedef struct * Additional distinguishing information (usually zero) */ unsigned long adi; -} ZT1_MulticastGroup; +} ZT_MulticastGroup; /** * Virtual network configuration update type */ -enum ZT1_VirtualNetworkConfigOperation +enum ZT_VirtualNetworkConfigOperation { /** * Network is coming up (either for the first time or after service restart) */ - ZT1_VIRTUAL_NETWORK_CONFIG_OPERATION_UP = 1, + ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP = 1, /** * Network configuration has been updated */ - ZT1_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE = 2, + ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE = 2, /** * Network is going down (not permanently) */ - ZT1_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN = 3, + ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN = 3, /** * Network is going down permanently (leave/delete) */ - ZT1_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY = 4 + ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY = 4 }; /** @@ -414,17 +419,17 @@ typedef struct /** * Network name (from network configuration master) */ - char name[ZT1_MAX_NETWORK_SHORT_NAME_LENGTH + 1]; + char name[ZT_MAX_NETWORK_SHORT_NAME_LENGTH + 1]; /** * Network configuration request status */ - enum ZT1_VirtualNetworkStatus status; + enum ZT_VirtualNetworkStatus status; /** * Network type */ - enum ZT1_VirtualNetworkType type; + enum ZT_VirtualNetworkType type; /** * Maximum interface MTU @@ -478,7 +483,7 @@ typedef struct /** * Multicast group subscriptions */ - ZT1_MulticastGroup multicastSubscriptions[ZT1_MAX_NETWORK_MULTICAST_SUBSCRIPTIONS]; + ZT_MulticastGroup multicastSubscriptions[ZT_MAX_NETWORK_MULTICAST_SUBSCRIPTIONS]; /** * Number of assigned addresses @@ -495,17 +500,17 @@ typedef struct * This is only used for ZeroTier-managed address assignments sent by the * virtual network's configuration master. */ - struct sockaddr_storage assignedAddresses[ZT1_MAX_ZT_ASSIGNED_ADDRESSES]; -} ZT1_VirtualNetworkConfig; + struct sockaddr_storage assignedAddresses[ZT_MAX_ZT_ASSIGNED_ADDRESSES]; +} ZT_VirtualNetworkConfig; /** * A list of networks */ typedef struct { - ZT1_VirtualNetworkConfig *networks; + ZT_VirtualNetworkConfig *networks; unsigned long networkCount; -} ZT1_VirtualNetworkList; +} ZT_VirtualNetworkList; /** * Physical network path to a peer @@ -541,15 +546,15 @@ typedef struct * Is path preferred? */ int preferred; -} ZT1_PeerPhysicalPath; +} ZT_PeerPhysicalPath; /** * What trust hierarchy role does this peer have? */ -enum ZT1_PeerRole { - ZT1_PEER_ROLE_LEAF = 0, // ordinary node - ZT1_PEER_ROLE_RELAY = 1, // relay node - ZT1_PEER_ROLE_ROOT = 2 // root server +enum ZT_PeerRole { + ZT_PEER_ROLE_LEAF = 0, // ordinary node + ZT_PEER_ROLE_RELAY = 1, // relay node + ZT_PEER_ROLE_ROOT = 2 // root server }; /** @@ -595,7 +600,7 @@ typedef struct /** * What trust hierarchy role does this device have? */ - enum ZT1_PeerRole role; + enum ZT_PeerRole role; /** * Number of paths (size of paths[]) @@ -605,31 +610,31 @@ typedef struct /** * Known network paths to peer */ - ZT1_PeerPhysicalPath paths[ZT1_MAX_PEER_NETWORK_PATHS]; -} ZT1_Peer; + ZT_PeerPhysicalPath paths[ZT_MAX_PEER_NETWORK_PATHS]; +} ZT_Peer; /** * List of peers */ typedef struct { - ZT1_Peer *peers; + ZT_Peer *peers; unsigned long peerCount; -} ZT1_PeerList; +} ZT_PeerList; /** * Local interface trust levels */ typedef enum { - ZT1_LOCAL_INTERFACE_ADDRESS_TRUST_NORMAL = 0, - ZT1_LOCAL_INTERFACE_ADDRESS_TRUST_PRIVACY = 1, - ZT1_LOCAL_INTERFACE_ADDRESS_TRUST_ULTIMATE = 2 -} ZT1_LocalInterfaceAddressTrust; + ZT_LOCAL_INTERFACE_ADDRESS_TRUST_NORMAL = 0, + ZT_LOCAL_INTERFACE_ADDRESS_TRUST_PRIVACY = 1, + ZT_LOCAL_INTERFACE_ADDRESS_TRUST_ULTIMATE = 2 +} ZT_LocalInterfaceAddressTrust; /** * An instance of a ZeroTier One node (opaque) */ -typedef void ZT1_Node; +typedef void ZT_Node; /****************************************************************************/ /* Callbacks used by Node API */ @@ -656,12 +661,12 @@ typedef void ZT1_Node; * on failure, and this results in the network being placed into the * PORT_ERROR state. */ -typedef int (*ZT1_VirtualNetworkConfigFunction)( - ZT1_Node *, +typedef int (*ZT_VirtualNetworkConfigFunction)( + ZT_Node *, void *, uint64_t, - enum ZT1_VirtualNetworkConfigOperation, - const ZT1_VirtualNetworkConfig *); + enum ZT_VirtualNetworkConfigOperation, + const ZT_VirtualNetworkConfig *); /** * Function to send a frame out to a virtual network port @@ -670,8 +675,8 @@ typedef int (*ZT1_VirtualNetworkConfigFunction)( * (5) destination MAC, (6) ethertype, (7) VLAN ID, (8) frame data, * (9) frame length. */ -typedef void (*ZT1_VirtualNetworkFrameFunction)( - ZT1_Node *, +typedef void (*ZT_VirtualNetworkFrameFunction)( + ZT_Node *, void *, uint64_t, uint64_t, @@ -688,12 +693,12 @@ typedef void (*ZT1_VirtualNetworkFrameFunction)( * and on certain non-fatal errors and events of interest. The final void * parameter points to event meta-data. The type of event meta-data (and * whether it is present at all) is event type dependent. See the comments - * in the definition of ZT1_Event. + * in the definition of ZT_Event. */ -typedef void (*ZT1_EventCallback)( - ZT1_Node *, +typedef void (*ZT_EventCallback)( + ZT_Node *, void *, - enum ZT1_Event, + enum ZT_Event, const void *); /** @@ -716,8 +721,8 @@ typedef void (*ZT1_EventCallback)( * read. The caller may call the function multiple times to read the whole * object. */ -typedef long (*ZT1_DataStoreGetFunction)( - ZT1_Node *, +typedef long (*ZT_DataStoreGetFunction)( + ZT_Node *, void *, const char *, void *, @@ -741,8 +746,8 @@ typedef long (*ZT1_DataStoreGetFunction)( * If the data pointer is null, this must be interpreted as a delete * operation. */ -typedef int (*ZT1_DataStorePutFunction)( - ZT1_Node *, +typedef int (*ZT_DataStorePutFunction)( + ZT_Node *, void *, const char *, const void *, @@ -755,23 +760,25 @@ typedef int (*ZT1_DataStorePutFunction)( * Parameters: * (1) Node * (2) User pointer - * (3) Local interface ID, -1==unspcified/random + * (3) Local interface address * (4) Remote address * (5) Packet data * (6) Packet length * - * If you have only one local interface it is fine to ignore the local - * interface ID field. This is used to support different local interface - * endpoints and differentiation between them. + * If there is only one local interface it is safe to ignore the local + * interface address. Otherwise if running with multiple interfaces, the + * correct local interface should be chosen by address unless NULL. If + * the ss_family field is zero (NULL address), a random or preferred + * default interface should be used. * * The function must return zero on success and may return any error code * on failure. Note that success does not (of course) guarantee packet * delivery. It only means that the packet appears to have been sent. */ -typedef int (*ZT1_WirePacketSendFunction)( - ZT1_Node *, /* Node */ +typedef int (*ZT_WirePacketSendFunction)( + ZT_Node *, /* Node */ void *, /* User ptr */ - int, /* Local interface ID, -1 for unspecified/random */ + const struct sockaddr_storage *, /* Local address */ const struct sockaddr_storage *, /* Remote address */ const void *, /* Packet data */ unsigned int); /* Packet length */ @@ -796,16 +803,16 @@ typedef int (*ZT1_WirePacketSendFunction)( * @param overrideRootTopology Alternative root server topology or NULL for default (mostly for test/debug use) * @return OK (0) or error code if a fatal error condition has occurred */ -enum ZT1_ResultCode ZT1_Node_new( - ZT1_Node **node, +enum ZT_ResultCode ZT_Node_new( + ZT_Node **node, void *uptr, uint64_t now, - ZT1_DataStoreGetFunction dataStoreGetFunction, - ZT1_DataStorePutFunction dataStorePutFunction, - ZT1_WirePacketSendFunction wirePacketSendFunction, - ZT1_VirtualNetworkFrameFunction virtualNetworkFrameFunction, - ZT1_VirtualNetworkConfigFunction virtualNetworkConfigFunction, - ZT1_EventCallback eventCallback, + ZT_DataStoreGetFunction dataStoreGetFunction, + ZT_DataStorePutFunction dataStorePutFunction, + ZT_WirePacketSendFunction wirePacketSendFunction, + ZT_VirtualNetworkFrameFunction virtualNetworkFrameFunction, + ZT_VirtualNetworkConfigFunction virtualNetworkConfigFunction, + ZT_EventCallback eventCallback, const char *overrideRootTopology); /** @@ -816,24 +823,24 @@ enum ZT1_ResultCode ZT1_Node_new( * * @param node Node to delete */ -void ZT1_Node_delete(ZT1_Node *node); +void ZT_Node_delete(ZT_Node *node); /** * Process a packet received from the physical wire * * @param node Node instance * @param now Current clock in milliseconds - * @param localInterfaceId Local interface ID on which packet was received (use 0 if only one interface or unsure) + * @param localAddress Local address, or point to ZT_SOCKADDR_NULL if unspecified * @param remoteAddress Origin of packet * @param packetData Packet data * @param packetLength Packet length * @param nextBackgroundTaskDeadline Value/result: set to deadline for next call to processBackgroundTasks() * @return OK (0) or error code if a fatal error condition has occurred */ -enum ZT1_ResultCode ZT1_Node_processWirePacket( - ZT1_Node *node, +enum ZT_ResultCode ZT_Node_processWirePacket( + ZT_Node *node, uint64_t now, - const int localInterfaceId, + const struct sockaddr_storage *localAddress, const struct sockaddr_storage *remoteAddress, const void *packetData, unsigned int packetLength, @@ -854,8 +861,8 @@ enum ZT1_ResultCode ZT1_Node_processWirePacket( * @param nextBackgroundTaskDeadline Value/result: set to deadline for next call to processBackgroundTasks() * @return OK (0) or error code if a fatal error condition has occurred */ -enum ZT1_ResultCode ZT1_Node_processVirtualNetworkFrame( - ZT1_Node *node, +enum ZT_ResultCode ZT_Node_processVirtualNetworkFrame( + ZT_Node *node, uint64_t now, uint64_t nwid, uint64_t sourceMac, @@ -874,7 +881,7 @@ enum ZT1_ResultCode ZT1_Node_processVirtualNetworkFrame( * @param nextBackgroundTaskDeadline Value/result: set to deadline for next call to processBackgroundTasks() * @return OK (0) or error code if a fatal error condition has occurred */ -enum ZT1_ResultCode ZT1_Node_processBackgroundTasks(ZT1_Node *node,uint64_t now,volatile uint64_t *nextBackgroundTaskDeadline); +enum ZT_ResultCode ZT_Node_processBackgroundTasks(ZT_Node *node,uint64_t now,volatile uint64_t *nextBackgroundTaskDeadline); /** * Join a network @@ -889,7 +896,7 @@ enum ZT1_ResultCode ZT1_Node_processBackgroundTasks(ZT1_Node *node,uint64_t now, * @param nwid 64-bit ZeroTier network ID * @return OK (0) or error code if a fatal error condition has occurred */ -enum ZT1_ResultCode ZT1_Node_join(ZT1_Node *node,uint64_t nwid); +enum ZT_ResultCode ZT_Node_join(ZT_Node *node,uint64_t nwid); /** * Leave a network @@ -902,7 +909,7 @@ enum ZT1_ResultCode ZT1_Node_join(ZT1_Node *node,uint64_t nwid); * @param nwid 64-bit network ID * @return OK (0) or error code if a fatal error condition has occurred */ -enum ZT1_ResultCode ZT1_Node_leave(ZT1_Node *node,uint64_t nwid); +enum ZT_ResultCode ZT_Node_leave(ZT_Node *node,uint64_t nwid); /** * Subscribe to an Ethernet multicast group @@ -929,7 +936,7 @@ enum ZT1_ResultCode ZT1_Node_leave(ZT1_Node *node,uint64_t nwid); * @param multicastAdi Multicast ADI (least significant 32 bits only, use 0 if not needed) * @return OK (0) or error code if a fatal error condition has occurred */ -enum ZT1_ResultCode ZT1_Node_multicastSubscribe(ZT1_Node *node,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi); +enum ZT_ResultCode ZT_Node_multicastSubscribe(ZT_Node *node,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi); /** * Unsubscribe from an Ethernet multicast group (or all groups) @@ -945,7 +952,7 @@ enum ZT1_ResultCode ZT1_Node_multicastSubscribe(ZT1_Node *node,uint64_t nwid,uin * @param multicastAdi Multicast ADI (least significant 32 bits only, use 0 if not needed) * @return OK (0) or error code if a fatal error condition has occurred */ -enum ZT1_ResultCode ZT1_Node_multicastUnsubscribe(ZT1_Node *node,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi); +enum ZT_ResultCode ZT_Node_multicastUnsubscribe(ZT_Node *node,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi); /** * Get this node's 40-bit ZeroTier address @@ -953,7 +960,7 @@ enum ZT1_ResultCode ZT1_Node_multicastUnsubscribe(ZT1_Node *node,uint64_t nwid,u * @param node Node instance * @return ZeroTier address (least significant 40 bits of 64-bit int) */ -uint64_t ZT1_Node_address(ZT1_Node *node); +uint64_t ZT_Node_address(ZT_Node *node); /** * Get the status of this node @@ -961,7 +968,7 @@ uint64_t ZT1_Node_address(ZT1_Node *node); * @param node Node instance * @param status Buffer to fill with current node status */ -void ZT1_Node_status(ZT1_Node *node,ZT1_NodeStatus *status); +void ZT_Node_status(ZT_Node *node,ZT_NodeStatus *status); /** * Get a list of known peer nodes @@ -972,7 +979,7 @@ void ZT1_Node_status(ZT1_Node *node,ZT1_NodeStatus *status); * @param node Node instance * @return List of known peers or NULL on failure */ -ZT1_PeerList *ZT1_Node_peers(ZT1_Node *node); +ZT_PeerList *ZT_Node_peers(ZT_Node *node); /** * Get the status of a virtual network @@ -984,7 +991,7 @@ ZT1_PeerList *ZT1_Node_peers(ZT1_Node *node); * @param nwid 64-bit network ID * @return Network configuration or NULL if we are not a member of this network */ -ZT1_VirtualNetworkConfig *ZT1_Node_networkConfig(ZT1_Node *node,uint64_t nwid); +ZT_VirtualNetworkConfig *ZT_Node_networkConfig(ZT_Node *node,uint64_t nwid); /** * Enumerate and get status of all networks @@ -992,7 +999,7 @@ ZT1_VirtualNetworkConfig *ZT1_Node_networkConfig(ZT1_Node *node,uint64_t nwid); * @param node Node instance * @return List of networks or NULL on failure */ -ZT1_VirtualNetworkList *ZT1_Node_networks(ZT1_Node *node); +ZT_VirtualNetworkList *ZT_Node_networks(ZT_Node *node); /** * Free a query result buffer @@ -1002,7 +1009,7 @@ ZT1_VirtualNetworkList *ZT1_Node_networks(ZT1_Node *node); * @param node Node instance * @param qr Query result buffer */ -void ZT1_Node_freeQueryResult(ZT1_Node *node,void *qr); +void ZT_Node_freeQueryResult(ZT_Node *node,void *qr); /** * Add a local interface address @@ -1030,12 +1037,12 @@ void ZT1_Node_freeQueryResult(ZT1_Node *node,void *qr); * @param trust How much do you trust the local network under this interface? * @return Boolean: non-zero if address was accepted and added */ -int ZT1_Node_addLocalInterfaceAddress(ZT1_Node *node,const struct sockaddr_storage *addr,int metric,ZT1_LocalInterfaceAddressTrust trust); +int ZT_Node_addLocalInterfaceAddress(ZT_Node *node,const struct sockaddr_storage *addr,int metric,ZT_LocalInterfaceAddressTrust trust); /** * Clear local interface addresses */ -void ZT1_Node_clearLocalInterfaceAddresses(ZT1_Node *node); +void ZT_Node_clearLocalInterfaceAddresses(ZT_Node *node); /** * Set a network configuration master instance for this node @@ -1052,7 +1059,7 @@ void ZT1_Node_clearLocalInterfaceAddresses(ZT1_Node *node); * @param networkConfigMasterInstance Instance of NetworkConfigMaster C++ class or NULL to disable * @return OK (0) or error code if a fatal error condition has occurred */ -void ZT1_Node_setNetconfMaster(ZT1_Node *node,void *networkConfigMasterInstance); +void ZT_Node_setNetconfMaster(ZT_Node *node,void *networkConfigMasterInstance); /** * Get ZeroTier One version @@ -1062,7 +1069,7 @@ void ZT1_Node_setNetconfMaster(ZT1_Node *node,void *networkConfigMasterInstance) * @param revision Result: revision * @param featureFlags: Result: feature flag bitmap */ -void ZT1_version(int *major,int *minor,int *revision,unsigned long *featureFlags); +void ZT_version(int *major,int *minor,int *revision,unsigned long *featureFlags); #ifdef __cplusplus } diff --git a/java/CMakeLists.txt b/java/CMakeLists.txt index db3eec1c..25e32638 100644 --- a/java/CMakeLists.txt +++ b/java/CMakeLists.txt @@ -53,8 +53,8 @@ set(src_files ../osdep/Http.cpp ../osdep/OSUtils.cpp jni/com_zerotierone_sdk_Node.cpp - jni/ZT1_jniutils.cpp - jni/ZT1_jnicache.cpp + jni/ZT_jniutils.cpp + jni/ZT_jnicache.cpp ) set(include_dirs diff --git a/java/jni/Android.mk b/java/jni/Android.mk index bbf14348..4dd4a57a 100644 --- a/java/jni/Android.mk +++ b/java/jni/Android.mk @@ -38,7 +38,7 @@ LOCAL_SRC_FILES := \ # JNI Files LOCAL_SRC_FILES += \ com_zerotierone_sdk_Node.cpp \ - ZT1_jniutils.cpp \ - ZT1_jnicache.cpp + ZT_jniutils.cpp \ + ZT_jnicache.cpp include $(BUILD_SHARED_LIBRARY) \ No newline at end of file diff --git a/java/jni/ZT1_jnicache.cpp b/java/jni/ZT1_jnicache.cpp index 8d6305cb..d8141058 100644 --- a/java/jni/ZT1_jnicache.cpp +++ b/java/jni/ZT1_jnicache.cpp @@ -25,8 +25,8 @@ * LLC. Start here: http://www.zerotier.com/ */ -#include "ZT1_jnicache.h" -#include "ZT1_jniutils.h" +#include "ZT_jnicache.h" +#include "ZT_jniutils.h" JniCache::JniCache() : m_jvm(NULL) diff --git a/java/jni/ZT1_jnicache.h b/java/jni/ZT1_jnicache.h index 43f43a08..001c13fe 100644 --- a/java/jni/ZT1_jnicache.h +++ b/java/jni/ZT1_jnicache.h @@ -25,8 +25,8 @@ * LLC. Start here: http://www.zerotier.com/ */ -#ifndef ZT1_JNICACHE_H_ -#define ZT1_JNICACHE_H_ +#ifndef ZT_JNICACHE_H_ +#define ZT_JNICACHE_H_ #include #include diff --git a/java/jni/ZT1_jniutils.cpp b/java/jni/ZT1_jniutils.cpp index 8779c3c3..794a0624 100644 --- a/java/jni/ZT1_jniutils.cpp +++ b/java/jni/ZT1_jniutils.cpp @@ -1,5 +1,5 @@ -#include "ZT1_jniutils.h" -#include "ZT1_jnicache.h" +#include "ZT_jniutils.h" +#include "ZT_jnicache.h" #include #include @@ -9,7 +9,7 @@ extern JniCache cache; extern "C" { #endif -jobject createResultObject(JNIEnv *env, ZT1_ResultCode code) +jobject createResultObject(JNIEnv *env, ZT_ResultCode code) { jclass resultClass = NULL; @@ -25,23 +25,23 @@ jobject createResultObject(JNIEnv *env, ZT1_ResultCode code) std::string fieldName; switch(code) { - case ZT1_RESULT_OK: - LOGV("ZT1_RESULT_OK"); + case ZT_RESULT_OK: + LOGV("ZT_RESULT_OK"); fieldName = "RESULT_OK"; break; - case ZT1_RESULT_FATAL_ERROR_OUT_OF_MEMORY: - LOGV("ZT1_RESULT_FATAL_ERROR_OUT_OF_MEMORY"); + case ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY: + LOGV("ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY"); fieldName = "RESULT_FATAL_ERROR_OUT_OF_MEMORY"; break; - case ZT1_RESULT_FATAL_ERROR_DATA_STORE_FAILED: + case ZT_RESULT_FATAL_ERROR_DATA_STORE_FAILED: LOGV("RESULT_FATAL_ERROR_DATA_STORE_FAILED"); fieldName = "RESULT_FATAL_ERROR_DATA_STORE_FAILED"; break; - case ZT1_RESULT_ERROR_NETWORK_NOT_FOUND: + case ZT_RESULT_ERROR_NETWORK_NOT_FOUND: LOGV("RESULT_FATAL_ERROR_DATA_STORE_FAILED"); fieldName = "RESULT_ERROR_NETWORK_NOT_FOUND"; break; - case ZT1_RESULT_FATAL_ERROR_INTERNAL: + case ZT_RESULT_FATAL_ERROR_INTERNAL: default: LOGV("RESULT_FATAL_ERROR_DATA_STORE_FAILED"); fieldName = "RESULT_FATAL_ERROR_INTERNAL"; @@ -64,7 +64,7 @@ jobject createResultObject(JNIEnv *env, ZT1_ResultCode code) } -jobject createVirtualNetworkStatus(JNIEnv *env, ZT1_VirtualNetworkStatus status) +jobject createVirtualNetworkStatus(JNIEnv *env, ZT_VirtualNetworkStatus status) { jobject statusObject = NULL; @@ -77,22 +77,22 @@ jobject createVirtualNetworkStatus(JNIEnv *env, ZT1_VirtualNetworkStatus status) std::string fieldName; switch(status) { - case ZT1_NETWORK_STATUS_REQUESTING_CONFIGURATION: + case ZT_NETWORK_STATUS_REQUESTING_CONFIGURATION: fieldName = "NETWORK_STATUS_REQUESTING_CONFIGURATION"; break; - case ZT1_NETWORK_STATUS_OK: + case ZT_NETWORK_STATUS_OK: fieldName = "NETWORK_STATUS_OK"; break; - case ZT1_NETWORK_STATUS_ACCESS_DENIED: + case ZT_NETWORK_STATUS_ACCESS_DENIED: fieldName = "NETWORK_STATUS_ACCESS_DENIED"; break; - case ZT1_NETWORK_STATUS_NOT_FOUND: + case ZT_NETWORK_STATUS_NOT_FOUND: fieldName = "NETWORK_STATUS_NOT_FOUND"; break; - case ZT1_NETWORK_STATUS_PORT_ERROR: + case ZT_NETWORK_STATUS_PORT_ERROR: fieldName = "NETWORK_STATUS_PORT_ERROR"; break; - case ZT1_NETWORK_STATUS_CLIENT_TOO_OLD: + case ZT_NETWORK_STATUS_CLIENT_TOO_OLD: fieldName = "NETWORK_STATUS_CLIENT_TOO_OLD"; break; } @@ -104,7 +104,7 @@ jobject createVirtualNetworkStatus(JNIEnv *env, ZT1_VirtualNetworkStatus status) return statusObject; } -jobject createEvent(JNIEnv *env, ZT1_Event event) +jobject createEvent(JNIEnv *env, ZT_Event event) { jclass eventClass = NULL; jobject eventObject = NULL; @@ -118,31 +118,31 @@ jobject createEvent(JNIEnv *env, ZT1_Event event) std::string fieldName; switch(event) { - case ZT1_EVENT_UP: + case ZT_EVENT_UP: fieldName = "EVENT_UP"; break; - case ZT1_EVENT_OFFLINE: + case ZT_EVENT_OFFLINE: fieldName = "EVENT_OFFLINE"; break; - case ZT1_EVENT_ONLINE: + case ZT_EVENT_ONLINE: fieldName = "EVENT_ONLINE"; break; - case ZT1_EVENT_DOWN: + case ZT_EVENT_DOWN: fieldName = "EVENT_DOWN"; break; - case ZT1_EVENT_FATAL_ERROR_IDENTITY_COLLISION: + case ZT_EVENT_FATAL_ERROR_IDENTITY_COLLISION: fieldName = "EVENT_FATAL_ERROR_IDENTITY_COLLISION"; break; - case ZT1_EVENT_SAW_MORE_RECENT_VERSION: + case ZT_EVENT_SAW_MORE_RECENT_VERSION: fieldName = "EVENT_SAW_MORE_RECENT_VERSION"; break; - case ZT1_EVENT_AUTHENTICATION_FAILURE: + case ZT_EVENT_AUTHENTICATION_FAILURE: fieldName = "EVENT_AUTHENTICATION_FAILURE"; break; - case ZT1_EVENT_INVALID_PACKET: + case ZT_EVENT_INVALID_PACKET: fieldName = "EVENT_INVALID_PACKET"; break; - case ZT1_EVENT_TRACE: + case ZT_EVENT_TRACE: fieldName = "EVENT_TRACE"; break; } @@ -154,7 +154,7 @@ jobject createEvent(JNIEnv *env, ZT1_Event event) return eventObject; } -jobject createPeerRole(JNIEnv *env, ZT1_PeerRole role) +jobject createPeerRole(JNIEnv *env, ZT_PeerRole role) { jclass peerRoleClass = NULL; jobject peerRoleObject = NULL; @@ -168,13 +168,13 @@ jobject createPeerRole(JNIEnv *env, ZT1_PeerRole role) std::string fieldName; switch(role) { - case ZT1_PEER_ROLE_LEAF: + case ZT_PEER_ROLE_LEAF: fieldName = "PEER_ROLE_LEAF"; break; - case ZT1_PEER_ROLE_HUB: + case ZT_PEER_ROLE_HUB: fieldName = "PEER_ROLE_HUB"; break; - case ZT1_PEER_ROLE_ROOTSERVER: + case ZT_PEER_ROLE_ROOTSERVER: fieldName = "PEER_ROLE_ROOTSERVER"; break; } @@ -186,7 +186,7 @@ jobject createPeerRole(JNIEnv *env, ZT1_PeerRole role) return peerRoleObject; } -jobject createVirtualNetworkType(JNIEnv *env, ZT1_VirtualNetworkType type) +jobject createVirtualNetworkType(JNIEnv *env, ZT_VirtualNetworkType type) { jclass vntypeClass = NULL; jobject vntypeObject = NULL; @@ -200,10 +200,10 @@ jobject createVirtualNetworkType(JNIEnv *env, ZT1_VirtualNetworkType type) std::string fieldName; switch(type) { - case ZT1_NETWORK_TYPE_PRIVATE: + case ZT_NETWORK_TYPE_PRIVATE: fieldName = "NETWORK_TYPE_PRIVATE"; break; - case ZT1_NETWORK_TYPE_PUBLIC: + case ZT_NETWORK_TYPE_PUBLIC: fieldName = "NETWORK_TYPE_PUBLIC"; break; } @@ -213,7 +213,7 @@ jobject createVirtualNetworkType(JNIEnv *env, ZT1_VirtualNetworkType type) return vntypeObject; } -jobject createVirtualNetworkConfigOperation(JNIEnv *env, ZT1_VirtualNetworkConfigOperation op) +jobject createVirtualNetworkConfigOperation(JNIEnv *env, ZT_VirtualNetworkConfigOperation op) { jclass vnetConfigOpClass = NULL; jobject vnetConfigOpObject = NULL; @@ -227,16 +227,16 @@ jobject createVirtualNetworkConfigOperation(JNIEnv *env, ZT1_VirtualNetworkConfi std::string fieldName; switch(op) { - case ZT1_VIRTUAL_NETWORK_CONFIG_OPERATION_UP: + case ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP: fieldName = "VIRTUAL_NETWORK_CONFIG_OPERATION_UP"; break; - case ZT1_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE: + case ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE: fieldName = "VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE"; break; - case ZT1_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN: + case ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN: fieldName = "VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN"; break; - case ZT1_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY: + case ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY: fieldName = "VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY"; break; } @@ -372,7 +372,7 @@ jobject newInetSocketAddress(JNIEnv *env, const sockaddr_storage &addr) return inetSocketAddressObject; } -jobject newMulticastGroup(JNIEnv *env, const ZT1_MulticastGroup &mc) +jobject newMulticastGroup(JNIEnv *env, const ZT_MulticastGroup &mc) { jclass multicastGroupClass = NULL; jmethodID multicastGroup_constructor = NULL; @@ -417,7 +417,7 @@ jobject newMulticastGroup(JNIEnv *env, const ZT1_MulticastGroup &mc) return multicastGroupObj; } -jobject newPeerPhysicalPath(JNIEnv *env, const ZT1_PeerPhysicalPath &ppp) +jobject newPeerPhysicalPath(JNIEnv *env, const ZT_PeerPhysicalPath &ppp) { LOGV("newPeerPhysicalPath Called"); jclass pppClass = NULL; @@ -514,7 +514,7 @@ jobject newPeerPhysicalPath(JNIEnv *env, const ZT1_PeerPhysicalPath &ppp) return pppObject; } -jobject newPeer(JNIEnv *env, const ZT1_Peer &peer) +jobject newPeer(JNIEnv *env, const ZT_Peer &peer) { LOGV("newPeer called"); @@ -656,7 +656,7 @@ jobject newPeer(JNIEnv *env, const ZT1_Peer &peer) return peerObject; } -jobject newNetworkConfig(JNIEnv *env, const ZT1_VirtualNetworkConfig &vnetConfig) +jobject newNetworkConfig(JNIEnv *env, const ZT_VirtualNetworkConfig &vnetConfig) { jclass vnetConfigClass = NULL; jmethodID vnetConfig_constructor = NULL; diff --git a/java/jni/ZT1_jniutils.h b/java/jni/ZT1_jniutils.h index 880f67d7..b76a28c2 100644 --- a/java/jni/ZT1_jniutils.h +++ b/java/jni/ZT1_jniutils.h @@ -1,5 +1,5 @@ -#ifndef ZT1_jniutils_h_ -#define ZT1_jniutils_h_ +#ifndef ZT_jniutils_h_ +#define ZT_jniutils_h_ #include #include #include @@ -23,22 +23,22 @@ extern "C" { #define LOGE(...) fprintf(stdout, __VA_ARGS__) #endif -jobject createResultObject(JNIEnv *env, ZT1_ResultCode code); -jobject createVirtualNetworkStatus(JNIEnv *env, ZT1_VirtualNetworkStatus status); -jobject createVirtualNetworkType(JNIEnv *env, ZT1_VirtualNetworkType type); -jobject createEvent(JNIEnv *env, ZT1_Event event); -jobject createPeerRole(JNIEnv *env, ZT1_PeerRole role); -jobject createVirtualNetworkConfigOperation(JNIEnv *env, ZT1_VirtualNetworkConfigOperation op); +jobject createResultObject(JNIEnv *env, ZT_ResultCode code); +jobject createVirtualNetworkStatus(JNIEnv *env, ZT_VirtualNetworkStatus status); +jobject createVirtualNetworkType(JNIEnv *env, ZT_VirtualNetworkType type); +jobject createEvent(JNIEnv *env, ZT_Event event); +jobject createPeerRole(JNIEnv *env, ZT_PeerRole role); +jobject createVirtualNetworkConfigOperation(JNIEnv *env, ZT_VirtualNetworkConfigOperation op); jobject newInetSocketAddress(JNIEnv *env, const sockaddr_storage &addr); jobject newInetAddress(JNIEnv *env, const sockaddr_storage &addr); -jobject newMulticastGroup(JNIEnv *env, const ZT1_MulticastGroup &mc); +jobject newMulticastGroup(JNIEnv *env, const ZT_MulticastGroup &mc); -jobject newPeer(JNIEnv *env, const ZT1_Peer &peer); -jobject newPeerPhysicalPath(JNIEnv *env, const ZT1_PeerPhysicalPath &ppp); +jobject newPeer(JNIEnv *env, const ZT_Peer &peer); +jobject newPeerPhysicalPath(JNIEnv *env, const ZT_PeerPhysicalPath &ppp); -jobject newNetworkConfig(JNIEnv *env, const ZT1_VirtualNetworkConfig &config); +jobject newNetworkConfig(JNIEnv *env, const ZT_VirtualNetworkConfig &config); jobject newVersion(JNIEnv *env, int major, int minor, int rev, long featureFlags); diff --git a/java/jni/com_zerotierone_sdk_Node.cpp b/java/jni/com_zerotierone_sdk_Node.cpp index f0405813..ff12708a 100644 --- a/java/jni/com_zerotierone_sdk_Node.cpp +++ b/java/jni/com_zerotierone_sdk_Node.cpp @@ -26,8 +26,8 @@ */ #include "com_zerotierone_sdk_Node.h" -#include "ZT1_jniutils.h" -#include "ZT1_jnicache.h" +#include "ZT_jniutils.h" +#include "ZT_jnicache.h" #include @@ -74,7 +74,7 @@ namespace { JavaVM *jvm; - ZT1_Node *node; + ZT_Node *node; jobject dataStoreGetListener; jobject dataStorePutListener; @@ -86,11 +86,11 @@ namespace { int VirtualNetworkConfigFunctionCallback( - ZT1_Node *node, + ZT_Node *node, void *userData, uint64_t nwid, - enum ZT1_VirtualNetworkConfigOperation operation, - const ZT1_VirtualNetworkConfig *config) + enum ZT_VirtualNetworkConfigOperation operation, + const ZT_VirtualNetworkConfig *config) { LOGD("VritualNetworkConfigFunctionCallback"); JniRef *ref = (JniRef*)userData; @@ -133,7 +133,7 @@ namespace { (jlong)nwid, operationObject, networkConfigObject); } - void VirtualNetworkFrameFunctionCallback(ZT1_Node *node,void *userData, + void VirtualNetworkFrameFunctionCallback(ZT_Node *node,void *userData, uint64_t nwid, uint64_t sourceMac, uint64_t destMac, @@ -186,7 +186,7 @@ namespace { } - void EventCallback(ZT1_Node *node,void *userData,enum ZT1_Event event, const void *data) + void EventCallback(ZT_Node *node,void *userData,enum ZT_Event event, const void *data) { LOGD("EventCallback"); JniRef *ref = (JniRef*)userData; @@ -245,18 +245,18 @@ namespace { switch(event) { - case ZT1_EVENT_UP: - case ZT1_EVENT_OFFLINE: - case ZT1_EVENT_ONLINE: - case ZT1_EVENT_DOWN: - case ZT1_EVENT_FATAL_ERROR_IDENTITY_COLLISION: + case ZT_EVENT_UP: + case ZT_EVENT_OFFLINE: + case ZT_EVENT_ONLINE: + case ZT_EVENT_DOWN: + case ZT_EVENT_FATAL_ERROR_IDENTITY_COLLISION: { LOGV("Regular Event"); // call onEvent() env->CallVoidMethod(ref->eventListener, onEventMethod, eventObject); } break; - case ZT1_EVENT_SAW_MORE_RECENT_VERSION: + case ZT_EVENT_SAW_MORE_RECENT_VERSION: { LOGV("Version Event"); // call onOutOfDate() @@ -268,8 +268,8 @@ namespace { } } break; - case ZT1_EVENT_AUTHENTICATION_FAILURE: - case ZT1_EVENT_INVALID_PACKET: + case ZT_EVENT_AUTHENTICATION_FAILURE: + case ZT_EVENT_INVALID_PACKET: { LOGV("Network Error Event"); // call onNetworkError() @@ -281,7 +281,7 @@ namespace { } } break; - case ZT1_EVENT_TRACE: + case ZT_EVENT_TRACE: { LOGV("Trace Event"); // call onTrace() @@ -296,7 +296,7 @@ namespace { } } - long DataStoreGetFunction(ZT1_Node *node,void *userData, + long DataStoreGetFunction(ZT_Node *node,void *userData, const char *objectName, void *buffer, unsigned long bufferSize, @@ -368,7 +368,7 @@ namespace { return retval; } - int DataStorePutFunction(ZT1_Node *node,void *userData, + int DataStorePutFunction(ZT_Node *node,void *userData, const char *objectName, const void *buffer, unsigned long bufferSize, @@ -426,7 +426,7 @@ namespace { } } - int WirePacketSendFunction(ZT1_Node *node,void *userData,\ + int WirePacketSendFunction(ZT_Node *node,void *userData,\ const struct sockaddr_storage *address, const void *buffer, unsigned int bufferSize) @@ -466,7 +466,7 @@ namespace { typedef std::map NodeMap; static NodeMap nodeMap; - ZT1_Node* findNode(uint64_t nodeId) + ZT_Node* findNode(uint64_t nodeId) { NodeMap::iterator found = nodeMap.find(nodeId); if(found != nodeMap.end()) @@ -498,10 +498,10 @@ JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init( JNIEnv *env, jobject obj, jlong now) { - LOGV("Creating ZT1_Node struct"); - jobject resultObject = createResultObject(env, ZT1_RESULT_OK); + LOGV("Creating ZT_Node struct"); + jobject resultObject = createResultObject(env, ZT_RESULT_OK); - ZT1_Node *node; + ZT_Node *node; JniRef *ref = new JniRef; ref->id = (uint64_t)now; env->GetJavaVM(&ref->jvm); @@ -593,7 +593,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init( } ref->eventListener = env->NewGlobalRef(tmp); - ZT1_ResultCode rc = ZT1_Node_new( + ZT_ResultCode rc = ZT_Node_new( &node, ref, (uint64_t)now, @@ -604,13 +604,13 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init( &VirtualNetworkConfigFunctionCallback, &EventCallback); - if(rc != ZT1_RESULT_OK) + if(rc != ZT_RESULT_OK) { LOGE("Error creating Node: %d", rc); resultObject = createResultObject(env, rc); if(node) { - ZT1_Node_delete(node); + ZT_Node_delete(node); node = NULL; } delete ref; @@ -632,7 +632,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_node_1init( JNIEXPORT void JNICALL Java_com_zerotier_sdk_Node_node_1delete( JNIEnv *env, jobject obj, jlong id) { - LOGV("Destroying ZT1_Node struct"); + LOGV("Destroying ZT_Node struct"); uint64_t nodeId = (uint64_t)id; NodeMap::iterator found = nodeMap.find(nodeId); @@ -641,7 +641,7 @@ JNIEXPORT void JNICALL Java_com_zerotier_sdk_Node_node_1delete( JniRef *ref = found->second; nodeMap.erase(found); - ZT1_Node_delete(ref->node); + ZT_Node_delete(ref->node); delete ref; ref = NULL; @@ -671,18 +671,18 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processVirtualNetworkFrame( { uint64_t nodeId = (uint64_t) id; - ZT1_Node *node = findNode(nodeId); + ZT_Node *node = findNode(nodeId); if(node == NULL) { // cannot find valid node. We should never get here. - return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL); + return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); } unsigned int nbtd_len = env->GetArrayLength(out_nextBackgroundTaskDeadline); if(nbtd_len < 1) { // array for next background task length has 0 elements! - return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL); + return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); } uint64_t now = (uint64_t)in_now; @@ -697,7 +697,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processVirtualNetworkFrame( uint64_t nextBackgroundTaskDeadline = 0; - ZT1_ResultCode rc = ZT1_Node_processVirtualNetworkFrame( + ZT_ResultCode rc = ZT_Node_processVirtualNetworkFrame( node, now, nwid, @@ -732,17 +732,17 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket( jlongArray out_nextBackgroundTaskDeadline) { uint64_t nodeId = (uint64_t) id; - ZT1_Node *node = findNode(nodeId); + ZT_Node *node = findNode(nodeId); if(node == NULL) { // cannot find valid node. We should never get here. - return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL); + return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); } unsigned int nbtd_len = env->GetArrayLength(out_nextBackgroundTaskDeadline); if(nbtd_len < 1) { - return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL); + return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); } uint64_t now = (uint64_t)in_now; @@ -752,7 +752,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket( if(inetAddressClass == NULL) { // can't find java.net.InetAddress - return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL); + return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); } jmethodID getAddressMethod = cache.findMethod( @@ -760,13 +760,13 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket( if(getAddressMethod == NULL) { // cant find InetAddress.getAddres() - return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL); + return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); } jclass InetSocketAddressClass = cache.findClass("java/net/InetSocketAddress"); if(InetSocketAddressClass == NULL) { - return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL); + return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); } jmethodID inetSockGetAddressMethod = cache.findMethod( @@ -776,7 +776,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket( if(addrObject == NULL) { - return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL); + return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); } jmethodID inetSock_getPort = cache.findMethod( @@ -785,7 +785,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket( if(env->ExceptionCheck() || inetSock_getPort == NULL) { LOGE("Couldn't find getPort method on InetSocketAddress"); - return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL); + return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); } // call InetSocketAddress.getPort() @@ -793,7 +793,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket( if(env->ExceptionCheck()) { LOGE("Exception calling InetSocketAddress.getPort()"); - return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL); + return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); } // Call InetAddress.getAddress() @@ -801,7 +801,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket( if(addressArray == NULL) { // unable to call getAddress() - return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL); + return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); } unsigned int addrSize = env->GetArrayLength(addressArray); @@ -833,7 +833,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket( { // unknown address type env->ReleaseByteArrayElements(addressArray, addr, 0); - return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL); + return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); } @@ -842,7 +842,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket( uint64_t nextBackgroundTaskDeadline = 0; - ZT1_ResultCode rc = ZT1_Node_processWirePacket( + ZT_ResultCode rc = ZT_Node_processWirePacket( node, now, &remoteAddress, @@ -872,23 +872,23 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processBackgroundTasks( jlongArray out_nextBackgroundTaskDeadline) { uint64_t nodeId = (uint64_t) id; - ZT1_Node *node = findNode(nodeId); + ZT_Node *node = findNode(nodeId); if(node == NULL) { // cannot find valid node. We should never get here. - return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL); + return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); } unsigned int nbtd_len = env->GetArrayLength(out_nextBackgroundTaskDeadline); if(nbtd_len < 1) { - return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL); + return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); } uint64_t now = (uint64_t)in_now; uint64_t nextBackgroundTaskDeadline = 0; - ZT1_ResultCode rc = ZT1_Node_processBackgroundTasks(node, now, &nextBackgroundTaskDeadline); + ZT_ResultCode rc = ZT_Node_processBackgroundTasks(node, now, &nextBackgroundTaskDeadline); jlong *outDeadline = env->GetLongArrayElements(out_nextBackgroundTaskDeadline, NULL); outDeadline[0] = (jlong)nextBackgroundTaskDeadline; @@ -906,16 +906,16 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_join( JNIEnv *env, jobject obj, jlong id, jlong in_nwid) { uint64_t nodeId = (uint64_t) id; - ZT1_Node *node = findNode(nodeId); + ZT_Node *node = findNode(nodeId); if(node == NULL) { // cannot find valid node. We should never get here. - return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL); + return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); } uint64_t nwid = (uint64_t)in_nwid; - ZT1_ResultCode rc = ZT1_Node_join(node, nwid); + ZT_ResultCode rc = ZT_Node_join(node, nwid); return createResultObject(env, rc); } @@ -929,16 +929,16 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_leave( JNIEnv *env, jobject obj, jlong id, jlong in_nwid) { uint64_t nodeId = (uint64_t) id; - ZT1_Node *node = findNode(nodeId); + ZT_Node *node = findNode(nodeId); if(node == NULL) { // cannot find valid node. We should never get here. - return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL); + return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); } uint64_t nwid = (uint64_t)in_nwid; - ZT1_ResultCode rc = ZT1_Node_leave(node, nwid); + ZT_ResultCode rc = ZT_Node_leave(node, nwid); return createResultObject(env, rc); } @@ -956,18 +956,18 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_multicastSubscribe( jlong in_multicastAdi) { uint64_t nodeId = (uint64_t) id; - ZT1_Node *node = findNode(nodeId); + ZT_Node *node = findNode(nodeId); if(node == NULL) { // cannot find valid node. We should never get here. - return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL); + return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); } uint64_t nwid = (uint64_t)in_nwid; uint64_t multicastGroup = (uint64_t)in_multicastGroup; unsigned long multicastAdi = (unsigned long)in_multicastAdi; - ZT1_ResultCode rc = ZT1_Node_multicastSubscribe( + ZT_ResultCode rc = ZT_Node_multicastSubscribe( node, nwid, multicastGroup, multicastAdi); return createResultObject(env, rc); @@ -986,18 +986,18 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_multicastUnsubscribe( jlong in_multicastAdi) { uint64_t nodeId = (uint64_t) id; - ZT1_Node *node = findNode(nodeId); + ZT_Node *node = findNode(nodeId); if(node == NULL) { // cannot find valid node. We should never get here. - return createResultObject(env, ZT1_RESULT_FATAL_ERROR_INTERNAL); + return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL); } uint64_t nwid = (uint64_t)in_nwid; uint64_t multicastGroup = (uint64_t)in_multicastGroup; unsigned long multicastAdi = (unsigned long)in_multicastAdi; - ZT1_ResultCode rc = ZT1_Node_multicastUnsubscribe( + ZT_ResultCode rc = ZT_Node_multicastUnsubscribe( node, nwid, multicastGroup, multicastAdi); return createResultObject(env, rc); @@ -1012,14 +1012,14 @@ JNIEXPORT jlong JNICALL Java_com_zerotier_sdk_Node_address( JNIEnv *env , jobject obj, jlong id) { uint64_t nodeId = (uint64_t) id; - ZT1_Node *node = findNode(nodeId); + ZT_Node *node = findNode(nodeId); if(node == NULL) { // cannot find valid node. We should never get here. return 0; } - uint64_t address = ZT1_Node_address(node); + uint64_t address = ZT_Node_address(node); return (jlong)address; } @@ -1032,7 +1032,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_status (JNIEnv *env, jobject obj, jlong id) { uint64_t nodeId = (uint64_t) id; - ZT1_Node *node = findNode(nodeId); + ZT_Node *node = findNode(nodeId); if(node == NULL) { // cannot find valid node. We should never get here. @@ -1062,8 +1062,8 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_status return NULL; } - ZT1_NodeStatus nodeStatus; - ZT1_Node_status(node, &nodeStatus); + ZT_NodeStatus nodeStatus; + ZT_Node_status(node, &nodeStatus); jfieldID addressField = NULL; jfieldID publicIdentityField = NULL; @@ -1124,18 +1124,18 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_networkConfig( JNIEnv *env, jobject obj, jlong id, jlong nwid) { uint64_t nodeId = (uint64_t) id; - ZT1_Node *node = findNode(nodeId); + ZT_Node *node = findNode(nodeId); if(node == NULL) { // cannot find valid node. We should never get here. return 0; } - ZT1_VirtualNetworkConfig *vnetConfig = ZT1_Node_networkConfig(node, nwid); + ZT_VirtualNetworkConfig *vnetConfig = ZT_Node_networkConfig(node, nwid); jobject vnetConfigObject = newNetworkConfig(env, *vnetConfig); - ZT1_Node_freeQueryResult(node, vnetConfig); + ZT_Node_freeQueryResult(node, vnetConfig); return vnetConfigObject; } @@ -1153,7 +1153,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_version( int revision = 0; unsigned long featureFlags = 0; - ZT1_version(&major, &minor, &revision, &featureFlags); + ZT_version(&major, &minor, &revision, &featureFlags); return newVersion(env, major, minor, revision, featureFlags); } @@ -1167,18 +1167,18 @@ JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_peers( JNIEnv *env, jobject obj, jlong id) { uint64_t nodeId = (uint64_t) id; - ZT1_Node *node = findNode(nodeId); + ZT_Node *node = findNode(nodeId); if(node == NULL) { // cannot find valid node. We should never get here. return 0; } - ZT1_PeerList *peerList = ZT1_Node_peers(node); + ZT_PeerList *peerList = ZT_Node_peers(node); if(peerList == NULL) { - LOGE("ZT1_Node_peers returned NULL"); + LOGE("ZT_Node_peers returned NULL"); return NULL; } @@ -1187,7 +1187,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_peers( if(env->EnsureLocalCapacity(peerCount)) { LOGE("EnsureLocalCapacity failed!!"); - ZT1_Node_freeQueryResult(node, peerList); + ZT_Node_freeQueryResult(node, peerList); return NULL; } @@ -1195,7 +1195,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_peers( if(env->ExceptionCheck() || peerClass == NULL) { LOGE("Error finding Peer class"); - ZT1_Node_freeQueryResult(node, peerList); + ZT_Node_freeQueryResult(node, peerList); return NULL; } @@ -1205,7 +1205,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_peers( if(env->ExceptionCheck() || peerArrayObj == NULL) { LOGE("Error creating Peer[] array"); - ZT1_Node_freeQueryResult(node, peerList); + ZT_Node_freeQueryResult(node, peerList); return NULL; } @@ -1221,7 +1221,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_peers( } } - ZT1_Node_freeQueryResult(node, peerList); + ZT_Node_freeQueryResult(node, peerList); peerList = NULL; return peerArrayObj; @@ -1236,14 +1236,14 @@ JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_networks( JNIEnv *env, jobject obj, jlong id) { uint64_t nodeId = (uint64_t) id; - ZT1_Node *node = findNode(nodeId); + ZT_Node *node = findNode(nodeId); if(node == NULL) { // cannot find valid node. We should never get here. return 0; } - ZT1_VirtualNetworkList *networkList = ZT1_Node_networks(node); + ZT_VirtualNetworkList *networkList = ZT_Node_networks(node); if(networkList == NULL) { return NULL; @@ -1253,7 +1253,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_networks( if(env->ExceptionCheck() || vnetConfigClass == NULL) { LOGE("Error finding VirtualNetworkConfig class"); - ZT1_Node_freeQueryResult(node, networkList); + ZT_Node_freeQueryResult(node, networkList); return NULL; } @@ -1262,7 +1262,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_networks( if(env->ExceptionCheck() || networkListObject == NULL) { LOGE("Error creating VirtualNetworkConfig[] array"); - ZT1_Node_freeQueryResult(node, networkList); + ZT_Node_freeQueryResult(node, networkList); return NULL; } @@ -1277,7 +1277,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_zerotier_sdk_Node_networks( } } - ZT1_Node_freeQueryResult(node, networkList); + ZT_Node_freeQueryResult(node, networkList); return networkListObject; } diff --git a/java/src/com/zerotier/sdk/VirtualNetworkConfig.java b/java/src/com/zerotier/sdk/VirtualNetworkConfig.java index 2be03acb..78ac9da5 100644 --- a/java/src/com/zerotier/sdk/VirtualNetworkConfig.java +++ b/java/src/com/zerotier/sdk/VirtualNetworkConfig.java @@ -33,7 +33,7 @@ import java.net.InetSocketAddress; public final class VirtualNetworkConfig { public static final int MAX_MULTICAST_SUBSCRIPTIONS = 4096; - public static final int ZT1_MAX_ZT_ASSIGNED_ADDRESSES = 16; + public static final int ZT_MAX_ZT_ASSIGNED_ADDRESSES = 16; private long nwid; private long mac; diff --git a/node/Constants.hpp b/node/Constants.hpp index b7aa9817..4f783550 100644 --- a/node/Constants.hpp +++ b/node/Constants.hpp @@ -161,7 +161,7 @@ /** * Default MTU used for Ethernet tap device */ -#define ZT_IF_MTU ZT1_MAX_MTU +#define ZT_IF_MTU ZT_MAX_MTU /** * Maximum number of packet fragments we'll support diff --git a/node/Defaults.cpp b/node/Defaults.cpp index e64f3844..b311fb6a 100644 --- a/node/Defaults.cpp +++ b/node/Defaults.cpp @@ -75,7 +75,7 @@ static inline std::map< Address,Identity > _mkRootTopologyAuth() Defaults::Defaults() : defaultRootTopology((const char *)ZT_DEFAULT_ROOT_TOPOLOGY,ZT_DEFAULT_ROOT_TOPOLOGY_LEN), rootTopologyAuthorities(_mkRootTopologyAuth()), - v4Broadcast(((uint32_t)0xffffffff),ZT1_DEFAULT_PORT) + v4Broadcast(((uint32_t)0xffffffff),ZT_DEFAULT_PORT) { } diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index e4861af7..c94ffe2e 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -69,7 +69,7 @@ bool IncomingPacket::tryDecode(const RuntimeEnvironment *RR) switch(verb()) { //case Packet::VERB_NOP: default: // ignore unknown verbs, but if they pass auth check they are "received" - peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),verb(),0,Packet::VERB_NOP); + peer->received(RR,_localAddress,_remoteAddress,hops(),packetId(),verb(),0,Packet::VERB_NOP); return true; case Packet::VERB_HELLO: return _doHELLO(RR); case Packet::VERB_ERROR: return _doERROR(RR,peer); @@ -130,7 +130,7 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,const SharedPtr case Packet::ERROR_IDENTITY_COLLISION: if (RR->topology->isRoot(peer->identity())) - RR->node->postEvent(ZT1_EVENT_FATAL_ERROR_IDENTITY_COLLISION); + RR->node->postEvent(ZT_EVENT_FATAL_ERROR_IDENTITY_COLLISION); break; case Packet::ERROR_NEED_MEMBERSHIP_CERTIFICATE: { @@ -144,7 +144,7 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,const SharedPtr Packet outp(peer->address(),RR->identity.address(),Packet::VERB_NETWORK_MEMBERSHIP_CERTIFICATE); nconf->com().serialize(outp); outp.armor(peer->key(),true); - RR->node->putPacket(_localInterfaceId,_remoteAddress,outp.data(),outp.size()); + RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size()); } } } break; @@ -165,7 +165,7 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,const SharedPtr default: break; } - peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),Packet::VERB_ERROR,inRePacketId,inReVerb); + peer->received(RR,_localAddress,_remoteAddress,hops(),packetId(),Packet::VERB_ERROR,inRePacketId,inReVerb); } catch (std::exception &ex) { TRACE("dropped ERROR from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),ex.what()); } catch ( ... ) { @@ -224,20 +224,20 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR) unsigned char key[ZT_PEER_SECRET_KEY_LENGTH]; if (RR->identity.agree(id,key,ZT_PEER_SECRET_KEY_LENGTH)) { if (dearmor(key)) { // ensure packet is authentic, otherwise drop - RR->node->postEvent(ZT1_EVENT_AUTHENTICATION_FAILURE,(const void *)&_remoteAddress); + RR->node->postEvent(ZT_EVENT_AUTHENTICATION_FAILURE,(const void *)&_remoteAddress); TRACE("rejected HELLO from %s(%s): address already claimed",id.address().toString().c_str(),_remoteAddress.toString().c_str()); Packet outp(id.address(),RR->identity.address(),Packet::VERB_ERROR); outp.append((unsigned char)Packet::VERB_HELLO); outp.append(packetId()); outp.append((unsigned char)Packet::ERROR_IDENTITY_COLLISION); outp.armor(key,true); - RR->node->putPacket(_localInterfaceId,_remoteAddress,outp.data(),outp.size()); + RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size()); } else { - RR->node->postEvent(ZT1_EVENT_AUTHENTICATION_FAILURE,(const void *)&_remoteAddress); + RR->node->postEvent(ZT_EVENT_AUTHENTICATION_FAILURE,(const void *)&_remoteAddress); TRACE("rejected HELLO from %s(%s): packet failed authentication",id.address().toString().c_str(),_remoteAddress.toString().c_str()); } } else { - RR->node->postEvent(ZT1_EVENT_AUTHENTICATION_FAILURE,(const void *)&_remoteAddress); + RR->node->postEvent(ZT_EVENT_AUTHENTICATION_FAILURE,(const void *)&_remoteAddress); TRACE("rejected HELLO from %s(%s): key agreement failed",id.address().toString().c_str(),_remoteAddress.toString().c_str()); } @@ -246,7 +246,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR) // Identity is the same as the one we already have -- check packet integrity if (!dearmor(peer->key())) { - RR->node->postEvent(ZT1_EVENT_AUTHENTICATION_FAILURE,(const void *)&_remoteAddress); + RR->node->postEvent(ZT_EVENT_AUTHENTICATION_FAILURE,(const void *)&_remoteAddress); TRACE("rejected HELLO from %s(%s): packet failed authentication",id.address().toString().c_str(),_remoteAddress.toString().c_str()); return true; } @@ -258,7 +258,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR) // Check identity proof of work if (!id.locallyValidate()) { - RR->node->postEvent(ZT1_EVENT_AUTHENTICATION_FAILURE,(const void *)&_remoteAddress); + RR->node->postEvent(ZT_EVENT_AUTHENTICATION_FAILURE,(const void *)&_remoteAddress); TRACE("dropped HELLO from %s(%s): identity invalid",id.address().toString().c_str(),_remoteAddress.toString().c_str()); return true; } @@ -266,7 +266,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR) // Check packet integrity and authentication SharedPtr newPeer(new Peer(RR->identity,id)); if (!dearmor(newPeer->key())) { - RR->node->postEvent(ZT1_EVENT_AUTHENTICATION_FAILURE,(const void *)&_remoteAddress); + RR->node->postEvent(ZT_EVENT_AUTHENTICATION_FAILURE,(const void *)&_remoteAddress); TRACE("rejected HELLO from %s(%s): packet failed authentication",id.address().toString().c_str(),_remoteAddress.toString().c_str()); return true; } @@ -278,7 +278,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR) // VALID -- continues here - peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),Packet::VERB_HELLO,0,Packet::VERB_NOP); + peer->received(RR,_localAddress,_remoteAddress,hops(),packetId(),Packet::VERB_HELLO,0,Packet::VERB_NOP); peer->setRemoteVersion(protoVersion,vMajor,vMinor,vRevision); bool trusted = false; @@ -316,7 +316,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR) } outp.armor(peer->key(),true); - RR->node->putPacket(_localInterfaceId,_remoteAddress,outp.data(),outp.size()); + RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size()); } catch (std::exception &ex) { TRACE("dropped HELLO from %s(%s): %s",source().toString().c_str(),_remoteAddress.toString().c_str(),ex.what()); } catch ( ... ) { @@ -436,7 +436,7 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,const SharedPtr &p default: break; } - peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),Packet::VERB_OK,inRePacketId,inReVerb); + peer->received(RR,_localAddress,_remoteAddress,hops(),packetId(),Packet::VERB_OK,inRePacketId,inReVerb); } catch (std::exception &ex) { TRACE("dropped OK from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),ex.what()); } catch ( ... ) { @@ -456,7 +456,7 @@ bool IncomingPacket::_doWHOIS(const RuntimeEnvironment *RR,const SharedPtr outp.append(packetId()); queried->identity().serialize(outp,false); outp.armor(peer->key(),true); - RR->node->putPacket(_localInterfaceId,_remoteAddress,outp.data(),outp.size()); + RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size()); } else { Packet outp(peer->address(),RR->identity.address(),Packet::VERB_ERROR); outp.append((unsigned char)Packet::VERB_WHOIS); @@ -464,12 +464,12 @@ bool IncomingPacket::_doWHOIS(const RuntimeEnvironment *RR,const SharedPtr outp.append((unsigned char)Packet::ERROR_OBJ_NOT_FOUND); outp.append(payload(),ZT_ADDRESS_LENGTH); outp.armor(peer->key(),true); - RR->node->putPacket(_localInterfaceId,_remoteAddress,outp.data(),outp.size()); + RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size()); } } else { TRACE("dropped WHOIS from %s(%s): missing or invalid address",source().toString().c_str(),_remoteAddress.toString().c_str()); } - peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),Packet::VERB_WHOIS,0,Packet::VERB_NOP); + peer->received(RR,_localAddress,_remoteAddress,hops(),packetId(),Packet::VERB_WHOIS,0,Packet::VERB_NOP); } catch ( ... ) { TRACE("dropped WHOIS from %s(%s): unexpected exception",source().toString().c_str(),_remoteAddress.toString().c_str()); } @@ -487,8 +487,8 @@ bool IncomingPacket::_doRENDEZVOUS(const RuntimeEnvironment *RR,const SharedPtr< if ((port > 0)&&((addrlen == 4)||(addrlen == 16))) { InetAddress atAddr(field(ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRESS,addrlen),addrlen,port); TRACE("RENDEZVOUS from %s says %s might be at %s, starting NAT-t",peer->address().toString().c_str(),with.toString().c_str(),atAddr.toString().c_str()); - peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),Packet::VERB_RENDEZVOUS,0,Packet::VERB_NOP); - RR->sw->rendezvous(withPeer,_localInterfaceId,atAddr); + peer->received(RR,_localAddress,_remoteAddress,hops(),packetId(),Packet::VERB_RENDEZVOUS,0,Packet::VERB_NOP); + RR->sw->rendezvous(withPeer,_localAddress,atAddr); } else { TRACE("dropped corrupt RENDEZVOUS from %s(%s) (bad address or port)",peer->address().toString().c_str(),_remoteAddress.toString().c_str()); } @@ -525,7 +525,7 @@ bool IncomingPacket::_doFRAME(const RuntimeEnvironment *RR,const SharedPtr RR->node->putFrame(network->id(),MAC(peer->address(),network->id()),network->mac(),etherType,0,field(ZT_PROTO_VERB_FRAME_IDX_PAYLOAD,payloadLen),payloadLen); } - peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),Packet::VERB_FRAME,0,Packet::VERB_NOP); + peer->received(RR,_localAddress,_remoteAddress,hops(),packetId(),Packet::VERB_FRAME,0,Packet::VERB_NOP); } else { TRACE("dropped FRAME from %s(%s): we are not connected to network %.16llx",source().toString().c_str(),_remoteAddress.toString().c_str(),at(ZT_PROTO_VERB_FRAME_IDX_NETWORK_ID)); } @@ -602,7 +602,7 @@ bool IncomingPacket::_doEXT_FRAME(const RuntimeEnvironment *RR,const SharedPtr

node->putFrame(network->id(),from,to,etherType,0,field(comLen + ZT_PROTO_VERB_EXT_FRAME_IDX_PAYLOAD,payloadLen),payloadLen); } - peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),Packet::VERB_EXT_FRAME,0,Packet::VERB_NOP); + peer->received(RR,_localAddress,_remoteAddress,hops(),packetId(),Packet::VERB_EXT_FRAME,0,Packet::VERB_NOP); } else { TRACE("dropped EXT_FRAME from %s(%s): we are not connected to network %.16llx",source().toString().c_str(),_remoteAddress.toString().c_str(),at(ZT_PROTO_VERB_FRAME_IDX_NETWORK_ID)); } @@ -623,7 +623,7 @@ bool IncomingPacket::_doMULTICAST_LIKE(const RuntimeEnvironment *RR,const Shared for(unsigned int ptr=ZT_PACKET_IDX_PAYLOAD;ptrmc->add(now,at(ptr),MulticastGroup(MAC(field(ptr + 8,6),6),at(ptr + 14)),peer->address()); - peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),Packet::VERB_MULTICAST_LIKE,0,Packet::VERB_NOP); + peer->received(RR,_localAddress,_remoteAddress,hops(),packetId(),Packet::VERB_MULTICAST_LIKE,0,Packet::VERB_NOP); } catch (std::exception &ex) { TRACE("dropped MULTICAST_LIKE from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),ex.what()); } catch ( ... ) { @@ -647,7 +647,7 @@ bool IncomingPacket::_doNETWORK_MEMBERSHIP_CERTIFICATE(const RuntimeEnvironment } } - peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),Packet::VERB_NETWORK_MEMBERSHIP_CERTIFICATE,0,Packet::VERB_NOP); + peer->received(RR,_localAddress,_remoteAddress,hops(),packetId(),Packet::VERB_NETWORK_MEMBERSHIP_CERTIFICATE,0,Packet::VERB_NOP); } catch (std::exception &ex) { TRACE("dropped NETWORK_MEMBERSHIP_CERTIFICATE from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),ex.what()); } catch ( ... ) { @@ -666,7 +666,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons const unsigned int h = hops(); const uint64_t pid = packetId(); - peer->received(RR,_localInterfaceId,_remoteAddress,h,pid,Packet::VERB_NETWORK_CONFIG_REQUEST,0,Packet::VERB_NOP); + peer->received(RR,_localAddress,_remoteAddress,h,pid,Packet::VERB_NETWORK_CONFIG_REQUEST,0,Packet::VERB_NOP); if (RR->localNetworkController) { Dictionary netconf; @@ -688,7 +688,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons if (outp.size() > ZT_PROTO_MAX_PACKET_LENGTH) { TRACE("NETWORK_CONFIG_REQUEST failed: internal error: netconf size %u is too large",(unsigned int)netconfStr.length()); } else { - RR->node->putPacket(_localInterfaceId,_remoteAddress,outp.data(),outp.size()); + RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size()); } } } break; @@ -700,7 +700,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons outp.append((unsigned char)Packet::ERROR_OBJ_NOT_FOUND); outp.append(nwid); outp.armor(peer->key(),true); - RR->node->putPacket(_localInterfaceId,_remoteAddress,outp.data(),outp.size()); + RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size()); } break; case NetworkController::NETCONF_QUERY_ACCESS_DENIED: { @@ -710,7 +710,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons outp.append((unsigned char)Packet::ERROR_NETWORK_ACCESS_DENIED_); outp.append(nwid); outp.armor(peer->key(),true); - RR->node->putPacket(_localInterfaceId,_remoteAddress,outp.data(),outp.size()); + RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size()); } break; case NetworkController::NETCONF_QUERY_INTERNAL_SERVER_ERROR: @@ -732,7 +732,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons outp.append((unsigned char)Packet::ERROR_UNSUPPORTED_OPERATION); outp.append(nwid); outp.armor(peer->key(),true); - RR->node->putPacket(_localInterfaceId,_remoteAddress,outp.data(),outp.size()); + RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size()); } } catch (std::exception &exc) { TRACE("dropped NETWORK_CONFIG_REQUEST from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),exc.what()); @@ -753,7 +753,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REFRESH(const RuntimeEnvironment *RR,cons nw->requestConfiguration(); ptr += 8; } - peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),Packet::VERB_NETWORK_CONFIG_REFRESH,0,Packet::VERB_NOP); + peer->received(RR,_localAddress,_remoteAddress,hops(),packetId(),Packet::VERB_NETWORK_CONFIG_REFRESH,0,Packet::VERB_NOP); } catch (std::exception &exc) { TRACE("dropped NETWORK_CONFIG_REFRESH from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),exc.what()); } catch ( ... ) { @@ -780,11 +780,11 @@ bool IncomingPacket::_doMULTICAST_GATHER(const RuntimeEnvironment *RR,const Shar outp.append((uint32_t)mg.adi()); if (RR->mc->gather(peer->address(),nwid,mg,outp,gatherLimit)) { outp.armor(peer->key(),true); - RR->node->putPacket(_localInterfaceId,_remoteAddress,outp.data(),outp.size()); + RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size()); } } - peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),Packet::VERB_MULTICAST_GATHER,0,Packet::VERB_NOP); + peer->received(RR,_localAddress,_remoteAddress,hops(),packetId(),Packet::VERB_MULTICAST_GATHER,0,Packet::VERB_NOP); } catch (std::exception &exc) { TRACE("dropped MULTICAST_GATHER from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),exc.what()); } catch ( ... ) { @@ -871,12 +871,12 @@ bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment *RR,const Share outp.append((unsigned char)0x02); // flag 0x02 = contains gather results if (RR->mc->gather(peer->address(),nwid,to,outp,gatherLimit)) { outp.armor(peer->key(),true); - RR->node->putPacket(_localInterfaceId,_remoteAddress,outp.data(),outp.size()); + RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size()); } } } // else ignore -- not a member of this network - peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),Packet::VERB_MULTICAST_FRAME,0,Packet::VERB_NOP); + peer->received(RR,_localAddress,_remoteAddress,hops(),packetId(),Packet::VERB_MULTICAST_FRAME,0,Packet::VERB_NOP); } catch (std::exception &exc) { TRACE("dropped MULTICAST_FRAME from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),exc.what()); } catch ( ... ) { @@ -905,14 +905,14 @@ bool IncomingPacket::_doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,const Sha InetAddress a(field(ptr,4),4,at(ptr + 4)); if ( ((flags & (0x01 | 0x02)) == 0) && (Path::isAddressValidForPath(a)) ) { TRACE("attempting to contact %s at pushed direct path %s",peer->address().toString().c_str(),a.toString().c_str()); - peer->attemptToContactAt(RR,_localInterfaceId,a,RR->node->now()); + peer->attemptToContactAt(RR,_localAddress,a,RR->node->now()); } } break; case 6: { InetAddress a(field(ptr,16),16,at(ptr + 16)); if ( ((flags & (0x01 | 0x02)) == 0) && (Path::isAddressValidForPath(a)) ) { TRACE("attempting to contact %s at pushed direct path %s",peer->address().toString().c_str(),a.toString().c_str()); - peer->attemptToContactAt(RR,_localInterfaceId,a,RR->node->now()); + peer->attemptToContactAt(RR,_localAddress,a,RR->node->now()); } } break; } @@ -934,7 +934,7 @@ void IncomingPacket::_sendErrorNeedCertificate(const RuntimeEnvironment *RR,cons outp.append((unsigned char)Packet::ERROR_NEED_MEMBERSHIP_CERTIFICATE); outp.append(nwid); outp.armor(peer->key(),true); - RR->node->putPacket(_localInterfaceId,_remoteAddress,outp.data(),outp.size()); + RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size()); } } // namespace ZeroTier diff --git a/node/IncomingPacket.hpp b/node/IncomingPacket.hpp index 170ab7f9..d19eb5c6 100644 --- a/node/IncomingPacket.hpp +++ b/node/IncomingPacket.hpp @@ -72,16 +72,16 @@ public: * * @param data Packet data * @param len Packet length - * @param localInterfaceId Local interface ID + * @param localAddress Local interface address * @param remoteAddress Address from which packet came * @param now Current time * @throws std::out_of_range Range error processing packet */ - IncomingPacket(const void *data,unsigned int len,int localInterfaceId,const InetAddress &remoteAddress,uint64_t now) : + IncomingPacket(const void *data,unsigned int len,const InetAddress &localAddress,const InetAddress &remoteAddress,uint64_t now) : Packet(data,len), _receiveTime(now), + _localAddress(localAddress), _remoteAddress(remoteAddress), - _localInterfaceId(localInterfaceId), __refCount() { } @@ -129,8 +129,8 @@ private: void _sendErrorNeedCertificate(const RuntimeEnvironment *RR,const SharedPtr &peer,uint64_t nwid); uint64_t _receiveTime; + InetAddress _localAddress; InetAddress _remoteAddress; - int _localInterfaceId; AtomicCounter __refCount; }; diff --git a/node/Network.cpp b/node/Network.cpp index f8130d76..2b24d5f9 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -100,28 +100,28 @@ Network::Network(const RuntimeEnvironment *renv,uint64_t nwid) : } if (!_portInitialized) { - ZT1_VirtualNetworkConfig ctmp; + ZT_VirtualNetworkConfig ctmp; _externalConfig(&ctmp); - _portError = RR->node->configureVirtualNetworkPort(_id,ZT1_VIRTUAL_NETWORK_CONFIG_OPERATION_UP,&ctmp); + _portError = RR->node->configureVirtualNetworkPort(_id,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP,&ctmp); _portInitialized = true; } } Network::~Network() { - ZT1_VirtualNetworkConfig ctmp; + ZT_VirtualNetworkConfig ctmp; _externalConfig(&ctmp); char n[128]; if (_destroyed) { - RR->node->configureVirtualNetworkPort(_id,ZT1_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY,&ctmp); + RR->node->configureVirtualNetworkPort(_id,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY,&ctmp); Utils::snprintf(n,sizeof(n),"networks.d/%.16llx.conf",_id); RR->node->dataStoreDelete(n); Utils::snprintf(n,sizeof(n),"networks.d/%.16llx.mcerts",_id); RR->node->dataStoreDelete(n); } else { - RR->node->configureVirtualNetworkPort(_id,ZT1_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN,&ctmp); + RR->node->configureVirtualNetworkPort(_id,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN,&ctmp); clean(); @@ -184,7 +184,7 @@ bool Network::applyConfiguration(const SharedPtr &conf) return false; try { if ((conf->networkId() == _id)&&(conf->issuedTo() == RR->identity.address())) { - ZT1_VirtualNetworkConfig ctmp; + ZT_VirtualNetworkConfig ctmp; bool portInitialized; { Mutex::Lock _l(_lock); @@ -195,7 +195,7 @@ bool Network::applyConfiguration(const SharedPtr &conf) portInitialized = _portInitialized; _portInitialized = true; } - _portError = RR->node->configureVirtualNetworkPort(_id,(portInitialized) ? ZT1_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE : ZT1_VIRTUAL_NETWORK_CONFIG_OPERATION_UP,&ctmp); + _portError = RR->node->configureVirtualNetworkPort(_id,(portInitialized) ? ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE : ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP,&ctmp); return true; } else { TRACE("ignored invalid configuration for network %.16llx (configuration contains mismatched network ID or issued-to address)",(unsigned long long)_id); @@ -431,9 +431,9 @@ void Network::setEnabled(bool enabled) Mutex::Lock _l(_lock); if (_enabled != enabled) { _enabled = enabled; - ZT1_VirtualNetworkConfig ctmp; + ZT_VirtualNetworkConfig ctmp; _externalConfig(&ctmp); - _portError = RR->node->configureVirtualNetworkPort(_id,ZT1_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE,&ctmp); + _portError = RR->node->configureVirtualNetworkPort(_id,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE,&ctmp); } } @@ -444,24 +444,24 @@ void Network::destroy() _destroyed = true; } -ZT1_VirtualNetworkStatus Network::_status() const +ZT_VirtualNetworkStatus Network::_status() const { // assumes _lock is locked if (_portError) - return ZT1_NETWORK_STATUS_PORT_ERROR; + return ZT_NETWORK_STATUS_PORT_ERROR; switch(_netconfFailure) { case NETCONF_FAILURE_ACCESS_DENIED: - return ZT1_NETWORK_STATUS_ACCESS_DENIED; + return ZT_NETWORK_STATUS_ACCESS_DENIED; case NETCONF_FAILURE_NOT_FOUND: - return ZT1_NETWORK_STATUS_NOT_FOUND; + return ZT_NETWORK_STATUS_NOT_FOUND; case NETCONF_FAILURE_NONE: - return ((_config) ? ZT1_NETWORK_STATUS_OK : ZT1_NETWORK_STATUS_REQUESTING_CONFIGURATION); + return ((_config) ? ZT_NETWORK_STATUS_OK : ZT_NETWORK_STATUS_REQUESTING_CONFIGURATION); default: - return ZT1_NETWORK_STATUS_PORT_ERROR; + return ZT_NETWORK_STATUS_PORT_ERROR; } } -void Network::_externalConfig(ZT1_VirtualNetworkConfig *ec) const +void Network::_externalConfig(ZT_VirtualNetworkConfig *ec) const { // assumes _lock is locked ec->nwid = _id; @@ -470,7 +470,7 @@ void Network::_externalConfig(ZT1_VirtualNetworkConfig *ec) const Utils::scopy(ec->name,sizeof(ec->name),_config->name().c_str()); else ec->name[0] = (char)0; ec->status = _status(); - ec->type = (_config) ? (_config->isPrivate() ? ZT1_NETWORK_TYPE_PRIVATE : ZT1_NETWORK_TYPE_PUBLIC) : ZT1_NETWORK_TYPE_PRIVATE; + ec->type = (_config) ? (_config->isPrivate() ? ZT_NETWORK_TYPE_PRIVATE : ZT_NETWORK_TYPE_PUBLIC) : ZT_NETWORK_TYPE_PRIVATE; ec->mtu = ZT_IF_MTU; ec->dhcp = 0; ec->bridge = (_config) ? ((_config->allowPassiveBridging() || (std::find(_config->activeBridges().begin(),_config->activeBridges().end(),RR->identity.address()) != _config->activeBridges().end())) ? 1 : 0) : 0; @@ -479,7 +479,7 @@ void Network::_externalConfig(ZT1_VirtualNetworkConfig *ec) const ec->enabled = (_enabled) ? 1 : 0; ec->netconfRevision = (_config) ? (unsigned long)_config->revision() : 0; - ec->multicastSubscriptionCount = std::min((unsigned int)_myMulticastGroups.size(),(unsigned int)ZT1_MAX_NETWORK_MULTICAST_SUBSCRIPTIONS); + ec->multicastSubscriptionCount = std::min((unsigned int)_myMulticastGroups.size(),(unsigned int)ZT_MAX_NETWORK_MULTICAST_SUBSCRIPTIONS); for(unsigned int i=0;imulticastSubscriptionCount;++i) { ec->multicastSubscriptions[i].mac = _myMulticastGroups[i].mac().toInt(); ec->multicastSubscriptions[i].adi = _myMulticastGroups[i].adi(); @@ -487,7 +487,7 @@ void Network::_externalConfig(ZT1_VirtualNetworkConfig *ec) const if (_config) { ec->assignedAddressCount = (unsigned int)_config->staticIps().size(); - for(unsigned long i=0;istaticIps().size()) memcpy(&(ec->assignedAddresses[i]),&(_config->staticIps()[i]),sizeof(struct sockaddr_storage)); } diff --git a/node/Network.hpp b/node/Network.hpp index 7f215555..ad9f18de 100644 --- a/node/Network.hpp +++ b/node/Network.hpp @@ -222,7 +222,7 @@ public: /** * @return Status of this network */ - inline ZT1_VirtualNetworkStatus status() const + inline ZT_VirtualNetworkStatus status() const { Mutex::Lock _l(_lock); return _status(); @@ -231,7 +231,7 @@ public: /** * @param ec Buffer to fill with externally-visible network configuration */ - inline void externalConfig(ZT1_VirtualNetworkConfig *ec) const + inline void externalConfig(ZT_VirtualNetworkConfig *ec) const { Mutex::Lock _l(_lock); _externalConfig(ec); @@ -354,8 +354,8 @@ private: uint64_t lastPushed; // when did we last push ours to them? }; - ZT1_VirtualNetworkStatus _status() const; - void _externalConfig(ZT1_VirtualNetworkConfig *ec) const; // assumes _lock is locked + ZT_VirtualNetworkStatus _status() const; + void _externalConfig(ZT_VirtualNetworkConfig *ec) const; // assumes _lock is locked bool _isAllowed(const Address &peer) const; void _announceMulticastGroups(); std::vector _allMulticastGroups() const; diff --git a/node/NetworkConfig.cpp b/node/NetworkConfig.cpp index 7898646c..e46da4a4 100644 --- a/node/NetworkConfig.cpp +++ b/node/NetworkConfig.cpp @@ -108,7 +108,7 @@ void NetworkConfig::_fromDictionary(const Dictionary &d) _private = (Utils::hexStrToUInt(d.get(ZT_NETWORKCONFIG_DICT_KEY_PRIVATE,one).c_str()) != 0); _enableBroadcast = (Utils::hexStrToUInt(d.get(ZT_NETWORKCONFIG_DICT_KEY_ENABLE_BROADCAST,one).c_str()) != 0); _name = d.get(ZT_NETWORKCONFIG_DICT_KEY_NAME); - if (_name.length() > ZT1_MAX_NETWORK_SHORT_NAME_LENGTH) + if (_name.length() > ZT_MAX_NETWORK_SHORT_NAME_LENGTH) throw std::invalid_argument("network short name too long (max: 255 characters)"); // In dictionary IPs are split into V4 and V6 addresses, but we don't really @@ -142,8 +142,8 @@ void NetworkConfig::_fromDictionary(const Dictionary &d) _localRoutes.push_back(addr); else _staticIps.push_back(addr); } - if (_localRoutes.size() > ZT1_MAX_ZT_ASSIGNED_ADDRESSES) throw std::invalid_argument("too many ZT-assigned routes"); - if (_staticIps.size() > ZT1_MAX_ZT_ASSIGNED_ADDRESSES) throw std::invalid_argument("too many ZT-assigned IP addresses"); + if (_localRoutes.size() > ZT_MAX_ZT_ASSIGNED_ADDRESSES) throw std::invalid_argument("too many ZT-assigned routes"); + if (_staticIps.size() > ZT_MAX_ZT_ASSIGNED_ADDRESSES) throw std::invalid_argument("too many ZT-assigned IP addresses"); std::sort(_localRoutes.begin(),_localRoutes.end()); _localRoutes.erase(std::unique(_localRoutes.begin(),_localRoutes.end()),_localRoutes.end()); std::sort(_staticIps.begin(),_staticIps.end()); diff --git a/node/Node.cpp b/node/Node.cpp index 7aad54b8..6dc83d4e 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -48,6 +48,8 @@ #include "SelfAwareness.hpp" #include "Defaults.hpp" +const struct sockaddr_storage ZT_SOCKADDR_NULL = {0}; + namespace ZeroTier { /****************************************************************************/ @@ -57,12 +59,12 @@ namespace ZeroTier { Node::Node( uint64_t now, void *uptr, - ZT1_DataStoreGetFunction dataStoreGetFunction, - ZT1_DataStorePutFunction dataStorePutFunction, - ZT1_WirePacketSendFunction wirePacketSendFunction, - ZT1_VirtualNetworkFrameFunction virtualNetworkFrameFunction, - ZT1_VirtualNetworkConfigFunction virtualNetworkConfigFunction, - ZT1_EventCallback eventCallback, + ZT_DataStoreGetFunction dataStoreGetFunction, + ZT_DataStorePutFunction dataStorePutFunction, + ZT_WirePacketSendFunction wirePacketSendFunction, + ZT_VirtualNetworkFrameFunction virtualNetworkFrameFunction, + ZT_VirtualNetworkConfigFunction virtualNetworkConfigFunction, + ZT_EventCallback eventCallback, const char *overrideRootTopology) : _RR(this), RR(&_RR), @@ -141,7 +143,7 @@ Node::Node( } RR->topology->setRootServers(Dictionary(rt.get("rootservers",""))); - postEvent(ZT1_EVENT_UP); + postEvent(ZT_EVENT_UP); } Node::~Node() @@ -155,20 +157,20 @@ Node::~Node() delete RR->sw; } -ZT1_ResultCode Node::processWirePacket( +ZT_ResultCode Node::processWirePacket( uint64_t now, - int localInterfaceId, + const struct sockaddr_storage *localAddress, const struct sockaddr_storage *remoteAddress, const void *packetData, unsigned int packetLength, volatile uint64_t *nextBackgroundTaskDeadline) { _now = now; - RR->sw->onRemotePacket(localInterfaceId,*(reinterpret_cast(remoteAddress)),packetData,packetLength); - return ZT1_RESULT_OK; + RR->sw->onRemotePacket(*(reinterpret_cast(localAddress)),*(reinterpret_cast(remoteAddress)),packetData,packetLength); + return ZT_RESULT_OK; } -ZT1_ResultCode Node::processVirtualNetworkFrame( +ZT_ResultCode Node::processVirtualNetworkFrame( uint64_t now, uint64_t nwid, uint64_t sourceMac, @@ -183,8 +185,8 @@ ZT1_ResultCode Node::processVirtualNetworkFrame( SharedPtr nw(this->network(nwid)); if (nw) { RR->sw->onLocalEthernet(nw,MAC(sourceMac),MAC(destMac),etherType,vlanId,frameData,frameLength); - return ZT1_RESULT_OK; - } else return ZT1_RESULT_ERROR_NETWORK_NOT_FOUND; + return ZT_RESULT_OK; + } else return ZT_RESULT_ERROR_NETWORK_NOT_FOUND; } class _PingPeersThatNeedPing @@ -228,7 +230,7 @@ private: std::vector

_rootAddresses; }; -ZT1_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *nextBackgroundTaskDeadline) +ZT_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *nextBackgroundTaskDeadline) { _now = now; Mutex::Lock bl(_backgroundTasksLock); @@ -264,7 +266,7 @@ ZT1_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *next if (nr->second) { SharedPtr rp(RR->topology->getPeer(nr->first)); if ((rp)&&(!rp->hasActiveDirectPath(now))) - rp->attemptToContactAt(RR,-1,nr->second,now); + rp->attemptToContactAt(RR,InetAddress(),nr->second,now); } } @@ -276,9 +278,9 @@ ZT1_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *next bool oldOnline = _online; _online = ((now - pfunc.lastReceiveFromUpstream) < ZT_PEER_ACTIVITY_TIMEOUT); if (oldOnline != _online) - postEvent(_online ? ZT1_EVENT_ONLINE : ZT1_EVENT_OFFLINE); + postEvent(_online ? ZT_EVENT_ONLINE : ZT_EVENT_OFFLINE); } catch ( ... ) { - return ZT1_RESULT_FATAL_ERROR_INTERNAL; + return ZT_RESULT_FATAL_ERROR_INTERNAL; } } else { timeUntilNextPingCheck -= (unsigned long)timeSinceLastPingCheck; @@ -291,30 +293,30 @@ ZT1_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *next RR->sa->clean(now); RR->mc->clean(now); } catch ( ... ) { - return ZT1_RESULT_FATAL_ERROR_INTERNAL; + return ZT_RESULT_FATAL_ERROR_INTERNAL; } } try { *nextBackgroundTaskDeadline = now + (uint64_t)std::max(std::min(timeUntilNextPingCheck,RR->sw->doTimerTasks(now)),(unsigned long)ZT_CORE_TIMER_TASK_GRANULARITY); } catch ( ... ) { - return ZT1_RESULT_FATAL_ERROR_INTERNAL; + return ZT_RESULT_FATAL_ERROR_INTERNAL; } - return ZT1_RESULT_OK; + return ZT_RESULT_OK; } -ZT1_ResultCode Node::join(uint64_t nwid) +ZT_ResultCode Node::join(uint64_t nwid) { Mutex::Lock _l(_networks_m); SharedPtr nw = _network(nwid); if(!nw) _networks.push_back(std::pair< uint64_t,SharedPtr >(nwid,SharedPtr(new Network(RR,nwid)))); std::sort(_networks.begin(),_networks.end()); // will sort by nwid since it's the first in a pair<> - return ZT1_RESULT_OK; + return ZT_RESULT_OK; } -ZT1_ResultCode Node::leave(uint64_t nwid) +ZT_ResultCode Node::leave(uint64_t nwid) { std::vector< std::pair< uint64_t,SharedPtr > > newn; Mutex::Lock _l(_networks_m); @@ -324,25 +326,25 @@ ZT1_ResultCode Node::leave(uint64_t nwid) else n->second->destroy(); } _networks.swap(newn); - return ZT1_RESULT_OK; + return ZT_RESULT_OK; } -ZT1_ResultCode Node::multicastSubscribe(uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi) +ZT_ResultCode Node::multicastSubscribe(uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi) { SharedPtr nw(this->network(nwid)); if (nw) { nw->multicastSubscribe(MulticastGroup(MAC(multicastGroup),(uint32_t)(multicastAdi & 0xffffffff))); - return ZT1_RESULT_OK; - } else return ZT1_RESULT_ERROR_NETWORK_NOT_FOUND; + return ZT_RESULT_OK; + } else return ZT_RESULT_ERROR_NETWORK_NOT_FOUND; } -ZT1_ResultCode Node::multicastUnsubscribe(uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi) +ZT_ResultCode Node::multicastUnsubscribe(uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi) { SharedPtr nw(this->network(nwid)); if (nw) { nw->multicastUnsubscribe(MulticastGroup(MAC(multicastGroup),(uint32_t)(multicastAdi & 0xffffffff))); - return ZT1_RESULT_OK; - } else return ZT1_RESULT_ERROR_NETWORK_NOT_FOUND; + return ZT_RESULT_OK; + } else return ZT_RESULT_ERROR_NETWORK_NOT_FOUND; } uint64_t Node::address() const @@ -350,7 +352,7 @@ uint64_t Node::address() const return RR->identity.address().toInt(); } -void Node::status(ZT1_NodeStatus *status) const +void Node::status(ZT_NodeStatus *status) const { status->address = RR->identity.address().toInt(); status->publicIdentity = RR->publicIdentityStr.c_str(); @@ -358,20 +360,20 @@ void Node::status(ZT1_NodeStatus *status) const status->online = _online ? 1 : 0; } -ZT1_PeerList *Node::peers() const +ZT_PeerList *Node::peers() const { std::vector< std::pair< Address,SharedPtr > > peers(RR->topology->allPeers()); std::sort(peers.begin(),peers.end()); - char *buf = (char *)::malloc(sizeof(ZT1_PeerList) + (sizeof(ZT1_Peer) * peers.size())); + char *buf = (char *)::malloc(sizeof(ZT_PeerList) + (sizeof(ZT_Peer) * peers.size())); if (!buf) - return (ZT1_PeerList *)0; - ZT1_PeerList *pl = (ZT1_PeerList *)buf; - pl->peers = (ZT1_Peer *)(buf + sizeof(ZT1_PeerList)); + return (ZT_PeerList *)0; + ZT_PeerList *pl = (ZT_PeerList *)buf; + pl->peers = (ZT_Peer *)(buf + sizeof(ZT_PeerList)); pl->peerCount = 0; for(std::vector< std::pair< Address,SharedPtr > >::iterator pi(peers.begin());pi!=peers.end();++pi) { - ZT1_Peer *p = &(pl->peers[pl->peerCount++]); + ZT_Peer *p = &(pl->peers[pl->peerCount++]); p->address = pi->second->address().toInt(); p->lastUnicastFrame = pi->second->lastUnicastFrame(); p->lastMulticastFrame = pi->second->lastMulticastFrame(); @@ -385,7 +387,7 @@ ZT1_PeerList *Node::peers() const p->versionRev = -1; } p->latency = pi->second->latency(); - p->role = RR->topology->isRoot(pi->second->identity()) ? ZT1_PEER_ROLE_ROOT : ZT1_PEER_ROLE_LEAF; + p->role = RR->topology->isRoot(pi->second->identity()) ? ZT_PEER_ROLE_ROOT : ZT_PEER_ROLE_LEAF; std::vector paths(pi->second->paths()); RemotePath *bestPath = pi->second->getBestPath(_now); @@ -404,27 +406,27 @@ ZT1_PeerList *Node::peers() const return pl; } -ZT1_VirtualNetworkConfig *Node::networkConfig(uint64_t nwid) const +ZT_VirtualNetworkConfig *Node::networkConfig(uint64_t nwid) const { Mutex::Lock _l(_networks_m); SharedPtr nw = _network(nwid); if(nw) { - ZT1_VirtualNetworkConfig *nc = (ZT1_VirtualNetworkConfig *)::malloc(sizeof(ZT1_VirtualNetworkConfig)); + ZT_VirtualNetworkConfig *nc = (ZT_VirtualNetworkConfig *)::malloc(sizeof(ZT_VirtualNetworkConfig)); nw->externalConfig(nc); return nc; } - return (ZT1_VirtualNetworkConfig *)0; + return (ZT_VirtualNetworkConfig *)0; } -ZT1_VirtualNetworkList *Node::networks() const +ZT_VirtualNetworkList *Node::networks() const { Mutex::Lock _l(_networks_m); - char *buf = (char *)::malloc(sizeof(ZT1_VirtualNetworkList) + (sizeof(ZT1_VirtualNetworkConfig) * _networks.size())); + char *buf = (char *)::malloc(sizeof(ZT_VirtualNetworkList) + (sizeof(ZT_VirtualNetworkConfig) * _networks.size())); if (!buf) - return (ZT1_VirtualNetworkList *)0; - ZT1_VirtualNetworkList *nl = (ZT1_VirtualNetworkList *)buf; - nl->networks = (ZT1_VirtualNetworkConfig *)(buf + sizeof(ZT1_VirtualNetworkList)); + return (ZT_VirtualNetworkList *)0; + ZT_VirtualNetworkList *nl = (ZT_VirtualNetworkList *)buf; + nl->networks = (ZT_VirtualNetworkConfig *)(buf + sizeof(ZT_VirtualNetworkList)); nl->networkCount = 0; for(std::vector< std::pair< uint64_t,SharedPtr > >::const_iterator n(_networks.begin());n!=_networks.end();++n) @@ -439,7 +441,7 @@ void Node::freeQueryResult(void *qr) ::free(qr); } -int Node::addLocalInterfaceAddress(const struct sockaddr_storage *addr,int metric,ZT1_LocalInterfaceAddressTrust trust) +int Node::addLocalInterfaceAddress(const struct sockaddr_storage *addr,int metric,ZT_LocalInterfaceAddressTrust trust) { if (Path::isAddressValidForPath(*(reinterpret_cast(addr)))) { Mutex::Lock _l(_directPaths_m); @@ -472,7 +474,7 @@ std::string Node::dataStoreGet(const char *name) std::string r; unsigned long olen = 0; do { - long n = _dataStoreGetFunction(reinterpret_cast(this),_uPtr,name,buf,sizeof(buf),(unsigned long)r.length(),&olen); + long n = _dataStoreGetFunction(reinterpret_cast(this),_uPtr,name,buf,sizeof(buf),(unsigned long)r.length(),&olen); if (n <= 0) return std::string(); r.append(buf,n); @@ -486,7 +488,7 @@ void Node::postNewerVersionIfNewer(unsigned int major,unsigned int minor,unsigne _newestVersionSeen[0] = major; _newestVersionSeen[1] = minor; _newestVersionSeen[2] = rev; - this->postEvent(ZT1_EVENT_SAW_MORE_RECENT_VERSION,(const void *)_newestVersionSeen); + this->postEvent(ZT_EVENT_SAW_MORE_RECENT_VERSION,(const void *)_newestVersionSeen); } } @@ -519,7 +521,7 @@ void Node::postTrace(const char *module,unsigned int line,const char *fmt,...) tmp2[sizeof(tmp2)-1] = (char)0; Utils::snprintf(tmp1,sizeof(tmp1),"[%s] %s:%u %s",nowstr,module,line,tmp2); - postEvent(ZT1_EVENT_TRACE,tmp1); + postEvent(ZT_EVENT_TRACE,tmp1); } #endif // ZT_TRACE @@ -539,59 +541,59 @@ uint64_t Node::prng() extern "C" { -enum ZT1_ResultCode ZT1_Node_new( - ZT1_Node **node, +enum ZT_ResultCode ZT_Node_new( + ZT_Node **node, void *uptr, uint64_t now, - ZT1_DataStoreGetFunction dataStoreGetFunction, - ZT1_DataStorePutFunction dataStorePutFunction, - ZT1_WirePacketSendFunction wirePacketSendFunction, - ZT1_VirtualNetworkFrameFunction virtualNetworkFrameFunction, - ZT1_VirtualNetworkConfigFunction virtualNetworkConfigFunction, - ZT1_EventCallback eventCallback, + ZT_DataStoreGetFunction dataStoreGetFunction, + ZT_DataStorePutFunction dataStorePutFunction, + ZT_WirePacketSendFunction wirePacketSendFunction, + ZT_VirtualNetworkFrameFunction virtualNetworkFrameFunction, + ZT_VirtualNetworkConfigFunction virtualNetworkConfigFunction, + ZT_EventCallback eventCallback, const char *overrideRootTopology) { - *node = (ZT1_Node *)0; + *node = (ZT_Node *)0; try { - *node = reinterpret_cast(new ZeroTier::Node(now,uptr,dataStoreGetFunction,dataStorePutFunction,wirePacketSendFunction,virtualNetworkFrameFunction,virtualNetworkConfigFunction,eventCallback,overrideRootTopology)); - return ZT1_RESULT_OK; + *node = reinterpret_cast(new ZeroTier::Node(now,uptr,dataStoreGetFunction,dataStorePutFunction,wirePacketSendFunction,virtualNetworkFrameFunction,virtualNetworkConfigFunction,eventCallback,overrideRootTopology)); + return ZT_RESULT_OK; } catch (std::bad_alloc &exc) { - return ZT1_RESULT_FATAL_ERROR_OUT_OF_MEMORY; + return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY; } catch (std::runtime_error &exc) { - return ZT1_RESULT_FATAL_ERROR_DATA_STORE_FAILED; + return ZT_RESULT_FATAL_ERROR_DATA_STORE_FAILED; } catch ( ... ) { - return ZT1_RESULT_FATAL_ERROR_INTERNAL; + return ZT_RESULT_FATAL_ERROR_INTERNAL; } } -void ZT1_Node_delete(ZT1_Node *node) +void ZT_Node_delete(ZT_Node *node) { try { delete (reinterpret_cast(node)); } catch ( ... ) {} } -enum ZT1_ResultCode ZT1_Node_processWirePacket( - ZT1_Node *node, +enum ZT_ResultCode ZT_Node_processWirePacket( + ZT_Node *node, uint64_t now, - int localInterfaceId, + const struct sockaddr_storage *localAddress, const struct sockaddr_storage *remoteAddress, const void *packetData, unsigned int packetLength, volatile uint64_t *nextBackgroundTaskDeadline) { try { - return reinterpret_cast(node)->processWirePacket(now,localInterfaceId,remoteAddress,packetData,packetLength,nextBackgroundTaskDeadline); + return reinterpret_cast(node)->processWirePacket(now,localAddress,remoteAddress,packetData,packetLength,nextBackgroundTaskDeadline); } catch (std::bad_alloc &exc) { - return ZT1_RESULT_FATAL_ERROR_OUT_OF_MEMORY; + return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY; } catch ( ... ) { - reinterpret_cast(node)->postEvent(ZT1_EVENT_INVALID_PACKET,(const void *)remoteAddress); - return ZT1_RESULT_OK; + reinterpret_cast(node)->postEvent(ZT_EVENT_INVALID_PACKET,(const void *)remoteAddress); + return ZT_RESULT_OK; } } -enum ZT1_ResultCode ZT1_Node_processVirtualNetworkFrame( - ZT1_Node *node, +enum ZT_ResultCode ZT_Node_processVirtualNetworkFrame( + ZT_Node *node, uint64_t now, uint64_t nwid, uint64_t sourceMac, @@ -605,121 +607,121 @@ enum ZT1_ResultCode ZT1_Node_processVirtualNetworkFrame( try { return reinterpret_cast(node)->processVirtualNetworkFrame(now,nwid,sourceMac,destMac,etherType,vlanId,frameData,frameLength,nextBackgroundTaskDeadline); } catch (std::bad_alloc &exc) { - return ZT1_RESULT_FATAL_ERROR_OUT_OF_MEMORY; + return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY; } catch ( ... ) { - return ZT1_RESULT_FATAL_ERROR_INTERNAL; + return ZT_RESULT_FATAL_ERROR_INTERNAL; } } -enum ZT1_ResultCode ZT1_Node_processBackgroundTasks(ZT1_Node *node,uint64_t now,volatile uint64_t *nextBackgroundTaskDeadline) +enum ZT_ResultCode ZT_Node_processBackgroundTasks(ZT_Node *node,uint64_t now,volatile uint64_t *nextBackgroundTaskDeadline) { try { return reinterpret_cast(node)->processBackgroundTasks(now,nextBackgroundTaskDeadline); } catch (std::bad_alloc &exc) { - return ZT1_RESULT_FATAL_ERROR_OUT_OF_MEMORY; + return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY; } catch ( ... ) { - return ZT1_RESULT_FATAL_ERROR_INTERNAL; + return ZT_RESULT_FATAL_ERROR_INTERNAL; } } -enum ZT1_ResultCode ZT1_Node_join(ZT1_Node *node,uint64_t nwid) +enum ZT_ResultCode ZT_Node_join(ZT_Node *node,uint64_t nwid) { try { return reinterpret_cast(node)->join(nwid); } catch (std::bad_alloc &exc) { - return ZT1_RESULT_FATAL_ERROR_OUT_OF_MEMORY; + return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY; } catch ( ... ) { - return ZT1_RESULT_FATAL_ERROR_INTERNAL; + return ZT_RESULT_FATAL_ERROR_INTERNAL; } } -enum ZT1_ResultCode ZT1_Node_leave(ZT1_Node *node,uint64_t nwid) +enum ZT_ResultCode ZT_Node_leave(ZT_Node *node,uint64_t nwid) { try { return reinterpret_cast(node)->leave(nwid); } catch (std::bad_alloc &exc) { - return ZT1_RESULT_FATAL_ERROR_OUT_OF_MEMORY; + return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY; } catch ( ... ) { - return ZT1_RESULT_FATAL_ERROR_INTERNAL; + return ZT_RESULT_FATAL_ERROR_INTERNAL; } } -enum ZT1_ResultCode ZT1_Node_multicastSubscribe(ZT1_Node *node,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi) +enum ZT_ResultCode ZT_Node_multicastSubscribe(ZT_Node *node,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi) { try { return reinterpret_cast(node)->multicastSubscribe(nwid,multicastGroup,multicastAdi); } catch (std::bad_alloc &exc) { - return ZT1_RESULT_FATAL_ERROR_OUT_OF_MEMORY; + return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY; } catch ( ... ) { - return ZT1_RESULT_FATAL_ERROR_INTERNAL; + return ZT_RESULT_FATAL_ERROR_INTERNAL; } } -enum ZT1_ResultCode ZT1_Node_multicastUnsubscribe(ZT1_Node *node,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi) +enum ZT_ResultCode ZT_Node_multicastUnsubscribe(ZT_Node *node,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi) { try { return reinterpret_cast(node)->multicastUnsubscribe(nwid,multicastGroup,multicastAdi); } catch (std::bad_alloc &exc) { - return ZT1_RESULT_FATAL_ERROR_OUT_OF_MEMORY; + return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY; } catch ( ... ) { - return ZT1_RESULT_FATAL_ERROR_INTERNAL; + return ZT_RESULT_FATAL_ERROR_INTERNAL; } } -uint64_t ZT1_Node_address(ZT1_Node *node) +uint64_t ZT_Node_address(ZT_Node *node) { return reinterpret_cast(node)->address(); } -void ZT1_Node_status(ZT1_Node *node,ZT1_NodeStatus *status) +void ZT_Node_status(ZT_Node *node,ZT_NodeStatus *status) { try { reinterpret_cast(node)->status(status); } catch ( ... ) {} } -ZT1_PeerList *ZT1_Node_peers(ZT1_Node *node) +ZT_PeerList *ZT_Node_peers(ZT_Node *node) { try { return reinterpret_cast(node)->peers(); } catch ( ... ) { - return (ZT1_PeerList *)0; + return (ZT_PeerList *)0; } } -ZT1_VirtualNetworkConfig *ZT1_Node_networkConfig(ZT1_Node *node,uint64_t nwid) +ZT_VirtualNetworkConfig *ZT_Node_networkConfig(ZT_Node *node,uint64_t nwid) { try { return reinterpret_cast(node)->networkConfig(nwid); } catch ( ... ) { - return (ZT1_VirtualNetworkConfig *)0; + return (ZT_VirtualNetworkConfig *)0; } } -ZT1_VirtualNetworkList *ZT1_Node_networks(ZT1_Node *node) +ZT_VirtualNetworkList *ZT_Node_networks(ZT_Node *node) { try { return reinterpret_cast(node)->networks(); } catch ( ... ) { - return (ZT1_VirtualNetworkList *)0; + return (ZT_VirtualNetworkList *)0; } } -void ZT1_Node_freeQueryResult(ZT1_Node *node,void *qr) +void ZT_Node_freeQueryResult(ZT_Node *node,void *qr) { try { reinterpret_cast(node)->freeQueryResult(qr); } catch ( ... ) {} } -void ZT1_Node_setNetconfMaster(ZT1_Node *node,void *networkControllerInstance) +void ZT_Node_setNetconfMaster(ZT_Node *node,void *networkControllerInstance) { try { reinterpret_cast(node)->setNetconfMaster(networkControllerInstance); } catch ( ... ) {} } -int ZT1_Node_addLocalInterfaceAddress(ZT1_Node *node,const struct sockaddr_storage *addr,int metric,ZT1_LocalInterfaceAddressTrust trust) +int ZT_Node_addLocalInterfaceAddress(ZT_Node *node,const struct sockaddr_storage *addr,int metric,ZT_LocalInterfaceAddressTrust trust) { try { return reinterpret_cast(node)->addLocalInterfaceAddress(addr,metric,trust); @@ -728,21 +730,21 @@ int ZT1_Node_addLocalInterfaceAddress(ZT1_Node *node,const struct sockaddr_stora } } -void ZT1_Node_clearLocalInterfaceAddresses(ZT1_Node *node) +void ZT_Node_clearLocalInterfaceAddresses(ZT_Node *node) { try { reinterpret_cast(node)->clearLocalInterfaceAddresses(); } catch ( ... ) {} } -void ZT1_version(int *major,int *minor,int *revision,unsigned long *featureFlags) +void ZT_version(int *major,int *minor,int *revision,unsigned long *featureFlags) { if (major) *major = ZEROTIER_ONE_VERSION_MAJOR; if (minor) *minor = ZEROTIER_ONE_VERSION_MINOR; if (revision) *revision = ZEROTIER_ONE_VERSION_REVISION; if (featureFlags) { *featureFlags = ( - ZT1_FEATURE_FLAG_THREAD_SAFE + ZT_FEATURE_FLAG_THREAD_SAFE ); } } diff --git a/node/Node.hpp b/node/Node.hpp index 0e614e5a..b81c1943 100644 --- a/node/Node.hpp +++ b/node/Node.hpp @@ -58,7 +58,7 @@ namespace ZeroTier { /** * Implementation of Node object as defined in CAPI * - * The pointer returned by ZT1_Node_new() is an instance of this class. + * The pointer returned by ZT_Node_new() is an instance of this class. */ class Node { @@ -66,26 +66,26 @@ public: Node( uint64_t now, void *uptr, - ZT1_DataStoreGetFunction dataStoreGetFunction, - ZT1_DataStorePutFunction dataStorePutFunction, - ZT1_WirePacketSendFunction wirePacketSendFunction, - ZT1_VirtualNetworkFrameFunction virtualNetworkFrameFunction, - ZT1_VirtualNetworkConfigFunction virtualNetworkConfigFunction, - ZT1_EventCallback eventCallback, + ZT_DataStoreGetFunction dataStoreGetFunction, + ZT_DataStorePutFunction dataStorePutFunction, + ZT_WirePacketSendFunction wirePacketSendFunction, + ZT_VirtualNetworkFrameFunction virtualNetworkFrameFunction, + ZT_VirtualNetworkConfigFunction virtualNetworkConfigFunction, + ZT_EventCallback eventCallback, const char *overrideRootTopology); ~Node(); // Public API Functions ---------------------------------------------------- - ZT1_ResultCode processWirePacket( + ZT_ResultCode processWirePacket( uint64_t now, - int localInterfaceId, + const struct sockaddr_storage *localAddress, const struct sockaddr_storage *remoteAddress, const void *packetData, unsigned int packetLength, volatile uint64_t *nextBackgroundTaskDeadline); - ZT1_ResultCode processVirtualNetworkFrame( + ZT_ResultCode processVirtualNetworkFrame( uint64_t now, uint64_t nwid, uint64_t sourceMac, @@ -95,18 +95,18 @@ public: const void *frameData, unsigned int frameLength, volatile uint64_t *nextBackgroundTaskDeadline); - ZT1_ResultCode processBackgroundTasks(uint64_t now,volatile uint64_t *nextBackgroundTaskDeadline); - ZT1_ResultCode join(uint64_t nwid); - ZT1_ResultCode leave(uint64_t nwid); - ZT1_ResultCode multicastSubscribe(uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi); - ZT1_ResultCode multicastUnsubscribe(uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi); + ZT_ResultCode processBackgroundTasks(uint64_t now,volatile uint64_t *nextBackgroundTaskDeadline); + ZT_ResultCode join(uint64_t nwid); + ZT_ResultCode leave(uint64_t nwid); + ZT_ResultCode multicastSubscribe(uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi); + ZT_ResultCode multicastUnsubscribe(uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi); uint64_t address() const; - void status(ZT1_NodeStatus *status) const; - ZT1_PeerList *peers() const; - ZT1_VirtualNetworkConfig *networkConfig(uint64_t nwid) const; - ZT1_VirtualNetworkList *networks() const; + void status(ZT_NodeStatus *status) const; + ZT_PeerList *peers() const; + ZT_VirtualNetworkConfig *networkConfig(uint64_t nwid) const; + ZT_VirtualNetworkList *networks() const; void freeQueryResult(void *qr); - int addLocalInterfaceAddress(const struct sockaddr_storage *addr,int metric,ZT1_LocalInterfaceAddressTrust trust); + int addLocalInterfaceAddress(const struct sockaddr_storage *addr,int metric,ZT_LocalInterfaceAddressTrust trust); void clearLocalInterfaceAddresses(); void setNetconfMaster(void *networkControllerInstance); @@ -120,18 +120,18 @@ public: /** * Enqueue a ZeroTier message to be sent * - * @param localInterfaceId Local interface ID, -1 for unspecified/random + * @param localAddress Local address * @param addr Destination address * @param data Packet data * @param len Packet length * @return True if packet appears to have been sent */ - inline bool putPacket(int localInterfaceId,const InetAddress &addr,const void *data,unsigned int len) + inline bool putPacket(const InetAddress &localAddress,const InetAddress &addr,const void *data,unsigned int len) { return (_wirePacketSendFunction( - reinterpret_cast(this), + reinterpret_cast(this), _uPtr, - localInterfaceId, + reinterpret_cast(&localAddress), reinterpret_cast(&addr), data, len) == 0); @@ -151,7 +151,7 @@ public: inline void putFrame(uint64_t nwid,const MAC &source,const MAC &dest,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len) { _virtualNetworkFrameFunction( - reinterpret_cast(this), + reinterpret_cast(this), _uPtr, nwid, source.toInt(), @@ -187,9 +187,9 @@ public: return _directPaths; } - inline bool dataStorePut(const char *name,const void *data,unsigned int len,bool secure) { return (_dataStorePutFunction(reinterpret_cast(this),_uPtr,name,data,len,(int)secure) == 0); } + inline bool dataStorePut(const char *name,const void *data,unsigned int len,bool secure) { return (_dataStorePutFunction(reinterpret_cast(this),_uPtr,name,data,len,(int)secure) == 0); } inline bool dataStorePut(const char *name,const std::string &data,bool secure) { return dataStorePut(name,(const void *)data.data(),(unsigned int)data.length(),secure); } - inline void dataStoreDelete(const char *name) { _dataStorePutFunction(reinterpret_cast(this),_uPtr,name,(const void *)0,0,0); } + inline void dataStoreDelete(const char *name) { _dataStorePutFunction(reinterpret_cast(this),_uPtr,name,(const void *)0,0,0); } std::string dataStoreGet(const char *name); /** @@ -198,7 +198,7 @@ public: * @param ev Event type * @param md Meta-data (default: NULL/none) */ - inline void postEvent(ZT1_Event ev,const void *md = (const void *)0) { _eventCallback(reinterpret_cast(this),_uPtr,ev,md); } + inline void postEvent(ZT_Event ev,const void *md = (const void *)0) { _eventCallback(reinterpret_cast(this),_uPtr,ev,md); } /** * Update virtual network port configuration @@ -207,7 +207,7 @@ public: * @param op Configuration operation * @param nc Network configuration */ - inline int configureVirtualNetworkPort(uint64_t nwid,ZT1_VirtualNetworkConfigOperation op,const ZT1_VirtualNetworkConfig *nc) { return _virtualNetworkConfigFunction(reinterpret_cast(this),_uPtr,nwid,op,nc); } + inline int configureVirtualNetworkPort(uint64_t nwid,ZT_VirtualNetworkConfigOperation op,const ZT_VirtualNetworkConfig *nc) { return _virtualNetworkConfigFunction(reinterpret_cast(this),_uPtr,nwid,op,nc); } /** * @return True if we appear to be online @@ -244,12 +244,12 @@ private: void *_uPtr; // _uptr (lower case) is reserved in Visual Studio :P - ZT1_DataStoreGetFunction _dataStoreGetFunction; - ZT1_DataStorePutFunction _dataStorePutFunction; - ZT1_WirePacketSendFunction _wirePacketSendFunction; - ZT1_VirtualNetworkFrameFunction _virtualNetworkFrameFunction; - ZT1_VirtualNetworkConfigFunction _virtualNetworkConfigFunction; - ZT1_EventCallback _eventCallback; + ZT_DataStoreGetFunction _dataStoreGetFunction; + ZT_DataStorePutFunction _dataStorePutFunction; + ZT_WirePacketSendFunction _wirePacketSendFunction; + ZT_VirtualNetworkFrameFunction _virtualNetworkFrameFunction; + ZT_VirtualNetworkConfigFunction _virtualNetworkConfigFunction; + ZT_EventCallback _eventCallback; std::vector< std::pair< uint64_t, SharedPtr > > _networks; Mutex _networks_m; diff --git a/node/Path.hpp b/node/Path.hpp index 1f947911..3fa06b58 100644 --- a/node/Path.hpp +++ b/node/Path.hpp @@ -57,7 +57,7 @@ public: * Nearly all paths will be normal trust. The other levels are for high * performance local SDN use only. * - * These values MUST match ZT1_LocalInterfaceAddressTrust in ZeroTierOne.h + * These values MUST match ZT_LocalInterfaceAddressTrust in ZeroTierOne.h */ enum Trust { diff --git a/node/Peer.cpp b/node/Peer.cpp index e966a9bf..48b77c85 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -64,7 +64,7 @@ Peer::Peer(const Identity &myIdentity,const Identity &peerIdentity) void Peer::received( const RuntimeEnvironment *RR, - int localInterfaceId, + const InetAddress &localAddr, const InetAddress &remoteAddr, unsigned int hops, uint64_t packetId, @@ -82,7 +82,7 @@ void Peer::received( { unsigned int np = _numPaths; for(unsigned int p=0;preceived(now); _numPaths = np; pathIsConfirmed = true; @@ -120,7 +120,7 @@ void Peer::received( if ((now - _lastPathConfirmationSent) >= ZT_MIN_PATH_CONFIRMATION_INTERVAL) { _lastPathConfirmationSent = now; TRACE("got %s via unknown path %s(%s), confirming...",Packet::verbString(verb),_id.address().toString().c_str(),remoteAddr.toString().c_str()); - attemptToContactAt(RR,localInterfaceId,remoteAddr,now); + attemptToContactAt(RR,localAddr,remoteAddr,now); } } } @@ -142,7 +142,7 @@ void Peer::received( for(std::vector::const_iterator mg(mgs.begin());mg!=mgs.end();++mg) { if ((outp.size() + 18) > ZT_UDP_DEFAULT_PAYLOAD_MTU) { outp.armor(_key,true); - RR->node->putPacket(localInterfaceId,remoteAddr,outp.data(),outp.size()); + RR->node->putPacket(localAddr,remoteAddr,outp.data(),outp.size()); outp.reset(_id.address(),RR->identity.address(),Packet::VERB_MULTICAST_LIKE); } @@ -155,7 +155,7 @@ void Peer::received( } if (outp.size() > ZT_PROTO_MIN_PACKET_LENGTH) { outp.armor(_key,true); - RR->node->putPacket(localInterfaceId,remoteAddr,outp.data(),outp.size()); + RR->node->putPacket(localAddr,remoteAddr,outp.data(),outp.size()); } } } @@ -181,7 +181,7 @@ RemotePath *Peer::getBestPath(uint64_t now) return bestPath; } -void Peer::attemptToContactAt(const RuntimeEnvironment *RR,int localInterfaceId,const InetAddress &atAddress,uint64_t now) +void Peer::attemptToContactAt(const RuntimeEnvironment *RR,const InetAddress &localAddr,const InetAddress &atAddress,uint64_t now) { Packet outp(_id.address(),RR->identity.address(),Packet::VERB_HELLO); outp.append((unsigned char)ZT_PROTO_VERSION); @@ -209,7 +209,7 @@ void Peer::attemptToContactAt(const RuntimeEnvironment *RR,int localInterfaceId, } outp.armor(_key,false); // HELLO is sent in the clear - RR->node->putPacket(localInterfaceId,atAddress,outp.data(),outp.size()); + RR->node->putPacket(localAddr,atAddress,outp.data(),outp.size()); } void Peer::doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now) @@ -218,12 +218,12 @@ void Peer::doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now) if (bestPath) { if ((now - bestPath->lastReceived()) >= ZT_PEER_DIRECT_PING_DELAY) { TRACE("PING %s(%s)",_id.address().toString().c_str(),bestPath->address().toString().c_str()); - attemptToContactAt(RR,bestPath->localInterfaceId(),bestPath->address(),now); + attemptToContactAt(RR,bestPath->localAddress(),bestPath->address(),now); bestPath->sent(now); } else if (((now - bestPath->lastSend()) >= ZT_NAT_KEEPALIVE_DELAY)&&(!bestPath->reliable())) { _natKeepaliveBuf += (uint32_t)((now * 0x9e3779b1) >> 1); // tumble this around to send constantly varying (meaningless) payloads TRACE("NAT keepalive %s(%s)",_id.address().toString().c_str(),bestPath->address().toString().c_str()); - RR->node->putPacket(bestPath->localInterfaceId(),bestPath->address(),&_natKeepaliveBuf,sizeof(_natKeepaliveBuf)); + RR->node->putPacket(bestPath->localAddress(),bestPath->address(),&_natKeepaliveBuf,sizeof(_natKeepaliveBuf)); bestPath->sent(now); } } @@ -311,13 +311,13 @@ void Peer::addPath(const RemotePath &newp) } RemotePath *slot = (RemotePath *)0; - if (np < ZT1_MAX_PEER_NETWORK_PATHS) { + if (np < ZT_MAX_PEER_NETWORK_PATHS) { // Add new path slot = &(_paths[np++]); } else { // Replace oldest non-fixed path uint64_t slotLRmin = 0xffffffffffffffffULL; - for(unsigned int p=0;pnode->putPacket(_localInterfaceId,address(),data,len)) { + if (RR->node->putPacket(_localAddress,address(),data,len)) { sent(now); RR->antiRec->logOutgoingZT(data,len); return true; @@ -138,7 +138,7 @@ public: private: uint64_t _lastSend; uint64_t _lastReceived; - int _localInterfaceId; + InetAddress _localAddress; bool _fixed; }; diff --git a/node/Switch.cpp b/node/Switch.cpp index 0de94400..ecae9b76 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -78,11 +78,8 @@ Switch::~Switch() { } -void Switch::onRemotePacket(int localInterfaceId,const InetAddress &fromAddr,const void *data,unsigned int len) +void Switch::onRemotePacket(const InetAddress &localAddr,const InetAddress &fromAddr,const void *data,unsigned int len) { - if (localInterfaceId < 0) - localInterfaceId = 0; - try { if (len == 13) { /* LEGACY: before VERB_PUSH_DIRECT_PATHS, peers used broadcast @@ -99,14 +96,14 @@ void Switch::onRemotePacket(int localInterfaceId,const InetAddress &fromAddr,con _lastBeaconResponse = now; Packet outp(peer->address(),RR->identity.address(),Packet::VERB_NOP); outp.armor(peer->key(),false); - RR->node->putPacket(localInterfaceId,fromAddr,outp.data(),outp.size()); + RR->node->putPacket(localAddr,fromAddr,outp.data(),outp.size()); } } } else if (len > ZT_PROTO_MIN_FRAGMENT_LENGTH) { if (((const unsigned char *)data)[ZT_PACKET_FRAGMENT_IDX_FRAGMENT_INDICATOR] == ZT_PACKET_FRAGMENT_INDICATOR) { - _handleRemotePacketFragment(localInterfaceId,fromAddr,data,len); + _handleRemotePacketFragment(localAddr,fromAddr,data,len); } else if (len >= ZT_PROTO_MIN_PACKET_LENGTH) { - _handleRemotePacketHead(localInterfaceId,fromAddr,data,len); + _handleRemotePacketHead(localAddr,fromAddr,data,len); } } } catch (std::exception &ex) { @@ -379,14 +376,14 @@ bool Switch::unite(const Address &p1,const Address &p2,bool force) return true; } -void Switch::rendezvous(const SharedPtr &peer,int localInterfaceId,const InetAddress &atAddr) +void Switch::rendezvous(const SharedPtr &peer,const InetAddress &localAddr,const InetAddress &atAddr) { TRACE("sending NAT-t message to %s(%s)",peer->address().toString().c_str(),atAddr.toString().c_str()); const uint64_t now = RR->node->now(); - peer->attemptToContactAt(RR,localInterfaceId,atAddr,now); + peer->attemptToContactAt(RR,localAddr,atAddr,now); { Mutex::Lock _l(_contactQueue_m); - _contactQueue.push_back(ContactQueueEntry(peer,now + ZT_NAT_T_TACTICAL_ESCALATION_DELAY,localInterfaceId,atAddr)); + _contactQueue.push_back(ContactQueueEntry(peer,now + ZT_NAT_T_TACTICAL_ESCALATION_DELAY,localAddr,atAddr)); } } @@ -456,14 +453,14 @@ unsigned long Switch::doTimerTasks(uint64_t now) } else { if (qi->strategyIteration == 0) { // First strategy: send packet directly to destination - qi->peer->attemptToContactAt(RR,qi->localInterfaceId,qi->inaddr,now); + qi->peer->attemptToContactAt(RR,qi->localAddr,qi->inaddr,now); } else if (qi->strategyIteration <= 4) { // Strategies 1-4: try escalating ports for symmetric NATs that remap sequentially InetAddress tmpaddr(qi->inaddr); int p = (int)qi->inaddr.port() + qi->strategyIteration; if (p < 0xffff) { tmpaddr.setPort((unsigned int)p); - qi->peer->attemptToContactAt(RR,qi->localInterfaceId,tmpaddr,now); + qi->peer->attemptToContactAt(RR,qi->localAddr,tmpaddr,now); } else qi->strategyIteration = 5; } else { // All strategies tried, expire entry @@ -554,7 +551,7 @@ unsigned long Switch::doTimerTasks(uint64_t now) return nextDelay; } -void Switch::_handleRemotePacketFragment(int localInterfaceId,const InetAddress &fromAddr,const void *data,unsigned int len) +void Switch::_handleRemotePacketFragment(const InetAddress &localAddr,const InetAddress &fromAddr,const void *data,unsigned int len) { Packet::Fragment fragment(data,len); Address destination(fragment.destination()); @@ -625,9 +622,9 @@ void Switch::_handleRemotePacketFragment(int localInterfaceId,const InetAddress } } -void Switch::_handleRemotePacketHead(int localInterfaceId,const InetAddress &fromAddr,const void *data,unsigned int len) +void Switch::_handleRemotePacketHead(const InetAddress &localAddr,const InetAddress &fromAddr,const void *data,unsigned int len) { - SharedPtr packet(new IncomingPacket(data,len,localInterfaceId,fromAddr,RR->node->now())); + SharedPtr packet(new IncomingPacket(data,len,localAddr,fromAddr,RR->node->now())); Address source(packet->source()); Address destination(packet->destination()); diff --git a/node/Switch.hpp b/node/Switch.hpp index a8d89f41..3bdc0c47 100644 --- a/node/Switch.hpp +++ b/node/Switch.hpp @@ -79,12 +79,12 @@ public: /** * Called when a packet is received from the real network * - * @param localInterfaceId Local interface ID or -1 for unspecified + * @param localAddr Local interface address * @param fromAddr Internet IP address of origin * @param data Packet data * @param len Packet length */ - void onRemotePacket(int localInterfaceId,const InetAddress &fromAddr,const void *data,unsigned int len); + void onRemotePacket(const InetAddress &localAddr,const InetAddress &fromAddr,const void *data,unsigned int len); /** * Called when a packet comes from a local Ethernet tap @@ -141,10 +141,10 @@ public: * Attempt NAT traversal to peer at a given physical address * * @param peer Peer to contact - * @param localInterfaceId Local interface ID or -1 if unspecified + * @param localAddr Local interface address * @param atAddr Address of peer */ - void rendezvous(const SharedPtr &peer,int localInterfaceId,const InetAddress &atAddr); + void rendezvous(const SharedPtr &peer,const InetAddress &localAddr,const InetAddress &atAddr); /** * Request WHOIS on a given address @@ -181,8 +181,8 @@ public: unsigned long doTimerTasks(uint64_t now); private: - void _handleRemotePacketFragment(int localInterfaceId,const InetAddress &fromAddr,const void *data,unsigned int len); - void _handleRemotePacketHead(int localInterfaceId,const InetAddress &fromAddr,const void *data,unsigned int len); + void _handleRemotePacketFragment(const InetAddress &localAddr,const InetAddress &fromAddr,const void *data,unsigned int len); + void _handleRemotePacketHead(const InetAddress &localAddr,const InetAddress &fromAddr,const void *data,unsigned int len); Address _sendWhoisRequest(const Address &addr,const Address *peersAlreadyConsulted,unsigned int numPeersAlreadyConsulted); bool _trySend(const Packet &packet,bool encrypt,uint64_t nwid); @@ -262,17 +262,17 @@ private: struct ContactQueueEntry { ContactQueueEntry() {} - ContactQueueEntry(const SharedPtr &p,uint64_t ft,int liid,const InetAddress &a) : + ContactQueueEntry(const SharedPtr &p,uint64_t ft,const InetAddress &laddr,const InetAddress &a) : peer(p), fireAtTime(ft), inaddr(a), - localInterfaceId(liid), + localAddr(laddr), strategyIteration(0) {} SharedPtr peer; uint64_t fireAtTime; InetAddress inaddr; - int localInterfaceId; + InetAddress localAddr; unsigned int strategyIteration; }; std::list _contactQueue; diff --git a/node/Topology.cpp b/node/Topology.cpp index c63ed9f4..e931df1e 100644 --- a/node/Topology.cpp +++ b/node/Topology.cpp @@ -62,7 +62,7 @@ void Topology::setRootServers(const std::map< Identity,std::vector if (!p) p = SharedPtr(new Peer(RR->identity,i->first)); for(std::vector::const_iterator j(i->second.begin());j!=i->second.end();++j) - p->addPath(RemotePath(0,*j,true)); + p->addPath(RemotePath(InetAddress(),*j,true)); p->use(now); _rootPeers.push_back(p); } diff --git a/one.cpp b/one.cpp index b96fef72..a4d5190c 100644 --- a/one.cpp +++ b/one.cpp @@ -73,7 +73,7 @@ #include "service/OneService.hpp" -#define ZT1_PID_PATH "zerotier-one.pid" +#define ZT_PID_PATH "zerotier-one.pid" using namespace ZeroTier; @@ -976,7 +976,7 @@ int main(int argc,char **argv) std::string overrideRootTopology; std::string homeDir; - unsigned int port = ZT1_DEFAULT_PORT; + unsigned int port = ZT_DEFAULT_PORT; bool skipRootCheck = false; for(int i=1;istatus) { - case ZT1_NETWORK_STATUS_REQUESTING_CONFIGURATION: nstatus = "REQUESTING_CONFIGURATION"; break; - case ZT1_NETWORK_STATUS_OK: nstatus = "OK"; break; - case ZT1_NETWORK_STATUS_ACCESS_DENIED: nstatus = "ACCESS_DENIED"; break; - case ZT1_NETWORK_STATUS_NOT_FOUND: nstatus = "NOT_FOUND"; break; - case ZT1_NETWORK_STATUS_PORT_ERROR: nstatus = "PORT_ERROR"; break; - case ZT1_NETWORK_STATUS_CLIENT_TOO_OLD: nstatus = "CLIENT_TOO_OLD"; break; + case ZT_NETWORK_STATUS_REQUESTING_CONFIGURATION: nstatus = "REQUESTING_CONFIGURATION"; break; + case ZT_NETWORK_STATUS_OK: nstatus = "OK"; break; + case ZT_NETWORK_STATUS_ACCESS_DENIED: nstatus = "ACCESS_DENIED"; break; + case ZT_NETWORK_STATUS_NOT_FOUND: nstatus = "NOT_FOUND"; break; + case ZT_NETWORK_STATUS_PORT_ERROR: nstatus = "PORT_ERROR"; break; + case ZT_NETWORK_STATUS_CLIENT_TOO_OLD: nstatus = "CLIENT_TOO_OLD"; break; } switch(nc->type) { - case ZT1_NETWORK_TYPE_PRIVATE: ntype = "PRIVATE"; break; - case ZT1_NETWORK_TYPE_PUBLIC: ntype = "PUBLIC"; break; + case ZT_NETWORK_TYPE_PRIVATE: ntype = "PRIVATE"; break; + case ZT_NETWORK_TYPE_PUBLIC: ntype = "PUBLIC"; break; } Utils::snprintf(json,sizeof(json), @@ -162,7 +162,7 @@ static void _jsonAppend(unsigned int depth,std::string &buf,const ZT1_VirtualNet buf.append(json); } -static std::string _jsonEnumerate(unsigned int depth,const ZT1_PeerPhysicalPath *pp,unsigned int count) +static std::string _jsonEnumerate(unsigned int depth,const ZT_PeerPhysicalPath *pp,unsigned int count) { char json[1024]; char prefix[32]; @@ -198,7 +198,7 @@ static std::string _jsonEnumerate(unsigned int depth,const ZT1_PeerPhysicalPath return buf; } -static void _jsonAppend(unsigned int depth,std::string &buf,const ZT1_Peer *peer) +static void _jsonAppend(unsigned int depth,std::string &buf,const ZT_Peer *peer) { char json[1024]; char prefix[32]; @@ -211,9 +211,9 @@ static void _jsonAppend(unsigned int depth,std::string &buf,const ZT1_Peer *peer const char *prole = ""; switch(peer->role) { - case ZT1_PEER_ROLE_LEAF: prole = "LEAF"; break; - case ZT1_PEER_ROLE_RELAY: prole = "RELAY"; break; - case ZT1_PEER_ROLE_ROOT: prole = "ROOT"; break; + case ZT_PEER_ROLE_LEAF: prole = "LEAF"; break; + case ZT_PEER_ROLE_RELAY: prole = "RELAY"; break; + case ZT_PEER_ROLE_ROOT: prole = "ROOT"; break; } Utils::snprintf(json,sizeof(json), @@ -356,7 +356,7 @@ unsigned int ControlPlane::handleRequest( if (ps[0] == "status") { responseContentType = "application/json"; - ZT1_NodeStatus status; + ZT_NodeStatus status; _node->status(&status); Utils::snprintf(json,sizeof(json), "{\n" @@ -386,7 +386,7 @@ unsigned int ControlPlane::handleRequest( responseBody = "{}"; // TODO scode = 200; } else if (ps[0] == "network") { - ZT1_VirtualNetworkList *nws = _node->networks(); + ZT_VirtualNetworkList *nws = _node->networks(); if (nws) { if (ps.size() == 1) { // Return [array] of all networks @@ -415,7 +415,7 @@ unsigned int ControlPlane::handleRequest( _node->freeQueryResult((void *)nws); } else scode = 500; } else if (ps[0] == "peer") { - ZT1_PeerList *pl = _node->peers(); + ZT_PeerList *pl = _node->peers(); if (pl) { if (ps.size() == 1) { // Return [array] of all peers @@ -473,7 +473,7 @@ unsigned int ControlPlane::handleRequest( if (ps.size() == 2) { uint64_t wantnw = Utils::hexStrToU64(ps[1].c_str()); _node->join(wantnw); // does nothing if we are a member - ZT1_VirtualNetworkList *nws = _node->networks(); + ZT_VirtualNetworkList *nws = _node->networks(); if (nws) { for(unsigned long i=0;inetworkCount;++i) { if (nws->networks[i].nwid == wantnw) { @@ -506,7 +506,7 @@ unsigned int ControlPlane::handleRequest( if (ps[0] == "config") { // TODO } else if (ps[0] == "network") { - ZT1_VirtualNetworkList *nws = _node->networks(); + ZT_VirtualNetworkList *nws = _node->networks(); if (nws) { if (ps.size() == 2) { uint64_t wantnw = Utils::hexStrToU64(ps[1].c_str()); diff --git a/service/OneService.cpp b/service/OneService.cpp index 27874518..6e6de8bd 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -118,20 +118,20 @@ namespace ZeroTier { typedef BSDEthernetTap EthernetTap; } #define ZT_TAP_CHECK_MULTICAST_INTERVAL 30000 // Path under ZT1 home for controller database if controller is enabled -#define ZT1_CONTROLLER_DB_PATH "controller.db" +#define ZT_CONTROLLER_DB_PATH "controller.db" // TCP fallback relay host -- geo-distributed using Amazon Route53 geo-aware DNS -#define ZT1_TCP_FALLBACK_RELAY "tcp-fallback.zerotier.com" -#define ZT1_TCP_FALLBACK_RELAY_PORT 443 +#define ZT_TCP_FALLBACK_RELAY "tcp-fallback.zerotier.com" +#define ZT_TCP_FALLBACK_RELAY_PORT 443 // Frequency at which we re-resolve the TCP fallback relay -#define ZT1_TCP_FALLBACK_RERESOLVE_DELAY 86400000 +#define ZT_TCP_FALLBACK_RERESOLVE_DELAY 86400000 // Attempt to engage TCP fallback after this many ms of no reply to packets sent to global-scope IPs -#define ZT1_TCP_FALLBACK_AFTER 60000 +#define ZT_TCP_FALLBACK_AFTER 60000 // How often to check for local interface addresses -#define ZT1_LOCAL_INTERFACE_CHECK_INTERVAL 300000 +#define ZT_LOCAL_INTERFACE_CHECK_INTERVAL 300000 namespace ZeroTier { @@ -340,12 +340,12 @@ static BackgroundSoftwareUpdateChecker backgroundSoftwareUpdateChecker; class OneServiceImpl; -static int SnodeVirtualNetworkConfigFunction(ZT1_Node *node,void *uptr,uint64_t nwid,enum ZT1_VirtualNetworkConfigOperation op,const ZT1_VirtualNetworkConfig *nwconf); -static void SnodeEventCallback(ZT1_Node *node,void *uptr,enum ZT1_Event event,const void *metaData); -static long SnodeDataStoreGetFunction(ZT1_Node *node,void *uptr,const char *name,void *buf,unsigned long bufSize,unsigned long readIndex,unsigned long *totalSize); -static int SnodeDataStorePutFunction(ZT1_Node *node,void *uptr,const char *name,const void *data,unsigned long len,int secure); -static int SnodeWirePacketSendFunction(ZT1_Node *node,void *uptr,int localInterfaceId,const struct sockaddr_storage *addr,const void *data,unsigned int len); -static void SnodeVirtualNetworkFrameFunction(ZT1_Node *node,void *uptr,uint64_t nwid,uint64_t sourceMac,uint64_t destMac,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len); +static int SnodeVirtualNetworkConfigFunction(ZT_Node *node,void *uptr,uint64_t nwid,enum ZT_VirtualNetworkConfigOperation op,const ZT_VirtualNetworkConfig *nwconf); +static void SnodeEventCallback(ZT_Node *node,void *uptr,enum ZT_Event event,const void *metaData); +static long SnodeDataStoreGetFunction(ZT_Node *node,void *uptr,const char *name,void *buf,unsigned long bufSize,unsigned long readIndex,unsigned long *totalSize); +static int SnodeDataStorePutFunction(ZT_Node *node,void *uptr,const char *name,const void *data,unsigned long len,int secure); +static int SnodeWirePacketSendFunction(ZT_Node *node,void *uptr,const struct sockaddr_storage *localAddr,const struct sockaddr_storage *addr,const void *data,unsigned int len); +static void SnodeVirtualNetworkFrameFunction(ZT_Node *node,void *uptr,uint64_t nwid,uint64_t sourceMac,uint64_t destMac,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len); static void StapFrameHandler(void *uptr,uint64_t nwid,const MAC &from,const MAC &to,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len); @@ -396,18 +396,14 @@ struct TcpConnection Mutex writeBuf_m; }; -// Interface IDs -- the uptr for UDP sockets is set to point to one of these -static const int ZT1_INTERFACE_ID_DEFAULT = 0; // default, usually port 9993 -static const int ZT1_INTERFACE_ID_UPNP = 1; // a randomly chosen UDP socket used with uPnP mappings, if enabled - class OneServiceImpl : public OneService { public: OneServiceImpl(const char *hp,unsigned int port,const char *overrideRootTopology) : _homePath((hp) ? hp : "."), - _tcpFallbackResolver(ZT1_TCP_FALLBACK_RELAY), + _tcpFallbackResolver(ZT_TCP_FALLBACK_RELAY), #ifdef ZT_ENABLE_NETWORK_CONTROLLER - _controller((_homePath + ZT_PATH_SEPARATOR_S + ZT1_CONTROLLER_DB_PATH).c_str()), + _controller((_homePath + ZT_PATH_SEPARATOR_S + ZT_CONTROLLER_DB_PATH).c_str()), #endif _phy(this,false,true), _overrideRootTopology((overrideRootTopology) ? overrideRootTopology : ""), @@ -426,9 +422,6 @@ public: #endif _run(true) { - struct sockaddr_in in4; - struct sockaddr_in6 in6; - const int portTrials = (port == 0) ? 256 : 1; // if port is 0, pick random for(int k=0;k(const_cast(&ZT1_INTERFACE_ID_DEFAULT)),131072); + _v4LocalAddress = InetAddress((uint32_t)0,port); + _v4UdpSocket = _phy.udpBind((const struct sockaddr *)&_v4LocalAddress,reinterpret_cast(&_v4LocalAddress),131072); if (_v4UdpSocket) { + struct sockaddr_in in4; + memset(&in4,0,sizeof(in4)); + in4.sin_family = AF_INET; in4.sin_addr.s_addr = Utils::hton((uint32_t)0x7f000001); // right now we just listen for TCP @localhost + in4.sin_port = Utils::hton((uint16_t)port); _v4TcpListenSocket = _phy.tcpListen((const struct sockaddr *)&in4,this); if (_v4TcpListenSocket) { + _v6LocalAddress = InetAddress("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",16,port); + _v6UdpSocket = _phy.udpBind((const struct sockaddr *)&_v6LocalAddress,reinterpret_cast(&_v6LocalAddress),131072); + + struct sockaddr_in6 in6; memset((void *)&in6,0,sizeof(in6)); in6.sin6_family = AF_INET6; in6.sin6_port = in4.sin_port; - - _v6UdpSocket = _phy.udpBind((const struct sockaddr *)&in6,reinterpret_cast(const_cast(&ZT1_INTERFACE_ID_DEFAULT)),131072); - - in6.sin6_addr.s6_addr[15] = 1; // listen for TCP only at localhost + in6.sin6_addr.s6_addr[15] = 1; // IPv6 localhost == ::1 _v6TcpListenSocket = _phy.tcpListen((const struct sockaddr *)&in6,this); _port = port; @@ -484,11 +479,8 @@ public: Utils::getSecureRandom(&randp,sizeof(randp)); unsigned int upnport = 40000 + (randp % 25500); - memset((void *)&in4,0,sizeof(in4)); - in4.sin_family = AF_INET; - in4.sin_port = Utils::hton((uint16_t)upnport); - - _v4UpnpUdpSocket = _phy.udpBind((const struct sockaddr *)&in4,reinterpret_cast(const_cast(&ZT1_INTERFACE_ID_UPNP)),131072); + _v4UpnpLocalAddress = InetAddress(0,upnport); + _v4UpnpUdpSocket = _phy.udpBind((const struct sockaddr *)&_v4UpnpLocalAddress,reinterpret_cast(&_v4UpnpLocalAddress),131072); if (_v4UpnpUdpSocket) { _upnpClient = new UPNPClient(upnport); break; @@ -567,7 +559,7 @@ public: _lastRestart = clockShouldBe; uint64_t lastTapMulticastGroupCheck = 0; uint64_t lastTcpFallbackResolve = 0; - uint64_t lastLocalInterfaceAddressCheck = (OSUtils::now() - ZT1_LOCAL_INTERFACE_CHECK_INTERVAL) + 15000; // do this in 15s to give UPnP time to configure and other things time to settle + uint64_t lastLocalInterfaceAddressCheck = (OSUtils::now() - ZT_LOCAL_INTERFACE_CHECK_INTERVAL) + 15000; // do this in 15s to give UPnP time to configure and other things time to settle #ifdef ZT_AUTO_UPDATE uint64_t lastSoftwareUpdateCheck = 0; #endif // ZT_AUTO_UPDATE @@ -600,12 +592,12 @@ public: } #endif // ZT_AUTO_UPDATE - if ((now - lastTcpFallbackResolve) >= ZT1_TCP_FALLBACK_RERESOLVE_DELAY) { + if ((now - lastTcpFallbackResolve) >= ZT_TCP_FALLBACK_RERESOLVE_DELAY) { lastTcpFallbackResolve = now; _tcpFallbackResolver.resolveNow(); } - if ((_tcpFallbackTunnel)&&((now - _lastDirectReceiveFromGlobal) < (ZT1_TCP_FALLBACK_AFTER / 2))) + if ((_tcpFallbackTunnel)&&((now - _lastDirectReceiveFromGlobal) < (ZT_TCP_FALLBACK_AFTER / 2))) _phy.close(_tcpFallbackTunnel->sock); if ((now - lastTapMulticastGroupCheck) >= ZT_TAP_CHECK_MULTICAST_INTERVAL) { @@ -621,7 +613,7 @@ public: } } - if ((now - lastLocalInterfaceAddressCheck) >= ZT1_LOCAL_INTERFACE_CHECK_INTERVAL) { + if ((now - lastLocalInterfaceAddressCheck) >= ZT_LOCAL_INTERFACE_CHECK_INTERVAL) { lastLocalInterfaceAddressCheck = now; #ifdef __UNIX_LIKE__ @@ -637,7 +629,7 @@ public: #ifdef ZT_USE_MINIUPNPC std::vector upnpAddresses(_upnpClient->get()); for(std::vector::const_iterator ext(upnpAddresses.begin());ext!=upnpAddresses.end();++ext) - _node->addLocalInterfaceAddress(reinterpret_cast(&(*ext)),0,ZT1_LOCAL_INTERFACE_ADDRESS_TRUST_NORMAL); + _node->addLocalInterfaceAddress(reinterpret_cast(&(*ext)),0,ZT_LOCAL_INTERFACE_ADDRESS_TRUST_NORMAL); #endif struct ifaddrs *ifatbl = (struct ifaddrs *)0; @@ -655,7 +647,7 @@ public: if (!isZT) { InetAddress ip(ifa->ifa_addr); ip.setPort(_port); - _node->addLocalInterfaceAddress(reinterpret_cast(&ip),0,ZT1_LOCAL_INTERFACE_ADDRESS_TRUST_NORMAL); + _node->addLocalInterfaceAddress(reinterpret_cast(&ip),0,ZT_LOCAL_INTERFACE_ADDRESS_TRUST_NORMAL); } } ifa = ifa->ifa_next; @@ -689,7 +681,7 @@ public: while (ua) { InetAddress ip(ua->Address.lpSockaddr); ip.setPort(_port); - _node->addLocalInterfaceAddress(reinterpret_cast(&ip),0,ZT1_LOCAL_INTERFACE_ADDRESS_TRUST_NORMAL); + _node->addLocalInterfaceAddress(reinterpret_cast(&ip),0,ZT_LOCAL_INTERFACE_ADDRESS_TRUST_NORMAL); ua = ua->Next; } } @@ -777,14 +769,14 @@ public: #endif if ((len >= 16)&&(reinterpret_cast(from)->ipScope() == InetAddress::IP_SCOPE_GLOBAL)) _lastDirectReceiveFromGlobal = OSUtils::now(); - ZT1_ResultCode rc = _node->processWirePacket( + ZT_ResultCode rc = _node->processWirePacket( OSUtils::now(), - *(reinterpret_cast(*uptr)), // for UDP sockets, we set uptr to point to their interface ID + reinterpret_cast(*uptr), (const struct sockaddr_storage *)from, // Phy<> uses sockaddr_storage, so it'll always be that big data, len, &_nextBackgroundTaskDeadline); - if (ZT1_ResultCode_isFatal(rc)) { + if (ZT_ResultCode_isFatal(rc)) { char tmp[256]; Utils::snprintf(tmp,sizeof(tmp),"fatal error code from processWirePacket: %d",(int)rc); Mutex::Lock _l(_termReason_m); @@ -926,14 +918,14 @@ public: } if (from) { - ZT1_ResultCode rc = _node->processWirePacket( + ZT_ResultCode rc = _node->processWirePacket( OSUtils::now(), 0, reinterpret_cast(&from), data, plen, &_nextBackgroundTaskDeadline); - if (ZT1_ResultCode_isFatal(rc)) { + if (ZT_ResultCode_isFatal(rc)) { char tmp[256]; Utils::snprintf(tmp,sizeof(tmp),"fatal error code from processWirePacket: %d",(int)rc); Mutex::Lock _l(_termReason_m); @@ -986,12 +978,12 @@ public: inline void phyOnSocketPairEndpointData(PhySocket *sock,void **uptr,void *data,unsigned long len) {} inline void phyOnSocketPairEndpointWritable(PhySocket *sock,void **uptr) {} - inline int nodeVirtualNetworkConfigFunction(uint64_t nwid,enum ZT1_VirtualNetworkConfigOperation op,const ZT1_VirtualNetworkConfig *nwc) + inline int nodeVirtualNetworkConfigFunction(uint64_t nwid,enum ZT_VirtualNetworkConfigOperation op,const ZT_VirtualNetworkConfig *nwc) { Mutex::Lock _l(_taps_m); std::map< uint64_t,EthernetTap * >::iterator t(_taps.find(nwid)); switch(op) { - case ZT1_VIRTUAL_NETWORK_CONFIG_OPERATION_UP: + case ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP: if (t == _taps.end()) { try { char friendlyName[1024]; @@ -1021,7 +1013,7 @@ public: } } // fall through... - case ZT1_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE: + case ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE: if (t != _taps.end()) { t->second->setEnabled(nwc->enabled != 0); @@ -1044,8 +1036,8 @@ public: return -999; // tap init failed } break; - case ZT1_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN: - case ZT1_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY: + case ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN: + case ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY: if (t != _taps.end()) { #ifdef __WINDOWS__ std::string winInstanceId(t->second->instanceId()); @@ -1054,7 +1046,7 @@ public: _taps.erase(t); _tapAssignedIps.erase(nwid); #ifdef __WINDOWS__ - if ((op == ZT1_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY)&&(winInstanceId.length() > 0)) + if ((op == ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY)&&(winInstanceId.length() > 0)) WindowsEthernetTap::deletePersistentTapDevice(winInstanceId.c_str()); #endif } @@ -1063,17 +1055,17 @@ public: return 0; } - inline void nodeEventCallback(enum ZT1_Event event,const void *metaData) + inline void nodeEventCallback(enum ZT_Event event,const void *metaData) { switch(event) { - case ZT1_EVENT_FATAL_ERROR_IDENTITY_COLLISION: { + case ZT_EVENT_FATAL_ERROR_IDENTITY_COLLISION: { Mutex::Lock _l(_termReason_m); _termReason = ONE_IDENTITY_COLLISION; _fatalErrorMessage = "identity/address collision"; this->terminate(); } break; - case ZT1_EVENT_TRACE: { + case ZT_EVENT_TRACE: { if (metaData) { ::fprintf(stderr,"%s"ZT_EOL_S,(const char *)metaData); ::fflush(stderr); @@ -1139,10 +1131,10 @@ public: } } - inline int nodeWirePacketSendFunction(int localInterfaceId,const struct sockaddr_storage *addr,const void *data,unsigned int len) + inline int nodeWirePacketSendFunction(const struct sockaddr_storage *localAddr,const struct sockaddr_storage *addr,const void *data,unsigned int len) { #ifdef ZT_USE_MINIUPNPC - if (localInterfaceId == ZT1_INTERFACE_ID_UPNP) { + if ((localAddr->ss_family == AF_INET)&&(reinterpret_cast(localAddr)->sin_port == reinterpret_cast(&_v4UpnpLocalAddress)->sin_port)) { #ifdef ZT_BREAK_UDP if (!OSUtils::fileExists("/tmp/ZT_BREAK_UDP")) { #endif @@ -1167,15 +1159,15 @@ public: } #endif -#ifdef ZT1_TCP_FALLBACK_RELAY +#ifdef ZT_TCP_FALLBACK_RELAY // TCP fallback tunnel support if ((len >= 16)&&(reinterpret_cast(addr)->ipScope() == InetAddress::IP_SCOPE_GLOBAL)) { uint64_t now = OSUtils::now(); // Engage TCP tunnel fallback if we haven't received anything valid from a global - // IP address in ZT1_TCP_FALLBACK_AFTER milliseconds. If we do start getting + // IP address in ZT_TCP_FALLBACK_AFTER milliseconds. If we do start getting // valid direct traffic we'll stop using it and close the socket after a while. - if (((now - _lastDirectReceiveFromGlobal) > ZT1_TCP_FALLBACK_AFTER)&&((now - _lastRestart) > ZT1_TCP_FALLBACK_AFTER)) { + if (((now - _lastDirectReceiveFromGlobal) > ZT_TCP_FALLBACK_AFTER)&&((now - _lastRestart) > ZT_TCP_FALLBACK_AFTER)) { if (_tcpFallbackTunnel) { Mutex::Lock _l(_tcpFallbackTunnel->writeBuf_m); if (!_tcpFallbackTunnel->writeBuf.length()) @@ -1191,7 +1183,7 @@ public: _tcpFallbackTunnel->writeBuf.append(reinterpret_cast(reinterpret_cast(&(reinterpret_cast(addr)->sin_port))),2); _tcpFallbackTunnel->writeBuf.append((const char *)data,len); result = 0; - } else if (((now - _lastSendToGlobal) < ZT1_TCP_FALLBACK_AFTER)&&((now - _lastSendToGlobal) > (ZT_PING_CHECK_INVERVAL / 2))) { + } else if (((now - _lastSendToGlobal) < ZT_TCP_FALLBACK_AFTER)&&((now - _lastSendToGlobal) > (ZT_PING_CHECK_INVERVAL / 2))) { std::vector tunnelIps(_tcpFallbackResolver.get()); if (tunnelIps.empty()) { if (!_tcpFallbackResolver.running()) @@ -1199,7 +1191,7 @@ public: } else { bool connected = false; InetAddress addr(tunnelIps[(unsigned long)now % tunnelIps.size()]); - addr.setPort(ZT1_TCP_FALLBACK_RELAY_PORT); + addr.setPort(ZT_TCP_FALLBACK_RELAY_PORT); _phy.tcpConnect(reinterpret_cast(&addr),connected); } } @@ -1207,7 +1199,7 @@ public: _lastSendToGlobal = now; } -#endif // ZT1_TCP_FALLBACK_RELAY +#endif // ZT_TCP_FALLBACK_RELAY break; @@ -1319,6 +1311,7 @@ private: Phy _phy; std::string _overrideRootTopology; Node *_node; + InetAddress _v4LocalAddress,_v6LocalAddress; PhySocket *_v4UdpSocket; PhySocket *_v6UdpSocket; PhySocket *_v4TcpListenSocket; @@ -1343,6 +1336,7 @@ private: unsigned int _port; #ifdef ZT_USE_MINIUPNPC + InetAddress _v4UpnpLocalAddress; PhySocket *_v4UpnpUdpSocket; UPNPClient *_upnpClient; #endif @@ -1351,17 +1345,17 @@ private: Mutex _run_m; }; -static int SnodeVirtualNetworkConfigFunction(ZT1_Node *node,void *uptr,uint64_t nwid,enum ZT1_VirtualNetworkConfigOperation op,const ZT1_VirtualNetworkConfig *nwconf) +static int SnodeVirtualNetworkConfigFunction(ZT_Node *node,void *uptr,uint64_t nwid,enum ZT_VirtualNetworkConfigOperation op,const ZT_VirtualNetworkConfig *nwconf) { return reinterpret_cast(uptr)->nodeVirtualNetworkConfigFunction(nwid,op,nwconf); } -static void SnodeEventCallback(ZT1_Node *node,void *uptr,enum ZT1_Event event,const void *metaData) +static void SnodeEventCallback(ZT_Node *node,void *uptr,enum ZT_Event event,const void *metaData) { reinterpret_cast(uptr)->nodeEventCallback(event,metaData); } -static long SnodeDataStoreGetFunction(ZT1_Node *node,void *uptr,const char *name,void *buf,unsigned long bufSize,unsigned long readIndex,unsigned long *totalSize) +static long SnodeDataStoreGetFunction(ZT_Node *node,void *uptr,const char *name,void *buf,unsigned long bufSize,unsigned long readIndex,unsigned long *totalSize) { return reinterpret_cast(uptr)->nodeDataStoreGetFunction(name,buf,bufSize,readIndex,totalSize); } -static int SnodeDataStorePutFunction(ZT1_Node *node,void *uptr,const char *name,const void *data,unsigned long len,int secure) +static int SnodeDataStorePutFunction(ZT_Node *node,void *uptr,const char *name,const void *data,unsigned long len,int secure) { return reinterpret_cast(uptr)->nodeDataStorePutFunction(name,data,len,secure); } -static int SnodeWirePacketSendFunction(ZT1_Node *node,void *uptr,int localInterfaceId,const struct sockaddr_storage *addr,const void *data,unsigned int len) -{ return reinterpret_cast(uptr)->nodeWirePacketSendFunction(localInterfaceId,addr,data,len); } -static void SnodeVirtualNetworkFrameFunction(ZT1_Node *node,void *uptr,uint64_t nwid,uint64_t sourceMac,uint64_t destMac,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len) +static int SnodeWirePacketSendFunction(ZT_Node *node,void *uptr,const struct sockaddr_storage *localAddr,const struct sockaddr_storage *addr,const void *data,unsigned int len) +{ return reinterpret_cast(uptr)->nodeWirePacketSendFunction(localAddr,addr,data,len); } +static void SnodeVirtualNetworkFrameFunction(ZT_Node *node,void *uptr,uint64_t nwid,uint64_t sourceMac,uint64_t destMac,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len) { reinterpret_cast(uptr)->nodeVirtualNetworkFrameFunction(nwid,sourceMac,destMac,etherType,vlanId,data,len); } static void StapFrameHandler(void *uptr,uint64_t nwid,const MAC &from,const MAC &to,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len) diff --git a/windows/ZeroTierOne/ZeroTierOneService.cpp b/windows/ZeroTierOne/ZeroTierOneService.cpp index 984bcf00..dbc7ef44 100644 --- a/windows/ZeroTierOne/ZeroTierOneService.cpp +++ b/windows/ZeroTierOne/ZeroTierOneService.cpp @@ -90,7 +90,7 @@ restart_node: _service = (ZeroTier::OneService *)0; // in case newInstance() fails _service = ZeroTier::OneService::newInstance( ZeroTier::OneService::platformDefaultHomePath().c_str(), - ZT1_DEFAULT_PORT); + ZT_DEFAULT_PORT); } switch(_service->run()) { case ZeroTier::OneService::ONE_UNRECOVERABLE_ERROR: { -- cgit v1.2.3