mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-07 13:03:45 +02:00
Cleanup, remove legacy accessors, formatting.
This commit is contained in:
parent
a117c92a1e
commit
a19bc1e826
17 changed files with 630 additions and 615 deletions
|
@ -13,5 +13,5 @@
|
||||||
|
|
||||||
package cli
|
package cli
|
||||||
|
|
||||||
func Controller(basePath, authToken string, args []string, jsonOutput bool) {
|
func Cert(basePath, authToken string, args []string, jsonOutput bool) {
|
||||||
}
|
}
|
|
@ -79,7 +79,7 @@ Commands:
|
||||||
validate <identity> Locally validate an identity
|
validate <identity> Locally validate an identity
|
||||||
sign <identity> <file> Sign a file with an identity's key
|
sign <identity> <file> Sign a file with an identity's key
|
||||||
verify <identity> <file> <sig> Verify a signature
|
verify <identity> <file> <sig> Verify a signature
|
||||||
certificate <command> [args] - Certificate commands
|
cert <command> [args] - Certificate commands
|
||||||
newid Create a new unique subject ID
|
newid Create a new unique subject ID
|
||||||
newcsr <subject json path> Create a new CSR (signing request)
|
newcsr <subject json path> Create a new CSR (signing request)
|
||||||
sign <csr path> <identity path> Sign a CSR to create a certificate
|
sign <csr path> <identity path> Sign a CSR to create a certificate
|
||||||
|
|
|
@ -139,12 +139,13 @@ func main() {
|
||||||
cli.Peers(basePath, authTokenRequired(basePath, *tflag, *tTflag), cmdArgs, *jflag, true)
|
cli.Peers(basePath, authTokenRequired(basePath, *tflag, *tTflag), cmdArgs, *jflag, true)
|
||||||
case "root":
|
case "root":
|
||||||
cli.Root(basePath, authTokenRequired(basePath, *tflag, *tTflag), cmdArgs, *jflag)
|
cli.Root(basePath, authTokenRequired(basePath, *tflag, *tTflag), cmdArgs, *jflag)
|
||||||
|
case "controller":
|
||||||
case "set":
|
case "set":
|
||||||
cli.Set(basePath, authTokenRequired(basePath, *tflag, *tTflag), cmdArgs)
|
cli.Set(basePath, authTokenRequired(basePath, *tflag, *tTflag), cmdArgs)
|
||||||
case "controller":
|
|
||||||
cli.Controller(basePath, authTokenRequired(basePath, *tflag, *tTflag), cmdArgs, *jflag)
|
|
||||||
case "identity":
|
case "identity":
|
||||||
cli.Identity(cmdArgs)
|
cli.Identity(cmdArgs)
|
||||||
|
case "cert":
|
||||||
|
cli.Cert(basePath, authTokenRequired(basePath, *tflag, *tTflag), cmdArgs, *jflag)
|
||||||
}
|
}
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,35 +41,18 @@ struct intl_MapHasher
|
||||||
std::size_t operator()(const O &obj) const noexcept
|
std::size_t operator()(const O &obj) const noexcept
|
||||||
{ return (std::size_t)obj.hashCode(); }
|
{ return (std::size_t)obj.hashCode(); }
|
||||||
std::size_t operator()(const uint64_t i) const noexcept
|
std::size_t operator()(const uint64_t i) const noexcept
|
||||||
{ return (std::size_t)Utils::hash64(i + Utils::s_mapNonce); }
|
{ return (std::size_t)Utils::hash64(i ^ Utils::s_mapNonce); }
|
||||||
std::size_t operator()(const int64_t i) const noexcept
|
std::size_t operator()(const int64_t i) const noexcept
|
||||||
{ return (std::size_t)Utils::hash64((uint64_t)i + Utils::s_mapNonce); }
|
{ return (std::size_t)Utils::hash64((uint64_t)i ^ Utils::s_mapNonce); }
|
||||||
std::size_t operator()(const uint32_t i) const noexcept
|
std::size_t operator()(const uint32_t i) const noexcept
|
||||||
{ return (std::size_t)Utils::hash32(i + (uint32_t)Utils::s_mapNonce); }
|
{ return (std::size_t)Utils::hash32(i ^ (uint32_t)Utils::s_mapNonce); }
|
||||||
std::size_t operator()(const int32_t i) const noexcept
|
std::size_t operator()(const int32_t i) const noexcept
|
||||||
{ return (std::size_t)Utils::hash32((uint32_t)i + (uint32_t)Utils::s_mapNonce); }
|
{ return (std::size_t)Utils::hash32((uint32_t)i ^ (uint32_t)Utils::s_mapNonce); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template< typename K, typename V >
|
template< typename K, typename V >
|
||||||
class Map : public std::unordered_map< K, V, intl_MapHasher >
|
class Map : public std::unordered_map< K, V, intl_MapHasher >
|
||||||
{
|
{};
|
||||||
public:
|
|
||||||
ZT_INLINE V *get(const K &key) noexcept
|
|
||||||
{
|
|
||||||
typename Map::iterator i(this->find(key));
|
|
||||||
if (i == this->end())
|
|
||||||
return nullptr;
|
|
||||||
return &(i->second);
|
|
||||||
}
|
|
||||||
ZT_INLINE const V *get(const K &key) const noexcept
|
|
||||||
{
|
|
||||||
typename Map::const_iterator i(this->find(key));
|
|
||||||
if (i == this->end())
|
|
||||||
return nullptr;
|
|
||||||
return &(i->second);
|
|
||||||
}
|
|
||||||
ZT_INLINE void set(const K &key, const V &value) { this->emplace(key, value); }
|
|
||||||
};
|
|
||||||
|
|
||||||
template< typename K, typename V >
|
template< typename K, typename V >
|
||||||
class MultiMap : public std::unordered_multimap< K, V, intl_MapHasher, std::equal_to< K > >
|
class MultiMap : public std::unordered_multimap< K, V, intl_MapHasher, std::equal_to< K > >
|
||||||
|
@ -78,33 +61,12 @@ class MultiMap : public std::unordered_multimap< K, V, intl_MapHasher, std::equa
|
||||||
#else
|
#else
|
||||||
|
|
||||||
template<typename K, typename V>
|
template<typename K, typename V>
|
||||||
class Map : public std::map< K,V,std::less<K> >
|
class Map : public std::map< K, V >
|
||||||
{
|
{};
|
||||||
public:
|
|
||||||
ZT_INLINE V *get(const K &key) noexcept
|
|
||||||
{
|
|
||||||
typename Map::iterator i(this->find(key));
|
|
||||||
if (i == this->end())
|
|
||||||
return nullptr;
|
|
||||||
return &(i->second);
|
|
||||||
}
|
|
||||||
|
|
||||||
ZT_INLINE const V *get(const K &key) const noexcept
|
|
||||||
{
|
|
||||||
typename Map::const_iterator i(this->find(key));
|
|
||||||
if (i == this->end())
|
|
||||||
return nullptr;
|
|
||||||
return &(i->second);
|
|
||||||
}
|
|
||||||
|
|
||||||
ZT_INLINE void set(const K &key,const V &value)
|
|
||||||
{ (*this)[key] = value; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename K, typename V>
|
template<typename K, typename V>
|
||||||
class MultiMap : public std::multimap< K,V,std::less<K>,Utils::Mallocator< std::pair<const K,V> > >
|
class MultiMap : public std::multimap< K, V >
|
||||||
{
|
{};
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -183,8 +183,10 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get or create message fragment.
|
// Get or create message fragment.
|
||||||
p_E *e = m_messages.get(messageId);
|
Defragmenter< MF, MFP, GCS, GCT, P >::p_E *e;
|
||||||
if (!e) {
|
{
|
||||||
|
typename Map< uint64_t, Defragmenter< MF, MFP, GCS, GCT, P >::p_E >::iterator ee(m_messages.find(messageId));
|
||||||
|
if (ee == m_messages.end()) {
|
||||||
ml.writing(); // acquire write lock on _messages if not already
|
ml.writing(); // acquire write lock on _messages if not already
|
||||||
try {
|
try {
|
||||||
e = &(m_messages[messageId]);
|
e = &(m_messages[messageId]);
|
||||||
|
@ -192,6 +194,9 @@ public:
|
||||||
return ERR_OUT_OF_MEMORY;
|
return ERR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
e->id = messageId;
|
e->id = messageId;
|
||||||
|
} else {
|
||||||
|
e = &(ee->second);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch back to holding only the read lock on _messages if we have locked for write
|
// Switch back to holding only the read lock on _messages if we have locked for write
|
||||||
|
|
|
@ -115,7 +115,7 @@ void Member::pushCredentials(const RuntimeEnvironment *RR, void *tPtr, const int
|
||||||
m_lastPushedCredentials = now;
|
m_lastPushedCredentials = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Member::clean(const int64_t now, const NetworkConfig &nconf)
|
void Member::clean(const NetworkConfig &nconf)
|
||||||
{
|
{
|
||||||
m_cleanCredImpl< TagCredential >(nconf, m_remoteTags);
|
m_cleanCredImpl< TagCredential >(nconf, m_remoteTags);
|
||||||
m_cleanCredImpl< CapabilityCredential >(nconf, m_remoteCaps);
|
m_cleanCredImpl< CapabilityCredential >(nconf, m_remoteCaps);
|
||||||
|
@ -164,18 +164,18 @@ static ZT_INLINE Member::AddCredentialResult _addCredImpl(
|
||||||
const NetworkConfig &nconf,
|
const NetworkConfig &nconf,
|
||||||
const C &cred)
|
const C &cred)
|
||||||
{
|
{
|
||||||
C *rc = remoteCreds.get(cred.id());
|
typename Map< uint32_t, C >::const_iterator rc(remoteCreds.find(cred.id()));
|
||||||
if (rc) {
|
if (rc != remoteCreds.end()) {
|
||||||
if (rc->timestamp() > cred.timestamp()) {
|
if (rc->second.timestamp() > cred.timestamp()) {
|
||||||
RR->t->credentialRejected(tPtr, 0x40000001, nconf.networkId, sourcePeerIdentity, cred.id(), cred.timestamp(), C::credentialType(), ZT_TRACE_CREDENTIAL_REJECTION_REASON_OLDER_THAN_LATEST);
|
RR->t->credentialRejected(tPtr, 0x40000001, nconf.networkId, sourcePeerIdentity, cred.id(), cred.timestamp(), C::credentialType(), ZT_TRACE_CREDENTIAL_REJECTION_REASON_OLDER_THAN_LATEST);
|
||||||
return Member::ADD_REJECTED;
|
return Member::ADD_REJECTED;
|
||||||
}
|
}
|
||||||
if (*rc == cred)
|
if (rc->second == cred)
|
||||||
return Member::ADD_ACCEPTED_REDUNDANT;
|
return Member::ADD_ACCEPTED_REDUNDANT;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int64_t *const rt = revocations.get(Member::credentialKey(C::credentialType(), cred.id()));
|
typename Map< uint64_t, int64_t >::const_iterator rt(revocations.find(Member::credentialKey(C::credentialType(), cred.id())));
|
||||||
if ((rt) && (*rt >= cred.timestamp())) {
|
if ((rt != revocations.end()) && (rt->second >= cred.timestamp())) {
|
||||||
RR->t->credentialRejected(tPtr, 0x24248124, nconf.networkId, sourcePeerIdentity, cred.id(), cred.timestamp(), C::credentialType(), ZT_TRACE_CREDENTIAL_REJECTION_REASON_REVOKED);
|
RR->t->credentialRejected(tPtr, 0x24248124, nconf.networkId, sourcePeerIdentity, cred.id(), cred.timestamp(), C::credentialType(), ZT_TRACE_CREDENTIAL_REJECTION_REASON_REVOKED);
|
||||||
return Member::ADD_REJECTED;
|
return Member::ADD_REJECTED;
|
||||||
}
|
}
|
||||||
|
@ -185,9 +185,8 @@ static ZT_INLINE Member::AddCredentialResult _addCredImpl(
|
||||||
RR->t->credentialRejected(tPtr, 0x01feba012, nconf.networkId, sourcePeerIdentity, cred.id(), cred.timestamp(), C::credentialType(), ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
|
RR->t->credentialRejected(tPtr, 0x01feba012, nconf.networkId, sourcePeerIdentity, cred.id(), cred.timestamp(), C::credentialType(), ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
|
||||||
return Member::ADD_REJECTED;
|
return Member::ADD_REJECTED;
|
||||||
case 0:
|
case 0:
|
||||||
if (!rc)
|
if (rc == remoteCreds.end())
|
||||||
rc = &(remoteCreds[cred.id()]);
|
remoteCreds[cred.id()] = cred;
|
||||||
*rc = cred;
|
|
||||||
return Member::ADD_ACCEPTED_NEW;
|
return Member::ADD_ACCEPTED_NEW;
|
||||||
case 1:
|
case 1:
|
||||||
return Member::ADD_DEFERRED_FOR_WHOIS;
|
return Member::ADD_DEFERRED_FOR_WHOIS;
|
||||||
|
|
|
@ -73,17 +73,16 @@ public:
|
||||||
*/
|
*/
|
||||||
ZT_INLINE const TagCredential *getTag(const NetworkConfig &nconf, const uint32_t id) const noexcept
|
ZT_INLINE const TagCredential *getTag(const NetworkConfig &nconf, const uint32_t id) const noexcept
|
||||||
{
|
{
|
||||||
const TagCredential *const t = m_remoteTags.get(id);
|
Map< uint32_t, TagCredential >::const_iterator t(m_remoteTags.find(id));
|
||||||
return (((t)&&(m_isCredentialTimestampValid(nconf, *t))) ? t : (TagCredential *)0);
|
return (((t != m_remoteTags.end())&&(m_isCredentialTimestampValid(nconf, t->second))) ? &(t->second) : (TagCredential *)0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clean internal databases of stale entries
|
* Clean internal databases of stale entries
|
||||||
*
|
*
|
||||||
* @param now Current time
|
|
||||||
* @param nconf Current network configuration
|
* @param nconf Current network configuration
|
||||||
*/
|
*/
|
||||||
void clean(int64_t now,const NetworkConfig &nconf);
|
void clean(const NetworkConfig &nconf);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a key for internal use in indexing credentials by type and credential ID
|
* Generates a key for internal use in indexing credentials by type and credential ID
|
||||||
|
@ -166,8 +165,8 @@ private:
|
||||||
{
|
{
|
||||||
const int64_t ts = remoteCredential.timestamp();
|
const int64_t ts = remoteCredential.timestamp();
|
||||||
if (((ts >= nconf.timestamp) ? (ts - nconf.timestamp) : (nconf.timestamp - ts)) <= nconf.credentialTimeMaxDelta) {
|
if (((ts >= nconf.timestamp) ? (ts - nconf.timestamp) : (nconf.timestamp - ts)) <= nconf.credentialTimeMaxDelta) {
|
||||||
const int64_t *threshold = m_revocations.get(credentialKey(C::credentialType(), remoteCredential.id()));
|
Map< uint64_t, int64_t >::const_iterator threshold(m_revocations.find(credentialKey(C::credentialType(), remoteCredential.id())));
|
||||||
return ((!threshold)||(ts > *threshold));
|
return ((threshold == m_revocations.end())||(ts > threshold->second));
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,7 +140,8 @@ _doZtFilterResult _doZtFilter(
|
||||||
ccWatch = (rt == ZT_NETWORK_RULE_ACTION_WATCH);
|
ccWatch = (rt == ZT_NETWORK_RULE_ACTION_WATCH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} continue;
|
}
|
||||||
|
continue;
|
||||||
|
|
||||||
case ZT_NETWORK_RULE_ACTION_BREAK:
|
case ZT_NETWORK_RULE_ACTION_BREAK:
|
||||||
return DOZTFILTER_NO_MATCH;
|
return DOZTFILTER_NO_MATCH;
|
||||||
|
@ -408,7 +409,8 @@ _doZtFilterResult _doZtFilter(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
thisRuleMatches = (uint8_t)((cf & rules[rn].v.characteristics) != 0);
|
thisRuleMatches = (uint8_t)((cf & rules[rn].v.characteristics) != 0);
|
||||||
} break;
|
}
|
||||||
|
break;
|
||||||
case ZT_NETWORK_RULE_MATCH_FRAME_SIZE_RANGE:
|
case ZT_NETWORK_RULE_MATCH_FRAME_SIZE_RANGE:
|
||||||
thisRuleMatches = (uint8_t)((frameLen >= (unsigned int)rules[rn].v.frameSize[0]) && (frameLen <= (unsigned int)rules[rn].v.frameSize[1]));
|
thisRuleMatches = (uint8_t)((frameLen >= (unsigned int)rules[rn].v.frameSize[0]) && (frameLen <= (unsigned int)rules[rn].v.frameSize[1]));
|
||||||
break;
|
break;
|
||||||
|
@ -455,7 +457,8 @@ _doZtFilterResult _doZtFilter(
|
||||||
} else {
|
} else {
|
||||||
thisRuleMatches = 0;
|
thisRuleMatches = 0;
|
||||||
}
|
}
|
||||||
} break;
|
}
|
||||||
|
break;
|
||||||
case ZT_NETWORK_RULE_MATCH_TAG_SENDER:
|
case ZT_NETWORK_RULE_MATCH_TAG_SENDER:
|
||||||
case ZT_NETWORK_RULE_MATCH_TAG_RECEIVER: {
|
case ZT_NETWORK_RULE_MATCH_TAG_RECEIVER: {
|
||||||
if (superAccept) {
|
if (superAccept) {
|
||||||
|
@ -481,7 +484,8 @@ _doZtFilterResult _doZtFilter(
|
||||||
thisRuleMatches = 0;
|
thisRuleMatches = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} break;
|
}
|
||||||
|
break;
|
||||||
case ZT_NETWORK_RULE_MATCH_INTEGER_RANGE: {
|
case ZT_NETWORK_RULE_MATCH_INTEGER_RANGE: {
|
||||||
uint64_t integer = 0;
|
uint64_t integer = 0;
|
||||||
const unsigned int bits = (rules[rn].v.intRange.format & 63U) + 1;
|
const unsigned int bits = (rules[rn].v.intRange.format & 63U) + 1;
|
||||||
|
@ -510,7 +514,8 @@ _doZtFilterResult _doZtFilter(
|
||||||
integer >>= (64 - bits);
|
integer >>= (64 - bits);
|
||||||
}
|
}
|
||||||
thisRuleMatches = (uint8_t)((integer >= rules[rn].v.intRange.start) && (integer <= (rules[rn].v.intRange.start + (uint64_t)rules[rn].v.intRange.end)));
|
thisRuleMatches = (uint8_t)((integer >= rules[rn].v.intRange.start) && (integer <= (rules[rn].v.intRange.start + (uint64_t)rules[rn].v.intRange.end)));
|
||||||
} break;
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
// The result of an unsupported MATCH is configurable at the network
|
// The result of an unsupported MATCH is configurable at the network
|
||||||
// level via a flag.
|
// level via a flag.
|
||||||
|
@ -551,7 +556,8 @@ Network::Network(const RuntimeEnvironment *renv,void *tPtr,uint64_t nwid,const F
|
||||||
m_lastConfigUpdate = 0; // still want to re-request since it's likely outdated
|
m_lastConfigUpdate = 0; // still want to re-request since it's likely outdated
|
||||||
} else {
|
} else {
|
||||||
uint64_t tmp[2];
|
uint64_t tmp[2];
|
||||||
tmp[0] = nwid; tmp[1] = 0;
|
tmp[0] = nwid;
|
||||||
|
tmp[1] = 0;
|
||||||
|
|
||||||
bool got = false;
|
bool got = false;
|
||||||
try {
|
try {
|
||||||
|
@ -626,7 +632,14 @@ bool Network::filterOutgoingPacket(
|
||||||
Mutex::Lock l1(m_memberships_l);
|
Mutex::Lock l1(m_memberships_l);
|
||||||
Mutex::Lock l2(m_config_l);
|
Mutex::Lock l2(m_config_l);
|
||||||
|
|
||||||
Member *const membership = (ztDest) ? m_memberships.get(ztDest) : nullptr;
|
Member *membership;
|
||||||
|
if (ztDest) {
|
||||||
|
Map<Address, Member>::iterator mm(m_memberships.find(ztDest));
|
||||||
|
if (mm != m_memberships.end())
|
||||||
|
membership = &(mm->second);
|
||||||
|
} else {
|
||||||
|
membership = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
switch (_doZtFilter(RR, rrl, m_config, membership, false, ztSource, ztFinalDest, macSource, macDest, frameData, frameLen, etherType, vlanId, m_config.rules, m_config.ruleCount, cc, ccLength, ccWatch, qosBucket)) {
|
switch (_doZtFilter(RR, rrl, m_config, membership, false, ztSource, ztFinalDest, macSource, macDest, frameData, frameLen, etherType, vlanId, m_config.rules, m_config.ruleCount, cc, ccLength, ccWatch, qosBucket)) {
|
||||||
|
|
||||||
|
@ -667,7 +680,8 @@ bool Network::filterOutgoingPacket(
|
||||||
if (accept)
|
if (accept)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} break;
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case DOZTFILTER_DROP:
|
case DOZTFILTER_DROP:
|
||||||
RR->t->networkFilter(tPtr, 0xadea5a2a, m_id, rrl.l, nullptr, 0, 0, ztSource, ztDest, macSource, macDest, (uint16_t)frameLen, frameData, (uint16_t)etherType, (uint16_t)vlanId, noTee, false, 0);
|
RR->t->networkFilter(tPtr, 0xadea5a2a, m_id, rrl.l, nullptr, 0, 0, ztSource, ztDest, macSource, macDest, (uint16_t)frameLen, frameData, (uint16_t)etherType, (uint16_t)vlanId, noTee, false, 0);
|
||||||
|
@ -794,7 +808,8 @@ int Network::filterIncomingPacket(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} break;
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case DOZTFILTER_DROP:
|
case DOZTFILTER_DROP:
|
||||||
//if (_config.remoteTraceTarget)
|
//if (_config.remoteTraceTarget)
|
||||||
|
@ -1050,7 +1065,8 @@ int Network::setConfiguration(void *tPtr,const NetworkConfig &nconf,bool saveToD
|
||||||
Dictionary d;
|
Dictionary d;
|
||||||
if (nconf.toDictionary(d)) {
|
if (nconf.toDictionary(d)) {
|
||||||
uint64_t tmp[2];
|
uint64_t tmp[2];
|
||||||
tmp[0] = m_id; tmp[1] = 0;
|
tmp[0] = m_id;
|
||||||
|
tmp[1] = 0;
|
||||||
Vector< uint8_t > d2;
|
Vector< uint8_t > d2;
|
||||||
d.encode(d2);
|
d.encode(d2);
|
||||||
RR->node->stateObjectPut(tPtr, ZT_STATE_OBJECT_NETWORK_CONFIG, tmp, d2.data(), (unsigned int)d2.size());
|
RR->node->stateObjectPut(tPtr, ZT_STATE_OBJECT_NETWORK_CONFIG, tmp, d2.data(), (unsigned int)d2.size());
|
||||||
|
@ -1074,15 +1090,7 @@ bool Network::gate(void *tPtr,const SharedPtr<Peer> &peer) noexcept
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Mutex::Lock l(m_memberships_l);
|
Mutex::Lock l(m_memberships_l);
|
||||||
Member *m = m_memberships.get(peer->address());
|
return m_memberships[peer->address()].certificateOfMembershipAgress(m_config.com, peer->identity());
|
||||||
if (m) {
|
|
||||||
// SECURITY: this method in CertificateOfMembership does a full fingerprint check as well as
|
|
||||||
// checking certificate agreement. See Membership.hpp.
|
|
||||||
return m->certificateOfMembershipAgress(m_config.com, peer->identity());
|
|
||||||
} else {
|
|
||||||
m = &(m_memberships[peer->address()]);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} catch (...) {}
|
} catch (...) {}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -1100,7 +1108,7 @@ void Network::doPeriodicTasks(void *tPtr,const int64_t now)
|
||||||
Mutex::Lock l1(m_memberships_l);
|
Mutex::Lock l1(m_memberships_l);
|
||||||
|
|
||||||
for (Map< Address, Member >::iterator i(m_memberships.begin()); i != m_memberships.end(); ++i)
|
for (Map< Address, Member >::iterator i(m_memberships.begin()); i != m_memberships.end(); ++i)
|
||||||
i->second.clean(now, m_config);
|
i->second.clean(m_config);
|
||||||
|
|
||||||
{
|
{
|
||||||
Mutex::Lock l2(m_myMulticastGroups_l);
|
Mutex::Lock l2(m_myMulticastGroups_l);
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
|
|
||||||
class RuntimeEnvironment;
|
class RuntimeEnvironment;
|
||||||
|
|
||||||
class Peer;
|
class Peer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -50,7 +51,8 @@ public:
|
||||||
/**
|
/**
|
||||||
* Compute primary controller device ID from network ID
|
* Compute primary controller device ID from network ID
|
||||||
*/
|
*/
|
||||||
static ZT_INLINE Address controllerFor(uint64_t nwid) noexcept { return Address(nwid >> 24U); }
|
static ZT_INLINE Address controllerFor(uint64_t nwid) noexcept
|
||||||
|
{ return Address(nwid >> 24U); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new network
|
* Construct a new network
|
||||||
|
@ -69,14 +71,29 @@ public:
|
||||||
|
|
||||||
~Network();
|
~Network();
|
||||||
|
|
||||||
ZT_INLINE uint64_t id() const noexcept { return m_id; }
|
ZT_INLINE uint64_t id() const noexcept
|
||||||
ZT_INLINE Address controller() const noexcept { return Address(m_id >> 24U); }
|
{ return m_id; }
|
||||||
ZT_INLINE bool multicastEnabled() const noexcept { return (m_config.multicastLimit > 0); }
|
|
||||||
ZT_INLINE bool hasConfig() const noexcept { return (m_config); }
|
ZT_INLINE Address controller() const noexcept
|
||||||
ZT_INLINE uint64_t lastConfigUpdate() const noexcept { return m_lastConfigUpdate; }
|
{ return Address(m_id >> 24U); }
|
||||||
ZT_INLINE ZT_VirtualNetworkStatus status() const noexcept { return m_status(); }
|
|
||||||
ZT_INLINE const NetworkConfig &config() const noexcept { return m_config; }
|
ZT_INLINE bool multicastEnabled() const noexcept
|
||||||
ZT_INLINE const MAC &mac() const noexcept { return m_mac; }
|
{ return (m_config.multicastLimit > 0); }
|
||||||
|
|
||||||
|
ZT_INLINE bool hasConfig() const noexcept
|
||||||
|
{ return (m_config); }
|
||||||
|
|
||||||
|
ZT_INLINE uint64_t lastConfigUpdate() const noexcept
|
||||||
|
{ return m_lastConfigUpdate; }
|
||||||
|
|
||||||
|
ZT_INLINE ZT_VirtualNetworkStatus status() const noexcept
|
||||||
|
{ return m_status(); }
|
||||||
|
|
||||||
|
ZT_INLINE const NetworkConfig &config() const noexcept
|
||||||
|
{ return m_config; }
|
||||||
|
|
||||||
|
ZT_INLINE const MAC &mac() const noexcept
|
||||||
|
{ return m_mac; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply filters to an outgoing packet
|
* Apply filters to an outgoing packet
|
||||||
|
@ -208,12 +225,14 @@ public:
|
||||||
/**
|
/**
|
||||||
* Set netconf failure to 'access denied' -- called in IncomingPacket when controller reports this
|
* Set netconf failure to 'access denied' -- called in IncomingPacket when controller reports this
|
||||||
*/
|
*/
|
||||||
ZT_INLINE void setAccessDenied() noexcept { _netconfFailure = NETCONF_FAILURE_ACCESS_DENIED; }
|
ZT_INLINE void setAccessDenied() noexcept
|
||||||
|
{ _netconfFailure = NETCONF_FAILURE_ACCESS_DENIED; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set netconf failure to 'not found' -- called by IncomingPacket when controller reports this
|
* Set netconf failure to 'not found' -- called by IncomingPacket when controller reports this
|
||||||
*/
|
*/
|
||||||
ZT_INLINE void setNotFound() noexcept { _netconfFailure = NETCONF_FAILURE_NOT_FOUND; }
|
ZT_INLINE void setNotFound() noexcept
|
||||||
|
{ _netconfFailure = NETCONF_FAILURE_NOT_FOUND; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine whether this peer is permitted to communicate on this network
|
* Determine whether this peer is permitted to communicate on this network
|
||||||
|
@ -237,8 +256,8 @@ public:
|
||||||
ZT_INLINE Address findBridgeTo(const MAC &mac) const
|
ZT_INLINE Address findBridgeTo(const MAC &mac) const
|
||||||
{
|
{
|
||||||
Mutex::Lock _l(m_remoteBridgeRoutes_l);
|
Mutex::Lock _l(m_remoteBridgeRoutes_l);
|
||||||
const Address *const br = m_remoteBridgeRoutes.get(mac);
|
Map< MAC, Address >::const_iterator br(m_remoteBridgeRoutes.find(mac));
|
||||||
return ((br) ? *br : Address());
|
return ((br == m_remoteBridgeRoutes.end()) ? Address() : br->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -259,7 +278,7 @@ public:
|
||||||
ZT_INLINE void learnBridgedMulticastGroup(void *tPtr, const MulticastGroup &mg, int64_t now)
|
ZT_INLINE void learnBridgedMulticastGroup(void *tPtr, const MulticastGroup &mg, int64_t now)
|
||||||
{
|
{
|
||||||
Mutex::Lock l(m_myMulticastGroups_l);
|
Mutex::Lock l(m_myMulticastGroups_l);
|
||||||
m_multicastGroupsBehindMe.set(mg, now);
|
m_multicastGroupsBehindMe[mg] = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -329,14 +348,19 @@ public:
|
||||||
/**
|
/**
|
||||||
* @return Externally usable pointer-to-pointer exported via the core API
|
* @return Externally usable pointer-to-pointer exported via the core API
|
||||||
*/
|
*/
|
||||||
ZT_INLINE void **userPtr() noexcept { return &m_uPtr; }
|
ZT_INLINE void **userPtr() noexcept
|
||||||
|
{ return &m_uPtr; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void m_requestConfiguration(void *tPtr);
|
void m_requestConfiguration(void *tPtr);
|
||||||
|
|
||||||
ZT_VirtualNetworkStatus m_status() const;
|
ZT_VirtualNetworkStatus m_status() const;
|
||||||
|
|
||||||
void m_externalConfig(ZT_VirtualNetworkConfig *ec) const; // assumes _lock is locked
|
void m_externalConfig(ZT_VirtualNetworkConfig *ec) const; // assumes _lock is locked
|
||||||
void m_announceMulticastGroups(void *tPtr, bool force);
|
void m_announceMulticastGroups(void *tPtr, bool force);
|
||||||
|
|
||||||
void m_announceMulticastGroupsTo(void *tPtr, const Address &peer, const Vector< MulticastGroup > &allMulticastGroups);
|
void m_announceMulticastGroupsTo(void *tPtr, const Address &peer, const Vector< MulticastGroup > &allMulticastGroups);
|
||||||
|
|
||||||
Vector< MulticastGroup > m_allMulticastGroups() const;
|
Vector< MulticastGroup > m_allMulticastGroups() const;
|
||||||
|
|
||||||
const RuntimeEnvironment *const RR;
|
const RuntimeEnvironment *const RR;
|
||||||
|
@ -354,7 +378,8 @@ private:
|
||||||
NetworkConfig m_config;
|
NetworkConfig m_config;
|
||||||
std::atomic< int64_t > m_lastConfigUpdate;
|
std::atomic< int64_t > m_lastConfigUpdate;
|
||||||
|
|
||||||
volatile enum {
|
volatile enum
|
||||||
|
{
|
||||||
NETCONF_FAILURE_NONE,
|
NETCONF_FAILURE_NONE,
|
||||||
NETCONF_FAILURE_ACCESS_DENIED,
|
NETCONF_FAILURE_ACCESS_DENIED,
|
||||||
NETCONF_FAILURE_NOT_FOUND,
|
NETCONF_FAILURE_NOT_FOUND,
|
||||||
|
|
|
@ -678,10 +678,11 @@ bool Node::externalPathLookup(void *tPtr, const Identity &id, int family, InetAd
|
||||||
bool Node::localControllerHasAuthorized(const int64_t now, const uint64_t nwid, const Address &addr) const
|
bool Node::localControllerHasAuthorized(const int64_t now, const uint64_t nwid, const Address &addr) const
|
||||||
{
|
{
|
||||||
m_localControllerAuthorizations_l.lock();
|
m_localControllerAuthorizations_l.lock();
|
||||||
const int64_t *const at = m_localControllerAuthorizations.get(p_LocalControllerAuth(nwid, addr));
|
Map<Node::p_LocalControllerAuth, int64_t>::const_iterator i(m_localControllerAuthorizations.find(p_LocalControllerAuth(nwid, addr)));
|
||||||
|
const int64_t at = (i == m_localControllerAuthorizations.end()) ? -1LL : i->second;
|
||||||
m_localControllerAuthorizations_l.unlock();
|
m_localControllerAuthorizations_l.unlock();
|
||||||
if (at)
|
if (at > 0)
|
||||||
return ((now - *at) < (ZT_NETWORK_AUTOCONF_DELAY * 3));
|
return ((now - at) < (ZT_NETWORK_AUTOCONF_DELAY * 3));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -225,9 +225,9 @@ public:
|
||||||
ZT_INLINE SharedPtr< Network > network(const uint64_t nwid) const noexcept
|
ZT_INLINE SharedPtr< Network > network(const uint64_t nwid) const noexcept
|
||||||
{
|
{
|
||||||
RWMutex::RLock l(m_networks_l);
|
RWMutex::RLock l(m_networks_l);
|
||||||
const SharedPtr<Network> *const n = m_networks.get(nwid);
|
Map< uint64_t, SharedPtr< Network > >::const_iterator n(m_networks.find(nwid));
|
||||||
if (n)
|
if (likely(n != m_networks.end()))
|
||||||
return *n;
|
return n->second;
|
||||||
return SharedPtr< Network >();
|
return SharedPtr< Network >();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -416,6 +416,20 @@ void Topology::m_loadCached(void *tPtr, const Address &zta, SharedPtr< Peer > &p
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SharedPtr< Peer > Topology::m_peerFromCached(void *tPtr, const Address &zta)
|
||||||
|
{
|
||||||
|
SharedPtr< Peer > p;
|
||||||
|
m_loadCached(tPtr, zta, p);
|
||||||
|
if (p) {
|
||||||
|
RWMutex::Lock l(m_peers_l);
|
||||||
|
SharedPtr< Peer > &hp = m_peers[zta];
|
||||||
|
if (hp)
|
||||||
|
return hp;
|
||||||
|
hp = p;
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
void Topology::m_updateRootPeers_l_roots_certs(void *tPtr)
|
void Topology::m_updateRootPeers_l_roots_certs(void *tPtr)
|
||||||
{
|
{
|
||||||
// assumes m_roots_l and m_certs_l are locked for write
|
// assumes m_roots_l and m_certs_l are locked for write
|
||||||
|
|
|
@ -65,24 +65,13 @@ public:
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
RWMutex::RLock l(m_peers_l);
|
RWMutex::RLock l(m_peers_l);
|
||||||
const SharedPtr< Peer > *const ap = m_peers.get(zta);
|
Map< Address, SharedPtr< Peer > >::const_iterator ap(m_peers.find(zta));
|
||||||
if (likely(ap != nullptr))
|
if (likely(ap != m_peers.end()))
|
||||||
return *ap;
|
return ap->second;
|
||||||
}
|
|
||||||
{
|
|
||||||
SharedPtr< Peer > p;
|
|
||||||
if (loadFromCached) {
|
|
||||||
m_loadCached(tPtr, zta, p);
|
|
||||||
if (p) {
|
|
||||||
RWMutex::Lock l(m_peers_l);
|
|
||||||
SharedPtr< Peer > &hp = m_peers[zta];
|
|
||||||
if (hp)
|
|
||||||
return hp;
|
|
||||||
hp = p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
|
if (loadFromCached)
|
||||||
|
return m_peerFromCached(tPtr, zta);
|
||||||
|
return SharedPtr< Peer >();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -97,9 +86,9 @@ public:
|
||||||
const UniqueID k(r.key());
|
const UniqueID k(r.key());
|
||||||
{
|
{
|
||||||
RWMutex::RLock lck(m_paths_l);
|
RWMutex::RLock lck(m_paths_l);
|
||||||
SharedPtr< Path > *const p = m_paths.get(k);
|
Map< UniqueID, SharedPtr< Path > >::const_iterator p(m_paths.find(k));
|
||||||
if (likely(p != nullptr))
|
if (likely(p != m_paths.end()))
|
||||||
return *p;
|
return p->second;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
SharedPtr< Path > p(new Path(l, r));
|
SharedPtr< Path > p(new Path(l, r));
|
||||||
|
@ -231,11 +220,19 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void m_eraseCertificate_l_certs(const SharedPtr< const Certificate > &cert);
|
void m_eraseCertificate_l_certs(const SharedPtr< const Certificate > &cert);
|
||||||
|
|
||||||
bool m_cleanCertificates_l_certs(int64_t now);
|
bool m_cleanCertificates_l_certs(int64_t now);
|
||||||
|
|
||||||
bool m_verifyCertificateChain_l_certs(const Certificate *current, const int64_t now) const;
|
bool m_verifyCertificateChain_l_certs(const Certificate *current, const int64_t now) const;
|
||||||
|
|
||||||
ZT_CertificateError m_verifyCertificate_l_certs(const Certificate &cert, const int64_t now, unsigned int localTrust, bool skipSignatureCheck) const;
|
ZT_CertificateError m_verifyCertificate_l_certs(const Certificate &cert, const int64_t now, unsigned int localTrust, bool skipSignatureCheck) const;
|
||||||
|
|
||||||
void m_loadCached(void *tPtr, const Address &zta, SharedPtr< Peer > &peer);
|
void m_loadCached(void *tPtr, const Address &zta, SharedPtr< Peer > &peer);
|
||||||
|
|
||||||
|
SharedPtr< Peer > m_peerFromCached(void *tPtr, const Address &zta);
|
||||||
|
|
||||||
void m_updateRootPeers_l_roots_certs(void *tPtr);
|
void m_updateRootPeers_l_roots_certs(void *tPtr);
|
||||||
|
|
||||||
void m_writeTrustStore_l_roots_certs(void *tPtr) const;
|
void m_writeTrustStore_l_roots_certs(void *tPtr) const;
|
||||||
|
|
||||||
const RuntimeEnvironment *const RR;
|
const RuntimeEnvironment *const RR;
|
||||||
|
|
|
@ -53,10 +53,10 @@ uint32_t Arp::processIncomingArp(const void *arp,unsigned int len,void *response
|
||||||
if (len >= 28) {
|
if (len >= 28) {
|
||||||
if (!memcmp(arp, ARP_REQUEST_HEADER, 8)) {
|
if (!memcmp(arp, ARP_REQUEST_HEADER, 8)) {
|
||||||
// Respond to ARP requests for locally-known IPs
|
// Respond to ARP requests for locally-known IPs
|
||||||
_ArpEntry *targetEntry = _cache.get(reinterpret_cast<const uint32_t *>(arp)[6]);
|
Map< uint32_t, Arp::_ArpEntry >::const_iterator targetEntry(_cache.find(reinterpret_cast<const uint32_t *>(arp)[6]));
|
||||||
if ((targetEntry)&&(targetEntry->local)) {
|
if ((targetEntry != _cache.end()) && (targetEntry->second.local)) {
|
||||||
memcpy(response, ARP_RESPONSE_HEADER, 8);
|
memcpy(response, ARP_RESPONSE_HEADER, 8);
|
||||||
targetEntry->mac.copyTo(reinterpret_cast<uint8_t *>(response) + 8);
|
targetEntry->second.mac.copyTo(reinterpret_cast<uint8_t *>(response) + 8);
|
||||||
memcpy(reinterpret_cast<uint8_t *>(response) + 14, reinterpret_cast<const uint8_t *>(arp) + 24, 4);
|
memcpy(reinterpret_cast<uint8_t *>(response) + 14, reinterpret_cast<const uint8_t *>(arp) + 24, 4);
|
||||||
memcpy(reinterpret_cast<uint8_t *>(response) + 18, reinterpret_cast<const uint8_t *>(arp) + 8, 10);
|
memcpy(reinterpret_cast<uint8_t *>(response) + 18, reinterpret_cast<const uint8_t *>(arp) + 8, 10);
|
||||||
responseLen = 28;
|
responseLen = 28;
|
||||||
|
@ -66,10 +66,10 @@ uint32_t Arp::processIncomingArp(const void *arp,unsigned int len,void *response
|
||||||
// Learn cache entries for remote IPs from relevant ARP replies
|
// Learn cache entries for remote IPs from relevant ARP replies
|
||||||
uint32_t responseIp = 0;
|
uint32_t responseIp = 0;
|
||||||
memcpy(&responseIp, reinterpret_cast<const uint8_t *>(arp) + 14, 4);
|
memcpy(&responseIp, reinterpret_cast<const uint8_t *>(arp) + 14, 4);
|
||||||
_ArpEntry *queryEntry = _cache.get(responseIp);
|
Map< uint32_t, Arp::_ArpEntry >::iterator queryEntry(_cache.find(responseIp));
|
||||||
if ((queryEntry)&&(!queryEntry->local)&&((now - queryEntry->lastQuerySent) <= ZT_ARP_QUERY_MAX_TTL)) {
|
if ((queryEntry != _cache.end()) && (!queryEntry->second.local) && ((now - queryEntry->second.lastQuerySent) <= ZT_ARP_QUERY_MAX_TTL)) {
|
||||||
queryEntry->lastResponseReceived = now;
|
queryEntry->second.lastResponseReceived = now;
|
||||||
queryEntry->mac.setTo(reinterpret_cast<const uint8_t *>(arp) + 8);
|
queryEntry->second.mac.setTo(reinterpret_cast<const uint8_t *>(arp) + 8);
|
||||||
ip = responseIp;
|
ip = responseIp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,10 +98,14 @@ MAC Arp::query(const MAC &localMac,uint32_t localIp,uint32_t targetIp,void *quer
|
||||||
e.lastQuerySent = now;
|
e.lastQuerySent = now;
|
||||||
|
|
||||||
uint8_t *q = reinterpret_cast<uint8_t *>(query);
|
uint8_t *q = reinterpret_cast<uint8_t *>(query);
|
||||||
memcpy(q,ARP_REQUEST_HEADER,8); q += 8; // ARP request header information, always the same
|
memcpy(q, ARP_REQUEST_HEADER, 8);
|
||||||
localMac.copyTo(q); q += 6; // sending host MAC address
|
q += 8; // ARP request header information, always the same
|
||||||
memcpy(q,&localIp,4); q += 4; // sending host IP (IP already in big-endian byte order)
|
localMac.copyTo(q);
|
||||||
memset(q,0,6); q += 6; // sending zeros for target MAC address as thats what we want to find
|
q += 6; // sending host MAC address
|
||||||
|
memcpy(q, &localIp, 4);
|
||||||
|
q += 4; // sending host IP (IP already in big-endian byte order)
|
||||||
|
memset(q, 0, 6);
|
||||||
|
q += 6; // sending zeros for target MAC address as thats what we want to find
|
||||||
memcpy(q, &targetIp, 4); // target IP address for resolution (IP already in big-endian byte order)
|
memcpy(q, &targetIp, 4); // target IP address for resolution (IP already in big-endian byte order)
|
||||||
queryLen = 28;
|
queryLen = 28;
|
||||||
if (e.mac)
|
if (e.mac)
|
||||||
|
|
|
@ -69,6 +69,7 @@ public:
|
||||||
void removeAddress(const InetAddress &addr, const char *iface);
|
void removeAddress(const InetAddress &addr, const char *iface);
|
||||||
|
|
||||||
void threadMain() throw();
|
void threadMain() throw();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int _doRecv(int fd);
|
int _doRecv(int fd);
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,8 @@ uint16_t calc_checksum (uint16_t *addr, int len)
|
||||||
return (answer);
|
return (answer);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct _pseudo_header {
|
struct _pseudo_header
|
||||||
|
{
|
||||||
uint8_t sourceAddr[16];
|
uint8_t sourceAddr[16];
|
||||||
uint8_t targetAddr[16];
|
uint8_t targetAddr[16];
|
||||||
uint32_t length;
|
uint32_t length;
|
||||||
|
@ -58,10 +59,10 @@ struct _pseudo_header {
|
||||||
uint8_t next; // 58
|
uint8_t next; // 58
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _option {
|
struct _option
|
||||||
|
{
|
||||||
_option(int optionType)
|
_option(int optionType)
|
||||||
: type(optionType)
|
: type(optionType), length(8)
|
||||||
, length(8)
|
|
||||||
{
|
{
|
||||||
memset(mac, 0, sizeof(mac));
|
memset(mac, 0, sizeof(mac));
|
||||||
}
|
}
|
||||||
|
@ -71,18 +72,17 @@ struct _option {
|
||||||
uint8_t mac[6];
|
uint8_t mac[6];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _neighbor_solicitation {
|
struct _neighbor_solicitation
|
||||||
|
{
|
||||||
_neighbor_solicitation()
|
_neighbor_solicitation()
|
||||||
: type(135)
|
: type(135), code(0), checksum(0), option(1)
|
||||||
, code(0)
|
|
||||||
, checksum(0)
|
|
||||||
, option(1)
|
|
||||||
{
|
{
|
||||||
memset(&reserved, 0, sizeof(reserved));
|
memset(&reserved, 0, sizeof(reserved));
|
||||||
memset(target, 0, sizeof(target));
|
memset(target, 0, sizeof(target));
|
||||||
}
|
}
|
||||||
|
|
||||||
void calculateChecksum(const sockaddr_storage &sourceIp, const sockaddr_storage &destIp) {
|
void calculateChecksum(const sockaddr_storage &sourceIp, const sockaddr_storage &destIp)
|
||||||
|
{
|
||||||
_pseudo_header ph;
|
_pseudo_header ph;
|
||||||
memset(&ph, 0, sizeof(_pseudo_header));
|
memset(&ph, 0, sizeof(_pseudo_header));
|
||||||
const sockaddr_in6 *src = (const sockaddr_in6 *)&sourceIp;
|
const sockaddr_in6 *src = (const sockaddr_in6 *)&sourceIp;
|
||||||
|
@ -112,19 +112,17 @@ struct _neighbor_solicitation {
|
||||||
_option option;
|
_option option;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _neighbor_advertisement {
|
struct _neighbor_advertisement
|
||||||
|
{
|
||||||
_neighbor_advertisement()
|
_neighbor_advertisement()
|
||||||
: type(136)
|
: type(136), code(0), checksum(0), rso(0x40), option(2)
|
||||||
, code(0)
|
|
||||||
, checksum(0)
|
|
||||||
, rso(0x40)
|
|
||||||
, option(2)
|
|
||||||
{
|
{
|
||||||
memset(padding, 0, sizeof(padding));
|
memset(padding, 0, sizeof(padding));
|
||||||
memset(target, 0, sizeof(target));
|
memset(target, 0, sizeof(target));
|
||||||
}
|
}
|
||||||
|
|
||||||
void calculateChecksum(const sockaddr_storage &sourceIp, const InetAddress &destIp) {
|
void calculateChecksum(const sockaddr_storage &sourceIp, const InetAddress &destIp)
|
||||||
|
{
|
||||||
_pseudo_header ph;
|
_pseudo_header ph;
|
||||||
memset(&ph, 0, sizeof(_pseudo_header));
|
memset(&ph, 0, sizeof(_pseudo_header));
|
||||||
const sockaddr_in6 *src = (const sockaddr_in6 *)&sourceIp;
|
const sockaddr_in6 *src = (const sockaddr_in6 *)&sourceIp;
|
||||||
|
@ -156,8 +154,7 @@ struct _neighbor_advertisement {
|
||||||
};
|
};
|
||||||
|
|
||||||
NeighborDiscovery::NeighborDiscovery()
|
NeighborDiscovery::NeighborDiscovery()
|
||||||
: _cache()
|
: _cache(), _lastCleaned(OSUtils::now())
|
||||||
, _lastCleaned(OSUtils::now())
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void NeighborDiscovery::addLocal(const sockaddr_storage &address, const MAC &mac)
|
void NeighborDiscovery::addLocal(const sockaddr_storage &address, const MAC &mac)
|
||||||
|
@ -187,10 +184,10 @@ sockaddr_storage NeighborDiscovery::processIncomingND(const uint8_t *nd, unsigne
|
||||||
_neighbor_solicitation solicitation;
|
_neighbor_solicitation solicitation;
|
||||||
memcpy(&solicitation, nd, len);
|
memcpy(&solicitation, nd, len);
|
||||||
InetAddress targetAddress(solicitation.target, 16, 0);
|
InetAddress targetAddress(solicitation.target, 16, 0);
|
||||||
_NDEntry *targetEntry = _cache.get(targetAddress);
|
Map<InetAddress, NeighborDiscovery::_NDEntry>::const_iterator targetEntry(_cache.find(targetAddress));
|
||||||
if (targetEntry && targetEntry->local) {
|
if ((targetEntry != _cache.end()) && targetEntry->second.local) {
|
||||||
_neighbor_advertisement adv;
|
_neighbor_advertisement adv;
|
||||||
targetEntry->mac.copyTo(adv.option.mac);
|
targetEntry->second.mac.copyTo(adv.option.mac);
|
||||||
memcpy(adv.target, solicitation.target, 16);
|
memcpy(adv.target, solicitation.target, 16);
|
||||||
adv.calculateChecksum(localIp, targetAddress);
|
adv.calculateChecksum(localIp, targetAddress);
|
||||||
memcpy(response, &adv, sizeof(_neighbor_advertisement));
|
memcpy(response, &adv, sizeof(_neighbor_advertisement));
|
||||||
|
@ -201,10 +198,10 @@ sockaddr_storage NeighborDiscovery::processIncomingND(const uint8_t *nd, unsigne
|
||||||
_neighbor_advertisement adv;
|
_neighbor_advertisement adv;
|
||||||
memcpy(&adv, nd, len);
|
memcpy(&adv, nd, len);
|
||||||
InetAddress responseAddress(adv.target, 16, 0);
|
InetAddress responseAddress(adv.target, 16, 0);
|
||||||
_NDEntry *queryEntry = _cache.get(responseAddress);
|
Map<InetAddress, NeighborDiscovery::_NDEntry>::iterator queryEntry(_cache.find(responseAddress));
|
||||||
if(queryEntry && !queryEntry->local && (now - queryEntry->lastQuerySent <= ZT_ND_QUERY_MAX_TTL)) {
|
if ((queryEntry != _cache.end()) && !queryEntry->second.local && (now - queryEntry->second.lastQuerySent <= ZT_ND_QUERY_MAX_TTL)) {
|
||||||
queryEntry->lastResponseReceived = now;
|
queryEntry->second.lastResponseReceived = now;
|
||||||
queryEntry->mac.setTo(adv.option.mac);
|
queryEntry->second.mac.setTo(adv.option.mac);
|
||||||
ip = responseAddress;
|
ip = responseAddress;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,9 @@ public:
|
||||||
private:
|
private:
|
||||||
struct _NDEntry
|
struct _NDEntry
|
||||||
{
|
{
|
||||||
_NDEntry() : lastQuerySent(0), lastResponseReceived(0), mac(), local(false) {}
|
_NDEntry() : lastQuerySent(0), lastResponseReceived(0), mac(), local(false)
|
||||||
|
{}
|
||||||
|
|
||||||
uint64_t lastQuerySent;
|
uint64_t lastQuerySent;
|
||||||
uint64_t lastResponseReceived;
|
uint64_t lastResponseReceived;
|
||||||
MAC mac;
|
MAC mac;
|
||||||
|
|
Loading…
Add table
Reference in a new issue