Merge branch 'dev' into dev-tunnel-report

This commit is contained in:
Sean OMeara 2023-01-12 10:04:58 +01:00 committed by GitHub
commit 5ff990aa7b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 422 additions and 25 deletions

108
.github/workflows/build.yml vendored Normal file
View file

@ -0,0 +1,108 @@
on: [ push, pull_request ]
jobs:
build_ubuntu:
runs-on: ubuntu-latest
steps:
- name: gitconfig
run: |
git config --global core.autocrlf false
git config --global core.eol lf
- name: checkout
uses: actions/checkout@v3
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
target: aarch64-apple-darwin
override: true
components: rustfmt, clippy
- name: Set up cargo cache
uses: actions/cache@v3
continue-on-error: false
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ${{ runner.os }}-cargo-
- name: make
run: make
- name: selftest
run: |
make selftest
./zerotier-selftest
build_macos:
runs-on: macos-latest
steps:
- name: gitconfig
run: |
git config --global core.autocrlf false
git config --global core.eol lf
- name: checkout
uses: actions/checkout@v3
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
target: aarch64-apple-darwin
override: true
components: rustfmt, clippy
- name: Set up cargo cache
uses: actions/cache@v3
continue-on-error: false
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ${{ runner.os }}-cargo-
- name: make
run: make
- name: selftest
run: |
make selftest
./zerotier-selftest
build_windows:
runs-on: windows-latest
steps:
- name: gitconfig
run: |
git config --global core.autocrlf false
git config --global core.eol lf
- name: checkout
uses: actions/checkout@v3
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
target: aarch64-apple-darwin
override: true
components: rustfmt, clippy
- name: Set up cargo cache
uses: actions/cache@v3
continue-on-error: false
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ${{ runner.os }}-cargo-
- name: setup msbuild
uses: microsoft/setup-msbuild@v1.1.3
- name: msbuild
run: |
msbuild windows\ZeroTierOne.sln /m /p:Configuration=Release /property:Platform=x64 /t:ZeroTierOne:Rebuild

View file

@ -384,7 +384,7 @@ enum ZT_ResultCode
*/
ZT_RESULT_OK_IGNORED = 1,
// Fatal errors (>100, <1000)
// Fatal errors (>=100, <1000)
/**
* Ran out of memory

View file

@ -43,7 +43,7 @@ jobject createResultObject(JNIEnv *env, ZT_ResultCode code)
resultClass = lookup.findClass("com/zerotier/sdk/ResultCode");
if(resultClass == NULL)
{
LOGE("Couldnt find ResultCode class");
LOGE("Couldn't find ResultCode class");
return NULL; // exception thrown
}
@ -1032,4 +1032,3 @@ jobject newVirtualNetworkDNS(JNIEnv *env, const ZT_VirtualNetworkDNS &dns)
#ifdef __cplusplus
}
#endif

View file

@ -41,7 +41,7 @@ public enum ResultCode {
*/
RESULT_OK(0),
// Fatal errors (> 0, < 1000)
// Fatal errors (>=100, <1000)
/**
* Ran out of memory
*/

View file

