diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 17c52ff93..4cc45681b 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -1,6 +1,10 @@ ZeroTier Release Notes ====== +# 2023-03-10 -- Version 1.10.5 + + * Fix for high CPU usage bug on Windows + # 2023-03-07 -- Version 1.10.4 * SECURITY FIX (Windows): this version fixes a file permission problem on diff --git a/debian/changelog b/debian/changelog index dc131fc78..76d9d0408 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,15 @@ +zerotier-one (1.10.6) unstable; urgency=medium + + * See RELEASE-NOTES.md for release notes. + + -- Adam Ierymenko Tue, 21 Mar 2023 01:00:00 -0700 + +zerotier-one (1.10.5) unstable; urgency=medium + + * See RELEASE-NOTES.md for release notes. + + -- Adam Ierymenko Fri, 10 Mar 2023 01:00:00 -0700 + zerotier-one (1.10.4) unstable; urgency=medium * See RELEASE-NOTES.md for release notes. diff --git a/ext/installfiles/mac/ZeroTier One.pkgproj b/ext/installfiles/mac/ZeroTier One.pkgproj index 80f4713f0..bbdb3d0b3 100755 --- a/ext/installfiles/mac/ZeroTier One.pkgproj +++ b/ext/installfiles/mac/ZeroTier One.pkgproj @@ -701,7 +701,7 @@ USE_HFS+_COMPRESSION VERSION - 1.10.4 + 1.10.6 TYPE 0 diff --git a/ext/installfiles/windows/ZeroTier One.aip b/ext/installfiles/windows/ZeroTier One.aip index daaea8cc3..ebe8e891a 100644 --- a/ext/installfiles/windows/ZeroTier One.aip +++ b/ext/installfiles/windows/ZeroTier One.aip @@ -1,15 +1,13 @@ - + - - @@ -32,10 +30,10 @@ - + - + @@ -70,7 +68,7 @@ - + @@ -140,10 +138,10 @@ - - - - + + + + @@ -296,6 +294,7 @@ + @@ -398,7 +397,7 @@ - + @@ -412,6 +411,7 @@ + @@ -528,7 +528,7 @@ - + diff --git a/java/jni/ZT_jnicache.cpp b/java/jni/ZT_jnicache.cpp index 68cacbd78..c721a9ee1 100644 --- a/java/jni/ZT_jnicache.cpp +++ b/java/jni/ZT_jnicache.cpp @@ -176,15 +176,7 @@ void setupJNICache(JavaVM *vm) { EXCEPTIONANDNULLCHECK(Peer_ctor = env->GetMethodID(Peer_class, "", "(JIIIILcom/zerotier/sdk/PeerRole;[Lcom/zerotier/sdk/PeerPhysicalPath;)V")); EXCEPTIONANDNULLCHECK(Version_ctor = env->GetMethodID(Version_class, "", "(III)V")); EXCEPTIONANDNULLCHECK(VirtualNetworkConfigListener_onNetworkConfigurationUpdated_method = env->GetMethodID(VirtualNetworkConfigListener_class, "onNetworkConfigurationUpdated", "(JLcom/zerotier/sdk/VirtualNetworkConfigOperation;Lcom/zerotier/sdk/VirtualNetworkConfig;)I")); - - - // - // ANDROID-56: temporarily remove parameters to prevent crashing - // -// EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_ctor = env->GetMethodID(VirtualNetworkConfig_class, "", "(JJLjava/lang/String;Lcom/zerotier/sdk/VirtualNetworkStatus;Lcom/zerotier/sdk/VirtualNetworkType;IZZZIJ[Ljava/net/InetSocketAddress;[Lcom/zerotier/sdk/VirtualNetworkRoute;Lcom/zerotier/sdk/VirtualNetworkDNS;)V")); - EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_ctor = env->GetMethodID(VirtualNetworkConfig_class, "", "(JJLjava/lang/String;Lcom/zerotier/sdk/VirtualNetworkStatus;Lcom/zerotier/sdk/VirtualNetworkType;IZZZ[Ljava/net/InetSocketAddress;[Lcom/zerotier/sdk/VirtualNetworkRoute;Lcom/zerotier/sdk/VirtualNetworkDNS;)V")); - - + EXCEPTIONANDNULLCHECK(VirtualNetworkConfig_ctor = env->GetMethodID(VirtualNetworkConfig_class, "", "(JJLjava/lang/String;Lcom/zerotier/sdk/VirtualNetworkStatus;Lcom/zerotier/sdk/VirtualNetworkType;IZZZIJ[Ljava/net/InetSocketAddress;[Lcom/zerotier/sdk/VirtualNetworkRoute;Lcom/zerotier/sdk/VirtualNetworkDNS;)V")); EXCEPTIONANDNULLCHECK(VirtualNetworkDNS_ctor = env->GetMethodID(VirtualNetworkDNS_class, "", "(Ljava/lang/String;Ljava/util/ArrayList;)V")); EXCEPTIONANDNULLCHECK(VirtualNetworkFrameListener_onVirtualNetworkFrame_method = env->GetMethodID(VirtualNetworkFrameListener_class, "onVirtualNetworkFrame", "(JJJJJ[B)V")); EXCEPTIONANDNULLCHECK(VirtualNetworkRoute_ctor = env->GetMethodID(VirtualNetworkRoute_class, "", "(Ljava/net/InetSocketAddress;Ljava/net/InetSocketAddress;II)V")); diff --git a/java/jni/ZT_jniutils.cpp b/java/jni/ZT_jniutils.cpp index 17e6a9b3e..8ab507bed 100644 --- a/java/jni/ZT_jniutils.cpp +++ b/java/jni/ZT_jniutils.cpp @@ -31,7 +31,7 @@ jobject createResultObject(JNIEnv *env, ZT_ResultCode code) { - jobject resultObject = env->CallStaticObjectMethod(ResultCode_class, ResultCode_fromInt_method, code); + jobject resultObject = env->CallStaticObjectMethod(ResultCode_class, ResultCode_fromInt_method, (jint)code); if(env->ExceptionCheck() || resultObject == NULL) { LOGE("Error creating ResultCode object"); return NULL; @@ -43,7 +43,7 @@ jobject createResultObject(JNIEnv *env, ZT_ResultCode code) jobject createVirtualNetworkStatus(JNIEnv *env, ZT_VirtualNetworkStatus status) { - jobject statusObject = env->CallStaticObjectMethod(VirtualNetworkStatus_class, VirtualNetworkStatus_fromInt_method, status); + jobject statusObject = env->CallStaticObjectMethod(VirtualNetworkStatus_class, VirtualNetworkStatus_fromInt_method, (jint)status); if (env->ExceptionCheck() || statusObject == NULL) { LOGE("Error creating VirtualNetworkStatus object"); return NULL; @@ -54,7 +54,7 @@ jobject createVirtualNetworkStatus(JNIEnv *env, ZT_VirtualNetworkStatus status) jobject createEvent(JNIEnv *env, ZT_Event event) { - jobject eventObject = env->CallStaticObjectMethod(Event_class, Event_fromInt_method, event); + jobject eventObject = env->CallStaticObjectMethod(Event_class, Event_fromInt_method, (jint)event); if (env->ExceptionCheck() || eventObject == NULL) { LOGE("Error creating Event object"); return NULL; @@ -65,7 +65,7 @@ jobject createEvent(JNIEnv *env, ZT_Event event) jobject createPeerRole(JNIEnv *env, ZT_PeerRole role) { - jobject peerRoleObject = env->CallStaticObjectMethod(PeerRole_class, PeerRole_fromInt_method, role); + jobject peerRoleObject = env->CallStaticObjectMethod(PeerRole_class, PeerRole_fromInt_method, (jint)role); if (env->ExceptionCheck() || peerRoleObject == NULL) { LOGE("Error creating PeerRole object"); return NULL; @@ -76,7 +76,7 @@ jobject createPeerRole(JNIEnv *env, ZT_PeerRole role) jobject createVirtualNetworkType(JNIEnv *env, ZT_VirtualNetworkType type) { - jobject vntypeObject = env->CallStaticObjectMethod(VirtualNetworkType_class, VirtualNetworkType_fromInt_method, type); + jobject vntypeObject = env->CallStaticObjectMethod(VirtualNetworkType_class, VirtualNetworkType_fromInt_method, (jint)type); if (env->ExceptionCheck() || vntypeObject == NULL) { LOGE("Error creating VirtualNetworkType object"); return NULL; @@ -87,7 +87,7 @@ jobject createVirtualNetworkType(JNIEnv *env, ZT_VirtualNetworkType type) jobject createVirtualNetworkConfigOperation(JNIEnv *env, ZT_VirtualNetworkConfigOperation op) { - jobject vnetConfigOpObject = env->CallStaticObjectMethod(VirtualNetworkConfigOperation_class, VirtualNetworkConfigOperation_fromInt_method, op); + jobject vnetConfigOpObject = env->CallStaticObjectMethod(VirtualNetworkConfigOperation_class, VirtualNetworkConfigOperation_fromInt_method, (jint)op); if (env->ExceptionCheck() || vnetConfigOpObject == NULL) { LOGE("Error creating VirtualNetworkConfigOperation object"); return NULL; @@ -113,7 +113,7 @@ jobject newInetAddress(JNIEnv *env, const sockaddr_storage &addr) } inetAddressObj = env->CallStaticObjectMethod( - InetAddress_class, InetAddress_getByAddress_method, buff); + InetAddress_class, InetAddress_getByAddress_method, (jbyteArray)buff); } break; case AF_INET: @@ -127,7 +127,7 @@ jobject newInetAddress(JNIEnv *env, const sockaddr_storage &addr) } inetAddressObj = env->CallStaticObjectMethod( - InetAddress_class, InetAddress_getByAddress_method, buff); + InetAddress_class, InetAddress_getByAddress_method, (jbyteArray)buff); } break; default: @@ -190,7 +190,7 @@ jobject newInetSocketAddress(JNIEnv *env, const sockaddr_storage &addr) int port = addressPort(addr); - jobject inetSocketAddressObject = env->NewObject(InetSocketAddress_class, InetSocketAddress_ctor, inetAddressObject, port); + jobject inetSocketAddressObject = env->NewObject(InetSocketAddress_class, InetSocketAddress_ctor, (jobject)inetAddressObject, (jint)port); if(env->ExceptionCheck() || inetSocketAddressObject == NULL) { LOGE("Error creating InetSocketAddress object"); return NULL; @@ -211,10 +211,10 @@ jobject newPeerPhysicalPath(JNIEnv *env, const ZT_PeerPhysicalPath &ppp) jobject pppObject = env->NewObject( PeerPhysicalPath_class, PeerPhysicalPath_ctor, - addressObject, - ppp.lastSend, - ppp.lastReceive, - ppp.preferred); + (jobject)addressObject, + (jlong)ppp.lastSend, + (jlong)ppp.lastReceive, + (jboolean)ppp.preferred); // ANDROID-56: cast to correct size if(env->ExceptionCheck() || pppObject == NULL) { LOGE("Error creating PPP object"); @@ -240,13 +240,13 @@ jobject newPeer(JNIEnv *env, const ZT_Peer &peer) jobject peerObject = env->NewObject( Peer_class, Peer_ctor, - peer.address, - peer.versionMajor, - peer.versionMinor, - peer.versionRev, - peer.latency, - peerRoleObj, - arrayObject); + (jlong)peer.address, + (jint)peer.versionMajor, + (jint)peer.versionMinor, + (jint)peer.versionRev, + (jint)peer.latency, + (jobject)peerRoleObj, + (jobjectArray)arrayObject); if(env->ExceptionCheck() || peerObject == NULL) { LOGE("Error creating Peer object"); @@ -298,23 +298,20 @@ jobject newNetworkConfig(JNIEnv *env, const ZT_VirtualNetworkConfig &vnetConfig) jobject vnetConfigObj = env->NewObject( VirtualNetworkConfig_class, VirtualNetworkConfig_ctor, - vnetConfig.nwid, - vnetConfig.mac, - nameStr, - statusObject, - typeObject, - vnetConfig.mtu, - vnetConfig.dhcp, - vnetConfig.bridge, - vnetConfig.broadcastEnabled, - // - // ANDROID-56: temporarily remove parameters to prevent crashing - // -// vnetConfig.portError, -// vnetConfig.netconfRevision, - assignedAddrArrayObj, - routesArrayObj, - dnsObj); + (jlong)vnetConfig.nwid, + (jlong)vnetConfig.mac, + (jstring)nameStr, + (jobject)statusObject, + (jobject)typeObject, + (jint)vnetConfig.mtu, + (jboolean)vnetConfig.dhcp, // ANDROID-56: cast to correct size + (jboolean)vnetConfig.bridge, // ANDROID-56: cast to correct size + (jboolean)vnetConfig.broadcastEnabled, // ANDROID-56: cast to correct size + (jint)vnetConfig.portError, + (jlong)vnetConfig.netconfRevision, + (jobjectArray)assignedAddrArrayObj, + (jobjectArray)routesArrayObj, + (jobject)dnsObj); if(env->ExceptionCheck() || vnetConfigObj == NULL) { LOGE("Error creating new VirtualNetworkConfig object"); @@ -327,7 +324,7 @@ jobject newNetworkConfig(JNIEnv *env, const ZT_VirtualNetworkConfig &vnetConfig) jobject newVersion(JNIEnv *env, int major, int minor, int rev) { // create a com.zerotier.sdk.Version object - jobject versionObj = env->NewObject(Version_class, Version_ctor, major, minor, rev); + jobject versionObj = env->NewObject(Version_class, Version_ctor, (jint)major, (jint)minor, (jint)rev); if(env->ExceptionCheck() || versionObj == NULL) { LOGE("Error creating new Version object"); @@ -358,10 +355,10 @@ jobject newVirtualNetworkRoute(JNIEnv *env, const ZT_VirtualNetworkRoute &route) jobject routeObj = env->NewObject( VirtualNetworkRoute_class, VirtualNetworkRoute_ctor, - targetObj, - viaObj, - route.flags, - route.metric); + (jobject)targetObj, + (jobject)viaObj, + (jint)route.flags, // ANDROID-56: cast to correct size + (jint)route.metric); // ANDROID-56: cast to correct size if(env->ExceptionCheck() || routeObj == NULL) { LOGE("Exception creating VirtualNetworkRoute"); @@ -387,7 +384,7 @@ jobject newVirtualNetworkDNS(JNIEnv *env, const ZT_VirtualNetworkDNS &dns) return NULL; } - jobject addrList = env->NewObject(ArrayList_class, ArrayList_ctor, 0); + jobject addrList = env->NewObject(ArrayList_class, ArrayList_ctor, (jint)0); if (env->ExceptionCheck() || addrList == NULL) { LOGE("Exception creating new ArrayList"); return NULL; @@ -409,7 +406,7 @@ jobject newVirtualNetworkDNS(JNIEnv *env, const ZT_VirtualNetworkDNS &dns) continue; } - env->CallBooleanMethod(addrList, ArrayList_add_method, addr); + env->CallBooleanMethod(addrList, ArrayList_add_method, (jobject)addr); if(env->ExceptionCheck()) { LOGE("Exception calling add"); @@ -422,8 +419,8 @@ jobject newVirtualNetworkDNS(JNIEnv *env, const ZT_VirtualNetworkDNS &dns) jobject dnsObj = env->NewObject( VirtualNetworkDNS_class, VirtualNetworkDNS_ctor, - domain, - addrList); + (jstring)domain, + (jobject)addrList); if (env->ExceptionCheck() || dnsObj == NULL) { LOGE("Exception creating new VirtualNetworkDNS"); return NULL; @@ -450,10 +447,10 @@ jobject newNodeStatus(JNIEnv *env, const ZT_NodeStatus &status) { jobject nodeStatusObj = env->NewObject( NodeStatus_class, NodeStatus_ctor, - status.address, - pubIdentStr, - secIdentStr, - status.online); + (jlong)status.address, + (jstring)pubIdentStr, + (jstring)secIdentStr, + (jboolean)status.online); if(env->ExceptionCheck() || nodeStatusObj == NULL) { LOGE("Exception creating new NodeStatus"); return NULL; diff --git a/java/jni/com_zerotierone_sdk_Node.cpp b/java/jni/com_zerotierone_sdk_Node.cpp index 536c7cb6a..36d722c7d 100644 --- a/java/jni/com_zerotierone_sdk_Node.cpp +++ b/java/jni/com_zerotierone_sdk_Node.cpp @@ -162,7 +162,7 @@ namespace { jint ret = env->CallIntMethod( ref->configListener, VirtualNetworkConfigListener_onNetworkConfigurationUpdated_method, - (jlong)nwid, operationObject, networkConfigObject); + (jlong)nwid, (jobject)operationObject, (jobject)networkConfigObject); if (env->ExceptionCheck()) { LOGE("Exception calling onNetworkConfigurationUpdated"); return -105; @@ -213,7 +213,7 @@ namespace { return; } - env->CallVoidMethod(ref->frameListener, VirtualNetworkFrameListener_onVirtualNetworkFrame_method, (jlong)nwid, (jlong)sourceMac, (jlong)destMac, (jlong)etherType, (jlong)vlanid, dataArray); + env->CallVoidMethod(ref->frameListener, VirtualNetworkFrameListener_onVirtualNetworkFrame_method, (jlong)nwid, (jlong)sourceMac, (jlong)destMac, (jlong)etherType, (jlong)vlanid, (jbyteArray)dataArray); if (env->ExceptionCheck()) { LOGE("Exception calling onVirtualNetworkFrame"); return; @@ -254,7 +254,7 @@ namespace { switch (event) { case ZT_EVENT_UP: { LOGD("Event Up"); - env->CallVoidMethod(ref->eventListener, EventListener_onEvent_method, eventObject); + env->CallVoidMethod(ref->eventListener, EventListener_onEvent_method, (jobject)eventObject); if (env->ExceptionCheck()) { LOGE("Exception calling onEvent"); return; @@ -263,7 +263,7 @@ namespace { } case ZT_EVENT_OFFLINE: { LOGD("Event Offline"); - env->CallVoidMethod(ref->eventListener, EventListener_onEvent_method, eventObject); + env->CallVoidMethod(ref->eventListener, EventListener_onEvent_method, (jobject)eventObject); if (env->ExceptionCheck()) { LOGE("Exception calling onEvent"); return; @@ -272,7 +272,7 @@ namespace { } case ZT_EVENT_ONLINE: { LOGD("Event Online"); - env->CallVoidMethod(ref->eventListener, EventListener_onEvent_method, eventObject); + env->CallVoidMethod(ref->eventListener, EventListener_onEvent_method, (jobject)eventObject); if (env->ExceptionCheck()) { LOGE("Exception calling onEvent"); return; @@ -281,7 +281,7 @@ namespace { } case ZT_EVENT_DOWN: { LOGD("Event Down"); - env->CallVoidMethod(ref->eventListener, EventListener_onEvent_method, eventObject); + env->CallVoidMethod(ref->eventListener, EventListener_onEvent_method, (jobject)eventObject); if (env->ExceptionCheck()) { LOGE("Exception calling onEvent"); return; @@ -291,7 +291,7 @@ namespace { case ZT_EVENT_FATAL_ERROR_IDENTITY_COLLISION: { LOGV("Identity Collision"); // call onEvent() - env->CallVoidMethod(ref->eventListener, EventListener_onEvent_method, eventObject); + env->CallVoidMethod(ref->eventListener, EventListener_onEvent_method, (jobject)eventObject); if (env->ExceptionCheck()) { LOGE("Exception calling onEvent"); return; @@ -311,7 +311,7 @@ namespace { return; } - env->CallVoidMethod(ref->eventListener, EventListener_onTrace_method, messageStr); + env->CallVoidMethod(ref->eventListener, EventListener_onTrace_method, (jstring)messageStr); if (env->ExceptionCheck()) { LOGE("Exception calling onTrace"); return; @@ -398,7 +398,7 @@ namespace { int retval = env->CallIntMethod(ref->dataStorePutListener, DataStorePutListener_onDataStorePut_method, - nameStr, bufferObj, secure); + (jstring)nameStr, (jbyteArray)bufferObj, (jboolean)secure); if (env->ExceptionCheck()) { LOGE("Exception calling onDataStorePut"); return; @@ -410,7 +410,7 @@ namespace { } else { LOGD("JNI: Delete file: %s", p); - int retval = env->CallIntMethod(ref->dataStorePutListener, DataStorePutListener_onDelete_method, nameStr); + int retval = env->CallIntMethod(ref->dataStorePutListener, DataStorePutListener_onDelete_method, (jstring)nameStr); if (env->ExceptionCheck()) { LOGE("Exception calling onDelete"); return; @@ -500,8 +500,8 @@ namespace { int retval = (int)env->CallLongMethod( ref->dataStoreGetListener, DataStoreGetListener_onDataStoreGet_method, - nameStr, - bufferObj); + (jstring)nameStr, + (jbyteArray)bufferObj); if (env->ExceptionCheck()) { LOGE("Exception calling onDataStoreGet"); return -106; @@ -570,7 +570,7 @@ namespace { return -103; } - int retval = env->CallIntMethod(ref->packetSender, PacketSender_onSendPacketRequested_method, localSocket, remoteAddressObj, bufferObj, 0); + int retval = env->CallIntMethod(ref->packetSender, PacketSender_onSendPacketRequested_method, (jlong)localSocket, (jobject)remoteAddressObj, (jbyteArray)bufferObj, (jint)0); if (env->ExceptionCheck()) { LOGE("Exception calling onSendPacketRequested"); return -104; @@ -616,7 +616,7 @@ namespace { return true; } - jboolean ret = env->CallBooleanMethod(ref->pathChecker, PathChecker_onPathCheck_method, address, localSocket, remoteAddressObj); + jboolean ret = env->CallBooleanMethod(ref->pathChecker, PathChecker_onPathCheck_method, (jlong)address, (jlong)localSocket, (jobject)remoteAddressObj); if (env->ExceptionCheck()) { LOGE("Exception calling onPathCheck"); return true; @@ -656,7 +656,7 @@ namespace { // // may be NULL // - jobject sockAddressObject = env->CallObjectMethod(ref->pathChecker, PathChecker_onPathLookup_method, address, ss_family); + jobject sockAddressObject = env->CallObjectMethod(ref->pathChecker, PathChecker_onPathLookup_method, (jlong)address, (jint)ss_family); if (env->ExceptionCheck()) { LOGE("Unable to call onPathLookup implementation"); return false; diff --git a/java/src/com/zerotier/sdk/VirtualNetworkConfig.java b/java/src/com/zerotier/sdk/VirtualNetworkConfig.java index fea354d07..bcf64854a 100644 --- a/java/src/com/zerotier/sdk/VirtualNetworkConfig.java +++ b/java/src/com/zerotier/sdk/VirtualNetworkConfig.java @@ -66,12 +66,9 @@ public class VirtualNetworkConfig implements Comparable { private final boolean broadcastEnabled; - // - // ANDROID-56: temporarily remove parameters to prevent crashing - // -// private final int portError; -// -// private final long netconfRevision; + private final int portError; + + private final long netconfRevision; private final InetSocketAddress[] assignedAddresses; @@ -79,7 +76,7 @@ public class VirtualNetworkConfig implements Comparable { private final VirtualNetworkDNS dns; - public VirtualNetworkConfig(long nwid, long mac, String name, VirtualNetworkStatus status, VirtualNetworkType type, int mtu, boolean dhcp, boolean bridge, boolean broadcastEnabled, InetSocketAddress[] assignedAddresses, VirtualNetworkRoute[] routes, VirtualNetworkDNS dns) { + public VirtualNetworkConfig(long nwid, long mac, String name, VirtualNetworkStatus status, VirtualNetworkType type, int mtu, boolean dhcp, boolean bridge, boolean broadcastEnabled, int portError, long netconfRevision, InetSocketAddress[] assignedAddresses, VirtualNetworkRoute[] routes, VirtualNetworkDNS dns) { this.nwid = nwid; this.mac = mac; this.name = name; @@ -92,11 +89,11 @@ public class VirtualNetworkConfig implements Comparable { this.dhcp = dhcp; this.bridge = bridge; this.broadcastEnabled = broadcastEnabled; -// this.portError = portError; -// if (netconfRevision < 0) { -// throw new RuntimeException("netconfRevision < 0: " + netconfRevision); -// } -// this.netconfRevision = netconfRevision; + this.portError = portError; + if (netconfRevision < 0) { + throw new RuntimeException("netconfRevision < 0: " + netconfRevision); + } + this.netconfRevision = netconfRevision; this.assignedAddresses = assignedAddresses; this.routes = routes; this.dns = dns; @@ -104,7 +101,7 @@ public class VirtualNetworkConfig implements Comparable { @Override public String toString() { - return "VirtualNetworkConfig(" + StringUtils.networkIdToString(nwid) + ", " + StringUtils.macAddressToString(mac) + ", " + name + ", " + status + ", " + type + ", " + mtu + ", " + dhcp + ", " + bridge + ", " + broadcastEnabled + ", " + Arrays.toString(assignedAddresses) + ", " + Arrays.toString(routes) + ", " + dns + ")"; + return "VirtualNetworkConfig(" + StringUtils.networkIdToString(nwid) + ", " + StringUtils.macAddressToString(mac) + ", " + name + ", " + status + ", " + type + ", " + mtu + ", " + dhcp + ", " + bridge + ", " + broadcastEnabled + ", " + portError + ", " + netconfRevision + ", " + Arrays.toString(assignedAddresses) + ", " + Arrays.toString(routes) + ", " + dns + ")"; } @Override @@ -171,17 +168,17 @@ public class VirtualNetworkConfig implements Comparable { return false; } -// if (this.portError != cfg.portError) { -// Log.i(TAG, "Port Error Changed. Old: " + this.portError + ", New: " + cfg.portError); -// -// return false; -// } -// -// if (this.netconfRevision != cfg.netconfRevision) { -// Log.i(TAG, "NetConfRevision Changed. Old: " + this.netconfRevision + ", New: " + cfg.netconfRevision); -// -// return false; -// } + if (this.portError != cfg.portError) { + Log.i(TAG, "Port Error Changed. Old: " + this.portError + ", New: " + cfg.portError); + + return false; + } + + if (this.netconfRevision != cfg.netconfRevision) { + Log.i(TAG, "NetConfRevision Changed. Old: " + this.netconfRevision + ", New: " + cfg.netconfRevision); + + return false; + } if (!Arrays.equals(assignedAddresses, cfg.assignedAddresses)) { @@ -280,8 +277,8 @@ public class VirtualNetworkConfig implements Comparable { result = 37 * result + (dhcp ? 1 : 0); result = 37 * result + (bridge ? 1 : 0); result = 37 * result + (broadcastEnabled ? 1 : 0); -// result = 37 * result + portError; -// result = 37 * result + (int) (netconfRevision ^ (netconfRevision >>> 32)); + result = 37 * result + portError; + result = 37 * result + (int) (netconfRevision ^ (netconfRevision >>> 32)); result = 37 * result + Arrays.hashCode(assignedAddresses); result = 37 * result + Arrays.hashCode(routes); result = 37 * result + (dns == null ? 0 : dns.hashCode()); @@ -362,18 +359,18 @@ public class VirtualNetworkConfig implements Comparable { /** * If the network is in PORT_ERROR state, this is the error most recently returned by the port config callback */ -// public int getPortError() { -// return portError; -// } + public int getPortError() { + return portError; + } /** * Network config revision as reported by netconf master * *

