Compare commits

..

No commits in common. "dev" and "1.4.2" have entirely different histories.
dev ... 1.4.2

1561 changed files with 36631 additions and 330349 deletions

View file

@ -1,75 +0,0 @@
---
BasedOnStyle: LLVM
BreakBeforeBraces: Stroustrup
IndentWidth: 4
TabWidth: 4
AlignAfterOpenBracket: AlwaysBreak
AlignConsecutiveMacros: 'true'
AlignConsecutiveAssignments: 'false'
AlignConsecutiveDeclarations: 'false'
AlignEscapedNewlines: Right
AlignOperands: 'true'
AlignTrailingComments: 'true'
AllowAllArgumentsOnNextLine: 'false'
AllowAllConstructorInitializersOnNextLine: 'false'
AllowAllParametersOfDeclarationOnNextLine: 'false'
AllowShortBlocksOnASingleLine: 'true'
AllowShortCaseLabelsOnASingleLine: 'false'
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: Never
AlwaysBreakAfterReturnType: None
BinPackArguments: 'false'
BinPackParameters: 'false'
BreakBeforeBinaryOperators: NonAssignment
BreakBeforeTernaryOperators: 'true'
BreakConstructorInitializers: BeforeComma
BreakInheritanceList: BeforeComma
CompactNamespaces: 'false'
ConstructorInitializerAllOnOneLineOrOnePerLine: 'true'
ConstructorInitializerIndentWidth: '4'
ContinuationIndentWidth: '4'
Cpp11BracedListStyle: 'false'
FixNamespaceComments: 'true'
IncludeBlocks: Regroup
IndentCaseLabels: 'true'
IndentPPDirectives: None
IndentWrappedFunctionNames: 'false'
KeepEmptyLinesAtTheStartOfBlocks: 'false'
MaxEmptyLinesToKeep: '1'
NamespaceIndentation: None
PointerAlignment: Left
ReflowComments: 'true'
SortIncludes: 'true'
SortUsingDeclarations: 'true'
SpaceAfterCStyleCast: 'false'
SpaceAfterLogicalNot: 'true'
SpaceAfterTemplateKeyword: 'true'
SpaceBeforeAssignmentOperators: 'true'
SpaceBeforeCpp11BracedList: 'true'
SpaceBeforeCtorInitializerColon: 'true'
SpaceBeforeInheritanceColon: 'true'
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: 'true'
SpaceInEmptyParentheses: 'false'
SpacesBeforeTrailingComments: '3'
SpacesInAngles: 'false'
SpacesInCStyleCastParentheses: 'false'
SpacesInContainerLiterals: 'true'
SpacesInParentheses: 'false'
SpacesInSquareBrackets: 'false'
UseTab: 'Always'
---
Language: Cpp
Standard: Cpp03
ColumnLimit: '240'
---
Language: ObjC
ColumnLimit: '240'
---
Language: Java
ColumnLimit: '240'
---
Language: CSharp
ColumnLimit: '240'
...

View file

@ -1,6 +0,0 @@
CompileFlags:
Add:
- "-std=c++17"
- "-I../ext"
- "-I../ext/prometheus-cpp-lite-1.0/core/include"
- "-I../ext/prometheus-cpp-lite-1.0/simpleapi/include"

View file

@ -1,2 +0,0 @@
.git/
workspace/

View file

