mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-05 03:53:44 +02:00
VERSION 0.4.4: multicast cleanup, Windows port work
In addition to a lot of Windows port work that isn't finished yet (and doesn't affect the *nix platforms at all), this version contains quite a bit of multicast cleanup and code simplification. I also pulled rate limits for now, as it seems to be causing problems. More testing on the testnet is going to be needed.
This commit is contained in:
parent
f6e7be102a
commit
b6248c7cb7
2 changed files with 19 additions and 37 deletions
|
@ -105,7 +105,7 @@ bool PacketDecoder::tryDecode(const RuntimeEnvironment *_r)
|
||||||
TRACE("NOP from %s(%s)",source().toString().c_str(),_remoteAddress.toString().c_str());
|
TRACE("NOP from %s(%s)",source().toString().c_str(),_remoteAddress.toString().c_str());
|
||||||
return true;
|
return true;
|
||||||
case Packet::VERB_HELLO:
|
case Packet::VERB_HELLO:
|
||||||
return _doHELLO(_r); // encrypted HELLO is technically allowed, but kind of pointless... :)
|
return _doHELLO(_r);
|
||||||
case Packet::VERB_ERROR:
|
case Packet::VERB_ERROR:
|
||||||
return _doERROR(_r,peer);
|
return _doERROR(_r,peer);
|
||||||
case Packet::VERB_OK:
|
case Packet::VERB_OK:
|
||||||
|
@ -238,29 +238,16 @@ bool PacketDecoder::_doHELLO(const RuntimeEnvironment *_r)
|
||||||
uint64_t timestamp = at<uint64_t>(ZT_PROTO_VERB_HELLO_IDX_TIMESTAMP);
|
uint64_t timestamp = at<uint64_t>(ZT_PROTO_VERB_HELLO_IDX_TIMESTAMP);
|
||||||
Identity id(*this,ZT_PROTO_VERB_HELLO_IDX_IDENTITY);
|
Identity id(*this,ZT_PROTO_VERB_HELLO_IDX_IDENTITY);
|
||||||
|
|
||||||
// Create a new candidate peer that we might decide to add to our
|
// Initial sniff test for valid addressing and that this is indeed the
|
||||||
// database. We create it now since we want its keys to send replies
|
// submitter's identity.
|
||||||
// even in the error case, and the code for keying is in Peer.
|
|
||||||
SharedPtr<Peer> candidate(new Peer(_r->identity,id));
|
|
||||||
candidate->setPathAddress(_remoteAddress,false);
|
|
||||||
|
|
||||||
// The initial sniff test... is the identity valid, and is it
|
|
||||||
// the sender's identity?
|
|
||||||
if ((id.address().isReserved())||(id.address() != source())) {
|
if ((id.address().isReserved())||(id.address() != source())) {
|
||||||
#ifdef ZT_TRACE
|
#ifdef ZT_TRACE
|
||||||
if (id.address().isReserved()) {
|
if (id.address().isReserved()) {
|
||||||
TRACE("rejected HELLO from %s(%s): identity has reserved address",source().toString().c_str(),_remoteAddress.toString().c_str());
|
TRACE("dropped HELLO from %s(%s): identity has reserved address",source().toString().c_str(),_remoteAddress.toString().c_str());
|
||||||
} else {
|
} else {
|
||||||
TRACE("rejected HELLO from %s(%s): identity is not for sender of packet (HELLO is a self-announcement)",source().toString().c_str(),_remoteAddress.toString().c_str());
|
TRACE("dropped HELLO from %s(%s): identity is not for sender of packet (HELLO is a self-announcement)",source().toString().c_str(),_remoteAddress.toString().c_str());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
Packet outp(source(),_r->identity.address(),Packet::VERB_ERROR);
|
|
||||||
outp.append((unsigned char)Packet::VERB_HELLO);
|
|
||||||
outp.append(packetId());
|
|
||||||
outp.append((unsigned char)((id.address().isReserved()) ? Packet::ERROR_IDENTITY_INVALID : Packet::ERROR_INVALID_REQUEST));
|
|
||||||
outp.encrypt(candidate->cryptKey());
|
|
||||||
outp.hmacSet(candidate->macKey());
|
|
||||||
_r->demarc->send(_localPort,_remoteAddress,outp.data(),outp.size(),-1);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,9 +268,9 @@ bool PacketDecoder::_doHELLO(const RuntimeEnvironment *_r)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise we call addPeer() and set up a callback to handle the verdict.
|
SharedPtr<Peer> candidate(new Peer(_r->identity,id));
|
||||||
// Topology evaluates the peer in the background, possibly doing the entire
|
candidate->setPathAddress(_remoteAddress,false);
|
||||||
// expensive analysis before determining whether to add it to the database.
|
|
||||||
_CBaddPeerFromHello_Data *arg = new _CBaddPeerFromHello_Data;
|
_CBaddPeerFromHello_Data *arg = new _CBaddPeerFromHello_Data;
|
||||||
arg->renv = _r;
|
arg->renv = _r;
|
||||||
arg->source = source();
|
arg->source = source();
|
||||||
|
@ -319,16 +306,15 @@ bool PacketDecoder::_doOK(const RuntimeEnvironment *_r,const SharedPtr<Peer> &pe
|
||||||
if (_r->topology->isSupernode(source())) {
|
if (_r->topology->isSupernode(source())) {
|
||||||
// Right now, only supernodes are queried for WHOIS so we only
|
// Right now, only supernodes are queried for WHOIS so we only
|
||||||
// accept OK(WHOIS) from supernodes. Otherwise peers could
|
// accept OK(WHOIS) from supernodes. Otherwise peers could
|
||||||
// potentially cache-poison. A more elegant but memory-intensive
|
// potentially cache-poison.
|
||||||
// solution would be to remember packet IDs of WHOIS requests.
|
|
||||||
_r->topology->addPeer(SharedPtr<Peer>(new Peer(_r->identity,Identity(*this,ZT_PROTO_VERB_WHOIS__OK__IDX_IDENTITY))),&PacketDecoder::_CBaddPeerFromWhois,const_cast<void *>((const void *)_r));
|
_r->topology->addPeer(SharedPtr<Peer>(new Peer(_r->identity,Identity(*this,ZT_PROTO_VERB_WHOIS__OK__IDX_IDENTITY))),&PacketDecoder::_CBaddPeerFromWhois,const_cast<void *>((const void *)_r));
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case Packet::VERB_NETWORK_CONFIG_REQUEST: {
|
case Packet::VERB_NETWORK_CONFIG_REQUEST: {
|
||||||
SharedPtr<Network> nw(_r->nc->network(at<uint64_t>(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_NETWORK_ID)));
|
SharedPtr<Network> nw(_r->nc->network(at<uint64_t>(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_NETWORK_ID)));
|
||||||
if ((nw)&&(nw->controller() == source())) {
|
if ((nw)&&(nw->controller() == source())) {
|
||||||
// Only accept OK(NETWORK_CONFIG_REQUEST) from masters for
|
// OK(NETWORK_CONFIG_REQUEST) is only accepted from a network's
|
||||||
// networks we have.
|
// controller.
|
||||||
unsigned int dictlen = at<uint16_t>(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_DICT_LEN);
|
unsigned int dictlen = at<uint16_t>(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_DICT_LEN);
|
||||||
std::string dict((const char *)field(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_DICT,dictlen),dictlen);
|
std::string dict((const char *)field(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_DICT,dictlen),dictlen);
|
||||||
if (dict.length()) {
|
if (dict.length()) {
|
||||||
|
@ -396,8 +382,7 @@ bool PacketDecoder::_doRENDEZVOUS(const RuntimeEnvironment *_r,const SharedPtr<P
|
||||||
* packet, but it's still maybe something we want to not allow just
|
* packet, but it's still maybe something we want to not allow just
|
||||||
* anyone to order due to possible DDOS or network forensic implications.
|
* anyone to order due to possible DDOS or network forensic implications.
|
||||||
* So if we diversify relays, we'll need some way of deciding whether the
|
* So if we diversify relays, we'll need some way of deciding whether the
|
||||||
* sender is someone we should trust with a RENDEZVOUS hint. Or maybe
|
* sender is someone we should trust with a RENDEZVOUS hint.
|
||||||
* we just need rate limiting to prevent DDOS and amplification attacks.
|
|
||||||
*/
|
*/
|
||||||
if (_r->topology->isSupernode(source())) {
|
if (_r->topology->isSupernode(source())) {
|
||||||
Address with(field(ZT_PROTO_VERB_RENDEZVOUS_IDX_ZTADDRESS,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH);
|
Address with(field(ZT_PROTO_VERB_RENDEZVOUS_IDX_ZTADDRESS,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH);
|
||||||
|
@ -469,10 +454,7 @@ bool PacketDecoder::_doMULTICAST_LIKE(const RuntimeEnvironment *_r,const SharedP
|
||||||
//TRACE("peer %s likes multicast group %s:%.8lx on network %llu",source().toString().c_str(),mac.toString().c_str(),(unsigned long)adi,nwid);
|
//TRACE("peer %s likes multicast group %s:%.8lx on network %llu",source().toString().c_str(),mac.toString().c_str(),(unsigned long)adi,nwid);
|
||||||
_r->multicaster->likesMulticastGroup(nwid,MulticastGroup(mac,adi),source(),now);
|
_r->multicaster->likesMulticastGroup(nwid,MulticastGroup(mac,adi),source(),now);
|
||||||
++numAccepted;
|
++numAccepted;
|
||||||
} else {
|
} else ptr += 10;
|
||||||
ptr += 10;
|
|
||||||
TRACE("ignored MULTICAST_LIKE from %s(%s): network %.16llx unknown, or sender is not a member of network",source().toString().c_str(),_remoteAddress.toString().c_str(),(unsigned long long)nwid);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Packet outp(source(),_r->identity.address(),Packet::VERB_OK);
|
Packet outp(source(),_r->identity.address(),Packet::VERB_OK);
|
||||||
|
@ -537,12 +519,12 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared
|
||||||
bool isDuplicate = _r->multicaster->checkDuplicate(mccrc,now);
|
bool isDuplicate = _r->multicaster->checkDuplicate(mccrc,now);
|
||||||
|
|
||||||
if (!isDuplicate) {
|
if (!isDuplicate) {
|
||||||
if (network->multicastRateGate(originalSubmitterAddress,datalen)) {
|
//if (network->multicastRateGate(originalSubmitterAddress,datalen)) {
|
||||||
network->tap().put(fromMac,mg.mac(),etherType,dataAndSignature,datalen);
|
network->tap().put(fromMac,mg.mac(),etherType,dataAndSignature,datalen);
|
||||||
} else {
|
//} else {
|
||||||
TRACE("dropped MULTICAST_FRAME from original submitter %s, received from %s(%s): sender rate limit exceeded",originalSubmitterAddress.toString().c_str(),source().toString().c_str(),_remoteAddress.toString().c_str());
|
// TRACE("dropped MULTICAST_FRAME from original submitter %s, received from %s(%s): sender rate limit exceeded",originalSubmitterAddress.toString().c_str(),source().toString().c_str(),_remoteAddress.toString().c_str());
|
||||||
return true;
|
// return true;
|
||||||
}
|
//}
|
||||||
|
|
||||||
/* It's important that we do this *after* rate limit checking,
|
/* It's important that we do this *after* rate limit checking,
|
||||||
* otherwise supernodes could be used to execute a flood by
|
* otherwise supernodes could be used to execute a flood by
|
||||||
|
|
|
@ -41,6 +41,6 @@
|
||||||
/**
|
/**
|
||||||
* Revision: 16-bit (0-65535)
|
* Revision: 16-bit (0-65535)
|
||||||
*/
|
*/
|
||||||
#define ZEROTIER_ONE_VERSION_REVISION 3
|
#define ZEROTIER_ONE_VERSION_REVISION 4
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Reference in a new issue