mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-05 20:13:44 +02:00
More work on network membership certs, and it builds now. Still in heavy development.
This commit is contained in:
parent
439e602d5a
commit
e4c5ad9f43
6 changed files with 95 additions and 18 deletions
|
@ -103,8 +103,7 @@ Network::Network(const RuntimeEnvironment *renv,uint64_t id)
|
||||||
throw(std::runtime_error) :
|
throw(std::runtime_error) :
|
||||||
_r(renv),
|
_r(renv),
|
||||||
_tap(renv,renv->identity.address().toMAC(),ZT_IF_MTU,&_CBhandleTapData,this),
|
_tap(renv,renv->identity.address().toMAC(),ZT_IF_MTU,&_CBhandleTapData,this),
|
||||||
_id(id),
|
_id(id)
|
||||||
_isOpen(false)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,12 +113,44 @@ Network::~Network()
|
||||||
|
|
||||||
void Network::setConfiguration(const Network::Config &conf)
|
void Network::setConfiguration(const Network::Config &conf)
|
||||||
{
|
{
|
||||||
|
Mutex::Lock _l(_lock);
|
||||||
|
_configuration = conf;
|
||||||
|
_myCertificate = conf.certificateOfMembership();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Network::requestConfiguration()
|
void Network::requestConfiguration()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Network::isAllowed(const Address &peer) const
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
Mutex::Lock _l(_lock);
|
||||||
|
if (_configuration.isOpen())
|
||||||
|
return true;
|
||||||
|
std::map<Address,Certificate>::const_iterator pc(_membershipCertificates.find(peer));
|
||||||
|
if (pc == _membershipCertificates.end())
|
||||||
|
return false;
|
||||||
|
return _myCertificate.qualifyMembership(pc->second);
|
||||||
|
} catch (std::exception &exc) {
|
||||||
|
TRACE("isAllowed() check failed for peer %s: unexpected exception: %s",peer.toString().c_str(),exc.what());
|
||||||
|
return false;
|
||||||
|
} catch ( ... ) {
|
||||||
|
TRACE("isAllowed() check failed for peer %s: unexpected exception: unknown exception",peer.toString().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Network::clean()
|
||||||
|
{
|
||||||
|
Mutex::Lock _l(_lock);
|
||||||
|
for(std::map<Address,Certificate>::iterator i=(_membershipCertificates.begin());i!=_membershipCertificates.end();) {
|
||||||
|
if (_myCertificate.qualifyMembership(i->second))
|
||||||
|
++i;
|
||||||
|
else _membershipCertificates.erase(i++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Network::_CBhandleTapData(void *arg,const MAC &from,const MAC &to,unsigned int etherType,const Buffer<4096> &data)
|
void Network::_CBhandleTapData(void *arg,const MAC &from,const MAC &to,unsigned int etherType,const Buffer<4096> &data)
|
||||||
{
|
{
|
||||||
const RuntimeEnvironment *_r = ((Network *)arg)->_r;
|
const RuntimeEnvironment *_r = ((Network *)arg)->_r;
|
||||||
|
|
|
@ -208,6 +208,30 @@ public:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void setNetworkId(uint64_t id)
|
||||||
|
{
|
||||||
|
char buf[32];
|
||||||
|
sprintf(buf,"%llu",id);
|
||||||
|
(*this)["nwid"] = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint64_t networkId() const
|
||||||
|
throw(std::invalid_argument)
|
||||||
|
{
|
||||||
|
return strtoull(get("nwid").c_str(),(char **)0,10);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void setPeerAddress(Address &a)
|
||||||
|
{
|
||||||
|
(*this)["peer"] = a.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Address peerAddress() const
|
||||||
|
throw(std::invalid_argument)
|
||||||
|
{
|
||||||
|
return Address(get("peer"));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Certificate of membership for this network, or empty cert if none
|
* @return Certificate of membership for this network, or empty cert if none
|
||||||
*/
|
*/
|
||||||
|
@ -221,7 +245,7 @@ public:
|
||||||
*/
|
*/
|
||||||
inline bool isOpen() const
|
inline bool isOpen() const
|
||||||
{
|
{
|
||||||
return (get("isOpen","0") == "1");
|
return (get("isOpen") == "1");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -304,8 +328,12 @@ public:
|
||||||
inline bool isOpen() const
|
inline bool isOpen() const
|
||||||
throw()
|
throw()
|
||||||
{
|
{
|
||||||
Mutex::Lock _l(_lock);
|
try {
|
||||||
return _isOpen;
|
Mutex::Lock _l(_lock);
|
||||||
|
return _configuration.isOpen();
|
||||||
|
} catch ( ... ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -343,6 +371,27 @@ public:
|
||||||
*/
|
*/
|
||||||
void requestConfiguration();
|
void requestConfiguration();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add or update a peer's membership certificate
|
||||||
|
*
|
||||||
|
* The certificate must already have been validated via signature checking.
|
||||||
|
*
|
||||||
|
* @param peer Peer that owns certificate
|
||||||
|
* @param cert Certificate itself
|
||||||
|
*/
|
||||||
|
inline void addMembershipCertificate(const Address &peer,const Certificate &cert)
|
||||||
|
{
|
||||||
|
Mutex::Lock _l(_lock);
|
||||||
|
_membershipCertificates[peer] = cert;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isAllowed(const Address &peer) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform periodic database cleaning such as removing expired membership certificates
|
||||||
|
*/
|
||||||
|
void clean();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void _CBhandleTapData(void *arg,const MAC &from,const MAC &to,unsigned int etherType,const Buffer<4096> &data);
|
static void _CBhandleTapData(void *arg,const MAC &from,const MAC &to,unsigned int etherType,const Buffer<4096> &data);
|
||||||
|
|
||||||
|
@ -350,10 +399,11 @@ private:
|
||||||
|
|
||||||
EthernetTap _tap;
|
EthernetTap _tap;
|
||||||
std::set<MulticastGroup> _multicastGroups;
|
std::set<MulticastGroup> _multicastGroups;
|
||||||
|
std::map<Address,Certificate> _membershipCertificates;
|
||||||
|
Config _configuration;
|
||||||
|
Certificate _myCertificate;
|
||||||
|
uint64_t _lastCertificateUpdate;
|
||||||
uint64_t _id;
|
uint64_t _id;
|
||||||
bool _isOpen;
|
|
||||||
|
|
||||||
Mutex _lock;
|
Mutex _lock;
|
||||||
|
|
||||||
AtomicCounter __refCount;
|
AtomicCounter __refCount;
|
||||||
|
|
|
@ -60,8 +60,7 @@ const char *Packet::errorString(ErrorCode e)
|
||||||
case ERROR_IDENTITY_COLLISION: return "IDENTITY_COLLISION";
|
case ERROR_IDENTITY_COLLISION: return "IDENTITY_COLLISION";
|
||||||
case ERROR_IDENTITY_INVALID: return "IDENTITY_INVALID";
|
case ERROR_IDENTITY_INVALID: return "IDENTITY_INVALID";
|
||||||
case ERROR_UNSUPPORTED_OPERATION: return "UNSUPPORTED_OPERATION";
|
case ERROR_UNSUPPORTED_OPERATION: return "UNSUPPORTED_OPERATION";
|
||||||
case ERROR_NO_MEMBER_CERTIFICATE_ON_FILE: return "NO_MEMBER_CERTIFICATE_ON_FILE";
|
case ERROR_NO_MEMBER_CERTIFICATE: return "NO_MEMBER_CERTIFICATE";
|
||||||
case ERROR_MEMBER_CERTIFICATE_UNQUALIFIED: return "MEMBER_CERTIFICATE_UNQUALIFIED";
|
|
||||||
}
|
}
|
||||||
return "(unknown)";
|
return "(unknown)";
|
||||||
}
|
}
|
||||||
|
|
|
@ -537,10 +537,7 @@ public:
|
||||||
ERROR_UNSUPPORTED_OPERATION = 6,
|
ERROR_UNSUPPORTED_OPERATION = 6,
|
||||||
|
|
||||||
/* Message to private network rejected -- no unexpired certificate on file */
|
/* Message to private network rejected -- no unexpired certificate on file */
|
||||||
ERROR_NO_MEMBER_CERTIFICATE_ON_FILE = 7,
|
ERROR_NO_MEMBER_CERTIFICATE = 7
|
||||||
|
|
||||||
/* Membership certificate no longer qualified for membership in network */
|
|
||||||
ERROR_MEMBER_CERTIFICATE_UNQUALIFIED = 8
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -386,7 +386,7 @@ void Switch::announceMulticastGroups(const std::map< SharedPtr<Network>,std::set
|
||||||
Packet outp((*p)->address(),_r->identity.address(),Packet::VERB_MULTICAST_LIKE);
|
Packet outp((*p)->address(),_r->identity.address(),Packet::VERB_MULTICAST_LIKE);
|
||||||
|
|
||||||
for(std::map< SharedPtr<Network>,std::set<MulticastGroup> >::const_iterator nwmgs(allMemberships.begin());nwmgs!=allMemberships.end();++nwmgs) {
|
for(std::map< SharedPtr<Network>,std::set<MulticastGroup> >::const_iterator nwmgs(allMemberships.begin());nwmgs!=allMemberships.end();++nwmgs) {
|
||||||
if ((nwmgs->first->open())||(_r->topology->isSupernode((*p)->address()))||(nwmgs->first->isMember((*p)->address()))) {
|
if ((_r->topology->isSupernode((*p)->address()))||(nwmgs->first->isAllowed((*p)->address()))) {
|
||||||
for(std::set<MulticastGroup>::iterator mg(nwmgs->second.begin());mg!=nwmgs->second.end();++mg) {
|
for(std::set<MulticastGroup>::iterator mg(nwmgs->second.begin());mg!=nwmgs->second.end();++mg) {
|
||||||
if ((outp.size() + 18) > ZT_UDP_DEFAULT_PAYLOAD_MTU) {
|
if ((outp.size() + 18) > ZT_UDP_DEFAULT_PAYLOAD_MTU) {
|
||||||
send(outp,true);
|
send(outp,true);
|
||||||
|
|
|
@ -133,7 +133,7 @@ SharedPtr<Peer> Topology::getPeer(const Address &zta)
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char ztatmp[ZT_ADDRESS_LENGTH];
|
unsigned char ztatmp[ZT_ADDRESS_LENGTH];
|
||||||
zta.copyTo(ztatmp);
|
zta.copyTo(ztatmp,ZT_ADDRESS_LENGTH);
|
||||||
|
|
||||||
Buffer<ZT_KISSDB_VALUE_SIZE> b(ZT_KISSDB_VALUE_SIZE);
|
Buffer<ZT_KISSDB_VALUE_SIZE> b(ZT_KISSDB_VALUE_SIZE);
|
||||||
_dbm_m.lock();
|
_dbm_m.lock();
|
||||||
|
@ -309,7 +309,7 @@ void Topology::main()
|
||||||
if (p->second->getAndResetDirty()) {
|
if (p->second->getAndResetDirty()) {
|
||||||
try {
|
try {
|
||||||
uint64_t atmp[ZT_ADDRESS_LENGTH];
|
uint64_t atmp[ZT_ADDRESS_LENGTH];
|
||||||
p->second->identity().address().copyTo(atmp);
|
p->second->identity().address().copyTo(atmp,ZT_ADDRESS_LENGTH);
|
||||||
Buffer<ZT_PEER_MAX_SERIALIZED_LENGTH> b;
|
Buffer<ZT_PEER_MAX_SERIALIZED_LENGTH> b;
|
||||||
p->second->serialize(b);
|
p->second->serialize(b);
|
||||||
b.zeroUnused();
|
b.zeroUnused();
|
||||||
|
@ -340,7 +340,7 @@ void Topology::_reallyAddPeer(const SharedPtr<Peer> &p)
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
uint64_t atmp[ZT_ADDRESS_LENGTH];
|
uint64_t atmp[ZT_ADDRESS_LENGTH];
|
||||||
p->address().copyTo(atmp);
|
p->address().copyTo(atmp,ZT_ADDRESS_LENGTH);
|
||||||
Buffer<ZT_PEER_MAX_SERIALIZED_LENGTH> b;
|
Buffer<ZT_PEER_MAX_SERIALIZED_LENGTH> b;
|
||||||
p->serialize(b);
|
p->serialize(b);
|
||||||
b.zeroUnused();
|
b.zeroUnused();
|
||||||
|
|
Loading…
Add table
Reference in a new issue