mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-04-19 13:36:54 +02:00
Almost done refactoring for long form addresses, etc.
This commit is contained in:
parent
3f047bc8dc
commit
fcadb343a3
34 changed files with 409 additions and 994 deletions
258
debian/changelog
vendored
258
debian/changelog
vendored
|
@ -1,258 +0,0 @@
|
|||
zerotier-one (1.10.2) unstable; urgency=medium
|
||||
|
||||
* See RELEASE-NOTES.md for release notes.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Thu, 13 Oct 2022 01:00:00 -0700
|
||||
|
||||
zerotier-one (1.10.1) unstable; urgency=medium
|
||||
|
||||
* See RELEASE-NOTES.md for release notes.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Mon, 27 Jun 2022 01:00:00 -0700
|
||||
|
||||
zerotier-one (1.10.0) unstable; urgency=medium
|
||||
|
||||
* See RELEASE-NOTES.md for release notes.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Fri, 03 Jun 2022 01:00:00 -0700
|
||||
|
||||
zerotier-one (1.8.10) unstable; urgency=medium
|
||||
|
||||
* See RELEASE-NOTES.md for release notes.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Tue, 10 May 2022 01:00:00 -0700
|
||||
|
||||
zerotier-one (1.8.9) unstable; urgency=medium
|
||||
|
||||
* See RELEASE-NOTES.md for release notes.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Mon, 25 Apr 2022 01:00:00 -0700
|
||||
|
||||
zerotier-one (1.8.8) unstable; urgency=medium
|
||||
|
||||
* See RELEASE-NOTES.md for release notes.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Mon, 11 Apr 2022 01:00:00 -0700
|
||||
|
||||
zerotier-one (1.8.7) unstable; urgency=medium
|
||||
|
||||
* See RELEASE-NOTES.md for release notes.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Mon, 21 Mar 2022 01:00:00 -0700
|
||||
|
||||
zerotier-one (1.8.6) unstable; urgency=medium
|
||||
|
||||
* See RELEASE-NOTES.md for release notes.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Mon, 07 Mar 2022 01:00:00 -0700
|
||||
|
||||
zerotier-one (1.8.5) unstable; urgency=medium
|
||||
|
||||
* See RELEASE-NOTES.md for release notes.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Fri, 17 Dec 2021 01:00:00 -0700
|
||||
|
||||
zerotier-one (1.8.4) unstable; urgency=medium
|
||||
|
||||
* See RELEASE-NOTES.md for release notes.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Mon, 23 Nov 2021 01:00:00 -0700
|
||||
|
||||
zerotier-one (1.8.3) unstable; urgency=medium
|
||||
|
||||
* See RELEASE-NOTES.md for release notes.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Mon, 15 Nov 2021 01:00:00 -0700
|
||||
|
||||
zerotier-one (1.8.2) unstable; urgency=medium
|
||||
|
||||
* See RELEASE-NOTES.md for release notes.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Mon, 08 Nov 2021 01:00:00 -0700
|
||||
|
||||
zerotier-one (1.8.1) unstable; urgency=medium
|
||||
|
||||
* See RELEASE-NOTES.md for release notes.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Wed, 20 Oct 2021 01:00:00 -0700
|
||||
|
||||
zerotier-one (1.8.0) unstable; urgency=medium
|
||||
|
||||
* See RELEASE-NOTES.md for release notes.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Wed, 15 Sep 2021 01:00:00 -0700
|
||||
|
||||
zerotier-one (1.6.6) unstable; urgency=medium
|
||||
|
||||
* Backport endpoint mitigation against address collision attack.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Tue, 21 Sep 2021 01:00:00 -0700
|
||||
|
||||
zerotier-one (1.6.5) unstable; urgency=medium
|
||||
|
||||
* Fix path filtering bug that could cause "software laser" effect.
|
||||
* Fix printf overflow in CLI (not exploitable or security related)
|
||||
* Fix Windows device enumeration issue.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Tue, 13 Apr 2021 01:00:00 -0700
|
||||
|
||||
zerotier-one (1.6.4) unstable; urgency=medium
|
||||
|
||||
* REALLY fix a problem causing nodes to go into a "coma" with some network configurations.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Tue, 15 Feb 2021 01:00:00 -0700
|
||||
|
||||
zerotier-one (1.6.3-1) unstable; urgency=medium
|
||||
|
||||
* Fix a problem causing nodes to go into a "coma" with some network configurations.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Tue, 02 Feb 2021 01:00:00 -0700
|
||||
|
||||
zerotier-one (1.6.2-2) unstable; urgency=medium
|
||||
|
||||
* This is a minor update to the 1.6.2 package to address issues with
|
||||
running on ARMv6 CPUs like the Raspberry Pi Zero and original v1 Pi.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Tue, 31 Nov 2020 01:00:00 -0700
|
||||
|
||||
zerotier-one (1.6.2) unstable; urgency=medium
|
||||
|
||||
* See RELEASE-NOTES.md for release notes.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Mon, 30 Nov 2020 01:00:00 -0700
|
||||
|
||||
zerotier-one (1.6.1) unstable; urgency=medium
|
||||
|
||||
* See RELEASE-NOTES.md for release notes.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Tue, 24 Nov 2020 01:00:00 -0700
|
||||
|
||||
zerotier-one (1.6.0) unstable; urgency=medium
|
||||
|
||||
* See RELEASE-NOTES.md for release notes.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Thu, 19 Nov 2020 01:00:00 -0700
|
||||
|
||||
zerotier-one (1.5.0) unstable; urgency=medium
|
||||
|
||||
* Version 1.5.0 is actually 1.6.0-beta1
|
||||
* See RELEASE-NOTES.md for release notes.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Mon, 05 Aug 2020 01:00:00 -0700
|
||||
|
||||
zerotier-one (1.4.6) unstable; urgency=medium
|
||||
|
||||
* Update default root server list
|
||||
* Fix build flags on "armhf" (32-bit ARM) platforms for better
|
||||
compatibility with Pi Zero and other devices.
|
||||
* Fix license text in one.cpp.
|
||||
* Add a clarification to LICENSE.txt.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Fri, 30 Aug 2019 01:00:00 -0700
|
||||
|
||||
zerotier-one (1.4.4) unstable; urgency=medium
|
||||
|
||||
* See https://github.com/zerotier/ZeroTierOne for release notes.
|
||||
* License changed to BSL 1.1
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Fri, 23 Aug 2019 01:00:00 -0700
|
||||
|
||||
zerotier-one (1.4.2-2) unstable; urgency=medium
|
||||
|
||||
* See https://github.com/zerotier/ZeroTierOne for release notes.
|
||||
* This is a new build that fixes a binary build issue with containers and SELinux
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Thu, 04 Aug 2019 01:00:00 -0700
|
||||
|
||||
zerotier-one (1.4.2) unstable; urgency=medium
|
||||
|
||||
* See https://github.com/zerotier/ZeroTierOne for release notes.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Thu, 04 Aug 2019 01:00:00 -0700
|
||||
|
||||
zerotier-one (1.4.0) unstable; urgency=medium
|
||||
|
||||
* See https://github.com/zerotier/ZeroTierOne for release notes.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Thu, 29 Jul 2019 01:00:00 -0700
|
||||
|
||||
zerotier-one (1.2.12) unstable; urgency=medium
|
||||
|
||||
* See https://github.com/zerotier/ZeroTierOne for release notes.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Tue, 25 Jul 2018 01:00:00 -0700
|
||||
|
||||
zerotier-one (1.2.10) unstable; urgency=medium
|
||||
|
||||
* See https://github.com/zerotier/ZeroTierOne for release notes.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Tue, 08 May 2018 01:00:00 -0700
|
||||
|
||||
zerotier-one (1.2.8) unstable; urgency=medium
|
||||
|
||||
* See https://github.com/zerotier/ZeroTierOne for release notes.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Tue, 27 Apr 2018 01:00:00 -0700
|
||||
|
||||
zerotier-one (1.2.6) unstable; urgency=medium
|
||||
|
||||
* See https://github.com/zerotier/ZeroTierOne for release notes.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Tue, 17 Apr 2018 01:00:00 -0700
|
||||
|
||||
zerotier-one (1.2.4) unstable; urgency=medium
|
||||
|
||||
* See https://github.com/zerotier/ZeroTierOne for release notes.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Mon, 24 Mar 2017 01:00:00 -0700
|
||||
|
||||
zerotier-one (1.2.2) unstable; urgency=medium
|
||||
|
||||
* See https://github.com/zerotier/ZeroTierOne for release notes.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Fri, 17 Mar 2017 01:00:00 -0700
|
||||
|
||||
zerotier-one (1.2.0) unstable; urgency=medium
|
||||
|
||||
* See https://github.com/zerotier/ZeroTierOne for release notes.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Tue, 14 Mar 2017 09:08:00 -0700
|
||||
|
||||
zerotier-one (1.1.14) unstable; urgency=medium
|
||||
|
||||
* See https://github.com/zerotier/ZeroTierOne for release notes.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Tue, 21 Jul 2016 07:14:12 -0700
|
||||
|
||||
zerotier-one (1.1.12) unstable; urgency=medium
|
||||
|
||||
* See https://github.com/zerotier/ZeroTierOne for release notes.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Tue, 12 Jul 2016 03:02:22 -0700
|
||||
|
||||
zerotier-one (1.1.10) unstable; urgency=medium
|
||||
|
||||
* See https://github.com/zerotier/ZeroTierOne for release notes.
|
||||
* ZeroTier Debian packages no longer depend on http-parser since its ABI is too unstable.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Tue, 12 Jul 2016 12:29:00 -0700
|
||||
|
||||
zerotier-one (1.1.8) unstable; urgency=low
|
||||
|
||||
* See https://github.com/zerotier/ZeroTierOne for release notes.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Fri, 08 Jul 2016 01:56:00 -0700
|
||||
|
||||
zerotier-one (1.1.6) unstable; urgency=medium
|
||||
|
||||
* First Debian release on ZeroTier, Inc. private apt repository.
|
||||
|
||||
* See https://github.com/zerotier/ZeroTierOne for release notes.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Fri, 24 Jun 2016 10:00:00 -0700
|
||||
|
||||
zerotier-one (1.1.5) UNRELEASED; urgency=medium
|
||||
|
||||
* Development package -- first clean Debian packaging test.
|
||||
|
||||
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Wed, 08 Jun 2016 10:05:01 -0700
|
1
debian/compat
vendored
1
debian/compat
vendored
|
@ -1 +0,0 @@
|
|||
8
|
19
debian/control
vendored
19
debian/control
vendored
|
@ -1,19 +0,0 @@
|
|||
Source: zerotier-one
|
||||
Maintainer: Adam Ierymenko <adam.ierymenko@zerotier.com>
|
||||
Section: net
|
||||
Priority: optional
|
||||
Standards-Version: 3.9.6
|
||||
Build-Depends: debhelper (>= 9)
|
||||
Vcs-Git: git://github.com/zerotier/ZeroTierOne
|
||||
Vcs-Browser: https://github.com/zerotier/ZeroTierOne
|
||||
Homepage: https://www.zerotier.com/
|
||||
|
||||
Package: zerotier-one
|
||||
Architecture: any
|
||||
Depends: iproute2, adduser, libstdc++6 (>= 5), openssl
|
||||
Homepage: https://www.zerotier.com/
|
||||
Description: ZeroTier network virtualization service
|
||||
ZeroTier One lets you join ZeroTier virtual networks and
|
||||
have them appear as tun/tap ports on your system. See
|
||||
https://www.zerotier.com/ for instructions and
|
||||
documentation.
|
19
debian/control.wheezy
vendored
19
debian/control.wheezy
vendored
|
@ -1,19 +0,0 @@
|
|||
Source: zerotier-one
|
||||
Maintainer: Adam Ierymenko <adam.ierymenko@zerotier.com>
|
||||
Section: net
|
||||
Priority: optional
|
||||
Standards-Version: 3.9.4
|
||||
Build-Depends: debhelper
|
||||
Vcs-Git: git://github.com/zerotier/ZeroTierOne
|
||||
Vcs-Browser: https://github.com/zerotier/ZeroTierOne
|
||||
Homepage: https://www.zerotier.com/
|
||||
|
||||
Package: zerotier-one
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}, iproute, libstdc++6
|
||||
Homepage: https://www.zerotier.com/
|
||||
Description: ZeroTier network virtualization service
|
||||
ZeroTier One lets you join ZeroTier virtual networks and
|
||||
have them appear as tun/tap ports on your system. See
|
||||
https://www.zerotier.com/ for instructions and
|
||||
documentation.
|
18
debian/copyright
vendored
18
debian/copyright
vendored
|
@ -1,18 +0,0 @@
|
|||
Format: http://dep.debian.net/deps/dep5
|
||||
Upstream-Name: zerotier-one
|
||||
Source: https://github.com/zerotier/ZeroTierOne
|
||||
|
||||
Files: *
|
||||
Copyright: 2011-2016 ZeroTier, Inc.
|
||||
License: ZeroTier BSL 1.1
|
||||
|
||||
License: ZeroTier BSL 1.1
|
||||
Copyright (c)2019 ZeroTier, Inc.
|
||||
|
||||
Use of this software is governed by the Business Source License included
|
||||
in the LICENSE.TXT file in the project's root directory.
|
||||
|
||||
Change Date: 2025-01-01
|
||||
|
||||
On the date above, in accordance with the Business Source License, use
|
||||
of this software will be governed by version 2.0 of the Apache License.
|
11
debian/postinst
vendored
11
debian/postinst
vendored
|
@ -1,11 +0,0 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
case "$1" in
|
||||
configure)
|
||||
if ! id zerotier-one >>/dev/null 2>&1; then
|
||||
useradd --system --user-group --home-dir /var/lib/zerotier-one --shell /usr/sbin/nologin --no-create-home zerotier-one
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
#DEBHELPER#
|
16
debian/rules
vendored
16
debian/rules
vendored
|
@ -1,16 +0,0 @@
|
|||
#!/usr/bin/make -f
|
||||
|
||||
CFLAGS=-O3 -fstack-protector-strong
|
||||
CXXFLAGS=-O3 -fstack-protector-strong
|
||||
|
||||
%:
|
||||
dh $@ --with systemd
|
||||
|
||||
override_dh_auto_build:
|
||||
make
|
||||
|
||||
override_dh_systemd_start:
|
||||
dh_systemd_start --restart-after-upgrade
|
||||
|
||||
override_dh_installinit:
|
||||
dh_installinit --name=zerotier-one -- defaults
|
16
debian/rules.static
vendored
16
debian/rules.static
vendored
|
@ -1,16 +0,0 @@
|
|||
#!/usr/bin/make -f
|
||||
|
||||
CFLAGS=-O3 -fstack-protector-strong
|
||||
CXXFLAGS=-O3 -fstack-protector-strong
|
||||
|
||||
%:
|
||||
dh $@ --with systemd
|
||||
|
||||
override_dh_auto_build:
|
||||
# make -j 2
|
||||
|
||||
override_dh_systemd_start:
|
||||
dh_systemd_start --restart-after-upgrade
|
||||
|
||||
override_dh_installinit:
|
||||
dh_installinit --name=zerotier-one -- defaults
|
11
debian/rules.wheezy
vendored
11
debian/rules.wheezy
vendored
|
@ -1,11 +0,0 @@
|
|||
#!/usr/bin/make -f
|
||||
|
||||
CFLAGS=-O3 -fstack-protector
|
||||
CXXFLAGS=-O3 -fstack-protector
|
||||
|
||||
%:
|
||||
dh $@
|
||||
|
||||
override_dh_auto_build:
|
||||
make -j 2
|
||||
|
11
debian/rules.wheezy.static
vendored
11
debian/rules.wheezy.static
vendored
|
@ -1,11 +0,0 @@
|
|||
#!/usr/bin/make -f
|
||||
|
||||
CFLAGS=-O3 -fstack-protector
|
||||
CXXFLAGS=-O3 -fstack-protector
|
||||
|
||||
%:
|
||||
dh $@
|
||||
|
||||
override_dh_auto_build:
|
||||
# make -j 2
|
||||
|
1
debian/source/format
vendored
1
debian/source/format
vendored
|
@ -1 +0,0 @@
|
|||
3.0 (quilt)
|
4
debian/ufw-zerotier-one
vendored
4
debian/ufw-zerotier-one
vendored
|
@ -1,4 +0,0 @@
|
|||
[zerotier-one]
|
||||
title=ZeroTier One
|
||||
description=A planetary Ethernet switch
|
||||
ports=9993/udp
|
49
debian/zerotier-one.init
vendored
49
debian/zerotier-one.init
vendored
|
@ -1,49 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
### BEGIN INIT INFO
|
||||
# Provides: zerotier-one
|
||||
# Required-Start: $remote_fs $syslog
|
||||
# Required-Stop: $remote_fs $syslog
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop:
|
||||
# Short-Description: ZeroTier One network virtualization service
|
||||
### END INIT INFO
|
||||
|
||||
PATH=/bin:/usr/bin:/sbin:/usr/sbin
|
||||
DESC="zerotier-one daemon"
|
||||
NAME=zerotier-one
|
||||
DAEMON=/usr/sbin/zerotier-one
|
||||
PIDFILE=/var/lib/zerotier-one/zerotier-one.pid
|
||||
SCRIPTNAME=/etc/init.d/"$NAME"
|
||||
EXTRA_OPTS=-d
|
||||
|
||||
test -f $DAEMON || exit 0
|
||||
|
||||
. /lib/lsb/init-functions
|
||||
|
||||
case "$1" in
|
||||
start) log_daemon_msg "Starting ZeroTier One" "zerotier-one"
|
||||
start_daemon -p $PIDFILE $DAEMON $EXTRA_OPTS
|
||||
log_end_msg $?
|
||||
;;
|
||||
stop) log_daemon_msg "Stopping ZeroTier One" "zerotier-one"
|
||||
killproc -p $PIDFILE $DAEMON
|
||||
RETVAL=$?
|
||||
[ $RETVAL -eq 0 ] && [ -e "$PIDFILE" ] && rm -f $PIDFILE
|
||||
log_end_msg $RETVAL
|
||||
;;
|
||||
restart) log_daemon_msg "Restarting ZeroTier One" "zerotier-one"
|
||||
$0 stop
|
||||
$0 start
|
||||
;;
|
||||
reload|force-reload) log_daemon_msg "Reloading ZeroTier One" "zerotier-one"
|
||||
log_end_msg 0
|
||||
;;
|
||||
status)
|
||||
status_of_proc -p $PIDFILE $DAEMON $NAME && exit 0 || exit $?
|
||||
;;
|
||||
*) log_action_msg "Usage: /etc/init.d/cron {start|stop|status|restart|reload|force-reload}"
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
exit 0
|
12
debian/zerotier-one.service
vendored
12
debian/zerotier-one.service
vendored
|
@ -1,12 +0,0 @@
|
|||
[Unit]
|
||||
Description=ZeroTier One
|
||||
After=network-online.target network.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/sbin/zerotier-one
|
||||
Restart=always
|
||||
KillMode=process
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
14
debian/zerotier-one.upstart
vendored
14
debian/zerotier-one.upstart
vendored
|
@ -1,14 +0,0 @@
|
|||
description "ZeroTier One upstart startup script"
|
||||
|
||||
author "Adam Ierymenko <adam.ierymenko@zerotier.com>"
|
||||
|
||||
start on (local-filesystems and net-device-up IFACE!=lo)
|
||||
stop on runlevel [!2345]
|
||||
|
||||
respawn
|
||||
respawn limit 2 300
|
||||
|
||||
#pre-start script
|
||||
#end script
|
||||
|
||||
exec /usr/sbin/zerotier-one
|
|
@ -306,8 +306,8 @@ pub mod v1 {
|
|||
#[inline(always)]
|
||||
pub fn get_packet_aad_bytes(destination: &Address, source: &Address, flags_cipher_hops: u8) -> [u8; 11] {
|
||||
let mut id = [0u8; 11];
|
||||
id[0..5].copy_from_slice(destination.as_bytes_v1());
|
||||
id[5..10].copy_from_slice(source.as_bytes_v1());
|
||||
id[0..5].copy_from_slice(destination.legacy_address().as_bytes());
|
||||
id[5..10].copy_from_slice(source.legacy_address().as_bytes());
|
||||
id[10] = flags_cipher_hops & FLAGS_FIELD_MASK_HIDE_HOPS;
|
||||
id
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// (c) 2020-2022 ZeroTier, Inc. -- currently proprietary pending actual release and licensing. See LICENSE.md.
|
||||
|
||||
use std::fmt::Debug;
|
||||
use std::hash::Hash;
|
||||
use std::num::NonZeroU64;
|
||||
use std::str::FromStr;
|
||||
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
@ -12,16 +14,15 @@ use zerotier_utils::memory;
|
|||
const BASE62_ALPHABET: &'static [u8; 62] = b"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
const BASE62_ALPHABET_REVERSE: [u8; 256] = [0; 256];
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
#[repr(transparent)]
|
||||
pub struct Address([u128; 3]);
|
||||
|
||||
impl Address {
|
||||
pub const V1_ADDRESS_SIZE: usize = 5;
|
||||
pub const V1_ADDRESS_STRING_SIZE: usize = 10;
|
||||
pub const V2_ADDRESS_SIZE: usize = 48;
|
||||
pub const V2_ADDRESS_STRING_SIZE: usize = 65;
|
||||
/// Size of a full length address in bytes.
|
||||
pub const SIZE_BYTES: usize = 48;
|
||||
|
||||
/// Addresses may not begin with 0xff; reserved for special signaling or future use.
|
||||
pub const RESERVED_PREFIX: u8 = 0xff;
|
||||
|
||||
#[inline(always)]
|
||||
|
@ -29,102 +30,50 @@ impl Address {
|
|||
Self([0, 0, 0])
|
||||
}
|
||||
|
||||
pub fn from_bytes(b: &[u8]) -> Result<Option<Self>, InvalidFormatError> {
|
||||
if b.len() == Self::V1_ADDRESS_SIZE {
|
||||
Ok(Self::from_bytes_v1(b))
|
||||
} else if b.len() == Self::V2_ADDRESS_SIZE {
|
||||
Ok(Self::from_bytes_v2(b))
|
||||
#[inline(always)]
|
||||
pub(crate) fn as_bytes_mut(&mut self) -> &mut [u8; 48] {
|
||||
memory::as_byte_array_mut(&mut self.0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn from_bytes(b: &[u8]) -> Result<Self, InvalidFormatError> {
|
||||
if b.len() >= Self::SIZE_BYTES {
|
||||
let a = Self(memory::load_raw(b));
|
||||
if b[0] != Self::RESERVED_PREFIX && memory::load_raw::<u64>(b) != 0 {
|
||||
Ok(a)
|
||||
} else {
|
||||
Err(InvalidFormatError)
|
||||
}
|
||||
} else {
|
||||
Err(InvalidFormatError)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn from_bytes_v1(b: &[u8]) -> Option<Self> {
|
||||
let mut a = Self([0; 3]);
|
||||
memory::as_byte_array_mut::<[u128; 3], 48>(&mut a.0)[..Self::V1_ADDRESS_SIZE].copy_from_slice(b);
|
||||
if a.0[0] != 0 {
|
||||
Some(a)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn from_bytes_v2(b: &[u8]) -> Option<Self> {
|
||||
#[inline(always)]
|
||||
pub fn from_bytes_exact(b: &[u8; Self::SIZE_BYTES]) -> Result<Self, InvalidFormatError> {
|
||||
let a = Self(memory::load_raw(b));
|
||||
if a.0.iter().any(|i| *i != 0) {
|
||||
Some(a)
|
||||
if b[0] != Self::RESERVED_PREFIX && memory::load_raw::<u64>(b) != 0 {
|
||||
Ok(a)
|
||||
} else {
|
||||
None
|
||||
Err(InvalidFormatError)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn from_bytes_raw(b: &[u8; 48]) -> Option<Self> {
|
||||
Self::from_bytes_v2(b)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn from_u64_v1(i: u64) -> Option<Self> {
|
||||
if i != 0 {
|
||||
Some(Self([i.wrapping_shl(24 + 64).to_be() as u128, 0, 0]))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// True if this address lacks extended hash information.
|
||||
#[inline(always)]
|
||||
pub fn is_v1_only(&self) -> bool {
|
||||
self.0[1] == 0 && self.0[2] == 0
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn as_bytes_raw(&self) -> &[u8; 48] {
|
||||
memory::as_byte_array::<[u128; 3], 48>(&self.0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn as_bytes_raw_mut(&mut self) -> &mut [u8; 48] {
|
||||
memory::as_byte_array_mut::<[u128; 3], 48>(&mut self.0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn as_u64_v1(&self) -> u64 {
|
||||
u128::from_be(self.0[0]).wrapping_shr(24 + 64) as u64
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn as_bytes_v1(&self) -> &[u8; Self::V1_ADDRESS_SIZE] {
|
||||
memory::array_range::<u8, 48, 0, 5>(memory::as_byte_array::<[u128; 3], 48>(&self.0))
|
||||
pub fn legacy_address(&self) -> LegacyAddress {
|
||||
LegacyAddress(NonZeroU64::new(memory::load_raw::<u64>(self.as_bytes())).unwrap())
|
||||
}
|
||||
|
||||
/// Get all bits in this address (last 344 will be zero if this is only a V1 address).
|
||||
#[inline(always)]
|
||||
pub fn as_bytes_full(&self) -> &[u8; Self::V2_ADDRESS_SIZE] {
|
||||
memory::as_byte_array::<[u128; 3], 48>(&self.0)
|
||||
}
|
||||
|
||||
/// Get a byte serialized address.
|
||||
/// This returns either a 40-bit short address or a full 384 bits depending on whether this
|
||||
/// contains only a short V1 address or a full length V2 address. Use as_bytes_full() to
|
||||
/// always get all 384 bits with the last 344 being zero for V1-only addresses.
|
||||
pub fn as_bytes(&self) -> &[u8] {
|
||||
if self.is_v1_only() {
|
||||
&memory::as_byte_array::<[u128; 3], 48>(&self.0)[..Self::V1_ADDRESS_SIZE]
|
||||
} else {
|
||||
memory::as_byte_array::<[u128; 3], 48>(&self.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the short 10-digit address string for this address.
|
||||
pub fn to_short_string(&self) -> String {
|
||||
hex::to_string(&memory::as_byte_array::<[u128; 3], 48>(&self.0)[..Self::V1_ADDRESS_SIZE])
|
||||
pub fn as_bytes(&self) -> &[u8; Self::SIZE_BYTES] {
|
||||
memory::as_byte_array(&self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for Address {
|
||||
fn to_string(&self) -> String {
|
||||
let mut s = String::with_capacity(Self::V2_ADDRESS_STRING_SIZE);
|
||||
let mut s = String::with_capacity(66);
|
||||
let mut remainders = 0u16;
|
||||
for qq in self.0.iter() {
|
||||
let mut q = u128::from_be(*qq);
|
||||
|
@ -148,43 +97,38 @@ impl FromStr for Address {
|
|||
type Err = InvalidFormatError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
if s.len() == Self::V1_ADDRESS_STRING_SIZE {
|
||||
return Ok(Self::from_bytes_v1(hex::from_string(s).as_slice()).ok_or(InvalidFormatError)?);
|
||||
} else if s.len() == Self::V2_ADDRESS_STRING_SIZE {
|
||||
let mut s = s.as_bytes();
|
||||
let mut a = Self([0, 0, 0]);
|
||||
for qi in 0..3 {
|
||||
let mut q = 0u128;
|
||||
for _ in 0..21 {
|
||||
let r = BASE62_ALPHABET_REVERSE[s[0] as usize];
|
||||
if r == 255 {
|
||||
return Err(InvalidFormatError);
|
||||
}
|
||||
q += r as u128;
|
||||
s = &s[1..];
|
||||
q *= 62;
|
||||
}
|
||||
a.0[qi] = q;
|
||||
}
|
||||
let mut remainders = 0u16;
|
||||
for _ in 0..2 {
|
||||
let mut s = s.as_bytes();
|
||||
let mut a = Self([0, 0, 0]);
|
||||
for qi in 0..3 {
|
||||
let mut q = 0u128;
|
||||
for _ in 0..21 {
|
||||
let r = BASE62_ALPHABET_REVERSE[s[0] as usize];
|
||||
s = &s[1..];
|
||||
if r == 255 {
|
||||
return Err(InvalidFormatError);
|
||||
}
|
||||
remainders += r as u16;
|
||||
s = &s[1..];
|
||||
remainders *= 62;
|
||||
q *= 62;
|
||||
q += r as u128;
|
||||
}
|
||||
if remainders > 511 {
|
||||
a.0[qi] = q;
|
||||
}
|
||||
let mut remainders = 0u16;
|
||||
for _ in 0..2 {
|
||||
let r = BASE62_ALPHABET_REVERSE[s[0] as usize];
|
||||
s = &s[1..];
|
||||
if r == 255 {
|
||||
return Err(InvalidFormatError);
|
||||
}
|
||||
a.0[0] += (remainders.wrapping_shr(6) & 7) as u128;
|
||||
a.0[1] += (remainders.wrapping_shr(3) & 7) as u128;
|
||||
a.0[2] += (remainders & 7) as u128;
|
||||
return Ok(a);
|
||||
remainders *= 62;
|
||||
remainders += r as u16;
|
||||
}
|
||||
return Err(InvalidFormatError);
|
||||
if remainders > 511 {
|
||||
return Err(InvalidFormatError);
|
||||
}
|
||||
a.0[0] += (remainders.wrapping_shr(6) & 7) as u128;
|
||||
a.0[1] += (remainders.wrapping_shr(3) & 7) as u128;
|
||||
a.0[2] += (remainders & 7) as u128;
|
||||
return Ok(a);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -196,6 +140,7 @@ impl PartialOrd for Address {
|
|||
}
|
||||
|
||||
impl Ord for Address {
|
||||
#[inline]
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
u128::from_be(self.0[0])
|
||||
.cmp(&u128::from_be(other.0[0]))
|
||||
|
@ -205,12 +150,21 @@ impl Ord for Address {
|
|||
}
|
||||
|
||||
impl Debug for Address {
|
||||
#[inline]
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_str(self.to_string().as_str())
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for Address {
|
||||
#[inline(always)]
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
state.write_u128(self.0[0])
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for Address {
|
||||
#[inline]
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
|
@ -228,15 +182,17 @@ struct AddressVisitor;
|
|||
impl<'de> serde::de::Visitor<'de> for AddressVisitor {
|
||||
type Value = Address;
|
||||
|
||||
#[inline]
|
||||
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
formatter.write_str("a ZeroTier address")
|
||||
formatter.write_str("address")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
if let Ok(Some(v)) = Address::from_bytes(v) {
|
||||
if let Ok(v) = Address::from_bytes(v) {
|
||||
Ok(v)
|
||||
} else {
|
||||
Err(E::custom("invalid address"))
|
||||
|
@ -252,6 +208,7 @@ impl<'de> serde::de::Visitor<'de> for AddressVisitor {
|
|||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for Address {
|
||||
#[inline]
|
||||
fn deserialize<D>(deserializer: D) -> Result<Address, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
|
@ -263,3 +220,133 @@ impl<'de> Deserialize<'de> for Address {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[repr(transparent)]
|
||||
pub struct LegacyAddress(NonZeroU64);
|
||||
|
||||
impl LegacyAddress {
|
||||
pub const SIZE_BYTES: usize = 5;
|
||||
pub const SIZE_HEX_STRING: usize = 10;
|
||||
|
||||
#[inline(always)]
|
||||
pub fn from_bytes(b: &[u8]) -> Option<Self> {
|
||||
if b.len() >= Self::SIZE_BYTES && b[0] != Address::RESERVED_PREFIX {
|
||||
let mut tmp = 0u64.to_ne_bytes();
|
||||
tmp[..Address::SIZE_BYTES].copy_from_slice(b);
|
||||
NonZeroU64::new(u64::from_ne_bytes(tmp)).map(|i| Self(i))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn from_bytes_exact(b: &[u8; Self::SIZE_BYTES]) -> Option<Self> {
|
||||
if b[0] != Address::RESERVED_PREFIX {
|
||||
let mut tmp = 0u64.to_ne_bytes();
|
||||
tmp[..Address::SIZE_BYTES].copy_from_slice(b);
|
||||
NonZeroU64::new(u64::from_ne_bytes(tmp)).map(|i| Self(i))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn from_u64(i: u64) -> Option<Self> {
|
||||
NonZeroU64::new(i.wrapping_shl(24).to_be()).map(|i| Self(i))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn to_u64(&self) -> u64 {
|
||||
u64::from_be(self.0.get()).wrapping_shr(24)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_bytes(&self) -> &[u8; Self::SIZE_BYTES] {
|
||||
debug_assert_eq!(std::mem::size_of::<NonZeroU64>(), 8);
|
||||
memory::array_range::<u8, 8, 0, 5>(memory::as_byte_array::<NonZeroU64, 8>(&self.0))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for LegacyAddress {
|
||||
fn to_string(&self) -> String {
|
||||
hex::to_string(&memory::as_byte_array::<NonZeroU64, 8>(&self.0)[..Self::SIZE_BYTES])
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for LegacyAddress {
|
||||
type Err = InvalidFormatError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
if s.len() == Self::SIZE_HEX_STRING {
|
||||
Self::from_bytes(hex::from_string(s).as_slice()).ok_or(InvalidFormatError)
|
||||
} else {
|
||||
Err(InvalidFormatError)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for LegacyAddress {
|
||||
#[inline]
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_str(self.to_string().as_str())
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for LegacyAddress {
|
||||
#[inline]
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
if serializer.is_human_readable() {
|
||||
serializer.serialize_str(self.to_string().as_str())
|
||||
} else {
|
||||
serializer.serialize_bytes(self.as_bytes())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct LegacyAddressVisitor;
|
||||
|
||||
impl<'de> serde::de::Visitor<'de> for LegacyAddressVisitor {
|
||||
type Value = LegacyAddress;
|
||||
|
||||
#[inline]
|
||||
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
formatter.write_str("address")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
if let Some(v) = LegacyAddress::from_bytes(v) {
|
||||
Ok(v)
|
||||
} else {
|
||||
Err(E::custom("invalid address"))
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
LegacyAddress::from_str(v).map_err(|e| E::custom(e.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for LegacyAddress {
|
||||
#[inline]
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
if deserializer.is_human_readable() {
|
||||
deserializer.deserialize_str(LegacyAddressVisitor)
|
||||
} else {
|
||||
deserializer.deserialize_bytes(LegacyAddressVisitor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -140,7 +140,7 @@ impl Marshalable for Endpoint {
|
|||
}
|
||||
Endpoint::ZeroTier(a) => {
|
||||
buf.append_u8(16 + TYPE_ZEROTIER)?;
|
||||
buf.append_bytes_fixed(a.as_bytes_raw())?;
|
||||
buf.append_bytes_fixed(a.as_bytes())?;
|
||||
}
|
||||
Endpoint::Ethernet(m) => {
|
||||
buf.append_u8(16 + TYPE_ETHERNET)?;
|
||||
|
@ -184,7 +184,7 @@ impl Marshalable for Endpoint {
|
|||
}
|
||||
Endpoint::ZeroTierEncap(a) => {
|
||||
buf.append_u8(16 + TYPE_ZEROTIER_ENCAP)?;
|
||||
buf.append_bytes_fixed(a.as_bytes_raw())?;
|
||||
buf.append_bytes_fixed(a.as_bytes())?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
@ -212,7 +212,7 @@ impl Marshalable for Endpoint {
|
|||
match type_byte - 16 {
|
||||
TYPE_NIL => Ok(Endpoint::Nil),
|
||||
TYPE_ZEROTIER => Ok(Endpoint::ZeroTier(
|
||||
Address::from_bytes_raw(buf.read_bytes_fixed(cursor)?).ok_or(UnmarshalError::InvalidData)?,
|
||||
Address::from_bytes(buf.read_bytes_fixed::<{ Address::SIZE_BYTES }>(cursor)?).map_err(|_| UnmarshalError::InvalidData)?,
|
||||
)),
|
||||
TYPE_ETHERNET => Ok(Endpoint::Ethernet(MAC::unmarshal(buf, cursor)?)),
|
||||
TYPE_WIFIDIRECT => Ok(Endpoint::WifiDirect(MAC::unmarshal(buf, cursor)?)),
|
||||
|
@ -225,7 +225,7 @@ impl Marshalable for Endpoint {
|
|||
)),
|
||||
TYPE_WEBRTC => Ok(Endpoint::WebRTC(buf.read_bytes(buf.read_varint(cursor)? as usize, cursor)?.to_vec())),
|
||||
TYPE_ZEROTIER_ENCAP => Ok(Endpoint::ZeroTier(
|
||||
Address::from_bytes_raw(buf.read_bytes_fixed(cursor)?).ok_or(UnmarshalError::InvalidData)?,
|
||||
Address::from_bytes(buf.read_bytes_fixed::<{ Address::SIZE_BYTES }>(cursor)?).map_err(|_| UnmarshalError::InvalidData)?,
|
||||
)),
|
||||
_ => Err(UnmarshalError::InvalidData),
|
||||
}
|
||||
|
|
|
@ -5,9 +5,9 @@ use std::str::FromStr;
|
|||
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
use super::Address;
|
||||
use super::{Address, LegacyAddress};
|
||||
|
||||
use zerotier_crypto::hash::{SHA384, SHA384_HASH_SIZE, SHA512};
|
||||
use zerotier_crypto::hash::{SHA384, SHA512};
|
||||
use zerotier_crypto::p384::*;
|
||||
use zerotier_crypto::salsa::Salsa;
|
||||
use zerotier_crypto::secret::Secret;
|
||||
|
@ -40,16 +40,20 @@ pub struct P384 {
|
|||
pub p384_self_signature: [u8; P384_ECDSA_SIGNATURE_SIZE],
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct IdentitySecret {
|
||||
pub public: Valid<Identity>,
|
||||
pub x25519: X25519Secret,
|
||||
pub p384: Option<P384Secret>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct X25519Secret {
|
||||
pub ecdh: X25519KeyPair,
|
||||
pub eddsa: Ed25519KeyPair,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct P384Secret {
|
||||
pub ecdh: P384KeyPair,
|
||||
pub ecdsa: P384KeyPair,
|
||||
|
@ -65,37 +69,35 @@ impl Identity {
|
|||
|
||||
/// Generate a new ZeroTier identity.
|
||||
/// If x25519_only is true a legacy identity without NIST P-384 key pairs will be generated.
|
||||
pub fn generate(x25519_only: bool) -> (Identity, IdentitySecret) {
|
||||
pub fn generate(x25519_only: bool) -> IdentitySecret {
|
||||
// Generate X25519 portions of the identity plus the first 40 bits of the address, which are
|
||||
// the legacy "short" address.
|
||||
let x25519_ecdh = X25519KeyPair::generate();
|
||||
let ed25519_eddsa = Ed25519KeyPair::generate();
|
||||
let x25519_ecdh_public = x25519_ecdh.public_bytes();
|
||||
let ed25519_eddsa_public = ed25519_eddsa.public_bytes();
|
||||
let mut secret = IdentitySecret {
|
||||
x25519: X25519Secret {
|
||||
ecdh: X25519KeyPair::generate(),
|
||||
eddsa: Ed25519KeyPair::generate(),
|
||||
},
|
||||
p384: None,
|
||||
};
|
||||
let mut public = Identity {
|
||||
address: Address::new_uninitialized(),
|
||||
x25519: X25519 {
|
||||
ecdh: secret.x25519.ecdh.public_bytes(),
|
||||
eddsa: secret.x25519.eddsa.public_bytes(),
|
||||
},
|
||||
public: Valid::mark_valid(Identity {
|
||||
address: Address::new_uninitialized(),
|
||||
x25519: X25519 { ecdh: x25519_ecdh_public, eddsa: ed25519_eddsa_public },
|
||||
p384: None,
|
||||
}),
|
||||
x25519: X25519Secret { ecdh: x25519_ecdh, eddsa: ed25519_eddsa },
|
||||
p384: None,
|
||||
};
|
||||
loop {
|
||||
let mut legacy_address_derivation_hash = SHA512::new();
|
||||
legacy_address_derivation_hash.update(&public.x25519.ecdh);
|
||||
legacy_address_derivation_hash.update(&public.x25519.eddsa);
|
||||
legacy_address_derivation_hash.update(&secret.public.x25519.ecdh);
|
||||
legacy_address_derivation_hash.update(&secret.public.x25519.eddsa);
|
||||
let mut legacy_address_derivation_hash = legacy_address_derivation_hash.finish();
|
||||
legacy_address_derivation_work_function(&mut legacy_address_derivation_hash);
|
||||
if legacy_address_derivation_hash[0] < Self::V0_IDENTITY_POW_THRESHOLD && legacy_address_derivation_hash[59] != Address::RESERVED_PREFIX {
|
||||
public.address.as_bytes_raw_mut()[..5].copy_from_slice(&legacy_address_derivation_hash[59..64]);
|
||||
secret.public.address.as_bytes_mut()[..5].copy_from_slice(&legacy_address_derivation_hash[59..64]);
|
||||
break;
|
||||
} else {
|
||||
// Regenerate one of the two keys until we meet the legacy address work function criteria.
|
||||
secret.x25519.ecdh = X25519KeyPair::generate();
|
||||
public.x25519.ecdh = secret.x25519.ecdh.public_bytes();
|
||||
secret.public.x25519.ecdh = secret.x25519.ecdh.public_bytes();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,7 +107,7 @@ impl Identity {
|
|||
ecdh: P384KeyPair::generate(),
|
||||
ecdsa: P384KeyPair::generate(),
|
||||
});
|
||||
public.p384 = secret.p384.as_ref().map(|p384s| P384 {
|
||||
secret.public.p384 = secret.p384.as_ref().map(|p384s| P384 {
|
||||
ecdh: p384s.ecdh.public_key().clone(),
|
||||
ecdsa: p384s.ecdsa.public_key().clone(),
|
||||
ed25519_self_signature: [0u8; ED25519_SIGNATURE_SIZE],
|
||||
|
@ -114,20 +116,20 @@ impl Identity {
|
|||
}
|
||||
|
||||
// Bits 40-384 of the address are filled from a SHA384 hash of all keys for a full length V2 address.
|
||||
public.populate_extended_address_bits();
|
||||
secret.public.populate_extended_address_bits();
|
||||
|
||||
// For V2 identities we include two self signatures to ensure that all these different key pairs
|
||||
// are properly bound together and can't be changed independently.
|
||||
if !x25519_only {
|
||||
let mut for_self_signing =
|
||||
[0u8; Address::V2_ADDRESS_SIZE + 1 + C25519_PUBLIC_KEY_SIZE + ED25519_PUBLIC_KEY_SIZE + P384_PUBLIC_KEY_SIZE + P384_PUBLIC_KEY_SIZE];
|
||||
public.encode_for_self_signing(&mut for_self_signing);
|
||||
let p384 = public.p384.as_mut().unwrap();
|
||||
[0u8; Address::SIZE_BYTES + 1 + C25519_PUBLIC_KEY_SIZE + ED25519_PUBLIC_KEY_SIZE + P384_PUBLIC_KEY_SIZE + P384_PUBLIC_KEY_SIZE];
|
||||
secret.public.encode_for_self_signing(&mut for_self_signing);
|
||||
let p384 = secret.public.p384.as_mut().unwrap();
|
||||
p384.ed25519_self_signature = secret.x25519.eddsa.sign(&for_self_signing);
|
||||
p384.p384_self_signature = secret.p384.as_ref().unwrap().ecdsa.sign(&for_self_signing);
|
||||
}
|
||||
|
||||
(public, secret)
|
||||
secret
|
||||
}
|
||||
|
||||
/// Locally validate this identity.
|
||||
|
@ -145,10 +147,10 @@ impl Identity {
|
|||
}
|
||||
}
|
||||
|
||||
/// Hash all keys for generation of bits 40-384 of the address.
|
||||
/// Populate bits 40-384 of the address with a hash of everything else.
|
||||
fn populate_extended_address_bits(&mut self) {
|
||||
let mut sha = SHA384::new();
|
||||
sha.update(self.address.as_bytes_v1()); // including the short address means we can elide the expensive legacy hash in the future
|
||||
sha.update(self.address.legacy_address().as_bytes()); // including the short address means we can elide the expensive legacy hash in the future
|
||||
sha.update(&[Self::ALGORITHM_X25519
|
||||
| if self.p384.is_some() {
|
||||
Self::ALGORITHM_P384
|
||||
|
@ -162,16 +164,16 @@ impl Identity {
|
|||
sha.update(p384.ecdsa.as_bytes());
|
||||
}
|
||||
let sha = sha.finish();
|
||||
self.address.as_bytes_raw_mut()[5..].copy_from_slice(&sha[..48 - 5]);
|
||||
self.address.as_bytes_mut()[LegacyAddress::SIZE_BYTES..].copy_from_slice(&sha[..Address::SIZE_BYTES - LegacyAddress::SIZE_BYTES]);
|
||||
}
|
||||
|
||||
/// Encode for self-signing, used only with p384 keys enabled and panics otherwise.
|
||||
fn encode_for_self_signing(
|
||||
&self,
|
||||
buf: &mut [u8; Address::V2_ADDRESS_SIZE + 1 + C25519_PUBLIC_KEY_SIZE + ED25519_PUBLIC_KEY_SIZE + P384_PUBLIC_KEY_SIZE + P384_PUBLIC_KEY_SIZE],
|
||||
buf: &mut [u8; Address::SIZE_BYTES + 1 + C25519_PUBLIC_KEY_SIZE + ED25519_PUBLIC_KEY_SIZE + P384_PUBLIC_KEY_SIZE + P384_PUBLIC_KEY_SIZE],
|
||||
) {
|
||||
let mut buf = &mut buf[Address::V2_ADDRESS_SIZE + 1..];
|
||||
let _ = buf.write_all(self.address.as_bytes_raw());
|
||||
let mut buf = &mut buf[Address::SIZE_BYTES + 1..];
|
||||
let _ = buf.write_all(self.address.as_bytes());
|
||||
let _ = buf.write_all(&[Self::ALGORITHM_X25519 | Self::ALGORITHM_P384]);
|
||||
let _ = buf.write_all(&self.x25519.ecdh);
|
||||
let _ = buf.write_all(&self.x25519.eddsa);
|
||||
|
@ -181,10 +183,10 @@ impl Identity {
|
|||
}
|
||||
|
||||
pub fn from_bytes(b: &[u8]) -> Result<Self, InvalidFormatError> {
|
||||
if b.len() == packed::V2_PUBLIC_SIZE && b[Address::V1_ADDRESS_SIZE] == (Self::ALGORITHM_X25519 | Self::ALGORITHM_P384) {
|
||||
let p: &packed::V2Public = unsafe { &*b.as_ptr().cast() };
|
||||
if b.len() == packed::V2_PUBLIC_SIZE && b[LegacyAddress::SIZE_BYTES] == (Self::ALGORITHM_X25519 | Self::ALGORITHM_P384) {
|
||||
let p: &packed::V2Public = memory::cast_to_struct(b);
|
||||
let mut id = Self {
|
||||
address: Address::from_bytes_v1(&p.short_address).ok_or(InvalidFormatError)?,
|
||||
address: Address::new_uninitialized(),
|
||||
x25519: X25519 { ecdh: p.c25519, eddsa: p.ed25519 },
|
||||
p384: Some(P384 {
|
||||
ecdh: P384PublicKey::from_bytes(&p.p384_ecdh).ok_or(InvalidFormatError)?,
|
||||
|
@ -193,19 +195,17 @@ impl Identity {
|
|||
p384_self_signature: p.p384_self_signature,
|
||||
}),
|
||||
};
|
||||
let hash = SHA384::hash(&b[..packed::V2_PUBLIC_SIZE]);
|
||||
id.address.as_bytes_raw_mut()[Address::V1_ADDRESS_SIZE..].copy_from_slice(&hash[..SHA384_HASH_SIZE - Address::V1_ADDRESS_SIZE]);
|
||||
id.address.as_bytes_mut()[..LegacyAddress::SIZE_BYTES].copy_from_slice(&p.short_address);
|
||||
id.populate_extended_address_bits();
|
||||
return Ok(id);
|
||||
} else if b.len() == packed::V1_PUBLIC_SIZE && b[Address::V1_ADDRESS_SIZE] == Self::ALGORITHM_X25519 {
|
||||
let p: &packed::V1Public = unsafe { &*b.as_ptr().cast() };
|
||||
} else if b.len() == packed::V1_PUBLIC_SIZE && b[LegacyAddress::SIZE_BYTES] == Self::ALGORITHM_X25519 {
|
||||
let p: &packed::V1Public = memory::cast_to_struct(b);
|
||||
let mut id = Self {
|
||||
address: Address::from_bytes_v1(&p.short_address).ok_or(InvalidFormatError)?,
|
||||
address: Address::new_uninitialized(),
|
||||
x25519: X25519 { ecdh: p.c25519, eddsa: p.ed25519 },
|
||||
p384: None,
|
||||
};
|
||||
let hash = SHA384::hash(&b[..packed::V1_PUBLIC_SIZE]);
|
||||
id.address.as_bytes_raw_mut()[Address::V1_ADDRESS_SIZE..].copy_from_slice(&hash[..SHA384_HASH_SIZE - Address::V1_ADDRESS_SIZE]);
|
||||
id.address.as_bytes_mut()[..LegacyAddress::SIZE_BYTES].copy_from_slice(&p.short_address);
|
||||
id.populate_extended_address_bits();
|
||||
return Ok(id);
|
||||
}
|
||||
|
@ -215,7 +215,7 @@ impl Identity {
|
|||
pub fn write_bytes<W: Write>(&self, w: &mut W, x25519_only: bool) -> Result<(), std::io::Error> {
|
||||
if let (false, Some(p384)) = (x25519_only, self.p384.as_ref()) {
|
||||
w.write_all(memory::as_byte_array::<packed::V2Public, { packed::V2_PUBLIC_SIZE }>(&packed::V2Public {
|
||||
short_address: *self.address.as_bytes_v1(),
|
||||
short_address: *self.address.legacy_address().as_bytes(),
|
||||
algorithms: Self::ALGORITHM_X25519 | Self::ALGORITHM_P384,
|
||||
c25519: self.x25519.ecdh,
|
||||
ed25519: self.x25519.eddsa,
|
||||
|
@ -226,7 +226,7 @@ impl Identity {
|
|||
}))
|
||||
} else {
|
||||
w.write_all(memory::as_byte_array::<packed::V1Public, { packed::V1_PUBLIC_SIZE }>(&packed::V1Public {
|
||||
short_address: *self.address.as_bytes_v1(),
|
||||
short_address: *self.address.legacy_address().as_bytes(),
|
||||
algorithms: Self::ALGORITHM_X25519,
|
||||
c25519: self.x25519.ecdh,
|
||||
ed25519: self.x25519.eddsa,
|
||||
|
@ -252,7 +252,7 @@ impl ToString for Identity {
|
|||
} else {
|
||||
format!(
|
||||
"{}:0:{}:{}",
|
||||
self.address.to_short_string(),
|
||||
self.address.legacy_address().to_string(),
|
||||
hex::to_string(&self.x25519.ecdh),
|
||||
hex::to_string(&self.x25519.eddsa)
|
||||
)
|
||||
|
@ -300,7 +300,7 @@ impl Marshalable for Identity {
|
|||
fn unmarshal<const BL: usize>(buf: &Buffer<BL>, cursor: &mut usize) -> Result<Self, UnmarshalError> {
|
||||
const V1_ALG: u8 = Identity::ALGORITHM_X25519;
|
||||
const V2_ALG: u8 = Identity::ALGORITHM_X25519 | Identity::ALGORITHM_P384;
|
||||
match buf.u8_at(*cursor + Address::V1_ADDRESS_SIZE)? {
|
||||
match buf.u8_at(*cursor + LegacyAddress::SIZE_BYTES)? {
|
||||
V1_ALG => Identity::from_bytes(buf.read_bytes_fixed::<{ packed::V1_PUBLIC_SIZE }>(cursor)?).map_err(|_| UnmarshalError::InvalidData),
|
||||
V2_ALG => Identity::from_bytes(buf.read_bytes_fixed::<{ packed::V2_PUBLIC_SIZE }>(cursor)?).map_err(|_| UnmarshalError::InvalidData),
|
||||
_ => Err(UnmarshalError::UnsupportedVersion),
|
||||
|
@ -446,6 +446,9 @@ mod packed {
|
|||
pub ed25519_self_signature: [u8; ED25519_SIGNATURE_SIZE],
|
||||
pub p384_self_signature: [u8; P384_ECDSA_SIGNATURE_SIZE],
|
||||
}
|
||||
|
||||
unsafe impl memory::FlatBuffer for V1Public {}
|
||||
unsafe impl memory::FlatBuffer for V2Public {}
|
||||
}
|
||||
|
||||
fn legacy_address_derivation_work_function(digest: &mut [u8; 64]) {
|
||||
|
|
|
@ -77,6 +77,7 @@ pub const AF_INET: AddressFamilyType = libc::AF_INET as AddressFamilyType;
|
|||
#[cfg(not(windows))]
|
||||
pub const AF_INET6: AddressFamilyType = libc::AF_INET6 as AddressFamilyType;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(u8)]
|
||||
pub enum IpScope {
|
||||
None = 0,
|
||||
|
|
|
@ -7,12 +7,13 @@ mod mac;
|
|||
mod node;
|
||||
mod path;
|
||||
mod peer;
|
||||
mod peermap;
|
||||
mod rootset;
|
||||
|
||||
pub mod identity;
|
||||
pub mod inetaddress;
|
||||
|
||||
pub use address::Address;
|
||||
pub use address::{Address, LegacyAddress};
|
||||
pub use endpoint::Endpoint;
|
||||
pub use event::Event;
|
||||
pub use inetaddress::InetAddress;
|
||||
|
|
|
@ -8,20 +8,22 @@ use std::sync::{Arc, Mutex, RwLock, Weak};
|
|||
use std::time::Duration;
|
||||
|
||||
use crate::protocol::*;
|
||||
use crate::vl1::address::Address;
|
||||
use crate::vl1::address::{Address, LegacyAddress};
|
||||
use crate::vl1::debug_event;
|
||||
use crate::vl1::endpoint::Endpoint;
|
||||
use crate::vl1::event::Event;
|
||||
use crate::vl1::identity::{Identity, IdentitySecret};
|
||||
use crate::vl1::path::{Path, PathServiceResult};
|
||||
use crate::vl1::peer::Peer;
|
||||
use crate::vl1::peermap::PeerMap;
|
||||
use crate::vl1::rootset::RootSet;
|
||||
|
||||
use zerotier_crypto::random;
|
||||
use zerotier_crypto::typestate::{Valid, Verified};
|
||||
use zerotier_utils::gate::IntervalGate;
|
||||
use zerotier_utils::hex;
|
||||
use zerotier_utils::marshalable::Marshalable;
|
||||
use zerotier_utils::ringbuffer::RingBuffer;
|
||||
use zerotier_utils::tokio::io::AsyncWriteExt;
|
||||
|
||||
/// Interface trait to be implemented by code that's using the ZeroTier network hypervisor.
|
||||
///
|
||||
|
@ -217,28 +219,23 @@ struct WhoisQueueItem<Application: ApplicationLayer + ?Sized> {
|
|||
retry_count: u16,
|
||||
}
|
||||
|
||||
/// A ZeroTier VL1 node that can communicate securely with the ZeroTier peer-to-peer network.
|
||||
pub struct Node<Application: ApplicationLayer + ?Sized> {
|
||||
pub instance_id: [u8; 16],
|
||||
pub identity: Valid<Identity>,
|
||||
identity_secret: IdentitySecret,
|
||||
intervals: Mutex<BackgroundTaskIntervals>,
|
||||
paths: RwLock<HashMap<PathKey<'static, 'static, Application::LocalSocket>, Arc<Path<Application>>>>,
|
||||
peers: RwLock<HashMap<Address, Arc<Peer<Application>>>>,
|
||||
peers: PeerMap<Application>,
|
||||
roots: RwLock<RootInfo<Application>>,
|
||||
best_root: RwLock<Option<Arc<Peer<Application>>>>,
|
||||
whois_queue: Mutex<HashMap<Address, WhoisQueueItem<Application>>>,
|
||||
whois_queue: Mutex<HashMap<LegacyAddress, WhoisQueueItem<Application>>>,
|
||||
}
|
||||
|
||||
impl<Application: ApplicationLayer + ?Sized> Node<Application> {
|
||||
pub fn new(identity: Valid<Identity>, identity_secret: IdentitySecret) -> Self {
|
||||
pub fn new(identity_secret: IdentitySecret) -> Self {
|
||||
Self {
|
||||
instance_id: random::get_bytes_secure(),
|
||||
identity,
|
||||
identity_secret,
|
||||
intervals: Mutex::new(BackgroundTaskIntervals::default()),
|
||||
paths: RwLock::new(HashMap::new()),
|
||||
peers: RwLock::new(HashMap::new()),
|
||||
peers: PeerMap::new(),
|
||||
roots: RwLock::new(RootInfo {
|
||||
sets: HashMap::new(),
|
||||
roots: HashMap::new(),
|
||||
|
@ -251,9 +248,19 @@ impl<Application: ApplicationLayer + ?Sized> Node<Application> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[inline(always)]
|
||||
pub fn identity(&self) -> &Valid<Identity> {
|
||||
&self.identity_secret.public
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn peer(&self, a: &Address) -> Option<Arc<Peer<Application>>> {
|
||||
self.peers.read().unwrap().get(&a).cloned()
|
||||
self.peers.get(a)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn peer_legacy(&self, a: &LegacyAddress) -> Option<Arc<Peer<Application>>> {
|
||||
self.peers.get_legacy(a)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -280,7 +287,6 @@ impl<Application: ApplicationLayer + ?Sized> Node<Application> {
|
|||
}
|
||||
|
||||
/// Add a new root set or update the existing root set if the new root set is newer and otherwise matches.
|
||||
#[inline]
|
||||
pub fn add_update_root_set(&self, rs: Verified<RootSet>) -> bool {
|
||||
let mut roots = self.roots.write().unwrap();
|
||||
if let Some(entry) = roots.sets.get_mut(&rs.name) {
|
||||
|
@ -299,13 +305,11 @@ impl<Application: ApplicationLayer + ?Sized> Node<Application> {
|
|||
}
|
||||
|
||||
/// Returns whether or not this node has any root sets defined.
|
||||
#[inline]
|
||||
pub fn has_roots_defined(&self) -> bool {
|
||||
self.roots.read().unwrap().sets.iter().any(|rs| !rs.1.members.is_empty())
|
||||
}
|
||||
|
||||
/// Initialize with default roots if there are no roots defined, otherwise do nothing.
|
||||
#[inline]
|
||||
pub fn init_default_roots(&self) -> bool {
|
||||
if !self.has_roots_defined() {
|
||||
self.add_update_root_set(RootSet::zerotier_default())
|
||||
|
@ -315,7 +319,6 @@ impl<Application: ApplicationLayer + ?Sized> Node<Application> {
|
|||
}
|
||||
|
||||
/// Get the root sets that this node trusts.
|
||||
#[inline]
|
||||
pub fn root_sets(&self) -> Vec<RootSet> {
|
||||
self.roots.read().unwrap().sets.values().cloned().map(|s| s.remove_typestate()).collect()
|
||||
}
|
||||
|
@ -359,26 +362,23 @@ impl<Application: ApplicationLayer + ?Sized> Node<Application> {
|
|||
|
||||
for (_, rs) in roots.sets.iter() {
|
||||
for m in rs.members.iter() {
|
||||
if m.endpoints.is_some() && !m.identity.eq(&self.identity) {
|
||||
if m.identity.eq(&self.identity_secret.public) {
|
||||
let _ = my_root_sets
|
||||
.get_or_insert_with(|| Vec::new())
|
||||
.write_all(rs.to_buffer::<{ RootSet::MAX_MARSHAL_SIZE }>().unwrap().as_bytes());
|
||||
} else if m.endpoints.is_some() {
|
||||
debug_event!(
|
||||
app,
|
||||
"[vl1] examining root {} with {} endpoints",
|
||||
m.identity.address.to_string(),
|
||||
m.endpoints.as_ref().map_or(0, |e| e.len())
|
||||
);
|
||||
let peers = self.peers.read().unwrap();
|
||||
if let Some(peer) = peers.get(&m.identity.address) {
|
||||
if let Some(peer) = self.peers.get(&m.identity.address) {
|
||||
new_roots.insert(peer.clone(), m.endpoints.as_ref().unwrap().iter().cloned().collect());
|
||||
} else {
|
||||
if let Some(peer) = Peer::new(&self.identity_secret, Valid::mark_valid(m.identity.clone()), time_ticks) {
|
||||
drop(peers);
|
||||
new_roots.insert(
|
||||
self.peers
|
||||
.write()
|
||||
.unwrap()
|
||||
.entry(m.identity.address.clone())
|
||||
.or_insert_with(|| Arc::new(peer))
|
||||
.clone(),
|
||||
self.peers.insert_if_unique(Arc::new(peer)).0,
|
||||
m.endpoints.as_ref().unwrap().iter().cloned().collect(),
|
||||
);
|
||||
} else {
|
||||
|
@ -503,14 +503,14 @@ impl<Application: ApplicationLayer + ?Sized> Node<Application> {
|
|||
let mut dead_peers = Vec::new();
|
||||
{
|
||||
let roots = self.roots.read().unwrap();
|
||||
for (a, peer) in self.peers.read().unwrap().iter() {
|
||||
self.peers.each(|peer| {
|
||||
if !peer.service(app, self, time_ticks) && !roots.roots.contains_key(peer) {
|
||||
dead_peers.push(a.clone());
|
||||
dead_peers.push(peer.identity.address.clone());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
for dp in dead_peers.iter() {
|
||||
self.peers.write().unwrap().remove(dp);
|
||||
self.peers.remove(dp);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -591,10 +591,10 @@ impl<Application: ApplicationLayer + ?Sized> Node<Application> {
|
|||
|
||||
// Legacy ZeroTier V1 packet handling
|
||||
if let Ok(fragment_header) = packet.struct_mut_at::<v1::FragmentHeader>(0) {
|
||||
if let Some(dest) = Address::from_bytes_v1(&fragment_header.dest) {
|
||||
if let Some(dest) = LegacyAddress::from_bytes_exact(&fragment_header.dest) {
|
||||
// Packet is addressed to this node.
|
||||
|
||||
if dest == self.identity.address {
|
||||
if dest == self.identity_secret.public.address.legacy_address() {
|
||||
let fragment_header = &*fragment_header; // discard mut
|
||||
let path = self.canonical_path(source_endpoint, source_local_socket, source_local_interface, time_ticks);
|
||||
path.log_receive_anything(time_ticks);
|
||||
|
@ -622,8 +622,8 @@ impl<Application: ApplicationLayer + ?Sized> Node<Application> {
|
|||
debug_event!(app, "[vl1] [v1] #{:0>16x} packet fully assembled!", fragment_header_id);
|
||||
|
||||
if let Ok(packet_header) = frag0.struct_at::<v1::PacketHeader>(0) {
|
||||
if let Some(source) = Address::from_bytes_v1(&packet_header.src) {
|
||||
if let Some(peer) = self.peer(&source) {
|
||||
if let Some(source) = LegacyAddress::from_bytes_exact(&packet_header.src) {
|
||||
if let Some(peer) = self.peers.get_legacy(&source) {
|
||||
peer.v1_proto_receive(
|
||||
self,
|
||||
app,
|
||||
|
@ -657,8 +657,8 @@ impl<Application: ApplicationLayer + ?Sized> Node<Application> {
|
|||
} else if let Ok(packet_header) = packet.struct_at::<v1::PacketHeader>(0) {
|
||||
debug_event!(app, "[vl1] [v1] #{:0>16x} is unfragmented", u64::from_be_bytes(packet_header.id));
|
||||
|
||||
if let Some(source) = Address::from_bytes_v1(&packet_header.src) {
|
||||
if let Some(peer) = self.peer(&source) {
|
||||
if let Some(source) = LegacyAddress::from_bytes_exact(&packet_header.src) {
|
||||
if let Some(peer) = self.peers.get_legacy(&source) {
|
||||
peer.v1_proto_receive(self, app, inner, time_ticks, &path, packet_header, packet.as_ref(), &[]);
|
||||
} else {
|
||||
self.whois(app, source, Some((Arc::downgrade(&path), packet)), time_ticks);
|
||||
|
@ -707,7 +707,7 @@ impl<Application: ApplicationLayer + ?Sized> Node<Application> {
|
|||
return;
|
||||
}
|
||||
|
||||
if let Some(peer) = self.peer(&dest) {
|
||||
if let Some(peer) = self.peers.get_legacy(&dest) {
|
||||
if let Some(forward_path) = peer.direct_path() {
|
||||
app.wire_send(
|
||||
&forward_path.endpoint,
|
||||
|
@ -729,10 +729,16 @@ impl<Application: ApplicationLayer + ?Sized> Node<Application> {
|
|||
}
|
||||
|
||||
/// Enqueue and send a WHOIS query for a given address, adding the supplied packet (if any) to the list to be processed on reply.
|
||||
fn whois(&self, app: &Application, address: Address, waiting_packet: Option<(Weak<Path<Application>>, PooledPacketBuffer)>, time_ticks: i64) {
|
||||
fn whois(
|
||||
&self,
|
||||
app: &Application,
|
||||
address: LegacyAddress,
|
||||
waiting_packet: Option<(Weak<Path<Application>>, PooledPacketBuffer)>,
|
||||
time_ticks: i64,
|
||||
) {
|
||||
{
|
||||
let mut whois_queue = self.whois_queue.lock().unwrap();
|
||||
let qi = whois_queue.entry(address.clone()).or_insert_with(|| WhoisQueueItem {
|
||||
let qi = whois_queue.entry(address).or_insert_with(|| WhoisQueueItem {
|
||||
v1_proto_waiting_packets: RingBuffer::new(),
|
||||
last_retry_time: 0,
|
||||
retry_count: 0,
|
||||
|
@ -751,7 +757,7 @@ impl<Application: ApplicationLayer + ?Sized> Node<Application> {
|
|||
}
|
||||
|
||||
/// Send a WHOIS query to the current best root.
|
||||
fn send_whois(&self, app: &Application, mut addresses: &[Address], time_ticks: i64) {
|
||||
fn send_whois(&self, app: &Application, mut addresses: &[LegacyAddress], time_ticks: i64) {
|
||||
debug_assert!(!addresses.is_empty());
|
||||
debug_event!(app, "[vl1] [v1] sending WHOIS for {}", {
|
||||
let mut tmp = String::new();
|
||||
|
@ -769,7 +775,7 @@ impl<Application: ApplicationLayer + ?Sized> Node<Application> {
|
|||
.send(app, self, None, time_ticks, |packet| -> Result<(), Infallible> {
|
||||
assert!(packet.append_u8(message_type::VL1_WHOIS).is_ok());
|
||||
while !addresses.is_empty() && (packet.len() + ADDRESS_SIZE) <= UDP_DEFAULT_MTU {
|
||||
assert!(packet.append_bytes_fixed(addresses[0].as_bytes_v1()).is_ok());
|
||||
assert!(packet.append_bytes_fixed(addresses[0].as_bytes()).is_ok());
|
||||
addresses = &addresses[1..];
|
||||
}
|
||||
Ok(())
|
||||
|
@ -794,10 +800,10 @@ impl<Application: ApplicationLayer + ?Sized> Node<Application> {
|
|||
if authoritative {
|
||||
if let Some(received_identity) = received_identity.validate() {
|
||||
let mut whois_queue = self.whois_queue.lock().unwrap();
|
||||
if let Some(qi) = whois_queue.get_mut(&received_identity.address) {
|
||||
let address = received_identity.address.clone();
|
||||
if let Some(qi) = whois_queue.get_mut(&received_identity.address.legacy_address()) {
|
||||
let address = received_identity.address.legacy_address();
|
||||
/*
|
||||
if app.should_respond_to(&received_identity) {
|
||||
let mut peers = self.peers.write().unwrap();
|
||||
if let Some(peer) = peers.get(&address).cloned().or_else(|| {
|
||||
Peer::new(&self.identity_secret, received_identity, time_ticks)
|
||||
.map(|p| Arc::new(p))
|
||||
|
@ -813,6 +819,7 @@ impl<Application: ApplicationLayer + ?Sized> Node<Application> {
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
whois_queue.remove(&address);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ use zerotier_utils::memory::array_range;
|
|||
use zerotier_utils::NEVER_HAPPENED_TICKS;
|
||||
|
||||
use crate::protocol::*;
|
||||
use crate::vl1::address::Address;
|
||||
use crate::vl1::debug_event;
|
||||
use crate::vl1::identity::{Identity, IdentitySecret};
|
||||
use crate::vl1::node::*;
|
||||
|
@ -23,6 +22,8 @@ use crate::vl1::Valid;
|
|||
use crate::vl1::{Endpoint, Path};
|
||||
use crate::{VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION};
|
||||
|
||||
use super::LegacyAddress;
|
||||
|
||||
pub(crate) const SERVICE_INTERVAL_MS: i64 = 10000;
|
||||
|
||||
pub struct Peer<Application: ApplicationLayer + ?Sized> {
|
||||
|
@ -327,7 +328,7 @@ impl<Application: ApplicationLayer + ?Sized> Peer<Application> {
|
|||
aes_gmac_siv.encrypt_init(&self.v1_proto_next_message_id().to_be_bytes());
|
||||
aes_gmac_siv.encrypt_set_aad(&v1::get_packet_aad_bytes(
|
||||
&self.identity.address,
|
||||
&node.identity.address,
|
||||
&node.identity().address,
|
||||
flags_cipher_hops,
|
||||
));
|
||||
let payload = packet.as_bytes_starting_at_mut(v1::HEADER_SIZE).unwrap();
|
||||
|
@ -338,8 +339,8 @@ impl<Application: ApplicationLayer + ?Sized> Peer<Application> {
|
|||
|
||||
let header = packet.struct_mut_at::<v1::PacketHeader>(0).unwrap();
|
||||
header.id.copy_from_slice(&tag[0..8]);
|
||||
header.dest = *self.identity.address.as_bytes_v1();
|
||||
header.src = *node.identity.address.as_bytes_v1();
|
||||
header.dest = *self.identity.address.legacy_address().as_bytes();
|
||||
header.src = *node.identity().address.legacy_address().as_bytes();
|
||||
header.flags_cipher_hops = flags_cipher_hops;
|
||||
header.mac.copy_from_slice(&tag[8..16]);
|
||||
} else {
|
||||
|
@ -355,8 +356,8 @@ impl<Application: ApplicationLayer + ?Sized> Peer<Application> {
|
|||
{
|
||||
let header = packet.struct_mut_at::<v1::PacketHeader>(0).unwrap();
|
||||
header.id = self.v1_proto_next_message_id().to_be_bytes();
|
||||
header.dest = *self.identity.address.as_bytes_v1();
|
||||
header.src = *node.identity.address.as_bytes_v1();
|
||||
header.dest = *self.identity.address.legacy_address().as_bytes();
|
||||
header.src = *node.identity().address.legacy_address().as_bytes();
|
||||
header.flags_cipher_hops = flags_cipher_hops;
|
||||
header
|
||||
},
|
||||
|
@ -413,8 +414,8 @@ impl<Application: ApplicationLayer + ?Sized> Peer<Application> {
|
|||
{
|
||||
let f: &mut (v1::PacketHeader, v1::message_component_structs::HelloFixedHeaderFields) = packet.append_struct_get_mut().unwrap();
|
||||
f.0.id = message_id.to_ne_bytes();
|
||||
f.0.dest = *self.identity.address.as_bytes_v1();
|
||||
f.0.src = *node.identity.address.as_bytes_v1();
|
||||
f.0.dest = *self.identity.address.legacy_address().as_bytes();
|
||||
f.0.src = *node.identity().address.legacy_address().as_bytes();
|
||||
f.0.flags_cipher_hops = v1::CIPHER_NOCRYPT_POLY1305;
|
||||
f.1.verb = message_type::VL1_HELLO;
|
||||
f.1.version_proto = PROTOCOL_VERSION;
|
||||
|
@ -425,7 +426,7 @@ impl<Application: ApplicationLayer + ?Sized> Peer<Application> {
|
|||
}
|
||||
|
||||
debug_assert_eq!(packet.len(), 41);
|
||||
assert!(node.identity.write_bytes(packet.as_mut(), !self.is_v2()).is_ok());
|
||||
assert!(node.identity().write_bytes(packet.as_mut(), !self.is_v2()).is_ok());
|
||||
|
||||
let (_, poly1305_key) = v1_proto_salsa_poly_create(
|
||||
&self.v1_proto_static_secret,
|
||||
|
@ -770,8 +771,8 @@ impl<Application: ApplicationLayer + ?Sized> Peer<Application> {
|
|||
if !self
|
||||
.send(app, node, None, time_ticks, |packet| {
|
||||
while addresses.len() >= ADDRESS_SIZE && (packet.len() + Identity::MAX_MARSHAL_SIZE) <= UDP_DEFAULT_MTU {
|
||||
if let Some(zt_address) = Address::from_bytes_v1(&addresses[..ADDRESS_SIZE]) {
|
||||
if let Some(peer) = node.peer(&zt_address) {
|
||||
if let Some(zt_address) = LegacyAddress::from_bytes(&addresses[..ADDRESS_SIZE]) {
|
||||
if let Some(peer) = node.peer_legacy(&zt_address) {
|
||||
peer.identity.write_bytes(packet, !self.is_v2())?;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -127,7 +127,7 @@ impl MulticastAuthority {
|
|||
|
||||
packet.append_u16(in_this_packet as u16)?;
|
||||
for _ in 0..in_this_packet {
|
||||
packet.append_bytes_fixed(gathered.pop().unwrap().as_bytes_v1())?;
|
||||
packet.append_bytes_fixed(gathered.pop().unwrap().legacy_address().as_bytes())?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -22,7 +22,7 @@ impl NetworkId {
|
|||
pub fn from_u64(i: u64) -> Option<NetworkId> {
|
||||
// Note that we check both that 'i' is non-zero and that the address of the controller is valid.
|
||||
if let Some(ii) = NonZeroU64::new(i) {
|
||||
if Address::from_u64_v1(i).is_some() {
|
||||
if Address::from_legacy_u64(i).is_some() {
|
||||
return Some(Self(ii));
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ impl NetworkId {
|
|||
|
||||
#[inline]
|
||||
pub fn from_controller_and_network_no(controller: Address, network_no: u64) -> Option<NetworkId> {
|
||||
Self::from_u64(controller.as_u64_v1().wrapping_shl(24) | (network_no & 0xffffff))
|
||||
Self::from_u64(controller.to_legacy_u64().wrapping_shl(24) | (network_no & 0xffffff))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -56,12 +56,12 @@ impl NetworkId {
|
|||
/// Get the network controller ID for this network, which is the most significant 40 bits.
|
||||
#[inline]
|
||||
pub fn network_controller(&self) -> Address {
|
||||
Address::from_u64_v1(self.0.get()).unwrap()
|
||||
Address::from_legacy_u64(self.0.get()).unwrap()
|
||||
}
|
||||
|
||||
/// Consume this network ID and return one with the same network number but a different controller ID.
|
||||
pub fn change_network_controller(self, new_controller: Address) -> NetworkId {
|
||||
Self(NonZeroU64::new((self.network_no() as u64) | new_controller.as_u64_v1().wrapping_shl(24)).unwrap())
|
||||
Self(NonZeroU64::new((self.network_no() as u64) | new_controller.to_legacy_u64().wrapping_shl(24)).unwrap())
|
||||
}
|
||||
|
||||
/// Get the 24-bit local network identifier minus the 40-bit controller address portion.
|
||||
|
|
|
@ -10,7 +10,7 @@ use zerotier_utils::buffer::{Buffer, OutOfBoundsError};
|
|||
use zerotier_utils::marshalable::{Marshalable, UnmarshalError};
|
||||
|
||||
use crate::protocol;
|
||||
use crate::vl1::{Address, InetAddress, MAC};
|
||||
use crate::vl1::{Address, InetAddress, LegacyAddress, MAC};
|
||||
|
||||
#[allow(unused)]
|
||||
pub const RULES_ENGINE_REVISION: u8 = 1;
|
||||
|
@ -174,16 +174,16 @@ impl Default for RuleValue {
|
|||
pub trait RuleVisitor {
|
||||
fn action_drop(&mut self) -> bool;
|
||||
fn action_accept(&mut self) -> bool;
|
||||
fn action_tee(&mut self, address: Address, flags: u32, length: u16) -> bool;
|
||||
fn action_watch(&mut self, address: Address, flags: u32, length: u16) -> bool;
|
||||
fn action_redirect(&mut self, address: Address, flags: u32, length: u16) -> bool;
|
||||
fn action_tee(&mut self, address: LegacyAddress, flags: u32, length: u16) -> bool;
|
||||
fn action_watch(&mut self, address: LegacyAddress, flags: u32, length: u16) -> bool;
|
||||
fn action_redirect(&mut self, address: LegacyAddress, flags: u32, length: u16) -> bool;
|
||||
fn action_break(&mut self) -> bool;
|
||||
fn action_priority(&mut self, qos_bucket: u8) -> bool;
|
||||
|
||||
fn invalid_rule(&mut self) -> bool;
|
||||
|
||||
fn match_source_zerotier_address(&mut self, not: bool, or: bool, address: Address);
|
||||
fn match_dest_zerotier_address(&mut self, not: bool, or: bool, address: Address);
|
||||
fn match_source_zerotier_address(&mut self, not: bool, or: bool, address: LegacyAddress);
|
||||
fn match_dest_zerotier_address(&mut self, not: bool, or: bool, address: LegacyAddress);
|
||||
fn match_vlan_id(&mut self, not: bool, or: bool, id: u16);
|
||||
fn match_vlan_pcp(&mut self, not: bool, or: bool, pcp: u8);
|
||||
fn match_vlan_dei(&mut self, not: bool, or: bool, dei: u8);
|
||||
|
@ -239,7 +239,7 @@ impl Rule {
|
|||
Self {
|
||||
t: action::TEE,
|
||||
v: RuleValue {
|
||||
forward: rule_value::Forward { address: address.as_u64_v1(), flags, length },
|
||||
forward: rule_value::Forward { address: address.legacy_address().to_u64(), flags, length },
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -248,7 +248,7 @@ impl Rule {
|
|||
Self {
|
||||
t: action::TEE,
|
||||
v: RuleValue {
|
||||
forward: rule_value::Forward { address: address.as_u64_v1(), flags, length },
|
||||
forward: rule_value::Forward { address: address.legacy_address().to_u64(), flags, length },
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -257,7 +257,7 @@ impl Rule {
|
|||
Self {
|
||||
t: action::TEE,
|
||||
v: RuleValue {
|
||||
forward: rule_value::Forward { address: address.as_u64_v1(), flags, length },
|
||||
forward: rule_value::Forward { address: address.legacy_address().to_u64(), flags, length },
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -273,14 +273,14 @@ impl Rule {
|
|||
pub fn match_source_zerotier_address(not: bool, or: bool, address: Address) -> Self {
|
||||
Self {
|
||||
t: t(not, or, match_cond::SOURCE_ZEROTIER_ADDRESS),
|
||||
v: RuleValue { zt: address.as_u64_v1() },
|
||||
v: RuleValue { zt: address.legacy_address().to_u64() },
|
||||
}
|
||||
}
|
||||
|
||||
pub fn match_dest_zerotier_address(not: bool, or: bool, address: Address) -> Self {
|
||||
Self {
|
||||
t: t(not, or, match_cond::DEST_ZEROTIER_ADDRESS),
|
||||
v: RuleValue { zt: address.as_u64_v1() },
|
||||
v: RuleValue { zt: address.legacy_address().to_u64() },
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -306,21 +306,21 @@ impl Rule {
|
|||
return v.action_accept();
|
||||
}
|
||||
action::TEE => {
|
||||
if let Some(a) = Address::from_u64_v1(self.v.forward.address) {
|
||||
if let Some(a) = LegacyAddress::from_u64(self.v.forward.address) {
|
||||
return v.action_tee(a, self.v.forward.flags, self.v.forward.length);
|
||||
} else {
|
||||
return v.invalid_rule();
|
||||
}
|
||||
}
|
||||
action::WATCH => {
|
||||
if let Some(a) = Address::from_u64_v1(self.v.forward.address) {
|
||||
if let Some(a) = LegacyAddress::from_u64(self.v.forward.address) {
|
||||
return v.action_watch(a, self.v.forward.flags, self.v.forward.length);
|
||||
} else {
|
||||
return v.invalid_rule();
|
||||
}
|
||||
}
|
||||
action::REDIRECT => {
|
||||
if let Some(a) = Address::from_u64_v1(self.v.forward.address) {
|
||||
if let Some(a) = LegacyAddress::from_u64(self.v.forward.address) {
|
||||
return v.action_redirect(a, self.v.forward.flags, self.v.forward.length);
|
||||
} else {
|
||||
return v.invalid_rule();
|
||||
|
@ -333,14 +333,14 @@ impl Rule {
|
|||
return v.action_priority(self.v.qos_bucket);
|
||||
}
|
||||
match_cond::SOURCE_ZEROTIER_ADDRESS => {
|
||||
if let Some(a) = Address::from_u64_v1(self.v.zt) {
|
||||
if let Some(a) = LegacyAddress::from_u64(self.v.zt) {
|
||||
v.match_source_zerotier_address(not, or, a);
|
||||
} else {
|
||||
return v.invalid_rule();
|
||||
}
|
||||
}
|
||||
match_cond::DEST_ZEROTIER_ADDRESS => {
|
||||
if let Some(a) = Address::from_u64_v1(self.v.zt) {
|
||||
if let Some(a) = LegacyAddress::from_u64(self.v.zt) {
|
||||
v.match_dest_zerotier_address(not, or, a);
|
||||
} else {
|
||||
return v.invalid_rule();
|
||||
|
@ -775,13 +775,13 @@ static HR_NAME_TO_RULE_TYPE: phf::Map<&'static str, u8> = phf_map! {
|
|||
#[derive(Default, Serialize, Deserialize)]
|
||||
struct HumanReadableRule<'a> {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub address: Option<Address>,
|
||||
pub address: Option<LegacyAddress>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub flags: Option<u32>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub length: Option<u16>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub zt: Option<Address>,
|
||||
pub zt: Option<LegacyAddress>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub vlanId: Option<u16>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
|
@ -837,7 +837,7 @@ impl<'a> HumanReadableRule<'a> {
|
|||
unsafe {
|
||||
match *t {
|
||||
action::TEE | action::WATCH | action::REDIRECT => {
|
||||
r.v.forward.address = self.address.as_ref()?.as_u64_v1();
|
||||
r.v.forward.address = self.address.as_ref()?.to_u64();
|
||||
r.v.forward.flags = self.flags?;
|
||||
r.v.forward.length = self.length?;
|
||||
}
|
||||
|
@ -845,7 +845,7 @@ impl<'a> HumanReadableRule<'a> {
|
|||
r.v.qos_bucket = self.qosBucket?;
|
||||
}
|
||||
match_cond::SOURCE_ZEROTIER_ADDRESS | match_cond::DEST_ZEROTIER_ADDRESS => {
|
||||
r.v.zt = self.address.as_ref()?.as_u64_v1();
|
||||
r.v.zt = self.address.as_ref()?.to_u64();
|
||||
}
|
||||
match_cond::VLAN_ID => {
|
||||
r.v.vlan_id = self.vlanId?;
|
||||
|
@ -982,7 +982,7 @@ impl<'a> RuleVisitor for MakeHumanReadable<'a> {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn action_tee(&mut self, address: Address, flags: u32, length: u16) -> bool {
|
||||
fn action_tee(&mut self, address: LegacyAddress, flags: u32, length: u16) -> bool {
|
||||
self.0._type = "ACTION_TEE";
|
||||
let _ = self.0.address.insert(address);
|
||||
let _ = self.0.flags.insert(flags);
|
||||
|
@ -991,7 +991,7 @@ impl<'a> RuleVisitor for MakeHumanReadable<'a> {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn action_watch(&mut self, address: Address, flags: u32, length: u16) -> bool {
|
||||
fn action_watch(&mut self, address: LegacyAddress, flags: u32, length: u16) -> bool {
|
||||
self.0._type = "ACTION_WATCH";
|
||||
let _ = self.0.address.insert(address);
|
||||
let _ = self.0.flags.insert(flags);
|
||||
|
@ -1000,7 +1000,7 @@ impl<'a> RuleVisitor for MakeHumanReadable<'a> {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn action_redirect(&mut self, address: Address, flags: u32, length: u16) -> bool {
|
||||
fn action_redirect(&mut self, address: LegacyAddress, flags: u32, length: u16) -> bool {
|
||||
self.0._type = "ACTION_REDIRECT";
|
||||
let _ = self.0.address.insert(address);
|
||||
let _ = self.0.flags.insert(flags);
|
||||
|
@ -1027,13 +1027,13 @@ impl<'a> RuleVisitor for MakeHumanReadable<'a> {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn match_source_zerotier_address(&mut self, not: bool, or: bool, address: Address) {
|
||||
fn match_source_zerotier_address(&mut self, not: bool, or: bool, address: LegacyAddress) {
|
||||
let _ = self.0.zt.insert(address);
|
||||
self.do_cond("MATCH_SOURCE_ZEROTIER_ADDRESS", not, or);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn match_dest_zerotier_address(&mut self, not: bool, or: bool, address: Address) {
|
||||
fn match_dest_zerotier_address(&mut self, not: bool, or: bool, address: LegacyAddress) {
|
||||
let _ = self.0.zt.insert(address);
|
||||
self.do_cond("MATCH_DEST_ZEROTIER_ADDRESS", not, or);
|
||||
}
|
||||
|
@ -1217,19 +1217,19 @@ impl RuleVisitor for RuleStringer {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn action_tee(&mut self, address: Address, flags: u32, length: u16) -> bool {
|
||||
fn action_tee(&mut self, address: LegacyAddress, flags: u32, length: u16) -> bool {
|
||||
self.0 = format!("ACTION_TEE({}, {}, {})", address.to_string(), flags, length);
|
||||
true
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn action_watch(&mut self, address: Address, flags: u32, length: u16) -> bool {
|
||||
fn action_watch(&mut self, address: LegacyAddress, flags: u32, length: u16) -> bool {
|
||||
self.0 = format!("ACTION_WATCH({}, {}, {})", address.to_string(), flags, length);
|
||||
true
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn action_redirect(&mut self, address: Address, flags: u32, length: u16) -> bool {
|
||||
fn action_redirect(&mut self, address: LegacyAddress, flags: u32, length: u16) -> bool {
|
||||
self.0 = format!("ACTION_REDIRECT({}, {}, {})", address.to_string(), flags, length);
|
||||
true
|
||||
}
|
||||
|
@ -1253,7 +1253,7 @@ impl RuleVisitor for RuleStringer {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn match_source_zerotier_address(&mut self, not: bool, or: bool, address: Address) {
|
||||
fn match_source_zerotier_address(&mut self, not: bool, or: bool, address: LegacyAddress) {
|
||||
self.0 = format!(
|
||||
"MATCH_SOURCE_ZEROTIER_ADDRESS({}{}{})",
|
||||
if or {
|
||||
|
@ -1271,7 +1271,7 @@ impl RuleVisitor for RuleStringer {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn match_dest_zerotier_address(&mut self, not: bool, or: bool, address: Address) {
|
||||
fn match_dest_zerotier_address(&mut self, not: bool, or: bool, address: LegacyAddress) {
|
||||
self.0 = format!(
|
||||
"MATCH_DEST_ZEROTIER_ADDRESS({}{}{})",
|
||||
if or {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::io::Write;
|
||||
|
||||
use crate::vl1::identity::{Identity, IdentitySecret};
|
||||
use crate::vl1::Address;
|
||||
use crate::vl1::LegacyAddress;
|
||||
use crate::vl2::NetworkId;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
@ -27,7 +27,7 @@ pub struct CertificateOfMembership {
|
|||
pub network_id: NetworkId,
|
||||
pub timestamp: i64,
|
||||
pub max_delta: u64,
|
||||
pub issued_to: Address,
|
||||
pub issued_to: LegacyAddress,
|
||||
pub issued_to_fingerprint: Blob<32>,
|
||||
pub signature: ArrayVec<u8, { Identity::MAX_SIGNATURE_SIZE }>,
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ impl CertificateOfMembership {
|
|||
network_id,
|
||||
timestamp,
|
||||
max_delta,
|
||||
issued_to: issued_to.address.clone(),
|
||||
issued_to: issued_to.address.legacy_address(),
|
||||
issued_to_fingerprint: Blob::default(),
|
||||
signature: ArrayVec::new(),
|
||||
};
|
||||
|
@ -59,7 +59,7 @@ impl CertificateOfMembership {
|
|||
q[4] = u64::from(self.network_id).to_be();
|
||||
q[5] = 0; // no disagreement permitted
|
||||
q[6] = 2u64.to_be();
|
||||
q[7] = self.issued_to.as_u64_v1().to_be();
|
||||
q[7] = self.issued_to.to_u64().to_be();
|
||||
q[8] = u64::MAX; // no to_be needed for all-1s
|
||||
|
||||
// This is a fix for a security issue in V1 in which an attacker could (with much CPU use)
|
||||
|
@ -86,20 +86,20 @@ impl CertificateOfMembership {
|
|||
/// Get the identity fingerprint used in V1, which only covers the curve25519 keys.
|
||||
fn v1_proto_issued_to_fingerprint(issued_to: &Identity) -> [u8; 32] {
|
||||
let mut v1_signee_hasher = SHA384::new();
|
||||
v1_signee_hasher.update(issued_to.address.as_bytes_v1());
|
||||
v1_signee_hasher.update(issued_to.address.legacy_address().as_bytes());
|
||||
v1_signee_hasher.update(&issued_to.x25519.ecdh);
|
||||
v1_signee_hasher.update(&issued_to.x25519.eddsa);
|
||||
(&v1_signee_hasher.finish()[..32]).try_into().unwrap()
|
||||
}
|
||||
|
||||
/// Get this certificate of membership in byte encoded format.
|
||||
pub fn to_bytes(&self, controller_address: Address) -> ArrayVec<u8, 384> {
|
||||
pub fn to_bytes(&self, controller_address: LegacyAddress) -> ArrayVec<u8, 384> {
|
||||
let mut v = ArrayVec::new();
|
||||
v.push(1); // version byte from v1 protocol
|
||||
v.push(0);
|
||||
v.push(7); // 7 qualifiers, big-endian 16-bit
|
||||
let _ = v.write_all(&self.v1_proto_get_qualifier_bytes());
|
||||
let _ = v.write_all(controller_address.as_bytes_v1());
|
||||
let _ = v.write_all(controller_address.as_bytes());
|
||||
let _ = v.write_all(self.signature.as_bytes());
|
||||
v
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ impl CertificateOfMembership {
|
|||
network_id: NetworkId::from_u64(network_id).ok_or(InvalidParameterError("invalid network ID"))?,
|
||||
timestamp,
|
||||
max_delta,
|
||||
issued_to: Address::from_u64_v1(issued_to).ok_or(InvalidParameterError("invalid issued to address"))?,
|
||||
issued_to: LegacyAddress::from_u64(issued_to).ok_or(InvalidParameterError("invalid issued to address"))?,
|
||||
issued_to_fingerprint: Blob::from(v1_fingerprint),
|
||||
signature: {
|
||||
let mut s = ArrayVec::new();
|
||||
|
|
|
@ -2,7 +2,7 @@ use std::collections::HashSet;
|
|||
use std::io::Write;
|
||||
|
||||
use crate::vl1::identity::{Identity, IdentitySecret};
|
||||
use crate::vl1::{Address, InetAddress, MAC};
|
||||
use crate::vl1::{InetAddress, LegacyAddress, MAC};
|
||||
use crate::vl2::NetworkId;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
@ -33,13 +33,13 @@ pub struct CertificateOfOwnership {
|
|||
pub network_id: NetworkId,
|
||||
pub timestamp: i64,
|
||||
pub things: HashSet<Thing>,
|
||||
pub issued_to: Address,
|
||||
pub issued_to: LegacyAddress,
|
||||
pub signature: ArrayVec<u8, { Identity::MAX_SIGNATURE_SIZE }>,
|
||||
}
|
||||
|
||||
impl CertificateOfOwnership {
|
||||
/// Create a new empty and unsigned certificate.
|
||||
pub fn new(network_id: NetworkId, timestamp: i64, issued_to: Address) -> Self {
|
||||
pub fn new(network_id: NetworkId, timestamp: i64, issued_to: LegacyAddress) -> Self {
|
||||
Self {
|
||||
network_id,
|
||||
timestamp,
|
||||
|
@ -63,7 +63,7 @@ impl CertificateOfOwnership {
|
|||
let _ = self.things.insert(Thing::Mac(mac));
|
||||
}
|
||||
|
||||
fn internal_to_bytes(&self, for_sign: bool, signed_by: &Address) -> Option<Vec<u8>> {
|
||||
fn internal_to_bytes(&self, for_sign: bool, signed_by: LegacyAddress) -> Option<Vec<u8>> {
|
||||
if self.things.len() > 0xffff {
|
||||
return None;
|
||||
}
|
||||
|
@ -94,8 +94,8 @@ impl CertificateOfOwnership {
|
|||
}
|
||||
}
|
||||
}
|
||||
let _ = v.write_all(self.issued_to.as_bytes_v1());
|
||||
let _ = v.write_all(signed_by.as_bytes_v1());
|
||||
let _ = v.write_all(self.issued_to.as_bytes());
|
||||
let _ = v.write_all(signed_by.as_bytes());
|
||||
if for_sign {
|
||||
v.push(0);
|
||||
v.push(0);
|
||||
|
@ -112,7 +112,7 @@ impl CertificateOfOwnership {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_bytes(&self, signed_by: &Address) -> Option<Vec<u8>> {
|
||||
pub fn to_bytes(&self, signed_by: LegacyAddress) -> Option<Vec<u8>> {
|
||||
self.internal_to_bytes(false, signed_by)
|
||||
}
|
||||
|
||||
|
@ -156,7 +156,7 @@ impl CertificateOfOwnership {
|
|||
network_id: NetworkId::from_u64(network_id).ok_or(InvalidParameterError("invalid network ID"))?,
|
||||
timestamp,
|
||||
things,
|
||||
issued_to: Address::from_bytes_v1(&b[..5]).ok_or(InvalidParameterError("invalid address"))?,
|
||||
issued_to: LegacyAddress::from_bytes(&b[..5]).ok_or(InvalidParameterError("invalid address"))?,
|
||||
signature: {
|
||||
let mut s = ArrayVec::new();
|
||||
s.push_slice(&b[13..109]);
|
||||
|
@ -168,8 +168,8 @@ impl CertificateOfOwnership {
|
|||
}
|
||||
|
||||
/// Sign certificate of ownership for use by V1 nodes.
|
||||
pub fn sign(&mut self, issuer_address: &Address, issuer: &IdentitySecret, issued_to: &Identity) -> bool {
|
||||
self.issued_to = issued_to.address.clone();
|
||||
pub fn sign(&mut self, issuer_address: LegacyAddress, issuer: &IdentitySecret, issued_to: &Identity) -> bool {
|
||||
self.issued_to = issued_to.address.legacy_address();
|
||||
if let Some(to_sign) = self.internal_to_bytes(true, issuer_address) {
|
||||
self.signature = issuer.sign(&to_sign.as_slice());
|
||||
return true;
|
||||
|
|
|
@ -175,7 +175,7 @@ impl NetworkConfig {
|
|||
proto_v1_field_name::network_config::CERTIFICATE_OF_MEMBERSHIP,
|
||||
v1cred
|
||||
.certificate_of_membership
|
||||
.to_bytes(self.network_id.network_controller())
|
||||
.to_bytes(self.network_id.network_controller().legacy_address())
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
);
|
||||
|
@ -183,7 +183,7 @@ impl NetworkConfig {
|
|||
if !v1cred.certificates_of_ownership.is_empty() {
|
||||
let mut certs = Vec::with_capacity(v1cred.certificates_of_ownership.len() * 256);
|
||||
for c in v1cred.certificates_of_ownership.iter() {
|
||||
let _ = certs.write_all(c.to_bytes(&controller_identity.address)?.as_slice());
|
||||
let _ = certs.write_all(c.to_bytes(controller_identity.address.legacy_address())?.as_slice());
|
||||
}
|
||||
d.set_bytes(proto_v1_field_name::network_config::CERTIFICATES_OF_OWNERSHIP, certs);
|
||||
}
|
||||
|
@ -191,7 +191,7 @@ impl NetworkConfig {
|
|||
if !v1cred.tags.is_empty() {
|
||||
let mut tags = Vec::with_capacity(v1cred.tags.len() * 256);
|
||||
for (_, t) in v1cred.tags.iter() {
|
||||
let _ = tags.write_all(t.to_bytes(&controller_identity.address).as_ref());
|
||||
let _ = tags.write_all(t.to_bytes(controller_identity.address.legacy_address()).as_ref());
|
||||
}
|
||||
d.set_bytes(proto_v1_field_name::network_config::TAGS, tags);
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ use zerotier_utils::arrayvec::ArrayVec;
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::vl1::identity::IdentitySecret;
|
||||
use crate::vl1::Address;
|
||||
use crate::vl1::LegacyAddress;
|
||||
use crate::vl2::v1::CredentialType;
|
||||
use crate::vl2::NetworkId;
|
||||
|
||||
|
@ -14,8 +14,8 @@ use crate::vl2::NetworkId;
|
|||
pub struct Revocation {
|
||||
pub network_id: NetworkId,
|
||||
pub threshold: i64,
|
||||
pub target: Address,
|
||||
pub issued_to: Address,
|
||||
pub target: LegacyAddress,
|
||||
pub issued_to: LegacyAddress,
|
||||
pub signature: ArrayVec<u8, 96>,
|
||||
pub fast_propagate: bool,
|
||||
}
|
||||
|
@ -24,9 +24,9 @@ impl Revocation {
|
|||
pub fn new(
|
||||
network_id: NetworkId,
|
||||
threshold: i64,
|
||||
target: Address,
|
||||
issued_to: Address,
|
||||
signer_address: &Address,
|
||||
target: LegacyAddress,
|
||||
issued_to: LegacyAddress,
|
||||
signer_address: LegacyAddress,
|
||||
signer: &IdentitySecret,
|
||||
fast_propagate: bool,
|
||||
) -> Self {
|
||||
|
@ -42,20 +42,20 @@ impl Revocation {
|
|||
r
|
||||
}
|
||||
|
||||
fn internal_to_bytes(&self, for_sign: bool, signed_by: &Address) -> ArrayVec<u8, 256> {
|
||||
fn internal_to_bytes(&self, for_sign: bool, signed_by: LegacyAddress) -> ArrayVec<u8, 256> {
|
||||
let mut v = ArrayVec::new();
|
||||
if for_sign {
|
||||
let _ = v.write_all(&[0x7f; 8]);
|
||||
}
|
||||
|
||||
let _ = v.write_all(&[0; 4]);
|
||||
let _ = v.write_all(&((self.threshold as u32) ^ (self.target.as_u64_v1() as u32)).to_be_bytes()); // ID only used in V1, arbitrary
|
||||
let _ = v.write_all(&((self.threshold as u32) ^ (self.target.to_u64() as u32)).to_be_bytes()); // ID only used in V1, arbitrary
|
||||
let _ = v.write_all(&self.network_id.to_bytes());
|
||||
let _ = v.write_all(&[0; 8]);
|
||||
let _ = v.write_all(&self.threshold.to_be_bytes());
|
||||
let _ = v.write_all(&(self.fast_propagate as u64).to_be_bytes()); // 0x1 is the flag for this
|
||||
let _ = v.write_all(self.target.as_bytes_v1());
|
||||
let _ = v.write_all(signed_by.as_bytes_v1());
|
||||
let _ = v.write_all(self.target.as_bytes());
|
||||
let _ = v.write_all(signed_by.as_bytes());
|
||||
v.push(CredentialType::CertificateOfMembership as u8);
|
||||
|
||||
if for_sign {
|
||||
|
@ -71,7 +71,7 @@ impl Revocation {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn v1_proto_to_bytes(&self, controller_address: &Address) -> ArrayVec<u8, 256> {
|
||||
pub fn v1_proto_to_bytes(&self, controller_address: LegacyAddress) -> ArrayVec<u8, 256> {
|
||||
self.internal_to_bytes(false, controller_address)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::io::Write;
|
||||
|
||||
use crate::vl1::identity::{Identity, IdentitySecret};
|
||||
use crate::vl1::Address;
|
||||
use crate::vl1::LegacyAddress;
|
||||
use crate::vl2::NetworkId;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
@ -14,7 +14,7 @@ use zerotier_utils::error::InvalidParameterError;
|
|||
pub struct Tag {
|
||||
pub network_id: NetworkId,
|
||||
pub timestamp: i64,
|
||||
pub issued_to: Address,
|
||||
pub issued_to: LegacyAddress,
|
||||
pub id: u32,
|
||||
pub value: u32,
|
||||
pub signature: Blob<96>,
|
||||
|
@ -24,7 +24,7 @@ impl Tag {
|
|||
pub fn new(
|
||||
id: u32,
|
||||
value: u32,
|
||||
issuer_address: &Address,
|
||||
issuer_address: LegacyAddress,
|
||||
issuer: &IdentitySecret,
|
||||
network_id: NetworkId,
|
||||
issued_to: &Identity,
|
||||
|
@ -33,7 +33,7 @@ impl Tag {
|
|||
let mut tag = Self {
|
||||
network_id,
|
||||
timestamp,
|
||||
issued_to: issued_to.address.clone(),
|
||||
issued_to: issued_to.address.legacy_address(),
|
||||
id,
|
||||
value,
|
||||
signature: Blob::default(),
|
||||
|
@ -43,7 +43,7 @@ impl Tag {
|
|||
tag
|
||||
}
|
||||
|
||||
fn internal_to_bytes(&self, for_sign: bool, signed_by: &Address) -> ArrayVec<u8, 256> {
|
||||
fn internal_to_bytes(&self, for_sign: bool, signed_by: LegacyAddress) -> ArrayVec<u8, 256> {
|
||||
let mut v = ArrayVec::new();
|
||||
if for_sign {
|
||||
let _ = v.write_all(&[0x7f; 8]);
|
||||
|
@ -52,8 +52,8 @@ impl Tag {
|
|||
let _ = v.write_all(&self.timestamp.to_be_bytes());
|
||||
let _ = v.write_all(&self.id.to_be_bytes());
|
||||
let _ = v.write_all(&self.value.to_be_bytes());
|
||||
let _ = v.write_all(self.issued_to.as_bytes_v1());
|
||||
let _ = v.write_all(signed_by.as_bytes_v1());
|
||||
let _ = v.write_all(self.issued_to.as_bytes());
|
||||
let _ = v.write_all(signed_by.as_bytes());
|
||||
if !for_sign {
|
||||
v.push(1);
|
||||
v.push(0);
|
||||
|
@ -69,7 +69,7 @@ impl Tag {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_bytes(&self, signed_by: &Address) -> ArrayVec<u8, 256> {
|
||||
pub fn to_bytes(&self, signed_by: LegacyAddress) -> ArrayVec<u8, 256> {
|
||||
self.internal_to_bytes(false, signed_by)
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,7 @@ impl Tag {
|
|||
Self {
|
||||
network_id: NetworkId::from_bytes(&b[0..8]).ok_or(InvalidParameterError("invalid network ID"))?,
|
||||
timestamp: i64::from_be_bytes(b[8..16].try_into().unwrap()),
|
||||
issued_to: Address::from_bytes_v1(&b[24..29]).ok_or(InvalidParameterError("invalid address"))?,
|
||||
issued_to: LegacyAddress::from_bytes(&b[24..29]).ok_or(InvalidParameterError("invalid address"))?,
|
||||
id: u32::from_be_bytes(b[16..20].try_into().unwrap()),
|
||||
value: u32::from_be_bytes(b[20..24].try_into().unwrap()),
|
||||
signature: {
|
||||
|
|
|
@ -22,6 +22,7 @@ pub mod io;
|
|||
pub mod json;
|
||||
pub mod marshalable;
|
||||
pub mod memory;
|
||||
pub mod oneormore;
|
||||
pub mod pool;
|
||||
pub mod proquint;
|
||||
#[cfg(feature = "tokio")]
|
||||
|
|
|
@ -15,6 +15,9 @@ use std::mem::{needs_drop, size_of, MaybeUninit};
|
|||
#[allow(unused_imports)]
|
||||
use std::ptr::copy_nonoverlapping;
|
||||
|
||||
/// Implement this trait to mark a struct as safe to cast from a byte array.
|
||||
pub unsafe trait FlatBuffer: Sized {}
|
||||
|
||||
/// Store a raw object to a byte array (for architectures known not to care about unaligned access).
|
||||
/// This will panic if the slice is too small or the object requires drop.
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64", target_arch = "aarch64", target_arch = "powerpc64"))]
|
||||
|
@ -79,7 +82,7 @@ pub fn array_chunks_exact<T, const S: usize>(a: &[T]) -> impl Iterator<Item = &[
|
|||
/// Obtain a view into an array cast as another array.
|
||||
/// This will panic if the template parameters would result in out of bounds access.
|
||||
#[inline(always)]
|
||||
pub fn array_range<T: Copy, const S: usize, const START: usize, const LEN: usize>(a: &[T; S]) -> &[T; LEN] {
|
||||
pub fn array_range<T, const S: usize, const START: usize, const LEN: usize>(a: &[T; S]) -> &[T; LEN] {
|
||||
assert!((START + LEN) <= S);
|
||||
unsafe { &*a.as_ptr().add(START).cast::<[T; LEN]>() }
|
||||
}
|
||||
|
@ -108,3 +111,11 @@ pub fn to_byte_array<T: Copy, const S: usize>(o: T) -> [u8; S] {
|
|||
assert!(!std::mem::needs_drop::<T>());
|
||||
unsafe { *(&o as *const T).cast() }
|
||||
}
|
||||
|
||||
/// Cast a byte slice into a flat struct.
|
||||
/// This will panic if the slice is too small or the struct requires drop.
|
||||
pub fn cast_to_struct<T: FlatBuffer>(b: &[u8]) -> &T {
|
||||
assert!(b.len() >= size_of::<T>());
|
||||
assert!(!std::mem::needs_drop::<T>());
|
||||
unsafe { &*b.as_ptr().cast() }
|
||||
}
|
||||
|
|
|
@ -1,237 +0,0 @@
|
|||
Name: zerotier-one
|
||||
Version: 1.10.2
|
||||
Release: 1%{?dist}
|
||||
Summary: ZeroTier network virtualization service
|
||||
|
||||
License: ZeroTier BSL 1.1
|
||||
URL: https://www.zerotier.com
|
||||
|
||||
# Fedora
|
||||
|
||||
%if "%{?dist}" == ".fc35"
|
||||
BuildRequires: systemd clang openssl openssl-devel
|
||||
Requires: systemd openssl
|
||||
Requires(pre): /usr/sbin/useradd, /usr/bin/getent
|
||||
%endif
|
||||
|
||||
%if "%{?dist}" == ".fc36"
|
||||
BuildRequires: systemd clang openssl1.1 openssl1.1-devel
|
||||
Requires: systemd openssl1.1
|
||||
Requires(pre): /usr/sbin/useradd, /usr/bin/getent
|
||||
%endif
|
||||
|
||||
%if "%{?dist}" == ".fc37"
|
||||
BuildRequires: systemd clang openssl1.1 openssl1.1-devel
|
||||
Requires: systemd openssl1.1
|
||||
Requires(pre): /usr/sbin/useradd, /usr/bin/getent
|
||||
%endif
|
||||
|
||||
# RHEL
|
||||
|
||||
%if "%{?dist}" == ".el6"
|
||||
Requires: chkconfig
|
||||
Requires(pre): /usr/sbin/useradd, /usr/bin/getent
|
||||
%endif
|
||||
|
||||
%if "%{?dist}" == ".el7"
|
||||
BuildRequires: systemd openssl-devel
|
||||
Requires: systemd openssl
|
||||
Requires(pre): /usr/sbin/useradd, /usr/bin/getent
|
||||
%endif
|
||||
|
||||
%if "%{?dist}" == ".el8"
|
||||
BuildRequires: systemd openssl-devel
|
||||
Requires: systemd openssl
|
||||
Requires(pre): /usr/sbin/useradd, /usr/bin/getent
|
||||
%endif
|
||||
|
||||
%if "%{?dist}" == ".el9"
|
||||
BuildRequires: systemd openssl-devel
|
||||
Requires: systemd openssl
|
||||
Requires(pre): /usr/sbin/useradd, /usr/bin/getent
|
||||
%endif
|
||||
|
||||
# Amazon
|
||||
|
||||
%if "%{?dist}" == ".amzn2"
|
||||
BuildRequires: systemd openssl-devel
|
||||
Requires: systemd openssl
|
||||
Requires(pre): /usr/sbin/useradd, /usr/bin/getent
|
||||
%endif
|
||||
|
||||
%if "%{?dist}" == ".amzn2022"
|
||||
BuildRequires: systemd openssl-devel
|
||||
Requires: systemd openssl
|
||||
Requires(pre): /usr/sbin/useradd, /usr/bin/getent
|
||||
%endif
|
||||
|
||||
%description
|
||||
ZeroTier is a software defined networking layer for Earth.
|
||||
|
||||
It can be used for on-premise network virtualization, as a peer to peer VPN
|
||||
for mobile teams, for hybrid or multi-data-center cloud deployments, or just
|
||||
about anywhere else secure software defined virtual networking is useful.
|
||||
|
||||
This is our OS-level client service. It allows Mac, Linux, Windows,
|
||||
FreeBSD, and soon other types of clients to join ZeroTier virtual networks
|
||||
like conventional VPNs or VLANs. It can run on native systems, VMs, or
|
||||
containers (Docker, OpenVZ, etc.).
|
||||
|
||||
%prep
|
||||
%if "%{?dist}" != ".el6"
|
||||
rm -rf BUILD BUILDROOT RPMS SRPMS SOURCES
|
||||
ln -s %{getenv:PWD} %{name}-%{version}
|
||||
mkdir -p SOURCES
|
||||
tar --exclude=%{name}-%{version}/.git --exclude=%{name}-%{version}/%{name}-%{version} -czf SOURCES/%{name}-%{version}.tar.gz %{name}-%{version}/*
|
||||
rm -f %{name}-%{version}
|
||||
cp -a %{getenv:PWD}/* .
|
||||
%endif
|
||||
|
||||
%build
|
||||
%if "%{?dist}" != ".el6"
|
||||
make ZT_USE_MINIUPNPC=1 %{?_smp_mflags} one
|
||||
%endif
|
||||
|
||||
%pre
|
||||
/usr/bin/getent passwd zerotier-one || /usr/sbin/useradd -r -d /var/lib/zerotier-one -s /sbin/nologin zerotier-one
|
||||
|
||||
%install
|
||||
%if "%{?dist}" != ".el6"
|
||||
make install DESTDIR=$RPM_BUILD_ROOT
|
||||
mkdir -p $RPM_BUILD_ROOT%{_unitdir}
|
||||
cp %{getenv:PWD}/debian/zerotier-one.service $RPM_BUILD_ROOT%{_unitdir}/%{name}.service
|
||||
%else
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
pushd %{getenv:PWD}
|
||||
make install DESTDIR=$RPM_BUILD_ROOT
|
||||
popd
|
||||
mkdir -p $RPM_BUILD_ROOT/etc/init.d
|
||||
cp %{getenv:PWD}/ext/installfiles/linux/zerotier-one.init.rhel6 $RPM_BUILD_ROOT/etc/init.d/zerotier-one
|
||||
chmod 0755 $RPM_BUILD_ROOT/etc/init.d/zerotier-one
|
||||
%endif
|
||||
|
||||
%files
|
||||
%{_sbindir}/*
|
||||
%{_mandir}/*
|
||||
%{_localstatedir}/*
|
||||
|
||||
%if 0%{?rhel} && 0%{?rhel} <= 6
|
||||
/etc/init.d/zerotier-one
|
||||
%else
|
||||
%{_unitdir}/%{name}.service
|
||||
%endif
|
||||
|
||||
%post
|
||||
%if ! 0%{?rhel} && 0%{?rhel} <= 6
|
||||
%systemd_post zerotier-one.service
|
||||
%endif
|
||||
|
||||
%preun
|
||||
%if ! 0%{?rhel} && 0%{?rhel} <= 6
|
||||
%systemd_preun zerotier-one.service
|
||||
%endif
|
||||
|
||||
%postun
|
||||
%if ! 0%{?rhel} && 0%{?rhel} <= 6
|
||||
%systemd_postun_with_restart zerotier-one.service
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Mon Oct 13 2022 Adam Ierymenko <adam.ierymenko@zerotier.com> - 1.10.2
|
||||
- see https://github.com/zerotier/ZeroTierOne for release notes
|
||||
|
||||
* Mon Jun 27 2022 Adam Ierymenko <adam.ierymenko@zerotier.com> - 1.10.1
|
||||
- see https://github.com/zerotier/ZeroTierOne for release notes
|
||||
|
||||
* Fri Jun 03 2022 Adam Ierymenko <adam.ierymenko@zerotier.com> - 1.10.0
|
||||
- see https://github.com/zerotier/ZeroTierOne for release notes
|
||||
|
||||
* Tue May 10 2022 Adam Ierymenko <adam.ierymenko@zerotier.com> - 1.8.10
|
||||
- see https://github.com/zerotier/ZeroTierOne for release notes
|
||||
|
||||
* Mon Apr 25 2022 Adam Ierymenko <adam.ierymenko@zerotier.com> - 1.8.9
|
||||
- see https://github.com/zerotier/ZeroTierOne for release notes
|
||||
|
||||
* Mon Apr 11 2022 Adam Ierymenko <adam.ierymenko@zerotier.com> - 1.8.8
|
||||
- see https://github.com/zerotier/ZeroTierOne for release notes
|
||||
|
||||
* Mon Mar 21 2022 Adam Ierymenko <adam.ierymenko@zerotier.com> - 1.8.7
|
||||
- see https://github.com/zerotier/ZeroTierOne for release notes
|
||||
|
||||
* Mon Mar 07 2022 Adam Ierymenko <adam.ierymenko@zerotier.com> - 1.8.6
|
||||
- see https://github.com/zerotier/ZeroTierOne for release notes
|
||||
|
||||
* Fri Dec 17 2021 Adam Ierymenko <adam.ierymenko@zerotier.com> - 1.8.5
|
||||
- see https://github.com/zerotier/ZeroTierOne for release notes
|
||||
|
||||
* Tue Nov 23 2021 Adam Ierymenko <adam.ierymenko@zerotier.com> - 1.8.4
|
||||
- see https://github.com/zerotier/ZeroTierOne for release notes
|
||||
|
||||
* Mon Nov 15 2021 Adam Ierymenko <adam.ierymenko@zerotier.com> - 1.8.3
|
||||
- see https://github.com/zerotier/ZeroTierOne for release notes
|
||||
|
||||
* Mon Nov 08 2021 Adam Ierymenko <adam.ierymenko@zerotier.com> - 1.8.2
|
||||
- see https://github.com/zerotier/ZeroTierOne for release notes
|
||||
|
||||
* Wed Oct 20 2021 Adam Ierymenko <adam.ierymenko@zerotier.com> - 1.8.1
|
||||
- see https://github.com/zerotier/ZeroTierOne for release notes
|
||||
|
||||
* Wed Sep 15 2021 Adam Ierymenko <adam.ierymenko@zerotier.com> - 1.8.0
|
||||
- see https://github.com/zerotier/ZeroTierOne for release notes
|
||||
|
||||
* Tue Apr 13 2021 Adam Ierymenko <adam.ierymenko@zerotier.com> - 1.6.5
|
||||
- see https://github.com/zerotier/ZeroTierOne for release notes
|
||||
|
||||
* Mon Feb 15 2021 Adam Ierymenko <adam.ierymenko@zerotier.com> - 1.6.4
|
||||
- see https://github.com/zerotier/ZeroTierOne for release notes
|
||||
|
||||
* Mon Nov 30 2020 Adam Ierymenko <adam.ierymenko@zerotier.com> - 1.6.2-0.1
|
||||
- see https://github.com/zerotier/ZeroTierOne for release notes
|
||||
|
||||
* Tue Nov 24 2020 Adam Ierymenko <adam.ierymenko@zerotier.com> - 1.6.1-0.1
|
||||
- see https://github.com/zerotier/ZeroTierOne for release notes
|
||||
|
||||
* Thu Nov 19 2020 Adam Ierymenko <adam.ierymenko@zerotier.com> - 1.6.0-0.1
|
||||
- see https://github.com/zerotier/ZeroTierOne for release notes
|
||||
|
||||
* Mon Oct 05 2020 Adam Ierymenko <adam.ierymenko@zerotier.com> - 1.6.0-beta1
|
||||
- see https://github.com/zerotier/ZeroTierOne for release notes
|
||||
|
||||
* Fri Aug 23 2019 Adam Ierymenko <adam.ierymenko@zerotier.com> - 1.4.4-0.1
|
||||
- see https://github.com/zerotier/ZeroTierOne for release notes
|
||||
|
||||
* Mon Jul 29 2019 Adam Ierymenko <adam.ierymenko@zerotier.com> - 1.4.0-0.1
|
||||
- see https://github.com/zerotier/ZeroTierOne for release notes
|
||||
|
||||
* Tue May 08 2018 Adam Ierymenko <adam.ierymenko@zerotier.com> - 1.2.10-0.1
|
||||
- see https://github.com/zerotier/ZeroTierOne for release notes
|
||||
|
||||
* Thu May 03 2018 Adam Ierymenko <adam.ierymenko@zerotier.com> - 1.2.8-0.1
|
||||
- see https://github.com/zerotier/ZeroTierOne for release notes
|
||||
|
||||
* Mon Apr 24 2017 Adam Ierymenko <adam.ierymenko@zerotier.com> - 1.2.2-0.1
|
||||
- see https://github.com/zerotier/ZeroTierOne for release notes
|
||||
|
||||
* Fri Mar 17 2017 Adam Ierymenko <adam.ierymenko@zerotier.com> - 1.2.2-0.1
|
||||
- see https://github.com/zerotier/ZeroTierOne for release notes
|
||||
|
||||
* Tue Mar 14 2017 Adam Ierymenko <adam.ierymenko@zerotier.com> - 1.2.0-0.1
|
||||
- see https://github.com/zerotier/ZeroTierOne for release notes
|
||||
|
||||
* Tue Jul 12 2016 Adam Ierymenko <adam.ierymenko@zerotier.com> - 1.1.10-0.1
|
||||
- see https://github.com/zerotier/ZeroTierOne for release notes
|
||||
|
||||
* Fri Jul 08 2016 Adam Ierymenko <adam.ierymenko@zerotier.com> - 1.1.8-0.1
|
||||
- see https://github.com/zerotier/ZeroTierOne for release notes
|
||||
|
||||
* Sat Jun 25 2016 Adam Ierymenko <adam.ierymenko@zerotier.com> - 1.1.6-0.1
|
||||
- now builds on CentOS 6 as well as newer distros, and some cleanup
|
||||
|
||||
* Wed Jun 08 2016 François Kooman <fkooman@tuxed.net> - 1.1.5-0.3
|
||||
- include systemd unit file
|
||||
|
||||
* Wed Jun 08 2016 François Kooman <fkooman@tuxed.net> - 1.1.5-0.2
|
||||
- add libnatpmp as (build)dependency
|
||||
|
||||
* Wed Jun 08 2016 François Kooman <fkooman@tuxed.net> - 1.1.5-0.1
|
||||
- initial package
|
Loading…
Add table
Reference in a new issue