If this is zero, it means we're still waiting for our netconf.

*/ -// public long getNetconfRevision() { -// return netconfRevision; -// } + public long getNetconfRevision() { + return netconfRevision; + } /** * ZeroTier-assigned addresses (in {@link InetSocketAddress} objects) diff --git a/node/Peer.cpp b/node/Peer.cpp index 28351c28d..5cb55fa4b 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -109,6 +109,13 @@ void Peer::received( havePath = true; break; } + // If same address on same interface then don't learn unless existing path isn't alive (prevents learning loop) + if (_paths[i].p->address().ipsEqual(path->address()) && _paths[i].p->localSocket() == path->localSocket()) { + if (_paths[i].p->alive(now) && !_bond) { + havePath = true; + break; + } + } } else { break; } @@ -116,69 +123,37 @@ void Peer::received( } if ( (!havePath) && RR->node->shouldUsePathForZeroTierTraffic(tPtr,_id.address(),path->localSocket(),path->address()) ) { - - /** - * First, fill all free slots before attempting to replace a path - * - If the above fails, attempt to replace the path that has been dead the longest - * - If there are no free slots, and no dead paths (unlikely), then replace old path most similar to new path - * - If all of the above fails to yield a suitable replacement. Replace first path found to have lower `(quality / priority)` - */ - if (verb == Packet::VERB_OK) { Mutex::Lock _l(_paths_m); + unsigned int oldestPathIdx = ZT_MAX_PEER_NETWORK_PATHS; + unsigned int oldestPathAge = 0; unsigned int replacePath = ZT_MAX_PEER_NETWORK_PATHS; - uint64_t maxScore = 0; - uint64_t currScore; - long replacePathQuality = 0; - bool foundFreeSlot = false; for(unsigned int i=0;ialive(now)) { - currScore = _paths[i].p->age(now) / 1000; + // Keep track of oldest path as a last resort option + unsigned int currAge = _paths[i].p->age(now); + if (currAge > oldestPathAge) { + oldestPathAge = currAge; + oldestPathIdx = i; } - // Reward as similarity increases if (_paths[i].p->address().ipsEqual(path->address())) { - currScore++; - if (_paths[i].p->address().port() == path->address().port()) { - currScore++; - if (_paths[i].p->localSocket() == path->localSocket()) { - currScore++; // max score (3) + if (_paths[i].p->localSocket() == path->localSocket()) { + if (!_paths[i].p->alive(now)) { + replacePath = i; + break; } } } - // If best so far, mark for replacement - if (currScore > maxScore) { - maxScore = currScore; - replacePath = i; - } } else { - foundFreeSlot = true; replacePath = i; break; } } - if (!foundFreeSlot) { - if (maxScore > 3) { - // Do nothing. We found a dead path and have already marked it as a candidate - } - // If we couldn't find a replacement by matching, replacing a dead path, or taking a free slot, then replace by quality - else if (maxScore == 0) { - for(unsigned int i=0;iquality(now) / _paths[i].priority; - if (q > replacePathQuality) { - replacePathQuality = q; - replacePath = i; - } - } - } - } - } + // If we didn't find a good candidate then resort to replacing oldest path + replacePath = (replacePath == ZT_MAX_PEER_NETWORK_PATHS) ? oldestPathIdx : replacePath; if (replacePath != ZT_MAX_PEER_NETWORK_PATHS) { RR->t->peerLearnedNewPath(tPtr, networkId, *this, path, packetId); _paths[replacePath].lr = now; @@ -540,11 +515,15 @@ unsigned int Peer::doPingAndKeepalive(void *tPtr,int64_t now) // let those old links expire. long maxPriority = 0; for(unsigned int i=0;isent(now); sent |= (_paths[i].p->address().ss_family == AF_INET) ? 0x1 : 0x2; } - } else { - _paths[i] = _PeerPath(); } - } else break; + else { + _paths[i] = _PeerPath(); + deletionOccurred = true; + } + } + if (!_paths[i].p || deletionOccurred) { + for(unsigned int j=i;j -#if ! defined(TARGET_OS_IOS) +#if defined(TARGET_OS_OSX) #include #endif #include @@ -333,7 +333,7 @@ class Binder { while (ifa) { if ((ifa->ifa_name) && (ifa->ifa_addr)) { InetAddress ip = *(ifa->ifa_addr); -#if (defined(__unix__) || defined(__APPLE__)) && !defined(__LINUX__) && !defined(ZT_SDK) && !defined(TARGET_OS_IOS) +#if (defined(__unix__) || defined(__APPLE__)) && !defined(__LINUX__) && !defined(ZT_SDK) && defined(TARGET_OS_OSX) // Check if the address is an IPv6 Temporary Address, macOS/BSD version if (ifa->ifa_addr->sa_family == AF_INET6) { struct sockaddr_in6* sa6 = (struct sockaddr_in6*)ifa->ifa_addr; @@ -349,8 +349,8 @@ class Binder { // if this is a temporary IPv6 address, skip to the next address if (flags & IN6_IFF_TEMPORARY) { - char buf[64]; #ifdef ZT_TRACE + char buf[64]; fprintf(stderr, "skip binding to temporary IPv6 address: %s\n", ip.toIpString(buf)); #endif ifa = ifa->ifa_next; diff --git a/service/OneService.cpp b/service/OneService.cpp index d01ae7d95..5864f2075 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -2307,8 +2307,10 @@ public: auto same_subnet = [ip](InetAddress i){ return ip->network() == i.network(); }; +#endif if (std::find(n.managedIps().begin(),n.managedIps().end(),*ip) == n.managedIps().end()) { +#ifdef __APPLE__ // if same subnet as a previously added address if ( std::find_if(n.managedIps().begin(),n.managedIps().end(), same_subnet) != n.managedIps().end() || @@ -2322,15 +2324,17 @@ public: } else { newManagedIps2.push_back(*ip); } - } #endif - 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 + if (! n.tap()->addIp(*ip)) { + fprintf(stderr, "ERROR: unable to add ip address %s" ZT_EOL_S, ip->toString(ipbuf)); + } + else { +#ifdef __WINDOWS__ + WinFWHelper::newICMPRule(*ip, n.config().nwid); +#endif + } + } } #ifdef __APPLE__ diff --git a/version.h b/version.h index f4d8abd09..6feff8bf2 100644 --- a/version.h +++ b/version.h @@ -27,7 +27,7 @@ /** * Revision */ -#define ZEROTIER_ONE_VERSION_REVISION 4 +#define ZEROTIER_ONE_VERSION_REVISION 6 /** * Build version diff --git a/zerotier-one.spec b/zerotier-one.spec index 7382b74c6..8ad75cfac 100644 --- a/zerotier-one.spec +++ b/zerotier-one.spec @@ -1,5 +1,5 @@ Name: zerotier-one -Version: 1.10.4 +Version: 1.10.6 Release: 1%{?dist} Summary: ZeroTier network virtualization service @@ -137,6 +137,12 @@ chmod 0755 $RPM_BUILD_ROOT/etc/init.d/zerotier-one %endif %changelog +* Tue Mar 21 2023 Adam Ierymenko - 1.10.6 +- see https://github.com/zerotier/ZeroTierOne for release notes + +* Sat Mar 10 2023 Adam Ierymenko - 1.10.5 +- see https://github.com/zerotier/ZeroTierOne for release notes + * Sat Mar 06 2023 Adam Ierymenko - 1.10.4 - see https://github.com/zerotier/ZeroTierOne for release notes