mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-03-05 21:51:56 +00:00
Merge branch 'dev' into fix-mac-handling-in-rules-parser
This commit is contained in:
commit
43b141547e
@ -44,6 +44,12 @@ The base path contains the ZeroTier One service main entry point (`one.cpp`), se
|
||||
- `windows/`: Visual Studio solution files, Windows service code, and the Windows task bar app UI.
|
||||
- `zeroidc/`: OIDC implementation used by ZeroTier service to log into SSO-enabled networks. (This part is written in Rust, and more Rust will be appearing in this repository in the future.)
|
||||
|
||||
### Contributing
|
||||
|
||||
Please do pull requests off of the `dev` branch.
|
||||
|
||||
Releases are done by merging `dev` into `main` and then tagging and doing builds.
|
||||
|
||||
### Build and Platform Notes
|
||||
|
||||
To build on Mac and Linux just type `make`. On FreeBSD and OpenBSD `gmake` (GNU make) is required and can be installed from packages or ports. For Windows there is a Visual Studio solution in `windows/`.
|
||||
@ -81,7 +87,7 @@ On most distributions, macOS, and Windows, the installer will start the service
|
||||
|
||||
A home folder for your system will automatically be created.
|
||||
|
||||
The service is controlled via the JSON API, which by default is available at 127.0.0.1 port 9993. We include a *zerotier-cli* command line utility to make API calls for standard things like joining and leaving networks. The *authtoken.secret* file in the home folder contains the secret token for accessing this API. See [service/README.md](service/README.md) for API documentation.
|
||||
The service is controlled via the JSON API, which by default is available at `127.0.0.1:9993`. It also listens on `0.0.0.0:9993` which is only usable if `allowManagementFrom` is properly configured in `local.conf`. We include a *zerotier-cli* command line utility to make API calls for standard things like joining and leaving networks. The *authtoken.secret* file in the home folder contains the secret token for accessing this API. See [service/README.md](service/README.md) for API documentation.
|
||||
|
||||
Here's where home folders live (by default) on each OS:
|
||||
|
||||
|
@ -196,7 +196,7 @@ bool DB::get(const uint64_t networkId,nlohmann::json &network,std::vector<nlohma
|
||||
void DB::networks(std::set<uint64_t> &networks)
|
||||
{
|
||||
waitForReady();
|
||||
Metrics::db_get_member_list++;
|
||||
Metrics::db_get_network_list++;
|
||||
std::shared_lock<std::shared_mutex> l(_networks_l);
|
||||
for(auto n=_networks.begin();n!=_networks.end();++n)
|
||||
networks.insert(n->first);
|
||||
|
@ -869,9 +869,11 @@ void EmbeddedNetworkController::configureHTTPControlPlane(
|
||||
// Control plane Endpoints
|
||||
std::string controllerPath = "/controller";
|
||||
std::string networkListPath = "/controller/network";
|
||||
std::string networkListPath2 = "/unstable/controller/network";
|
||||
std::string networkPath = "/controller/network/([0-9a-fA-F]{16})";
|
||||
std::string oldAndBustedNetworkCreatePath = "/controller/network/([0-9a-fA-F]{10})______";
|
||||
std::string memberListPath = "/controller/network/([0-9a-fA-F]{16})/member";
|
||||
std::string memberListPath2 = "/unstable/controller/network/([0-9a-fA-F]{16})/member";
|
||||
std::string memberPath = "/controller/network/([0-9a-fA-F]{16})/member/([0-9a-fA-F]{10})";
|
||||
|
||||
auto controllerGet = [&, setContent](const httplib::Request &req, httplib::Response &res) {
|
||||
@ -910,6 +912,52 @@ void EmbeddedNetworkController::configureHTTPControlPlane(
|
||||
s.Get(networkListPath, networkListGet);
|
||||
sv6.Get(networkListPath, networkListGet);
|
||||
|
||||
auto networkListGet2 = [&, setContent](const httplib::Request &req, httplib::Response &res) {
|
||||
std::set<uint64_t> networkIds;
|
||||
_db.networks(networkIds);
|
||||
|
||||
auto meta = json::object();
|
||||
auto data = json::array();
|
||||
uint64_t networkCount = 0;
|
||||
|
||||
for(std::set<uint64_t>::const_iterator nwid(networkIds.begin()); nwid != networkIds.end(); ++nwid) {
|
||||
json network;
|
||||
if (!_db.get(*nwid, network)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::vector<json> memTmp;
|
||||
if (_db.get(*nwid, network, memTmp)) {
|
||||
if (!network.is_null()) {
|
||||
uint64_t authorizedCount = 0;
|
||||
uint64_t totalCount = memTmp.size();
|
||||
networkCount++;
|
||||
|
||||
for (auto m = memTmp.begin(); m != memTmp.end(); ++m) {
|
||||
bool a = OSUtils::jsonBool((*m)["authorized"], 0);
|
||||
if (a) { authorizedCount++; }
|
||||
}
|
||||
|
||||
auto nwMeta = json::object();
|
||||
nwMeta["totalMemberCount"] = totalCount;
|
||||
nwMeta["authorizedMemberCount"] = authorizedCount;
|
||||
network["meta"] = nwMeta;
|
||||
|
||||
data.push_back(network);
|
||||
}
|
||||
}
|
||||
}
|
||||
meta["networkCount"] = networkCount;
|
||||
|
||||
auto out = json::object();
|
||||
out["data"] = data;
|
||||
out["meta"] = meta;
|
||||
|
||||
setContent(req, res, out.dump());
|
||||
};
|
||||
s.Get(networkListPath2, networkListGet2);
|
||||
sv6.Get(networkListPath2, networkListGet2);
|
||||
|
||||
auto networkGet = [&, setContent](const httplib::Request &req, httplib::Response &res) {
|
||||
auto networkID = req.matches[1];
|
||||
uint64_t nwid = Utils::hexStrToU64(networkID.str().c_str());
|
||||
@ -925,7 +973,7 @@ void EmbeddedNetworkController::configureHTTPControlPlane(
|
||||
sv6.Get(networkPath, networkGet);
|
||||
|
||||
auto createNewNetwork = [&, setContent](const httplib::Request &req, httplib::Response &res) {
|
||||
fprintf(stderr, "creating new network (new style)\n");
|
||||
// fprintf(stderr, "creating new network (new style)\n");
|
||||
uint64_t nwid = 0;
|
||||
uint64_t nwidPrefix = (Utils::hexStrToU64(_signingIdAddressString.c_str()) << 24) & 0xffffffffff000000ULL;
|
||||
uint64_t nwidPostfix = 0;
|
||||
@ -1035,6 +1083,41 @@ void EmbeddedNetworkController::configureHTTPControlPlane(
|
||||
s.Get(memberListPath, memberListGet);
|
||||
sv6.Get(memberListPath, memberListGet);
|
||||
|
||||
auto memberListGet2 = [&, setContent](const httplib::Request &req, httplib::Response &res) {
|
||||
auto networkID = req.matches[1];
|
||||
uint64_t nwid = Utils::hexStrToU64(networkID.str().c_str());
|
||||
json network;
|
||||
if (!_db.get(nwid, network)) {
|
||||
res.status = 404;
|
||||
return;
|
||||
}
|
||||
|
||||
auto out = nlohmann::json::object();
|
||||
auto meta = nlohmann::json::object();
|
||||
std::vector<json> memTmp;
|
||||
if (_db.get(nwid, network, memTmp)) {
|
||||
uint64_t authorizedCount = 0;
|
||||
uint64_t totalCount = memTmp.size();
|
||||
for (auto m = memTmp.begin(); m != memTmp.end(); ++m) {
|
||||
bool a = OSUtils::jsonBool((*m)["authorized"], 0);
|
||||
if (a) { authorizedCount++; }
|
||||
}
|
||||
|
||||
meta["totalCount"] = totalCount;
|
||||
meta["authorizedCount"] = authorizedCount;
|
||||
|
||||
out["data"] = memTmp;
|
||||
out["meta"] = meta;
|
||||
|
||||
setContent(req, res, out.dump());
|
||||
} else {
|
||||
res.status = 404;
|
||||
return;
|
||||
}
|
||||
};
|
||||
s.Get(memberListPath2, memberListGet2);
|
||||
sv6.Get(memberListPath2, memberListGet2);
|
||||
|
||||
auto memberGet = [&, setContent](const httplib::Request &req, httplib::Response &res) {
|
||||
auto networkID = req.matches[1];
|
||||
auto memberID = req.matches[2];
|
||||
@ -1057,6 +1140,12 @@ void EmbeddedNetworkController::configureHTTPControlPlane(
|
||||
auto memberID = req.matches[2].str();
|
||||
uint64_t nwid = Utils::hexStrToU64(networkID.c_str());
|
||||
uint64_t memid = Utils::hexStrToU64(memberID.c_str());
|
||||
|
||||
if (!_db.hasNetwork(nwid)) {
|
||||
res.status = 404;
|
||||
return;
|
||||
}
|
||||
|
||||
json network;
|
||||
json member;
|
||||
_db.get(nwid, network, memid, member);
|
||||
@ -1068,6 +1157,7 @@ void EmbeddedNetworkController::configureHTTPControlPlane(
|
||||
if (b.count("noAutoAssignIps")) member["noAutoAssignIps"] = OSUtils::jsonBool(b["noAutoAssignIps"], false);
|
||||
if (b.count("authenticationExpiryTime")) member["authenticationExpiryTime"] = (uint64_t)OSUtils::jsonInt(b["authenticationExpiryTime"], 0ULL);
|
||||
if (b.count("authenticationURL")) member["authenticationURL"] = OSUtils::jsonString(b["authenticationURL"], "");
|
||||
if (b.count("name")) member["name"] = OSUtils::jsonString(b["name"], "");
|
||||
|
||||
if (b.count("remoteTraceTarget")) {
|
||||
const std::string rtt(OSUtils::jsonString(b["remoteTraceTarget"],""));
|
||||
|
@ -136,7 +136,7 @@ void FileDB::eraseNetwork(const uint64_t networkId)
|
||||
char p[16384];
|
||||
OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "%.16llx.json",_networksPath.c_str(),networkId);
|
||||
OSUtils::rm(p);
|
||||
OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "%.16llx" ZT_PATH_SEPARATOR_S "member",_networksPath.c_str(),(unsigned long long)networkId);
|
||||
OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "%.16llx",_networksPath.c_str(),(unsigned long long)networkId);
|
||||
OSUtils::rmDashRf(p);
|
||||
_networkChanged(network,nullJson,true);
|
||||
std::lock_guard<std::mutex> l(this->_online_l);
|
||||
|
@ -1436,7 +1436,21 @@ void PostgreSQL::commitThread()
|
||||
w.commit();
|
||||
|
||||
if (_smee != NULL && isNewMember) {
|
||||
notifyNewMember(networkId, memberId);
|
||||
pqxx::row row = w.exec_params1(
|
||||
"SELECT "
|
||||
" count(h.hook_id) "
|
||||
"FROM "
|
||||
" ztc_hook h "
|
||||
" INNER JOIN ztc_org o ON o.org_id = h.org_id "
|
||||
" INNER JOIN ztc_network n ON n.owner_id = o.owner_id "
|
||||
" WHERE "
|
||||
"n.id = $1 ",
|
||||
networkId
|
||||
);
|
||||
int64_t hookCount = row[0].as<int64_t>();
|
||||
if (hookCount > 0) {
|
||||
notifyNewMember(networkId, memberId);
|
||||
}
|
||||
}
|
||||
|
||||
const uint64_t nwidInt = OSUtils::jsonIntHex(config["nwid"], 0ULL);
|
||||
|
@ -100,12 +100,14 @@ else
|
||||
done
|
||||
fi
|
||||
|
||||
echo "Waiting for temporal"
|
||||
while ! nc -z ${ZT_TEMPORAL_HOST} ${ZT_TEMPORAL_PORT}; do
|
||||
echo "waiting...";
|
||||
sleep 1;
|
||||
done
|
||||
echo "Temporal is up"
|
||||
if [ -n "$ZT_TEMPORAL_HOST" ] && [ -n "$ZT_TEMPORAL_PORT" ]; then
|
||||
echo "waiting for temporal..."
|
||||
while ! nc -z ${ZT_TEMPORAL_HOST} ${ZT_TEMPORAL_PORT}; do
|
||||
echo "waiting...";
|
||||
sleep 1;
|
||||
done
|
||||
echo "Temporal is up"
|
||||
fi
|
||||
|
||||
export GLIBCXX_FORCE_NEW=1
|
||||
export GLIBCPP_FORCE_NEW=1
|
||||
|
File diff suppressed because it is too large
Load Diff
112
node/Network.cpp
112
node/Network.cpp
@ -107,11 +107,22 @@ static _doZtFilterResult _doZtFilter(
|
||||
// The default match state for each set of entries starts as 'true' since an
|
||||
// ACTION with no MATCH entries preceding it is always taken.
|
||||
uint8_t thisSetMatches = 1;
|
||||
uint8_t skipDrop = 0;
|
||||
|
||||
rrl.clear();
|
||||
|
||||
// uncomment for easier debugging fprintf
|
||||
// if (!ztDest) { return DOZTFILTER_ACCEPT; }
|
||||
#ifdef ZT_TRACE
|
||||
//char buf[40], buf2[40];
|
||||
//fprintf(stderr, "\nsrc %s dest %s inbound: %d ethertype %u", ztSource.toString(buf), ztDest.toString(buf2), inbound, etherType);
|
||||
#endif
|
||||
|
||||
for(unsigned int rn=0;rn<ruleCount;++rn) {
|
||||
const ZT_VirtualNetworkRuleType rt = (ZT_VirtualNetworkRuleType)(rules[rn].t & 0x3f);
|
||||
#ifdef ZT_TRACE
|
||||
//fprintf(stderr, "\n%02u %02d", rn, rt);
|
||||
#endif
|
||||
|
||||
// First check if this is an ACTION
|
||||
if ((unsigned int)rt <= (unsigned int)ZT_NETWORK_RULE_ACTION__MAX_ID) {
|
||||
@ -121,11 +132,25 @@ static _doZtFilterResult _doZtFilter(
|
||||
qosBucket = (rules[rn].v.qosBucket <= 8) ? rules[rn].v.qosBucket : 4; // 4 = default bucket (no priority)
|
||||
return DOZTFILTER_ACCEPT;
|
||||
|
||||
case ZT_NETWORK_RULE_ACTION_DROP:
|
||||
case ZT_NETWORK_RULE_ACTION_DROP: {
|
||||
if (!!skipDrop) {
|
||||
#ifdef ZT_TRACE
|
||||
//fprintf(stderr, "\tskip Drop");
|
||||
#endif
|
||||
skipDrop = 0; continue;
|
||||
}
|
||||
#ifdef ZT_TRACE
|
||||
//fprintf(stderr, "\tDrop\n");
|
||||
#endif
|
||||
return DOZTFILTER_DROP;
|
||||
}
|
||||
|
||||
case ZT_NETWORK_RULE_ACTION_ACCEPT:
|
||||
case ZT_NETWORK_RULE_ACTION_ACCEPT: {
|
||||
#ifdef ZT_TRACE
|
||||
//fprintf(stderr, "\tAccept\n");
|
||||
#endif
|
||||
return (superAccept ? DOZTFILTER_SUPER_ACCEPT : DOZTFILTER_ACCEPT); // match, accept packet
|
||||
}
|
||||
|
||||
// These are initially handled together since preliminary logic is common
|
||||
case ZT_NETWORK_RULE_ACTION_TEE:
|
||||
@ -192,6 +217,9 @@ static _doZtFilterResult _doZtFilter(
|
||||
// If this was not an ACTION evaluate next MATCH and update thisSetMatches with (AND [result])
|
||||
uint8_t thisRuleMatches = 0;
|
||||
uint64_t ownershipVerificationMask = 1; // this magic value means it hasn't been computed yet -- this is done lazily the first time it's needed
|
||||
uint8_t hardYes = (rules[rn].t >> 7) ^ 1; // XOR with the NOT bit of the rule
|
||||
uint8_t hardNo = (rules[rn].t >> 7) ^ 0;
|
||||
|
||||
switch(rt) {
|
||||
case ZT_NETWORK_RULE_MATCH_SOURCE_ZEROTIER_ADDRESS:
|
||||
thisRuleMatches = (uint8_t)(rules[rn].v.zt == ztSource.toInt());
|
||||
@ -220,28 +248,28 @@ static _doZtFilterResult _doZtFilter(
|
||||
if ((etherType == ZT_ETHERTYPE_IPV4)&&(frameLen >= 20)) {
|
||||
thisRuleMatches = (uint8_t)(InetAddress((const void *)&(rules[rn].v.ipv4.ip),4,rules[rn].v.ipv4.mask).containsAddress(InetAddress((const void *)(frameData + 12),4,0)));
|
||||
} else {
|
||||
thisRuleMatches = 0;
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
break;
|
||||
case ZT_NETWORK_RULE_MATCH_IPV4_DEST:
|
||||
if ((etherType == ZT_ETHERTYPE_IPV4)&&(frameLen >= 20)) {
|
||||
thisRuleMatches = (uint8_t)(InetAddress((const void *)&(rules[rn].v.ipv4.ip),4,rules[rn].v.ipv4.mask).containsAddress(InetAddress((const void *)(frameData + 16),4,0)));
|
||||
} else {
|
||||
thisRuleMatches = 0;
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
break;
|
||||
case ZT_NETWORK_RULE_MATCH_IPV6_SOURCE:
|
||||
if ((etherType == ZT_ETHERTYPE_IPV6)&&(frameLen >= 40)) {
|
||||
thisRuleMatches = (uint8_t)(InetAddress((const void *)rules[rn].v.ipv6.ip,16,rules[rn].v.ipv6.mask).containsAddress(InetAddress((const void *)(frameData + 8),16,0)));
|
||||
} else {
|
||||
thisRuleMatches = 0;
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
break;
|
||||
case ZT_NETWORK_RULE_MATCH_IPV6_DEST:
|
||||
if ((etherType == ZT_ETHERTYPE_IPV6)&&(frameLen >= 40)) {
|
||||
thisRuleMatches = (uint8_t)(InetAddress((const void *)rules[rn].v.ipv6.ip,16,rules[rn].v.ipv6.mask).containsAddress(InetAddress((const void *)(frameData + 24),16,0)));
|
||||
} else {
|
||||
thisRuleMatches = 0;
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
break;
|
||||
case ZT_NETWORK_RULE_MATCH_IP_TOS:
|
||||
@ -252,7 +280,7 @@ static _doZtFilterResult _doZtFilter(
|
||||
const uint8_t tosMasked = (((frameData[0] << 4) & 0xf0) | ((frameData[1] >> 4) & 0x0f)) & rules[rn].v.ipTos.mask;
|
||||
thisRuleMatches = (uint8_t)((tosMasked >= rules[rn].v.ipTos.value[0])&&(tosMasked <= rules[rn].v.ipTos.value[1]));
|
||||
} else {
|
||||
thisRuleMatches = 0;
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
break;
|
||||
case ZT_NETWORK_RULE_MATCH_IP_PROTOCOL:
|
||||
@ -263,10 +291,10 @@ static _doZtFilterResult _doZtFilter(
|
||||
if (_ipv6GetPayload(frameData,frameLen,pos,proto)) {
|
||||
thisRuleMatches = (uint8_t)(rules[rn].v.ipProtocol == (uint8_t)proto);
|
||||
} else {
|
||||
thisRuleMatches = 0;
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
} else {
|
||||
thisRuleMatches = 0;
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
break;
|
||||
case ZT_NETWORK_RULE_MATCH_ETHERTYPE:
|
||||
@ -281,16 +309,16 @@ static _doZtFilterResult _doZtFilter(
|
||||
if ((rules[rn].v.icmp.flags & 0x01) != 0) {
|
||||
thisRuleMatches = (uint8_t)(frameData[ihl+1] == rules[rn].v.icmp.code);
|
||||
} else {
|
||||
thisRuleMatches = 1;
|
||||
thisRuleMatches = hardYes;
|
||||
}
|
||||
} else {
|
||||
thisRuleMatches = 0;
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
} else {
|
||||
thisRuleMatches = 0;
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
} else {
|
||||
thisRuleMatches = 0;
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
} else if (etherType == ZT_ETHERTYPE_IPV6) {
|
||||
unsigned int pos = 0,proto = 0;
|
||||
@ -300,19 +328,19 @@ static _doZtFilterResult _doZtFilter(
|
||||
if ((rules[rn].v.icmp.flags & 0x01) != 0) {
|
||||
thisRuleMatches = (uint8_t)(frameData[pos+1] == rules[rn].v.icmp.code);
|
||||
} else {
|
||||
thisRuleMatches = 1;
|
||||
thisRuleMatches = hardYes;
|
||||
}
|
||||
} else {
|
||||
thisRuleMatches = 0;
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
} else {
|
||||
thisRuleMatches = 0;
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
} else {
|
||||
thisRuleMatches = 0;
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
} else {
|
||||
thisRuleMatches = 0;
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
break;
|
||||
case ZT_NETWORK_RULE_MATCH_IP_SOURCE_PORT_RANGE:
|
||||
@ -356,10 +384,10 @@ static _doZtFilterResult _doZtFilter(
|
||||
}
|
||||
thisRuleMatches = (p > 0) ? (uint8_t)((p >= (int)rules[rn].v.port[0])&&(p <= (int)rules[rn].v.port[1])) : (uint8_t)0;
|
||||
} else {
|
||||
thisRuleMatches = 0;
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
} else {
|
||||
thisRuleMatches = 0;
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
break;
|
||||
case ZT_NETWORK_RULE_MATCH_CHARACTERISTICS: {
|
||||
@ -444,6 +472,14 @@ static _doZtFilterResult _doZtFilter(
|
||||
const Tag *const localTag = std::lower_bound(&(nconf.tags[0]),&(nconf.tags[nconf.tagCount]),rules[rn].v.tag.id,Tag::IdComparePredicate());
|
||||
if ((localTag != &(nconf.tags[nconf.tagCount]))&&(localTag->id() == rules[rn].v.tag.id)) {
|
||||
const Tag *const remoteTag = ((membership) ? membership->getTag(nconf,rules[rn].v.tag.id) : (const Tag *)0);
|
||||
#ifdef ZT_TRACE
|
||||
/*fprintf(stderr, "\tlocal tag [%u: %u] remote tag [%u: %u] match [%u]",
|
||||
!!localTag ? localTag->id() : 0,
|
||||
!!localTag ? localTag->value() : 0,
|
||||
!!remoteTag ? remoteTag->id() : 0,
|
||||
!!remoteTag ? remoteTag->value() : 0,
|
||||
thisRuleMatches);*/
|
||||
#endif
|
||||
if (remoteTag) {
|
||||
const uint32_t ltv = localTag->value();
|
||||
const uint32_t rtv = remoteTag->value();
|
||||
@ -459,28 +495,46 @@ static _doZtFilterResult _doZtFilter(
|
||||
} else if (rt == ZT_NETWORK_RULE_MATCH_TAGS_EQUAL) {
|
||||
thisRuleMatches = (uint8_t)((ltv == rules[rn].v.tag.value)&&(rtv == rules[rn].v.tag.value));
|
||||
} else { // sanity check, can't really happen
|
||||
thisRuleMatches = 0;
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
} else {
|
||||
if ((inbound)&&(!superAccept)) {
|
||||
thisRuleMatches = 0;
|
||||
thisRuleMatches = hardNo;
|
||||
#ifdef ZT_TRACE
|
||||
//fprintf(stderr, "\tinbound ");
|
||||
#endif
|
||||
} else {
|
||||
// Outbound side is not strict since if we have to match both tags and
|
||||
// we are sending a first packet to a recipient, we probably do not know
|
||||
// about their tags yet. They will filter on inbound and we will filter
|
||||
// once we get their tag. If we are a tee/redirect target we are also
|
||||
// not strict since we likely do not have these tags.
|
||||
thisRuleMatches = 1;
|
||||
skipDrop = 1;
|
||||
thisRuleMatches = hardYes;
|
||||
#ifdef ZT_TRACE
|
||||
//fprintf(stderr, "\toutbound ");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} else {
|
||||
thisRuleMatches = 0;
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
} break;
|
||||
case ZT_NETWORK_RULE_MATCH_TAG_SENDER:
|
||||
case ZT_NETWORK_RULE_MATCH_TAG_RECEIVER: {
|
||||
const Tag *const localTag = std::lower_bound(&(nconf.tags[0]),&(nconf.tags[nconf.tagCount]),rules[rn].v.tag.id,Tag::IdComparePredicate());
|
||||
#ifdef ZT_TRACE
|
||||
/*const Tag *const remoteTag = ((membership) ? membership->getTag(nconf,rules[rn].v.tag.id) : (const Tag *)0);
|
||||
fprintf(stderr, "\tlocal tag [%u: %u] remote tag [%u: %u] match [%u]",
|
||||
!!localTag ? localTag->id() : 0,
|
||||
!!localTag ? localTag->value() : 0,
|
||||
!!remoteTag ? remoteTag->id() : 0,
|
||||
!!remoteTag ? remoteTag->value() : 0,
|
||||
thisRuleMatches);*/
|
||||
#endif
|
||||
if (superAccept) {
|
||||
thisRuleMatches = 1;
|
||||
skipDrop = 1;
|
||||
thisRuleMatches = hardYes;
|
||||
} else if ( ((rt == ZT_NETWORK_RULE_MATCH_TAG_SENDER)&&(inbound)) || ((rt == ZT_NETWORK_RULE_MATCH_TAG_RECEIVER)&&(!inbound)) ) {
|
||||
const Tag *const remoteTag = ((membership) ? membership->getTag(nconf,rules[rn].v.tag.id) : (const Tag *)0);
|
||||
if (remoteTag) {
|
||||
@ -489,17 +543,17 @@ static _doZtFilterResult _doZtFilter(
|
||||
if (rt == ZT_NETWORK_RULE_MATCH_TAG_RECEIVER) {
|
||||
// If we are checking the receiver and this is an outbound packet, we
|
||||
// can't be strict since we may not yet know the receiver's tag.
|
||||
thisRuleMatches = 1;
|
||||
skipDrop = 1;
|
||||
thisRuleMatches = hardYes;
|
||||
} else {
|
||||
thisRuleMatches = 0;
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
}
|
||||
} else { // sender and outbound or receiver and inbound
|
||||
const Tag *const localTag = std::lower_bound(&(nconf.tags[0]),&(nconf.tags[nconf.tagCount]),rules[rn].v.tag.id,Tag::IdComparePredicate());
|
||||
if ((localTag != &(nconf.tags[nconf.tagCount]))&&(localTag->id() == rules[rn].v.tag.id)) {
|
||||
thisRuleMatches = (uint8_t)(localTag->value() == rules[rn].v.tag.value);
|
||||
} else {
|
||||
thisRuleMatches = 0;
|
||||
thisRuleMatches = hardNo;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
@ -1172,25 +1172,25 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// If secondary port is not configured to a constant value and we've been offline for a while,
|
||||
// bind a new secondary port. This is a workaround for a "coma" issue caused by buggy NATs that stop
|
||||
// working on one port after a while.
|
||||
if (_secondaryPort == 0) {
|
||||
if (_node->online()) {
|
||||
lastOnline = now;
|
||||
}
|
||||
if ((now - lastOnline) > ZT_PATH_HEARTBEAT_PERIOD || restarted) {
|
||||
_ports[1] = _getRandomPort();
|
||||
#if ZT_DEBUG==1
|
||||
fprintf(stderr, "randomized secondary port. Now it's %d\n", _ports[1]);
|
||||
#endif
|
||||
lastOnline = now; // don't keep spamming this branch. online() will be false for a few seconds
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Refresh bindings in case device's interfaces have changed, and also sync routes to update any shadow routes (e.g. shadow default)
|
||||
if (((now - lastBindRefresh) >= (_node->bondController()->inUse() ? ZT_BINDER_REFRESH_PERIOD / 4 : ZT_BINDER_REFRESH_PERIOD))||restarted) {
|
||||
// If secondary port is not configured to a constant value and we've been offline for a while,
|
||||
// bind a new secondary port. This is a workaround for a "coma" issue caused by buggy NATs that stop
|
||||
// working on one port after a while.
|
||||
if (_secondaryPort == 0) {
|
||||
if (_node->online()) {
|
||||
lastOnline = now;
|
||||
}
|
||||
else if (now - lastOnline > (ZT_PEER_PING_PERIOD * 2) || restarted) {
|
||||
lastOnline = now; // don't keep changing the port before we have a chance to connect
|
||||
_ports[1] = _getRandomPort();
|
||||
|
||||
#if ZT_DEBUG==1
|
||||
fprintf(stderr, "Randomized secondary port. Now it's %d\n", _ports[1]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int p[3];
|
||||
unsigned int pc = 0;
|
||||
for(int i=0;i<3;++i) {
|
||||
@ -2041,6 +2041,7 @@ public:
|
||||
settings["primaryPort"] = OSUtils::jsonInt(settings["primaryPort"],(uint64_t)_primaryPort) & 0xffff;
|
||||
settings["secondaryPort"] = OSUtils::jsonInt(settings["secondaryPort"],(uint64_t)_ports[1]) & 0xffff;
|
||||
settings["tertiaryPort"] = OSUtils::jsonInt(settings["tertiaryPort"],(uint64_t)_tertiaryPort) & 0xffff;
|
||||
settings["homeDir"] = _homePath;
|
||||
// Enumerate all local address/port pairs that this node is listening on
|
||||
std::vector<InetAddress> boundAddrs(_binder.allBoundLocalInterfaceAddresses());
|
||||
auto boundAddrArray = json::array();
|
||||
|
@ -3,7 +3,7 @@ CXX=$(shell which clang++ g++ c++ 2>/dev/null | head -n 1)
|
||||
INCLUDES?=-I../ext/prometheus-cpp-lite-1.0/core/include -I../ext/prometheus-cpp-lite-1.0/simpleapi/include
|
||||
|
||||
all:
|
||||
$(CXX) -O3 -fno-rtti $(INCLUDES) -std=c++11 -frtti -o tcp-proxy tcp-proxy.cpp ../node/Metrics.cpp
|
||||
$(CXX) -O3 -fno-rtti $(INCLUDES) -std=c++11 -pthread -frtti -o tcp-proxy tcp-proxy.cpp ../node/Metrics.cpp
|
||||
|
||||
clean:
|
||||
rm -f *.o tcp-proxy *.dSYM
|
||||
|
Loading…
x
Reference in New Issue
Block a user