@ -1,256 +0,0 @@
//
// tweakables
//
local registry = "084037375216.dkr.ecr.us-east-2.amazonaws.com";
local build_channel = "zerotier-builds";
local release_channel = "zerotier-releases";
local targets = [
{ "os": "linux", distro: "redhat", "name": "el9", "isas": [ "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "tag", "custom" ] },
{ "os": "linux", distro: "redhat", "name": "el8", "isas": [ "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "tag" ] },
{ "os": "linux", distro: "redhat", "name": "el7", "isas": [ "386", "amd64", "ppc64le"], "events": [ "tag" ] },
{ "os": "linux", distro: "amazon", "name": "amzn2", "isas": [ "amd64", "arm64" ], "events": [ "tag" ] },
{ "os": "linux", distro: "amazon", "name": "amzn2022", "isas": [ "amd64", "arm64" ], "events": [ "tag" ] },
{ "os": "linux", distro: "fedora", "name": "fc38", "isas": [ "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "tag" ] },
{ "os": "linux", distro: "fedora", "name": "fc37", "isas": [ "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "tag" ] },
{ "os": "linux", distro: "fedora", "name": "fc36", "isas": [ "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "tag" ] },
{ "os": "linux", distro: "ubuntu", "name": "jammy", "isas": [ "armv7", "amd64", "arm64", "ppc64le", "s390x", "riscv64" ], "events": [ "tag" ] },
{ "os": "linux", distro: "ubuntu", "name": "focal", "isas": [ "armv7", "amd64", "arm64", "ppc64le", "s390x", "riscv64" ], "events": [ "tag" ] },
{ "os": "linux", distro: "ubuntu", "name": "bionic", "isas": [ "386", "armv7", "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "tag" ] },
{ "os": "linux", distro: "ubuntu", "name": "xenial", "isas": [ "386", "armv7", "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "tag" ] },
{ "os": "linux", distro: "ubuntu", "name": "trusty", "isas": [ "386", "armv7", "amd64", "arm64" ], "events": [ "tag" ] },
{ "os": "linux", distro: "debian", "name": "bookworm", "isas": [ "386", "armv7", "amd64", "arm64", "mips64le", "ppc64le", "s390x" ], "events": [ "tag"] },
{ "os": "linux", distro: "debian", "name": "bullseye", "isas": [ "386", "armv7", "amd64", "arm64", "mips64le", "ppc64le", "s390x" ], "events": [ "push", "tag", "custom" ] },
{ "os": "linux", distro: "debian", "name": "buster", "isas": [ "386", "armv7", "amd64", "arm64" ], "events": [ "tag" ] },
{ "os": "linux", distro: "debian", "name": "stretch", "isas": [ "386", "armv7", "amd64", "arm64" ], "events": [ "tag" ] },
{ "os": "linux", distro: "debian", "name": "jessie", "isas": [ "386", "armv7", "amd64" ], "events": [ "tag" ] },
// { "os": "windows", distro: "windows", "name": "windows", "isas": [ "amd64" ], "events": [ "push", "tag", "custom" ] },
// { "os": "darwin", distro: "darwin", "name": "darwin", "isas": [ "amd64" ], "events": [ "push", "tag", "custom" ] },
];
local less_targets = [
{ "os": "linux", distro: "redhat", "name": "el9", "isas": [ "amd64", "arm64" ], "events": [ "push", "tag", "custom" ] },
{ "os": "linux", distro: "redhat", "name": "el8", "isas": [ "amd64", "arm64" ], "events": [ "push", "tag", "custom" ] },
{ "os": "linux", distro: "ubuntu", "name": "jammy", "isas": [ "armv7", "amd64", "arm64" ], "events": [ "push", "tag", "custom" ] },
{ "os": "linux", distro: "ubuntu", "name": "focal", "isas": [ "armv7", "amd64", "arm64" ], "events": [ "push", "tag", "custom" ] },
];
local native_targets = [
{ "os": "linux", distro: "debian", "name": "bullseye", "isas": [ "386", "armv7", "amd64", "arm64" ], "events": [ "push", "tag", "custom" ] },
];
local master_targets = [
//
// copypasta from here
//
{ "os": "linux", distro: "redhat", "name": "el9", "isas": [ "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "push", "tag", "custom" ] },
{ "os": "linux", distro: "redhat", "name": "el8", "isas": [ "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "push", "tag", "custom" ] },
{ "os": "linux", distro: "redhat", "name": "el7", "isas": [ "386", "amd64", "ppc64le"], "events": [ "push", "tag", "custom" ] },
{ "os": "linux", distro: "amazon", "name": "amzn2", "isas": [ "amd64", "arm64" ], "events": [ "push", "tag", "custom" ] },
{ "os": "linux", distro: "amazon", "name": "amzn2022", "isas": [ "amd64", "arm64" ], "events": [ "push", "tag", "custom" ] },
{ "os": "linux", distro: "fedora", "name": "fc38", "isas": [ "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "push", "tag", "custom" ] },
{ "os": "linux", distro: "fedora", "name": "fc37", "isas": [ "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "push", "tag", "custom" ] },
{ "os": "linux", distro: "fedora", "name": "fc36", "isas": [ "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "push", "tag", "custom" ] },
{ "os": "linux", distro: "ubuntu", "name": "jammy", "isas": [ "armv7", "amd64", "arm64", "ppc64le", "s390x", "riscv64" ], "events": [ "push", "tag", "custom" ] },
{ "os": "linux", distro: "ubuntu", "name": "focal", "isas": [ "armv7", "amd64", "arm64", "ppc64le", "s390x", "riscv64" ], "events": [ "push", "tag", "custom" ] },
{ "os": "linux", distro: "ubuntu", "name": "bionic", "isas": [ "386", "armv7", "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "push", "tag", "custom" ] },
{ "os": "linux", distro: "ubuntu", "name": "xenial", "isas": [ "386", "armv7", "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "push", "tag", "custom" ] },
{ "os": "linux", distro: "ubuntu", "name": "trusty", "isas": [ "386", "armv7", "amd64", "arm64" ], "events": [ "push", "tag", "custom" ] },
{ "os": "linux", distro: "debian", "name": "sid", "isas": [ "386", "armv7", "amd64", "arm64", "mips64le", "ppc64le", "s390x", "riscv64" ], "events": [ "push", "tag", "custom" ] },
{ "os": "linux", distro: "debian", "name": "bookworm", "isas": [ "386", "armv7", "amd64", "arm64", "mips64le", "ppc64le", "s390x" ], "events": [ "push", "tag", "custom" ] },
{ "os": "linux", distro: "debian", "name": "bullseye", "isas": [ "386", "armv7", "amd64", "arm64", "mips64le", "ppc64le", "s390x" ], "events": [ "push", "tag", "custom" ] },
{ "os": "linux", distro: "debian", "name": "buster", "isas": [ "386", "armv7", "amd64", "arm64" ], "events": [ "push", "tag", "custom" ] },
{ "os": "linux", distro: "debian", "name": "stretch", "isas": [ "386", "armv7", "amd64", "arm64" ], "events": [ "push", "tag", "custom" ] },
{ "os": "linux", distro: "debian", "name": "jessie", "isas": [ "386", "armv7", "amd64" ], "events": [ "push", "tag", "custom" ] },
{ "os": "windows", distro: "windows", "name": "win2k22", "isas": [ "amd64" ], "events": [ "push", "tag", "custom" ] }
];
//
// functions
//
local pipeline_type(os) = if os == "darwin" then "exec" else "docker";
local builder_image(os) = if os == "linux" then registry + "/honda-builder" else registry + "/windows-builder";
local tester_image(os) = if os == "linux" then registry + "/honda-builder" else registry + "/windows-tester";
local build_step_volumes(os) = if os == "linux" then [ { name: "zerotier-builds", path: "/zerotier-builds" } ] else [];
local release_step_volumes(os) = if os == "linux" then [ { name: "zerotier-releases", path: "/zerotier-releases" } ] else [];
local host_volumes(os) = if os == "linux" then [
{ name: "zerotier-builds", host: { path: "/zerotier-builds" } },
{ name: "zerotier-releases", host: { path: "/zerotier-releases" } },
] else [];
local index_image(distro) =
if distro == "debian" || distro == "ubuntu" then
registry + "/apt-builder"
else if distro == "redhat" || distro == "fedora" || distro == "amazon" then
registry + "/dnf-builder"
else if distro == "windows" then
registry + "/msi-builder"
;
local copy_commands(os, distro, name, isa, version) =
if os == "linux" then [
std.join(" ", [ "./ci/scripts/publish.sh", name, distro, isa, version, "${DRONE_BUILD_EVENT}" ])
]
else if os == "windows" then [
"C:\\scripts\\fix-ec2-metadata.ps1",
"Get-ChildItem windows",
// "aws s3 cp windows\\bytey-SetupFiles\\bytey.msi s3://zerotier-builds/windows/" + version + "/bytey.msi",
] else if os == "darwin" then [
"echo hello"
]
;
local index_commands(os, channel, distro, name, isas) =
if os == "linux" then
[ "/usr/local/bin/index " + channel + " " + distro + " " + name + " " + std.join(" ", isas) ]
else if os == "windows" then
[ "Get-ChildItem -Recurse windows" ]
;
local build_commands(os, distro, name, isa, version) =
if os == "linux" then
[ std.join(" ", [ "./ci/scripts/build.sh", name, distro, isa, version, "${DRONE_BUILD_EVENT}" ]) ]
else
if os == "windows" then
[ "windows/build.ps1", "windows/package.ps1" ]
else
if os == "darwin" then
[ "whoami" ]
;
local test_commands(os, distro, name, isa, version) =
if os == "linux" then
[ std.join(" ", [ "./ci/scripts/test.sh", name, distro, isa, version, "${DRONE_BUILD_EVENT}" ]) ]
else
if os == "windows" then
[ "windows/testpackage.ps1 " + version ]
;
//
// render
//
local Build(os, distro, name, isa, events) = {
"kind": "pipeline",
"type": pipeline_type(os),
"name": std.join(" ", [ name, isa, "build" ]),
"pull": "always",
"clone": { "depth": 1, [ if os == "darwin" then "disable" ]: true },
"steps": [
{
"name": "build",
"image": builder_image(os),
"commands": build_commands(os, distro, name, isa, "100.0.0+${DRONE_COMMIT_SHA:0:8}"),
"when": { "event": [ "push" ]},
},
{
"name": "release",
"image": builder_image(os),
"commands": build_commands(os, distro, name, isa, "${DRONE_TAG}"),
"when": { "event": [ "tag" ]},
},
{
"name": "copy build",
"image": builder_image(os),
"commands": copy_commands(os, distro, name, isa, "100.0.0+${DRONE_COMMIT_SHA:0:8}"),
"volumes": build_step_volumes(os),
"when": { "event": [ "push" ]},
},
{
"name": "copy relase",
"image": builder_image(os),
"commands": copy_commands(os, distro, name, isa, "${DRONE_TAG}"),
"volumes": release_step_volumes(os),
"when": { "event": [ "tag" ]},
},
],
"volumes": host_volumes(os),
"platform": { "os": os, [ if isa == "arm64" || isa == "armv7" then "arch" ]: "arm64" },
"trigger": { "event": events }
};
local Test(os, distro, name, isa, events) = {
"kind": "pipeline",
"type": pipeline_type(os),
"name": std.join(" ", [ name, isa, "test"]),
"pull": "always",
"clone": { "depth": 1 },
"steps": [
{
"name": "test build",
"image": tester_image(os),
"volumes": build_step_volumes(os),
"commands": test_commands(os, distro, name, isa, "100.0.0+${DRONE_COMMIT_SHA:0:8}"),
"when": { "event": [ "push" ]},
},
{
"name": "test release",
"image": tester_image(os),
"volumes": release_step_volumes(os),
"commands": test_commands(os, distro, name, isa, "${DRONE_TAG}"),
"when": { "event": [ "tag" ]},
},
],
"volumes": host_volumes(os),
"platform": { "os": os, [ if isa == "arm64" || isa == "armv7" then "arch" ]: "arm64" },
"depends_on": [ std.join(" ", [ name, "index" ]) ],
"trigger": { "event": events }
};
local Index(p) = {
"kind": "pipeline",
"type": pipeline_type(p.os),
"name": std.join(" ", [ p.name, "index" ]),
"pull": "always",
"clone": { "depth": 1 },
"steps": [
{
"name": "index build",
"image": index_image(p.distro),
"commands": index_commands(p.os, "zerotier-builds", p.distro, p.name, p.isas),
"volumes": build_step_volumes(p.os),
"environment":{ "GPG_PRIVATE_KEY": { from_secret: "gpg-private-key" }},
"when": { "event": [ "push" ]},
},
{
"name": "index release",
"image": index_image(p.distro),
"commands": index_commands(p.os, "zerotier-releases", p.distro, p.name, p.isas),
"volumes": release_step_volumes(p.os),
"environment":{ "GPG_PRIVATE_KEY": { from_secret: "gpg-private-key" }},
"when": { "event": [ "tag" ]},
},
],
"volumes": host_volumes(p.os),
"platform": { "os": p.os },
depends_on: std.flattenArrays([ [ std.join(" ", [ p.name, isa, "build" ]) ] for isa in p.isas ]),
"trigger": { "event": p.events }
};
//
// print
//
std.flattenArrays([
[
Build(p.os, p.distro, p.name, isa, p.events)
for isa in p.isas
] +
[
Index(p)
]
for p in native_targets
]) +
std.flattenArrays([
[
Test(p.os, p.distro, p.name, isa, p.events)
for isa in p.isas
]
for p in native_targets
])

View file

@ -1,465 +0,0 @@
---
clone:
depth: 1
kind: pipeline
name: bullseye 386 build
platform:
os: linux
pull: always
steps:
- commands:
- ./ci/scripts/build.sh bullseye debian 386 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder
name: build
when:
event:
- push
- commands:
- ./ci/scripts/build.sh bullseye debian 386 ${DRONE_TAG} ${DRONE_BUILD_EVENT}
image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder
name: release
when:
event:
- tag
- commands:
- ./ci/scripts/publish.sh bullseye debian 386 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder
name: copy build
volumes:
- name: zerotier-builds
path: /zerotier-builds
when:
event:
- push
- commands:
- ./ci/scripts/publish.sh bullseye debian 386 ${DRONE_TAG} ${DRONE_BUILD_EVENT}
image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder
name: copy relase
volumes:
- name: zerotier-releases
path: /zerotier-releases
when:
event:
- tag
trigger:
event:
- push
- tag
- custom
type: docker
volumes:
- host:
path: /zerotier-builds
name: zerotier-builds
- host:
path: /zerotier-releases
name: zerotier-releases
---
clone:
depth: 1
kind: pipeline
name: bullseye armv7 build
platform:
arch: arm64
os: linux
pull: always
steps:
- commands:
- ./ci/scripts/build.sh bullseye debian armv7 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder
name: build
when:
event:
- push
- commands:
- ./ci/scripts/build.sh bullseye debian armv7 ${DRONE_TAG} ${DRONE_BUILD_EVENT}
image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder
name: release
when:
event:
- tag
- commands:
- ./ci/scripts/publish.sh bullseye debian armv7 100.0.0+${DRONE_COMMIT_SHA:0:8}
${DRONE_BUILD_EVENT}
image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder
name: copy build
volumes:
- name: zerotier-builds
path: /zerotier-builds
when:
event:
- push
- commands:
- ./ci/scripts/publish.sh bullseye debian armv7 ${DRONE_TAG} ${DRONE_BUILD_EVENT}
image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder
name: copy relase
volumes:
- name: zerotier-releases
path: /zerotier-releases
when:
event:
- tag
trigger:
event:
- push
- tag
- custom
type: docker
volumes:
- host:
path: /zerotier-builds
name: zerotier-builds
- host:
path: /zerotier-releases
name: zerotier-releases
---
clone:
depth: 1
kind: pipeline
name: bullseye amd64 build
platform:
os: linux
pull: always
steps:
- commands:
- ./ci/scripts/build.sh bullseye debian amd64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder
name: build
when:
event:
- push
- commands:
- ./ci/scripts/build.sh bullseye debian amd64 ${DRONE_TAG} ${DRONE_BUILD_EVENT}
image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder
name: release
when:
event:
- tag
- commands:
- ./ci/scripts/publish.sh bullseye debian amd64 100.0.0+${DRONE_COMMIT_SHA:0:8}
${DRONE_BUILD_EVENT}
image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder
name: copy build
volumes:
- name: zerotier-builds
path: /zerotier-builds
when:
event:
- push
- commands:
- ./ci/scripts/publish.sh bullseye debian amd64 ${DRONE_TAG} ${DRONE_BUILD_EVENT}
image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder
name: copy relase
volumes:
- name: zerotier-releases
path: /zerotier-releases
when:
event:
- tag
trigger:
event:
- push
- tag
- custom
type: docker
volumes:
- host:
path: /zerotier-builds
name: zerotier-builds
- host:
path: /zerotier-releases
name: zerotier-releases
---
clone:
depth: 1
kind: pipeline
name: bullseye arm64 build
platform:
arch: arm64
os: linux
pull: always
steps:
- commands:
- ./ci/scripts/build.sh bullseye debian arm64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder
name: build
when:
event:
- push
- commands:
- ./ci/scripts/build.sh bullseye debian arm64 ${DRONE_TAG} ${DRONE_BUILD_EVENT}
image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder
name: release
when:
event:
- tag
- commands:
- ./ci/scripts/publish.sh bullseye debian arm64 100.0.0+${DRONE_COMMIT_SHA:0:8}
${DRONE_BUILD_EVENT}
image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder
name: copy build
volumes:
- name: zerotier-builds
path: /zerotier-builds
when:
event:
- push
- commands:
- ./ci/scripts/publish.sh bullseye debian arm64 ${DRONE_TAG} ${DRONE_BUILD_EVENT}
image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder
name: copy relase
volumes:
- name: zerotier-releases
path: /zerotier-releases
when:
event:
- tag
trigger:
event:
- push
- tag
- custom
type: docker
volumes:
- host:
path: /zerotier-builds
name: zerotier-builds
- host:
path: /zerotier-releases
name: zerotier-releases
---
clone:
depth: 1
depends_on:
- bullseye 386 build
- bullseye armv7 build
- bullseye amd64 build
- bullseye arm64 build
kind: pipeline
name: bullseye index
platform:
os: linux
pull: always
steps:
- commands:
- /usr/local/bin/index zerotier-builds debian bullseye 386 armv7 amd64 arm64
environment:
GPG_PRIVATE_KEY:
from_secret: gpg-private-key
image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/apt-builder
name: index build
volumes:
- name: zerotier-builds
path: /zerotier-builds
when:
event:
- push
- commands:
- /usr/local/bin/index zerotier-releases debian bullseye 386 armv7 amd64 arm64
environment:
GPG_PRIVATE_KEY:
from_secret: gpg-private-key
image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/apt-builder
name: index release
volumes:
- name: zerotier-releases
path: /zerotier-releases
when:
event:
- tag
trigger:
event:
- push
- tag
- custom
type: docker
volumes:
- host:
path: /zerotier-builds
name: zerotier-builds
- host:
path: /zerotier-releases
name: zerotier-releases
---
clone:
depth: 1
depends_on:
- bullseye index
kind: pipeline
name: bullseye 386 test
platform:
os: linux
pull: always
steps:
- commands:
- ./ci/scripts/test.sh bullseye debian 386 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder
name: test build
volumes:
- name: zerotier-builds
path: /zerotier-builds
when:
event:
- push
- commands:
- ./ci/scripts/test.sh bullseye debian 386 ${DRONE_TAG} ${DRONE_BUILD_EVENT}
image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder
name: test release
volumes:
- name: zerotier-releases
path: /zerotier-releases
when:
event:
- tag
trigger:
event:
- push
- tag
- custom
type: docker
volumes:
- host:
path: /zerotier-builds
name: zerotier-builds
- host:
path: /zerotier-releases
name: zerotier-releases
---
clone:
depth: 1
depends_on:
- bullseye index
kind: pipeline
name: bullseye armv7 test
platform:
arch: arm64
os: linux
pull: always
steps:
- commands:
- ./ci/scripts/test.sh bullseye debian armv7 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder
name: test build
volumes:
- name: zerotier-builds
path: /zerotier-builds
when:
event:
- push
- commands:
- ./ci/scripts/test.sh bullseye debian armv7 ${DRONE_TAG} ${DRONE_BUILD_EVENT}
image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder
name: test release
volumes:
- name: zerotier-releases
path: /zerotier-releases
when:
event:
- tag
trigger:
event:
- push
- tag
- custom
type: docker
volumes:
- host:
path: /zerotier-builds
name: zerotier-builds
- host:
path: /zerotier-releases
name: zerotier-releases
---
clone:
depth: 1
depends_on:
- bullseye index
kind: pipeline
name: bullseye amd64 test
platform:
os: linux
pull: always
steps:
- commands:
- ./ci/scripts/test.sh bullseye debian amd64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder
name: test build
volumes:
- name: zerotier-builds
path: /zerotier-builds
when:
event:
- push
- commands:
- ./ci/scripts/test.sh bullseye debian amd64 ${DRONE_TAG} ${DRONE_BUILD_EVENT}
image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder
name: test release
volumes:
- name: zerotier-releases
path: /zerotier-releases
when:
event:
- tag
trigger:
event:
- push
- tag
- custom
type: docker
volumes:
- host:
path: /zerotier-builds
name: zerotier-builds
- host:
path: /zerotier-releases
name: zerotier-releases
---
clone:
depth: 1
depends_on:
- bullseye index
kind: pipeline
name: bullseye arm64 test
platform:
arch: arm64
os: linux
pull: always
steps:
- commands:
- ./ci/scripts/test.sh bullseye debian arm64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder
name: test build
volumes:
- name: zerotier-builds
path: /zerotier-builds
when:
event:
- push
- commands:
- ./ci/scripts/test.sh bullseye debian arm64 ${DRONE_TAG} ${DRONE_BUILD_EVENT}
image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder
name: test release
volumes:
- name: zerotier-releases
path: /zerotier-releases
when:
event:
- tag
trigger:
event:
- push
- tag
- custom
type: docker
volumes:
- host:
path: /zerotier-builds
name: zerotier-builds
- host:
path: /zerotier-releases
name: zerotier-releases
---
kind: signature
hmac: 887a3ef78d3fe8f0149911e1e4876401dd7dd313b36eb893e791fa42f45d7768
...

4
.gitattributes vendored
View file

@ -1,4 +0,0 @@
ext/bin/tap-windows-ndis6/x64/zttap300.inf eol=crlf
ext/bin/tap-windows-ndis6/x64.old/zttap300.inf eol=crlf
ext/bin/tap-windows-ndis6/x86/zttap300.inf eol=crlf
windows/TapDriver6/zttap300.inf eol=crlf

46
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View file

@ -0,0 +1,46 @@
---
name: Bug report
about: Create a report to help us improve
---
**Alternative, faster ways to get help**
If you have just started using ZeroTier, here are some places to get help:
- my.zerotier.com has a _Community_ tab. It's a live chat with other users and the developers.
- [ZeroTier Knowledge Base](https://zerotier.atlassian.net/wiki/spaces/SD/overview)
- www.zerotier.com has a Contact Us button
- email contact@zerotier.com
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Create a Network '...'
2. Install zerotier-one '....'
3. '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots or console output to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. Mac, Linux, Windows, BSD]
- OS/Distribution Version
- ZeroTier Version [e.g. 1.2.4]
- Hardware [e.g. raspberry pi 3]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Version [e.g. 1.2.4]
**Additional context**
Add any other context about the problem here.
- ZeroTier Network Configuration
- Router Config
- Firewall Config (try turning the firewall off)
- General Network Environment: [ e.g Home, University Campus, Corporate LAN ]

View file

@ -1,31 +0,0 @@
---
name: Bugs and Issues
about: Create a report to help us improve
title: ''
labels: NEEDS TRIAGE
assignees: ''
---
# Before filing a Bug Report
_Using these will ensure you get quicker support, and make this space available for code-related issues. Thank you!_
- [Docs Site](https://docs.zerotier.com/zerotier/troubleshooting) => Troubleshooting, quickstarts, and more advanced topics.
- [Discuss Forum](https://discuss.zerotier.com/) => Our discussion forum for users and support to mutually resolve issues & suggest ideas.
- [Reddit](https://www.reddit.com/r/zerotier/) => Our subreddit, which we monitor regularly and is fairly active.
- [Knowledge Base](https://zerotier.atlassian.net/wiki/spaces/SD/overview) => Older wiki.
If you are having a connection issue, it's much easier to diagnose through the discussion forum or the ticket system.
# If you still want to file a Bug Report
## Please let us know
- What you expect to be happening.
- What is actually happening?
- Any steps to reproduce the error.
- Any relevant console output or screenshots.
- What operating system and ZeroTier version. Please try the latest ZeroTier release.

View file

@ -1,13 +1,17 @@
--- ---
name: Feature request name: Feature request
about: Suggest an idea for this project about: Suggest an idea for this project
title: "[Feature Request] "
labels: suggestion
assignees: ''
--- ---
If there is something you'd like to have added to ZeroTier, to go to https://discuss.zerotier.com/c/feature-requests/ instead. Issues there can be voted on and discussed in-depth. **Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
Thank you! **Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View file

@ -1,15 +0,0 @@
---
name: Game Connection Issue
about: Game issues are better served by forum posts
title: Please go to our Discuss or Reddit for game-related issues. Thanks!
labels: wontfix
assignees: ''
---
Are you having trouble connecting to a game on your virtual network after installing ZeroTier?
- [ ] Yes
- [ ] No
If you answered yes, then it is very likely that your question would be better answered on our [Community Forums](https://discuss.zerotier.com) or [Reddit](https://www.reddit.com/r/zerotier/) community; we monitor both regularly. We also have extensive documentation on our [Knowledge Base](https://zerotier.atlassian.net/wiki/spaces/SD/overview). Thank you!

View file

@ -1,126 +0,0 @@
on:
pull_request:
push:
workflow_dispatch:
jobs:
build_ubuntu:
runs-on: ubuntu-latest
steps:
- name: gitconfig
run: |
git config --global core.autocrlf input
# git config --global core.eol lf
- name: checkout
uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
toolchain: stable
targets: x86_64-unknown-linux-gnu
components: rustfmt, clippy
- name: Set up cargo cache
uses: Swatinem/rust-cache@v2
continue-on-error: false
with:
key: ${{ runner.os }}-cargo-${{ hashFiles('rustybits//Cargo.lock') }}
shared-key: ${{ runner.os }}-cargo-
workspaces: |
rustybits/
- name: make
run: make
- name: selftest
run: |
make selftest
./zerotier-selftest
- name: 'Tar files' # keeps permissions (execute)
run: tar -cvf zerotier-one.tar zerotier-one
- name: Archive production artifacts
uses: actions/upload-artifact@v4
with:
name: zerotier-one-ubuntu-x64
path: zerotier-one.tar
retention-days: 7
build_macos:
runs-on: macos-latest
steps:
- name: gitconfig
run: |
git config --global core.autocrlf input
# git config --global core.eol lf
- name: checkout
uses: actions/checkout@v4
- name: Install Rust aarch64
uses: dtolnay/rust-toolchain@stable
with:
toolchain: stable
target: aarch64-apple-darwin
components: rustfmt, clippy
- name: Install Rust x86_64
uses: dtolnay/rust-toolchain@stable
with:
toolchain: stable
target: x86_64-apple-darwin
components: rustfmt, clippy
- name: Set up cargo cache
uses: Swatinem/rust-cache@v2
continue-on-error: false
with:
key: ${{ runner.os }}-cargo-${{ hashFiles('rustybits//Cargo.lock') }}
shared-key: ${{ runner.os }}-cargo-
workspaces: |
rustybits/
- name: make
run: make
- name: selftest
run: |
make selftest
./zerotier-selftest
- name: 'Tar files' # keeps permissions (execute)
run: tar -cvf zerotier-one.tar zerotier-one
- name: Archive production artifacts
uses: actions/upload-artifact@v4
with:
name: zerotier-one-mac
path: zerotier-one.tar
retention-days: 7
build_windows:
runs-on: windows-latest
steps:
- name: gitconfig
run: |
git config --global core.autocrlf true
# git config --global core.eol lf
- name: checkout
uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
toolchain: stable
target: aarch64-apple-darwin
components: rustfmt, clippy
- name: Set up cargo cache
uses: Swatinem/rust-cache@v2
continue-on-error: false
with:
key: ${{ runner.os }}-cargo-${{ hashFiles('rustybits//Cargo.lock') }}
shared-key: ${{ runner.os }}-cargo-
workspaces: |
rustybits/
- name: setup msbuild
uses: microsoft/setup-msbuild@v2
- name: msbuild
run: |
msbuild windows\ZeroTierOne.sln /m /p:Configuration=Release /property:Platform=x64 /t:ZeroTierOne
- name: Archive production artifacts
uses: actions/upload-artifact@v4
with:
name: zerotier-one-windows
path: windows/Build
retention-days: 7

View file

@ -1,497 +0,0 @@
#!/bin/bash
# This test script joins Earth and pokes some stuff
TEST_NETWORK=8056c2e21c000001
RUN_LENGTH=30
TEST_FINISHED=false
ZTO_VER=$(git describe --tags $(git rev-list --tags --max-count=1))
ZTO_COMMIT=$(git rev-parse HEAD)
ZTO_COMMIT_SHORT=$(git rev-parse --short HEAD)
TEST_DIR_PREFIX="$ZTO_VER-$ZTO_COMMIT_SHORT-test-results"
TEST_OK=0
TEST_FAIL=1
echo "Performing test on: $ZTO_VER-$ZTO_COMMIT_SHORT"
TEST_FILEPATH_PREFIX="$TEST_DIR_PREFIX/$ZTO_COMMIT_SHORT"
mkdir $TEST_DIR_PREFIX
# How long we will wait for ZT to come online before considering it a failure
MAX_WAIT_SECS=30
ZT_PORT_NODE_1=9996
ZT_PORT_NODE_2=9997
################################################################################
# Multi-node connectivity and performance test #
################################################################################
test() {
echo -e "\nPerforming pre-flight checks"
check_exit_on_invalid_identity
echo -e "\nRunning test for $RUN_LENGTH seconds"
export NS1="ip netns exec ns1"
export NS2="ip netns exec ns2"
export ZT1="$NS1 ./zerotier-cli -p9996 -D$(pwd)/node1"
# Specify custom port on one node to ensure that feature works
export ZT2="$NS2 ./zerotier-cli -p9997 -D$(pwd)/node2"
echo -e "\nSetting up network namespaces..."
echo "Setting up ns1"
ip netns add ns1
$NS1 ip link set dev lo up
ip link add veth0 type veth peer name veth1
ip link set veth1 netns ns1
ip addr add 192.168.0.1/24 dev veth0
ip link set dev veth0 up
$NS1 ip addr add 192.168.0.2/24 dev veth1
$NS1 ip link set dev veth1 up
# Add default route
$NS1 ip route add default via 192.168.0.1
iptables -t nat -A POSTROUTING -s 192.168.0.0/255.255.255.0 \
-o eth0 -j MASQUERADE
iptables -A FORWARD -i eth0 -o veth0 -j ACCEPT
iptables -A FORWARD -o eth0 -i veth0 -j ACCEPT
echo "Setting up ns2"
ip netns add ns2
$NS2 ip link set dev lo up
ip link add veth2 type veth peer name veth3
ip link set veth3 netns ns2
ip addr add 192.168.1.1/24 dev veth2
ip link set dev veth2 up
$NS2 ip addr add 192.168.1.2/24 dev veth3
$NS2 ip link set dev veth3 up
$NS2 ip route add default via 192.168.1.1
iptables -t nat -A POSTROUTING -s 192.168.1.0/255.255.255.0 \
-o eth0 -j MASQUERADE
iptables -A FORWARD -i eth0 -o veth2 -j ACCEPT
iptables -A FORWARD -o eth0 -i veth2 -j ACCEPT
# Allow forwarding
sysctl -w net.ipv4.ip_forward=1
################################################################################
# Memory Leak Check #
################################################################################
export FILENAME_MEMORY_LOG="$TEST_FILEPATH_PREFIX-memory.log"
echo -e "\nStarting a ZeroTier instance in each namespace..."
export time_test_start=$(date +%s)
# Spam the CLI as ZeroTier is starting
spam_cli 100
echo "Starting memory leak check"
$NS1 sudo valgrind --demangle=yes --exit-on-first-error=yes \
--error-exitcode=1 \
--xml=yes \
--xml-file=$FILENAME_MEMORY_LOG \
--leak-check=full \
./zerotier-one node1 -p$ZT_PORT_NODE_1 -U >>node_1.log 2>&1 &
# Second instance, not run in memory profiler
# Don't set up internet access until _after_ zerotier is running
# This has been a source of stuckness in the past.
$NS2 ip addr del 192.168.1.2/24 dev veth3
$NS2 sudo ./zerotier-one node2 -U -p$ZT_PORT_NODE_2 >>node_2.log 2>&1 &
sleep 10; # New HTTP control plane is a bit sluggish, so we delay here
check_bind_to_correct_ports $ZT_PORT_NODE_1
check_bind_to_correct_ports $ZT_PORT_NODE_2
$NS2 ip addr add 192.168.1.2/24 dev veth3
$NS2 ip route add default via 192.168.1.1
echo -e "\nPing from host to namespaces"
ping -c 3 192.168.0.1
ping -c 3 192.168.1.1
echo -e "\nPing from namespace to host"
$NS1 ping -c 3 192.168.0.1
$NS1 ping -c 3 192.168.0.1
$NS2 ping -c 3 192.168.0.2
$NS2 ping -c 3 192.168.0.2
echo -e "\nPing from ns1 to ns2"
$NS1 ping -c 3 192.168.0.1
echo -e "\nPing from ns2 to ns1"
$NS2 ping -c 3 192.168.0.1
################################################################################
# Online Check #
################################################################################
echo "Waiting for ZeroTier to come online before attempting test..."
node1_online=false
node2_online=false
both_instances_online=false
time_zt_node1_start=$(date +%s)
time_zt_node2_start=$(date +%s)
for ((s = 0; s <= $MAX_WAIT_SECS; s++)); do
node1_online="$($ZT1 -j info | jq '.online' 2>/dev/null)"
node2_online="$($ZT2 -j info | jq '.online' 2>/dev/null)"
echo "Checking for online status: try #$s, node1:$node1_online, node2:$node2_online"
if [[ "$node2_online" == "true" && "$node1_online" == "true" ]]; then
export both_instances_online=true
export time_to_both_nodes_online=$(date +%s)
break
fi
sleep 1
done
echo -e "\n\nContents of ZeroTier home paths:"
ls -lga node1
tree node1
ls -lga node2
tree node2
echo -e "\n\nRunning ZeroTier processes:"
echo -e "\nNode 1:\n"
$NS1 ps aux | grep zerotier-one
echo -e "\nNode 2:\n"
$NS2 ps aux | grep zerotier-one
echo -e "\n\nStatus of each instance:"
echo -e "\n\nNode 1:\n"
$ZT1 status
echo -e "\n\nNode 2:\n"
$ZT2 status
if [[ "$both_instances_online" != "true" ]]; then
exit_test_and_generate_report $TEST_FAIL "one or more nodes failed to come online"
fi
echo -e "\nJoining networks"
$ZT1 join $TEST_NETWORK
$ZT2 join $TEST_NETWORK
sleep 10
node1_ip4=$($ZT1 get $TEST_NETWORK ip4)
node2_ip4=$($ZT2 get $TEST_NETWORK ip4)
echo "node1_ip4=$node1_ip4"
echo "node2_ip4=$node2_ip4"
echo -e "\nPinging each node"
PING12_FILENAME="$TEST_FILEPATH_PREFIX-ping-1-to-2.txt"
PING21_FILENAME="$TEST_FILEPATH_PREFIX-ping-2-to-1.txt"
$NS1 ping -c 16 $node2_ip4 >$PING12_FILENAME
$NS2 ping -c 16 $node1_ip4 >$PING21_FILENAME
ping_loss_percent_1_to_2=$(cat $PING12_FILENAME |
grep "packet loss" | awk '{print $6}' | sed 's/%//')
ping_loss_percent_2_to_1=$(cat $PING21_FILENAME |
grep "packet loss" | awk '{print $6}' | sed 's/%//')
# Normalize loss value
export ping_loss_percent_1_to_2=$(echo "scale=2; $ping_loss_percent_1_to_2/100.0" | bc)
export ping_loss_percent_2_to_1=$(echo "scale=2; $ping_loss_percent_2_to_1/100.0" | bc)
################################################################################
# CLI Check #
################################################################################
echo "Testing basic CLI functionality..."
spam_cli 10
$ZT1 join $TEST_NETWORK
$ZT1 -h
$ZT1 -v
$ZT1 status
$ZT1 info
$ZT1 listnetworks
$ZT1 peers
$ZT1 listpeers
$ZT1 -j status
$ZT1 -j info
$ZT1 -j listnetworks
$ZT1 -j peers
$ZT1 -j listpeers
$ZT1 dump
$ZT1 get $TEST_NETWORK allowDNS
$ZT1 get $TEST_NETWORK allowDefault
$ZT1 get $TEST_NETWORK allowGlobal
$ZT1 get $TEST_NETWORK allowManaged
$ZT1 get $TEST_NETWORK bridge
$ZT1 get $TEST_NETWORK broadcastEnabled
$ZT1 get $TEST_NETWORK dhcp
$ZT1 get $TEST_NETWORK id
$ZT1 get $TEST_NETWORK mac
$ZT1 get $TEST_NETWORK mtu
$ZT1 get $TEST_NETWORK name
$ZT1 get $TEST_NETWORK netconfRevision
$ZT1 get $TEST_NETWORK nwid
$ZT1 get $TEST_NETWORK portDeviceName
$ZT1 get $TEST_NETWORK portError
$ZT1 get $TEST_NETWORK status
$ZT1 get $TEST_NETWORK type
# Test an invalid command
$ZT1 get $TEST_NETWORK derpderp
# TODO: Validate JSON
# Performance Test
export FILENAME_PERF_JSON="$TEST_FILEPATH_PREFIX-iperf.json"
echo -e "\nBeginning performance test:"
echo -e "\nStarting server:"
echo "$NS1 iperf3 -s &"
sleep 1
echo -e "\nStarting client:"
sleep 1
echo "$NS2 iperf3 --json -c $node1_ip4 > $FILENAME_PERF_JSON"
cat $FILENAME_PERF_JSON
# Let ZeroTier idle long enough for various timers
echo -e "\nIdling ZeroTier for $RUN_LENGTH seconds..."
sleep $RUN_LENGTH
echo -e "\nLeaving networks"
$ZT1 leave $TEST_NETWORK
$ZT2 leave $TEST_NETWORK
sleep 5
exit_test_and_generate_report $TEST_OK "completed test"
}
################################################################################
# Generate report #
################################################################################
exit_test_and_generate_report() {
echo -e "\nStopping memory check..."
sudo pkill -15 -f valgrind
sleep 10
time_test_end=$(date +%s)
echo "Exiting test with reason: $2 ($1)"
# Collect ZeroTier dump files
echo -e "\nCollecting ZeroTier dump files"
node1_id=$($ZT1 -j status | jq -r .address)
node2_id=$($ZT2 -j status | jq -r .address)
$ZT1 dump
mv zerotier_dump.txt "$TEST_FILEPATH_PREFIX-node-dump-$node1_id.txt"
$ZT2 dump
mv zerotier_dump.txt "$TEST_FILEPATH_PREFIX-node-dump-$node2_id.txt"
# Copy ZeroTier stdout/stderr logs
cp node_1.log "$TEST_FILEPATH_PREFIX-node-log-$node1_id.txt"
cp node_2.log "$TEST_FILEPATH_PREFIX-node-log-$node2_id.txt"
# Generate report
cat $FILENAME_MEMORY_LOG
DEFINITELY_LOST=$(xmlstarlet sel -t -v '/valgrindoutput/error/xwhat' \
$FILENAME_MEMORY_LOG | grep "definitely" | awk '{print $1;}')
POSSIBLY_LOST=$(xmlstarlet sel -t -v '/valgrindoutput/error/xwhat' \
$FILENAME_MEMORY_LOG | grep "possibly" | awk '{print $1;}')
# Generate coverage report artifact and summary
FILENAME_COVERAGE_JSON="$TEST_FILEPATH_PREFIX-coverage.json"
FILENAME_COVERAGE_HTML="$TEST_FILEPATH_PREFIX-coverage.html"
echo -e "\nGenerating coverage test report..."
gcovr -r . --exclude ext --json-summary $FILENAME_COVERAGE_JSON \
--html >$FILENAME_COVERAGE_HTML
cat $FILENAME_COVERAGE_JSON
COVERAGE_LINE_COVERED=$(cat $FILENAME_COVERAGE_JSON | jq .line_covered)
COVERAGE_LINE_TOTAL=$(cat $FILENAME_COVERAGE_JSON | jq .line_total)
COVERAGE_LINE_PERCENT=$(cat $FILENAME_COVERAGE_JSON | jq .line_percent)
COVERAGE_LINE_COVERED="${COVERAGE_LINE_COVERED:-0}"
COVERAGE_LINE_TOTAL="${COVERAGE_LINE_TOTAL:-0}"
COVERAGE_LINE_PERCENT="${COVERAGE_LINE_PERCENT:-0}"
# Default values
DEFINITELY_LOST="${DEFINITELY_LOST:-0}"
POSSIBLY_LOST="${POSSIBLY_LOST:-0}"
ping_loss_percent_1_to_2="${ping_loss_percent_1_to_2:-100.0}"
ping_loss_percent_2_to_1="${ping_loss_percent_2_to_1:-100.0}"
time_to_both_nodes_online="${time_to_both_nodes_online:--1}"
# Summarize and emit json for trend reporting
FILENAME_SUMMARY="$TEST_FILEPATH_PREFIX-summary.json"
time_length_test=$((time_test_end - time_test_start))
if [[ $time_to_both_nodes_online != -1 ]];
then
time_to_both_nodes_online=$((time_to_both_nodes_online - time_test_start))
fi
#time_length_zt_join=$((time_zt_join_end-time_zt_join_start))
#time_length_zt_leave=$((time_zt_leave_end-time_zt_leave_start))
#time_length_zt_can_still_ping=$((time_zt_can_still_ping-time_zt_leave_start))
summary=$(
cat <<EOF
{
"version":"$ZTO_VER",
"commit":"$ZTO_COMMIT",
"arch_m":"$(uname -m)",
"arch_a":"$(uname -a)",
"binary_size":"$(stat -c %s zerotier-one)",
"time_length_test":$time_length_test,
"time_to_both_nodes_online":$time_to_both_nodes_online,
"num_possible_bytes_lost": $POSSIBLY_LOST,
"num_definite_bytes_lost": $DEFINITELY_LOST,
"num_bad_formattings": $POSSIBLY_LOST,
"coverage_lines_covered": $COVERAGE_LINE_COVERED,
"coverage_lines_total": $COVERAGE_LINE_TOTAL,
"coverage_lines_percent": $COVERAGE_LINE_PERCENT,
"ping_loss_percent_1_to_2": $ping_loss_percent_1_to_2,
"ping_loss_percent_2_to_1": $ping_loss_percent_2_to_1,
"test_exit_code": $1,
"test_exit_reason":"$2"
}
EOF
)
echo $summary >$FILENAME_SUMMARY
cat $FILENAME_SUMMARY
exit 0
}
################################################################################
# CLI Check #
################################################################################
spam_cli() {
echo "Spamming CLI..."
# Rapidly spam the CLI with joins/leaves
MAX_TRIES="${1:-10}"
for ((s = 0; s <= MAX_TRIES; s++)); do
$ZT1 status
$ZT2 status
sleep 0.1
done
SPAM_TRIES=128
for ((s = 0; s <= SPAM_TRIES; s++)); do
$ZT1 join $TEST_NETWORK
done
for ((s = 0; s <= SPAM_TRIES; s++)); do
$ZT1 leave $TEST_NETWORK
done
for ((s = 0; s <= SPAM_TRIES; s++)); do
$ZT1 leave $TEST_NETWORK
$ZT1 join $TEST_NETWORK
done
}
################################################################################
# Check for proper exit on load of invalid identity #
################################################################################
check_exit_on_invalid_identity() {
echo "Checking ZeroTier exits on invalid identity..."
mkdir -p $(pwd)/exit_test
ZT1="sudo ./zerotier-one -p9999 $(pwd)/exit_test"
echo "asdfasdfasdfasdf" > $(pwd)/exit_test/identity.secret
echo "asdfasdfasdfasdf" > $(pwd)/exit_test/authtoken.secret
echo "Launch ZeroTier with an invalid identity"
$ZT1 &
my_pid=$!
echo "Waiting 5 seconds"
sleep 5
# check if process is running
kill -0 $my_pid
if [ $? -eq 0 ]; then
exit_test_and_generate_report $TEST_FAIL "Exit test FAILED: Process still running after being fed an invalid identity"
fi
}
################################################################################
# Check that we're binding to the primary port for TCP/TCP6/UDP #
################################################################################
check_bind_to_correct_ports() {
PORT_NUMBER=$1
echo "Checking bound ports:"
sudo netstat -anp | grep "$PORT_NUMBER" | grep "zerotier"
if [[ $(sudo netstat -anp | grep "$PORT_NUMBER" | grep "zerotier" | grep "tcp") ]];
then
:
else
exit_test_and_generate_report $TEST_FAIL "ZeroTier did not bind to tcp/$1"
fi
if [[ $(sudo netstat -anp | grep "$PORT_NUMBER" | grep "zerotier" | grep "tcp6") ]];
then
:
else
exit_test_and_generate_report $TEST_FAIL "ZeroTier did not bind to tcp6/$1"
fi
if [[ $(sudo netstat -anp | grep "$PORT_NUMBER" | grep "zerotier" | grep "udp") ]];
then
:
else
exit_test_and_generate_report $TEST_FAIL "ZeroTier did not bind to udp/$1"
fi
}
test "$@"

View file

@ -1,24 +0,0 @@
#!/bin/bash
################################################################################
# Set exit code depending on tool reports #
################################################################################
DEFINITELY_LOST=$(cat *test-results/*summary.json | jq .num_definite_bytes_lost)
EXIT_CODE=$(cat *test-results/*summary.json | jq .exit_code)
EXIT_REASON=$(cat *test-results/*summary.json | jq .exit_reason)
cat *test-results/*summary.json
echo -e "\nBytes of memory definitely lost: $DEFINITELY_LOST"
if [[ "$DEFINITELY_LOST" -gt 0 ]]; then
exit 1
fi
# Catch-all for other non-zero exit codes
if [[ "$EXIT_CODE" -gt 0 ]]; then
echo "Test failed: $EXIT_REASON"
exit 1
fi

View file

@ -1,57 +0,0 @@
on:
pull_request:
push:
workflow_dispatch:
jobs:
build_ubuntu:
runs-on: ubuntu-latest
steps:
- name: gitconfig
run: |
git config --global core.autocrlf input
- name: checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
target: x86_64-unknown-linux-gnu
override: true
components: rustfmt, clippy
- name: Set up cargo cache
uses: Swatinem/rust-cache@v2
continue-on-error: false
with:
key: ${{ runner.os }}-cargo-${{ hashFiles('zeroidc//Cargo.lock') }}
shared-key: ${{ runner.os }}-cargo-
workspaces: |
zeroidc/
- name: validate-1m-linux
env:
CC: 'gcc'
CXX: 'g++'
BRANCH: ${{ github.ref_name }}
run: |
sudo apt install -y valgrind xmlstarlet gcovr iperf3 tree
make one ZT_COVERAGE=1 ZT_TRACE=1
sudo chmod +x ./.github/workflows/validate-linux.sh
sudo ./.github/workflows/validate-linux.sh
- name: Archive test results
uses: actions/upload-artifact@v4
with:
name: ${{github.sha}}-test-results
path: "*test-results*"
- name: final-report
run: |
sudo chmod +x ./.github/workflows/validate-report.sh
sudo ./.github/workflows/validate-report.sh

30
.gitignore vendored
View file

@ -6,11 +6,6 @@
/zerotier /zerotier
/nltest /nltest
# IDE stuff
/.idea
/.nova
/compile_commands.json
# OS-created garbage files from various platforms # OS-created garbage files from various platforms
.DS_Store .DS_Store
.Apple* .Apple*
@ -35,8 +30,10 @@ Thumbs.db
/windows/WebUIWrapper/obj /windows/WebUIWrapper/obj
/windows/lib /windows/lib
/ext/installfiles/windows/ZeroTier One-SetupFiles /ext/installfiles/windows/ZeroTier One-SetupFiles
/ext/installfiles/windows/Prerequisites
/ext/installfiles/windows/*-cache /ext/installfiles/windows/*-cache
/ZeroTier One.msi /ZeroTier One.msi
/windows/.vs
*.vcxproj.backup *.vcxproj.backup
/windows/TapDriver6/Win7Debug /windows/TapDriver6/Win7Debug
/windows/TapDriver6/win7Release /windows/TapDriver6/win7Release
@ -45,7 +42,6 @@ Thumbs.db
enc_temp_folder enc_temp_folder
/windows/copyutil/bin /windows/copyutil/bin
/windows/copyutil/obj /windows/copyutil/obj
.vs/
# *nix/Mac build droppings # *nix/Mac build droppings
/build-* /build-*
@ -62,6 +58,7 @@ zt1-src.tar.gz
*.opensdf *.opensdf
*.user *.user
*.cache *.cache
*.obj
*.tlog *.tlog
*.pid *.pid
*.pkg *.pkg
@ -106,6 +103,7 @@ windows/ZeroTierOne/Debug/
*.swp *.swp
*~.nib *~.nib
DerivedData/ DerivedData/
build/
*.pbxuser *.pbxuser
*.mode1v3 *.mode1v3
*.mode2v3 *.mode2v3
@ -116,27 +114,9 @@ DerivedData/
!default.perspectivev3 !default.perspectivev3
*.xccheckout *.xccheckout
xcuserdata/ xcuserdata/
ext/librethinkdbxx/build
.vscode .vscode
__pycache__ __pycache__
*~ *~
attic/world/*.c25519 attic/world/*.c25519
attic/world/mkworld attic/world/mkworld
workspace/
workspace2/
zeroidc/target/
tcp-proxy/target
#snapcraft specifics
/parts/
/stage/
/prime/
*.snap
.snapcraft
__pycache__
*.pyc
*_source.tar.bz2
snap/.snapcraft
tcp-proxy/tcp-proxy
rustybits/target

14
.kick
View file

@ -1,14 +0,0 @@
kick
kick
kick
kick
kick
kick
kick
kick
kick
kick
kick
kick
kick
kick

View file

@ -1,5 +1,3 @@
# Authors and Third Party Code Licensing Information
## Primary Authors ## Primary Authors
* ZeroTier Core and ZeroTier One virtual networking service<br> * ZeroTier Core and ZeroTier One virtual networking service<br>
@ -28,7 +26,7 @@
## Third-Party Code ## Third-Party Code
ZeroTier includes the following third party code, either in ext/ or incorporated into the ZeroTier core. This third party code remains licensed under its original license and is not subject to ZeroTier's BSL license. ZeroTier includes the following third party code, either in ext/ or incorporated into the ZeroTier core.
* LZ4 compression algorithm by Yann Collet * LZ4 compression algorithm by Yann Collet

View file

@ -1,8 +1,13 @@
ZeroTier One, an endpoint server for the ZeroTier virtual network layer. ZeroTier One, an endpoint server for the ZeroTier virtual network layer.
Copyright © 20112019 ZeroTier, Inc. Copyright © 20112019 ZeroTier, Inc.
ZeroTier is released under the terms of the BSL version 1.1. See the ZeroTier One is free software: you can redistribute it and/or modify
file LICENSE.txt for details. it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or (at
your option) any later version.
See the file LICENSE.GPL-3 for the text of the GNU GPL version 3.
If that file is not present, see <http://www.gnu.org/licenses/>.
.. ..
Local variables: Local variables:

View file

@ -1,28 +0,0 @@
# vim: ft=dockerfile
FROM ubuntu:21.04 as stage
RUN apt-get update -qq && apt-get -qq install make clang
COPY . .
RUN /usr/bin/make
RUN echo $PWD
RUN cp zerotier-one /usr/sbin
FROM ubuntu:21.04
COPY --from=stage /zerotier-one /usr/sbin
RUN ln -sf /usr/sbin/zerotier-one /usr/sbin/zerotier-idtool
RUN ln -sf /usr/sbin/zerotier-one /usr/sbin/zerotier-cli
RUN echo "${VERSION}" > /etc/zerotier-version
RUN rm -rf /var/lib/zerotier-one
RUN apt-get -qq update
RUN apt-get -qq install iproute2 net-tools fping 2ping iputils-ping iputils-arping
COPY entrypoint.sh.release /entrypoint.sh
RUN chmod 755 /entrypoint.sh
CMD []
ENTRYPOINT ["/entrypoint.sh"]

View file

@ -1,23 +0,0 @@
# vim: ft=dockerfile
FROM debian:bookworm
ARG VERSION
RUN apt-get update -qq && apt-get install curl gpg -y
RUN mkdir -p /usr/share/zerotier && \
curl -o /usr/share/zerotier/tmp.asc "https://download.zerotier.com/contact%40zerotier.com.gpg" && \
gpg --no-default-keyring --keyring /usr/share/zerotier/zerotier.gpg --import /usr/share/zerotier/tmp.asc && \
rm -f /usr/share/zerotier/tmp.asc && \
echo "deb [signed-by=/usr/share/zerotier/zerotier.gpg] http://download.zerotier.com/debian/bookworm bookworm main" > /etc/apt/sources.list.d/zerotier.list
RUN apt-get update -qq && apt-get install zerotier-one=${VERSION} curl iproute2 net-tools iputils-ping openssl libssl3 -y
RUN rm -rf /var/lib/zerotier-one
COPY entrypoint.sh.release /entrypoint.sh
RUN chmod 755 /entrypoint.sh
HEALTHCHECK --interval=1s CMD bash /healthcheck.sh
CMD []
ENTRYPOINT ["/entrypoint.sh"]

84
Jenkinsfile vendored Normal file
View file

@ -0,0 +1,84 @@
#!/usr/bin/env groovy
node('master') {
checkout scm
def changelog = getChangeLog currentBuild
mattermostSend "Building ${env.JOB_NAME} #${env.BUILD_NUMBER} \n Change Log: \n ${changelog}"
}
parallel 'centos7': {
node('centos7') {
try {
checkout scm
stage('Build Centos 7') {
sh 'make -f make-linux.mk'
}
}
catch (err) {
currentBuild.result = "FAILURE"
mattermostSend color: '#ff0000', message: "${env.JOB_NAME} broken on Centos 7 (<${env.BUILD_URL}|Open>)"
throw err
}
}
// }, 'android-ndk': {
// node('android-ndk') {
// try {
// checkout scm
// stage('Build Android NDK') {
// sh "/android/android-ndk-r15b/ndk-build -C $WORKSPACE/java ZT1=${WORKSPACE}"
// }
// }
// catch (err) {
// currentBuild.result = "FAILURE"
// mattermostSend color: '#ff0000', message: "${env.JOB_NAME} broken on Android NDK (<${env.BUILD_URL}|Open>)"
// throw err
// }
// }
// }, 'macOS': {
// node('macOS') {
// try {
// checkout scm
// stage('Build macOS') {
// sh 'make -f make-mac.mk'
// }
// stage('Build macOS UI') {
// sh 'cd macui && xcodebuild -target "ZeroTier One" -configuration Debug'
// }
// }
// catch (err) {
// currentBuild.result = "FAILURE"
// mattermostSend color: '#ff0000', message: "${env.JOB_NAME} broken on macOS (<${env.BUILD_URL}|Open>)"
// throw err
// }
// }
// }, 'windows': {
// node('windows') {
// try {
// checkout scm
// stage('Build Windows') {
// bat '''CALL "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\vcvarsall.bat" amd64
// git clean -dfx
// msbuild windows\\ZeroTierOne.sln
// '''
// }
// }
// catch (err) {
// currentBuild.result = "FAILURE"
// mattermostSend color: '#ff0000', message: "${env.JOB_NAME} broken on Windows (<${env.BUILD_URL}|Open>)"
// throw err
// }
// }
}
mattermostSend color: "#00ff00", message: "${env.JOB_NAME} #${env.BUILD_NUMBER} Complete (<${env.BUILD_URL}|Show More...>)"

339
LICENSE.GPL-2 Normal file
View file

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

674
LICENSE.GPL-3 Normal file
View file

@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

View file

@ -1,149 +1,37 @@
----------------------------------------------------------------------------- ZeroTier One - Network Virtualization Everywhere
Copyright (C) 2011-2019 ZeroTier, Inc. https://www.zerotier.com/
Business Source License 1.1 This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved. This program is distributed in the hope that it will be useful,
"Business Source License" is a trademark of MariaDB Corporation Ab. but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
----------------------------------------------------------------------------- You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Parameters See LICENSE.GPL-3 for the full GNU GPL v3 license.
Licensor: ZeroTier, Inc. --
Licensed Work: ZeroTier Network Virtualization Engine 1.4.4
The Licensed Work is (c)2019 ZeroTier, Inc.
Additional Use Grant: You may make use of the Licensed Work, provided you
do not use it in any of the following ways:
* Sell hosted ZeroTier services as a "SaaS" Product You can be released from the requirements of the license by purchasing
a commercial license. Buying such a license is mandatory as soon as you
develop commercial closed-source software that incorporates or links
directly against ZeroTier software without disclosing the source code
of your own application.
(1) Operate or sell access to ZeroTier root servers, --
network controllers, or authorization key or certificate
generation components of the Licensed Work as a
for-profit service, regardless of whether the use of
these components is sold alone or is bundled with other
services. Note that this does not apply to the use of
ZeroTier behind the scenes to operate a service not
related to ZeroTier network administration.
* Create Non-Open-Source Commercial Derivative Works The above license does not apply to third party code included with or
linked against by ZeroTier software. See the third party code section
of the AUTHORS.md for an index of third party software included in
this software repository.
(2) Link or directly include the Licensed Work in a Licenses for third party code are all relatively permissive: MIT,
commercial or for-profit application or other product BSD, and public domain. The only exception is the tap-windows driver
not distributed under an Open Source Initiative (OSI) which is under the GPLv2, but this is only needed to produce the
compliant license. See: https://opensource.org/licenses binary tap device driver used by the ZeroTier service on Windows.
(3) Remove the name, logo, copyright, or other branding
material from the Licensed Work to create a "rebranded"
or "white labeled" version to distribute as part of
any commercial or for-profit product or service.
* Certain Government Uses
(4) Use or deploy the Licensed Work in a government
setting in support of any active government function
or operation with the exception of the following:
physical or mental health care, family and social
services, social welfare, senior care, child care, and
the care of persons with disabilities.
Change Date: 2026-01-01
Change License: Apache License version 2.0 as published by the Apache
Software Foundation
https://www.apache.org/licenses/
Alternative Licensing
If you would like to use the Licensed Work in any way that conflicts with
the stipulations of the Additional Use Grant, contact ZeroTier, Inc. to
obtain an alternative commercial license.
Visit us on the web at: https://www.zerotier.com/
Notice
The Business Source License (this document, or the "License") is not an Open
Source license. However, the Licensed Work will eventually be made available
under an Open Source License, as stated in this License.
For more information on the use of the Business Source License for ZeroTier
products, please visit our pricing page which contains license details and
and license FAQ: https://zerotier.com/pricing
For more information on the use of the Business Source License generally,
please visit the Adopting and Developing Business Source License FAQ at
https://mariadb.com/bsl-faq-adopting.
-----------------------------------------------------------------------------
Business Source License 1.1
Terms
The Licensor hereby grants you the right to copy, modify, create derivative
works, redistribute, and make non-production use of the Licensed Work. The
Licensor may make an Additional Use Grant, above, permitting limited
production use.
Effective on the Change Date, or the fourth anniversary of the first publicly
available distribution of a specific version of the Licensed Work under this
License, whichever comes first, the Licensor hereby grants you rights under
the terms of the Change License, and the rights granted in the paragraph
above terminate.
If your use of the Licensed Work does not comply with the requirements
currently in effect as described in this License, you must purchase a
commercial license from the Licensor, its affiliated entities, or authorized
resellers, or you must refrain from using the Licensed Work.
All copies of the original and modified Licensed Work, and derivative works
of the Licensed Work, are subject to this License. This License applies
separately for each version of the Licensed Work and the Change Date may vary
for each version of the Licensed Work released by Licensor.
You must conspicuously display this License on each original or modified copy
of the Licensed Work. If you receive the Licensed Work in original or
modified form from a third party, the terms and conditions set forth in this
License apply to your use of that work.
Any use of the Licensed Work in violation of this License will automatically
terminate your rights under this License for the current and all other
versions of the Licensed Work.
This License does not grant you any right in any trademark or logo of
Licensor or its affiliates (provided that you may use a trademark or logo of
Licensor as expressly required by this License).
TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
TITLE.
-----------------------------------------------------------------------------
MariaDB hereby grants you permission to use this Licenses text to license
your works, and to refer to it using the trademark "Business Source License",
as long as you comply with the Covenants of Licensor below.
Covenants of Licensor
In consideration of the right to use this Licenses text and the "Business
Source License" name and trademark, Licensor covenants to MariaDB, and to all
other recipients of the licensed work to be provided by Licensor:
1. To specify as the Change License the GPL Version 2.0 or any later version,
or a license that is compatible with GPL Version 2.0 or a later version,
where "compatible" means that software provided under the Change License can
be included in a program with software provided under GPL Version 2.0 or a
later version. Licensor may specify additional Change Licenses without
limitation.
2. To either: (a) specify an additional grant of rights to use that does not
impose any additional restriction on the right granted in this License, as
the Additional Use Grant; or (b) insert the text "None".
3. To specify a Change Date.
4. Not to modify this License in any other way.

View file

@ -17,8 +17,8 @@ ifeq ($(OSTYPE),FreeBSD)
include make-bsd.mk include make-bsd.mk
endif endif
ifeq ($(OSTYPE),OpenBSD) ifeq ($(OSTYPE),OpenBSD)
CC=clang CC=egcc
CXX=clang++ CXX=eg++
ZT_BUILD_PLATFORM=9 ZT_BUILD_PLATFORM=9
include make-bsd.mk include make-bsd.mk
endif endif
@ -26,8 +26,3 @@ endif
ifeq ($(OSTYPE),NetBSD) ifeq ($(OSTYPE),NetBSD)
include make-netbsd.mk include make-netbsd.mk
endif endif
drone:
@echo "rendering .drone.yaml from .drone.jsonnet"
drone jsonnet --format --stream
drone sign zerotier/ZeroTierOne --save

View file

@ -14,7 +14,7 @@ The version must be incremented in all of the following files:
/debian/changelog /debian/changelog
/ext/installfiles/mac/ZeroTier One.pkgproj /ext/installfiles/mac/ZeroTier One.pkgproj
/ext/installfiles/windows/ZeroTier One.aip /ext/installfiles/windows/ZeroTier One.aip
../DesktopUI/mac-app-template/ZeroTier.app/Contents/Info.plist /windows/WinUI/AboutView.xaml
The final .AIP file can only be edited on Windows with [Advanced Installer Enterprise](http://www.advancedinstaller.com/). In addition to incrementing the version be sure that a new product code is generated. (The "upgrade code" GUID on the other hand must never change.) The final .AIP file can only be edited on Windows with [Advanced Installer Enterprise](http://www.advancedinstaller.com/). In addition to incrementing the version be sure that a new product code is generated. (The "upgrade code" GUID on the other hand must never change.)

View file

@ -1,73 +0,0 @@
# ZeroTier One in a container!
**NOTE:** _Most of this information pertains to the docker image only. For more information about ZeroTier, check out the repository_: [here](https://github.com/zerotier/ZeroTierOne) or the [commercial website](https://www.zerotier.com).
[ZeroTier](https://www.zerotier.com) is a smart programmable Ethernet switch for planet Earth. It allows all networked devices, VMs, containers, and applications to communicate as if they all reside in the same physical data center or cloud region.
This is accomplished by combining a cryptographically addressed and secure peer to peer network (termed VL1) with an Ethernet emulation layer somewhat similar to VXLAN (termed VL2). Our VL2 Ethernet virtualization layer includes advanced enterprise SDN features like fine grained access control rules for network micro-segmentation and security monitoring.
All ZeroTier traffic is encrypted end-to-end using secret keys that only you control. Most traffic flows peer to peer, though we offer free (but slow) relaying for users who cannot establish peer to peer connections.
The goals and design principles of ZeroTier are inspired by among other things the original [Google BeyondCorp](https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/43231.pdf) paper and the [Jericho Forum](https://en.wikipedia.org/wiki/Jericho_Forum) with its notion of "deperimeterization."
Visit [ZeroTier's site](https://www.zerotier.com/) for more information and [pre-built binary packages](https://www.zerotier.com/download/). Apps for Android and iOS are available for free in the Google Play and Apple app stores.
ZeroTier is licensed under the [BSL version 1.1](https://mariadb.com/bsl11/). See [LICENSE.txt](https://github.com/zerotier/ZeroTierOne/blob/master/LICENSE.txt) and the [ZeroTier pricing page](https://www.zerotier.com/pricing) for details. ZeroTier is free to use internally in businesses and academic institutions and for non-commercial purposes. Certain types of commercial use such as building closed-source apps and devices based on ZeroTier or offering ZeroTier network controllers and network management as a SaaS service require a commercial license.
A small amount of third party code is also included in ZeroTier and is not subject to our BSL license. See [AUTHORS.md](https://github.com/zerotier/ZeroTierOne/blob/master/AUTHORS.md) for a list of third party code, where it is included, and the licenses that apply to it. All of the third party code in ZeroTier is liberally licensed (MIT, BSD, Apache, public domain, etc.).
## Building the docker image
Due to the network being a substrate for most applications and not an application unto itself, it makes sense that many people would want to build their own image based on our formula.
The image is based on `debian:buster`.
The `Dockerfile.release` file contains build instructions for building the described image in the rest of the README. The build is multi-arch and multi-release capable.
These build arguments power the build:
- `PACKAGE_BASEURL`: The base URL of the package repository to fetch from. (default: `https://download.zerotier.com/debian/buster/pool/main/z/zerotier-one/`)
- `ARCH`: The architecture of the package, in debian format. Must match your image arch. (default: `amd64`)
- `VERSION`: **REQUIRED** the version of ZeroTier to fetch.
You can build this image like so:
```
docker build -f Dockerfile.release -t mybuild --build-arg VERSION=1.6.5 .
```
## Using the docker image
The `entrypoint.sh` in the docker image is a little different; zerotier will be spawned in the background and the "main process" is actually just a sleeping shell script. This allows `zerotier-one` to gracefully terminate in some situations largely unique to docker.
The `zerotier/zerotier` image requires the `CAP_NET_ADMIN` capability and the `/dev/net/tun` device must be forwarded to it.
To join a network, simply supply it on the command-line; you can supply multiple networks.
```
docker run --name myzerotier --rm --cap-add NET_ADMIN --device /dev/net/tun zerotier/zerotier:latest abcdefdeadbeef00
```
Once joining all the networks you have provided, it will sleep until terminated. Note that in ZeroTier, joining a network does not necessarily mean you have an IP or can do anything, really. You will want to probe the control socket:
```
docker exec myzerotier zerotier-cli listnetworks
```
To ensure you have a network available before trying to listen on it. Without pre-configuring the identity, this usually means going to the central admin panel and clicking the checkmark against your zerotier identity.
### Environment Variables
You can control a few settings including the identity used and the authtoken used to interact with the control socket (which you can forward and access through `localhost:9993`).
- `ZEROTIER_JOIN_NETWORKS`: additional way to set networks to join.
- `ZEROTIER_API_SECRET`: replaces the `authtoken.secret` before booting and allows you to manage the control socket's authentication key.
- `ZEROTIER_IDENTITY_PUBLIC`: the `identity.public` file for zerotier-one. Use `zerotier-idtool` to generate one of these for you.
- `ZEROTIER_IDENTITY_SECRET`: the `identity.secret` file for zerotier-one. Use `zerotier-idtool` to generate one of these for you.
- `ZEROTIER_LOCAL_CONF`: Sets the the `local.conf` file content for zerotier-one
### Tips
- Forwarding port `<dockerip>:9993` to somewhere outside is probably a good idea for highly trafficked services.
- Forwarding `localhost:9993` to a control network where you can drive it remotely might be a good idea, just be sure to set your authtoken properly through environment variables.
- Pre-generating your identities could be much simpler to do via our [terraform plugin](https://github.com/zerotier/terraform-provider-zerotier)

156
README.md
View file

@ -1,29 +1,19 @@
ZeroTier - Global Area Networking ZeroTier - Global Area Networking
====== ======
*This document is written for a software developer audience. For information on using ZeroTier, see the: [Website](https://www.zerotier.com), [Documentation Site](https://docs.zerotier.com), and [Discussion Forum](https://discuss.zerotier.com).* ZeroTier is a smart programmable Ethernet switch for planet Earth. It allows networked devices and applications to be managed as if the entire world is one data center or cloud region.
ZeroTier is a smart programmable Ethernet switch for planet Earth. It allows all networked devices, VMs, containers, and applications to communicate as if they all reside in the same physical data center or cloud region. It replaces the physical LAN/WAN boundary with a virtual one, allowing devices of any type at any location to be managed as if they all reside in the same cloud region or data center. All traffic is encrypted end-to-end and takes the most direct path available for minimum latency and maximum performance. The goals and design of ZeroTier are inspired by among other things the original [Google BeyondCorp](https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/43231.pdf) paper and the [Jericho Forum](https://en.wikipedia.org/wiki/Jericho_Forum).
This is accomplished by combining a cryptographically addressed and secure peer to peer network (termed VL1) with an Ethernet emulation layer somewhat similar to VXLAN (termed VL2). Our VL2 Ethernet virtualization layer includes advanced enterprise SDN features like fine grained access control rules for network micro-segmentation and security monitoring.
All ZeroTier traffic is encrypted end-to-end using secret keys that only you control. Most traffic flows peer to peer, though we offer free (but slow) relaying for users who cannot establish peer to peer connections.
The goals and design principles of ZeroTier are inspired by among other things the original [Google BeyondCorp](https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/43231.pdf) paper and the [Jericho Forum](https://en.wikipedia.org/wiki/Jericho_Forum) with its notion of "deperimeterization."
Visit [ZeroTier's site](https://www.zerotier.com/) for more information and [pre-built binary packages](https://www.zerotier.com/download/). Apps for Android and iOS are available for free in the Google Play and Apple app stores. Visit [ZeroTier's site](https://www.zerotier.com/) for more information and [pre-built binary packages](https://www.zerotier.com/download/). Apps for Android and iOS are available for free in the Google Play and Apple app stores.
ZeroTier is licensed under the [BSL version 1.1](https://mariadb.com/bsl11/). See [LICENSE.txt](LICENSE.txt) and the [ZeroTier pricing page](https://www.zerotier.com/pricing) for details. ZeroTier is free to use internally in businesses and academic institutions and for non-commercial purposes. Certain types of commercial use such as building closed-source apps and devices based on ZeroTier or offering ZeroTier network controllers and network management as a SaaS service require a commercial license.
A small amount of third party code is also included in ZeroTier and is not subject to our BSL license. See [AUTHORS.md](AUTHORS.md) for a list of third party code, where it is included, and the licenses that apply to it. All of the third party code in ZeroTier is liberally licensed (MIT, BSD, Apache, public domain, etc.).
### Getting Started ### Getting Started
Everything in the ZeroTier world is controlled by two types of identifier: 40-bit/10-digit *ZeroTier addresses* and 64-bit/16-digit *network IDs*. These identifiers are easily distinguished by their length. A ZeroTier address identifies a node or "device" (laptop, phone, server, VM, app, etc.) while a network ID identifies a virtual Ethernet network that can be joined by devices. Everything in the ZeroTier world is controlled by two types of identifier: 40-bit/10-digit *ZeroTier addresses* and 64-bit/16-digit *network IDs*. A ZeroTier address identifies a node or "device" (laptop, phone, server, VM, app, etc.) while a network ID identifies a virtual Ethernet network that can be joined by devices.
ZeroTier addresses can be thought of as port numbers on an enormous planet-wide enterprise Ethernet smart switch supporting VLANs. Network IDs are VLAN IDs to which these ports may be assigned. A single port can be assigned to more than one VLAN. Another way of thinking about it is that ZeroTier addresses are port numbers on a giant planetary-sized smart switch while network IDs are VLANs to which these ports can be assigned. For more details read about VL1 and VL2 in [the ZeroTier manual](https://www.zerotier.com/manual/).
A ZeroTier address looks like `8056c2e21c` and a network ID looks like `8056c2e21c000001`. Network IDs are composed of the ZeroTier address of that network's primary controller and an arbitrary 24-bit ID that identifies the network on this controller. Network controllers are roughly analogous to SDN controllers in SDN protocols like [OpenFlow](https://en.wikipedia.org/wiki/OpenFlow), though as with the analogy between VXLAN and VL2 this should not be read to imply that the protocols or design are the same. You can use our convenient and inexpensive SaaS hosted controllers at [my.zerotier.com](https://my.zerotier.com/) or [run your own controller](controller/) if you don't mind messing around with JSON configuration files or writing scripts to do so. *Network controllers* are ZeroTier nodes that act as access control certificate authorities and configuration managers for virtual networks. The first 40 bits (or 10 digits) of a network ID is the ZeroTier address of its controller. You can create networks with our [hosted controllers](https://my.zerotier.com/) and web UI/API or [host your own](controller/) if you don't mind posting some JSON configuration info or writing a script to do so.
### Project Layout ### Project Layout
@ -34,164 +24,86 @@ The base path contains the ZeroTier One service main entry point (`one.cpp`), se
- `controller/`: the reference network controller implementation, which is built and included by default on desktop and server build targets. - `controller/`: the reference network controller implementation, which is built and included by default on desktop and server build targets.
- `debian/`: files for building Debian packages on Linux. - `debian/`: files for building Debian packages on Linux.
- `doc/`: manual pages and other documentation. - `doc/`: manual pages and other documentation.
- `docker/`: Dockerfile to build as a container for containerized Linux systems and Kubernetes clusters.
- `ext/`: third party libraries, binaries that we ship for convenience on some platforms (Mac and Windows), and installation support files. - `ext/`: third party libraries, binaries that we ship for convenience on some platforms (Mac and Windows), and installation support files.
- `include/`: include files for the ZeroTier core. - `include/`: include files for the ZeroTier core.
- `java/`: a JNI wrapper used with our Android mobile app. (The whole Android app is not open source but may be made so in the future.) - `java/`: a JNI wrapper used with our Android mobile app. (The whole Android app is not open source but may be made so in the future.)
- `macui/`: a Macintosh menu-bar app for controlling ZeroTier One, written in Objective C.
- `node/`: the ZeroTier virtual Ethernet switch core, which is designed to be entirely separate from the rest of the code and able to be built as a stand-alone OS-independent library. Note to developers: do not use C++11 features in here, since we want this to build on old embedded platforms that lack C++11 support. C++11 can be used elsewhere. - `node/`: the ZeroTier virtual Ethernet switch core, which is designed to be entirely separate from the rest of the code and able to be built as a stand-alone OS-independent library. Note to developers: do not use C++11 features in here, since we want this to build on old embedded platforms that lack C++11 support. C++11 can be used elsewhere.
- `osdep/`: code to support and integrate with OSes, including platform-specific stuff only built for certain targets. - `osdep/`: code to support and integrate with OSes, including platform-specific stuff only built for certain targets.
- `rule-compiler/`: JavaScript rules language compiler for defining network-level rules. - `rule-compiler/`: JavaScript rules language compiler for defining network-level rules.
- `service/`: the ZeroTier One service, which wraps the ZeroTier core and provides VPN-like connectivity to virtual networks for desktops, laptops, servers, VMs, and containers. - `service/`: the ZeroTier One service, which wraps the ZeroTier core and provides VPN-like connectivity to virtual networks for desktops, laptops, servers, VMs, and containers.
- `windows/`: Visual Studio solution files, Windows service code, and the Windows task bar app UI. - `windows/`: Visual Studio solution files, Windows service code for ZeroTier One, and the Windows task bar app UI.
- `zeroidc/`: OIDC implementation used by ZeroTier service to log into SSO-enabled networks. (This part is written in Rust, and more Rust will be appearing in this repository in the future.)
### Contributing
Please do pull requests off of the `dev` branch.
Releases are done by merging `dev` into `main` and then tagging and doing builds.
### Build and Platform Notes ### Build and Platform Notes
To build on Mac and Linux just type `make`. On FreeBSD and OpenBSD `gmake` (GNU make) is required and can be installed from packages or ports. For Windows there is a Visual Studio solution in `windows/`. To build on Mac and Linux just type `make`. On FreeBSD and OpenBSD `gmake` (GNU make) is required and can be installed from packages or ports. For Windows there is a Visual Studio solution in `windows/'.
- **Mac** - **Mac**
- Xcode command line tools for macOS 10.13 or newer are required. - Xcode command line tools for OSX 10.8 or newer are required.
- Rust for x86_64 and ARM64 targets *if SSO is enabled in the build*.
- **Linux** - **Linux**
- The minimum compiler versions required are GCC/G++ 8.x or CLANG/CLANG++ 5.x. - The minimum compiler versions required are GCC/G++ 4.9.3 or CLANG/CLANG++ 3.4.2. (Install `clang` on CentOS 7 as G++ is too old.)
- Linux makefiles automatically detect and prefer clang/clang++ if present as it produces smaller and slightly faster binaries in most cases. You can override by supplying CC and CXX variables on the make command line. - Linux makefiles automatically detect and prefer clang/clang++ if present as it produces smaller and slightly faster binaries in most cases. You can override by supplying CC and CXX variables on the make command line.
- Rust for x86_64 and ARM64 targets *if SSO is enabled in the build*.
- **Windows** - **Windows**
- Visual Studio 2022 on Windows 10 or newer. - Windows 7 or newer is supported. This *may* work on Vista but isn't officially supported there. It will not work on Windows XP.
- Rust for x86_64 and ARM64 targets *if SSO is enabled in the build*. - We build with Visual Studio 2017. Older versions may not work. Clang or MinGW will also probably work but may require some makefile hacking.
- **FreeBSD** - **FreeBSD**
- GNU make is required. Type `gmake` to build. - GNU make is required. Type `gmake` to build.
- `binutils` is required. Type `pkg install binutils` to install.
- Rust for x86_64 and ARM64 targets *if SSO is enabled in the build*.
- **OpenBSD** - **OpenBSD**
- There is a limit of four network memberships on OpenBSD as there are only four tap devices (`/dev/tap0` through `/dev/tap3`). - There is a limit of four network memberships on OpenBSD as there are only four tap devices (`/dev/tap0` through `/dev/tap3`).
- GNU make is required. Type `gmake` to build. - GNU make is required. Type `gmake` to build.
- Rust for x86_64 and ARM64 targets *if SSO is enabled in the build*.
Typing `make selftest` will build a *zerotier-selftest* binary which unit tests various internals and reports on a few aspects of the build environment. It's a good idea to try this on novel platforms or architectures. Typing `make selftest` will build a *zerotier-selftest* binary which unit tests various internals and reports on a few aspects of the build environment. It's a good idea to try this on novel platforms or architectures.
### Running ### Running
Running *zerotier-one* with `-h` option will show help. Running *zerotier-one* with -h will show help.
On Linux and BSD, if you built from source, you can start the service with: On Linux and BSD you can start the service with:
sudo ./zerotier-one -d sudo ./zerotier-one -d
On most distributions, macOS, and Windows, the installer will start the service and set it up to start on boot.
A home folder for your system will automatically be created. A home folder for your system will automatically be created.
The service is controlled via the JSON API, which by default is available at `127.0.0.1:9993`. It also listens on `0.0.0.0:9993` which is only usable if `allowManagementFrom` is properly configured in `local.conf`. We include a *zerotier-cli* command line utility to make API calls for standard things like joining and leaving networks. The *authtoken.secret* file in the home folder contains the secret token for accessing this API. See [service/README.md](service/README.md) for API documentation. The service is controlled via the JSON API, which by default is available at 127.0.0.1 port 9993. We include a *zerotier-cli* command line utility to make API calls for standard things like joining and leaving networks. The *authtoken.secret* file in the home folder contains the secret token for accessing this API. See README.md in [service/](service/) for API documentation.
Here's where home folders live (by default) on each OS: Here's where home folders live (by default) on each OS:
* **Linux**: `/var/lib/zerotier-one` * **Linux**: `/var/lib/zerotier-one`
* **FreeBSD** / **OpenBSD**: `/var/db/zerotier-one` * **FreeBSD** / **OpenBSD**: `/var/db/zerotier-one`
* **Mac**: `/Library/Application Support/ZeroTier/One` * **Mac**: `/Library/Application Support/ZeroTier/One`
* **Windows**: `\ProgramData\ZeroTier\One` (That's the default. The base 'shared app data' folder might be different if Windows is installed with a non-standard drive letter assignment or layout.) * **Windows**: `\ProgramData\ZeroTier\One` (That's for Windows 7. The base 'shared app data' folder might be different on different Windows versions.)
### Basic Troubleshooting Running ZeroTier One on a Mac is the same, but OSX requires a kernel extension. We ship a signed binary build of the ZeroTier tap device driver, which can be installed on Mac with:
sudo make install-mac-tap
This will create the home folder for Mac, place *tap.kext* there, and set its modes correctly to enable ZeroTier One to manage it with *kextload* and *kextunload*.
### Troubleshooting
For most users, it just works. For most users, it just works.
If you are running a local system firewall, we recommend adding a rules permitting zerotier. If you installed binaries for Windows this should be done automatically. Other platforms might require manual editing of local firewall rules depending on your configuration. If you are running a local system firewall, we recommend adding a rule permitting UDP port 9993 inbound and outbound. If you installed binaries for Windows this should be done automatically. Other platforms might require manual editing of local firewall rules depending on your configuration.
See the [documentation site](https://docs.zerotier.com/zerotier/troubleshooting) for more information. The Mac firewall can be found under "Security" in System Preferences. Linux has a variety of firewall configuration systems and tools. If you're using Ubuntu's *ufw*, you can do this:
The Mac firewall can be found under "Security" in System Preferences. Linux has a variety of firewall configuration systems and tools. sudo ufw allow 9993/udp
On CentOS check `/etc/sysconfig/iptables` for IPTables rules. For other distributions consult your distribution's documentation. You'll also have to check the UIs or documentation for commercial third party firewall applications like Little Snitch (Mac), McAfee Firewall Enterprise (Windows), etc. if you are running any of those. Some corporate environments might have centrally managed firewall software, so you might also have to contact IT. On CentOS check `/etc/sysconfig/iptables` for IPTables rules. For other distributions consult your distribution's documentation. You'll also have to check the UIs or documentation for commercial third party firewall applications like Little Snitch (Mac), McAfee Firewall Enterprise (Windows), etc. if you are running any of those. Some corporate environments might have centrally managed firewall software, so you might also have to contact IT.
ZeroTier One peers will automatically locate each other and communicate directly over a local wired LAN *if UDP port 9993 inbound is open*. If that port is filtered, they won't be able to see each others' LAN announcement packets. If you're experiencing poor performance between devices on the same physical network, check their firewall settings. Without LAN auto-location peers must attempt "loopback" NAT traversal, which sometimes fails and in any case requires that every packet traverse your external router twice. ZeroTier One peers will automatically locate each other and communicate directly over a local wired LAN *if UDP port 9993 inbound is open*. If that port is filtered, they won't be able to see each others' LAN announcement packets. If you're experiencing poor performance between devices on the same physical network, check their firewall settings. Without LAN auto-location peers must attempt "loopback" NAT traversal, which sometimes fails and in any case requires that every packet traverse your external router twice.
Users behind certain types of firewalls and "symmetric" NAT devices may not be able to connect to external peers directly at all. ZeroTier has limited support for port prediction and will *attempt* to traverse symmetric NATs, but this doesn't always work. If P2P connectivity fails you'll be bouncing UDP packets off our relay servers resulting in slower performance. Some NAT router(s) have a configurable NAT mode, and setting this to "full cone" will eliminate this problem. If you do this you may also see a magical improvement for things like VoIP phones, Skype, BitTorrent, WebRTC, certain games, etc., since all of these use NAT traversal techniques similar to ours. Users behind certain types of firewalls and "symmetric" NAT devices may not able able to connect to external peers directly at all. ZeroTier has limited support for port prediction and will *attempt* to traverse symmetric NATs, but this doesn't always work. If P2P connectivity fails you'll be bouncing UDP packets off our relay servers resulting in slower performance. Some NAT router(s) have a configurable NAT mode, and setting this to "full cone" will eliminate this problem. If you do this you may also see a magical improvement for things like VoIP phones, Skype, BitTorrent, WebRTC, certain games, etc., since all of these use NAT traversal techniques similar to ours.
If you're interested, there's a [technical deep dive about NAT traversal on our blog](https://www.zerotier.com/blog/?p=226?pk_campaign=github_ZeroTierOne). A troubleshooting tool to help you diagnose NAT issues is planned for the future as are uPnP/IGD/NAT-PMP and IPv6 transport.
If a firewall between you and the Internet blocks ZeroTier's UDP traffic, you will fall back to last-resort TCP tunneling to rootservers over port 443 (https impersonation). This will work almost anywhere but is *very slow* compared to UDP or direct peer to peer connectivity. If a firewall between you and the Internet blocks ZeroTier's UDP traffic, you will fall back to last-resort TCP tunneling to rootservers over port 443 (https impersonation). This will work almost anywhere but is *very slow* compared to UDP or direct peer to peer connectivity.
Additional help can be found in our [knowledge base](https://zerotier.atlassian.net/wiki/spaces/SD/overview). ### Contributing
### Prometheus Metrics Please make pull requests against the `dev` branch. The `master` branch is release, and `edge` is for unstable and work in progress changes and is not likely to work.
Prometheus Metrics are available at the `/metrics` API endpoint. This endpoint is protected by an API key stored in `metricstoken.secret` to prevent unwanted information leakage. Information that could be gleaned from the metrics include joined networks and peers your instance is talking to. ### License
Access control is via the ZeroTier control interface itself and `metricstoken.secret`. This can be sent as a bearer auth token, via the `X-ZT1-Auth` HTTP header field, or appended to the URL as `?auth=<token>`. You can see the current metrics via `cURL` with the following command: The ZeroTier source code is open source and is licensed under the GNU GPL v3 (not LGPL). If you'd like to embed it in a closed-source commercial product or appliance, please e-mail [contact@zerotier.com](mailto:contact@zerotier.com) to discuss commercial licensing. Otherwise it can be used for free.
// Linux
curl -H "X-ZT1-Auth: $(sudo cat /var/lib/zerotier-one/metricstoken.secret)" http://localhost:9993/metrics
// macOS
curl -H "X-ZT1-Auth: $(sudo cat /Library/Application\ Support/ZeroTier/One/metricstoken.secret)" http://localhost:9993/metrics
// Windows PowerShell (Admin)
Invoke-RestMethod -Headers @{'X-ZT1-Auth' = "$(Get-Content C:\ProgramData\ZeroTier\One\metricstoken.secret)"; } -Uri http://localhost:9993/metrics
To configure a scrape job in Prometheus on the machine ZeroTier is running on, add this to your Prometheus `scrape_config`:
- job_name: zerotier-one
honor_labels: true
scrape_interval: 15s
metrics_path: /metrics
static_configs:
- targets:
- 127.0.0.1:9993
labels:
group: zerotier-one
node_id: $YOUR_10_CHARACTER_NODE_ID
authorization:
credentials: $YOUR_METRICS_TOKEN_SECRET
If neither of these methods are desirable, it is probably possible to distribute metrics via [Prometheus Proxy](https://github.com/pambrose/prometheus-proxy) or some other tool. Note: We have not tested this internally, but will probably work with the correct configuration.
Metrics are also available on disk in ZeroTier's working directory:
// Linux
/var/lib/zerotier-one/metrics.prom
// macOS
/Library/Application\ Support/ZeroTier/One/metrics.prom
//Windows
C:\ProgramData\ZeroTier\One\metrics.prom
#### Available Metrics
| Metric Name | Labels | Metric Type | Description |
| --- | --- | --- | --- |
| zt_packet | packet_type, direction | Counter | ZeroTier packet type counts |
| zt_packet_error | error_type, direction | Counter | ZeroTier packet errors|
| zt_data | protocol, direction | Counter | number of bytes ZeroTier has transmitted or received |
| zt_num_networks | | Gauge | number of networks this instance is joined to |
| zt_network_multicast_groups_subscribed | network_id | Gauge | number of multicast groups networks are subscribed to |
| zt_network_packets | network_id, direction | Counter | number of incoming/outgoing packets per network |
| zt_peer_latency | node_id | Histogram | peer latency (ms) |
| zt_peer_path_count | node_id, status | Gauge | number of paths to peer |
| zt_peer_packets | node_id, direction | Counter | number of packets to/from a peer |
| zt_peer_packet_errors | node_id | Counter | number of incoming packet errors from a peer |
If there are other metrics you'd like to see tracked, ask us in an Issue or send us a Pull Request!
### HTTP / App server
There is a static http file server suitable for hosting Single Page Apps at http://localhost:9993/app/<app-path>
Use `zerotier-cli info -j` to find your zerotier-one service's homeDir
``` sh
cd $ZT_HOME
sudo mkdir -p app/app1
sudo mkdir -p app/appB
echo '<html><meta charset=utf-8><title>appA</title><body><h1>hello world A' | sudo tee app/appA/index.html
echo '<html><meta charset=utf-8><title>app2</title><body><h1>hello world 2' | sudo tee app/app2/index.html
curl -sL http://localhost:9993/app/appA http://localhost:9993/app/app2
```
Then visit [http://localhost:9993/app/app1/](http://localhost:9993/app/app1/) and [http://localhost:9993/app/appB/](http://localhost:9993/app/appB/)
Requests to paths don't exist return the app root index.html, as is customary for SPAs.
If you want, you can write some javascript that talks to the service or controller [api](https://docs.zerotier.com/service/v1).

View file

@ -1,294 +1,6 @@
ZeroTier Release Notes ZeroTier Release Notes
====== ======
# 2024-10-23 -- Version 1.14.2
* Fix for missing entitlement on macOS Sequoia.
* Fix for a problem correctly parsing local.conf to enable low bandwidth mode.
* Increment versions of some dependent libraries.
* Other fixes.
# 2024-09-12 -- Version 1.14.1
* Multithreaded packet I/O support! Currently this is just for Linux and must
be enabled in local.conf. It will likely make the largest difference on small
multi-core devices where CPU is a bottleneck and high throughput is desired.
It may be enabled by default in the future but we want it to be thoroughly
tested. It's a little harder than it seems at first glance due to the need
to keep packets in sequence and balance load.
* Several multipath bug fixes.
* Updated the versions on a number of libraries related to OIDC support and HTTP.
* MacOS .app now shows the correct version in its Info.plist manifest.
* Sanitize MAC addresses in JSON format rules parser.
* Some basic information about the platform (OS, CPU architecture) is now reported
to network controllers when networks are joined so it can be displayed to
network admins and in the future used in policy checking and inventory operations.
# 2024-05-02 -- Version 1.14.0
* Linux I/O performance improvements under heavy load
* Improvements to multipath
* Fix for port rebinding "coma" bug after periods offline (some laptop users)
* Fixed a rules engine quirk/ambiguity (GitHub Issue #2200)
* Controller API enhancements: node names and other node meta-data
* Other bug fixes
# 2023-09-12 -- Version 1.12.2
* More improvements to macOS full tunnel mode.
* Faster recovery after changes to physical network settings.
# 2023-08-25 -- Version 1.12.1
* Minor release to fix a port binding issue in Linux.
* Update Debian dependencies.
* No changes for other platforms.
# 2023-08-23 -- Version 1.12.0
* Experimental Windows ARM64 support
* Fix numerous sleep/wake issues on macOS and other platforms
* Faster recovery after changes to physical network settings
* Prometheus compatible metrics support!
* Fix full tunnel mode on recent macOS versions
* Numerous macOS DNS fixes
* 10-30% speed improvement on Linux
# 2023-03-23 -- Version 1.10.6
* Prevent binding temporary ipv6 addresses on macos (#1910)
* Prevent path-learning loops (#1914)
* Prevent infinite loop of UAC prompts in tray app
# 2023-03-10 -- Version 1.10.5
* Fix for high CPU usage bug on Windows
# 2023-03-07 -- Version 1.10.4
* SECURITY FIX (Windows): this version fixes a file permission problem on
Windows that could allow non-privileged users on a Windows system to read
privileged files in the ZeroTier service's working directory. This could
allow an unprivileged local Windows user to administrate the local ZeroTier
instance without appropriate local permissions. This issue is not remotely
exploitable unless a remote user can read arbitrary local files, and does
not impact other operating systems.
* Fix a bug in the handling of multiple IP address assignments to virtual
interfaces on macOS.
# 2023-02-15 -- Version 1.10.3
* Fix for duplicate paths in client. Could cause connectivity issues. Affects all platforms.
* Fix for Ethernet Tap MTU setting, would not properly apply on Linux.
* Fix default route bugs (macOS.)
* Enable Ping automatically for ZeroTier Adapters (Windows.)
* SSO updates and minor bugfixes.
* Add low-bandwidth mode.
* Add forceTcpRelay mode (optionally enabled.)
* Fix bug that prevented setting of custom TCP relay address.
* Build script improvements and bug fixes.
# 2022-11-01 -- Version 1.10.2
* Fix another SSO "stuck client" issue in zeroidc.
* Expose root-reported external IP/port information via the local JSON API for better diagnostics.
* Multipath: CLI output improvement for inspecting bonds
* Multipath: balance-aware mode
* Multipath: Custom policies
* Multipath: Link quality measurement improvements
Note that releases are coming few and far between because most of our dev effort is going into version 2.
# 2022-06-27 -- Version 1.10.1
* Fix an issue that could cause SSO clients to get "stuck" on stale auth URLs.
* A few other SSO related bug fixes.
# 2022-06-07 -- Version 1.10.0
* Fix formatting problem in `zerotier-cli` when using SSO networks.
* Fix a few other minor bugs in SSO signin to prepare for general availability.
* Remove requirement for webview in desktop UI and instead just make everything available via the tray pulldown/menu. Use [libui-ng](https://github.com/libui-ng/libui-ng) for minor prompt dialogs. Saves space and eliminates installation headaches on Windows.
* Fix SSO "spam" bug in desktop UI.
* Use system default browser for SSO login so all your plugins, MFA devices, password managers, etc. will work as you have them configured.
* Minor fix for bonding/multipath.
# 2022-05-10 -- Version 1.8.10
* Fixed a bug preventing SSO sign-on on Windows.
# 2022-04-25 -- Version 1.8.9
* Fixed a long-standing and strange bug that was causing sporadic "phantom" packet authentication failures. Not a security problem but could be behind sporadic reports of link failures under some conditions.
* Fixed a memory leak in SSO/OIDC support.
* Fixed SSO/OIDC display error on CLI.
* Fixed a bug causing nodes to sometimes fail to push certs to each other (primarily affects SSO/OIDC use cases).
* Fixed a deadlock bug on leaving SSO/OIDC managed networks.
* Added some new Linux distributions to the build subsystem.
# 2022-04-11 -- Version 1.8.8
* Fix a local privilege escalation bug in the Windows installer.
* Dependency fix for some Ubuntu versions.
* No changes for other platforms. Windows upgrade recommended, everyone else optional.
# 2022-03-30 -- Version 1.8.7
* Fix for dependency installations in Windows MSI package.
* Fix for desktop UI setup when run by a non-super-user.
* Bug fix in local OIDC / SSO support for auth0 and other providers.
* Other minor fixes for e.g. old Linux distributions.
# 2022-03-04 -- Version 1.8.6
* Fixed an issue that could cause the UI to be non-responsive if not joined to any networks.
* Fix dependency issues in Debian and RedHat packages for some distributions (Fedora, Mint).
* Bumped the peer cache serialization version to prevent "coma" issues on upgrade due to changes in path logic behaving badly with old values.
# 2022-02-22 -- Version 1.8.5
* Plumbing under the hood for endpoint device SSO support.
* Fix in LinuxEthernetTap to tap device support on very old (2.6) Linux kernels.
* Fix an issue that could cause self-hosted roots ("moons") to fail to assist peers in making direct links. (GitHub issue #1512)
* Merge a series of changes by Joseph Henry (of ZeroTier) that should fix some edge cases where ZeroTier would "forget" valid paths.
* Minor multipath improvements for automatic path negotiation.
# 2021-11-30 -- Version 1.8.4
* Fixed an ugly font problem on some older macOS versions.
* Fixed a bug that could cause the desktop tray app control panel to stop opening after a while on Windows.
* Fixed a possible double "release" in macOS tray app code that crashed on older macOS versions.
* Fixed installation on 32-bit Windows 10.
* Fixed a build flags issue that could cause ZeroTier to crash on older ARM32 CPUs.
# 2021-11-15 -- Version 1.8.3
* Remove problematic spinlock, which was only used on x86_64 anyway. Just use pthread always.
* Fix fd leak on MacOS that caused non-responsiveness after some time.
* Fix Debian install scripts to set /usr/sbin/nologin as shell on service user.
* Fix regression that could prevent managed routes from being deleted.
* DesktopUI: Remove NSDate:now() call, now works on MacOS 10.13 or newer!
# 2021-11-08 -- Version 1.8.2
* Fix multicast on linux.
* Fix a bug that could cause the tap adapter to have the wrong MAC on Linux.
* Update build flags to possibly support MacOS older than 10.14, but more work needs to be done. It may not work yet.
* Fix path variable setting on Windows.
# 2021-10-28 -- Version 1.8.1
* Fix numerous UI issues from 1.8.0 (never fully released).
* Remove support for REALLY ancient 1.1.6 or earlier network controllers.
* MacOS IPv6 no longer binds to temporary addresses as these can cause interruptions if they expire.
* Added additional hardening against address impersonation on networks (also in 1.6.6).
* Fix an issue that could cause clobbering of MacOS IP route settings on restart.
* NOTE: Windows 7 is no longer supported! Windows 7 users will have to use version 1.6.5 or earlier.
# 2021-09-15 -- Version 1.8.0 (preview release only)
* A *completely* rewritten desktop UI for Mac and Windows!
* Implement a workaround for one potential source of a "coma" bug, which can occur if buggy NATs/routers stop allowing the service to communicate on a given port. ZeroTier now reassigns a new secondary port if it's offline for a while unless a secondary port is manually specified in local.conf. Working around crummy buggy routers is an ongoing effort.
* Fix for MacOS MTU capping issue on feth devices
* Fix for mistakenly using v6 source addresses for v4 routes on some platforms
* Stop binding to temporary IPv6 addresses
* Set MAC address before bringing up Linux TAP link
* Check if DNS servers need to be applied on macOS
* Upgrade json.hpp dependency to version 3.10.2
# 2021-09-21 -- Version 1.6.6
* Backport COM hash check mitigation against network member impersonation.
# 2021-04-13 -- Version 1.6.5
* Fix a bug in potential network path filtering that could in some circumstances lead to "software laser" effects.
* Fix a printf overflow in zerotier-cli (not exploitable or a security risk)
* Windows now looks up the name of ZeroTier devices instead of relying on them having "ZeroTier" in them.
# 2021-02-15 -- Version 1.6.4
* The groundhog saw his shadow, which meant that the "connection coma" bug still wasn't gone. We think we found it this time.
# 2021-02-02 -- Version 1.6.3
* Likely fix for GitHub issue #1334, an issue that could cause ZeroTier to
go into a "coma" on some networks.
* Also groundhog day
# 2020-11-30 -- Version 1.6.2
* Fix an ARM hardware AES crypto issue (not an exploitable vulnerability).
* Fix a Linux network leave hang due to a mutex deadlock.
# 2020-11-24 -- Version 1.6.1
This release fixes some minor bugs and other issues in 1.6.0.
* Fixed a bug that caused IP addresses in the 203.0.0.0/8 block to be miscategorized as not being in global scope.
* Changed Linux builds to (hopefully) fix LXC and SELinux issues.
* Fixed unaligned memory access that caused crash on FreeBSD systems on the ARM architecture.
* Merged CLI options for controlling bonded devices into the beta multipath code.
* Updated Windows driver with Microsoft cross-signing to fix issues on some Windows systems.
# 2020-11-19 -- Version 1.6.0
Version 1.6.0 is a major release that incorporates back-ported features from the 2.0 branch, which is still under development. It also fixes a number of issues.
New features and improvements (including those listed under 1.5.0):
* **Apple Silicon** (MacOS ARM64) native support via universal binary. ZeroTier now requires the very latest Xcode to build.
* **Linux performance improvements** for up to 25% faster tun/tap I/O performance on multi-core systems.
* **Multipath support** with modes modeled after the Linux kernel's bonding driver. This includes active-passive and active-active modes with fast failover and load balancing. See section 2.1.5 of the manual.
* **DNS configuration** push from network controllers to end nodes, with locally configurable permissions for whether or not push is allowed.
* **AES-GMAC-SIV** encryption mode, which is both somewhat more secure and significantly faster than the old Salsa20/12-Poly1305 mode on hardware that supports AES acceleration. This includes virtually all X86-64 chips and most ARM64. This mode is based on AES-SIV and has been audited by Trail of Bits to ensure that it is equivalent security-wise.
Bug fixes:
* **Managed route assignment fixes** to eliminate missing routes on Linux and what we believe to be the source of sporadic high CPU usage on MacOS.
* **Hang on shutdown** issues should be fixed.
* **Sporadic multicast outages** should be fixed.
Known remaining issues:
* AES hardware acceleration is not yet supported on 32-bit ARM, PowerPC (32 or 64), or MIPS (32 or 64) systems. Currently supported are X86-64 and ARM64/AARCH64 with crypto extensions.
# 2020-10-05 -- Version 1.5.0 (actually 1.6.0-beta1)
Version 1.6.0 (1.5.0 is a beta!) is a significant release that incorporates a number of back-ported fixes and features from the ZeroTier 2.0 tree.
Major new features are:
* **Multipath support** with modes modeled after the Linux kernel's bonding driver. This includes active-passive and active-active modes with fast failover and load balancing. See section 2.1.5 of the manual.
* **DNS configuration** push from network controllers to end nodes, with locally configurable permissions for whether or not push is allowed.
* **AES-GMAC-SIV** encryption mode, which is both somewhat more secure and significantly faster than the old Salsa20/12-Poly1305 mode on hardware that supports AES acceleration. This includes virtually all X86-64 chips and most ARM64. This mode is based on AES-SIV and has been audited by Trail of Bits to ensure that it is equivalent security-wise.
Known issues that are not yet fixed in this beta:
* Some Mac users have reported periods of 100% CPU in kernel_task and connection instability after leaving networks that have been joined for a period of time, or needing to kill ZeroTier and restart it to finish leaving a network. This doesn't appear to affect all users and we haven't diagnosed the root cause yet.
* The service sometimes hangs on shutdown requiring a kill -9. This also does not affect all systems or users.
* AES hardware acceleration is not yet supported on 32-bit ARM, PowerPC (32 or 64), or MIPS (32 or 64) systems. Currently supported are X86-64 and ARM64/AARCH64 with crypto extensions.
* Some users have reported multicast/broadcast outages on networks lasting up to 30 seconds. Still investigating.
We're trying to fix all these issues before the 1.6.0 release. Stay tuned.
# 2019-08-30 -- Version 1.4.6
* Update default root list to latest
* ARM32 platform build and flag fixes
* Add a clarification line to LICENSE.txt
* Fix license message in CLI
* Windows service now looks for service command line arguments
* Fixed a bug that could cause excessive queued multicasts
# 2019-08-23 -- Version 1.4.4
* Change license from GPL3 to BSL 1.1, see LICENSE.txt
* Fix an issue with the "ipauth" rule and auto-generated unforgeable IPv6 addresses
* Fix socket/bind errors setting IPs and routes on Linux
# 2019-08-12 -- Version 1.4.2 # 2019-08-12 -- Version 1.4.2
* Fix high CPU use bug on some platforms * Fix high CPU use bug on some platforms
@ -372,7 +84,7 @@ We're trying to fix all these issues before the 1.6.0 release. Stay tuned.
# 2017-04-20 -- Version 1.2.4 # 2017-04-20 -- Version 1.2.4
* Managed routes are now only bifurcated for the default route. This is a change in behavior, though few people will probably notice. Bifurcating all managed routes was causing more trouble than it was worth for most users. * Managed routes are now only bifurcated for the default route. This is a change in behavior, though few people will probably notice. Bifurcating all managed routes was causing more trouble than it was worth for most users.
* Up to 2X crypto speedup on x86-64 (except Windows, which will take some porting) and 32-bit ARM platforms due to integration of fast assembly language implementations of Salsa20/12 from the [supercop](http://bench.cr.yp.to/supercop.html) code base. These were written by Daniel J. Bernstein and are in the public domain. My MacBook Pro (Core i5 2.8ghz) now does almost 1.5GiB/sec Salsa20/12 per core and a Raspberry Pi got a 2X boost. 64-bit ARM support and Windows support will take some work but should not be too hard. * Up to 2X crypto speedup on x86-64 (except Windows, which will take some porting) and 32-bit ARM platforms due to integration of fast assembly language implementations of Salsa20/12 from the [supercop](http://bench.cr.yp.to/supercop.html) code base. These were written by Daniel J. Bernstein and are in the public domain. My Macbook Pro (Core i5 2.8ghz) now does almost 1.5GiB/sec Salsa20/12 per core and a Raspberry Pi got a 2X boost. 64-bit ARM support and Windows support will take some work but should not be too hard.
* Refactored code that manages credentials to greatly reduce memory use in most cases. This may also result in a small performance improvement. * Refactored code that manages credentials to greatly reduce memory use in most cases. This may also result in a small performance improvement.
* Reworked and simplified path selection and priority logic to fix path instability and dead path persistence edge cases. There have been some sporadic reports of persistent path instabilities and dead paths hanging around that take minutes to resolve. These have proven difficult to reproduce in house, but hopefully this will fix them. In any case it seems to speed up path establishment in our tests and it makes the code simpler and more readable. * Reworked and simplified path selection and priority logic to fix path instability and dead path persistence edge cases. There have been some sporadic reports of persistent path instabilities and dead paths hanging around that take minutes to resolve. These have proven difficult to reproduce in house, but hopefully this will fix them. In any case it seems to speed up path establishment in our tests and it makes the code simpler and more readable.
* Eliminated some unused cruft from the code around path management and in the peer class. * Eliminated some unused cruft from the code around path management and in the peer class.

View file

@ -1,93 +0,0 @@
# Security
ZeroTier takes the security of our software products and services seriously, which
includes all source code repositories managed through our GitHub organization.
## Supported Versions
The following versions of ZeroTier One receive security updates
| Version | Supported |
| -------- | ------------------ |
| 1.14.x | :white_check_mark: |
| 1.12.x | :white_check_mark: |
| < 1.12.0 | :x: |
## Reporting a Vulnerability
**Please do not report security issues through public GitHub issues**
Instead, please report vulnerabilities via email to security@zerotier.com. If possible,
please encrypt with our PGP key (see below).
Please include the following information, or as much as you can provide to help us
understand the nature and scope of the issue:
* Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
* Full paths of source file(s) related to the manifestation of the issue
* The location of the affected source code (tag/branch/commit or direct URL)
* Any special configuration required to reproduce the issue
* Step-by-step instructions to reproduce the issue
* Proof-of-concept or exploit code (if possible)
* Impact of the issue, including how an attacker might exploit the issue
## Preferred Languages
We prefer all communications to be in English.
## security@zerotier.com PGP key
```
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBGQGOVIBEACalXTnNqaiSOVLFEiqHpDMg8N/OI5D5850Xy1ZEvx3B3rz7cbn
k30ozHtJKbh+vqpyItE7DjyQAuF19gP5Q64Yh0Y+MmLHq60q/GwOwAYz7cI+UzA3
5x8YqcmTp32LAM1xJn+iMlMLBuAmJl4kULKmOXPlpqPiyTFs5saizvm7fgRmfgJJ
HpsnIrTkaDFJhAR+jvMJohVYwmhuydeI0DsHu7KGpG1ddcHDrUjOPNqXnnAPSPwx
llw4yfKlQb8GYErsv/G5QVyzd5+SxEuiI4MARRnrk8LlMQ33CR6pzIQ/Bk5AAmye
mHqfEAknkiOf++urYhRs9BL3Kz3MdV0cg92zr9EFOg0u56jxf5OnAiTOhGUUA0hn
dS7peVGl46R9Oy2JYIazNDGi+4NIsYDFXsnsss9xOQVygPyeQd71zFHfix0jct9w
j3o/kj7Egsnm9nc13354bYT6bbalqXiRWwGH1eAFpjueNWiVFwZS6NZUP3WeNDiY
BlPo1LodvolbXiJcTILTCyEkERJPCK2zoE2nTdVfvTLWsuehw1M6Yd2/q74TVYy/
RY+KjHkrChEBQ9PqXsXRHj6opKbT8JLfZkvU5k+3IiqqxOpB+QXFI/whj493CxWW
so7QAmzOCyJq8GDVPxzkwUac22YIkXdiOmb8i/HWq+kLY/HjQE259Gx6KwARAQAB
tClaZXJvVGllciBTZWN1cml0eSA8c2VjdXJpdHlAemVyb3RpZXIuY29tPokCTAQT
AQoANhYhBH1HQGb+4jzl6mnFqf09m6uqADkABQJkBjlSAhsDBAsJCAcEFQoJCAUW
AgMBAAIeAQIXgAAKCRD9PZurqgA5ACqPD/sFt6SG6Tu0HwTY2ofJtYsa2GBLL0pf
dYlX4cWSs1PVB5+m5Oj18y+GB2umA9GnsVtmvaSfp3XEngt2zNWX27uUsVfL35b2
/5TVVe8RjzOedqMN+lQWMvO+f/C1zmWYXjjpC+iGjgMMaRRrofkkn+7uL4N9y6gY
rcXtpACT1rYFC+i1AKnZfUO8Vr5ji7odq0f7bDkN/N38rB0kRRwEmO8wqdpQK6gK
nxf9vgJl5ggimDk5Xtz1sfd3y28bf5N4hdOCkXUbd10nUFY3wDNTM4VxozxTGJeG
imdcc19Wuw/1fGUZ5SIjgPanCdPLGYwSTr+M6Fuern9uTtlC1GOby3BUtmVGP6EU
1pSAJSRpmoBPHKKOYtSMwV8PCboXru9P1ab8y8STKM3SKyghUJrl17gdc0LaksZa
E54pJudGPIQMFRqZjMdV6jgMuaLTozjZ4mW8EThf4mkX4xDkO8l7cOn0225ZYJZC
lZKpdnwzk9owkJA80u4KBNJxTtB4ZAPzjBsD5hFzCZQTLNQp/psU3EjZsau28eXT
E/C1QjEQHgy4ohkgQlCm1H1+clKssCWcdmsVGXuS1u8gh4K6X9b0Z6LeCGRaQvH2
+DB8oTAdqp9nUZv9rP4pbo+sR4fF67CFLriVuxjedAiFkbM4uHMFcL4tc/X9+DRo
YN5X7oEkZvO507kCDQRkBjlSARAAz58UMF7K1qKyQjzKTcutaYZ5SaIGky9lCLZn
/2vjpFCoBogkxS/6IKQcwZk8b4S9QstaaQZDFEkxqNeKC0GiFTAMAb6SmYcK495h
EZnHl0NA5Nc2dBlZk5E/ENzTCz2bXaxCcVESc2z+xCzu07brbhGrqvliKiwOUzt9
JzqEsar6I95OutBcZvkFCs44/Uf9bS1qf1w4klE8w3vdMtGH23umrET4tFZ+sh6o
ZFtQx0u2eKjsRdn/RMtsxLNaJlcE1DdIAqBpQrcmuwMC8v5wUGfCGZjhClzmyQlq
akUkayir7UtbHbFT/mgO+YI77YGXWk5QrwPscqqT2l8KB/YMujNDmaWa/0KV1lIY
zr5s4dzVeiwqFLR9ANFIhzFwzf3JLi6XSx123Qix0TxZoYPZCHl7yoi9qi6qybz5
0Od2LSz3jbApeKYymZ+zjE+YV5y9DI6Wzy1j2M1FogNvTO9fMk+6dLt4HhTdSNvH
cKya462YCcy+tnZTkhmh+FTebbJlV6D4wG7skE5KCdBhjm53xLwp6XW9L6n2CrkL
W1IDBcCz0oPd1sMkXbO3wnxdXprV2XurCfsg/R2nszSNzvdJ8/xj3cr9hpoJ714R
qqyoEDRZ1Ss9kGL166o5MpN5qb/EewdkqGgWP7YFXbhsdHQiW7Z7dAqzjoaybD4O
nakkwyUAEQEAAYkCNgQYAQoAIBYhBH1HQGb+4jzl6mnFqf09m6uqADkABQJkBjlS
AhsMAAoJEP09m6uqADkAax0P/Rh8EZYRqW6dPYTl1YQusAK10rAcRNq3ekjofXGk
oXK1S7HWGoFgl5++5nfSfNgFJ5VLcgIM56wtIf49zFjWe5oC6fw8k+ghh4d2chMP
hdDILx6e0c30Iq1+EvovGR9hWa0wJ4cKTdzlwhY9ZC09q0ia+bl2mwpie1JQDR0c
zXCjt+PldLeeK9z1/XT0Q7KowYC+U18oR+KFm+EaRV4QT85JVequnIeGkmaHJrHB
lH4T5A5ib7y8edon1c0Zx3GsaxJUojkEJ0SX7ffVDu6ztUZfkHfCVpMW4VzUeGA/
m+CtFO9ciLRGZEkRa+zhIGoBvwEXU0GiwiF4nZ0F2C8UioeW0YIEV9zl3nXJctYE
ZKc2whSENQRTGgaYHVoVZhznt71LKWgFLshwBo81UCXVkzwAjMW1ActDnmPw5M7q
xR5Qp5G49Z1GmfSozazha0HVFPKNV5i3RlTzs4yLUnZyH0yC9IvtOefMHcLjG96L
N5miEV97gvJJjrn8rhRvpUwAWgmT/9IuYjBNQTtNN40arto5HxezR76WCjdKYxdL
p3dM1iiBDShHNm7LdyZlLFhTOMU0tNBxJJ7B09ar5gakeZjD+2aB1ODX9VuFtozL
onBjI2gIkry0UIkuznHfFw05lZAZAiqHEVgVi/WTk4C/bklDZNgE0lx+IWzEz2iS
L455
=lheL
-----END PGP PUBLIC KEY BLOCK-----
```

View file

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View file

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict/>
</plist>

View file

@ -1,3 +1,3 @@
#!/bin/bash #!/bin/bash
c++ -std=c++11 -I../.. -I../../ext -I.. -g -o mkworld ../../node/C25519.cpp ../../node/Salsa20.cpp ../../node/SHA512.cpp ../../node/Identity.cpp ../../node/Utils.cpp ../../node/InetAddress.cpp ../../osdep/OSUtils.cpp mkworld.cpp -lm c++ -std=c++11 -I../.. -I.. -O -o mkworld ../../node/C25519.cpp ../../node/Salsa20.cpp ../../node/SHA512.cpp ../../node/Identity.cpp ../../node/Utils.cpp ../../node/InetAddress.cpp ../../osdep/OSUtils.cpp mkworld.cpp -lm

View file

@ -81,63 +81,44 @@ int main(int argc,char **argv)
std::vector<World::Root> roots; std::vector<World::Root> roots;
const uint64_t id = ZT_WORLD_ID_EARTH; const uint64_t id = ZT_WORLD_ID_EARTH;
const uint64_t ts = 1567191349589ULL; // August 30th, 2019 const uint64_t ts = 1562631342273ULL; // July 8th, 2019
// Los Angeles
roots.push_back(World::Root()); roots.push_back(World::Root());
roots.back().identity = Identity("3a46f1bf30:0:76e66fab33e28549a62ee2064d1843273c2c300ba45c3f20bef02dbad225723bb59a9bb4b13535730961aeecf5a163ace477cceb0727025b99ac14a5166a09a3"); roots.back().identity = Identity("3a46f1bf30:0:76e66fab33e28549a62ee2064d1843273c2c300ba45c3f20bef02dbad225723bb59a9bb4b13535730961aeecf5a163ace477cceb0727025b99ac14a5166a09a3");
roots.back().stableEndpoints.push_back(InetAddress("185.180.13.82/9993")); roots.back().stableEndpoints.push_back(InetAddress("185.180.13.82/9993"));
roots.back().stableEndpoints.push_back(InetAddress("2a02:6ea0:c815::/9993")); roots.back().stableEndpoints.push_back(InetAddress("2a02:6ea0:c815::/9993"));
// Miami
roots.push_back(World::Root());
roots.back().identity = Identity("de8950a8b2:0:1b3ada8251b91b6b6fa6535b8c7e2460918f4f729abdec97d3c7f3796868fb02f0de0b0ee554b2d59fc3524743eebfcf5315e790ed6d92db5bd10c28c09b40ef");
roots.back().stableEndpoints.push_back(InetAddress("207.246.73.245/443"));
roots.back().stableEndpoints.push_back(InetAddress("2001:19f0:9002:5cb:ec4:7aff:fe8f:69d9/443"));
// Tokyo
roots.push_back(World::Root());
roots.back().identity = Identity("34e0a5e174:0:93efb50934788f856d5cfb9ca5be88e85b40965586b75befac900df77352c145a1ba7007569d37c77bfe52c0999f3bdc67a47a4a6000b720a883ce47aa2fb7f8");
roots.back().stableEndpoints.push_back(InetAddress("147.75.92.2/443"));
roots.back().stableEndpoints.push_back(InetAddress("2604:1380:3000:7100::1/443"));
// Amsterdam
roots.push_back(World::Root());
roots.back().identity = Identity("992fcf1db7:0:206ed59350b31916f749a1f85dffb3a8787dcbf83b8c6e9448d4e3ea0e3369301be716c3609344a9d1533850fb4460c50af43322bcfc8e13d3301a1f1003ceb6");
roots.back().stableEndpoints.push_back(InetAddress("195.181.173.159/443"));
roots.back().stableEndpoints.push_back(InetAddress("2a02:6ea0:c024::/443"));
// Alice // Alice
//roots.push_back(World::Root()); roots.push_back(World::Root());
//roots.back().identity = Identity("9d219039f3:0:01f0922a98e3b34ebcbff333269dc265d7a020aab69d72be4d4acc9c8c9294785771256cd1d942a90d1bd1d2dca3ea84ef7d85afe6611fb43ff0b74126d90a6e"); roots.back().identity = Identity("9d219039f3:0:01f0922a98e3b34ebcbff333269dc265d7a020aab69d72be4d4acc9c8c9294785771256cd1d942a90d1bd1d2dca3ea84ef7d85afe6611fb43ff0b74126d90a6e");
//roots.back().stableEndpoints.push_back(InetAddress("188.166.94.177/9993")); // Amsterdam roots.back().stableEndpoints.push_back(InetAddress("188.166.94.177/9993")); // Amsterdam
//roots.back().stableEndpoints.push_back(InetAddress("2a03:b0c0:2:d0::7d:1/9993")); // Amsterdam roots.back().stableEndpoints.push_back(InetAddress("2a03:b0c0:2:d0::7d:1/9993")); // Amsterdam
//roots.back().stableEndpoints.push_back(InetAddress("154.66.197.33/9993")); // Johannesburg roots.back().stableEndpoints.push_back(InetAddress("154.66.197.33/9993")); // Johannesburg
//roots.back().stableEndpoints.push_back(InetAddress("2c0f:f850:154:197::33/9993")); // Johannesburg roots.back().stableEndpoints.push_back(InetAddress("2c0f:f850:154:197::33/9993")); // Johannesburg
//roots.back().stableEndpoints.push_back(InetAddress("159.203.97.171/9993")); // New York roots.back().stableEndpoints.push_back(InetAddress("159.203.97.171/9993")); // New York
//roots.back().stableEndpoints.push_back(InetAddress("2604:a880:800:a1::54:6001/9993")); // New York roots.back().stableEndpoints.push_back(InetAddress("2604:a880:800:a1::54:6001/9993")); // New York
//roots.back().stableEndpoints.push_back(InetAddress("131.255.6.16/9993")); // Buenos Aires roots.back().stableEndpoints.push_back(InetAddress("131.255.6.16/9993")); // Buenos Aires
//roots.back().stableEndpoints.push_back(InetAddress("2803:eb80:0:e::2/9993")); // Buenos Aires roots.back().stableEndpoints.push_back(InetAddress("2803:eb80:0:e::2/9993")); // Buenos Aires
//roots.back().stableEndpoints.push_back(InetAddress("107.170.197.14/9993")); // San Francisco roots.back().stableEndpoints.push_back(InetAddress("107.170.197.14/9993")); // San Francisco
//roots.back().stableEndpoints.push_back(InetAddress("2604:a880:1:20::200:e001/9993")); // San Francisco roots.back().stableEndpoints.push_back(InetAddress("2604:a880:1:20::200:e001/9993")); // San Francisco
//roots.back().stableEndpoints.push_back(InetAddress("128.199.197.217/9993")); // Singapore roots.back().stableEndpoints.push_back(InetAddress("128.199.197.217/9993")); // Singapore
//roots.back().stableEndpoints.push_back(InetAddress("2400:6180:0:d0::b7:4001/9993")); // Singapore roots.back().stableEndpoints.push_back(InetAddress("2400:6180:0:d0::b7:4001/9993")); // Singapore
// Bob // Bob
//roots.push_back(World::Root()); roots.push_back(World::Root());
//roots.back().identity = Identity("8841408a2e:0:bb1d31f2c323e264e9e64172c1a74f77899555ed10751cd56e86405cde118d02dffe555d462ccf6a85b5631c12350c8d5dc409ba10b9025d0f445cf449d92b1c"); roots.back().identity = Identity("8841408a2e:0:bb1d31f2c323e264e9e64172c1a74f77899555ed10751cd56e86405cde118d02dffe555d462ccf6a85b5631c12350c8d5dc409ba10b9025d0f445cf449d92b1c");
//roots.back().stableEndpoints.push_back(InetAddress("45.32.198.130/9993")); // Dallas roots.back().stableEndpoints.push_back(InetAddress("45.32.198.130/9993")); // Dallas
//roots.back().stableEndpoints.push_back(InetAddress("2001:19f0:6400:81c3:5400:00ff:fe18:1d61/9993")); // Dallas roots.back().stableEndpoints.push_back(InetAddress("2001:19f0:6400:81c3:5400:00ff:fe18:1d61/9993")); // Dallas
//roots.back().stableEndpoints.push_back(InetAddress("46.101.160.249/9993")); // Frankfurt roots.back().stableEndpoints.push_back(InetAddress("46.101.160.249/9993")); // Frankfurt
//roots.back().stableEndpoints.push_back(InetAddress("2a03:b0c0:3:d0::6a:3001/9993")); // Frankfurt roots.back().stableEndpoints.push_back(InetAddress("2a03:b0c0:3:d0::6a:3001/9993")); // Frankfurt
//roots.back().stableEndpoints.push_back(InetAddress("107.191.46.210/9993")); // Paris roots.back().stableEndpoints.push_back(InetAddress("107.191.46.210/9993")); // Paris
//roots.back().stableEndpoints.push_back(InetAddress("2001:19f0:6800:83a4::64/9993")); // Paris roots.back().stableEndpoints.push_back(InetAddress("2001:19f0:6800:83a4::64/9993")); // Paris
//roots.back().stableEndpoints.push_back(InetAddress("45.32.246.179/9993")); // Sydney roots.back().stableEndpoints.push_back(InetAddress("45.32.246.179/9993")); // Sydney
//roots.back().stableEndpoints.push_back(InetAddress("2001:19f0:5800:8bf8:5400:ff:fe15:b39a/9993")); // Sydney roots.back().stableEndpoints.push_back(InetAddress("2001:19f0:5800:8bf8:5400:ff:fe15:b39a/9993")); // Sydney
//roots.back().stableEndpoints.push_back(InetAddress("45.32.248.87/9993")); // Tokyo roots.back().stableEndpoints.push_back(InetAddress("45.32.248.87/9993")); // Tokyo
//roots.back().stableEndpoints.push_back(InetAddress("2001:19f0:7000:9bc9:5400:00ff:fe15:c4f5/9993")); // Tokyo roots.back().stableEndpoints.push_back(InetAddress("2001:19f0:7000:9bc9:5400:00ff:fe15:c4f5/9993")); // Tokyo
//roots.back().stableEndpoints.push_back(InetAddress("159.203.2.154/9993")); // Toronto roots.back().stableEndpoints.push_back(InetAddress("159.203.2.154/9993")); // Toronto
//roots.back().stableEndpoints.push_back(InetAddress("2604:a880:cad:d0::26:7001/9993")); // Toronto roots.back().stableEndpoints.push_back(InetAddress("2604:a880:cad:d0::26:7001/9993")); // Toronto
// END WORLD DEFINITION // END WORLD DEFINITION
// ========================================================================= // =========================================================================

Binary file not shown.

View file

@ -1,13 +0,0 @@
ARG ZT_NAME
FROM 084037375216.dkr.ecr.us-east-2.amazonaws.com/${ZT_NAME}-builder as builder
WORKDIR /work/build
COPY . .
RUN pwd
RUN ls -la .
RUN make clean
RUN make debian
RUN ls -ls /work
FROM scratch AS export
ARG ZT_NAME
COPY --from=builder /work/*.deb ./${ZT_NAME}/

View file

@ -1,36 +0,0 @@
ARG DOCKER_ARCH
FROM --platform=linux/${DOCKER_ARCH} alpine:edge AS builder
RUN apk update
RUN apk add curl
RUN apk add bash
RUN apk add file
RUN apk add rust
RUN apk add cargo
RUN apk add make
RUN apk add cmake
RUN apk add clang
RUN apk add openssl-dev
RUN apk add linux-headers
RUN apk add build-base
RUN apk add openssl-libs-static
COPY . .
RUN ZT_STATIC=1 make
RUN ls -la
ARG DOCKER_ARCH
FROM --platform=linux/${DOCKER_ARCH} centos:6 AS stage
WORKDIR /root/rpmbuild/BUILD
COPY . .
COPY --from=builder zerotier-* ./
RUN curl https://gist.githubusercontent.com/someara/b363002ba6e57b3c474dd027d4daef85/raw/4ac5534139752fc92fbe1a53599a390214f69615/el6%2520vault --output /etc/yum.repos.d/CentOS-Base.repo
RUN uname -a
RUN yum -y install make gcc rpm-build
RUN pwd
RUN ls -la
RUN make redhat
FROM scratch AS export
ARG ZT_NAME
COPY --from=stage /root/rpmbuild/RPMS/*/*.rpm ./${ZT_NAME}/

View file

@ -1,9 +0,0 @@
ARG ZT_NAME
FROM 084037375216.dkr.ecr.us-east-2.amazonaws.com/${ZT_NAME}-builder as builder
WORKDIR /root/rpmbuild/BUILD
COPY . .
RUN make redhat
FROM scratch AS export
ARG ZT_NAME
COPY --from=builder /root/rpmbuild/RPMS/*/*.rpm ./${ZT_NAME}/

View file

@ -1,13 +0,0 @@
ARG ZT_NAME
FROM 084037375216.dkr.ecr.us-east-2.amazonaws.com/${ZT_NAME}-tester
ARG BASEURL
ARG VERSION
ARG DEB_ARCH
ARG ZT_NAME
ARG DISTRO
RUN curl -s http://${BASEURL}/key.gpg -o /etc/apt/trusted.gpg.d/zerotier.gpg
RUN echo "deb [arch=${DEB_ARCH} signed-by=/etc/apt/trusted.gpg.d/zerotier.gpg] http://${BASEURL}/${DISTRO} ${ZT_NAME} main" > /etc/apt/sources.list.d/zerotier.list
RUN apt-get -qq update
RUN apt-get -qq install zerotier-one=${VERSION}
RUN ldd $(which zerotier-cli)

View file

@ -1,4 +0,0 @@
ARG DOCKER_ARCH
FROM --platform=linux/${DOCKER_ARCH} centos:6
RUN printf "[C6.10-base]\nname=CentOS-6.10 - Base\nbaseurl=http://vault.epel.cloud/6.10/os/\$basearch/\ngpgcheck=1\ngpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6\nenabled=1\nmetadata_expire=never\n" > /etc/yum.repos.d/CentOS-Base.repo
RUN yum -y install curl

View file

@ -1,17 +0,0 @@
ARG ZT_NAME
FROM 084037375216.dkr.ecr.us-east-2.amazonaws.com/${ZT_NAME}-tester
ARG BASEURL
ARG VERSION
ARG DEB_ARCH
ARG ZT_NAME
ARG DISTRO
ARG DNF_ARCH
RUN curl -s http://${BASEURL}/key.asc -o /etc/pki/rpm-gpg/RPM-GPG-KEY-zerotier
RUN rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-zerotier
RUN rpm -q gpg-pubkey --qf '%{NAME}-%{VERSION}-%{RELEASE}\t%{SUMMARY}\n'
RUN printf "[zerotier]\nname=zerotier\nbaseurl=http://${BASEURL}/${DISTRO}/${ZT_NAME}/$basearch/\nenabled=1\ngpgcheck=1\ngpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-zerotier\n" > /etc/yum.repos.d/zerotier.repo
# RUN yum -v repolist
RUN setarch ${DNF_ARCH} yum -y install zerotier-one-${VERSION}
RUN file $(which zerotier-cli)
RUN ldd $(which zerotier-cli)

View file

@ -1,49 +0,0 @@
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
ZT_NAME="$1" ; shift
DISTRO="$1" ; shift
ZT_ISA="$1" ; shift
VERSION="$1" ; shift
BUILD_EVENT="$1" ; shift
source "$(dirname $0)/lib.sh"
if [ -f "ci/Dockerfile-build.${ZT_NAME}" ]; then
DOCKERFILE="ci/Dockerfile-build.${ZT_NAME}"
else
DOCKERFILE="ci/Dockerfile-build.${PKGFMT}"
fi
echo "#~~~~~~~~~~~~~~~~~~~~"
echo "$0 variables:"
echo "nproc: $(nproc)"
echo "ZT_NAME: ${ZT_NAME}"
echo "DISTRO: ${DISTRO}"
echo "ZT_ISA: ${ZT_ISA}"
echo "VERSION: ${VERSION}"
echo "BUILD_EVENT: ${BUILD_EVENT}"
echo "DOCKER_ARCH: ${DOCKER_ARCH}"
echo "DNF_ARCH: ${DNF_ARCH}"
echo "RUST_TRIPLET: ${RUST_TRIPLET}"
echo "PKGFMT: ${PKGFMT}"
echo "PWD: ${PWD}"
echo "DOCKERFILE: ${DOCKERFILE}"
echo "#~~~~~~~~~~~~~~~~~~~~"
make munge_rpm zerotier-one.spec VERSION=${VERSION}
make munge_deb debian/changelog VERSION=${VERSION}
docker buildx build \
--no-cache=true \
--build-arg ZT_NAME="${ZT_NAME}" \
--build-arg RUST_TRIPLET="${RUST_TRIPLET}" \
--build-arg DOCKER_ARCH="${DOCKER_ARCH}" \
--build-arg DNF_ARCH="${DNF_ARCH}" \
--platform linux/${DOCKER_ARCH} \
-f ${DOCKERFILE} \
-t build \
. \
--output type=local,dest=. \
--target export

View file

@ -1,63 +0,0 @@
case $ZT_NAME in
el*|fc*|amzn*)
export PKGFMT=rpm
;;
*)
export PKGFMT=deb
esac
case $ZT_ISA in
386)
export DOCKER_ARCH=386
export DEB_ARCH=i386
export DNF_ARCH=i686
export RUST_TRIPLET=i686-unknown-linux-gnu
;;
amd64)
export DOCKER_ARCH=amd64
export DEB_ARCH=amd64
export DNF_ARCH=x86_64
export RUST_TRIPLET=x86_64-unknown-linux-gnu
;;
armv7)
export DOCKER_ARCH=arm/v7
export DNF_ARCH=armv7
export DEB_ARCH=armhf
export RUST_TRIPLET=armv7-unknown-linux-gnueabihf
;;
arm64)
export DOCKER_ARCH=arm64/v8
export DEB_ARCH=arm64
export DNF_ARCH=linux64
export RUST_TRIPLET=aarch64-unknown-linux-gnu
;;
riscv64)
export DOCKER_ARCH=riscv64
export DEB_ARCH=riscv64
export DNF_ARCH=riscv64
export RUST_TRIPLET=riscv64gc-unknown-linux-gnu
;;
ppc64le)
export DOCKER_ARCH=ppc64le
export DEB_ARCH=ppc64el
export DNF_ARCH=ppc64le
export RUST_TRIPLET=powerpc64le-unknown-linux-gnu
;;
mips64le)
export DOCKER_ARCH=mips64le
export DEB_ARCH=mips64le
export DNF_ARCH=mips64le
export RUST_TRIPLET=mips64el-unknown-linux-gnuabi64
;;
s390x)
export DOCKER_ARCH=s390x
export DEB_ARCH=s390x
export DNF_ARCH=s390x
export RUST_TRIPLET=s390x-unknown-linux-gnu
;;
*)
echo "ERROR: could not determine architecture settings. PLEASE FIX ME"
exit 1
;;
esac

View file

@ -1,37 +0,0 @@
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
export FILE=$1
export VERSION=$2
export NAME=$3
export MESSAGE=$4
export DATE=$(date "+%a, %d %b %Y %T %z")
# export DATE=$(date "+%a %b %d %Y")
set +e
grep --version | grep BSD &> /dev/null
if [ $? == 0 ]; then BSDGREP=true ; else BSDGREP=false ; fi
set -e
# echo "#~~~~~~~~~~~~~~~~~~~~"
# echo "$0 variables:"
# echo "VERSION: ${VERSION}"
# echo "NAME: ${NAME}"
# echo "MESSAGE: ${MESSAGE}"
# echo "DATE: ${DATE}"
# echo "BSDGREP: ${BSDGREP}"
# echo "#~~~~~~~~~~~~~~~~~~~~"
# echo
if $BSDGREP ; then
sed -i '' s/^Version:.*/"Version: ${VERSION}"/ ${FILE}
else
sed -i s/^Version:.*/"Version: ${VERSION}"/ ${FILE}
fi
awk -v version=${VERSION} -v date=${DATE} -v name=${NAME} -v message=${MESSAGE} \
'BEGIN{print "zerotier-one (" version ") stable; urgency=medium\n\n * " message "\n\n -- " name " " date "\n" }{ print }' \
${FILE} > ${FILE}.new
mv ${FILE}.new ${FILE}

View file

@ -1,36 +0,0 @@
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
export FILE=$1
export VERSION=$2
export NAME=$3
export MESSAGE=$4
export DATE=$(date "+%a %b %d %Y")
set +e
grep --version | grep BSD &> /dev/null
if [ $? == 0 ]; then BSDGREP=true ; else BSDGREP=false ; fi
set -e
# echo "#~~~~~~~~~~~~~~~~~~~~"
# echo "$0 variables:"
# echo "VERSION: ${VERSION}"
# echo "NAME: ${NAME}"
# echo "MESSAGE: ${MESSAGE}"
# echo "DATE: ${DATE}"
# echo "BSDGREP: ${BSDGREP}"
# echo "#~~~~~~~~~~~~~~~~~~~~"
# echo
if $BSDGREP ; then
sed -i '' s/^Version:.*/"Version: ${VERSION}"/ ${FILE}
else
sed -i s/^Version:.*/"Version: ${VERSION}"/ ${FILE}
fi
awk -v version=${VERSION} -v date=${DATE} -v name=${NAME} -v message=${MESSAGE} \
'FNR==NR{ if (/%changelog/) p=NR; next} 1; FNR==p{ print "* " date " " name " - " version "\n- " message "\n" }' \
${FILE} ${FILE} > ${FILE}.new
mv ${FILE}.new ${FILE}

View file

@ -1,38 +0,0 @@
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
ZT_NAME="$1" ; shift
DISTRO="$1" ; shift
ZT_ISA="$1" ; shift
VERSION="$1" ; shift
BUILD_EVENT="$1" ; shift
source "$(dirname $0)/lib.sh"
if [ ${BUILD_EVENT} == "tag" ]; then
CHANNEL="zerotier-releases"
else
CHANNEL="zerotier-builds"
fi
function publish_rpm {
mkdir -p /${CHANNEL}/${DISTRO}
ls -la /${CHANNEL}
ls -la .
cp -a ${ZT_NAME} /${CHANNEL}/${DISTRO}
}
function publish_deb {
mkdir -p /${CHANNEL}/${DISTRO}/pool/dists/${ZT_NAME}/main
cp -a ${ZT_NAME}/* /${CHANNEL}/${DISTRO}/pool/dists/${ZT_NAME}/main
}
case ${PKGFMT} in
"rpm")
publish_rpm
;;
"deb")
publish_deb
esac

View file

@ -1,55 +0,0 @@
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
ZT_NAME="$1" ; shift
DISTRO="$1" ; shift
ZT_ISA="$1" ; shift
VERSION="$1" ; shift
BUILD_EVENT="$1" ; shift
source "$(dirname $0)/lib.sh"
if [ -f "ci/Dockerfile-test.${ZT_NAME}" ]; then
DOCKERFILE="ci/Dockerfile-test.${ZT_NAME}"
else
DOCKERFILE="ci/Dockerfile-test.${PKGFMT}"
fi
if [ ${BUILD_EVENT} == "tag" ]; then
BASEURL="zerotier-releases.home.arpa"
else
BASEURL="zerotier-builds.home.arpa"
fi
echo "#~~~~~~~~~~~~~~~~~~~~"
echo "$0 variables:"
echo "nproc: $(nproc)"
echo "ZT_NAME: ${ZT_NAME}"
echo "DISTRO: ${DISTRO}"
echo "ZT_ISA: ${ZT_ISA}"
echo "VERSION: ${VERSION}"
echo "BUILD_EVENT: ${BUILD_EVENT}"
echo "DOCKER_ARCH: ${DOCKER_ARCH}"
echo "DNF_ARCH: ${DNF_ARCH}"
echo "RUST_TRIPLET: ${RUST_TRIPLET}"
echo "PKGFMT: ${PKGFMT}"
echo "PWD: ${PWD}"
echo "DOCKERFILE: ${DOCKERFILE}"
echo "#~~~~~~~~~~~~~~~~~~~~"
# docker pull -q --platform="linux/${DOCKER_ARCH}" 084037375216.dkr.ecr.us-east-2.amazonaws.com/${ZT_NAME}-tester
docker buildx build \
--build-arg BASEURL="${BASEURL}" \
--build-arg ZT_NAME="${ZT_NAME}" \
--build-arg DISTRO="${DISTRO}" \
--build-arg DEB_ARCH="${DEB_ARCH}" \
--build-arg DNF_ARCH="${DNF_ARCH}" \
--build-arg VERSION="${VERSION}" \
--build-arg DOCKER_ARCH="${DOCKER_ARCH}" \
--platform "linux/${DOCKER_ARCH}" \
--no-cache \
-f ${DOCKERFILE} \
-t test \
.

View file

@ -1,175 +0,0 @@
/*
* Copyright (c)2021 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: 2026-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.
*/
/****/
#ifndef ZT_CONNECTION_POOL_H_
#define ZT_CONNECTION_POOL_H_
#ifndef _DEBUG
#define _DEBUG(x)
#endif
#include "../node/Metrics.hpp"
#include <deque>
#include <set>
#include <memory>
#include <mutex>
#include <exception>
#include <string>
namespace ZeroTier {
struct ConnectionUnavailable : std::exception {
char const* what() const throw() {
return "Unable to allocate connection";
};
};
class Connection {
public:
virtual ~Connection() {};
};
class ConnectionFactory {
public:
virtual ~ConnectionFactory() {};
virtual std::shared_ptr<Connection> create()=0;
};
struct ConnectionPoolStats {
size_t pool_size;
size_t borrowed_size;
};
template<class T>
class ConnectionPool {
public:
ConnectionPool(size_t max_pool_size, size_t min_pool_size, std::shared_ptr<ConnectionFactory> factory)
: m_maxPoolSize(max_pool_size)
, m_minPoolSize(min_pool_size)
, m_factory(factory)
{
Metrics::max_pool_size += max_pool_size;
Metrics::min_pool_size += min_pool_size;
while(m_pool.size() < m_minPoolSize){
m_pool.push_back(m_factory->create());
Metrics::pool_avail++;
}
};
ConnectionPoolStats get_stats() {
std::unique_lock<std::mutex> lock(m_poolMutex);
ConnectionPoolStats stats;
stats.pool_size = m_pool.size();
stats.borrowed_size = m_borrowed.size();
return stats;
};
~ConnectionPool() {
};
/**
* Borrow
*
* Borrow a connection for temporary use
*
* When done, either (a) call unborrow() to return it, or (b) (if it's bad) just let it go out of scope. This will cause it to automatically be replaced.
* @retval a shared_ptr to the connection object
*/
std::shared_ptr<T> borrow() {
std::unique_lock<std::mutex> l(m_poolMutex);
while((m_pool.size() + m_borrowed.size()) < m_minPoolSize) {
std::shared_ptr<Connection> conn = m_factory->create();
m_pool.push_back(conn);
Metrics::pool_avail++;
}
if(m_pool.size()==0){
if ((m_pool.size() + m_borrowed.size()) < m_maxPoolSize) {
try {
std::shared_ptr<Connection> conn = m_factory->create();
m_borrowed.insert(conn);
Metrics::pool_in_use++;
return std::static_pointer_cast<T>(conn);
} catch (std::exception &e) {
Metrics::pool_errors++;
throw ConnectionUnavailable();
}
} else {
for(auto it = m_borrowed.begin(); it != m_borrowed.end(); ++it){
if((*it).unique()) {
// This connection has been abandoned! Destroy it and create a new connection
try {
// If we are able to create a new connection, return it
_DEBUG("Creating new connection to replace discarded connection");
std::shared_ptr<Connection> conn = m_factory->create();
m_borrowed.erase(it);
m_borrowed.insert(conn);
return std::static_pointer_cast<T>(conn);
} catch(std::exception& e) {
// Error creating a replacement connection
Metrics::pool_errors++;
throw ConnectionUnavailable();
}
}
}
// Nothing available
Metrics::pool_errors++;
throw ConnectionUnavailable();
}
}
// Take one off the front
std::shared_ptr<Connection> conn = m_pool.front();
m_pool.pop_front();
Metrics::pool_avail--;
// Add it to the borrowed list
m_borrowed.insert(conn);
Metrics::pool_in_use++;
return std::static_pointer_cast<T>(conn);
};
/**
* Unborrow a connection
*
* Only call this if you are returning a working connection. If the connection was bad, just let it go out of scope (so the connection manager can replace it).
* @param the connection
*/
void unborrow(std::shared_ptr<T> conn) {
// Lock
std::unique_lock<std::mutex> lock(m_poolMutex);
m_borrowed.erase(conn);
Metrics::pool_in_use--;
if ((m_pool.size() + m_borrowed.size()) < m_maxPoolSize) {
Metrics::pool_avail++;
m_pool.push_back(conn);
}
};
protected:
size_t m_maxPoolSize;
size_t m_minPoolSize;
std::shared_ptr<ConnectionFactory> m_factory;
std::deque<std::shared_ptr<Connection> > m_pool;
std::set<std::shared_ptr<Connection> > m_borrowed;
std::mutex m_poolMutex;
};
}
#endif

View file

@ -1,19 +1,31 @@
/* /*
* Copyright (c)2019 ZeroTier, Inc. * ZeroTier One - Network Virtualization Everywhere
* Copyright (C) 2011-2019 ZeroTier, Inc. https://www.zerotier.com/
* *
* Use of this software is governed by the Business Source License included * This program is free software: you can redistribute it and/or modify
* in the LICENSE.TXT file in the project's root directory. * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* *
* Change Date: 2026-01-01 * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* *
* On the date above, in accordance with the Business Source License, use * You should have received a copy of the GNU General Public License
* of this software will be governed by version 2.0 of the Apache License. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial closed-source software that incorporates or links
* directly against ZeroTier software without disclosing the source code
* of your own application.
*/ */
/****/
#include "DB.hpp" #include "DB.hpp"
#include "EmbeddedNetworkController.hpp" #include "EmbeddedNetworkController.hpp"
#include "../node/Metrics.hpp"
#include <chrono> #include <chrono>
#include <algorithm> #include <algorithm>
@ -49,18 +61,12 @@ void DB::initNetwork(nlohmann::json &network)
{ "type","ACTION_ACCEPT" } { "type","ACTION_ACCEPT" }
}}; }};
} }
if (!network.count("dns")) network["dns"] = nlohmann::json::array();
if (!network.count("ssoEnabled")) network["ssoEnabled"] = false;
if (!network.count("clientId")) network["clientId"] = "";
if (!network.count("authorizationEndpoint")) network["authorizationEndpoint"] = "";
network["objtype"] = "network"; network["objtype"] = "network";
} }
void DB::initMember(nlohmann::json &member) void DB::initMember(nlohmann::json &member)
{ {
if (!member.count("authorized")) member["authorized"] = false; if (!member.count("authorized")) member["authorized"] = false;
if (!member.count("ssoExempt")) member["ssoExempt"] = false;
if (!member.count("ipAssignments")) member["ipAssignments"] = nlohmann::json::array(); if (!member.count("ipAssignments")) member["ipAssignments"] = nlohmann::json::array();
if (!member.count("activeBridge")) member["activeBridge"] = false; if (!member.count("activeBridge")) member["activeBridge"] = false;
if (!member.count("tags")) member["tags"] = nlohmann::json::array(); if (!member.count("tags")) member["tags"] = nlohmann::json::array();
@ -72,7 +78,6 @@ void DB::initMember(nlohmann::json &member)
if (!member.count("lastAuthorizedTime")) member["lastAuthorizedTime"] = 0ULL; if (!member.count("lastAuthorizedTime")) member["lastAuthorizedTime"] = 0ULL;
if (!member.count("lastAuthorizedCredentialType")) member["lastAuthorizedCredentialType"] = nlohmann::json(); if (!member.count("lastAuthorizedCredentialType")) member["lastAuthorizedCredentialType"] = nlohmann::json();
if (!member.count("lastAuthorizedCredential")) member["lastAuthorizedCredential"] = nlohmann::json(); if (!member.count("lastAuthorizedCredential")) member["lastAuthorizedCredential"] = nlohmann::json();
if (!member.count("authenticationExpiryTime")) member["authenticationExpiryTime"] = 0LL;
if (!member.count("vMajor")) member["vMajor"] = -1; if (!member.count("vMajor")) member["vMajor"] = -1;
if (!member.count("vMinor")) member["vMinor"] = -1; if (!member.count("vMinor")) member["vMinor"] = -1;
if (!member.count("vRev")) member["vRev"] = -1; if (!member.count("vRev")) member["vRev"] = -1;
@ -98,8 +103,6 @@ void DB::cleanMember(nlohmann::json &member)
member.erase("recentLog"); member.erase("recentLog");
member.erase("lastModified"); member.erase("lastModified");
member.erase("lastRequestMetaData"); member.erase("lastRequestMetaData");
member.erase("authenticationURL"); // computed
member.erase("authenticationClientID"); // computed
} }
DB::DB() {} DB::DB() {}
@ -108,17 +111,16 @@ DB::~DB() {}
bool DB::get(const uint64_t networkId,nlohmann::json &network) bool DB::get(const uint64_t networkId,nlohmann::json &network)
{ {
waitForReady(); waitForReady();
Metrics::db_get_network++;
std::shared_ptr<_Network> nw; std::shared_ptr<_Network> nw;
{ {
std::shared_lock<std::shared_mutex> l(_networks_l); std::lock_guard<std::mutex> l(_networks_l);
auto nwi = _networks.find(networkId); auto nwi = _networks.find(networkId);
if (nwi == _networks.end()) if (nwi == _networks.end())
return false; return false;
nw = nwi->second; nw = nwi->second;
} }
{ {
std::shared_lock<std::shared_mutex> l2(nw->lock); std::lock_guard<std::mutex> l2(nw->lock);
network = nw->config; network = nw->config;
} }
return true; return true;
@ -127,17 +129,16 @@ bool DB::get(const uint64_t networkId,nlohmann::json &network)
bool DB::get(const uint64_t networkId,nlohmann::json &network,const uint64_t memberId,nlohmann::json &member) bool DB::get(const uint64_t networkId,nlohmann::json &network,const uint64_t memberId,nlohmann::json &member)
{ {
waitForReady(); waitForReady();
Metrics::db_get_network_and_member++;
std::shared_ptr<_Network> nw; std::shared_ptr<_Network> nw;
{ {
std::shared_lock<std::shared_mutex> l(_networks_l); std::lock_guard<std::mutex> l(_networks_l);
auto nwi = _networks.find(networkId); auto nwi = _networks.find(networkId);
if (nwi == _networks.end()) if (nwi == _networks.end())
return false; return false;
nw = nwi->second; nw = nwi->second;
} }
{ {
std::shared_lock<std::shared_mutex> l2(nw->lock); std::lock_guard<std::mutex> l2(nw->lock);
network = nw->config; network = nw->config;
auto m = nw->members.find(memberId); auto m = nw->members.find(memberId);
if (m == nw->members.end()) if (m == nw->members.end())
@ -150,17 +151,16 @@ bool DB::get(const uint64_t networkId,nlohmann::json &network,const uint64_t mem
bool DB::get(const uint64_t networkId,nlohmann::json &network,const uint64_t memberId,nlohmann::json &member,NetworkSummaryInfo &info) bool DB::get(const uint64_t networkId,nlohmann::json &network,const uint64_t memberId,nlohmann::json &member,NetworkSummaryInfo &info)
{ {
waitForReady(); waitForReady();
Metrics::db_get_network_and_member_and_summary++;
std::shared_ptr<_Network> nw; std::shared_ptr<_Network> nw;
{ {
std::shared_lock<std::shared_mutex> l(_networks_l); std::lock_guard<std::mutex> l(_networks_l);
auto nwi = _networks.find(networkId); auto nwi = _networks.find(networkId);
if (nwi == _networks.end()) if (nwi == _networks.end())
return false; return false;
nw = nwi->second; nw = nwi->second;
} }
{ {
std::shared_lock<std::shared_mutex> l2(nw->lock); std::lock_guard<std::mutex> l2(nw->lock);
network = nw->config; network = nw->config;
_fillSummaryInfo(nw,info); _fillSummaryInfo(nw,info);
auto m = nw->members.find(memberId); auto m = nw->members.find(memberId);
@ -174,21 +174,19 @@ bool DB::get(const uint64_t networkId,nlohmann::json &network,const uint64_t mem
bool DB::get(const uint64_t networkId,nlohmann::json &network,std::vector<nlohmann::json> &members) bool DB::get(const uint64_t networkId,nlohmann::json &network,std::vector<nlohmann::json> &members)
{ {
waitForReady(); waitForReady();
Metrics::db_get_member_list++;
std::shared_ptr<_Network> nw; std::shared_ptr<_Network> nw;
{ {
std::shared_lock<std::shared_mutex> l(_networks_l); std::lock_guard<std::mutex> l(_networks_l);
auto nwi = _networks.find(networkId); auto nwi = _networks.find(networkId);
if (nwi == _networks.end()) if (nwi == _networks.end())
return false; return false;
nw = nwi->second; nw = nwi->second;
} }
{ {
std::shared_lock<std::shared_mutex> l2(nw->lock); std::lock_guard<std::mutex> l2(nw->lock);
network = nw->config; network = nw->config;
for(auto m=nw->members.begin();m!=nw->members.end();++m) { for(auto m=nw->members.begin();m!=nw->members.end();++m)
members.push_back(m->second); members.push_back(m->second);
}
} }
return true; return true;
} }
@ -196,15 +194,13 @@ bool DB::get(const uint64_t networkId,nlohmann::json &network,std::vector<nlohma
void DB::networks(std::set<uint64_t> &networks) void DB::networks(std::set<uint64_t> &networks)
{ {
waitForReady(); waitForReady();
Metrics::db_get_network_list++; std::lock_guard<std::mutex> l(_networks_l);
std::shared_lock<std::shared_mutex> l(_networks_l);
for(auto n=_networks.begin();n!=_networks.end();++n) for(auto n=_networks.begin();n!=_networks.end();++n)
networks.insert(n->first); networks.insert(n->first);
} }
void DB::_memberChanged(nlohmann::json &old,nlohmann::json &memberConfig,bool notifyListeners) void DB::_memberChanged(nlohmann::json &old,nlohmann::json &memberConfig,bool notifyListeners)
{ {
Metrics::db_member_change++;
uint64_t memberId = 0; uint64_t memberId = 0;
uint64_t networkId = 0; uint64_t networkId = 0;
bool isAuth = false; bool isAuth = false;
@ -216,21 +212,18 @@ void DB::_memberChanged(nlohmann::json &old,nlohmann::json &memberConfig,bool no
networkId = OSUtils::jsonIntHex(old["nwid"],0ULL); networkId = OSUtils::jsonIntHex(old["nwid"],0ULL);
if ((memberId)&&(networkId)) { if ((memberId)&&(networkId)) {
{ {
std::unique_lock<std::shared_mutex> l(_networks_l); std::lock_guard<std::mutex> l(_networks_l);
auto nw2 = _networks.find(networkId); auto nw2 = _networks.find(networkId);
if (nw2 != _networks.end()) { if (nw2 != _networks.end())
nw = nw2->second; nw = nw2->second;
}
} }
if (nw) { if (nw) {
std::unique_lock<std::shared_mutex> l(nw->lock); std::lock_guard<std::mutex> l(nw->lock);
if (OSUtils::jsonBool(old["activeBridge"],false)) { if (OSUtils::jsonBool(old["activeBridge"],false))
nw->activeBridgeMembers.erase(memberId); nw->activeBridgeMembers.erase(memberId);
}
wasAuth = OSUtils::jsonBool(old["authorized"],false); wasAuth = OSUtils::jsonBool(old["authorized"],false);
if (wasAuth) { if (wasAuth)
nw->authorizedMembers.erase(memberId); nw->authorizedMembers.erase(memberId);
}
json &ips = old["ipAssignments"]; json &ips = old["ipAssignments"];
if (ips.is_array()) { if (ips.is_array()) {
for(unsigned long i=0;i<ips.size();++i) { for(unsigned long i=0;i<ips.size();++i) {
@ -253,7 +246,7 @@ void DB::_memberChanged(nlohmann::json &old,nlohmann::json &memberConfig,bool no
networkId = OSUtils::jsonIntHex(memberConfig["nwid"],0ULL); networkId = OSUtils::jsonIntHex(memberConfig["nwid"],0ULL);
if ((!memberId)||(!networkId)) if ((!memberId)||(!networkId))
return; return;
std::unique_lock<std::shared_mutex> l(_networks_l); std::lock_guard<std::mutex> l(_networks_l);
std::shared_ptr<_Network> &nw2 = _networks[networkId]; std::shared_ptr<_Network> &nw2 = _networks[networkId];
if (!nw2) if (!nw2)
nw2.reset(new _Network); nw2.reset(new _Network);
@ -261,18 +254,15 @@ void DB::_memberChanged(nlohmann::json &old,nlohmann::json &memberConfig,bool no
} }
{ {
std::unique_lock<std::shared_mutex> l(nw->lock); std::lock_guard<std::mutex> l(nw->lock);
nw->members[memberId] = memberConfig; nw->members[memberId] = memberConfig;
if (OSUtils::jsonBool(memberConfig["activeBridge"],false)) { if (OSUtils::jsonBool(memberConfig["activeBridge"],false))
nw->activeBridgeMembers.insert(memberId); nw->activeBridgeMembers.insert(memberId);
}
isAuth = OSUtils::jsonBool(memberConfig["authorized"],false); isAuth = OSUtils::jsonBool(memberConfig["authorized"],false);
if (isAuth) { if (isAuth)
Metrics::member_auths++;
nw->authorizedMembers.insert(memberId); nw->authorizedMembers.insert(memberId);
}
json &ips = memberConfig["ipAssignments"]; json &ips = memberConfig["ipAssignments"];
if (ips.is_array()) { if (ips.is_array()) {
for(unsigned long i=0;i<ips.size();++i) { for(unsigned long i=0;i<ips.size();++i) {
@ -294,18 +284,18 @@ void DB::_memberChanged(nlohmann::json &old,nlohmann::json &memberConfig,bool no
} }
if (notifyListeners) { if (notifyListeners) {
std::unique_lock<std::shared_mutex> ll(_changeListeners_l); std::lock_guard<std::mutex> ll(_changeListeners_l);
for(auto i=_changeListeners.begin();i!=_changeListeners.end();++i) { for(auto i=_changeListeners.begin();i!=_changeListeners.end();++i) {
(*i)->onNetworkMemberUpdate(this,networkId,memberId,memberConfig); (*i)->onNetworkMemberUpdate(this,networkId,memberId,memberConfig);
} }
} }
} else if (memberId) { } else if (memberId) {
if (nw) { if (nw) {
std::unique_lock<std::shared_mutex> l(nw->lock); std::lock_guard<std::mutex> l(nw->lock);
nw->members.erase(memberId); nw->members.erase(memberId);
} }
if (networkId) { if (networkId) {
std::unique_lock<std::shared_mutex> l(_networks_l); std::lock_guard<std::mutex> l(_networks_l);
auto er = _networkByMember.equal_range(memberId); auto er = _networkByMember.equal_range(memberId);
for(auto i=er.first;i!=er.second;++i) { for(auto i=er.first;i!=er.second;++i) {
if (i->second == networkId) { if (i->second == networkId) {
@ -316,26 +306,8 @@ void DB::_memberChanged(nlohmann::json &old,nlohmann::json &memberConfig,bool no
} }
} }
if (notifyListeners) {
if(networkId != 0 && memberId != 0 && old.is_object() && !memberConfig.is_object()) {
// member delete
Metrics::member_count--;
} else if (networkId != 0 && memberId != 0 && !old.is_object() && memberConfig.is_object()) {
// new member
Metrics::member_count++;
}
if (!wasAuth && isAuth) {
Metrics::member_auths++;
} else if (wasAuth && !isAuth) {
Metrics::member_deauths++;
} else {
Metrics::member_changes++;
}
}
if ((notifyListeners)&&((wasAuth)&&(!isAuth)&&(networkId)&&(memberId))) { if ((notifyListeners)&&((wasAuth)&&(!isAuth)&&(networkId)&&(memberId))) {
std::unique_lock<std::shared_mutex> ll(_changeListeners_l); std::lock_guard<std::mutex> ll(_changeListeners_l);
for(auto i=_changeListeners.begin();i!=_changeListeners.end();++i) { for(auto i=_changeListeners.begin();i!=_changeListeners.end();++i) {
(*i)->onNetworkMemberDeauthorize(this,networkId,memberId); (*i)->onNetworkMemberDeauthorize(this,networkId,memberId);
} }
@ -344,35 +316,24 @@ void DB::_memberChanged(nlohmann::json &old,nlohmann::json &memberConfig,bool no
void DB::_networkChanged(nlohmann::json &old,nlohmann::json &networkConfig,bool notifyListeners) void DB::_networkChanged(nlohmann::json &old,nlohmann::json &networkConfig,bool notifyListeners)
{ {
Metrics::db_network_change++;
if (notifyListeners) {
if (old.is_object() && old.contains("id") && networkConfig.is_object() && networkConfig.contains("id")) {
Metrics::network_changes++;
} else if (!old.is_object() && networkConfig.is_object() && networkConfig.contains("id")) {
Metrics::network_count++;
} else if (old.is_object() && old.contains("id") && !networkConfig.is_object()) {
Metrics::network_count--;
}
}
if (networkConfig.is_object()) { if (networkConfig.is_object()) {
const std::string ids = networkConfig["id"]; const std::string ids = networkConfig["id"];
const uint64_t networkId = Utils::hexStrToU64(ids.c_str()); const uint64_t networkId = Utils::hexStrToU64(ids.c_str());
if (networkId) { if (networkId) {
std::shared_ptr<_Network> nw; std::shared_ptr<_Network> nw;
{ {
std::unique_lock<std::shared_mutex> l(_networks_l); std::lock_guard<std::mutex> l(_networks_l);
std::shared_ptr<_Network> &nw2 = _networks[networkId]; std::shared_ptr<_Network> &nw2 = _networks[networkId];
if (!nw2) if (!nw2)
nw2.reset(new _Network); nw2.reset(new _Network);
nw = nw2; nw = nw2;
} }
{ {
std::unique_lock<std::shared_mutex> l2(nw->lock); std::lock_guard<std::mutex> l2(nw->lock);
nw->config = networkConfig; nw->config = networkConfig;
} }
if (notifyListeners) { if (notifyListeners) {
std::unique_lock<std::shared_mutex> ll(_changeListeners_l); std::lock_guard<std::mutex> ll(_changeListeners_l);
for(auto i=_changeListeners.begin();i!=_changeListeners.end();++i) { for(auto i=_changeListeners.begin();i!=_changeListeners.end();++i) {
(*i)->onNetworkUpdate(this,networkId,networkConfig); (*i)->onNetworkUpdate(this,networkId,networkConfig);
} }
@ -382,25 +343,7 @@ void DB::_networkChanged(nlohmann::json &old,nlohmann::json &networkConfig,bool
const std::string ids = old["id"]; const std::string ids = old["id"];
const uint64_t networkId = Utils::hexStrToU64(ids.c_str()); const uint64_t networkId = Utils::hexStrToU64(ids.c_str());
if (networkId) { if (networkId) {
try { std::lock_guard<std::mutex> l(_networks_l);
// deauth all members on the network
nlohmann::json network;
std::vector<nlohmann::json> members;
this->get(networkId, network, members);
for(auto i=members.begin();i!=members.end();++i) {
const std::string nodeID = (*i)["id"];
const uint64_t memberId = Utils::hexStrToU64(nodeID.c_str());
std::unique_lock<std::shared_mutex> ll(_changeListeners_l);
for(auto j=_changeListeners.begin();j!=_changeListeners.end();++j) {
(*j)->onNetworkMemberDeauthorize(this,networkId,memberId);
}
}
} catch (std::exception &e) {
std::cerr << "Error deauthorizing members on network delete: " << e.what() << std::endl;
}
// delete the network
std::unique_lock<std::shared_mutex> l(_networks_l);
_networks.erase(networkId); _networks.erase(networkId);
} }
} }

View file

@ -1,15 +1,28 @@
/* /*
* Copyright (c)2019 ZeroTier, Inc. * ZeroTier One - Network Virtualization Everywhere
* Copyright (C) 2011-2019 ZeroTier, Inc. https://www.zerotier.com/
* *
* Use of this software is governed by the Business Source License included * This program is free software: you can redistribute it and/or modify
* in the LICENSE.TXT file in the project's root directory. * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* *
* Change Date: 2026-01-01 * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* *
* On the date above, in accordance with the Business Source License, use * You should have received a copy of the GNU General Public License
* of this software will be governed by version 2.0 of the Apache License. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial closed-source software that incorporates or links
* directly against ZeroTier software without disclosing the source code
* of your own application.
*/ */
/****/
#ifndef ZT_CONTROLLER_DB_HPP #ifndef ZT_CONTROLLER_DB_HPP
#define ZT_CONTROLLER_DB_HPP #define ZT_CONTROLLER_DB_HPP
@ -29,47 +42,14 @@
#include <unordered_set> #include <unordered_set>
#include <vector> #include <vector>
#include <atomic> #include <atomic>
#include <shared_mutex> #include <mutex>
#include <set> #include <set>
#include <map>
#include <nlohmann/json.hpp> #include "../ext/json/json.hpp"
#include <prometheus/simpleapi.h>
#define ZT_MEMBER_AUTH_TIMEOUT_NOTIFY_BEFORE 25000
namespace ZeroTier namespace ZeroTier
{ {
struct AuthInfo
{
public:
AuthInfo()
: enabled(false)
, version(0)
, authenticationURL()
, authenticationExpiryTime(0)
, issuerURL()
, centralAuthURL()
, ssoNonce()
, ssoState()
, ssoClientID()
, ssoProvider("default")
{}
bool enabled;
uint64_t version;
std::string authenticationURL;
uint64_t authenticationExpiryTime;
std::string issuerURL;
std::string centralAuthURL;
std::string ssoNonce;
std::string ssoState;
std::string ssoClientID;
std::string ssoProvider;
};
/** /**
* Base class with common infrastructure for all controller DB implementations * Base class with common infrastructure for all controller DB implementations
*/ */
@ -109,7 +89,7 @@ public:
inline bool hasNetwork(const uint64_t networkId) const inline bool hasNetwork(const uint64_t networkId) const
{ {
std::shared_lock<std::shared_mutex> l(_networks_l); std::lock_guard<std::mutex> l(_networks_l);
return (_networks.find(networkId) != _networks.end()); return (_networks.find(networkId) != _networks.end());
} }
@ -124,7 +104,7 @@ public:
inline void each(F f) inline void each(F f)
{ {
nlohmann::json nullJson; nlohmann::json nullJson;
std::unique_lock<std::shared_mutex> lck(_networks_l); std::lock_guard<std::mutex> lck(_networks_l);
for(auto nw=_networks.begin();nw!=_networks.end();++nw) { for(auto nw=_networks.begin();nw!=_networks.end();++nw) {
f(nw->first,nw->second->config,0,nullJson); // first provide network with 0 for member ID f(nw->first,nw->second->config,0,nullJson); // first provide network with 0 for member ID
for(auto m=nw->second->members.begin();m!=nw->second->members.end();++m) { for(auto m=nw->second->members.begin();m!=nw->second->members.end();++m) {
@ -134,15 +114,15 @@ public:
} }
virtual bool save(nlohmann::json &record,bool notifyListeners) = 0; virtual bool save(nlohmann::json &record,bool notifyListeners) = 0;
virtual void eraseNetwork(const uint64_t networkId) = 0; virtual void eraseNetwork(const uint64_t networkId) = 0;
virtual void eraseMember(const uint64_t networkId,const uint64_t memberId) = 0; virtual void eraseMember(const uint64_t networkId,const uint64_t memberId) = 0;
virtual void nodeIsOnline(const uint64_t networkId,const uint64_t memberId,const InetAddress &physicalAddress) = 0;
virtual AuthInfo getSSOAuthInfo(const nlohmann::json &member, const std::string &redirectURL) { return AuthInfo(); } virtual void nodeIsOnline(const uint64_t networkId,const uint64_t memberId,const InetAddress &physicalAddress) = 0;
inline void addListener(DB::ChangeListener *const listener) inline void addListener(DB::ChangeListener *const listener)
{ {
std::unique_lock<std::shared_mutex> l(_changeListeners_l); std::lock_guard<std::mutex> l(_changeListeners_l);
_changeListeners.push_back(listener); _changeListeners.push_back(listener);
} }
@ -178,18 +158,18 @@ protected:
std::unordered_set<uint64_t> authorizedMembers; std::unordered_set<uint64_t> authorizedMembers;
std::unordered_set<InetAddress,InetAddress::Hasher> allocatedIps; std::unordered_set<InetAddress,InetAddress::Hasher> allocatedIps;
int64_t mostRecentDeauthTime; int64_t mostRecentDeauthTime;
std::shared_mutex lock; std::mutex lock;
}; };
virtual void _memberChanged(nlohmann::json &old,nlohmann::json &memberConfig,bool notifyListeners); void _memberChanged(nlohmann::json &old,nlohmann::json &memberConfig,bool notifyListeners);
virtual void _networkChanged(nlohmann::json &old,nlohmann::json &networkConfig,bool notifyListeners); void _networkChanged(nlohmann::json &old,nlohmann::json &networkConfig,bool notifyListeners);
void _fillSummaryInfo(const std::shared_ptr<_Network> &nw,NetworkSummaryInfo &info); void _fillSummaryInfo(const std::shared_ptr<_Network> &nw,NetworkSummaryInfo &info);
std::vector<DB::ChangeListener *> _changeListeners; std::vector<DB::ChangeListener *> _changeListeners;
std::unordered_map< uint64_t,std::shared_ptr<_Network> > _networks; std::unordered_map< uint64_t,std::shared_ptr<_Network> > _networks;
std::unordered_multimap< uint64_t,uint64_t > _networkByMember; std::unordered_multimap< uint64_t,uint64_t > _networkByMember;
mutable std::shared_mutex _changeListeners_l; mutable std::mutex _changeListeners_l;
mutable std::shared_mutex _networks_l; mutable std::mutex _networks_l;
}; };
} // namespace ZeroTier } // namespace ZeroTier

View file

@ -1,26 +1,36 @@
/* /*
* Copyright (c)2019 ZeroTier, Inc. * ZeroTier One - Network Virtualization Everywhere
* Copyright (C) 2011-2019 ZeroTier, Inc. https://www.zerotier.com/
* *
* Use of this software is governed by the Business Source License included * This program is free software: you can redistribute it and/or modify
* in the LICENSE.TXT file in the project's root directory. * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* *
* Change Date: 2026-01-01 * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* *
* On the date above, in accordance with the Business Source License, use * You should have received a copy of the GNU General Public License
* of this software will be governed by version 2.0 of the Apache License. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial closed-source software that incorporates or links
* directly against ZeroTier software without disclosing the source code
* of your own application.
*/ */
/****/
#include "DBMirrorSet.hpp" #include "DBMirrorSet.hpp"
namespace ZeroTier { namespace ZeroTier {
DBMirrorSet::DBMirrorSet(DB::ChangeListener *listener) DBMirrorSet::DBMirrorSet(DB::ChangeListener *listener) :
: _listener(listener) _listener(listener),
, _running(true) _running(true)
, _syncCheckerThread()
, _dbs()
, _dbs_l()
{ {
_syncCheckerThread = std::thread([this]() { _syncCheckerThread = std::thread([this]() {
for(;;) { for(;;) {
@ -32,14 +42,14 @@ DBMirrorSet::DBMirrorSet(DB::ChangeListener *listener)
std::vector< std::shared_ptr<DB> > dbs; std::vector< std::shared_ptr<DB> > dbs;
{ {
std::unique_lock<std::shared_mutex> l(_dbs_l); std::lock_guard<std::mutex> l(_dbs_l);
if (_dbs.size() <= 1) if (_dbs.size() <= 1)
continue; // no need to do this if there's only one DB, so skip the iteration continue; // no need to do this if there's only one DB, so skip the iteration
dbs = _dbs; dbs = _dbs;
} }
for(auto db=dbs.begin();db!=dbs.end();++db) { for(auto db=dbs.begin();db!=dbs.end();++db) {
(*db)->each([&dbs,&db](uint64_t networkId,const nlohmann::json &network,uint64_t memberId,const nlohmann::json &member) { (*db)->each([this,&dbs,&db](uint64_t networkId,const nlohmann::json &network,uint64_t memberId,const nlohmann::json &member) {
try { try {
if (network.is_object()) { if (network.is_object()) {
if (memberId == 0) { if (memberId == 0) {
@ -79,7 +89,7 @@ DBMirrorSet::~DBMirrorSet()
bool DBMirrorSet::hasNetwork(const uint64_t networkId) const bool DBMirrorSet::hasNetwork(const uint64_t networkId) const
{ {
std::shared_lock<std::shared_mutex> l(_dbs_l); std::lock_guard<std::mutex> l(_dbs_l);
for(auto d=_dbs.begin();d!=_dbs.end();++d) { for(auto d=_dbs.begin();d!=_dbs.end();++d) {
if ((*d)->hasNetwork(networkId)) if ((*d)->hasNetwork(networkId))
return true; return true;
@ -89,7 +99,7 @@ bool DBMirrorSet::hasNetwork(const uint64_t networkId) const
bool DBMirrorSet::get(const uint64_t networkId,nlohmann::json &network) bool DBMirrorSet::get(const uint64_t networkId,nlohmann::json &network)
{ {
std::shared_lock<std::shared_mutex> l(_dbs_l); std::lock_guard<std::mutex> l(_dbs_l);
for(auto d=_dbs.begin();d!=_dbs.end();++d) { for(auto d=_dbs.begin();d!=_dbs.end();++d) {
if ((*d)->get(networkId,network)) { if ((*d)->get(networkId,network)) {
return true; return true;
@ -100,7 +110,7 @@ bool DBMirrorSet::get(const uint64_t networkId,nlohmann::json &network)
bool DBMirrorSet::get(const uint64_t networkId,nlohmann::json &network,const uint64_t memberId,nlohmann::json &member) bool DBMirrorSet::get(const uint64_t networkId,nlohmann::json &network,const uint64_t memberId,nlohmann::json &member)
{ {
std::shared_lock<std::shared_mutex> l(_dbs_l); std::lock_guard<std::mutex> l(_dbs_l);
for(auto d=_dbs.begin();d!=_dbs.end();++d) { for(auto d=_dbs.begin();d!=_dbs.end();++d) {
if ((*d)->get(networkId,network,memberId,member)) if ((*d)->get(networkId,network,memberId,member))
return true; return true;
@ -110,7 +120,7 @@ bool DBMirrorSet::get(const uint64_t networkId,nlohmann::json &network,const uin
bool DBMirrorSet::get(const uint64_t networkId,nlohmann::json &network,const uint64_t memberId,nlohmann::json &member,DB::NetworkSummaryInfo &info) bool DBMirrorSet::get(const uint64_t networkId,nlohmann::json &network,const uint64_t memberId,nlohmann::json &member,DB::NetworkSummaryInfo &info)
{ {
std::shared_lock<std::shared_mutex> l(_dbs_l); std::lock_guard<std::mutex> l(_dbs_l);
for(auto d=_dbs.begin();d!=_dbs.end();++d) { for(auto d=_dbs.begin();d!=_dbs.end();++d) {
if ((*d)->get(networkId,network,memberId,member,info)) if ((*d)->get(networkId,network,memberId,member,info))
return true; return true;
@ -120,7 +130,7 @@ bool DBMirrorSet::get(const uint64_t networkId,nlohmann::json &network,const uin
bool DBMirrorSet::get(const uint64_t networkId,nlohmann::json &network,std::vector<nlohmann::json> &members) bool DBMirrorSet::get(const uint64_t networkId,nlohmann::json &network,std::vector<nlohmann::json> &members)
{ {
std::shared_lock<std::shared_mutex> l(_dbs_l); std::lock_guard<std::mutex> l(_dbs_l);
for(auto d=_dbs.begin();d!=_dbs.end();++d) { for(auto d=_dbs.begin();d!=_dbs.end();++d) {
if ((*d)->get(networkId,network,members)) if ((*d)->get(networkId,network,members))
return true; return true;
@ -128,21 +138,9 @@ bool DBMirrorSet::get(const uint64_t networkId,nlohmann::json &network,std::vect
return false; return false;
} }
AuthInfo DBMirrorSet::getSSOAuthInfo(const nlohmann::json &member, const std::string &redirectURL)
{
std::shared_lock<std::shared_mutex> l(_dbs_l);
for(auto d=_dbs.begin();d!=_dbs.end();++d) {
AuthInfo info = (*d)->getSSOAuthInfo(member, redirectURL);
if (info.enabled) {
return info;
}
}
return AuthInfo();
}
void DBMirrorSet::networks(std::set<uint64_t> &networks) void DBMirrorSet::networks(std::set<uint64_t> &networks)
{ {
std::shared_lock<std::shared_mutex> l(_dbs_l); std::lock_guard<std::mutex> l(_dbs_l);
for(auto d=_dbs.begin();d!=_dbs.end();++d) { for(auto d=_dbs.begin();d!=_dbs.end();++d) {
(*d)->networks(networks); (*d)->networks(networks);
} }
@ -151,7 +149,7 @@ void DBMirrorSet::networks(std::set<uint64_t> &networks)
bool DBMirrorSet::waitForReady() bool DBMirrorSet::waitForReady()
{ {
bool r = false; bool r = false;
std::shared_lock<std::shared_mutex> l(_dbs_l); std::lock_guard<std::mutex> l(_dbs_l);
for(auto d=_dbs.begin();d!=_dbs.end();++d) { for(auto d=_dbs.begin();d!=_dbs.end();++d) {
r |= (*d)->waitForReady(); r |= (*d)->waitForReady();
} }
@ -160,7 +158,7 @@ bool DBMirrorSet::waitForReady()
bool DBMirrorSet::isReady() bool DBMirrorSet::isReady()
{ {
std::shared_lock<std::shared_mutex> l(_dbs_l); std::lock_guard<std::mutex> l(_dbs_l);
for(auto d=_dbs.begin();d!=_dbs.end();++d) { for(auto d=_dbs.begin();d!=_dbs.end();++d) {
if (!(*d)->isReady()) if (!(*d)->isReady())
return false; return false;
@ -172,7 +170,7 @@ bool DBMirrorSet::save(nlohmann::json &record,bool notifyListeners)
{ {
std::vector< std::shared_ptr<DB> > dbs; std::vector< std::shared_ptr<DB> > dbs;
{ {
std::unique_lock<std::shared_mutex> l(_dbs_l); std::lock_guard<std::mutex> l(_dbs_l);
dbs = _dbs; dbs = _dbs;
} }
if (notifyListeners) { if (notifyListeners) {
@ -192,7 +190,7 @@ bool DBMirrorSet::save(nlohmann::json &record,bool notifyListeners)
void DBMirrorSet::eraseNetwork(const uint64_t networkId) void DBMirrorSet::eraseNetwork(const uint64_t networkId)
{ {
std::unique_lock<std::shared_mutex> l(_dbs_l); std::lock_guard<std::mutex> l(_dbs_l);
for(auto d=_dbs.begin();d!=_dbs.end();++d) { for(auto d=_dbs.begin();d!=_dbs.end();++d) {
(*d)->eraseNetwork(networkId); (*d)->eraseNetwork(networkId);
} }
@ -200,7 +198,7 @@ void DBMirrorSet::eraseNetwork(const uint64_t networkId)
void DBMirrorSet::eraseMember(const uint64_t networkId,const uint64_t memberId) void DBMirrorSet::eraseMember(const uint64_t networkId,const uint64_t memberId)
{ {
std::unique_lock<std::shared_mutex> l(_dbs_l); std::lock_guard<std::mutex> l(_dbs_l);
for(auto d=_dbs.begin();d!=_dbs.end();++d) { for(auto d=_dbs.begin();d!=_dbs.end();++d) {
(*d)->eraseMember(networkId,memberId); (*d)->eraseMember(networkId,memberId);
} }
@ -208,7 +206,7 @@ void DBMirrorSet::eraseMember(const uint64_t networkId,const uint64_t memberId)
void DBMirrorSet::nodeIsOnline(const uint64_t networkId,const uint64_t memberId,const InetAddress &physicalAddress) void DBMirrorSet::nodeIsOnline(const uint64_t networkId,const uint64_t memberId,const InetAddress &physicalAddress)
{ {
std::shared_lock<std::shared_mutex> l(_dbs_l); std::lock_guard<std::mutex> l(_dbs_l);
for(auto d=_dbs.begin();d!=_dbs.end();++d) { for(auto d=_dbs.begin();d!=_dbs.end();++d) {
(*d)->nodeIsOnline(networkId,memberId,physicalAddress); (*d)->nodeIsOnline(networkId,memberId,physicalAddress);
} }
@ -217,7 +215,7 @@ void DBMirrorSet::nodeIsOnline(const uint64_t networkId,const uint64_t memberId,
void DBMirrorSet::onNetworkUpdate(const void *db,uint64_t networkId,const nlohmann::json &network) void DBMirrorSet::onNetworkUpdate(const void *db,uint64_t networkId,const nlohmann::json &network)
{ {
nlohmann::json record(network); nlohmann::json record(network);
std::unique_lock<std::shared_mutex> l(_dbs_l); std::lock_guard<std::mutex> l(_dbs_l);
for(auto d=_dbs.begin();d!=_dbs.end();++d) { for(auto d=_dbs.begin();d!=_dbs.end();++d) {
if (d->get() != db) { if (d->get() != db) {
(*d)->save(record,false); (*d)->save(record,false);
@ -229,7 +227,7 @@ void DBMirrorSet::onNetworkUpdate(const void *db,uint64_t networkId,const nlohma
void DBMirrorSet::onNetworkMemberUpdate(const void *db,uint64_t networkId,uint64_t memberId,const nlohmann::json &member) void DBMirrorSet::onNetworkMemberUpdate(const void *db,uint64_t networkId,uint64_t memberId,const nlohmann::json &member)
{ {
nlohmann::json record(member); nlohmann::json record(member);
std::unique_lock<std::shared_mutex> l(_dbs_l); std::lock_guard<std::mutex> l(_dbs_l);
for(auto d=_dbs.begin();d!=_dbs.end();++d) { for(auto d=_dbs.begin();d!=_dbs.end();++d) {
if (d->get() != db) { if (d->get() != db) {
(*d)->save(record,false); (*d)->save(record,false);

View file

@ -1,15 +1,28 @@
/* /*
* Copyright (c)2019 ZeroTier, Inc. * ZeroTier One - Network Virtualization Everywhere
* Copyright (C) 2011-2019 ZeroTier, Inc. https://www.zerotier.com/
* *
* Use of this software is governed by the Business Source License included * This program is free software: you can redistribute it and/or modify
* in the LICENSE.TXT file in the project's root directory. * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* *
* Change Date: 2026-01-01 * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* *
* On the date above, in accordance with the Business Source License, use * You should have received a copy of the GNU General Public License
* of this software will be governed by version 2.0 of the Apache License. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial closed-source software that incorporates or links
* directly against ZeroTier software without disclosing the source code
* of your own application.
*/ */
/****/
#ifndef ZT_DBMIRRORSET_HPP #ifndef ZT_DBMIRRORSET_HPP
#define ZT_DBMIRRORSET_HPP #define ZT_DBMIRRORSET_HPP
@ -18,7 +31,7 @@
#include <vector> #include <vector>
#include <memory> #include <memory>
#include <shared_mutex> #include <mutex>
#include <set> #include <set>
#include <thread> #include <thread>
@ -51,12 +64,10 @@ public:
virtual void onNetworkMemberUpdate(const void *db,uint64_t networkId,uint64_t memberId,const nlohmann::json &member); virtual void onNetworkMemberUpdate(const void *db,uint64_t networkId,uint64_t memberId,const nlohmann::json &member);
virtual void onNetworkMemberDeauthorize(const void *db,uint64_t networkId,uint64_t memberId); virtual void onNetworkMemberDeauthorize(const void *db,uint64_t networkId,uint64_t memberId);
AuthInfo getSSOAuthInfo(const nlohmann::json &member, const std::string &redirectURL);
inline void addDB(const std::shared_ptr<DB> &db) inline void addDB(const std::shared_ptr<DB> &db)
{ {
db->addListener(this); db->addListener(this);
std::unique_lock<std::shared_mutex> l(_dbs_l); std::lock_guard<std::mutex> l(_dbs_l);
_dbs.push_back(db); _dbs.push_back(db);
} }
@ -65,7 +76,7 @@ private:
std::atomic_bool _running; std::atomic_bool _running;
std::thread _syncCheckerThread; std::thread _syncCheckerThread;
std::vector< std::shared_ptr< DB > > _dbs; std::vector< std::shared_ptr< DB > > _dbs;
mutable std::shared_mutex _dbs_l; mutable std::mutex _dbs_l;
}; };
} // namespace ZeroTier } // namespace ZeroTier

File diff suppressed because it is too large Load diff

View file

@ -1,15 +1,28 @@
/* /*
* Copyright (c)2019 ZeroTier, Inc. * ZeroTier One - Network Virtualization Everywhere
* Copyright (C) 2011-2019 ZeroTier, Inc. https://www.zerotier.com/
* *
* Use of this software is governed by the Business Source License included * This program is free software: you can redistribute it and/or modify
* in the LICENSE.TXT file in the project's root directory. * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* *
* Change Date: 2026-01-01 * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* *
* On the date above, in accordance with the Business Source License, use * You should have received a copy of the GNU General Public License
* of this software will be governed by version 2.0 of the Apache License. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial closed-source software that incorporates or links
* directly against ZeroTier software without disclosing the source code
* of your own application.
*/ */
/****/
#ifndef ZT_SQLITENETWORKCONTROLLER_HPP #ifndef ZT_SQLITENETWORKCONTROLLER_HPP
#define ZT_SQLITENETWORKCONTROLLER_HPP #define ZT_SQLITENETWORKCONTROLLER_HPP
@ -35,9 +48,7 @@
#include "../osdep/Thread.hpp" #include "../osdep/Thread.hpp"
#include "../osdep/BlockingQueue.hpp" #include "../osdep/BlockingQueue.hpp"
#include <nlohmann/json.hpp> #include "../ext/json/json.hpp"
#include <cpp-httplib/httplib.h>
#include "DB.hpp" #include "DB.hpp"
#include "DBMirrorSet.hpp" #include "DBMirrorSet.hpp"
@ -45,7 +56,8 @@
namespace ZeroTier { namespace ZeroTier {
class Node; class Node;
struct RedisConfig;
struct MQConfig;
class EmbeddedNetworkController : public NetworkController,public DB::ChangeListener class EmbeddedNetworkController : public NetworkController,public DB::ChangeListener
{ {
@ -54,13 +66,11 @@ public:
* @param node Parent node * @param node Parent node
* @param dbPath Database path (file path or database credentials) * @param dbPath Database path (file path or database credentials)
*/ */
EmbeddedNetworkController(Node *node,const char *ztPath,const char *dbPath, int listenPort, RedisConfig *rc); EmbeddedNetworkController(Node *node,const char *ztPath,const char *dbPath, int listenPort, MQConfig *mqc = NULL);
virtual ~EmbeddedNetworkController(); virtual ~EmbeddedNetworkController();
virtual void init(const Identity &signingId,Sender *sender); virtual void init(const Identity &signingId,Sender *sender);
void setSSORedirectURL(const std::string &url);
virtual void request( virtual void request(
uint64_t nwid, uint64_t nwid,
const InetAddress &fromAddr, const InetAddress &fromAddr,
@ -68,10 +78,27 @@ public:
const Identity &identity, const Identity &identity,
const Dictionary<ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY> &metaData); const Dictionary<ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY> &metaData);
void configureHTTPControlPlane( unsigned int handleControlPlaneHttpGET(
httplib::Server &s, const std::vector<std::string> &path,
httplib::Server &sV6, const std::map<std::string,std::string> &urlArgs,
const std::function<void(const httplib::Request&, httplib::Response&, std::string)>); const std::map<std::string,std::string> &headers,
const std::string &body,
std::string &responseBody,
std::string &responseContentType);
unsigned int handleControlPlaneHttpPOST(
const std::vector<std::string> &path,
const std::map<std::string,std::string> &urlArgs,
const std::map<std::string,std::string> &headers,
const std::string &body,
std::string &responseBody,
std::string &responseContentType);
unsigned int handleControlPlaneHttpDELETE(
const std::vector<std::string> &path,
const std::map<std::string,std::string> &urlArgs,
const std::map<std::string,std::string> &headers,
const std::string &body,
std::string &responseBody,
std::string &responseContentType);
void handleRemoteTrace(const ZT_RemoteTrace &rt); void handleRemoteTrace(const ZT_RemoteTrace &rt);
@ -82,9 +109,6 @@ public:
private: private:
void _request(uint64_t nwid,const InetAddress &fromAddr,uint64_t requestPacketId,const Identity &identity,const Dictionary<ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY> &metaData); void _request(uint64_t nwid,const InetAddress &fromAddr,uint64_t requestPacketId,const Identity &identity,const Dictionary<ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY> &metaData);
void _startThreads(); void _startThreads();
void _ssoExpiryThread();
std::string networkUpdateFromPostData(uint64_t networkID, const std::string &body);
struct _RQEntry struct _RQEntry
{ {
@ -97,7 +121,6 @@ private:
RQENTRY_TYPE_REQUEST = 0 RQENTRY_TYPE_REQUEST = 0
} type; } type;
}; };
struct _MemberStatusKey struct _MemberStatusKey
{ {
_MemberStatusKey() : networkId(0),nodeId(0) {} _MemberStatusKey() : networkId(0),nodeId(0) {}
@ -105,13 +128,11 @@ private:
uint64_t networkId; uint64_t networkId;
uint64_t nodeId; uint64_t nodeId;
inline bool operator==(const _MemberStatusKey &k) const { return ((k.networkId == networkId)&&(k.nodeId == nodeId)); } inline bool operator==(const _MemberStatusKey &k) const { return ((k.networkId == networkId)&&(k.nodeId == nodeId)); }
inline bool operator<(const _MemberStatusKey &k) const { return (k.networkId < networkId) || ((k.networkId == networkId)&&(k.nodeId < nodeId)); }
}; };
struct _MemberStatus struct _MemberStatus
{ {
_MemberStatus() : lastRequestTime(0),authenticationExpiryTime(-1),vMajor(-1),vMinor(-1),vRev(-1),vProto(-1) {} _MemberStatus() : lastRequestTime(0),vMajor(-1),vMinor(-1),vRev(-1),vProto(-1) {}
int64_t lastRequestTime; uint64_t lastRequestTime;
int64_t authenticationExpiryTime;
int vMajor,vMinor,vRev,vProto; int vMajor,vMinor,vRev,vProto;
Dictionary<ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY> lastRequestMetaData; Dictionary<ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY> lastRequestMetaData;
Identity identity; Identity identity;
@ -143,39 +164,7 @@ private:
std::unordered_map< _MemberStatusKey,_MemberStatus,_MemberStatusHash > _memberStatus; std::unordered_map< _MemberStatusKey,_MemberStatus,_MemberStatusHash > _memberStatus;
std::mutex _memberStatus_l; std::mutex _memberStatus_l;
std::set< std::pair<int64_t, _MemberStatusKey> > _expiringSoon; MQConfig *_mqc;
std::mutex _expiringSoon_l;
RedisConfig *_rc;
std::string _ssoRedirectURL;
bool _ssoExpiryRunning;
std::thread _ssoExpiry;
#ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK
prometheus::simpleapi::benchmark_family_t _member_status_lookup;
prometheus::simpleapi::counter_family_t _member_status_lookup_count;
prometheus::simpleapi::benchmark_family_t _node_is_online;
prometheus::simpleapi::counter_family_t _node_is_online_count;
prometheus::simpleapi::benchmark_family_t _get_and_init_member;
prometheus::simpleapi::counter_family_t _get_and_init_member_count;
prometheus::simpleapi::benchmark_family_t _have_identity;
prometheus::simpleapi::counter_family_t _have_identity_count;
prometheus::simpleapi::benchmark_family_t _determine_auth;
prometheus::simpleapi::counter_family_t _determine_auth_count;
prometheus::simpleapi::benchmark_family_t _sso_check;
prometheus::simpleapi::counter_family_t _sso_check_count;
prometheus::simpleapi::benchmark_family_t _auth_check;
prometheus::simpleapi::counter_family_t _auth_check_count;
prometheus::simpleapi::benchmark_family_t _json_schlep;
prometheus::simpleapi::counter_family_t _json_schlep_count;
prometheus::simpleapi::benchmark_family_t _issue_certificate;
prometheus::simpleapi::counter_family_t _issue_certificate_count;
prometheus::simpleapi::benchmark_family_t _save_member;
prometheus::simpleapi::counter_family_t _save_member_count;
prometheus::simpleapi::benchmark_family_t _send_netconf;
prometheus::simpleapi::counter_family_t _send_netconf_count;
#endif
}; };
} // namespace ZeroTier } // namespace ZeroTier

View file

@ -1,20 +1,31 @@
/* /*
* Copyright (c)2019 ZeroTier, Inc. * ZeroTier One - Network Virtualization Everywhere
* Copyright (C) 2011-2019 ZeroTier, Inc. https://www.zerotier.com/
* *
* Use of this software is governed by the Business Source License included * This program is free software: you can redistribute it and/or modify
* in the LICENSE.TXT file in the project's root directory. * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* *
* Change Date: 2026-01-01 * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* *
* On the date above, in accordance with the Business Source License, use * You should have received a copy of the GNU General Public License
* of this software will be governed by version 2.0 of the Apache License. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial closed-source software that incorporates or links
* directly against ZeroTier software without disclosing the source code
* of your own application.
*/ */
/****/
#include "FileDB.hpp" #include "FileDB.hpp"
#include "../node/Metrics.hpp"
namespace ZeroTier namespace ZeroTier
{ {
@ -41,7 +52,6 @@ FileDB::FileDB(const char *path) :
if (nwids.length() == 16) { if (nwids.length() == 16) {
nlohmann::json nullJson; nlohmann::json nullJson;
_networkChanged(nullJson,network,false); _networkChanged(nullJson,network,false);
Metrics::network_count++;
std::string membersPath(_networksPath + ZT_PATH_SEPARATOR_S + nwids + ZT_PATH_SEPARATOR_S "member"); std::string membersPath(_networksPath + ZT_PATH_SEPARATOR_S + nwids + ZT_PATH_SEPARATOR_S "member");
std::vector<std::string> members(OSUtils::listDirectory(membersPath.c_str(),false)); std::vector<std::string> members(OSUtils::listDirectory(membersPath.c_str(),false));
for(auto m=members.begin();m!=members.end();++m) { for(auto m=members.begin();m!=members.end();++m) {
@ -53,7 +63,6 @@ FileDB::FileDB(const char *path) :
if (addrs.length() == 10) { if (addrs.length() == 10) {
nlohmann::json nullJson2; nlohmann::json nullJson2;
_memberChanged(nullJson2,member,false); _memberChanged(nullJson2,member,false);
Metrics::member_count++;
} }
} catch ( ... ) {} } catch ( ... ) {}
} }
@ -92,9 +101,8 @@ bool FileDB::save(nlohmann::json &record,bool notifyListeners)
if ((!old.is_object())||(!_compareRecords(old,record))) { if ((!old.is_object())||(!_compareRecords(old,record))) {
record["revision"] = OSUtils::jsonInt(record["revision"],0ULL) + 1ULL; record["revision"] = OSUtils::jsonInt(record["revision"],0ULL) + 1ULL;
OSUtils::ztsnprintf(p1,sizeof(p1),"%s" ZT_PATH_SEPARATOR_S "%.16llx.json",_networksPath.c_str(),nwid); OSUtils::ztsnprintf(p1,sizeof(p1),"%s" ZT_PATH_SEPARATOR_S "%.16llx.json",_networksPath.c_str(),nwid);
if (!OSUtils::writeFile(p1,OSUtils::jsonDump(record,-1))) { if (!OSUtils::writeFile(p1,OSUtils::jsonDump(record,-1)))
fprintf(stderr,"WARNING: controller unable to write to path: %s" ZT_EOL_S,p1); fprintf(stderr,"WARNING: controller unable to write to path: %s" ZT_EOL_S,p1);
}
_networkChanged(old,record,notifyListeners); _networkChanged(old,record,notifyListeners);
modified = true; modified = true;
} }
@ -115,9 +123,8 @@ bool FileDB::save(nlohmann::json &record,bool notifyListeners)
OSUtils::ztsnprintf(p2,sizeof(p2),"%s" ZT_PATH_SEPARATOR_S "%.16llx",_networksPath.c_str(),(unsigned long long)nwid); OSUtils::ztsnprintf(p2,sizeof(p2),"%s" ZT_PATH_SEPARATOR_S "%.16llx",_networksPath.c_str(),(unsigned long long)nwid);
OSUtils::mkdir(p2); OSUtils::mkdir(p2);
OSUtils::mkdir(pb); OSUtils::mkdir(pb);
if (!OSUtils::writeFile(p1,OSUtils::jsonDump(record,-1))) { if (!OSUtils::writeFile(p1,OSUtils::jsonDump(record,-1)))
fprintf(stderr,"WARNING: controller unable to write to path: %s" ZT_EOL_S,p1); fprintf(stderr,"WARNING: controller unable to write to path: %s" ZT_EOL_S,p1);
}
} }
_memberChanged(old,record,notifyListeners); _memberChanged(old,record,notifyListeners);
modified = true; modified = true;
@ -136,7 +143,7 @@ void FileDB::eraseNetwork(const uint64_t networkId)
char p[16384]; char p[16384];
OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "%.16llx.json",_networksPath.c_str(),networkId); OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "%.16llx.json",_networksPath.c_str(),networkId);
OSUtils::rm(p); OSUtils::rm(p);
OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "%.16llx",_networksPath.c_str(),(unsigned long long)networkId); OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "%.16llx" ZT_PATH_SEPARATOR_S "member",_networksPath.c_str(),(unsigned long long)networkId);
OSUtils::rmDashRf(p); OSUtils::rmDashRf(p);
_networkChanged(network,nullJson,true); _networkChanged(network,nullJson,true);
std::lock_guard<std::mutex> l(this->_online_l); std::lock_guard<std::mutex> l(this->_online_l);
@ -146,7 +153,8 @@ void FileDB::eraseNetwork(const uint64_t networkId)
void FileDB::eraseMember(const uint64_t networkId,const uint64_t memberId) void FileDB::eraseMember(const uint64_t networkId,const uint64_t memberId)
{ {
nlohmann::json network,member,nullJson; nlohmann::json network,member,nullJson;
get(networkId,network,memberId,member); get(networkId,network);
get(memberId,member);
char p[4096]; char p[4096];
OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "%.16llx" ZT_PATH_SEPARATOR_S "member" ZT_PATH_SEPARATOR_S "%.10llx.json",_networksPath.c_str(),networkId,memberId); OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "%.16llx" ZT_PATH_SEPARATOR_S "member" ZT_PATH_SEPARATOR_S "%.10llx.json",_networksPath.c_str(),networkId,memberId);
OSUtils::rm(p); OSUtils::rm(p);

View file

@ -1,15 +1,28 @@
/* /*
* Copyright (c)2019 ZeroTier, Inc. * ZeroTier One - Network Virtualization Everywhere
* Copyright (C) 2011-2019 ZeroTier, Inc. https://www.zerotier.com/
* *
* Use of this software is governed by the Business Source License included * This program is free software: you can redistribute it and/or modify
* in the LICENSE.TXT file in the project's root directory. * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* *
* Change Date: 2026-01-01 * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* *
* On the date above, in accordance with the Business Source License, use * You should have received a copy of the GNU General Public License
* of this software will be governed by version 2.0 of the Apache License. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial closed-source software that incorporates or links
* directly against ZeroTier software without disclosing the source code
* of your own application.
*/ */
/****/
#ifndef ZT_CONTROLLER_FILEDB_HPP #ifndef ZT_CONTROLLER_FILEDB_HPP
#define ZT_CONTROLLER_FILEDB_HPP #define ZT_CONTROLLER_FILEDB_HPP

View file

@ -1,15 +1,28 @@
/* /*
* Copyright (c)2019 ZeroTier, Inc. * ZeroTier One - Network Virtualization Everywhere
* Copyright (C) 2011-2019 ZeroTier, Inc. https://www.zerotier.com/
* *
* Use of this software is governed by the Business Source License included * This program is free software: you can redistribute it and/or modify
* in the LICENSE.TXT file in the project's root directory. * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* *
* Change Date: 2026-01-01 * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* *
* On the date above, in accordance with the Business Source License, use * You should have received a copy of the GNU General Public License
* of this software will be governed by version 2.0 of the Apache License. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial closed-source software that incorporates or links
* directly against ZeroTier software without disclosing the source code
* of your own application.
*/ */
/****/
#include "LFDB.hpp" #include "LFDB.hpp"
@ -48,7 +61,7 @@ LFDB::LFDB(const Identity &myId,const char *path,const char *lfOwnerPrivate,cons
char maskingKey [128]; char maskingKey [128];
Utils::hex(sha512pk,32,maskingKey); Utils::hex(sha512pk,32,maskingKey);
httplib::Client htcli(_lfNodeHost.c_str(),_lfNodePort); httplib::Client htcli(_lfNodeHost.c_str(),_lfNodePort,600);
int64_t timeRangeStart = 0; int64_t timeRangeStart = 0;
while (_running.load()) { while (_running.load()) {
{ {
@ -190,10 +203,10 @@ LFDB::LFDB(const Identity &myId,const char *path,const char *lfOwnerPrivate,cons
if (resp) { if (resp) {
if (resp->status == 200) { if (resp->status == 200) {
nlohmann::json results(OSUtils::jsonParse(resp->body)); nlohmann::json results(OSUtils::jsonParse(resp->body));
if ((results.is_array())&&(!results.empty())) { if ((results.is_array())&&(results.size() > 0)) {
for(std::size_t ri=0;ri<results.size();++ri) { for(std::size_t ri=0;ri<results.size();++ri) {
nlohmann::json &rset = results[ri]; nlohmann::json &rset = results[ri];
if ((rset.is_array())&&(!rset.empty())) { if ((rset.is_array())&&(rset.size() > 0)) {
nlohmann::json &result = rset[0]; nlohmann::json &result = rset[0];
if (result.is_object()) { if (result.is_object()) {
@ -258,10 +271,10 @@ LFDB::LFDB(const Identity &myId,const char *path,const char *lfOwnerPrivate,cons
if (resp) { if (resp) {
if (resp->status == 200) { if (resp->status == 200) {
nlohmann::json results(OSUtils::jsonParse(resp->body)); nlohmann::json results(OSUtils::jsonParse(resp->body));
if ((results.is_array())&&(!results.empty())) { if ((results.is_array())&&(results.size() > 0)) {
for(std::size_t ri=0;ri<results.size();++ri) { for(std::size_t ri=0;ri<results.size();++ri) {
nlohmann::json &rset = results[ri]; nlohmann::json &rset = results[ri];
if ((rset.is_array())&&(!rset.empty())) { if ((rset.is_array())&&(rset.size() > 0)) {
nlohmann::json &result = rset[0]; nlohmann::json &result = rset[0];
if (result.is_object()) { if (result.is_object()) {

View file

@ -1,15 +1,28 @@
/* /*
* Copyright (c)2019 ZeroTier, Inc. * ZeroTier One - Network Virtualization Everywhere
* Copyright (C) 2011-2019 ZeroTier, Inc. https://www.zerotier.com/
* *
* Use of this software is governed by the Business Source License included * This program is free software: you can redistribute it and/or modify
* in the LICENSE.TXT file in the project's root directory. * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* *
* Change Date: 2026-01-01 * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* *
* On the date above, in accordance with the Business Source License, use * You should have received a copy of the GNU General Public License
* of this software will be governed by version 2.0 of the Apache License. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial closed-source software that incorporates or links
* directly against ZeroTier software without disclosing the source code
* of your own application.
*/ */
/****/
#ifndef ZT_CONTROLLER_LFDB_HPP #ifndef ZT_CONTROLLER_LFDB_HPP
#define ZT_CONTROLLER_LFDB_HPP #define ZT_CONTROLLER_LFDB_HPP

File diff suppressed because it is too large Load diff

View file

@ -1,15 +1,28 @@
/* /*
* Copyright (c)2019 ZeroTier, Inc. * ZeroTier One - Network Virtualization Everywhere
* Copyright (C) 2011-2019 ZeroTier, Inc. https://www.zerotier.com/
* *
* Use of this software is governed by the Business Source License included * This program is free software: you can redistribute it and/or modify
* in the LICENSE.TXT file in the project's root directory. * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* *
* Change Date: 2026-01-01 * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* *
* On the date above, in accordance with the Business Source License, use * You should have received a copy of the GNU General Public License
* of this software will be governed by version 2.0 of the Apache License. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial closed-source software that incorporates or links
* directly against ZeroTier software without disclosing the source code
* of your own application.
*/ */
/****/
#include "DB.hpp" #include "DB.hpp"
@ -20,92 +33,24 @@
#define ZT_CENTRAL_CONTROLLER_COMMIT_THREADS 4 #define ZT_CENTRAL_CONTROLLER_COMMIT_THREADS 4
#include "ConnectionPool.hpp"
#include <pqxx/pqxx>
#include <memory>
#include <redis++/redis++.h>
#include "../node/Metrics.hpp"
extern "C" { extern "C" {
typedef struct pg_conn PGconn; typedef struct pg_conn PGconn;
} }
namespace smeeclient {
struct SmeeClient;
}
namespace ZeroTier { namespace ZeroTier {
struct RedisConfig; struct MQConfig;
class PostgresConnection : public Connection {
public:
virtual ~PostgresConnection() {
}
std::shared_ptr<pqxx::connection> c;
int a;
};
class PostgresConnFactory : public ConnectionFactory {
public:
PostgresConnFactory(std::string &connString)
: m_connString(connString)
{
}
virtual std::shared_ptr<Connection> create() {
Metrics::conn_counter++;
auto c = std::shared_ptr<PostgresConnection>(new PostgresConnection());
c->c = std::make_shared<pqxx::connection>(m_connString);
return std::static_pointer_cast<Connection>(c);
}
private:
std::string m_connString;
};
class PostgreSQL;
class MemberNotificationReceiver : public pqxx::notification_receiver {
public:
MemberNotificationReceiver(PostgreSQL *p, pqxx::connection &c, const std::string &channel);
virtual ~MemberNotificationReceiver() {
fprintf(stderr, "MemberNotificationReceiver destroyed\n");
}
virtual void operator() (const std::string &payload, int backendPid);
private:
PostgreSQL *_psql;
};
class NetworkNotificationReceiver : public pqxx::notification_receiver {
public:
NetworkNotificationReceiver(PostgreSQL *p, pqxx::connection &c, const std::string &channel);
virtual ~NetworkNotificationReceiver() {
fprintf(stderr, "NetworkNotificationReceiver destroyed\n");
};
virtual void operator() (const std::string &payload, int packend_pid);
private:
PostgreSQL *_psql;
};
/** /**
* A controller database driver that talks to PostgreSQL * A controller database driver that talks to PostgreSQL
* *
* This is for use with ZeroTier Central. Others are free to build and use it * This is for use with ZeroTier Central. Others are free to build and use it
* but be aware that we might change it at any time. * but be aware taht we might change it at any time.
*/ */
class PostgreSQL : public DB class PostgreSQL : public DB
{ {
friend class MemberNotificationReceiver;
friend class NetworkNotificationReceiver;
public: public:
PostgreSQL(const Identity &myId, const char *path, int listenPort, RedisConfig *rc); PostgreSQL(const Identity &myId, const char *path, int listenPort, MQConfig *mqc = NULL);
virtual ~PostgreSQL(); virtual ~PostgreSQL();
virtual bool waitForReady(); virtual bool waitForReady();
@ -114,49 +59,33 @@ public:
virtual void eraseNetwork(const uint64_t networkId); virtual void eraseNetwork(const uint64_t networkId);
virtual void eraseMember(const uint64_t networkId, const uint64_t memberId); virtual void eraseMember(const uint64_t networkId, const uint64_t memberId);
virtual void nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress &physicalAddress); virtual void nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress &physicalAddress);
virtual AuthInfo getSSOAuthInfo(const nlohmann::json &member, const std::string &redirectURL);
protected: protected:
struct _PairHasher struct _PairHasher
{ {
inline std::size_t operator()(const std::pair<uint64_t,uint64_t> &p) const { return (std::size_t)(p.first ^ p.second); } inline std::size_t operator()(const std::pair<uint64_t,uint64_t> &p) const { return (std::size_t)(p.first ^ p.second); }
}; };
virtual void _memberChanged(nlohmann::json &old,nlohmann::json &memberConfig,bool notifyListeners) {
DB::_memberChanged(old, memberConfig, notifyListeners);
}
virtual void _networkChanged(nlohmann::json &old,nlohmann::json &networkConfig,bool notifyListeners) {
DB::_networkChanged(old, networkConfig, notifyListeners);
}
private: private:
void initializeNetworks(); void initializeNetworks(PGconn *conn);
void initializeMembers(); void initializeMembers(PGconn *conn);
void heartbeat(); void heartbeat();
void membersDbWatcher(); void membersDbWatcher();
void _membersWatcher_Postgres(); void _membersWatcher_Postgres(PGconn *conn);
void _membersWatcher_RabbitMQ();
void networksDbWatcher(); void networksDbWatcher();
void _networksWatcher_Postgres(); void _networksWatcher_Postgres(PGconn *conn);
void _networksWatcher_RabbitMQ();
void _membersWatcher_Redis();
void _networksWatcher_Redis();
void commitThread(); void commitThread();
void onlineNotificationThread(); void onlineNotificationThread();
void onlineNotification_Postgres();
void onlineNotification_Redis();
uint64_t _doRedisUpdate(sw::redis::Transaction &tx, std::string &controllerId,
std::unordered_map< std::pair<uint64_t,uint64_t>,std::pair<int64_t,InetAddress>,_PairHasher > &lastOnline);
void configureSmee();
void notifyNewMember(const std::string &networkID, const std::string &memberID);
enum OverrideMode { enum OverrideMode {
ALLOW_PGBOUNCER_OVERRIDE = 0, ALLOW_PGBOUNCER_OVERRIDE = 0,
NO_OVERRIDE = 1 NO_OVERRIDE = 1
}; };
std::shared_ptr<ConnectionPool<PostgresConnection> > _pool; PGconn * getPgConn( OverrideMode m = ALLOW_PGBOUNCER_OVERRIDE );
const Identity _myId; const Identity _myId;
const Address _myAddress; const Address _myAddress;
@ -179,14 +108,8 @@ private:
mutable volatile bool _waitNoticePrinted; mutable volatile bool _waitNoticePrinted;
int _listenPort; int _listenPort;
uint8_t _ssoPsk[48];
RedisConfig *_rc; MQConfig *_mqc;
std::shared_ptr<sw::redis::Redis> _redis;
std::shared_ptr<sw::redis::RedisCluster> _cluster;
bool _redisMemberStatus;
smeeclient::SmeeClient *_smee;
}; };
} // namespace ZeroTier } // namespace ZeroTier

View file

@ -3,7 +3,7 @@ Network Controller Microservice
Every ZeroTier virtual network has a *network controller* responsible for admitting members to the network, issuing certificates, and issuing default configuration information. Every ZeroTier virtual network has a *network controller* responsible for admitting members to the network, issuing certificates, and issuing default configuration information.
This is our reference controller implementation and is almost the same as the one we use to power our own hosted services at [my.zerotier.com](https://my.zerotier.com/). The only difference is the database backend used. This is our reference controller implementation and is the same one we use to power our own hosted services at [my.zerotier.com](https://my.zerotier.com/). As of ZeroTier One version 1.2.0 this code is included in normal builds for desktop, laptop, and server (Linux, etc.) targets.
Controller data is stored in JSON format under `controller.d` in the ZeroTier working directory. It can be copied, rsync'd, placed in `git`, etc. The files under `controller.d` should not be modified in place while the controller is running or data loss may result, and if they are edited directly take care not to save corrupt JSON since that can also lead to data loss when the controller is restarted. Going through the API is strongly preferred to directly modifying these files. Controller data is stored in JSON format under `controller.d` in the ZeroTier working directory. It can be copied, rsync'd, placed in `git`, etc. The files under `controller.d` should not be modified in place while the controller is running or data loss may result, and if they are edited directly take care not to save corrupt JSON since that can also lead to data loss when the controller is restarted. Going through the API is strongly preferred to directly modifying these files.
@ -19,6 +19,10 @@ Since ZeroTier nodes are mobile and do not need static IPs, implementing high av
ZeroTier network controllers can easily be run in Docker or other container systems. Since containers do not need to actually join networks, extra privilege options like "--device=/dev/net/tun --privileged" are not needed. You'll just need to map the local JSON API port of the running controller and allow it to access the Internet (over UDP/9993 at a minimum) so things can reach and query it. ZeroTier network controllers can easily be run in Docker or other container systems. Since containers do not need to actually join networks, extra privilege options like "--device=/dev/net/tun --privileged" are not needed. You'll just need to map the local JSON API port of the running controller and allow it to access the Internet (over UDP/9993 at a minimum) so things can reach and query it.
### PostgreSQL Database Implementation
The default controller stores its data in the filesystem in `controller.d` under ZeroTier's home folder. There's an alternative implementation that stores data in PostgreSQL that can be built with `make central-controller`. Right now this is only guaranteed to build and run on Centos 7 Linux with PostgreSQL 10 installed via the [PostgreSQL Yum Repository](https://www.postgresql.org/download/linux/redhat/) and is designed for use with [ZeroTier Central](https://my.zerotier.com/). You're welcome to use it but we don't "officially" support it for end-user use and it could change at any time.
### Upgrading from Older (1.1.14 or earlier) Versions ### Upgrading from Older (1.1.14 or earlier) Versions
Older versions of this code used a SQLite database instead of in-filesystem JSON. A migration utility called `migrate-sqlite` is included here and *must* be used to migrate this data to the new format. If the controller is started with an old `controller.db` in its working directory it will terminate after printing an error to *stderr*. This is done to prevent "surprises" for those running DIY controllers using the old code. Older versions of this code used a SQLite database instead of in-filesystem JSON. A migration utility called `migrate-sqlite` is included here and *must* be used to migrate this data to the new format. If the controller is started with an old `controller.db` in its working directory it will terminate after printing an error to *stderr*. This is done to prevent "surprises" for those running DIY controllers using the old code.
@ -39,17 +43,191 @@ While networks with any valid ID can be added to the controller's database, it w
The controller JSON API is *very* sensitive about types. Integers must be integers and strings strings, etc. Incorrect types may be ignored, set to default values, or set to undefined values. The controller JSON API is *very* sensitive about types. Integers must be integers and strings strings, etc. Incorrect types may be ignored, set to default values, or set to undefined values.
Full documentation of the Controller API can be found on our [documentation site](https://docs.zerotier.com/service/v1#tag/controller) #### `/controller`
### Prometheus Metrics * Purpose: Check for controller function and return controller status
* Methods: GET
* Returns: { object }
Controller specific metrics are available from the `/metrics` endpoint. | Field | Type | Description | Writable |
| ------------------ | ----------- | ------------------------------------------------- | -------- |
| controller | boolean | Always 'true' | no |
| apiVersion | integer | Controller API version, currently 3 | no |
| clock | integer | Current clock on controller, ms since epoch | no |
#### `/controller/network`
* Purpose: List all networks hosted by this controller
* Methods: GET
* Returns: [ string, ... ]
This returns an array of 16-digit hexadecimal network IDs.
#### `/controller/network/<network ID>`
* Purpose: Create, configure, and delete hosted networks
* Methods: GET, POST, DELETE
* Returns: { object }
By making queries to this path you can create, configure, and delete networks. DELETE is final, so don't do it unless you really mean it.
When POSTing new networks take care that their IDs are not in use, otherwise you may overwrite an existing one. To create a new network with a random unused ID, POST to `/controller/network/##########______`. The #'s are the controller's 10-digit ZeroTier address and they're followed by six underscores. Check the `nwid` field of the returned JSON object for your network's newly allocated ID. Subsequent POSTs to this network must refer to its actual path.
Example:
`curl -X POST --header "X-ZT1-Auth: secret" -d '{"name":"my network"}' http://localhost:9993/controller/network/305f406058______`
**Network object format:**
| Field | Type | Description | Writable |
| --------------------- | ------------- | ------------------------------------------------- | -------- |
| id | string | 16-digit network ID | no |
| nwid | string | 16-digit network ID (legacy) | no |
| objtype | string | Always "network" | no |
| name | string | A short name for this network | YES |
| creationTime | integer | Time network record was created (ms since epoch) | no |
| private | boolean | Is access control enabled? | YES |
| enableBroadcast | boolean | Ethernet ff:ff:ff:ff:ff:ff allowed? | YES |
| v4AssignMode | object | IPv4 management and assign options (see below) | YES |
| v6AssignMode | object | IPv6 management and assign options (see below) | YES |
| mtu | integer | Network MTU (default: 2800) | YES |
| multicastLimit | integer | Maximum recipients for a multicast packet | YES |
| creationTime | integer | Time network was first created | no |
| revision | integer | Network config revision counter | no |
| routes | array[object] | Managed IPv4 and IPv6 routes; see below | YES |
| ipAssignmentPools | array[object] | IP auto-assign ranges; see below | YES |
| rules | array[object] | Traffic rules; see below | YES |
| capabilities | array[object] | Array of capability objects (see below) | YES |
| tags | array[object] | Array of tag objects (see below) | YES |
| remoteTraceTarget | string | 10-digit ZeroTier ID of remote trace target | YES |
| remoteTraceLevel | integer | Remote trace verbosity level | YES |
* Networks without rules won't carry any traffic. If you don't specify any on network creation an "accept anything" rule set will automatically be added.
* Managed IP address assignments and IP assignment pools that do not fall within a route configured in `routes` are ignored and won't be used or sent to members.
* The default for `private` is `true` and this is probably what you want. Turning `private` off means *anyone* can join your network with only its 16-digit network ID. It's also impossible to de-authorize a member as these networks don't issue or enforce certificates. Such "party line" networks are used for decentralized app backplanes, gaming, and testing but are otherwise not common.
* Changing the MTU can be disruptive and on some operating systems may require a leave/rejoin of the network or a restart of the ZeroTier service.
**Auto-Assign Modes:**
Auto assign modes (`v4AssignMode` and `v6AssignMode`) contain objects that map assignment modes to booleans.
For IPv4 the only valid setting is `zt` which, if true, causes IPv4 addresses to be auto-assigned from `ipAssignmentPools` to members that do not have an IPv4 assignment. Note that active bridges are exempt and will not get auto-assigned IPs since this can interfere with bridging. (You can still manually assign one if you want.)
IPv6 includes this option and two others: `6plane` and `rfc4193`. These assign private IPv6 addresses to each member based on a deterministic assignment scheme that allows members to emulate IPv6 NDP to skip multicast for better performance and scalability. The `rfc4193` mode gives every member a /128 on a /88 network, while `6plane` gives every member a /80 within a /40 network but uses NDP emulation to route *all* IPs under that /80 to its owner. The `6plane` mode is great for use cases like Docker since it allows every member to assign IPv6 addresses within its /80 that just work instantly and globally across the network.
**IP assignment pool object format:**
| Field | Type | Description |
| --------------------- | ------------- | ------------------------------------------------- |
| ipRangeStart | string | Starting IP address in range |
| ipRangeEnd | string | Ending IP address in range (inclusive) |
Pools are only used if auto-assignment is on for the given address type (IPv4 or IPv6) and if the entire range falls within a managed route.
IPv6 ranges work just like IPv4 ranges and look like this:
{
"ipRangeStart": "fd00:feed:feed:beef:0000:0000:0000:0000",
"ipRangeEnd": "fd00:feed:feed:beef:ffff:ffff:ffff:ffff"
}
(You can POST a shortened-form IPv6 address but the API will always report back un-shortened canonical form addresses.)
That defines a range within network `fd00:feed:feed:beef::/64` that contains up to 2^64 addresses. If an IPv6 range is large enough, the controller will assign addresses by placing each member's device ID into the address in a manner similar to the RFC4193 and 6PLANE modes. Otherwise it will assign addresses at random.
**Rule object format:**
Each rule is actually a sequence of zero or more `MATCH_` entries in the rule array followed by an `ACTION_` entry that describes what to do if all the preceding entries match. An `ACTION_` without any preceding `MATCH_` entries is always taken, so setting a single `ACTION_ACCEPT` rule yields a network that allows all traffic. If no rules are present the default action is `ACTION_DROP`.
Rules are evaluated in the order in which they appear in the array. There is currently a limit of 256 entries per network. Capabilities should be used if a larger and more complex rule set is needed since they allow rules to be grouped by purpose and only shipped to members that need them.
Each rule table entry has two common fields.
| Field | Type | Description |
| --------------------- | ------------- | ------------------------------------------------- |
| type | string | Entry type (all caps, case sensitive) |
| not | boolean | If true, MATCHes match if they don't match |
The following fields may or may not be present depending on rule type:
| Field | Type | Description |
| --------------------- | ------------- | ------------------------------------------------- |
| zt | string | 10-digit hex ZeroTier address |
| etherType | integer | Ethernet frame type |
| mac | string | Hex MAC address (with or without :'s) |
| ip | string | IPv4 or IPv6 address |
| ipTos | integer | IP type of service |
| ipProtocol | integer | IP protocol (e.g. TCP) |
| start | integer | Start of an integer range (e.g. port range) |
| end | integer | End of an integer range (inclusive) |
| id | integer | Tag ID |
| value | integer | Tag value or comparison value |
| mask | integer | Bit mask (for characteristics flags) |
The entry types and their additional fields are:
| Entry type | Description | Fields |
| ------------------------------- | ----------------------------------------------------------------- | -------------- |
| `ACTION_DROP` | Drop any packets matching this rule | (none) |
| `ACTION_ACCEPT` | Accept any packets matching this rule | (none) |
| `ACTION_TEE` | Send a copy of this packet to a node (rule parsing continues) | `zt` |
| `ACTION_REDIRECT` | Redirect this packet to another node | `zt` |
| `ACTION_DEBUG_LOG` | Output debug info on match (if built with rules engine debug) | (none) |
| `MATCH_SOURCE_ZEROTIER_ADDRESS` | Match VL1 ZeroTier address of packet sender. | `zt` |
| `MATCH_DEST_ZEROTIER_ADDRESS` | Match VL1 ZeroTier address of recipient | `zt` |
| `MATCH_ETHERTYPE` | Match Ethernet frame type | `etherType` |
| `MATCH_MAC_SOURCE` | Match source Ethernet MAC address | `mac` |
| `MATCH_MAC_DEST` | Match destination Ethernet MAC address | `mac` |
| `MATCH_IPV4_SOURCE` | Match source IPv4 address | `ip` |
| `MATCH_IPV4_DEST` | Match destination IPv4 address | `ip` |
| `MATCH_IPV6_SOURCE` | Match source IPv6 address | `ip` |
| `MATCH_IPV6_DEST` | Match destination IPv6 address | `ip` |
| `MATCH_IP_TOS` | Match IP TOS field | `ipTos` |
| `MATCH_IP_PROTOCOL` | Match IP protocol field | `ipProtocol` |
| `MATCH_IP_SOURCE_PORT_RANGE` | Match a source IP port range | `start`,`end` |
| `MATCH_IP_DEST_PORT_RANGE` | Match a destination IP port range | `start`,`end` |
| `MATCH_CHARACTERISTICS` | Match on characteristics flags | `mask`,`value` |
| `MATCH_FRAME_SIZE_RANGE` | Match a range of Ethernet frame sizes | `start`,`end` |
| `MATCH_TAGS_SAMENESS` | Match if both sides' tags differ by no more than value | `id`,`value` |
| `MATCH_TAGS_BITWISE_AND` | Match if both sides' tags AND to value | `id`,`value` |
| `MATCH_TAGS_BITWISE_OR` | Match if both sides' tags OR to value | `id`,`value` |
| `MATCH_TAGS_BITWISE_XOR` | Match if both sides' tags XOR to value | `id`,`value` |
Important notes about rules engine behavior:
* IPv4 and IPv6 IP address rules do not match for frames that are not IPv4 or IPv6 respectively.
* `ACTION_DEBUG_LOG` is a no-op on nodes not built with `ZT_RULES_ENGINE_DEBUGGING` enabled (see Network.cpp). If that is enabled nodes will dump a trace of rule evaluation results to *stdout* when this action is encountered but will otherwise keep evaluating rules. This is used for basic "smoke testing" of the rules engine.
* Multicast packets and packets destined for bridged devices treated a little differently. They are matched more than once. They are matched at the point of send with a NULL ZeroTier destination address, meaning that `MATCH_DEST_ZEROTIER_ADDRESS` is useless. That's because the true VL1 destination is not yet known. Then they are matched again for each true VL1 destination. On these later subsequent matches TEE actions are ignored and REDIRECT rules are interpreted as DROPs. This prevents multiple TEE or REDIRECT packets from being sent to third party devices.
* Rules in capabilities are always matched as if the current device is the sender (inbound == false). A capability specifies sender side rules that can be enforced on both sides.
#### `/controller/network/<network ID>/member`
* Purpose: Get a set of all members on this network
* Methods: GET
* Returns: { object }
This returns a JSON object containing all member IDs as keys and their `memberRevisionCounter` values as values.
#### `/controller/network/<network ID>/member/<address>`
* Purpose: Create, authorize, or remove a network member
* Methods: GET, POST, DELETE
* Returns: { object }
| Field | Type | Description | Writable |
| --------------------- | ------------- | ------------------------------------------------- | -------- |
| id | string | Member's 10-digit ZeroTier address | no |
| address | string | Member's 10-digit ZeroTier address | no |
| nwid | string | 16-digit network ID | no |
| authorized | boolean | Is member authorized? (for private networks) | YES |
| activeBridge | boolean | Member is able to bridge to other Ethernet nets | YES |
| identity | string | Member's public ZeroTier identity (if known) | no |
| ipAssignments | array[string] | Managed IP address assignments | YES |
| revision | integer | Member revision counter | no |
| vMajor | integer | Most recently known major version | no |
| vMinor | integer | Most recently known minor version | no |
| vRev | integer | Most recently known revision | no |
| vProto | integer | Most recently known protocl version | no |
Note that managed IP assignments are only used if they fall within a managed route. Otherwise they are ignored.
| Metric Name | Type | Description |
| --- | --- | --- |
| controller_network_count | Gauge | number of networks the controller is serving |
| controller_member_count | Gauge | number of network members the controller is serving |
| controller_network_change_count | Counter | number of times a network configuration is changed |
| controller_member_change_count | Counter | number of times a network member configuration is changed |
| controller_member_auth_count | Counter | number of network member auths |
| controller_member_deauth_count | Counter | number of network member deauths|

134
controller/RabbitMQ.cpp Normal file
View file

@ -0,0 +1,134 @@
/*
* ZeroTier One - Network Virtualization Everywhere
* Copyright (C) 2011-2019 ZeroTier, Inc. https://www.zerotier.com/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial closed-source software that incorporates or links
* directly against ZeroTier software without disclosing the source code
* of your own application.
*/
#include "RabbitMQ.hpp"
#ifdef ZT_CONTROLLER_USE_LIBPQ
#include <amqp.h>
#include <amqp_tcp_socket.h>
#include <stdexcept>
#include <cstring>
namespace ZeroTier
{
RabbitMQ::RabbitMQ(MQConfig *cfg, const char *queueName)
: _mqc(cfg)
, _qName(queueName)
, _socket(NULL)
, _status(0)
{
}
RabbitMQ::~RabbitMQ()
{
amqp_channel_close(_conn, _channel, AMQP_REPLY_SUCCESS);
amqp_connection_close(_conn, AMQP_REPLY_SUCCESS);
amqp_destroy_connection(_conn);
}
void RabbitMQ::init()
{
struct timeval tval;
memset(&tval, 0, sizeof(struct timeval));
tval.tv_sec = 5;
fprintf(stderr, "Initializing RabbitMQ %s\n", _qName);
_conn = amqp_new_connection();
_socket = amqp_tcp_socket_new(_conn);
if (!_socket) {
throw std::runtime_error("Can't create socket for RabbitMQ");
}
_status = amqp_socket_open_noblock(_socket, _mqc->host, _mqc->port, &tval);
if (_status) {
throw std::runtime_error("Can't connect to RabbitMQ");
}
amqp_rpc_reply_t r = amqp_login(_conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN,
_mqc->username, _mqc->password);
if (r.reply_type != AMQP_RESPONSE_NORMAL) {
throw std::runtime_error("RabbitMQ Login Error");
}
static int chan = 0;
{
Mutex::Lock l(_chan_m);
_channel = ++chan;
}
amqp_channel_open(_conn, _channel);
r = amqp_get_rpc_reply(_conn);
if(r.reply_type != AMQP_RESPONSE_NORMAL) {
throw std::runtime_error("Error opening communication channel");
}
_q = amqp_queue_declare(_conn, _channel, amqp_cstring_bytes(_qName), 0, 0, 0, 0, amqp_empty_table);
r = amqp_get_rpc_reply(_conn);
if (r.reply_type != AMQP_RESPONSE_NORMAL) {
throw std::runtime_error("Error declaring queue " + std::string(_qName));
}
amqp_basic_consume(_conn, _channel, amqp_cstring_bytes(_qName), amqp_empty_bytes, 0, 1, 0, amqp_empty_table);
r = amqp_get_rpc_reply(_conn);
if (r.reply_type != AMQP_RESPONSE_NORMAL) {
throw std::runtime_error("Error consuming queue " + std::string(_qName));
}
fprintf(stderr, "RabbitMQ Init OK %s\n", _qName);
}
std::string RabbitMQ::consume()
{
amqp_rpc_reply_t res;
amqp_envelope_t envelope;
amqp_maybe_release_buffers(_conn);
struct timeval timeout;
timeout.tv_sec = 1;
timeout.tv_usec = 0;
res = amqp_consume_message(_conn, &envelope, &timeout, 0);
if (res.reply_type != AMQP_RESPONSE_NORMAL) {
if (res.reply_type == AMQP_RESPONSE_LIBRARY_EXCEPTION && res.library_error == AMQP_STATUS_TIMEOUT) {
// timeout waiting for message. Return empty string
return "";
} else {
throw std::runtime_error("Error getting message");
}
}
std::string msg(
(const char*)envelope.message.body.bytes,
envelope.message.body.len
);
amqp_destroy_envelope(&envelope);
return msg;
}
}
#endif // ZT_CONTROLLER_USE_LIBPQ

81
controller/RabbitMQ.hpp Normal file
View file

@ -0,0 +1,81 @@
/*
* ZeroTier One - Network Virtualization Everywhere
* Copyright (C) 2011-2019 ZeroTier, Inc. https://www.zerotier.com/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial closed-source software that incorporates or links
* directly against ZeroTier software without disclosing the source code
* of your own application.
*/
#ifndef ZT_CONTROLLER_RABBITMQ_HPP
#define ZT_CONTROLLER_RABBITMQ_HPP
#include "DB.hpp"
namespace ZeroTier
{
struct MQConfig {
const char *host;
int port;
const char *username;
const char *password;
};
}
#ifdef ZT_CONTROLLER_USE_LIBPQ
#include "../node/Mutex.hpp"
#include <amqp.h>
#include <amqp_tcp_socket.h>
#include <string>
namespace ZeroTier
{
class RabbitMQ {
public:
RabbitMQ(MQConfig *cfg, const char *queueName);
~RabbitMQ();
void init();
std::string consume();
private:
MQConfig *_mqc;
const char *_qName;
amqp_socket_t *_socket;
amqp_connection_state_t _conn;
amqp_queue_declare_ok_t *_q;
int _status;
int _channel;
Mutex _chan_m;
};
}
#endif // ZT_CONTROLLER_USE_LIBPQ
#endif // ZT_CONTROLLER_RABBITMQ_HPP

View file

@ -1,15 +0,0 @@
#ifndef ZT_CONTROLLER_REDIS_HPP
#define ZT_CONTROLLER_REDIS_HPP
#include <string>
namespace ZeroTier {
struct RedisConfig {
std::string hostname;
int port;
std::string password;
bool clusterMode;
};
}
#endif

226
debian/changelog vendored
View file

@ -1,229 +1,3 @@
zerotier-one (1.14.2) unstable; urgency=medium
* See RELEASE-NOTES.md for release notes.
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Wed, 23 Oct 2024 01:00:00 -0700
zerotier-one (1.14.1) unstable; urgency=medium
* See RELEASE-NOTES.md for release notes.
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Wed, 11 Sep 2024 01:00:00 -0700
zerotier-one (1.14.0) unstable; urgency=medium
* See RELEASE-NOTES.md for release notes.
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Tue, 19 Mar 2024 01:00:00 -0700
zerotier-one (1.12.2) unstable; urgency=medium
* See RELEASE-NOTES.md for release notes.
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Tue, 12 Sep 2023 01:00:00 -0700
zerotier-one (1.12.1) unstable; urgency=medium
* See RELEASE-NOTES.md for release notes.
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Fri, 25 Aug 2023 01:00:00 -0700
zerotier-one (1.12.0) unstable; urgency=medium
* See RELEASE-NOTES.md for release notes.
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Thu, 17 Aug 2023 01:00:00 -0700
zerotier-one (1.10.6) unstable; urgency=medium
* See RELEASE-NOTES.md for release notes.
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Tue, 21 Mar 2023 01:00:00 -0700
zerotier-one (1.10.5) unstable; urgency=medium
* See RELEASE-NOTES.md for release notes.
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Fri, 10 Mar 2023 01:00:00 -0700
zerotier-one (1.10.4) unstable; urgency=medium
* See RELEASE-NOTES.md for release notes.
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Mon, 06 Mar 2023 01:00:00 -0700
zerotier-one (1.10.3) unstable; urgency=medium
* See RELEASE-NOTES.md for release notes.
-- Adam Ierymenko <adam.ierymenko@zerotier.com> Sat, 21 Jan 2023 01:00:00 -0700
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 zerotier-one (1.4.2) unstable; urgency=medium
* See https://github.com/zerotier/ZeroTierOne for release notes. * See https://github.com/zerotier/ZeroTierOne for release notes.

2
debian/compat vendored
View file

@ -1 +1 @@
10 8

4
debian/control vendored
View file

@ -3,14 +3,14 @@ Maintainer: Adam Ierymenko <adam.ierymenko@zerotier.com>
Section: net Section: net
Priority: optional Priority: optional
Standards-Version: 3.9.6 Standards-Version: 3.9.6
Build-Depends: debhelper Build-Depends: debhelper (>= 9)
Vcs-Git: git://github.com/zerotier/ZeroTierOne Vcs-Git: git://github.com/zerotier/ZeroTierOne
Vcs-Browser: https://github.com/zerotier/ZeroTierOne Vcs-Browser: https://github.com/zerotier/ZeroTierOne
Homepage: https://www.zerotier.com/ Homepage: https://www.zerotier.com/
Package: zerotier-one Package: zerotier-one
Architecture: any Architecture: any
Depends: adduser, libstdc++6 (>= 5), openssl Depends: ${shlibs:Depends}, ${misc:Depends}, iproute2, adduser, libstdc++6
Homepage: https://www.zerotier.com/ Homepage: https://www.zerotier.com/
Description: ZeroTier network virtualization service Description: ZeroTier network virtualization service
ZeroTier One lets you join ZeroTier virtual networks and ZeroTier One lets you join ZeroTier virtual networks and

View file

@ -10,7 +10,7 @@ Homepage: https://www.zerotier.com/
Package: zerotier-one Package: zerotier-one
Architecture: any Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, libstdc++6 Depends: ${shlibs:Depends}, ${misc:Depends}, iproute, libstdc++6
Homepage: https://www.zerotier.com/ Homepage: https://www.zerotier.com/
Description: ZeroTier network virtualization service Description: ZeroTier network virtualization service
ZeroTier One lets you join ZeroTier virtual networks and ZeroTier One lets you join ZeroTier virtual networks and

28
debian/copyright vendored
View file

@ -4,15 +4,21 @@ Source: https://github.com/zerotier/ZeroTierOne
Files: * Files: *
Copyright: 2011-2016 ZeroTier, Inc. Copyright: 2011-2016 ZeroTier, Inc.
License: ZeroTier BSL 1.1 License: GPL-3.0+
License: ZeroTier BSL 1.1 License: GPL-3.0+
Copyright (c)2019 ZeroTier, Inc. This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Use of this software is governed by the Business Source License included the Free Software Foundation, either version 3 of the License, or
in the LICENSE.TXT file in the project's root directory. (at your option) any later version.
.
Change Date: 2026-01-01 This package is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
On the date above, in accordance with the Business Source License, use MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
of this software will be governed by version 2.0 of the Apache License. GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
.
On Debian systems, the complete text of the GNU General
Public License version 3 can be found in "/usr/share/common-licenses/GPL-3".

2
debian/postinst vendored
View file

@ -3,7 +3,7 @@
case "$1" in case "$1" in
configure) configure)
if ! id zerotier-one >>/dev/null 2>&1; then 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 useradd --system --user-group --home-dir /var/lib/zerotier-one --no-create-home zerotier-one
fi fi
;; ;;
esac esac

2
debian/rules vendored Normal file → Executable file
View file

@ -7,7 +7,7 @@ CXXFLAGS=-O3 -fstack-protector-strong
dh $@ --with systemd dh $@ --with systemd
override_dh_auto_build: override_dh_auto_build:
make make -j 4
override_dh_systemd_start: override_dh_systemd_start:
dh_systemd_start --restart-after-upgrade dh_systemd_start --restart-after-upgrade

0
debian/rules.wheezy vendored Normal file → Executable file
View file

View file

@ -1,6 +1,6 @@
[Unit] [Unit]
Description=ZeroTier One Description=ZeroTier One
After=network-online.target network.target After=network-online.target
Wants=network-online.target Wants=network-online.target
[Service] [Service]

View file

@ -3,4 +3,4 @@ Manual Pages and Other Documentation
Use "./build.sh" to build the manual pages. Use "./build.sh" to build the manual pages.
You'll need either Node.js/npm installed (script will then automatically install the npm *marked-man* package) or */usr/bin/ronn*. The latter is a Ruby program packaged on some distributions as *rubygem-ronn* or *ruby-ronn* or installable as *gem install ronn*. The Node *marked-man* package and *ronn* from RubyGems are two roughly equivalent alternatives for compiling Markdown into roff/man format. You'll need either NodeJS/npm installed (script will then automatically install the npm *marked-man* package) or */usr/bin/ronn*. The latter is a Ruby program packaged on some distributions as *rubygem-ronn* or *ruby-ronn* or installable as *gem install ronn*. The Node *marked-man* package and *ronn* from rubygems are two roughly equivalent alternatives for compiling MarkDown into roff/man format.

View file

@ -81,7 +81,7 @@ These are found in the service's working directory.
If the ZeroTier One service is built with the network controller enabled, it periodically backs up its controller.db database in this file (currently every 5 minutes if there have been changes). Since this file is not a currently in use SQLite3 database it's safer to back up without corruption. On new backups the file is rotated out rather than being rewritten in place. If the ZeroTier One service is built with the network controller enabled, it periodically backs up its controller.db database in this file (currently every 5 minutes if there have been changes). Since this file is not a currently in use SQLite3 database it's safer to back up without corruption. On new backups the file is rotated out rather than being rewritten in place.
* `iddb.d/` (directory): * `iddb.d/` (directory):
Caches the public identity of every peer ZeroTier has spoken with in the last 60 days. This directory and its contents can be deleted, but this may result in slower connection initiations since it will require that we go out and re-fetch full identities for peers we're speaking to. Caches the public identity of every peer ZeroTier has spoken with in the last 60 days. This directory and its contents can be deleted, but this may result in slower connection initations since it will require that we go out and re-fetch full identities for peers we're speaking to.
* `networks.d` (directory): * `networks.d` (directory):
This caches network configurations and certificate information for networks you belong to. ZeroTier scans this directory for <network ID>.conf files on startup to recall its networks, so "touch"ing an empty <network ID>.conf file in this directory is a way of pre-configuring ZeroTier to join a specific network on startup without using the API. If the config file is empty ZeroTIer will just fetch it from the network's controller. This caches network configurations and certificate information for networks you belong to. ZeroTier scans this directory for <network ID>.conf files on startup to recall its networks, so "touch"ing an empty <network ID>.conf file in this directory is a way of pre-configuring ZeroTier to join a specific network on startup without using the API. If the config file is empty ZeroTIer will just fetch it from the network's controller.

19
docker/Dockerfile Normal file
View file

@ -0,0 +1,19 @@
# Dockerfile for ZeroTier Central Controllers
FROM centos:7
MAINTAINER Adam Ierymekno <adam.ierymenko@zerotier.com>, Grant Limberg <grant.limberg@zerotier.com>
RUN yum update -y
RUN yum install -y https://download.postgresql.org/pub/repos/yum/10/redhat/rhel-7-x86_64/pgdg-centos10-10-2.noarch.rpm
RUN yum install -y bash postgresql10 libpqxx-devel
RUN yum -y install epel-release && yum -y update && yum clean all
RUN yum -y install clang jemalloc jemalloc-devel
ADD zerotier-one /usr/local/bin/zerotier-one
RUN chmod a+x /usr/local/bin/zerotier-one
ADD docker/main.sh /
RUN chmod a+x /main.sh
ENTRYPOINT /main.sh

80
docker/main.sh Normal file
View file

@ -0,0 +1,80 @@
#!/bin/bash
if [ -z "$ZT_IDENTITY_PATH" ]; then
echo '*** FAILED: ZT_IDENTITY_PATH environment variable is not defined'
exit 1
fi
if [ -z "$ZT_DB_HOST" ]; then
echo '*** FAILED: ZT_DB_HOST environment variable not defined'
exit 1
fi
if [ -z "$ZT_DB_PORT" ]; then
echo '*** FAILED: ZT_DB_PORT environment variable not defined'
exit 1
fi
if [ -z "$ZT_DB_NAME" ]; then
echo '*** FAILED: ZT_DB_NAME environment variable not defined'
exit 1
fi
if [ -z "$ZT_DB_USER" ]; then
echo '*** FAILED: ZT_DB_USER environment variable not defined'
exit 1
fi
if [ -z "$ZT_DB_PASSWORD" ]; then
echo '*** FAILED: ZT_DB_PASSWORD environment variable not defined'
exit 1
fi
RMQ=""
if [ "$ZT_USE_RABBITMQ" == "true" ]; then
if [ -z "$RABBITMQ_HOST" ]; then
echo '*** FAILED: RABBITMQ_HOST environment variable not defined'
exit 1
fi
if [ -z "$RABBITMQ_PORT" ]; then
echo '*** FAILED: RABBITMQ_PORT environment variable not defined'
exit 1
fi
if [ -z "$RABBITMQ_USERNAME" ]; then
echo '*** FAILED: RABBITMQ_USERNAME environment variable not defined'
exit 1
fi
if [ -z "$RABBITMQ_PASSWORD" ]; then
echo '*** FAILED: RABBITMQ_PASSWORD environment variable not defined'
exit 1
fi
RMQ=", \"rabbitmq\": {
\"host\": \"${RABBITMQ_HOST}\",
\"port\": ${RABBITMQ_PORT},
\"username\": \"${RABBITMQ_USERNAME}\",
\"password\": \"${RABBITMQ_PASSWORD}\"
}"
fi
mkdir -p /var/lib/zerotier-one
pushd /var/lib/zerotier-one
ln -s $ZT_IDENTITY_PATH/identity.public identity.public
ln -s $ZT_IDENTITY_PATH/identity.secret identity.secret
popd
DEFAULT_PORT=9993
echo "{
\"settings\": {
\"portMappingEnabled\": true,
\"softwareUpdate\": \"disable\",
\"interfacePrefixBlacklist\": [
\"inot\",
\"nat64\"
],
\"controllerDbPath\": \"postgres:host=${ZT_DB_HOST} port=${ZT_DB_PORT} dbname=${ZT_DB_NAME} user=${ZT_DB_USER} password=${ZT_DB_PASSWORD} sslmode=prefer sslcert=${DB_CLIENT_CERT} sslkey=${DB_CLIENT_KEY} sslrootcert=${DB_SERVER_CA}\"
${RMQ}
}
}
" > /var/lib/zerotier-one/local.conf
export GLIBCXX_FORCE_NEW=1
export GLIBCPP_FORCE_NEW=1
export LD_PRELOAD="/usr/lib64/libjemalloc.so"
exec /usr/local/bin/zerotier-one -p${ZT_CONTROLLER_PORT:-$DEFAULT_PORT} /var/lib/zerotier-one

View file

@ -1,130 +0,0 @@
#!/bin/sh
grepzt() {
[ -f /var/lib/zerotier-one/zerotier-one.pid -a -n "$(cat /var/lib/zerotier-one/zerotier-one.pid 2>/dev/null)" -a -d "/proc/$(cat /var/lib/zerotier-one/zerotier-one.pid 2>/dev/null)" ]
return $?
}
mkztfile() {
file=$1
mode=$2
content=$3
echo "creating $file"
mkdir -p /var/lib/zerotier-one
echo -n "$content" > "/var/lib/zerotier-one/$file"
chmod "$mode" "/var/lib/zerotier-one/$file"
}
if [ "x$ZEROTIER_API_SECRET" != "x" ]
then
mkztfile authtoken.secret 0600 "$ZEROTIER_API_SECRET"
mkztfile metricstoken.secret 0600 "$ZEROTIER_API_SECRET"
fi
if [ "x$ZEROTIER_IDENTITY_PUBLIC" != "x" ]
then
mkztfile identity.public 0644 "$ZEROTIER_IDENTITY_PUBLIC"
fi
if [ "x$ZEROTIER_IDENTITY_SECRET" != "x" ]
then
mkztfile identity.secret 0600 "$ZEROTIER_IDENTITY_SECRET"
fi
if [ "x$ZEROTIER_LOCAL_CONF" != "x" ]
then
mkztfile local.conf 0644 "$ZEROTIER_LOCAL_CONF"
fi
mkztfile zerotier-one.port 0600 "9993"
killzerotier() {
log "Killing zerotier"
kill $(cat /var/lib/zerotier-one/zerotier-one.pid 2>/dev/null)
exit 0
}
log_header() {
echo -n "\r=>"
}
log_detail_header() {
echo -n "\r===>"
}
log() {
echo "$(log_header)" "$@"
}
log_params() {
title=$1
shift
log "$title" "[$@]"
}
log_detail() {
echo "$(log_detail_header)" "$@"
}
log_detail_params() {
title=$1
shift
log_detail "$title" "[$@]"
}
trap killzerotier INT TERM
log "Configuring networks to join"
mkdir -p /var/lib/zerotier-one/networks.d
log_params "Joining networks from command line:" $@
for i in "$@"
do
log_detail_params "Configuring join:" "$i"
touch "/var/lib/zerotier-one/networks.d/${i}.conf"
done
if [ "x$ZEROTIER_JOIN_NETWORKS" != "x" ]
then
log_params "Joining networks from environment:" $ZEROTIER_JOIN_NETWORKS
for i in $ZEROTIER_JOIN_NETWORKS
do
log_detail_params "Configuring join:" "$i"
touch "/var/lib/zerotier-one/networks.d/${i}.conf"
done
fi
log "Starting ZeroTier"
nohup /usr/sbin/zerotier-one &
while ! grepzt
do
log_detail "ZeroTier hasn't started, waiting a second"
if [ -f nohup.out ]
then
tail -n 10 nohup.out
fi
sleep 1
done
log_params "Writing healthcheck for networks:" $@
cat >/healthcheck.sh <<EOF
#!/bin/bash
for i in $@ $ZEROTIER_JOIN_NETWORKS
do
[ "\$(zerotier-cli get \$i status)" = "OK" ] || exit 1
done
EOF
chmod +x /healthcheck.sh
log_params "zerotier-cli info:" "$(zerotier-cli info)"
log "Sleeping infinitely"
while true
do
sleep 1
done

View file

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>tap</string>
<key>CFBundleIdentifier</key>
<string>com.zerotier.tap</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>tap</string>
<key>CFBundlePackageType</key>
<string>KEXT</string>
<key>CFBundleShortVersionString</key>
<string>20150118</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>OSBundleLibraries</key>
<dict>
<key>com.apple.kpi.mach</key>
<string>8.0</string>
<key>com.apple.kpi.bsd</key>
<string>8.0</string>
<key>com.apple.kpi.libkern</key>
<string>8.0</string>
<key>com.apple.kpi.unsupported</key>
<string>8.0</string>
</dict>
</dict>
</plist>

Binary file not shown.

View file

@ -0,0 +1,105 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>files</key>
<dict/>
<key>files2</key>
<dict/>
<key>rules</key>
<dict>
<key>^Resources/</key>
<true/>
<key>^Resources/.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^Resources/.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^version.plist$</key>
<true/>
</dict>
<key>rules2</key>
<dict>
<key>.*\.dSYM($|/)</key>
<dict>
<key>weight</key>
<real>11</real>
</dict>
<key>^(.*/)?\.DS_Store$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>2000</real>
</dict>
<key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key>
<dict>
<key>nested</key>
<true/>
<key>weight</key>
<real>10</real>
</dict>
<key>^.*</key>
<true/>
<key>^Info\.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^PkgInfo$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^Resources/</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
<key>^Resources/.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^Resources/.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^[^/]+$</key>
<dict>
<key>nested</key>
<true/>
<key>weight</key>
<real>10</real>
</dict>
<key>^embedded\.provisionprofile$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
<key>^version\.plist$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
</dict>
</dict>
</plist>

View file

@ -1,145 +0,0 @@
;
; ****************************************************************************
; * Copyright (C) 2002-2014 OpenVPN Technologies, Inc. *
; * This program is free software; you can redistribute it and/or modify *
; * it under the terms of the GNU General Public License version 2 *
; * as published by the Free Software Foundation. *
; ****************************************************************************
;
;
; ZeroTier One Virtual Network Port NDIS6 Driver
;
; Modified by ZeroTier, Inc. - https://www.zerotier.com/
;
; (1) Comment out 'tun' functionality and related features such as DHCP
; emulation, since we don't use any of that. Just want straight 'tap'.
; (2) Added custom IOCTL to enumerate L2 multicast memberships.
; (3) Increase maximum number of multicast memberships to 128.
; (4) Set default and max device MTU to 2800.
; (5) Rename/rebrand driver as ZeroTier network port driver.
;
; Original copyright below. Modifications released under GPLv2 as well.
[Version]
Signature = "$Windows NT$"
CatalogFile = zttap300.cat
ClassGUID = {4d36e972-e325-11ce-bfc1-08002be10318}
Provider = %Provider%
Class = Net
DriverVer=11/24/2020,3.00.00.1
[Strings]
DeviceDescription = "ZeroTier Virtual Port"
Provider = "ZeroTier"
[Manufacturer]
%Provider%=zttap300,NTx86
%Provider%=zttap300,NTamd64
%Provider%=zttap300,NTarm64
[zttap300.NTx86]
%DeviceDescription% = zttap300.ndi, root\zttap300 ; Root enumerated
%DeviceDescription% = zttap300.ndi, zttap300 ; Legacy
[zttap300.NTamd64]
%DeviceDescription% = zttap300.ndi, root\zttap300 ; Root enumerated
%DeviceDescription% = zttap300.ndi, zttap300 ; Legacy
[zttap300.NTarm64]
%DeviceDescription% = zttap300.ndi, root\zttap300 ; Root enumerated
%DeviceDescription% = zttap300.ndi, zttap300 ; Legacy
;----------------- Characteristics ------------
; NCF_PHYSICAL = 0x04
; NCF_VIRTUAL = 0x01
; NCF_SOFTWARE_ENUMERATED = 0x02
; NCF_HIDDEN = 0x08
; NCF_NO_SERVICE = 0x10
; NCF_HAS_UI = 0x80
;----------------- Characteristics ------------
[zttap300.ndi]
CopyFiles = zttap300.driver, zttap300.files
AddReg = zttap300.reg
AddReg = zttap300.params.reg
Characteristics = 0x81
*IfType = 0x6 ; IF_TYPE_ETHERNET_CSMACD
*MediaType = 0x0 ; NdisMedium802_3
*PhysicalMediaType = 14 ; NdisPhysicalMedium802_3
[zttap300.ndi.Services]
AddService = zttap300, 2, zttap300.service
[zttap300.reg]
HKR, Ndi, Service, 0, "zttap300"
HKR, Ndi\Interfaces, UpperRange, 0, "ndis5" ; yes, 'ndis5' is correct... yup, Windows.
HKR, Ndi\Interfaces, LowerRange, 0, "ethernet"
HKR, , Manufacturer, 0, "%Provider%"
HKR, , ProductName, 0, "%DeviceDescription%"
[zttap300.params.reg]
HKR, Ndi\params\MTU, ParamDesc, 0, "MTU"
HKR, Ndi\params\MTU, Type, 0, "int"
HKR, Ndi\params\MTU, Default, 0, "2800"
HKR, Ndi\params\MTU, Optional, 0, "0"
HKR, Ndi\params\MTU, Min, 0, "100"
HKR, Ndi\params\MTU, Max, 0, "2800"
HKR, Ndi\params\MTU, Step, 0, "1"
HKR, Ndi\params\MediaStatus, ParamDesc, 0, "Media Status"
HKR, Ndi\params\MediaStatus, Type, 0, "enum"
HKR, Ndi\params\MediaStatus, Default, 0, "0"
HKR, Ndi\params\MediaStatus, Optional, 0, "0"
HKR, Ndi\params\MediaStatus\enum, "0", 0, "Application Controlled"
HKR, Ndi\params\MediaStatus\enum, "1", 0, "Always Connected"
HKR, Ndi\params\MAC, ParamDesc, 0, "MAC Address"
HKR, Ndi\params\MAC, Type, 0, "edit"
HKR, Ndi\params\MAC, Optional, 0, "1"
HKR, Ndi\params\AllowNonAdmin, ParamDesc, 0, "Non-Admin Access"
HKR, Ndi\params\AllowNonAdmin, Type, 0, "enum"
HKR, Ndi\params\AllowNonAdmin, Default, 0, "0"
HKR, Ndi\params\AllowNonAdmin, Optional, 0, "0"
HKR, Ndi\params\AllowNonAdmin\enum, "0", 0, "Not Allowed"
HKR, Ndi\params\AllowNonAdmin\enum, "1", 0, "Allowed"
;---------- Service Type -------------
; SERVICE_KERNEL_DRIVER = 0x01
; SERVICE_WIN32_OWN_PROCESS = 0x10
;---------- Service Type -------------
;---------- Start Mode ---------------
; SERVICE_BOOT_START = 0x0
; SERVICE_SYSTEM_START = 0x1
; SERVICE_AUTO_START = 0x2
; SERVICE_DEMAND_START = 0x3
; SERVICE_DISABLED = 0x4
;---------- Start Mode ---------------
[zttap300.service]
DisplayName = %DeviceDescription%
ServiceType = 1
StartType = 3
ErrorControl = 1
LoadOrderGroup = NDIS
ServiceBinary = %12%\zttap300.sys
;----------------- Copy Flags ------------
; COPYFLG_NOSKIP = 0x02
; COPYFLG_NOVERSIONCHECK = 0x04
;----------------- Copy Flags ------------
[SourceDisksNames]
1 = %DeviceDescription%, zttap300.sys
[SourceDisksFiles]
zttap300.sys = 1
[DestinationDirs]
zttap300.files = 11
zttap300.driver = 12
[zttap300.files]
;
[zttap300.driver]
zttap300.sys,,,6 ; COPYFLG_NOSKIP | COPYFLG_NOVERSIONCHECK

Binary file not shown.

View file

@ -30,11 +30,11 @@ CatalogFile = zttap300.cat
ClassGUID = {4d36e972-e325-11ce-bfc1-08002be10318} ClassGUID = {4d36e972-e325-11ce-bfc1-08002be10318}
Provider = %Provider% Provider = %Provider%
Class = Net Class = Net
DriverVer=11/24/2020,3.00.00.1 DriverVer=08/13/2015,6.2.9200.20557
[Strings] [Strings]
DeviceDescription = "ZeroTier Virtual Port" DeviceDescription = "ZeroTier One Virtual Port"
Provider = "ZeroTier" Provider = "ZeroTier Networks LLC" ; We're ZeroTier, Inc. now but kernel mode certs are $300+ so fuqdat.
; To build for x86, take NTamd64 off this and off the named section manually, build, then put it back! ; To build for x86, take NTamd64 off this and off the named section manually, build, then put it back!
[Manufacturer] [Manufacturer]
@ -141,4 +141,3 @@ zttap300.driver = 12
[zttap300.driver] [zttap300.driver]
zttap300.sys,,,6 ; COPYFLG_NOSKIP | COPYFLG_NOVERSIONCHECK zttap300.sys,,,6 ; COPYFLG_NOSKIP | COPYFLG_NOVERSIONCHECK

View file

@ -1,15 +1,10 @@
;
; ****************************************************************************
; * Copyright (C) 2002-2014 OpenVPN Technologies, Inc. *
; * This program is free software; you can redistribute it and/or modify *
; * it under the terms of the GNU General Public License version 2 *
; * as published by the Free Software Foundation. *
; ****************************************************************************
;
; ;
; ZeroTier One Virtual Network Port NDIS6 Driver ; ZeroTier One Virtual Network Port NDIS6 Driver
; ;
; Based on the OpenVPN tap-windows6 driver version 9.21.1 git
; commit 48f027cfca52b16b5fd23d82e6016ed8a91fc4d3.
; See: https://github.com/OpenVPN/tap-windows6
;
; Modified by ZeroTier, Inc. - https://www.zerotier.com/ ; Modified by ZeroTier, Inc. - https://www.zerotier.com/
; ;
; (1) Comment out 'tun' functionality and related features such as DHCP ; (1) Comment out 'tun' functionality and related features such as DHCP
@ -20,6 +15,14 @@
; (5) Rename/rebrand driver as ZeroTier network port driver. ; (5) Rename/rebrand driver as ZeroTier network port driver.
; ;
; Original copyright below. Modifications released under GPLv2 as well. ; Original copyright below. Modifications released under GPLv2 as well.
;
; ****************************************************************************
; * Copyright (C) 2002-2014 OpenVPN Technologies, Inc. *
; * This program is free software; you can redistribute it and/or modify *
; * it under the terms of the GNU General Public License version 2 *
; * as published by the Free Software Foundation. *
; ****************************************************************************
;
[Version] [Version]
Signature = "$Windows NT$" Signature = "$Windows NT$"
@ -27,17 +30,17 @@ CatalogFile = zttap300.cat
ClassGUID = {4d36e972-e325-11ce-bfc1-08002be10318} ClassGUID = {4d36e972-e325-11ce-bfc1-08002be10318}
Provider = %Provider% Provider = %Provider%
Class = Net Class = Net
DriverVer=11/24/2020,3.00.00.1 DriverVer=08/13/2015,6.2.9200.20557
[Strings] [Strings]
DeviceDescription = "ZeroTier Virtual Port" DeviceDescription = "ZeroTier One Virtual Port"
Provider = "ZeroTier" Provider = "ZeroTier Networks LLC" ; We're ZeroTier, Inc. now but kernel mode certs are $300+ so fuqdat.
; To build for x86, take NTamd64 off this and off the named section manually, build, then put it back!
[Manufacturer] [Manufacturer]
%Provider%=zttap300,NTx86 %Provider%=zttap300,NTamd64
;%Provider%=zttap300,NTamd64
[zttap300.NTx86] [zttap300]
%DeviceDescription% = zttap300.ndi, root\zttap300 ; Root enumerated %DeviceDescription% = zttap300.ndi, root\zttap300 ; Root enumerated
%DeviceDescription% = zttap300.ndi, zttap300 ; Legacy %DeviceDescription% = zttap300.ndi, zttap300 ; Legacy
@ -138,4 +141,3 @@ zttap300.driver = 12
[zttap300.driver] [zttap300.driver]
zttap300.sys,,,6 ; COPYFLG_NOSKIP | COPYFLG_NOVERSIONCHECK zttap300.sys,,,6 ; COPYFLG_NOSKIP | COPYFLG_NOVERSIONCHECK

Binary file not shown.

View file

@ -1,15 +0,0 @@
# Dockerfile for ZeroTier Central Controllers
FROM registry.zerotier.com/zerotier/ctlbuild:latest as builder
MAINTAINER Adam Ierymekno <adam.ierymenko@zerotier.com>, Grant Limberg <grant.limberg@zerotier.com>
ADD . /ZeroTierOne
RUN export PATH=$PATH:~/.cargo/bin && cd ZeroTierOne && make clean && make central-controller -j8
FROM registry.zerotier.com/zerotier/ctlrun:latest
COPY --from=builder /ZeroTierOne/zerotier-one /usr/local/bin/zerotier-one
RUN chmod a+x /usr/local/bin/zerotier-one
RUN echo "/usr/local/lib64" > /etc/ld.so.conf.d/usr-local-lib64.conf && ldconfig
ADD ext/central-controller-docker/main.sh /
RUN chmod a+x /main.sh
ENTRYPOINT /main.sh

View file

@ -1,26 +0,0 @@
# Dockerfile for building ZeroTier Central Controllers
FROM ubuntu:jammy as builder
MAINTAINER Adam Ierymekno <adam.ierymenko@zerotier.com>, Grant Limberg <grant.limberg@zerotier.com>
ARG git_branch=master
RUN apt update && apt upgrade -y
RUN apt -y install \
build-essential \
pkg-config \
bash \
clang \
libjemalloc2 \
libjemalloc-dev \
libpq5 \
libpq-dev \
openssl \
libssl-dev \
postgresql-client \
postgresql-client-common \
curl \
google-perftools \
libgoogle-perftools-dev \
protobuf-compiler
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y

View file

@ -1,15 +0,0 @@
FROM ubuntu:jammy
RUN apt update && apt upgrade -y
RUN apt -y install \
netcat \
postgresql-client \
postgresql-client-common \
libjemalloc2 \
libpq5 \
curl \
binutils \
linux-tools-gke \
perf-tools-unstable \
google-perftools

View file

@ -1,16 +0,0 @@
registry = registry.zerotier.com/zerotier
all: controller-builder controller-runbase
buildx:
@echo "docker buildx create"
# docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
docker run --privileged --rm tonistiigi/binfmt --install all
@echo docker buildx create --name multiarch --driver docker-container --use
@echo docker buildx inspect --bootstrap
controller-builder: buildx
docker buildx build --no-cache --platform linux/amd64,linux/arm64 -t $(registry)/ctlbuild:latest -f Dockerfile.builder . --push
controller-runbase: buildx
docker buildx build --no-cache --platform linux/amd64,linux/arm64 -t $(registry)/ctlrun:latest -f Dockerfile.run_base . --push

View file

@ -1,3 +0,0 @@
# ZeroTier Central Controller Docker Image
Dockerfile & startup script for use with [ZeroTier Central](https://my.zerotier.com). Not intended for public use.

View file

@ -1,115 +0,0 @@
#!/bin/bash
if [ -z "$ZT_IDENTITY_PATH" ]; then
echo '*** FAILED: ZT_IDENTITY_PATH environment variable is not defined'
exit 1
fi
if [ -z "$ZT_DB_HOST" ]; then
echo '*** FAILED: ZT_DB_HOST environment variable not defined'
exit 1
fi
if [ -z "$ZT_DB_PORT" ]; then
echo '*** FAILED: ZT_DB_PORT environment variable not defined'
exit 1
fi
if [ -z "$ZT_DB_NAME" ]; then
echo '*** FAILED: ZT_DB_NAME environment variable not defined'
exit 1
fi
if [ -z "$ZT_DB_USER" ]; then
echo '*** FAILED: ZT_DB_USER environment variable not defined'
exit 1
fi
if [ -z "$ZT_DB_PASSWORD" ]; then
echo '*** FAILED: ZT_DB_PASSWORD environment variable not defined'
exit 1
fi
REDIS=""
if [ "$ZT_USE_REDIS" == "true" ]; then
if [ -z "$ZT_REDIS_HOST" ]; then
echo '*** FAILED: ZT_REDIS_HOST environment variable not defined'
exit 1
fi
if [ -z "$ZT_REDIS_PORT" ]; then
echo '*** FAILED: ZT_REDIS_PORT enivronment variable not defined'
exit 1
fi
if [ -z "$ZT_REDIS_CLUSTER_MODE" ]; then
echo '*** FAILED: ZT_REDIS_CLUSTER_MODE environment variable not defined'
exit 1
fi
REDIS="\"redis\": {
\"hostname\": \"${ZT_REDIS_HOST}\",
\"port\": ${ZT_REDIS_PORT},
\"clusterMode\": ${ZT_REDIS_CLUSTER_MODE},
\"password\": \"${ZT_REDIS_PASSWORD}\"
}
"
else
REDIS="\"redis\": null"
fi
mkdir -p /var/lib/zerotier-one
pushd /var/lib/zerotier-one
ln -s $ZT_IDENTITY_PATH/identity.public identity.public
ln -s $ZT_IDENTITY_PATH/identity.secret identity.secret
if [ -f "$ZT_IDENTITY_PATH/authtoken.secret" ]; then
ln -s $ZT_IDENTITY_PATH/authtoken.secret authtoken.secret
fi
popd
DEFAULT_PORT=9993
DEFAULT_LB_MODE=false
APP_NAME="controller-$(cat /var/lib/zerotier-one/identity.public | cut -d ':' -f 1)"
echo "{
\"settings\": {
\"controllerDbPath\": \"postgres:host=${ZT_DB_HOST} port=${ZT_DB_PORT} dbname=${ZT_DB_NAME} user=${ZT_DB_USER} password=${ZT_DB_PASSWORD} application_name=${APP_NAME} sslmode=prefer sslcert=${DB_CLIENT_CERT} sslkey=${DB_CLIENT_KEY} sslrootcert=${DB_SERVER_CA}\",
\"portMappingEnabled\": true,
\"softwareUpdate\": \"disable\",
\"interfacePrefixBlacklist\": [
\"inot\",
\"nat64\"
],
\"lowBandwidthMode\": ${ZT_LB_MODE:-$DEFAULT_LB_MODE},
\"ssoRedirectURL\": \"${ZT_SSO_REDIRECT_URL}\",
\"allowManagementFrom\": [\"127.0.0.1\", \"::1\", \"10.0.0.0/8\"],
${REDIS}
}
}
" > /var/lib/zerotier-one/local.conf
if [ -n "$DB_SERVER_CA" ]; then
echo "secret list"
chmod 600 /secrets/db/*.pem
ls -l /secrets/db/
until /usr/bin/pg_isready -h ${ZT_DB_HOST} -p ${ZT_DB_PORT} -d "sslmode=prefer sslcert=${DB_CLIENT_CERT} sslkey=${DB_CLIENT_KEY} sslrootcert=${DB_SERVER_CA}"; do
echo "Waiting for PostgreSQL...";
sleep 2;
done
else
until /usr/bin/pg_isready -h ${ZT_DB_HOST} -p ${ZT_DB_PORT}; do
echo "Waiting for PostgreSQL...";
sleep 2;
done
fi
if [ -n "$ZT_TEMPORAL_HOST" ] && [ -n "$ZT_TEMPORAL_PORT" ]; then
echo "waiting for temporal..."
while ! nc -z ${ZT_TEMPORAL_HOST} ${ZT_TEMPORAL_PORT}; do
echo "waiting...";
sleep 1;
done
echo "Temporal is up"
fi
export GLIBCXX_FORCE_NEW=1
export GLIBCPP_FORCE_NEW=1
export LD_PRELOAD="/usr/lib/x86_64-linux-gnu/libjemalloc.so.2"
exec /usr/local/bin/zerotier-one -p${ZT_CONTROLLER_PORT:-$DEFAULT_PORT} /var/lib/zerotier-one

Some files were not shown because too many files have changed in this diff Show more