@ -184,7 +184,7 @@ SharedPtr<Link> Bond::getLinkBySocket(const std::string& policyAlias, uint64_t l
auto search = _interfaceToLinkMap[policyAlias].find(ifnameStr);
if (search == _interfaceToLinkMap[policyAlias].end()) {
if (createIfNeeded) {
SharedPtr<Link> s = new Link(ifnameStr, 0, 0, true, ZT_BOND_SLAVE_MODE_PRIMARY, "");
SharedPtr<Link> s = new Link(ifnameStr, 0, 0, 0, true, ZT_BOND_SLAVE_MODE_PRIMARY, "");
_interfaceToLinkMap[policyAlias].insert(std::pair<std::string, SharedPtr<Link> >(ifnameStr, s));
return s;
}
@ -1253,6 +1253,7 @@ void Bond::estimatePathQuality(int64_t now)
if (link) {
int linkSpeed = link->capacity();
_paths[i].p->_givenLinkSpeed = linkSpeed;
_paths[i].p->_mtu = link->mtu();
maxObservedLinkCap = linkSpeed > maxObservedLinkCap ? linkSpeed : maxObservedLinkCap;
}
}

View file

@ -122,9 +122,10 @@ class Link {
* @param mode
* @param failoverToLinkStr
*/
Link(std::string ifnameStr, uint8_t ipvPref, uint32_t capacity, bool enabled, uint8_t mode, std::string failoverToLinkStr)
Link(std::string ifnameStr, uint8_t ipvPref, uint16_t mtu, uint32_t capacity, bool enabled, uint8_t mode, std::string failoverToLinkStr)
: _ifnameStr(ifnameStr)
, _ipvPref(ipvPref)
, _mtu(mtu)
, _capacity(capacity)
, _relativeCapacity(0.0)
, _enabled(enabled)
@ -226,6 +227,14 @@ class Link {
return _ipvPref;
}
/**
* @return The MTU for this link (as specified by the user.)
*/
inline uint16_t mtu()
{
return _mtu;
}
/**
* @return The mode (e.g. primary/spare) for this link (as specified by the user.)
*/
@ -260,6 +269,11 @@ class Link {
*/
uint8_t _ipvPref;
/**
* The physical-layer MTU for this link
*/
uint16_t _mtu;
/**
* User-specified capacity of this link
*/

View file

@ -149,7 +149,7 @@ public:
/**
* Get the ZeroTier address for this MAC on this network (assuming no bridging of course, basic unicast)
*
* This just XORs the next-lest-significant 5 bytes of the network ID again to unmask.
* This just XORs the next-least-significant 5 bytes of the network ID again to unmask.
*
* @param nwid Network ID
*/

View file

@ -268,7 +268,8 @@ void Multicaster::send(
const unsigned int gatherLimit = (limit - (unsigned int)gs.members.size()) + 1;
if ((gs.members.empty())||((now - gs.lastExplicitGather) >= ZT_MULTICAST_EXPLICIT_GATHER_DELAY)) {
int timerScale = RR->node->lowBandwidthModeEnabled() ? 3 : 1;
if ((gs.members.empty())||((now - gs.lastExplicitGather) >= (ZT_MULTICAST_EXPLICIT_GATHER_DELAY * timerScale))) {
gs.lastExplicitGather = now;
Address explicitGatherPeers[16];

View file

@ -50,7 +50,8 @@ Node::Node(void *uptr,void *tptr,const struct ZT_Node_Callbacks *callbacks,int64
_lastPingCheck(0),
_lastGratuitousPingCheck(0),
_lastHousekeepingRun(0),
_lastMemoizedTraceSettings(0)
_lastMemoizedTraceSettings(0),
_lowBandwidthMode(false)
{
if (callbacks->version != 0)
throw ZT_EXCEPTION_INVALID_ARGUMENT;
@ -202,6 +203,14 @@ public:
{
const std::vector<InetAddress> *const alwaysContactEndpoints = _alwaysContact.get(p->address());
if (alwaysContactEndpoints) {
// Contact upstream peers as infrequently as possible
ZT_PeerRole role = RR->topology->role(p->address());
int roleBasedTimerScale = (role == ZT_PEER_ROLE_LEAF) ? 2 : 16;
if ((RR->node->now() - p->lastSentFullHello()) <= (ZT_PATH_HEARTBEAT_PERIOD * roleBasedTimerScale)) {
return;
}
const unsigned int sent = p->doPingAndKeepalive(_tPtr,_now);
bool contacted = (sent != 0);
@ -262,7 +271,7 @@ ZT_ResultCode Node::processBackgroundTasks(void *tptr,int64_t now,volatile int64
}
}
unsigned long timeUntilNextPingCheck = ZT_PING_CHECK_INVERVAL;
unsigned long timeUntilNextPingCheck = _lowBandwidthMode ? (ZT_PING_CHECK_INVERVAL * 5) : ZT_PING_CHECK_INVERVAL;
const int64_t timeSinceLastPingCheck = now - _lastPingCheck;
if (timeSinceLastPingCheck >= timeUntilNextPingCheck) {
try {
@ -309,6 +318,7 @@ ZT_ResultCode Node::processBackgroundTasks(void *tptr,int64_t now,volatile int64
// Get peers we should stay connected to according to network configs
// Also get networks and whether they need config so we only have to do one pass over networks
int timerScale = _lowBandwidthMode ? 64 : 1;
std::vector< std::pair< SharedPtr<Network>,bool > > networkConfigNeeded;
{
Mutex::Lock l(_networks_m);
@ -317,7 +327,7 @@ ZT_ResultCode Node::processBackgroundTasks(void *tptr,int64_t now,volatile int64
SharedPtr<Network> *network = (SharedPtr<Network> *)0;
while (i.next(nwid,network)) {
(*network)->config().alwaysContactAddresses(alwaysContact);
networkConfigNeeded.push_back( std::pair< SharedPtr<Network>,bool >(*network,(((now - (*network)->lastConfigUpdate()) >= ZT_NETWORK_AUTOCONF_DELAY)||(!(*network)->hasConfig()))) );
networkConfigNeeded.push_back( std::pair< SharedPtr<Network>,bool >(*network,(((now - (*network)->lastConfigUpdate()) >= ZT_NETWORK_AUTOCONF_DELAY * timerScale)||(!(*network)->hasConfig()))) );
}
}
@ -336,10 +346,13 @@ ZT_ResultCode Node::processBackgroundTasks(void *tptr,int64_t now,volatile int64
// Refresh network config or broadcast network updates to members as needed
for(std::vector< std::pair< SharedPtr<Network>,bool > >::const_iterator n(networkConfigNeeded.begin());n!=networkConfigNeeded.end();++n) {
if (n->second)
if (n->second) {
n->first->requestConfiguration(tptr);
}
if (! _lowBandwidthMode) {
n->first->sendUpdatesToMembers(tptr);
}
}
// Update online status, post status change as event
const bool oldOnline = _online;

View file

@ -269,6 +269,16 @@ public:
_stats.inVerbBytes[v] += (uint64_t)bytes;
}
inline void setLowBandwidthMode(bool isEnabled)
{
_lowBandwidthMode = isEnabled;
}
inline bool lowBandwidthModeEnabled()
{
return _lowBandwidthMode;
}
private:
RuntimeEnvironment _RR;
RuntimeEnvironment *RR;
@ -316,6 +326,7 @@ private:
int64_t _lastMemoizedTraceSettings;
volatile int64_t _prngState[2];
bool _online;
bool _lowBandwidthMode;
};
} // namespace ZeroTier

View file

@ -92,6 +92,7 @@ public:
_valid(true),
_eligible(false),
_bonded(false),
_mtu(0),
_givenLinkSpeed(0),
_relativeQuality(0),
_latency(0xffff),
@ -112,6 +113,7 @@ public:
_valid(true),
_eligible(false),
_bonded(false),
_mtu(0),
_givenLinkSpeed(0),
_relativeQuality(0),
_latency(0xffff),
@ -334,6 +336,11 @@ public:
*/
inline unsigned int bonded() const { return _bonded; }
/**
* @return Whether the user-specified MTU for this path (determined by MTU for parent link)
*/
inline unsigned int mtu() const { return _mtu; }
/**
* @return Given link capacity as reported by the bonding layer
*/
@ -370,6 +377,7 @@ private:
volatile bool _valid;
volatile bool _eligible;
volatile bool _bonded;
volatile uint16_t _mtu;
volatile uint32_t _givenLinkSpeed;
volatile float _relativeQuality;

View file

@ -219,11 +219,15 @@ void Peer::received(
// is done less frequently.
if (this->trustEstablished(now)) {
const int64_t sinceLastPush = now - _lastDirectPathPushSent;
if (sinceLastPush >= ((hops == 0) ? ZT_DIRECT_PATH_PUSH_INTERVAL_HAVEPATH : ZT_DIRECT_PATH_PUSH_INTERVAL)) {
bool lowBandwidth = RR->node->lowBandwidthModeEnabled();
int timerScale = lowBandwidth ? 16 : 1;
if (sinceLastPush >= ((hops == 0) ? ZT_DIRECT_PATH_PUSH_INTERVAL_HAVEPATH * timerScale : ZT_DIRECT_PATH_PUSH_INTERVAL)) {
_lastDirectPathPushSent = now;
std::vector<InetAddress> pathsToPush(RR->node->directPaths());
if (! lowBandwidth) {
std::vector<InetAddress> ma = RR->sa->whoami();
pathsToPush.insert(pathsToPush.end(), ma.begin(), ma.end());
}
if (!pathsToPush.empty()) {
std::vector<InetAddress>::const_iterator p(pathsToPush.begin());
while (p != pathsToPush.end()) {
@ -453,7 +457,7 @@ void Peer::sendHELLO(void *tPtr,const int64_t localSocket,const InetAddress &atA
if (atAddress) {
outp.armor(_key,false,nullptr); // false == don't encrypt full payload, but add MAC
RR->node->expectReplyTo(outp.packetId());
RR->node->putPacket(tPtr,-1,atAddress,outp.data(),outp.size());
RR->node->putPacket(tPtr,RR->node->lowBandwidthModeEnabled() ? localSocket : -1,atAddress,outp.data(),outp.size());
} else {
RR->node->expectReplyTo(outp.packetId());
RR->sw->send(tPtr,outp,false); // false == don't encrypt full payload, but add MAC
@ -477,9 +481,10 @@ void Peer::tryMemorizedPath(void *tPtr,int64_t now)
if ((now - _lastTriedMemorizedPath) >= ZT_TRY_MEMORIZED_PATH_INTERVAL) {
_lastTriedMemorizedPath = now;
InetAddress mp;
if (RR->node->externalPathLookup(tPtr,_id.address(),-1,mp))
if (RR->node->externalPathLookup(tPtr,_id.address(),-1,mp)) {
attemptToContactAt(tPtr,-1,mp,now,true);
}
}
}
void Peer::performMultipathStateCheck(void *tPtr, int64_t now)

View file

@ -302,6 +302,8 @@ public:
*/
inline int64_t isActive(int64_t now) const { return ((now - _lastNontrivialReceive) < ZT_PEER_ACTIVITY_TIMEOUT); }
inline int64_t lastSentFullHello() { return _lastSentFullHello; }
/**
* @return Latency in milliseconds of best/aggregate path or 0xffff if unknown / no paths
*/

View file

@ -1009,7 +1009,8 @@ bool Switch::_trySend(void *tPtr,Packet &packet,bool encrypt,int32_t flowId)
Mutex::Lock _l(peer->_paths_m);
for(int i=0;i<ZT_MAX_PEER_NETWORK_PATHS;++i) {
if (peer->_paths[i].p && peer->_paths[i].p->alive(now)) {
_sendViaSpecificPath(tPtr,peer,peer->_paths[i].p,now,packet,encrypt,flowId);
uint16_t userSpecifiedMtu = peer->_paths[i].p->mtu();
_sendViaSpecificPath(tPtr,peer,peer->_paths[i].p, userSpecifiedMtu,now,packet,encrypt,flowId);
}
}
return true;
@ -1025,7 +1026,8 @@ bool Switch::_trySend(void *tPtr,Packet &packet,bool encrypt,int32_t flowId)
}
}
if (viaPath) {
_sendViaSpecificPath(tPtr,peer,viaPath,now,packet,encrypt,flowId);
uint16_t userSpecifiedMtu = viaPath->mtu();
_sendViaSpecificPath(tPtr,peer,viaPath,userSpecifiedMtu,now,packet,encrypt,flowId);
return true;
}
}
@ -1033,12 +1035,15 @@ bool Switch::_trySend(void *tPtr,Packet &packet,bool encrypt,int32_t flowId)
return false;
}
void Switch::_sendViaSpecificPath(void *tPtr,SharedPtr<Peer> peer,SharedPtr<Path> viaPath,int64_t now,Packet &packet,bool encrypt,int32_t flowId)
void Switch::_sendViaSpecificPath(void *tPtr,SharedPtr<Peer> peer,SharedPtr<Path> viaPath,uint16_t userSpecifiedMtu, int64_t now,Packet &packet,bool encrypt,int32_t flowId)
{
unsigned int mtu = ZT_DEFAULT_PHYSMTU;
uint64_t trustedPathId = 0;
RR->topology->getOutboundPathInfo(viaPath->address(),mtu,trustedPathId);
if (userSpecifiedMtu > 0) {
mtu = userSpecifiedMtu;
}
unsigned int chunkSize = std::min(packet.size(),mtu);
packet.setFragmented(chunkSize < packet.size());

View file

@ -207,7 +207,7 @@ public:
private:
bool _shouldUnite(const int64_t now,const Address &source,const Address &destination);
bool _trySend(void *tPtr,Packet &packet,bool encrypt,int32_t flowId = ZT_QOS_NO_FLOW); // packet is modified if return is true
void _sendViaSpecificPath(void *tPtr,SharedPtr<Peer> peer,SharedPtr<Path> viaPath,int64_t now,Packet &packet,bool encrypt,int32_t flowId);
void _sendViaSpecificPath(void *tPtr,SharedPtr<Peer> peer,SharedPtr<Path> viaPath,uint16_t userSpecifiedMtu, int64_t now,Packet &packet,bool encrypt,int32_t flowId);
const RuntimeEnvironment *const RR;
int64_t _lastBeaconResponse;

View file

@ -477,7 +477,7 @@ bool ManagedRoute::sync()
if ((newSystemVia)&&(!newSystemDevice[0])) {
rtes = _getRTEs(newSystemVia,true);
for(std::vector<_RTE>::iterator r(rtes.begin());r!=rtes.end();++r) {
if ( (r->device[0]) && (strcmp(r->device,_device) != 0) ) {
if ( (r->device[0]) && (strcmp(r->device,_device) != 0) && r->target.netmaskBits() != 0) {
Utils::scopy(newSystemDevice,sizeof(newSystemDevice),r->device);
break;
}

172
osdep/WinFWHelper.cpp Normal file
View file

@ -0,0 +1,172 @@
#include "WinFWHelper.hpp"
namespace ZeroTier {
void ZeroTier::WinFWHelper::newICMPRule(const InetAddress& ip, uint64_t nwid)
{
char nwString[32] = { 0 };
char ipbuf[64];
sprintf(nwString, "%.16llx", nwid);
std::string nwString2 = { nwString };
ip.toString(ipbuf);
if (ip.isV4()) {
WinFWHelper::newICMPv4Rule(ipbuf, nwid);
}
else {
WinFWHelper::newICMPv6Rule(ipbuf, nwid);
}
}
void ZeroTier::WinFWHelper::removeICMPRule(const InetAddress& ip, uint64_t nwid)
{
char nwString[32] = { 0 };
char ipbuf[64];
sprintf(nwString, "%.16llx", nwid);
std::string nwString2 = { nwString };
ip.toString(ipbuf);
if (ip.isV4()) {
WinFWHelper::removeICMPv4Rule(ipbuf, nwid);
}
else {
WinFWHelper::removeICMPv6Rule(ipbuf, nwid);
}
}
void WinFWHelper::newICMPv4Rule(std::string address, uint64_t nwid)
{
// allows icmp, scoped to a specific ip address and interface name
char nwString[32] = { 0 };
sprintf(nwString, "%.16llx", nwid);
std::string nwString2 = { nwString };
std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "New-NetFirewallRule -DisplayName zerotier-icmpv4-)" + nwString2 + address +
R"( -InterfaceAlias 'ZeroTier One `[)" + nwString2 + R"(`]')" +
" -Protocol ICMPv4 -Action Allow" +
" -LocalAddress " + address + "\"\r\n";
_run(cmd);
}
void WinFWHelper::newICMPv6Rule(std::string address, uint64_t nwid)
{
// allows icmp, scoped to a specific ip address and interface name
char nwString[32] = { 0 };
sprintf(nwString, "%.16llx", nwid);
std::string nwString2 = { nwString };
std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "New-NetFirewallRule -DisplayName zerotier-icmpv6-)" + nwString2 + address +
R"( -InterfaceAlias 'ZeroTier One `[)" + nwString2 + R"(`]')" +
" -Protocol ICMPv6 -Action Allow" +
" -LocalAddress " + address + "\"\r\n";
_run(cmd);
}
void WinFWHelper::removeICMPv4Rule(std::string addr, uint64_t nwid)
{
// removes 1 icmp firewall rule
char nwString[32] = { 0 };
sprintf(nwString, "%.16llx", nwid);
std::string nwString2 = { nwString };
std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "Remove-NetFirewallRule -DisplayName zerotier-icmpv4-)" + nwString2 + addr +
"\"\r\n";
_run(cmd);
}
void WinFWHelper::removeICMPv6Rule(std::string addr, uint64_t nwid)
{
// removes 1 icmp firewall rule
char nwString[32] = { 0 };
sprintf(nwString, "%.16llx", nwid);
std::string nwString2 = { nwString };
std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "Remove-NetFirewallRule -DisplayName zerotier-icmpv6-)" + nwString2 + addr +
"\"\r\n";
_run(cmd);
}
void WinFWHelper::removeICMPv4Rules(uint64_t nwid)
{
// removes all icmp firewall rules for this network id
char nwString[32] = { 0 };
sprintf(nwString, "%.16llx", nwid);
std::string nwString2 = { nwString };
std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "Remove-NetFirewallRule -DisplayName zerotier-icmpv4-)" + nwString2 + "*\" \r\n";
_run(cmd);
}
void WinFWHelper::removeICMPv6Rules(uint64_t nwid)
{
// removes all icmp firewall rules for this network id
char nwString[32] = { 0 };
sprintf(nwString, "%.16llx", nwid);
std::string nwString2 = { nwString };
std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "Remove-NetFirewallRule -DisplayName zerotier-icmpv6-)" + nwString2 + "*\" \r\n";
_run(cmd);
}
void WinFWHelper::removeICMPRules()
{
// removes all icmp firewall rules for all networks
std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "Remove-NetFirewallRule -DisplayName zerotier-icmp*)" + std::string("\r\n");
_run(cmd);
}
void WinFWHelper::removeICMPRules(uint64_t nwid)
{
// removes all icmp firewall rules for this network
WinFWHelper::removeICMPv4Rules(nwid);
WinFWHelper::removeICMPv6Rules(nwid);
}
void WinFWHelper::_run(std::string cmd)
{
#ifdef ZT_DEBUG
fprintf(stderr, cmd.c_str());
#endif
STARTUPINFOA startupInfo;
PROCESS_INFORMATION processInfo;
startupInfo.cb = sizeof(startupInfo);
memset(&startupInfo, 0, sizeof(STARTUPINFOA));
memset(&processInfo, 0, sizeof(PROCESS_INFORMATION));
if (CreateProcessA(NULL, (LPSTR)cmd.c_str(), NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &startupInfo, &processInfo)) {
WaitForSingleObject(processInfo.hProcess, INFINITE);
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
}
}
} // namespace ZeroTier

31
osdep/WinFWHelper.hpp Normal file
View file

@ -0,0 +1,31 @@
#ifndef WIN_FW_HELPER_H_
#define WIN_FW_HELPER_H_
#include "../node/InetAddress.hpp"
#include <cstdint>
#include <vector>
namespace ZeroTier {
class WinFWHelper {
public:
static void newICMPRule(const InetAddress& ip, uint64_t nwid);
static void removeICMPRule(const InetAddress& ip, uint64_t nwid);
static void removeICMPRules(uint64_t nwid);
static void removeICMPRules();
private:
static void _run(std::string cmd);
static void newICMPv4Rule(std::string address, uint64_t nwid);
static void newICMPv6Rule(std::string address, uint64_t nwid);
static void removeICMPv4Rule(std::string address, uint64_t nwid);
static void removeICMPv6Rule(std::string address, uint64_t nwid);
static void removeICMPv4Rules(uint64_t nwid);
static void removeICMPv6Rules(uint64_t nwid);
};
} // namespace ZeroTier
#endif

View file

@ -78,6 +78,7 @@
#include "../osdep/MacDNSHelper.hpp"
#elif defined(__WINDOWS__)
#include "../osdep/WinDNSHelper.hpp"
#include "../osdep/WinFWHelper.hpp"
#endif
#ifdef ZT_USE_SYSTEM_HTTP_PARSER
@ -850,6 +851,9 @@ public:
virtual ~OneServiceImpl()
{
#ifdef __WINDOWS__
WinFWHelper::removeICMPRules();
#endif
_binder.closeAll(_phy);
_phy.close(_localControlSocket4);
_phy.close(_localControlSocket6);
@ -858,6 +862,8 @@ public:
curl_global_cleanup();
#endif
#ifdef ZT_USE_MINIUPNPC
delete _portMapper;
#endif
@ -902,6 +908,7 @@ public:
_node = new Node(this,(void *)0,&cb,OSUtils::now());
}
// local.conf
readLocalSettings();
applyLocalConfig();
@ -2068,6 +2075,7 @@ public:
bool enabled = OSUtils::jsonInt(link["enabled"],true);
uint32_t capacity = OSUtils::jsonInt(link["capacity"],0);
uint8_t ipvPref = OSUtils::jsonInt(link["ipvPref"],0);
uint16_t mtu = OSUtils::jsonInt(link["mtu"],0);
std::string failoverToStr(OSUtils::jsonString(link["failoverTo"],""));
// Mode
std::string linkModeStr(OSUtils::jsonString(link["mode"],"spare"));
@ -2084,7 +2092,7 @@ public:
failoverToStr = "";
enabled = false;
}
_node->bondController()->addCustomLink(customPolicyStr, new Link(linkNameStr,ipvPref,capacity,enabled,linkMode,failoverToStr));
_node->bondController()->addCustomLink(customPolicyStr, new Link(linkNameStr,ipvPref,mtu,capacity,enabled,linkMode,failoverToStr));
}
std::string linkSelectMethodStr(OSUtils::jsonString(customPolicy["activeReselect"],"optimize"));
if (linkSelectMethodStr == "always") {
@ -2132,6 +2140,7 @@ public:
fprintf(stderr,"WARNING: using manually-specified secondary and/or tertiary ports. This can cause NAT issues." ZT_EOL_S);
}
_portMappingEnabled = OSUtils::jsonBool(settings["portMappingEnabled"],true);
_node->setLowBandwidthMode(OSUtils::jsonBool(settings["lowBandwidthMode"],false));
#ifndef ZT_SDK
const std::string up(OSUtils::jsonString(settings["softwareUpdate"],ZT_SOFTWARE_UPDATE_DEFAULT));
@ -2272,6 +2281,10 @@ public:
if (std::find(newManagedIps.begin(),newManagedIps.end(),*ip) == newManagedIps.end()) {
if (!n.tap()->removeIp(*ip))
fprintf(stderr,"ERROR: unable to remove ip address %s" ZT_EOL_S, ip->toString(ipbuf));
#ifdef __WINDOWS__
WinFWHelper::removeICMPRule(*ip, n.config().nwid);
#endif
}
}
@ -2279,6 +2292,10 @@ public:
if (std::find(n.managedIps().begin(),n.managedIps().end(),*ip) == n.managedIps().end()) {
if (!n.tap()->addIp(*ip))
fprintf(stderr,"ERROR: unable to add ip address %s" ZT_EOL_S, ip->toString(ipbuf));
#ifdef __WINDOWS__
WinFWHelper::newICMPRule(*ip, n.config().nwid);
#endif
}
}
@ -2762,8 +2779,10 @@ public:
n.tap().reset();
_nets.erase(nwid);
#if defined(__WINDOWS__) && !defined(ZT_SDK)
if ((op == ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY)&&(winInstanceId.length() > 0))
if ((op == ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY) && (winInstanceId.length() > 0)) {
WindowsEthernetTap::deletePersistentTapDevice(winInstanceId.c_str());
WinFWHelper::removeICMPRules(nwid);
}
#endif
if (op == ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY) {
char nlcpath[256];

View file

@ -124,6 +124,7 @@
<ClCompile Include="..\..\osdep\PortMapper.cpp" />
<ClCompile Include="..\..\osdep\WinDNSHelper.cpp" />
<ClCompile Include="..\..\osdep\WindowsEthernetTap.cpp" />
<ClCompile Include="..\..\osdep\WinFWHelper.cpp" />
<ClCompile Include="..\..\selftest.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@ -241,6 +242,7 @@
<ClInclude Include="..\..\osdep\Thread.hpp" />
<ClInclude Include="..\..\osdep\WinDNSHelper.hpp" />
<ClInclude Include="..\..\osdep\WindowsEthernetTap.hpp" />
<ClInclude Include="..\..\osdep\WinFWHelper.hpp" />
<ClInclude Include="..\..\service\OneService.hpp" />
<ClInclude Include="..\..\service\SoftwareUpdater.hpp" />
<ClInclude Include="..\..\version.h" />

View file

@ -288,6 +288,9 @@
<ClCompile Include="..\..\node\AES_armcrypto.cpp">
<Filter>Source Files\node</Filter>
</ClCompile>
<ClCompile Include="..\..\osdep\WinFWHelper.cpp">
<Filter>Source Files\osdep</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="resource.h">
@ -551,6 +554,9 @@
<ClInclude Include="..\..\osdep\WinDNSHelper.hpp">
<Filter>Header Files\osdep</Filter>
</ClInclude>
<ClInclude Include="..\..\osdep\WinFWHelper.hpp">
<Filter>Header Files\osdep</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="ZeroTierOne.rc">