From f82085ceded9212f5f9290a818c70857bcea1a79 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Mon, 8 Mar 2021 14:05:33 -0500 Subject: [PATCH] cleanup, warning removal. --- core/AES.hpp | 28 ++--- core/AES_aesni.cpp | 3 + core/AES_armcrypto.cpp | 2 + core/Certificate.cpp | 12 +- core/Certificate.hpp | 2 +- core/Constants.hpp | 9 -- core/MIMC52.cpp | 8 +- core/Spinlock.hpp | 15 ++- core/Topology.cpp | 17 +-- core/Utils.cpp | 81 +++++++------ core/Utils.hpp | 18 +-- rust-zerotier-core/src/address.rs | 18 +-- rust-zerotier-core/src/mac.rs | 18 +-- rust-zerotier-core/src/networkid.rs | 18 +-- rust-zerotier-service/Cargo.lock | 170 ++++++++++++++++++++++++++++ rust-zerotier-service/Cargo.toml | 1 + 16 files changed, 270 insertions(+), 150 deletions(-) diff --git a/core/AES.hpp b/core/AES.hpp index c66613dd5..2216d0106 100644 --- a/core/AES.hpp +++ b/core/AES.hpp @@ -190,21 +190,22 @@ public: { _rp = 0; _len = 0; + // We fill the least significant 32 bits in the _iv field with 1 since in GCM mode - // this would hold the counter, but we're not doing GCM. The counter is therefore - // always 1. + // this would hold the counter, but we're not doing GCM just GMAC. That means the + // counter always stays just 1. #ifdef ZT_AES_AESNI // also implies an x64 processor *reinterpret_cast(_iv) = *reinterpret_cast(iv); *reinterpret_cast(_iv + 8) = *reinterpret_cast(iv + 8); *reinterpret_cast(_iv + 12) = 0x01000000; // 0x00000001 in big-endian byte order #else - for(int i=0;i<12;++i) - _iv[i] = iv[i]; + Utils::copy<12>(_iv, iv); _iv[12] = 0; _iv[13] = 0; _iv[14] = 0; _iv[15] = 1; #endif + _y[0] = 0; _y[1] = 0; } @@ -247,7 +248,8 @@ public: * Streaming AES-CTR encrypt/decrypt * * NOTE: this doesn't support overflow of the counter in the least significant 32 bits. - * AES-GMAC-CTR doesn't need this, so we don't support it as an optimization. + * We will never encrypt more than a tiny fraction of 2^32 blocks, so this is left out as + * an optimization. */ class CTR { @@ -359,10 +361,9 @@ public: /** * Process AAD (additional authenticated data) that is not being encrypted. * - * If such data exists this must be called before update1() and finish1(). - * - * Note: current code only supports one single chunk of AAD. Don't call this - * multiple times per message. + * This MUST be called before update1() and finish1() if there is AAD to + * be included. This also MUST NOT be called more than once as the current + * code only supports one chunk of AAD. * * @param aad Additional authenticated data * @param len Length of AAD in bytes @@ -375,7 +376,7 @@ public: // End of AAD is padded to a multiple of 16 bytes to ensure unique encoding. len &= 0xfU; if (len != 0) - _gmac.update(Utils::ZERO256, 16 - len); + _gmac.update(Utils::ZERO256, 16U - len); } /** @@ -401,7 +402,7 @@ public: // this get split into the packet ID (64 bits) and the MAC (64 bits) in each // packet and then recombined on receipt for legacy reasons (but with no // cryptographic or performance impact). - _tag[1] = tmp[0] ^ tmp[1]; + _tag[1] = tmp[0] ^ tmp[1]; // NOTE: _tag[0] already contains message IV, see init() _ctr._aes.encrypt(_tag, _tag); // Initialize CTR with 96-bit CTR nonce and 32-bit counter. The counter @@ -420,8 +421,9 @@ public: /** * Second pass plaintext input function * - * The same plaintext must be fed in the second time in the same order, - * though chunk boundaries do not have to be the same. + * The same plaintext must be fed in the second time. Chunk boundaries + * (between calls to update2()) do not have to be the same, just the order + * of the bytes. * * @param input Plaintext chunk * @param len Length of plaintext chunk diff --git a/core/AES_aesni.cpp b/core/AES_aesni.cpp index b296b693a..cb7f84000 100644 --- a/core/AES_aesni.cpp +++ b/core/AES_aesni.cpp @@ -11,6 +11,9 @@ */ /****/ +// AES for X64 AES-NI extensions (no 32-bit X86 support). Supports AVX2 and +// AVX512 VAES for performance in excess of 10GiB/sec/core on newer chips. + #include "Constants.hpp" #include "AES.hpp" diff --git a/core/AES_armcrypto.cpp b/core/AES_armcrypto.cpp index f76c64f5c..39628c08c 100644 --- a/core/AES_armcrypto.cpp +++ b/core/AES_armcrypto.cpp @@ -11,6 +11,8 @@ */ /****/ +// AES for ARM crypto extensions and NEON. + #include "Constants.hpp" #include "AES.hpp" diff --git a/core/Certificate.cpp b/core/Certificate.cpp index 1d9616c58..544a60995 100644 --- a/core/Certificate.cpp +++ b/core/Certificate.cpp @@ -222,9 +222,15 @@ Vector< uint8_t > Certificate::encode(const bool omitSignature) const Vector< uint8_t > enc; Dictionary d; - // A Dictionary is used to encode certificates as it's a common and extensible - // format. Custom packed formats are used for credentials as these are smaller - // and faster to marshal/unmarshal. + /* + * A Dictionary is used to encode certificates as it's a common and extensible + * format. Custom packed formats are used for credentials as these are smaller + * and faster to marshal/unmarshal. + * + * We use the slower actually-insert-keys method of building a dictionary + * instead of the faster append method because for signing and verification + * purposes the keys must be always be in order. + */ if (this->flags != 0) d.add("f", this->flags); diff --git a/core/Certificate.hpp b/core/Certificate.hpp index 2b666d3c9..32db7cfc9 100644 --- a/core/Certificate.hpp +++ b/core/Certificate.hpp @@ -52,7 +52,7 @@ class Certificate : public ZT_Certificate public: Certificate() noexcept; - Certificate(const ZT_Certificate &apiCert); + explicit Certificate(const ZT_Certificate &apiCert); Certificate(const Certificate &cert); ~Certificate(); diff --git a/core/Constants.hpp b/core/Constants.hpp index c7df13fa1..324dd7dea 100644 --- a/core/Constants.hpp +++ b/core/Constants.hpp @@ -23,15 +23,6 @@ #include "zerotier.h" #include "version.h" -/** - * Version bit packed into four 16-bit fields in a 64-bit unsigned integer. - */ -#define ZT_VERSION_PACKED ( \ - ((uint64_t)ZEROTIER_VERSION_MAJOR << 48U) | \ - ((uint64_t)ZEROTIER_VERSION_MINOR << 32U) | \ - ((uint64_t)ZEROTIER_VERSION_REVISION << 16U) | \ - ((uint64_t)ZEROTIER_VERSION_BUILD) ) - /** * Length of a ZeroTier address in bytes */ diff --git a/core/MIMC52.cpp b/core/MIMC52.cpp index 15f5696af..4b1e73d02 100644 --- a/core/MIMC52.cpp +++ b/core/MIMC52.cpp @@ -45,8 +45,8 @@ const uint32_t ZT_MIMC52_PRIMES[1024] = {4294895267, 4294895477, 4294895513, 429 #ifdef ZT_NO_IEEE_DOUBLE -// Integer 64-bit modular multiply for systems without an IEEE FPU. This is -// much slower on systems that can use the FPU hack. +/* Integer 64-bit modular multiply for systems without an IEEE FPU. This is + * much slower on systems that can use the FPU hack. */ static uint64_t mulmod64(uint64_t a, uint64_t b, const uint64_t m) { uint64_t res = 0; @@ -63,6 +63,10 @@ static uint64_t mulmod64(uint64_t a, uint64_t b, const uint64_t m) #else +/* If we have IEEE double precision FPU support, we can do this trick to + * execute a 52-bit mulmod faster than the integer ALU. This trick is why + * this is a 52-bit work function and not a 64-bit work function, as it + * performs fairly equally across CPUs. */ ZT_INLINE uint64_t mulmod52(uint64_t a, const uint64_t b, const uint64_t m, const double mf) { a = ( ( a * b ) - ( ((uint64_t)(((double)a * (double)b) / mf) - 1) * m ) ); diff --git a/core/Spinlock.hpp b/core/Spinlock.hpp index dea4390bb..bbd7a9223 100644 --- a/core/Spinlock.hpp +++ b/core/Spinlock.hpp @@ -14,9 +14,14 @@ #ifndef ZT_SPINLOCK_HPP #define ZT_SPINLOCK_HPP -#include "OS.hpp" +#include "Constants.hpp" +#include "Mutex.hpp" +#ifdef __LINUX__ +#include +#else #include +#endif /** * Simple spinlock @@ -27,14 +32,18 @@ class Spinlock { public: - ZT_INLINE Spinlock() noexcept - { m_locked.clear(); } + ZT_INLINE Spinlock() noexcept: m_locked(false) + {} ZT_INLINE void lock() noexcept { if (unlikely(m_locked.test_and_set(std::memory_order_acquire))) { do { +#ifdef __LINUX__ + sched_yield(); +#else std::this_thread::yield(); +#endif } while (m_locked.test_and_set(std::memory_order_acquire)); } } diff --git a/core/Topology.cpp b/core/Topology.cpp index 3738bfac3..bcf9dafa4 100644 --- a/core/Topology.cpp +++ b/core/Topology.cpp @@ -41,9 +41,10 @@ Topology::Topology(const RuntimeEnvironment *renv, void *tPtr, const int64_t now addCertificate(tPtr, cert, now, (unsigned int)d.getUI(Dictionary::arraySubscript(tmp, sizeof(tmp), "c$.lt", idx)), false, false, false); } } - m_cleanCertificates(tPtr, now); - m_updateRootPeers(tPtr, now); } + + m_cleanCertificates(tPtr, now); + m_updateRootPeers(tPtr, now); } SharedPtr< Peer > Topology::add(void *tPtr, const SharedPtr< Peer > &peer) @@ -89,7 +90,7 @@ void Topology::doPeriodicTasks(void *tPtr, const int64_t now) } } - // Rank roots and get root lookup map. + // Get a list of root peer pointer addresses for filtering during peer cleanup. Vector< uintptr_t > rootLookup; { Mutex::Lock l(m_roots_l); @@ -102,17 +103,12 @@ void Topology::doPeriodicTasks(void *tPtr, const int64_t now) // Cleaning of peers and paths uses a two pass method to avoid write locking // m_peers or m_paths for any significant amount of time. This avoids pauses // on nodes with large numbers of peers or paths. - - // Delete peers that are stale or offline and are not roots. First pass: grab - // peers to delete in read lock mode. Second pass: delete peers one by one, - // acquiring hard write lock each time to avoid pauses. { Vector< Address > toDelete; { RWMutex::RLock l1(m_peers_l); for (Map< Address, SharedPtr< Peer > >::iterator i(m_peers.begin()); i != m_peers.end(); ++i) { - // TODO: also delete if the peer has not exchanged meaningful communication in a while, such as - // a network frame or non-trivial control packet. + // TODO: also delete if the peer has not exchanged meaningful communication in a while, such as a network frame or non-trivial control packet. if (((now - i->second->lastReceive()) > ZT_PEER_ALIVE_TIMEOUT) && (std::find(rootLookup.begin(), rootLookup.end(), (uintptr_t)(i->second.ptr())) == rootLookup.end())) toDelete.push_back(i->first); } @@ -307,13 +303,12 @@ struct p_RootRankingComparisonOperator void Topology::m_rankRoots(const int64_t now) { // assumes m_roots is locked - std::sort(m_roots.begin(), m_roots.end(), p_RootRankingComparisonOperator()); - if (unlikely(m_roots.empty())) { l_bestRoot.lock(); m_bestRoot.zero(); l_bestRoot.unlock(); } else { + std::sort(m_roots.begin(), m_roots.end(), p_RootRankingComparisonOperator()); l_bestRoot.lock(); m_bestRoot = m_roots.front(); l_bestRoot.unlock(); diff --git a/core/Utils.cpp b/core/Utils.cpp index 6f7d9f462..f104b2fb3 100644 --- a/core/Utils.cpp +++ b/core/Utils.cpp @@ -16,14 +16,14 @@ #include "AES.hpp" #include "SHA512.hpp" +#include + #ifdef __UNIX_LIKE__ #include #include #include #endif -#include - #ifdef __WINDOWS__ #include #include @@ -64,13 +64,13 @@ static inline long getauxval(int caps) #define HWCAP_SHA2 0 #endif -#endif // ZT_ARCH_ARM_HAS_NEON +#endif /* ZT_ARCH_ARM_HAS_NEON */ namespace ZeroTier { namespace Utils { -#ifdef ZT_ARCH_ARM_HAS_NEON /****************************************************************************************/ +#ifdef ZT_ARCH_ARM_HAS_NEON ARMCapabilities::ARMCapabilities() noexcept { @@ -111,9 +111,9 @@ ARMCapabilities::ARMCapabilities() noexcept } const ARMCapabilities ARMCAP; -#endif /*************************************************************************************************************/ +#endif /* ZT_ARCH_ARM_HAS_NEON */ -#ifdef ZT_ARCH_X64 /*************************************************************************************************/ +#ifdef ZT_ARCH_X64 CPUIDRegisters::CPUIDRegisters() noexcept { uint32_t eax, ebx, ecx, edx; @@ -160,7 +160,7 @@ CPUIDRegisters::CPUIDRegisters() noexcept } const CPUIDRegisters CPUID; -#endif /*************************************************************************************************************/ +#endif /* ZT_ARCH_X64 */ const std::bad_alloc BadAllocException; const std::out_of_range OutOfRangeException("access out of range"); @@ -313,28 +313,29 @@ void getSecureRandom(void *const buf, unsigned int bytes) noexcept Mutex::Lock gl(globalLock); - // Re-initialize the generator every ITERATIONS_PER_GENERATOR bytes. - if (unlikely((randomByteCounter += bytes) >= ZT_GETSECURERANDOM_ITERATIONS_PER_GENERATOR)) { - // On first run fill randomState with random bits from the system. + // Re-initialize the PRNG every ZT_GETSECURERANDOM_ITERATIONS_PER_GENERATOR bytes. Note that + // if 'bytes' is larger than ZT_GETSECURERANDOM_ITERATIONS_PER_GENERATOR we can generate more + // than this, but this isn't an issue. ZT_GETSECURERANDOM_ITERATIONS_PER_GENERATOR could be + // much larger if we wanted and this would still be safe. + randomByteCounter += bytes; + if (unlikely(randomByteCounter >= ZT_GETSECURERANDOM_ITERATIONS_PER_GENERATOR)) { + randomByteCounter = 0; + if (unlikely(!initialized)) { initialized = true; - - // Don't let randomState be swapped to disk (if supported by OS). Utils::memoryLock(randomState, sizeof(randomState)); - - // Fill randomState with entropy from the system. Failure equals hard exit. Utils::zero< sizeof(randomState) >(randomState); #ifdef __WINDOWS__ HCRYPTPROV cryptProvider = NULL; - if (!CryptAcquireContextA(&cryptProvider,NULL,NULL,PROV_RSA_FULL,CRYPT_VERIFYCONTEXT|CRYPT_SILENT)) { - fprintf(stderr,"FATAL: Utils::getSecureRandom() unable to obtain WinCrypt context!\r\n"); - exit(1); - } - if (!CryptGenRandom(cryptProvider,(DWORD)sizeof(randomState),(BYTE *)randomState)) { - fprintf(stderr,"FATAL: Utils::getSecureRandom() CryptGenRandom failed!\r\n"); - exit(1); - } - CryptReleaseContext(cryptProvider,0); + if (!CryptAcquireContextA(&cryptProvider,NULL,NULL,PROV_RSA_FULL,CRYPT_VERIFYCONTEXT|CRYPT_SILENT)) { + fprintf(stderr,"FATAL: Utils::getSecureRandom() unable to obtain WinCrypt context!\r\n"); + exit(1); + } + if (!CryptGenRandom(cryptProvider,(DWORD)sizeof(randomState),(BYTE *)randomState)) { + fprintf(stderr,"FATAL: Utils::getSecureRandom() CryptGenRandom failed!\r\n"); + exit(1); + } + CryptReleaseContext(cryptProvider,0); #else int devURandomFd = ::open("/dev/urandom", O_RDONLY); if (devURandomFd < 0) { @@ -348,19 +349,17 @@ void getSecureRandom(void *const buf, unsigned int bytes) noexcept } close(devURandomFd); #endif - #ifdef __UNIX_LIKE__ randomState[0] += (uint64_t)getpid(); randomState[1] += (uint64_t)getppid(); #endif #ifdef ZT_ARCH_X64 if (CPUID.rdrand) { - // RDRAND is very slow on some chips, so only sample it a little bit for extra entropy. uint64_t tmp = 0; - _rdrand64_step((unsigned long long *)&tmp); - randomState[2] ^= tmp; - _rdrand64_step((unsigned long long *)&tmp); - randomState[3] ^= tmp; + for (unsigned long i = 0; i < ZT_GETSECURERANDOM_STATE_SIZE; ++i) { + _rdrand64_step((unsigned long long *)&tmp); + randomState[i] ^= tmp; + } } #endif } @@ -368,10 +367,7 @@ void getSecureRandom(void *const buf, unsigned int bytes) noexcept // Initialize or re-initialize generator by hashing the full state, // replacing the first 64 bytes with this hash, and then re-initializing // AES with the first 32 bytes. - randomByteCounter = 0; - randomState[4] += (uint64_t)((uintptr_t)buf); - randomState[5] += (uint64_t)bytes; - randomState[6] += (uint64_t)time(nullptr); + randomState[0] += (uint64_t)time(nullptr); SHA512(randomState, randomState, sizeof(randomState)); randomGen.init(randomState); } @@ -381,12 +377,14 @@ void getSecureRandom(void *const buf, unsigned int bytes) noexcept // for a random generator. uint64_t *const ctr = randomState + 4; uint8_t *out = reinterpret_cast(buf); + while (bytes >= 16) { ++*ctr; randomGen.encrypt(ctr, out); out += 16; bytes -= 16; } + if (bytes > 0) { uint8_t tmp[16]; ++*ctr; @@ -482,19 +480,18 @@ int b32d(const char *encoded, uint8_t *result, int bufSize) noexcept uint64_t random() noexcept { - // https://en.wikipedia.org/wiki/Xorshift#xoshiro256** - static volatile uint64_t s_s0 = getSecureRandomU64(); static volatile uint64_t s_s1 = getSecureRandomU64(); static volatile uint64_t s_s2 = getSecureRandomU64(); static volatile uint64_t s_s3 = getSecureRandomU64(); + // https://en.wikipedia.org/wiki/Xorshift#xoshiro256** uint64_t s0 = s_s0; uint64_t s1 = s_s1; uint64_t s2 = s_s2; uint64_t s3 = s_s3; - const uint64_t s1x5 = s1 * 5; - const uint64_t result = ((s1x5 << 7U) | (s1x5 >> 57U)) * 9; + const uint64_t s1x5 = s1 * 5ULL; + const uint64_t result = ((s1x5 << 7U) | (s1x5 >> 57U)) * 9ULL; const uint64_t t = s1 << 17U; s2 ^= s0; s3 ^= s1; @@ -512,9 +509,10 @@ uint64_t random() noexcept bool scopy(char *const dest, const unsigned int len, const char *const src) noexcept { - if (!len) - return false; // sanity check - if (!src) { + if (unlikely((len == 0)||(dest == nullptr))) { + return false; + } + if (unlikely(src == nullptr)) { *dest = (char)0; return true; } @@ -524,8 +522,9 @@ bool scopy(char *const dest, const unsigned int len, const char *const src) noex dest[len - 1] = 0; return false; } - if ((dest[i] = src[i]) == 0) + if ((dest[i] = src[i]) == 0) { return true; + } ++i; } } diff --git a/core/Utils.hpp b/core/Utils.hpp index 19a81a4c2..ece3292d1 100644 --- a/core/Utils.hpp +++ b/core/Utils.hpp @@ -60,12 +60,7 @@ namespace Utils { struct ARMCapabilities { ARMCapabilities() noexcept; - - bool aes; - bool crc32; - bool pmull; - bool sha1; - bool sha2; + bool aes, crc32, pmull, sha1, sha2; }; extern const ARMCapabilities ARMCAP; #endif @@ -74,16 +69,7 @@ extern const ARMCapabilities ARMCAP; struct CPUIDRegisters { CPUIDRegisters() noexcept; - - bool rdrand; - bool aes; - bool avx; - bool vaes; // implies AVX - bool vpclmulqdq; // implies AVX - bool avx2; - bool avx512f; - bool sha; - bool fsrm; + bool rdrand, aes, avx, vaes, vpclmulqdq, avx2, avx512f, sha, fsrm; }; extern const CPUIDRegisters CPUID; #endif diff --git a/rust-zerotier-core/src/address.rs b/rust-zerotier-core/src/address.rs index 2e7a99856..693d34da2 100644 --- a/rust-zerotier-core/src/address.rs +++ b/rust-zerotier-core/src/address.rs @@ -13,7 +13,7 @@ use std::cmp::Ordering; -#[derive(Copy)] +#[derive(PartialEq, Eq, Clone, Copy)] pub struct Address(pub u64); impl From<&[u8]> for Address { @@ -46,15 +46,6 @@ impl From<&str> for Address { } } -impl PartialEq for Address { - #[inline(always)] - fn eq(&self, other: &Self) -> bool { - self.0 == other.0 - } -} - -impl Eq for Address {} - impl Ord for Address { #[inline(always)] fn cmp(&self, other: &Self) -> Ordering { @@ -69,13 +60,6 @@ impl PartialOrd for Address { } } -impl Clone for Address { - #[inline(always)] - fn clone(&self) -> Self { - Address(self.0) - } -} - impl serde::Serialize for Address { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { serializer.serialize_str(self.to_string().as_str()) diff --git a/rust-zerotier-core/src/mac.rs b/rust-zerotier-core/src/mac.rs index f253886da..572c18933 100644 --- a/rust-zerotier-core/src/mac.rs +++ b/rust-zerotier-core/src/mac.rs @@ -13,7 +13,7 @@ use std::cmp::Ordering; -#[derive(Copy)] +#[derive(PartialEq, Eq, Clone, Copy)] pub struct MAC(pub u64); impl ToString for MAC { @@ -41,15 +41,6 @@ impl serde::Serialize for MAC { } } -impl PartialEq for MAC { - #[inline(always)] - fn eq(&self, other: &Self) -> bool { - self.0 == other.0 - } -} - -impl Eq for MAC {} - impl Ord for MAC { #[inline(always)] fn cmp(&self, other: &Self) -> Ordering { @@ -64,13 +55,6 @@ impl PartialOrd for MAC { } } -impl Clone for MAC { - #[inline(always)] - fn clone(&self) -> Self { - MAC(self.0) - } -} - struct AddressVisitor; impl<'de> serde::de::Visitor<'de> for AddressVisitor { diff --git a/rust-zerotier-core/src/networkid.rs b/rust-zerotier-core/src/networkid.rs index e5192b81b..e4379ea47 100644 --- a/rust-zerotier-core/src/networkid.rs +++ b/rust-zerotier-core/src/networkid.rs @@ -13,7 +13,7 @@ use std::cmp::Ordering; -#[derive(Copy)] +#[derive(PartialEq, Eq, Clone, Copy)] pub struct NetworkId(pub u64); impl NetworkId { @@ -57,22 +57,6 @@ impl PartialOrd for NetworkId { } } -impl PartialEq for NetworkId { - #[inline(always)] - fn eq(&self, other: &Self) -> bool { - self.0 == other.0 - } -} - -impl Clone for NetworkId { - #[inline(always)] - fn clone(&self) -> Self { - NetworkId(self.0) - } -} - -impl Eq for NetworkId {} - impl serde::Serialize for NetworkId { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { serializer.serialize_str(self.to_string().as_str()) diff --git a/rust-zerotier-service/Cargo.lock b/rust-zerotier-service/Cargo.lock index 206604253..9c61622bf 100644 --- a/rust-zerotier-service/Cargo.lock +++ b/rust-zerotier-service/Cargo.lock @@ -79,6 +79,40 @@ dependencies = [ "vec_map", ] +[[package]] +name = "console" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a50aab2529019abfabfa93f1e6c41ef392f91fbf179b347a7e96abb524884a08" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "regex", + "terminal_size", + "unicode-width", + "winapi", + "winapi-util", +] + +[[package]] +name = "dialoguer" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70f807b2943dc90f9747497d9d65d7e92472149be0b88bf4ce1201b4ac979c26" +dependencies = [ + "console", + "lazy_static", + "tempfile", + "zeroize", +] + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + [[package]] name = "fnv" version = "1.0.7" @@ -180,6 +214,17 @@ dependencies = [ "slab", ] +[[package]] +name = "getrandom" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi", +] + [[package]] name = "hermit-abi" version = "0.1.17" @@ -394,6 +439,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + [[package]] name = "proc-macro-hack" version = "0.5.19" @@ -424,6 +475,79 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" +dependencies = [ + "rand_core", +] + +[[package]] +name = "redox_syscall" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581" + +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + [[package]] name = "ryu" version = "1.0.5" @@ -504,6 +628,20 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "tempfile" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "rand", + "redox_syscall", + "remove_dir_all", + "winapi", +] + [[package]] name = "term_size" version = "0.3.2" @@ -514,6 +652,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "terminal_size" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86ca8ced750734db02076f44132d802af0b33b09942331f4459dde8636fd2406" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "textwrap" version = "0.11.0" @@ -621,6 +769,12 @@ dependencies = [ "try-lock", ] +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + [[package]] name = "winapi" version = "0.3.9" @@ -637,12 +791,27 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "zeroize" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45af6a010d13e4cf5b54c94ba5a2b2eba5596b9e46bf5875612d332a1f2b3f86" + [[package]] name = "zerotier-core" version = "0.1.0" @@ -660,6 +829,7 @@ version = "0.1.0" dependencies = [ "chrono", "clap", + "dialoguer", "futures", "hex", "hyper", diff --git a/rust-zerotier-service/Cargo.toml b/rust-zerotier-service/Cargo.toml index dfb466187..49db1ee9c 100644 --- a/rust-zerotier-service/Cargo.toml +++ b/rust-zerotier-service/Cargo.toml @@ -22,6 +22,7 @@ num-traits = "0" num-derive = "0" hyper = { version = "0", features = ["http1", "runtime", "server", "client", "tcp", "stream"] } socket2 = { version = "0", features = ["reuseport", "unix", "pair"] } +dialoguer = "0" [target."cfg(windows)".dependencies] winapi = { version = "0.3.9", features = ["handleapi", "ws2ipdef", "ws2tcpip"] }