mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-05 20:13:44 +02:00
Take the 0.6.0 opportunity to add flags to a few protocol verbs and do a bit more cleanup. Also fix it so certificates wont be accepted unless they are newer than existing ones.
This commit is contained in:
parent
555471200c
commit
ce14ba9004
7 changed files with 84 additions and 68 deletions
|
@ -198,14 +198,14 @@ public:
|
||||||
/**
|
/**
|
||||||
* @return Timestamp for this cert in ms since epoch (according to netconf's clock)
|
* @return Timestamp for this cert in ms since epoch (according to netconf's clock)
|
||||||
*/
|
*/
|
||||||
inline Address timestamp() const
|
inline uint64_t timestamp() const
|
||||||
throw()
|
throw()
|
||||||
{
|
{
|
||||||
for(std::vector<_Qualifier>::const_iterator q(_qualifiers.begin());q!=_qualifiers.end();++q) {
|
for(std::vector<_Qualifier>::const_iterator q(_qualifiers.begin());q!=_qualifiers.end();++q) {
|
||||||
if (q->id == COM_RESERVED_ID_TIMESTAMP)
|
if (q->id == COM_RESERVED_ID_TIMESTAMP)
|
||||||
return Address(q->value);
|
return q->value;
|
||||||
}
|
}
|
||||||
return Address();
|
return 0ULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -178,10 +178,14 @@ void Network::requestConfiguration()
|
||||||
void Network::addMembershipCertificate(const CertificateOfMembership &cert)
|
void Network::addMembershipCertificate(const CertificateOfMembership &cert)
|
||||||
{
|
{
|
||||||
Mutex::Lock _l(_lock);
|
Mutex::Lock _l(_lock);
|
||||||
|
|
||||||
// We go ahead and accept certs provisionally even if _isOpen is true, since
|
// We go ahead and accept certs provisionally even if _isOpen is true, since
|
||||||
// that might be changed in short order if the user is fiddling in the UI.
|
// that might be changed in short order if the user is fiddling in the UI.
|
||||||
// These will be purged on clean() for open networks eventually.
|
// These will be purged on clean() for open networks eventually.
|
||||||
_membershipCertificates[cert.issuedTo()] = cert;
|
|
||||||
|
CertificateOfMembership &old = _membershipCertificates[cert.issuedTo()];
|
||||||
|
if (cert.timestamp() >= old.timestamp())
|
||||||
|
old = cert;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Network::isAllowed(const Address &peer) const
|
bool Network::isAllowed(const Address &peer) const
|
||||||
|
@ -299,30 +303,38 @@ void Network::_restoreState()
|
||||||
|
|
||||||
_membershipCertificates.clear();
|
_membershipCertificates.clear();
|
||||||
|
|
||||||
try {
|
FILE *mcdb = fopen(mcdbPath.c_str(),"rb");
|
||||||
FILE *mcdb = fopen(mcdbPath.c_str(),"rb");
|
if (mcdb) {
|
||||||
if (mcdb) {
|
try {
|
||||||
for(;;) {
|
char magic[6];
|
||||||
long rlen = (long)fread(buf.data() + buf.size(),1,ZT_NETWORK_CERT_WRITE_BUF_SIZE - buf.size(),mcdb);
|
if ((fread(magic,6,1,mcdb) == 1)&&(!memcmp("ZTMCD0",magic,6))) {
|
||||||
if (rlen <= 0)
|
for(;;) {
|
||||||
break;
|
long rlen = (long)fread(buf.data() + buf.size(),1,ZT_NETWORK_CERT_WRITE_BUF_SIZE - buf.size(),mcdb);
|
||||||
buf.setSize(buf.size() + (unsigned int)rlen);
|
if (rlen <= 0)
|
||||||
unsigned int ptr = 0;
|
break;
|
||||||
while ((ptr < (ZT_NETWORK_CERT_WRITE_BUF_SIZE / 2))&&(ptr < buf.size())) {
|
buf.setSize(buf.size() + (unsigned int)rlen);
|
||||||
ptr += com.deserialize(buf,ptr);
|
unsigned int ptr = 0;
|
||||||
if (com.issuedTo())
|
while ((ptr < (ZT_NETWORK_CERT_WRITE_BUF_SIZE / 2))&&(ptr < buf.size())) {
|
||||||
_membershipCertificates[com.issuedTo()] = com;
|
ptr += com.deserialize(buf,ptr);
|
||||||
}
|
if (com.issuedTo())
|
||||||
if (ptr) {
|
_membershipCertificates[com.issuedTo()] = com;
|
||||||
memmove(buf.data(),buf.data() + ptr,buf.size() - ptr);
|
}
|
||||||
buf.setSize(buf.size() - ptr);
|
if (ptr) {
|
||||||
|
memmove(buf.data(),buf.data() + ptr,buf.size() - ptr);
|
||||||
|
buf.setSize(buf.size() - ptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
fclose(mcdb);
|
||||||
|
} else {
|
||||||
|
fclose(mcdb);
|
||||||
|
Utils::rm(mcdbPath);
|
||||||
}
|
}
|
||||||
|
} catch ( ... ) {
|
||||||
|
// Membership cert dump file invalid. We'll re-learn them off the net.
|
||||||
|
_membershipCertificates.clear();
|
||||||
|
fclose(mcdb);
|
||||||
|
Utils::rm(mcdbPath);
|
||||||
}
|
}
|
||||||
} catch ( ... ) {
|
|
||||||
// Membership cert dump file invalid. We'll re-learn them off the net.
|
|
||||||
_membershipCertificates.clear();
|
|
||||||
Utils::rm(mcdbPath);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ const char *Packet::verbString(Verb v)
|
||||||
case VERB_WHOIS: return "WHOIS";
|
case VERB_WHOIS: return "WHOIS";
|
||||||
case VERB_RENDEZVOUS: return "RENDEZVOUS";
|
case VERB_RENDEZVOUS: return "RENDEZVOUS";
|
||||||
case VERB_FRAME: return "FRAME";
|
case VERB_FRAME: return "FRAME";
|
||||||
case VERB_PROXY_FRAME: return "PROXY_FRAME";
|
case VERB_BRIDGED_FRAME: return "BRIDGED_FRAME";
|
||||||
case VERB_MULTICAST_FRAME: return "MULTICAST_FRAME";
|
case VERB_MULTICAST_FRAME: return "MULTICAST_FRAME";
|
||||||
case VERB_MULTICAST_LIKE: return "MULTICAST_LIKE";
|
case VERB_MULTICAST_LIKE: return "MULTICAST_LIKE";
|
||||||
case VERB_NETWORK_MEMBERSHIP_CERTIFICATE: return "NETWORK_MEMBERSHIP_CERTIFICATE";
|
case VERB_NETWORK_MEMBERSHIP_CERTIFICATE: return "NETWORK_MEMBERSHIP_CERTIFICATE";
|
||||||
|
|
|
@ -155,7 +155,8 @@
|
||||||
|
|
||||||
#define ZT_PROTO_VERB_WHOIS_IDX_ZTADDRESS (ZT_PACKET_IDX_PAYLOAD)
|
#define ZT_PROTO_VERB_WHOIS_IDX_ZTADDRESS (ZT_PACKET_IDX_PAYLOAD)
|
||||||
|
|
||||||
#define ZT_PROTO_VERB_RENDEZVOUS_IDX_ZTADDRESS (ZT_PACKET_IDX_PAYLOAD)
|
#define ZT_PROTO_VERB_RENDEZVOUS_IDX_FLAGS (ZT_PACKET_IDX_PAYLOAD)
|
||||||
|
#define ZT_PROTO_VERB_RENDEZVOUS_IDX_ZTADDRESS (ZT_PROTO_VERB_RENDEZVOUS_IDX_FLAGS + 1)
|
||||||
#define ZT_PROTO_VERB_RENDEZVOUS_IDX_PORT (ZT_PROTO_VERB_RENDEZVOUS_IDX_ZTADDRESS + 5)
|
#define ZT_PROTO_VERB_RENDEZVOUS_IDX_PORT (ZT_PROTO_VERB_RENDEZVOUS_IDX_ZTADDRESS + 5)
|
||||||
#define ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRLEN (ZT_PROTO_VERB_RENDEZVOUS_IDX_PORT + 2)
|
#define ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRLEN (ZT_PROTO_VERB_RENDEZVOUS_IDX_PORT + 2)
|
||||||
#define ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRESS (ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRLEN + 1)
|
#define ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRESS (ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRLEN + 1)
|
||||||
|
@ -199,8 +200,6 @@
|
||||||
#define ZT_PROTO_VERB_MULTICAST_FRAME_LEN_FRAME_LEN 2
|
#define ZT_PROTO_VERB_MULTICAST_FRAME_LEN_FRAME_LEN 2
|
||||||
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FRAME (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FRAME_LEN + ZT_PROTO_VERB_MULTICAST_FRAME_LEN_FRAME_LEN)
|
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FRAME (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FRAME_LEN + ZT_PROTO_VERB_MULTICAST_FRAME_LEN_FRAME_LEN)
|
||||||
|
|
||||||
#define ZT_PROTO_VERB_NETWORK_MEMBERSHIP_CERTIFICATE_IDX_CERTIFICATE (ZT_PACKET_IDX_PAYLOAD)
|
|
||||||
|
|
||||||
#define ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_NETWORK_ID (ZT_PACKET_IDX_PAYLOAD)
|
#define ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_NETWORK_ID (ZT_PACKET_IDX_PAYLOAD)
|
||||||
#define ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT_LEN (ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_NETWORK_ID + 8)
|
#define ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT_LEN (ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_NETWORK_ID + 8)
|
||||||
#define ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT (ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT_LEN + 2)
|
#define ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT (ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT_LEN + 2)
|
||||||
|
@ -434,11 +433,13 @@ public:
|
||||||
* OK response payload:
|
* OK response payload:
|
||||||
* <[...] binary serialized identity>
|
* <[...] binary serialized identity>
|
||||||
*
|
*
|
||||||
* Error payload will be address queried.
|
* ERROR response payload:
|
||||||
|
* <[5] address>
|
||||||
*/
|
*/
|
||||||
VERB_WHOIS = 4,
|
VERB_WHOIS = 4,
|
||||||
|
|
||||||
/* Meet another node at a given protocol address:
|
/* Meet another node at a given protocol address:
|
||||||
|
* <[1] flags (unused, currently 0)>
|
||||||
* <[5] ZeroTier address of peer that might be found at this address>
|
* <[5] ZeroTier address of peer that might be found at this address>
|
||||||
* <[2] 16-bit protocol address port>
|
* <[2] 16-bit protocol address port>
|
||||||
* <[1] protocol address length (4 for IPv4, 16 for IPv6)>
|
* <[1] protocol address length (4 for IPv4, 16 for IPv6)>
|
||||||
|
@ -470,8 +471,7 @@ public:
|
||||||
* <[...] ethernet payload>
|
* <[...] ethernet payload>
|
||||||
*
|
*
|
||||||
* MAC addresses are derived from the packet's source and destination
|
* MAC addresses are derived from the packet's source and destination
|
||||||
* ZeroTier addresses. ZeroTier does not support VLANs or other extensions
|
* ZeroTier addresses.
|
||||||
* beyond core Ethernet.
|
|
||||||
*
|
*
|
||||||
* ERROR may be generated if a membership certificate is needed for a
|
* ERROR may be generated if a membership certificate is needed for a
|
||||||
* closed network. Payload will be network ID.
|
* closed network. Payload will be network ID.
|
||||||
|
@ -479,7 +479,7 @@ public:
|
||||||
VERB_FRAME = 6,
|
VERB_FRAME = 6,
|
||||||
|
|
||||||
/* TODO: not implemented yet */
|
/* TODO: not implemented yet */
|
||||||
VERB_PROXY_FRAME = 7,
|
VERB_BRIDGED_FRAME = 7,
|
||||||
|
|
||||||
/* A multicast frame:
|
/* A multicast frame:
|
||||||
* <[2] 16-bit propagation depth or 0xffff for "do not forward">
|
* <[2] 16-bit propagation depth or 0xffff for "do not forward">
|
||||||
|
@ -556,6 +556,7 @@ public:
|
||||||
|
|
||||||
/* Network member certificate:
|
/* Network member certificate:
|
||||||
* <[...] serialized certificate of membership>
|
* <[...] serialized certificate of membership>
|
||||||
|
* [ ... additional certificates may follow ...]
|
||||||
*
|
*
|
||||||
* Certificate contains network ID, peer it was issued for, etc.
|
* Certificate contains network ID, peer it was issued for, etc.
|
||||||
*
|
*
|
||||||
|
@ -583,9 +584,8 @@ public:
|
||||||
* node can push to other peers to demonstrate its right to speak on
|
* node can push to other peers to demonstrate its right to speak on
|
||||||
* a given network.
|
* a given network.
|
||||||
*
|
*
|
||||||
* ERROR may be NOT_FOUND if no such network is known, or
|
* ERROR response payload:
|
||||||
* UNSUPPORTED_OPERATION if the netconf service isn't available. The
|
* <[8] 64-bit network ID>
|
||||||
* payload will be the network ID.
|
|
||||||
*/
|
*/
|
||||||
VERB_NETWORK_CONFIG_REQUEST = 11,
|
VERB_NETWORK_CONFIG_REQUEST = 11,
|
||||||
|
|
||||||
|
@ -594,7 +594,8 @@ public:
|
||||||
*
|
*
|
||||||
* This message can be sent by the network configuration master node
|
* This message can be sent by the network configuration master node
|
||||||
* to request that nodes refresh their network configuration. It can
|
* to request that nodes refresh their network configuration. It can
|
||||||
* thus be used to "push" updates.
|
* thus be used to "push" updates so that network config changes will
|
||||||
|
* take effect quickly.
|
||||||
*
|
*
|
||||||
* It does not generate an OK or ERROR message, and is treated only as
|
* It does not generate an OK or ERROR message, and is treated only as
|
||||||
* a hint to refresh now.
|
* a hint to refresh now.
|
||||||
|
|
|
@ -102,8 +102,8 @@ bool PacketDecoder::tryDecode(const RuntimeEnvironment *_r)
|
||||||
return _doRENDEZVOUS(_r,peer);
|
return _doRENDEZVOUS(_r,peer);
|
||||||
case Packet::VERB_FRAME:
|
case Packet::VERB_FRAME:
|
||||||
return _doFRAME(_r,peer);
|
return _doFRAME(_r,peer);
|
||||||
case Packet::VERB_PROXY_FRAME:
|
case Packet::VERB_BRIDGED_FRAME:
|
||||||
return _doPROXY_FRAME(_r,peer);
|
return _doBRIDGED_FRAME(_r,peer);
|
||||||
case Packet::VERB_MULTICAST_FRAME:
|
case Packet::VERB_MULTICAST_FRAME:
|
||||||
return _doMULTICAST_FRAME(_r,peer);
|
return _doMULTICAST_FRAME(_r,peer);
|
||||||
case Packet::VERB_MULTICAST_LIKE:
|
case Packet::VERB_MULTICAST_LIKE:
|
||||||
|
@ -151,9 +151,6 @@ bool PacketDecoder::_doERROR(const RuntimeEnvironment *_r,const SharedPtr<Peer>
|
||||||
// if (_r->topology->isSupernode(source())) {}
|
// if (_r->topology->isSupernode(source())) {}
|
||||||
break;
|
break;
|
||||||
case Packet::ERROR_NEED_MEMBERSHIP_CERTIFICATE: {
|
case Packet::ERROR_NEED_MEMBERSHIP_CERTIFICATE: {
|
||||||
// TODO: this allows anyone to request a membership cert, which is
|
|
||||||
// harmless until these contain possibly privacy-sensitive info.
|
|
||||||
// Then we'll need to be more careful.
|
|
||||||
SharedPtr<Network> network(_r->nc->network(at<uint64_t>(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD)));
|
SharedPtr<Network> network(_r->nc->network(at<uint64_t>(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD)));
|
||||||
if (network)
|
if (network)
|
||||||
network->pushMembershipCertificate(source(),true,Utils::now());
|
network->pushMembershipCertificate(source(),true,Utils::now());
|
||||||
|
@ -399,7 +396,7 @@ bool PacketDecoder::_doFRAME(const RuntimeEnvironment *_r,const SharedPtr<Peer>
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PacketDecoder::_doPROXY_FRAME(const RuntimeEnvironment *_r,const SharedPtr<Peer> &peer)
|
bool PacketDecoder::_doBRIDGED_FRAME(const RuntimeEnvironment *_r,const SharedPtr<Peer> &peer)
|
||||||
{
|
{
|
||||||
// TODO: bridging is not implemented yet
|
// TODO: bridging is not implemented yet
|
||||||
return true;
|
return true;
|
||||||
|
@ -654,40 +651,44 @@ bool PacketDecoder::_doMULTICAST_LIKE(const RuntimeEnvironment *_r,const SharedP
|
||||||
bool PacketDecoder::_doNETWORK_MEMBERSHIP_CERTIFICATE(const RuntimeEnvironment *_r,const SharedPtr<Peer> &peer)
|
bool PacketDecoder::_doNETWORK_MEMBERSHIP_CERTIFICATE(const RuntimeEnvironment *_r,const SharedPtr<Peer> &peer)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
CertificateOfMembership com(*this,ZT_PROTO_VERB_NETWORK_MEMBERSHIP_CERTIFICATE_IDX_CERTIFICATE);
|
CertificateOfMembership com;
|
||||||
if (!com.hasRequiredFields()) {
|
unsigned int ptr = ZT_PACKET_IDX_PAYLOAD;
|
||||||
TRACE("dropped NETWORK_MEMBERSHIP_CERTIFICATE from %s(%s): invalid cert: at least one required field is missing",source().toString().c_str(),_remoteAddress.toString().c_str());
|
while (ptr < size()) {
|
||||||
return true;
|
ptr += com.deserialize(*this,ptr);
|
||||||
} else if (com.signedBy()) {
|
if (!com.hasRequiredFields()) {
|
||||||
SharedPtr<Peer> signer(_r->topology->getPeer(com.signedBy()));
|
TRACE("dropped NETWORK_MEMBERSHIP_CERTIFICATE from %s(%s): invalid cert: at least one required field is missing",source().toString().c_str(),_remoteAddress.toString().c_str());
|
||||||
if (signer) {
|
return true;
|
||||||
if (com.verify(signer->identity())) {
|
} else if (com.signedBy()) {
|
||||||
uint64_t nwid = com.networkId();
|
SharedPtr<Peer> signer(_r->topology->getPeer(com.signedBy()));
|
||||||
SharedPtr<Network> network(_r->nc->network(nwid));
|
if (signer) {
|
||||||
if (network) {
|
if (com.verify(signer->identity())) {
|
||||||
if (network->controller() == signer) {
|
uint64_t nwid = com.networkId();
|
||||||
network->addMembershipCertificate(com);
|
SharedPtr<Network> network(_r->nc->network(nwid));
|
||||||
return true;
|
if (network) {
|
||||||
|
if (network->controller() == signer) {
|
||||||
|
network->addMembershipCertificate(com);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
TRACE("dropped NETWORK_MEMBERSHIP_CERTIFICATE from %s(%s): signer %s is not the controller for network %.16llx",source().toString().c_str(),_remoteAddress.toString().c_str(),signer->address().toString().c_str(),(unsigned long long)nwid);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
TRACE("dropped NETWORK_MEMBERSHIP_CERTIFICATE from %s(%s): signer %s is not the controller for network %.16llx",source().toString().c_str(),_remoteAddress.toString().c_str(),signer->address().toString().c_str(),(unsigned long long)nwid);
|
TRACE("dropped NETWORK_MEMBERSHIP_CERTIFICATE from %s(%s): not a member of network %.16llx",source().toString().c_str(),_remoteAddress.toString().c_str(),(unsigned long long)nwid);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
TRACE("dropped NETWORK_MEMBERSHIP_CERTIFICATE from %s(%s): not a member of network %.16llx",source().toString().c_str(),_remoteAddress.toString().c_str(),(unsigned long long)nwid);
|
TRACE("dropped NETWORK_MEMBERSHIP_CERTIFICATE from %s(%s): failed signature verification for signer %s",source().toString().c_str(),_remoteAddress.toString().c_str(),signer->address().toString().c_str());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
TRACE("dropped NETWORK_MEMBERSHIP_CERTIFICATE from %s(%s): failed signature verification for signer %s",source().toString().c_str(),_remoteAddress.toString().c_str(),signer->address().toString().c_str());
|
_r->sw->requestWhois(com.signedBy());
|
||||||
return true;
|
_step = DECODE_WAITING_FOR_NETWORK_MEMBERSHIP_CERTIFICATE_SIGNER_LOOKUP;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_r->sw->requestWhois(com.signedBy());
|
TRACE("dropped NETWORK_MEMBERSHIP_CERTIFICATE from %s(%s): invalid cert: no signature",source().toString().c_str(),_remoteAddress.toString().c_str());
|
||||||
_step = DECODE_WAITING_FOR_NETWORK_MEMBERSHIP_CERTIFICATE_SIGNER_LOOKUP;
|
return true;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
TRACE("dropped NETWORK_MEMBERSHIP_CERTIFICATE from %s(%s): invalid cert: no signature",source().toString().c_str(),_remoteAddress.toString().c_str());
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
} catch (std::exception &ex) {
|
} 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());
|
TRACE("dropped NETWORK_MEMBERSHIP_CERTIFICATE from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),ex.what());
|
||||||
|
|
|
@ -117,7 +117,7 @@ private:
|
||||||
bool _doWHOIS(const RuntimeEnvironment *_r,const SharedPtr<Peer> &peer);
|
bool _doWHOIS(const RuntimeEnvironment *_r,const SharedPtr<Peer> &peer);
|
||||||
bool _doRENDEZVOUS(const RuntimeEnvironment *_r,const SharedPtr<Peer> &peer);
|
bool _doRENDEZVOUS(const RuntimeEnvironment *_r,const SharedPtr<Peer> &peer);
|
||||||
bool _doFRAME(const RuntimeEnvironment *_r,const SharedPtr<Peer> &peer);
|
bool _doFRAME(const RuntimeEnvironment *_r,const SharedPtr<Peer> &peer);
|
||||||
bool _doPROXY_FRAME(const RuntimeEnvironment *_r,const SharedPtr<Peer> &peer);
|
bool _doBRIDGED_FRAME(const RuntimeEnvironment *_r,const SharedPtr<Peer> &peer);
|
||||||
bool _doMULTICAST_FRAME(const RuntimeEnvironment *_r,const SharedPtr<Peer> &peer);
|
bool _doMULTICAST_FRAME(const RuntimeEnvironment *_r,const SharedPtr<Peer> &peer);
|
||||||
bool _doMULTICAST_LIKE(const RuntimeEnvironment *_r,const SharedPtr<Peer> &peer);
|
bool _doMULTICAST_LIKE(const RuntimeEnvironment *_r,const SharedPtr<Peer> &peer);
|
||||||
bool _doNETWORK_MEMBERSHIP_CERTIFICATE(const RuntimeEnvironment *_r,const SharedPtr<Peer> &peer);
|
bool _doNETWORK_MEMBERSHIP_CERTIFICATE(const RuntimeEnvironment *_r,const SharedPtr<Peer> &peer);
|
||||||
|
|
|
@ -265,6 +265,7 @@ bool Switch::unite(const Address &p1,const Address &p2,bool force)
|
||||||
|
|
||||||
{ // tell p1 where to find p2
|
{ // tell p1 where to find p2
|
||||||
Packet outp(p1,_r->identity.address(),Packet::VERB_RENDEZVOUS);
|
Packet outp(p1,_r->identity.address(),Packet::VERB_RENDEZVOUS);
|
||||||
|
outp.append((unsigned char)0);
|
||||||
p2.appendTo(outp);
|
p2.appendTo(outp);
|
||||||
outp.append((uint16_t)cg.first.port());
|
outp.append((uint16_t)cg.first.port());
|
||||||
if (cg.first.isV6()) {
|
if (cg.first.isV6()) {
|
||||||
|
@ -279,6 +280,7 @@ bool Switch::unite(const Address &p1,const Address &p2,bool force)
|
||||||
}
|
}
|
||||||
{ // tell p2 where to find p1
|
{ // tell p2 where to find p1
|
||||||
Packet outp(p2,_r->identity.address(),Packet::VERB_RENDEZVOUS);
|
Packet outp(p2,_r->identity.address(),Packet::VERB_RENDEZVOUS);
|
||||||
|
outp.append((unsigned char)0);
|
||||||
p1.appendTo(outp);
|
p1.appendTo(outp);
|
||||||
outp.append((uint16_t)cg.second.port());
|
outp.append((uint16_t)cg.second.port());
|
||||||
if (cg.second.isV6()) {
|
if (cg.second.isV6()) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue