diff --git a/.drone.jsonnet b/.drone.jsonnet
index 338d79b63..eae15501b 100644
--- a/.drone.jsonnet
+++ b/.drone.jsonnet
@@ -1,26 +1,7 @@
+local registry = "084037375216.dkr.ecr.us-east-2.amazonaws.com";
local targets = [
- //
- // Render these into .drone.yaml by running "make drone"
- //
- { "os": "linux", "name": "el9", "isas": [ "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "tag" ] },
- { "os": "linux", "name": "el8", "isas": [ "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "tag" ] },
- { "os": "linux", "name": "el7", "isas": [ "amd64", "ppc64le"], "events": [ "tag" ] },
- { "os": "linux", "name": "el6", "isas": [ "amd64" ], "events": [ "tag" ] },
- { "os": "linux", "name": "amzn2", "isas": [ "amd64", "arm64" ], "events": [ "tag" ] },
- { "os": "linux", "name": "fc37", "isas": [ "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "tag" ] },
- { "os": "linux", "name": "fc36", "isas": [ "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "tag" ] },
- { "os": "linux", "name": "fc35", "isas": [ "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "tag" ] },
- { "os": "linux", "name": "jammy", "isas": [ "amd64", "arm64", "armv7", "riscv64", "ppc64le", "s390x" ], "events": [ "tag" ] },
- { "os": "linux", "name": "focal", "isas": [ "amd64", "arm64", "armv7", "riscv64", "ppc64le" ], "events": [ "tag" ] },
- { "os": "linux", "name": "bionic", "isas": [ "amd64", "arm64", "386", "ppc64le", "s390x" ], "events": ["tag" ] },
- { "os": "linux", "name": "xenial", "isas": [ "amd64", "arm64", "386" ], "events": [ "tag" ] },
- { "os": "linux", "name": "sid", "isas": [ "386", "amd64", "arm64", "armv7", "riscv64", "mips64le", "ppc64le", "s390x" ], "events": [ "push", "tag" ] },
- { "os": "linux", "name": "bookworm", "isas": [ "amd64", "arm64", "armv7", "386", "mips64le", "ppc64le", "s390x" ], "events": [ "tag" ] },
- { "os": "linux", "name": "bullseye", "isas": [ "amd64", "arm64", "armv7", "386", "mips64le", "ppc64le", "s390x" ], "events": [ "tag" ] },
- { "os": "linux", "name": "buster", "isas": [ "amd64", "arm64", "armv7", "386", "mips64le", "ppc64le", "s390x" ], "events": [ "tag" ] },
- { "os": "linux", "name": "stretch", "isas": [ "amd64", "arm64", "386" ], "events": [ "tag" ] },
- // { "os": "windows", "name": "win2k19", "isas": [ "amd64" ], "events": ["push", "tag" ] }
+ { "os": "linux", "name": "sid", "isas": [ "386", "armv7", "amd64", "arm64", "mips64le", "ppc64le", "s390x", "riscv64" ], "events": [ "push", "tag", "custom" ] },
];
local Build(platform, os, isa, events) = {
@@ -32,27 +13,18 @@ local Build(platform, os, isa, events) = {
"steps": [
{
"name": "build",
- "image": "registry.sean.farm/honda-builder",
- "commands": [ "./ci/scripts/build.sh " + platform + " " + isa + " " + "100.0.0+${DRONE_COMMIT_SHA:0:8}" + " " + "${DRONE_BUILD_EVENT}" ]
+ "image": registry + "/honda-builder",
+ "commands": [
+ "aws ecr get-login-password --region us-east-2 | docker login --username AWS --password-stdin " + registry,
+ "./ci/scripts/build.sh " + platform + " " + isa + " " + "100.0.0+${DRONE_COMMIT_SHA:0:8}" + " " + "${DRONE_BUILD_EVENT}"
+ ]
},
- {
- "name": "list",
- "image": "registry.sean.farm/honda-builder",
- "commands": [ "ls -la " + platform ]
- },
- {
- "name": "notify-mattermost",
- "image": "registry.sean.farm/mattermost-notify",
- "environment": {
- "token": { "from_secret": "mattermost-token" },
- "host": { "from_secret": "mattermost-host" },
- "channel": { "from_secret": "mattermost-channel" },
- "maxRetry": 3,
- },
- "when": { "status": [ "failure" ] }
- }
+ // {
+ // "name": "list",
+ // "image": registry + "/honda-builder",
+ // "commands": [ "ls -la " + platform ]
+ // },
],
- "image_pull_secrets": [ "dockerconfigjson" ],
[ if isa == "arm64" || isa == "armv7" then "platform" ]: { os: os, arch: "arm64" },
"trigger": { "event": events }
};
diff --git a/.drone.yml b/.drone.yml
index 54587abf4..fc7643d45 100644
--- a/.drone.yml
+++ b/.drone.yml
@@ -1,1648 +1,25 @@
---
clone:
depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: el9 amd64 build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh el9 amd64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la el9
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: el9 arm64 build
-platform:
- arch: arm64
- os: linux
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh el9 arm64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la el9
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: el9 ppc64le build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh el9 ppc64le 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la el9
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: el9 s390x build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh el9 s390x 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la el9
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: el8 amd64 build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh el8 amd64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la el8
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: el8 arm64 build
-platform:
- arch: arm64
- os: linux
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh el8 arm64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la el8
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: el8 ppc64le build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh el8 ppc64le 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la el8
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: el8 s390x build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh el8 s390x 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la el8
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: el7 amd64 build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh el7 amd64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la el7
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: el7 ppc64le build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh el7 ppc64le 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la el7
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: el6 amd64 build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh el6 amd64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la el6
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: amzn2 amd64 build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh amzn2 amd64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la amzn2
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: amzn2 arm64 build
-platform:
- arch: arm64
- os: linux
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh amzn2 arm64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la amzn2
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: fc37 amd64 build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh fc37 amd64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la fc37
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: fc37 arm64 build
-platform:
- arch: arm64
- os: linux
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh fc37 arm64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la fc37
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: fc37 ppc64le build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh fc37 ppc64le 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la fc37
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: fc37 s390x build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh fc37 s390x 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la fc37
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: fc36 amd64 build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh fc36 amd64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la fc36
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: fc36 arm64 build
-platform:
- arch: arm64
- os: linux
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh fc36 arm64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la fc36
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: fc36 ppc64le build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh fc36 ppc64le 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la fc36
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: fc36 s390x build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh fc36 s390x 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la fc36
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: fc35 amd64 build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh fc35 amd64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la fc35
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: fc35 arm64 build
-platform:
- arch: arm64
- os: linux
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh fc35 arm64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la fc35
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: fc35 ppc64le build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh fc35 ppc64le 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la fc35
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: fc35 s390x build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh fc35 s390x 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la fc35
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: jammy amd64 build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh jammy amd64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la jammy
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: jammy arm64 build
-platform:
- arch: arm64
- os: linux
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh jammy arm64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la jammy
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: jammy armv7 build
-platform:
- arch: arm64
- os: linux
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh jammy armv7 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la jammy
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: jammy riscv64 build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh jammy riscv64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la jammy
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: jammy ppc64le build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh jammy ppc64le 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la jammy
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: jammy s390x build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh jammy s390x 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la jammy
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: focal amd64 build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh focal amd64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la focal
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: focal arm64 build
-platform:
- arch: arm64
- os: linux
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh focal arm64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la focal
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: focal armv7 build
-platform:
- arch: arm64
- os: linux
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh focal armv7 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la focal
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: focal riscv64 build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh focal riscv64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la focal
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: focal ppc64le build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh focal ppc64le 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la focal
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: bionic amd64 build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh bionic amd64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la bionic
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: bionic arm64 build
-platform:
- arch: arm64
- os: linux
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh bionic arm64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la bionic
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: bionic 386 build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh bionic 386 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la bionic
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: bionic ppc64le build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh bionic ppc64le 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la bionic
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: bionic s390x build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh bionic s390x 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la bionic
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: xenial amd64 build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh xenial amd64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la xenial
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: xenial arm64 build
-platform:
- arch: arm64
- os: linux
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh xenial arm64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la xenial
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: xenial 386 build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh xenial 386 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la xenial
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
kind: pipeline
name: sid 386 build
pull: always
steps:
- commands:
+ - aws ecr get-login-password --region us-east-2 | docker login --username AWS --password-stdin
+ 084037375216.dkr.ecr.us-east-2.amazonaws.com
- ./ci/scripts/build.sh sid 386 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
+ image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder
name: build
-- commands:
- - ls -la sid
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
trigger:
event:
- push
- tag
+ - custom
type: docker
---
clone:
depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: sid amd64 build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh sid amd64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la sid
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - push
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: sid arm64 build
-platform:
- arch: arm64
- os: linux
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh sid arm64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la sid
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - push
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
kind: pipeline
name: sid armv7 build
platform:
@@ -1651,1005 +28,131 @@ platform:
pull: always
steps:
- commands:
+ - aws ecr get-login-password --region us-east-2 | docker login --username AWS --password-stdin
+ 084037375216.dkr.ecr.us-east-2.amazonaws.com
- ./ci/scripts/build.sh sid armv7 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
+ image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder
name: build
-- commands:
- - ls -la sid
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
trigger:
event:
- push
- tag
+ - custom
type: docker
---
clone:
depth: 1
-image_pull_secrets:
-- dockerconfigjson
kind: pipeline
-name: sid riscv64 build
+name: sid amd64 build
pull: always
steps:
- commands:
- - ./ci/scripts/build.sh sid riscv64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
+ - aws ecr get-login-password --region us-east-2 | docker login --username AWS --password-stdin
+ 084037375216.dkr.ecr.us-east-2.amazonaws.com
+ - ./ci/scripts/build.sh sid 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
-- commands:
- - ls -la sid
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
trigger:
event:
- push
- tag
+ - custom
+type: docker
+---
+clone:
+ depth: 1
+kind: pipeline
+name: sid arm64 build
+platform:
+ arch: arm64
+ os: linux
+pull: always
+steps:
+- commands:
+ - aws ecr get-login-password --region us-east-2 | docker login --username AWS --password-stdin
+ 084037375216.dkr.ecr.us-east-2.amazonaws.com
+ - ./ci/scripts/build.sh sid 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
+trigger:
+ event:
+ - push
+ - tag
+ - custom
type: docker
---
clone:
depth: 1
-image_pull_secrets:
-- dockerconfigjson
kind: pipeline
name: sid mips64le build
pull: always
steps:
- commands:
+ - aws ecr get-login-password --region us-east-2 | docker login --username AWS --password-stdin
+ 084037375216.dkr.ecr.us-east-2.amazonaws.com
- ./ci/scripts/build.sh sid mips64le 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
+ image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder
name: build
-- commands:
- - ls -la sid
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
trigger:
event:
- push
- tag
+ - custom
type: docker
---
clone:
depth: 1
-image_pull_secrets:
-- dockerconfigjson
kind: pipeline
name: sid ppc64le build
pull: always
steps:
- commands:
+ - aws ecr get-login-password --region us-east-2 | docker login --username AWS --password-stdin
+ 084037375216.dkr.ecr.us-east-2.amazonaws.com
- ./ci/scripts/build.sh sid ppc64le 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
+ image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder
name: build
-- commands:
- - ls -la sid
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
trigger:
event:
- push
- tag
+ - custom
type: docker
---
clone:
depth: 1
-image_pull_secrets:
-- dockerconfigjson
kind: pipeline
name: sid s390x build
pull: always
steps:
- commands:
+ - aws ecr get-login-password --region us-east-2 | docker login --username AWS --password-stdin
+ 084037375216.dkr.ecr.us-east-2.amazonaws.com
- ./ci/scripts/build.sh sid s390x 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
+ image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder
name: build
-- commands:
- - ls -la sid
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
trigger:
event:
- push
- tag
+ - custom
type: docker
---
clone:
depth: 1
-image_pull_secrets:
-- dockerconfigjson
kind: pipeline
-name: bookworm amd64 build
+name: sid riscv64 build
pull: always
steps:
- commands:
- - ./ci/scripts/build.sh bookworm amd64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
+ - aws ecr get-login-password --region us-east-2 | docker login --username AWS --password-stdin
+ 084037375216.dkr.ecr.us-east-2.amazonaws.com
+ - ./ci/scripts/build.sh sid riscv64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
+ image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder
name: build
-- commands:
- - ls -la bookworm
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: bookworm arm64 build
-platform:
- arch: arm64
- os: linux
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh bookworm arm64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la bookworm
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: bookworm armv7 build
-platform:
- arch: arm64
- os: linux
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh bookworm armv7 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la bookworm
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: bookworm 386 build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh bookworm 386 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la bookworm
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: bookworm mips64le build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh bookworm mips64le 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la bookworm
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: bookworm ppc64le build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh bookworm ppc64le 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la bookworm
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: bookworm s390x build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh bookworm s390x 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la bookworm
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: bullseye amd64 build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh bullseye amd64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la bullseye
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: bullseye arm64 build
-platform:
- arch: arm64
- os: linux
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh bullseye arm64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la bullseye
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: bullseye armv7 build
-platform:
- arch: arm64
- os: linux
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh bullseye armv7 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la bullseye
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: bullseye 386 build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh bullseye 386 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la bullseye
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: bullseye mips64le build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh bullseye mips64le 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la bullseye
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: bullseye ppc64le build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh bullseye ppc64le 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la bullseye
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: bullseye s390x build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh bullseye s390x 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la bullseye
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: buster amd64 build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh buster amd64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la buster
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: buster arm64 build
-platform:
- arch: arm64
- os: linux
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh buster arm64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la buster
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: buster armv7 build
-platform:
- arch: arm64
- os: linux
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh buster armv7 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la buster
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: buster 386 build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh buster 386 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la buster
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: buster mips64le build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh buster mips64le 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la buster
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: buster ppc64le build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh buster ppc64le 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la buster
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: buster s390x build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh buster s390x 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la buster
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: stretch amd64 build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh stretch amd64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la stretch
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: stretch arm64 build
-platform:
- arch: arm64
- os: linux
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh stretch arm64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la stretch
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
-trigger:
- event:
- - tag
-type: docker
----
-clone:
- depth: 1
-image_pull_secrets:
-- dockerconfigjson
-kind: pipeline
-name: stretch 386 build
-pull: always
-steps:
-- commands:
- - ./ci/scripts/build.sh stretch 386 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT}
- image: registry.sean.farm/honda-builder
- name: build
-- commands:
- - ls -la stretch
- image: registry.sean.farm/honda-builder
- name: list
-- environment:
- channel:
- from_secret: mattermost-channel
- host:
- from_secret: mattermost-host
- maxRetry: 3
- token:
- from_secret: mattermost-token
- image: registry.sean.farm/mattermost-notify
- name: notify-mattermost
- when:
- status:
- - failure
trigger:
event:
+ - push
- tag
+ - custom
type: docker
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 000000000..1f76d5b67
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,108 @@
+on: [ push ]
+
+jobs:
+ build_ubuntu:
+ runs-on: ubuntu-latest
+ steps:
+ - name: gitconfig
+ run: |
+ git config --global core.autocrlf false
+ git config --global core.eol lf
+ - name: checkout
+ uses: actions/checkout@v3
+ - name: Install Rust
+ uses: actions-rs/toolchain@v1
+ with:
+ toolchain: stable
+ target: aarch64-apple-darwin
+ override: true
+ components: rustfmt, clippy
+
+ - name: Set up cargo cache
+ uses: actions/cache@v3
+ continue-on-error: false
+ with:
+ path: |
+ ~/.cargo/bin/
+ ~/.cargo/registry/index/
+ ~/.cargo/registry/cache/
+ ~/.cargo/git/db/
+ target/
+ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
+ restore-keys: ${{ runner.os }}-cargo-
+ - name: make
+ run: make
+ - name: selftest
+ run: |
+ make selftest
+ ./zerotier-selftest
+
+ build_macos:
+ runs-on: macos-latest
+ steps:
+ - name: gitconfig
+ run: |
+ git config --global core.autocrlf false
+ git config --global core.eol lf
+ - name: checkout
+ uses: actions/checkout@v3
+ - name: Install Rust
+ uses: actions-rs/toolchain@v1
+ with:
+ toolchain: stable
+ target: aarch64-apple-darwin
+ override: true
+ components: rustfmt, clippy
+ - name: Set up cargo cache
+ uses: actions/cache@v3
+ continue-on-error: false
+ with:
+ path: |
+ ~/.cargo/bin/
+ ~/.cargo/registry/index/
+ ~/.cargo/registry/cache/
+ ~/.cargo/git/db/
+ target/
+ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
+ restore-keys: ${{ runner.os }}-cargo-
+ - name: make
+ run: make
+ - name: selftest
+ run: |
+ make selftest
+ ./zerotier-selftest
+
+ build_windows:
+ runs-on: windows-latest
+ steps:
+ - name: gitconfig
+ run: |
+ git config --global core.autocrlf false
+ git config --global core.eol lf
+ - name: checkout
+ uses: actions/checkout@v3
+ - name: Install Rust
+ uses: actions-rs/toolchain@v1
+ with:
+ toolchain: stable
+ target: aarch64-apple-darwin
+ override: true
+ components: rustfmt, clippy
+ - name: Set up cargo cache
+ uses: actions/cache@v3
+ continue-on-error: false
+ with:
+ path: |
+ ~/.cargo/bin/
+ ~/.cargo/registry/index/
+ ~/.cargo/registry/cache/
+ ~/.cargo/git/db/
+ target/
+ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
+ restore-keys: ${{ runner.os }}-cargo-
+ - name: setup msbuild
+ uses: microsoft/setup-msbuild@v1.1.3
+ - name: msbuild
+ run: |
+ msbuild windows\ZeroTierOne.sln /m /p:Configuration=Release /property:Platform=x64 /t:ZeroTierOne:Rebuild
+
diff --git a/.gitignore b/.gitignore
index 198a7f669..79a9e247c 100755
--- a/.gitignore
+++ b/.gitignore
@@ -136,4 +136,5 @@ zeroidc/target/
__pycache__
*.pyc
*_source.tar.bz2
-snap/.snapcraft
\ No newline at end of file
+snap/.snapcraft
+tcp-proxy/tcp-proxy
diff --git a/Dockerfile.release b/Dockerfile.release
index a676226a3..87ef65348 100644
--- a/Dockerfile.release
+++ b/Dockerfile.release
@@ -1,22 +1,17 @@
# vim: ft=dockerfile
-FROM debian:buster as stage
+FROM debian:bullseye
-ARG PACKAGE_BASEURL=https://download.zerotier.com/debian/buster/pool/main/z/zerotier-one/
-ARG ARCH=amd64
ARG VERSION
-RUN apt-get update -qq && apt-get install curl -y
-RUN curl -sSL -o zerotier-one.deb "${PACKAGE_BASEURL}/zerotier-one_${VERSION}_${ARCH}.deb"
+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/bullseye bullseye main" > /etc/apt/sources.list.d/zerotier.list
-FROM debian:buster
-
-RUN apt-get update -qq && apt-get install openssl libssl1.1 -y
-
-COPY --from=stage zerotier-one.deb .
-
-RUN dpkg -i zerotier-one.deb && rm -f zerotier-one.deb
-RUN echo "${VERSION}" >/etc/zerotier-version
+RUN apt-get update -qq && apt-get install zerotier-one=${VERSION} curl iproute2 net-tools iputils-ping openssl libssl1.1 -y
RUN rm -rf /var/lib/zerotier-one
COPY entrypoint.sh.release /entrypoint.sh
diff --git a/Jenkinsfile b/Jenkinsfile
deleted file mode 100644
index 757729e33..000000000
--- a/Jenkinsfile
+++ /dev/null
@@ -1,365 +0,0 @@
-pipeline {
- options {
- disableConcurrentBuilds()
- preserveStashes(buildCount: 10)
- timestamps()
- }
- parameters {
- booleanParam(name: "BUILD_ALL", defaultValue: false, description: "Build all supported platform/architecture combos. Defaults to x86/x64 only")
- }
-
- agent none
-
- stages {
- stage ("Build") {
- steps {
- script {
- def tasks = [:]
- tasks << buildStaticBinaries()
- tasks << buildDebianNative()
- tasks << buildCentosNative()
-
- parallel tasks
- }
- }
- }
- stage ("Package Static") {
- steps {
- script {
- parallel packageStatic()
- }
- }
- }
- }
-}
-
-def buildStaticBinaries() {
- def tasks = [:]
- def dist = ["alpine"]
- def archs = []
- if (params.BUILD_ALL == true) {
- archs = ["arm64", "amd64", "i386", "armhf", "armel", "ppc64le", "s390x"]
- } else {
- archs = ["amd64", "i386"]
- }
-
- tasks << getTasks(dist, archs, { distro, platform ->
- def myNode = {
- node ('linux-build') {
- dir ("build") {
- checkout scm
- }
- sh "echo ${distro}-${platform}"
- def runtime = docker.image("ztbuild/${distro}-${platform}:latest")
- runtime.inside {
- dir("build") {
- sh 'make -j8 ZT_STATIC=1 all'
- sh "file ./zerotier-one"
- sh "mv zerotier-one zerotier-one-static-${platform}"
- stash includes: 'zerotier-one-static-*', name: "static-${platform}"
- }
- cleanWs deleteDirs: true, disableDeferredWipeout: true, notFailBuild: true
- }
- }
- }
- return myNode
- })
-
- return tasks
-}
-
-def getTasks(axisDistro, axisPlatform, task) {
- def tasks = [:]
- for(int i=0; i< axisDistro.size(); i++) {
- def axisDistroValue = axisDistro[i]
- for(int j=0; j< axisPlatform.size(); j++) {
- def axisPlatformValue = axisPlatform[j]
- tasks["${axisDistroValue}/${axisPlatformValue}"] = task(axisDistroValue, axisPlatformValue)
- }
- }
- return tasks
-}
-
-def packageStatic() {
- def tasks = [:]
-
- def centos6 = ["centos6"]
- def centos6Arch = ["i386", "amd64"]
- tasks << getTasks(centos6, centos6Arch, { distro, arch ->
- def myNode = {
- node ('linux-build') {
- dir ("build") {
- checkout scm
- }
- def runtime = docker.image("ztbuild/${distro}-${arch}:latest")
- runtime.inside {
- dir("build") {
- unstash "static-${arch}"
- sh "mv zerotier-one-static-${arch} zerotier-one && chmod +x zerotier-one"
- sh "make redhat"
- sh "mkdir -p ${distro}"
- sh "cp -av `find ~/rpmbuild/ -type f -name \"*.rpm\"` ${distro}/"
- archiveArtifacts artifacts: "${distro}/*.rpm", onlyIfSuccessful: true
- }
- }
- cleanWs deleteDirs: true, disableDeferredWipeout: true, notFailBuild: true
- }
- }
- return myNode
- })
-
- def centos7 = ["centos7"]
- def centos7Arch = ["i386"]
- tasks << getTasks(centos7, centos7Arch, { distro, arch ->
- def myNode = {
- node ('linux-build') {
- dir ("build") {
- checkout scm
- }
- def runtime = docker.image("ztbuild/${distro}-${arch}:latest")
- runtime.inside {
- dir("build") {
- unstash "static-${arch}"
- sh "mv zerotier-one-static-${arch} zerotier-one && chmod +x zerotier-one"
- sh "make redhat"
- sh "mkdir -p ${distro}"
- sh "cp -av `find ~/rpmbuild/ -type f -name \"*.rpm\"` ${distro}/"
- archiveArtifacts artifacts: "${distro}/*.rpm", onlyIfSuccessful: true
- }
- }
- cleanWs deleteDirs: true, disableDeferredWipeout: true, notFailBuild: true
- }
- }
- return myNode
- })
-
- if (params.BUILD_ALL == true) {
- def clefos7 = ["clefos"]
- def clefos7Arch = ["s390x"]
- tasks << getTasks(clefos7, clefos7Arch, { distro, arch ->
- def myNode = {
- node ('linux-build') {
- dir ("build") {
- checkout scm
- }
- def runtime = docker.image("ztbuild/${distro}-${arch}:latest")
- runtime.inside {
- dir("build/") {
- unstash "static-${arch}"
- sh "mv zerotier-one-static-${arch} zerotier-one && chmod +x zerotier-one"
- sh "make redhat"
- sh "mkdir -p ${distro}"
- sh "cp -av `find ~/rpmbuild/ -type f -name \"*.rpm\"` ${distro}/"
- archiveArtifacts artifacts: "${distro}/*.rpm", onlyIfSuccessful: true
- }
- }
- cleanWs deleteDirs: true, disableDeferredWipeout: true, notFailBuild: true
- }
- }
- return myNode
- })
- }
-
- def debianJessie = ["debian-jessie"]
- def debianJessieArchs = []
- if (params.BUILD_ALL == true) {
- debianJessieArch = ["armhf", "armel", "amd64", "i386"]
- } else {
- debianJessieArch = ["amd64", "i386"]
- }
- tasks << getTasks(debianJessie, debianJessieArch, { distro, arch ->
- def myNode = {
- node ('linux-build') {
- dir ("build") {
- checkout scm
- }
- def runtime = docker.image("ztbuild/${distro}-${arch}:latest")
- runtime.inside {
- sh "ls -la ."
- dir('build/') {
- sh "ls -la ."
- unstash "static-${arch}"
- sh "pwd"
- sh "mv zerotier-one-static-${arch} zerotier-one && chmod +x zerotier-one && file ./zerotier-one"
- sh "mv -f debian/rules.static debian/rules"
- sh "make debian"
- }
- sh "mkdir -p ${distro}"
- sh "mv *.deb ${distro}"
- archiveArtifacts artifacts: "${distro}/*.deb", onlyIfSuccessful: true
- }
- cleanWs deleteDirs: true, disableDeferredWipeout: true, notFailBuild: true
- }
- }
- return myNode
- })
-
- def ubuntuTrusty = ["ubuntu-trusty"]
- def ubuntuTrustyArch = []
- if (params.BUILD_ALL == true) {
- ubuntuTrustyArch = ["i386", "amd64", "armhf", "arm64", "ppc64le"]
- } else {
- ubuntuTrustyArch = ["i386", "amd64"]
- }
- tasks << getTasks(ubuntuTrusty, ubuntuTrustyArch, { distro, arch ->
- def myNode = {
- node ('linux-build') {
- dir ("build") {
- checkout scm
- }
- def runtime = docker.image("ztbuild/${distro}-${arch}:latest")
- runtime.inside {
- sh "ls -la ."
- dir('build/') {
- sh "ls -la ."
- unstash "static-${arch}"
- sh "pwd"
- sh "mv zerotier-one-static-${arch} zerotier-one && chmod +x zerotier-one && file ./zerotier-one"
- sh "mv -f debian/rules.static debian/rules"
- sh "make debian"
- }
- sh "mkdir -p ${distro}"
- sh "mv *.deb ${distro}"
- archiveArtifacts artifacts: "${distro}/*.deb", onlyIfSuccessful: true
- }
- cleanWs deleteDirs: true, disableDeferredWipeout: true, notFailBuild: true
- }
- }
- return myNode
- })
-
- def debianWheezy = ["debian-wheezy"]
- def debianWheezyArchs = []
- if (params.BUILD_ALL == true) {
- debianWheezyArchs = ["armhf", "armel", "amd64", "i386"]
- } else {
- debianWheezyArchs = ["amd64", "i386"]
- }
- tasks << getTasks(debianJessie, debianJessieArch, { distro, arch ->
- def myNode = {
- node ('linux-build') {
- dir ("build") {
- checkout scm
- }
- def runtime = docker.image("ztbuild/${distro}-${arch}:latest")
- runtime.inside {
- dir('build/') {
- unstash "static-${arch}"
- sh "mv zerotier-one-static-${arch} zerotier-one && chmod +x zerotier-one && file ./zerotier-one"
- sh "mv -f debian/rules.wheezy.static debian/rules"
- sh "mv -f debian/control.wheezy debian/control"
- sh "make debian"
- }
- sh "mkdir -p ${distro}"
- sh "mv *.deb ${distro}"
- archiveArtifacts artifacts: "${distro}/*.deb", onlyIfSuccessful: true
- }
- cleanWs deleteDirs: true, disableDeferredWipeout: true, notFailBuild: true
- }
- }
- return myNode
- })
-
- return tasks
-}
-
-def buildDebianNative() {
- def tasks = [:]
- def buster = ["debian-buster", "debian-stretch", "debian-bullseye", "debian-sid"]
- def busterArchs = []
- if (params.BUILD_ALL) {
- busterArchs = ["s390x", "ppc64le", "i386", "armhf", "armel", "arm64", "amd64"]
- } else {
- busterArchs = ["amd64", "i386"]
- }
-
- def build = { distro, arch ->
- def myNode = {
- node ('linux-build') {
- dir ("build") {
- checkout scm
- }
- def runtime = docker.image("ztbuild/${distro}-${arch}:latest")
- runtime.inside {
- dir("build") {
- sh 'make debian'
- }
- sh "mkdir -p ${distro}"
- sh "mv *.deb ${distro}"
- archiveArtifacts artifacts: "${distro}/*.deb", onlyIfSuccessful: true
- cleanWs deleteDirs: true, disableDeferredWipeout: true, notFailBuild: true
- }
- }
- }
- return myNode
- }
-
- tasks << getTasks(buster, busterArchs, build)
-
- // bash is broken when running under QEMU-s390x on Xenial
- def xenial = ["ubuntu-xenial"]
- def xenialArchs = []
- if (params.BUILD_ALL == true) {
- xenialArchs = ["i386", "amd64", "armhf", "arm64", "ppc64le"]
- } else {
- xenialArchs = ["i386", "amd64"]
- }
- tasks << getTasks(xenial, xenialArchs, build)
-
- def ubuntu = ["ubuntu-bionic", "ubuntu-eoan"]
- def ubuntuArchs = []
- if (params.BUILD_ALL == true) {
- ubuntuArchs = ["i386", "amd64", "armhf", "arm64", "ppc64le", "s390x"]
- } else {
- ubuntuArchs = ["i386", "amd64"]
- }
- tasks << getTasks(ubuntu, ubuntuArchs, build)
-
- def kali = ["kali-rolling"]
- def kaliArchs = ["amd64"]
- tasks << getTasks(kali, kaliArchs, build)
-
- return tasks
-}
-
-def buildCentosNative() {
- def tasks = [:]
-
- def build = { distro, arch ->
- def myNode = {
- node ('linux-build') {
- dir ("build") {
- checkout scm
- }
- def runtime = docker.image("ztbuild/${distro}-${arch}:latest")
- runtime.inside {
- dir("build") {
- sh 'make -j4'
- sh 'make redhat'
- sh "mkdir -p ${distro}"
- sh "cp -av `find ~/rpmbuild/ -type f -name \"*.rpm\"` ${distro}/"
- archiveArtifacts artifacts: "${distro}/*.rpm", onlyIfSuccessful: true
- }
-
- cleanWs deleteDirs: true, disableDeferredWipeout: true, notFailBuild: true
- }
- }
- }
- return myNode
- }
-
- def centos8 = ["centos8"]
- def centos8Archs = []
- if (params.BUILD_ALL == true) {
- centos8Archs = ["amd64", "arm64", "ppc64le"]
- } else {
- centos8Archs = ["amd64"]
- }
- tasks << getTasks(centos8, centos8Archs, build)
-
- def centos7 = ["centos7"]
- def centos7Archs = ["amd64"]
- tasks << getTasks(centos7, centos7Archs, build)
-
- return tasks
-}
diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md
index 5fc0de669..a925a3a04 100644
--- a/RELEASE-NOTES.md
+++ b/RELEASE-NOTES.md
@@ -1,6 +1,17 @@
ZeroTier Release Notes
======
+# 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.
@@ -21,7 +32,7 @@ ZeroTier Release Notes
# 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 spordaic reports of link failures under some conditions.
+ * 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.
* Fized 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).
diff --git a/ci/Dockerfile.deb b/ci/Dockerfile.deb
index 91b383a6a..151bca397 100644
--- a/ci/Dockerfile.deb
+++ b/ci/Dockerfile.deb
@@ -1,5 +1,5 @@
ARG PLATFORM
-FROM registry.sean.farm/${PLATFORM}-builder as stage
+FROM 084037375216.dkr.ecr.us-east-2.amazonaws.com/${PLATFORM}-builder as stage
WORKDIR /work/build
COPY . .
RUN make debian
diff --git a/ci/Dockerfile.none b/ci/Dockerfile.none
new file mode 100644
index 000000000..bee0128f7
--- /dev/null
+++ b/ci/Dockerfile.none
@@ -0,0 +1,5 @@
+ARG PLATFORM
+FROM 084037375216.dkr.ecr.us-east-2.amazonaws.com/${PLATFORM}-builder as stage
+WORKDIR /work
+COPY . .
+RUN make
diff --git a/ci/Dockerfile.rpm b/ci/Dockerfile.rpm
index 9969be05e..0965148bc 100644
--- a/ci/Dockerfile.rpm
+++ b/ci/Dockerfile.rpm
@@ -1,5 +1,5 @@
ARG PLATFORM
-FROM registry.sean.farm/${PLATFORM}-builder as stage
+FROM 084037375216.dkr.ecr.us-east-2.amazonaws.com/${PLATFORM}-builder as stage
WORKDIR /root/rpmbuild/BUILD
COPY . .
RUN make redhat
diff --git a/ci/scripts/build.sh b/ci/scripts/build.sh
index e6aee6bc6..bc28e42f2 100755
--- a/ci/scripts/build.sh
+++ b/ci/scripts/build.sh
@@ -8,6 +8,9 @@ export VERSION=$3
export EVENT=$4
case $PLATFORM in
+ sid)
+ export PKGFMT=none
+ ;;
el*|fc*|amzn*)
export PKGFMT=rpm
;;
@@ -15,22 +18,21 @@ case $PLATFORM in
export PKGFMT=deb
esac
-# OSX
-# x86_64-apple-darwin
-# aarch64-apple-darwin
+#
+# Allow user to drop in custom Dockerfile for PLATFORM
+#
-# Windows
-# x86_64-pc-windows-msvc
-# i686-pc-windows-msvc
-# aarch64-pc-windows-msvc
+if [ -f "ci/Dockerfile.${PLATFORM}" ]; then
+ export DOCKERFILE="ci/Dockerfile.${PLATFORM}"
+else
+ export DOCKERFILE="ci/Dockerfile.${PKGFMT}"
+fi
-# Linux
-# i686-unknown-linux-gnu
-# x86_64-unknown-linux-gnu
-# arm-unknown-linux-gnueabi ?
-# arm-unknown-linux-gnueabihf ?
-# armv7-unknown-linux-gnueabihf
-#
+#
+# Rust sometimes gets confused about where it's running.
+# Normally, the build images will have Rust pre-baked.
+# Pass RUST_TRIPLET for convenience when using a custom Dockerfile
+#
case $ZT_ISA in
386)
@@ -41,13 +43,9 @@ case $ZT_ISA in
export DOCKER_ARCH=amd64
export RUST_TRIPLET=x86_64-unknown-linux-gnu
;;
- armv6)
- export DOCKER_ARCH=arm/v6
- export RUST_TRIPLET=arm-unknown-linux-gnueabi
- ;;
- armv7)
+ armv7)
export DOCKER_ARCH=arm/v7
- export RUST_TRIPLET=arm-unknown-linux-gnueabihf
+ export RUST_TRIPLET=armv7-unknown-linux-gnueabihf
;;
arm64)
export DOCKER_ARCH=arm64/v8
@@ -60,7 +58,7 @@ case $ZT_ISA in
ppc64le)
export DOCKER_ARCH=ppc64le
export RUST_TRIPLET=powerpc64le-unknown-linux-gnu
- ;;
+ ;;
mips64le)
export DOCKER_ARCH=mips64le
export RUST_TRIPLET=mips64el-unknown-linux-gnuabi64
@@ -69,17 +67,15 @@ case $ZT_ISA in
export DOCKER_ARCH=s390x
export RUST_TRIPLET=s390x-unknown-linux-gnu
;;
- *)
+ *)
echo "ERROR: could not determine architecture settings. PLEASE FIX ME"
exit 1
;;
esac
-if [ -f "ci/Dockerfile.${PLATFORM}" ]; then
- export DOCKERFILE="ci/Dockerfile.${PLATFORM}"
-else
- export DOCKERFILE="ci/Dockerfile.${PKGFMT}"
-fi
+#
+# Print debug info
+#
echo "#~~~~~~~~~~~~~~~~~~~~"
echo "$0 variables:"
@@ -94,23 +90,37 @@ echo "PWD: ${PWD}"
echo "DOCKERFILE: ${DOCKERFILE}"
echo "#~~~~~~~~~~~~~~~~~~~~"
-if [ ${EVENT} == "push" ]; then
-make munge_rpm zerotier-one.spec VERSION=${VERSION}
-make munge_deb debian/changelog VERSION=${VERSION}
+#
+# Munge RPM and Deb
+#
+
+if [ ${PKGFMT} != "none" ] && [ ${EVENT} != "tag" ]; then
+ make munge_rpm zerotier-one.spec VERSION=${VERSION}
+ make munge_deb debian/changelog VERSION=${VERSION}
fi
-export DOCKER_BUILDKIT=1
-docker run --privileged --rm tonistiigi/binfmt --install all
+#
+# Assemble buildx arguments
+#
-# docker pull --platform linux/${DOCKER_ARCH} registry.sean.farm/${PLATFORM}-builder
+build_args=(
+ --no-cache
+ --build-arg PLATFORM=${PLATFORM}
+ --build-arg RUST_TRIPLET=${RUST_TRIPLET}
+ --build-arg DOCKER_ARCH=${DOCKER_ARCH}
+ --platform linux/${DOCKER_ARCH}
+ -f ${DOCKERFILE}
+ -t build
+ .
+)
-docker buildx build \
- --build-arg PLATFORM="${PLATFORM}" \
- --build-arg RUST_TRIPLET="${RUST_TRIPLET}" \
- --build-arg DOCKER_ARCH="${DOCKER_ARCH}" \
- --platform linux/${DOCKER_ARCH} \
- -f ${DOCKERFILE} \
- -t build \
- . \
- --output type=local,dest=. \
- --target export
+if [ ${PKGFMT} != "none" ]; then
+ build_args+=("--output type=local,dest=.")
+ build_args+=("--target export")
+fi
+
+#
+# Do build
+#
+
+docker buildx build ${build_args[@]}
diff --git a/controller/PostgreSQL.cpp b/controller/PostgreSQL.cpp
index cf154ecf2..ef1ba0ff9 100644
--- a/controller/PostgreSQL.cpp
+++ b/controller/PostgreSQL.cpp
@@ -113,7 +113,7 @@ MemberNotificationReceiver::MemberNotificationReceiver(PostgreSQL *p, pqxx::conn
: pqxx::notification_receiver(c, channel)
, _psql(p)
{
- fprintf(stderr, "initialize MemberNotificaitonReceiver\n");
+ fprintf(stderr, "initialize MemberNotificationReceiver\n");
}
@@ -140,7 +140,7 @@ NetworkNotificationReceiver::NetworkNotificationReceiver(PostgreSQL *p, pqxx::co
}
void NetworkNotificationReceiver::operator() (const std::string &payload, int packend_pid) {
- fprintf(stderr, "Network Notificaiton received: %s\n", payload.c_str());
+ fprintf(stderr, "Network Notification received: %s\n", payload.c_str());
json tmp(json::parse(payload));
json &ov = tmp["old_val"];
json &nv = tmp["new_val"];
@@ -185,7 +185,7 @@ PostgreSQL::PostgreSQL(const Identity &myId, const char *path, int listenPort, R
fprintf(stderr, "ZT_SSO_PSK: %s\n", ssoPskHex);
#endif
if (ssoPskHex) {
- // SECURITY: note that ssoPskHex will always be null-terminated if libc acatually
+ // SECURITY: note that ssoPskHex will always be null-terminated if libc actually
// returns something non-NULL. If the hex encodes something shorter than 48 bytes,
// it will be padded at the end with zeroes. If longer, it'll be truncated.
Utils::unhex(ssoPskHex, _ssoPsk, sizeof(_ssoPsk));
@@ -217,10 +217,11 @@ PostgreSQL::PostgreSQL(const Identity &myId, const char *path, int listenPort, R
opts.password = _rc->password;
opts.db = 0;
opts.keep_alive = true;
- opts.connect_timeout = std::chrono::seconds(5);
+ opts.connect_timeout = std::chrono::seconds(3);
poolOpts.size = 25;
- poolOpts.wait_timeout = std::chrono::milliseconds(1000);
- poolOpts.connection_lifetime = std::chrono::minutes(5);
+ poolOpts.wait_timeout = std::chrono::seconds(5);
+ poolOpts.connection_lifetime = std::chrono::minutes(3);
+ poolOpts.connection_idle_time = std::chrono::minutes(1);
if (_rc->clusterMode) {
fprintf(stderr, "Using Redis in Cluster Mode\n");
_cluster = std::make_shared(opts, poolOpts);
@@ -709,11 +710,11 @@ void PostgreSQL::initializeNetworks()
if (_redisMemberStatus) {
fprintf(stderr, "adding networks to redis...\n");
if (_rc->clusterMode) {
- auto tx = _cluster->transaction(_myAddressStr, true);
+ auto tx = _cluster->transaction(_myAddressStr, true, false);
tx.sadd(setKey, networkSet.begin(), networkSet.end());
tx.exec();
} else {
- auto tx = _redis->transaction(true);
+ auto tx = _redis->transaction(true, false);
tx.sadd(setKey, networkSet.begin(), networkSet.end());
tx.exec();
}
@@ -765,13 +766,13 @@ void PostgreSQL::initializeMembers()
if (!deletes.empty()) {
try {
if (_rc->clusterMode) {
- auto tx = _cluster->transaction(_myAddressStr, true);
+ auto tx = _cluster->transaction(_myAddressStr, true, false);
for (std::string k : deletes) {
tx.del(k);
}
tx.exec();
} else {
- auto tx = _redis->transaction(true);
+ auto tx = _redis->transaction(true, false);
for (std::string k : deletes) {
tx.del(k);
}
@@ -784,22 +785,29 @@ void PostgreSQL::initializeMembers()
}
char qbuf[2048];
- sprintf(qbuf, "SELECT m.id, m.network_id, m.active_bridge, m.authorized, m.capabilities, (EXTRACT(EPOCH FROM m.creation_time AT TIME ZONE 'UTC')*1000)::bigint, m.identity, "
- " (EXTRACT(EPOCH FROM m.last_authorized_time AT TIME ZONE 'UTC')*1000)::bigint, "
- " (EXTRACT(EPOCH FROM m.last_deauthorized_time AT TIME ZONE 'UTC')*1000)::bigint, "
- " m.remote_trace_level, m.remote_trace_target, m.tags, m.v_major, m.v_minor, m.v_rev, m.v_proto, "
- " m.no_auto_assign_ips, m.revision, sso_exempt, "
- " (SELECT (EXTRACT(EPOCH FROM e.authentication_expiry_time)*1000)::bigint "
- " FROM ztc_sso_expiry e "
- " INNER JOIN ztc_network n1 "
- " ON n.id = e.network_id "
- " WHERE e.network_id = m.network_id AND e.member_id = m.id AND n.sso_enabled = TRUE AND e.authentication_expiry_time IS NOT NULL "
- " ORDER BY e.authentication_expiry_time DESC LIMIT 1) AS authentication_expiry_time, "
- " ARRAY(SELECT DISTINCT address FROM ztc_member_ip_assignment WHERE member_id = m.id AND network_id = m.network_id) AS assigned_addresses "
+ sprintf(qbuf,
+ "SELECT m.id, m.network_id, m.active_bridge, m.authorized, m.capabilities, "
+ "(EXTRACT(EPOCH FROM m.creation_time AT TIME ZONE 'UTC')*1000)::bigint, m.identity, "
+ "(EXTRACT(EPOCH FROM m.last_authorized_time AT TIME ZONE 'UTC')*1000)::bigint, "
+ "(EXTRACT(EPOCH FROM m.last_deauthorized_time AT TIME ZONE 'UTC')*1000)::bigint, "
+ "m.remote_trace_level, m.remote_trace_target, m.tags, m.v_major, m.v_minor, m.v_rev, m.v_proto, "
+ "m.no_auto_assign_ips, m.revision, m.sso_exempt, "
+ "(CASE WHEN n.sso_enabled = TRUE AND m.sso_exempt = FALSE THEN "
+ " ( "
+ " SELECT (EXTRACT(EPOCH FROM e.authentication_expiry_time)*1000)::bigint "
+ " FROM ztc_sso_expiry e "
+ " INNER JOIN ztc_network n1 "
+ " ON n1.id = e.network_id AND n1.deleted = TRUE "
+ " WHERE e.network_id = m.network_id AND e.member_id = m.id AND n.sso_enabled = TRUE AND e.authentication_expiry_time IS NOT NULL "
+ " ORDER BY e.authentication_expiry_time DESC LIMIT 1 "
+ " ) "
+ " ELSE NULL "
+ " END) AS authentication_expiry_time, "
+ "ARRAY(SELECT DISTINCT address FROM ztc_member_ip_assignment WHERE member_id = m.id AND network_id = m.network_id) AS assigned_addresses "
"FROM ztc_member m "
"INNER JOIN ztc_network n "
" ON n.id = m.network_id "
- "WHERE n.controller_id = '%s' AND m.deleted = false", _myAddressStr.c_str());
+ "WHERE n.controller_id = '%s' AND n.deleted = FALSE AND m.deleted = FALSE", _myAddressStr.c_str());
auto c = _pool->borrow();
auto c2 = _pool->borrow();
pqxx::work w{*c->c};
@@ -925,13 +933,13 @@ void PostgreSQL::initializeMembers()
if (_redisMemberStatus) {
fprintf(stderr, "Load member data into redis...\n");
if (_rc->clusterMode) {
- auto tx = _cluster->transaction(_myAddressStr, true);
+ auto tx = _cluster->transaction(_myAddressStr, true, false);
for (auto it : networkMembers) {
tx.sadd(it.first, it.second);
}
tx.exec();
} else {
- auto tx = _redis->transaction(true);
+ auto tx = _redis->transaction(true, false);
for (auto it : networkMembers) {
tx.sadd(it.first, it.second);
}
@@ -951,6 +959,7 @@ void PostgreSQL::initializeMembers()
}
} catch (sw::redis::Error &e) {
fprintf(stderr, "ERROR: Error initializing members (redis): %s\n", e.what());
+ exit(-1);
} catch (std::exception &e) {
fprintf(stderr, "ERROR: Error initializing member: %s-%s %s\n", networkId.c_str(), memberId.c_str(), e.what());
exit(-1);
@@ -1012,12 +1021,16 @@ void PostgreSQL::heartbeat()
}
_pool->unborrow(c);
- if (_redisMemberStatus) {
- if (_rc->clusterMode) {
- _cluster->zadd("controllers", "controllerId", ts);
- } else {
- _redis->zadd("controllers", "controllerId", ts);
+ try {
+ if (_redisMemberStatus) {
+ if (_rc->clusterMode) {
+ _cluster->zadd("controllers", "controllerId", ts);
+ } else {
+ _redis->zadd("controllers", "controllerId", ts);
+ }
}
+ } catch (sw::redis::Error &e) {
+ fprintf(stderr, "ERROR: Redis error in heartbeat thread: %s\n", e.what());
}
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
@@ -1374,7 +1387,7 @@ void PostgreSQL::commitThread()
"sso_enabled = EXCLUDED.sso_enabled",
id,
_myAddressStr,
- OSUtils::jsonDump(config["capabilitles"], -1),
+ OSUtils::jsonDump(config["capabilities"], -1),
(bool)config["enableBroadcast"],
OSUtils::now(),
(int)config["mtu"],
@@ -1573,7 +1586,7 @@ void PostgreSQL::onlineNotificationThread()
/**
* ONLY UNCOMMENT FOR TEMPORARY DB MAINTENANCE
*
- * This define temproarly turns off writing to the member status table
+ * This define temporarily turns off writing to the member status table
* so it can be reindexed when the indexes get too large.
*/
@@ -1694,10 +1707,10 @@ void PostgreSQL::onlineNotification_Redis()
try {
if (!lastOnline.empty()) {
if (_rc->clusterMode) {
- auto tx = _cluster->transaction(controllerId, true);
+ auto tx = _cluster->transaction(controllerId, true, false);
count = _doRedisUpdate(tx, controllerId, lastOnline);
} else {
- auto tx = _redis->transaction(true);
+ auto tx = _redis->transaction(true, false);
count = _doRedisUpdate(tx, controllerId, lastOnline);
}
}
diff --git a/controller/README.md b/controller/README.md
index 0a76ebbc7..331710a15 100644
--- a/controller/README.md
+++ b/controller/README.md
@@ -246,7 +246,7 @@ This returns a JSON object containing all member IDs as keys and their `memberRe
| 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 |
+| vProto | integer | Most recently known protocol version | no |
Note that managed IP assignments are only used if they fall within a managed route. Otherwise they are ignored.
diff --git a/debian/changelog b/debian/changelog
index 19e9929d9..dcc312250 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+zerotier-one (1.10.2) unstable; urgency=medium
+
+ * See RELEASE-NOTES.md for release notes.
+
+ -- Adam Ierymenko Thu, 13 Oct 2022 01:00:00 -0700
+
zerotier-one (1.10.1) unstable; urgency=medium
* See RELEASE-NOTES.md for release notes.
diff --git a/doc/zerotier-one.8.md b/doc/zerotier-one.8.md
index bd31d5c80..4f4655076 100644
--- a/doc/zerotier-one.8.md
+++ b/doc/zerotier-one.8.md
@@ -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.
* `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 initations 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 initiations since it will require that we go out and re-fetch full identities for peers we're speaking to.
* `networks.d` (directory):
This caches network configurations and certificate information for networks you belong to. ZeroTier scans this directory for .conf files on startup to recall its networks, so "touch"ing an empty .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.
diff --git a/dockerbuild/Dockerfile.alpine b/dockerbuild/Dockerfile.alpine
deleted file mode 100644
index 04c298d15..000000000
--- a/dockerbuild/Dockerfile.alpine
+++ /dev/null
@@ -1,23 +0,0 @@
-FROM alpine:3.15
-
-ARG go_pkg_url
-
-RUN apk add --update alpine-sdk linux-headers cmake openssh curl
-
-
-RUN adduser -D -s /bin/ash jenkins && \
- passwd -u jenkins && \
- ssh-keygen -A && \
- mkdir /home/jenkins/.ssh && \
- chown -R jenkins:jenkins /home/jenkins
-
-RUN curl -s $go_pkg_url -o go.tar.gz && \
- tar -C /usr/local -xzf go.tar.gz
-
-COPY authorized_keys /home/jenkins/.ssh/authorized_keys
-RUN chown -R jenkins:jenkins /home/jenkins/.ssh && \
- chmod 600 /home/jenkins/.ssh/authorized_keys
-
-EXPOSE 22
-CMD ["/usr/sbin/sshd", "-D"]
-
diff --git a/dockerbuild/Dockerfile.centos6 b/dockerbuild/Dockerfile.centos6
deleted file mode 100644
index 6b8f023ed..000000000
--- a/dockerbuild/Dockerfile.centos6
+++ /dev/null
@@ -1,20 +0,0 @@
-FROM centos:6
-
-ARG go_pkg_url
-
-RUN yum update -y
-RUN yum install -y curl git wget openssh-server sudo make rpmdevtools && yum clean all
-
-RUN curl -s $go_pkg_url -o go.tar.gz && \
- tar -C /usr/local -xzf go.tar.gz && \
- rm go.tar.gz
-
-RUN groupadd -g 1000 jenkins-build && useradd -u 1000 -g 1000 jenkins-build
-
-RUN echo $'\n\
- export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin\n'\
- >> ~/.bash_profile
-
-RUN mkdir /rpmbuild && chmod 777 /rpmbuild
-
-CMD ["/usr/sbin/sshd", "-D"]
diff --git a/dockerbuild/Dockerfile.centos6-i386 b/dockerbuild/Dockerfile.centos6-i386
deleted file mode 100644
index c6a47072b..000000000
--- a/dockerbuild/Dockerfile.centos6-i386
+++ /dev/null
@@ -1,21 +0,0 @@
-FROM i386/centos:6
-
-ARG go_pkg_url
-
-RUN echo i386 > /etc/yum/vars/basearch && echo i686 > /etc/yum/vars/arch
-
-RUN yum install -y curl git wget openssh-server sudo make rpmdevtools && yum clean all
-
-RUN curl -s $go_pkg_url -o go.tar.gz && \
- tar -C /usr/local -xzf go.tar.gz && \
- rm go.tar.gz
-
-RUN groupadd -g 1000 jenkins-build && useradd -u 1000 -g 1000 jenkins-build
-
-RUN echo $'\n\
- export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin\n'\
- >> ~/.bash_profile
-
-RUN mkdir /rpmbuild && chmod 777 /rpmbuild
-
-CMD ["/usr/sbin/sshd", "-D"]
diff --git a/dockerbuild/Dockerfile.centos7 b/dockerbuild/Dockerfile.centos7
deleted file mode 100644
index 751d02c0c..000000000
--- a/dockerbuild/Dockerfile.centos7
+++ /dev/null
@@ -1,25 +0,0 @@
-FROM centos:7
-
-ARG go_pkg_url
-
-RUN yum install -y epel-release
-RUN yum install -y curl git wget openssh-server sudo make development-tools rpmdevtools clang gcc-c++ ruby ruby-devel centos-release-scl devtoolset-8 llvm-toolset-7 && yum clean all
-
-RUN curl -s $go_pkg_url -o go.tar.gz && \
- tar -C /usr/local -xzf go.tar.gz && \
- rm go.tar.gz
-
-RUN wget -qO- "https://cmake.org/files/v3.15/cmake-3.15.1-Linux-x86_64.tar.gz" | tar --strip-components=1 -xz -C /usr/local
-
-RUN /usr/bin/ssh-keygen -A
-RUN useradd jenkins-build
-
-RUN echo $'\n\
- export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin\n\
- source scl_source enable devtoolset-8 llvm-toolset-7\n'\
- >> ~/.bash_profile
-
-RUN mkdir /rpmbuild && chmod 777 /rpmbuild
-
-CMD ["/usr/sbin/sshd", "-D"]
-
diff --git a/dockerbuild/Dockerfile.centos7-i386 b/dockerbuild/Dockerfile.centos7-i386
deleted file mode 100644
index f7ee9a0c4..000000000
--- a/dockerbuild/Dockerfile.centos7-i386
+++ /dev/null
@@ -1,22 +0,0 @@
-FROM centos:7
-
-ARG go_pkg_url
-
-RUN yum install -y curl git wget openssh-server sudo make development-tools rpmdevtools clang gcc-c++ ruby ruby-devel && yum clean all
-
-RUN curl -s $go_pkg_url -o go.tar.gz && \
- tar -C /usr/local -xzf go.tar.gz && \
- rm go.tar.gz
-
-RUN /usr/bin/ssh-keygen -A
-
-RUN useradd jenkins-build
-
-RUN echo $'\n\
- export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin\n'\
- >> ~/.bash_profile
-
-RUN mkdir /rpmbuild && chmod 777 /rpmbuild
-
-CMD ["/usr/sbin/sshd", "-D"]
-
diff --git a/dockerbuild/Dockerfile.centos8 b/dockerbuild/Dockerfile.centos8
deleted file mode 100644
index 106ab5b44..000000000
--- a/dockerbuild/Dockerfile.centos8
+++ /dev/null
@@ -1,25 +0,0 @@
-FROM centos:8
-
-ARG go_pkg_url
-
-RUN yum install -y epel-release
-RUN yum install -y curl git wget openssh-server sudo make rpmdevtools clang gcc-c++ ruby ruby-devel && yum clean all
-
-RUN curl -s $go_pkg_url -o go.tar.gz && \
- tar -C /usr/local -xzf go.tar.gz && \
- rm go.tar.gz
-
-RUN wget -qO- "https://cmake.org/files/v3.15/cmake-3.15.1-Linux-x86_64.tar.gz" | tar --strip-components=1 -xz -C /usr/local
-
-RUN /usr/bin/ssh-keygen -A
-RUN useradd jenkins-build
-
-RUN echo $'\n\
- export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin\n\
- source scl_source enable devtoolset-8 llvm-toolset-7\n'\
- >> ~/.bash_profile
-
-RUN mkdir /rpmbuild && chmod 777 /rpmbuild
-
-CMD ["/usr/sbin/sshd", "-D"]
-
diff --git a/dockerbuild/Dockerfile.clefos-s390x b/dockerbuild/Dockerfile.clefos-s390x
deleted file mode 100644
index 135f70abc..000000000
--- a/dockerbuild/Dockerfile.clefos-s390x
+++ /dev/null
@@ -1,20 +0,0 @@
-FROM s390x/clefos:7
-
-ARG go_pkg_url
-
-RUN yum install -y curl git wget openssh-server sudo make development-tools rpmdevtools clang gcc-c++ ruby ruby-devel && yum clean all
-
-RUN curl -s $go_pkg_url -o go.tar.gz && \
- tar -C /usr/local -xzf go.tar.gz && \
- rm go.tar.gz
-
-RUN /usr/bin/ssh-keygen -A
-
-RUN echo $'\n\
- export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin\n'\
- >> ~/.bash_profile
-
-RUN mkdir /rpmbuild && chmod 777 /rpmbuild
-
-CMD ["/usr/sbin/sshd", "-D"]
-
diff --git a/dockerbuild/Dockerfile.debian-bullseye b/dockerbuild/Dockerfile.debian-bullseye
deleted file mode 100644
index 518a08ae2..000000000
--- a/dockerbuild/Dockerfile.debian-bullseye
+++ /dev/null
@@ -1,15 +0,0 @@
-FROM debian:bullseye-20191224
-
-ARG go_pkg_url
-
-RUN apt-get update && apt-get upgrade -y && apt-get -y install build-essential curl ca-certificates devscripts dh-systemd
-
-RUN curl -s -k $go_pkg_url -o go.tar.gz && \
- tar -C /usr/local -xzf go.tar.gz && \
- rm go.tar.gz
-
-RUN groupadd -g 1000 jenkins-build && useradd -u 1000 -g 1000 jenkins-build
-RUN chmod 777 /home
-
-CMD ["/usr/bin/sshd", "-D"]
-
diff --git a/dockerbuild/Dockerfile.debian-buster b/dockerbuild/Dockerfile.debian-buster
deleted file mode 100644
index 6504178bc..000000000
--- a/dockerbuild/Dockerfile.debian-buster
+++ /dev/null
@@ -1,15 +0,0 @@
-FROM debian:buster-20191224
-
-ARG go_pkg_url
-
-RUN apt-get update && apt-get -y install build-essential curl ca-certificates devscripts dh-systemd
-
-RUN curl -s -k $go_pkg_url -o go.tar.gz && \
- tar -C /usr/local -xzf go.tar.gz && \
- rm go.tar.gz
-
-RUN groupadd -g 1000 jenkins-build && useradd -u 1000 -g 1000 jenkins-build
-RUN chmod 777 /home
-
-CMD ["/usr/bin/sshd", "-D"]
-
diff --git a/dockerbuild/Dockerfile.debian-jessie b/dockerbuild/Dockerfile.debian-jessie
deleted file mode 100644
index 31b0a904b..000000000
--- a/dockerbuild/Dockerfile.debian-jessie
+++ /dev/null
@@ -1,15 +0,0 @@
-FROM debian:jessie-20191224
-
-ARG go_pkg_url
-
-RUN apt-get update && apt-get -y install build-essential curl ca-certificates devscripts dh-systemd
-
-RUN curl -s -k $go_pkg_url -o go.tar.gz && \
- tar -C /usr/local -xzf go.tar.gz && \
- rm go.tar.gz
-
-RUN groupadd -g 1000 jenkins-build && useradd -u 1000 -g 1000 jenkins-build
-RUN chmod 777 /home
-
-CMD ["/usr/bin/sshd", "-D"]
-
diff --git a/dockerbuild/Dockerfile.debian-sid b/dockerbuild/Dockerfile.debian-sid
deleted file mode 100644
index 5fde10d5d..000000000
--- a/dockerbuild/Dockerfile.debian-sid
+++ /dev/null
@@ -1,15 +0,0 @@
-FROM debian:sid-20191224
-
-ARG go_pkg_url
-
-RUN apt-get update && apt-get upgrade -y && apt-get -y install build-essential curl ca-certificates devscripts dh-systemd
-
-RUN curl -s -k $go_pkg_url -o go.tar.gz && \
- tar -C /usr/local -xzf go.tar.gz && \
- rm go.tar.gz
-
-RUN groupadd -g 1000 jenkins-build && useradd -u 1000 -g 1000 jenkins-build
-RUN chmod 777 /home
-
-CMD ["/usr/bin/sshd", "-D"]
-
diff --git a/dockerbuild/Dockerfile.debian-stretch b/dockerbuild/Dockerfile.debian-stretch
deleted file mode 100644
index 76342fb8d..000000000
--- a/dockerbuild/Dockerfile.debian-stretch
+++ /dev/null
@@ -1,15 +0,0 @@
-FROM debian:stretch-20191224
-
-ARG go_pkg_url
-
-RUN apt-get update && apt-get -y install build-essential curl ca-certificates devscripts dh-systemd
-
-RUN curl -s -k $go_pkg_url -o go.tar.gz && \
- tar -C /usr/local -xzf go.tar.gz && \
- rm go.tar.gz
-
-RUN groupadd -g 1000 jenkins-build && useradd -u 1000 -g 1000 jenkins-build
-RUN chmod 777 /home
-
-CMD ["/usr/bin/sshd", "-D"]
-
diff --git a/dockerbuild/Dockerfile.debian-wheezy b/dockerbuild/Dockerfile.debian-wheezy
deleted file mode 100644
index 7322959e6..000000000
--- a/dockerbuild/Dockerfile.debian-wheezy
+++ /dev/null
@@ -1,23 +0,0 @@
-FROM debian:wheezy-20190228
-
-ARG go_pkg_url
-
-RUN echo "deb http://archive.debian.org/debian/ wheezy contrib main non-free" > /etc/apt/sources.list && \
- echo "deb-src http://archive.debian.org/debian/ wheezy contrib main non-free" >> /etc/apt/sources.list && \
- apt-get update && apt-get install -y apt-utils && \
- apt-get install -y --force-yes \
- curl gcc make sudo expect gnupg fakeroot perl-base=5.14.2-21+deb7u3 perl \
- libc-bin=2.13-38+deb7u10 libc6=2.13-38+deb7u10 libc6-dev build-essential \
- cdbs devscripts equivs automake autoconf libtool libaudit-dev selinux-basics \
- libdb5.1=5.1.29-5 libdb5.1-dev libssl1.0.0=1.0.1e-2+deb7u20 procps gawk libsigsegv2 \
- curl ca-certificates devscripts
-
-RUN curl -s -k $go_pkg_url -o go.tar.gz && \
- tar -C /usr/local -xzf go.tar.gz && \
- rm go.tar.gz
-
-RUN groupadd -g 1000 jenkins-build && useradd -u 1000 -g 1000 jenkins-build
-RUN chmod 777 /home
-
-CMD ["/usr/bin/sshd", "-D"]
-
diff --git a/dockerbuild/Dockerfile.kali-rolling b/dockerbuild/Dockerfile.kali-rolling
deleted file mode 100644
index 2825dffe4..000000000
--- a/dockerbuild/Dockerfile.kali-rolling
+++ /dev/null
@@ -1,15 +0,0 @@
-FROM kalilinux/kali-rolling:latest
-
-ARG go_pkg_url
-
-RUN apt-get update && apt-get upgrade -y && apt-get -y install build-essential curl ca-certificates devscripts dh-systemd cmake
-
-RUN curl -s -k $go_pkg_url -o go.tar.gz && \
- tar -C /usr/local -xzf go.tar.gz && \
- rm go.tar.gz
-
-RUN groupadd -g 1000 jenkins-build && useradd -u 1000 -g 1000 jenkins-build
-RUN chmod 777 /home
-
-CMD ["/usr/bin/sshd", "-D"]
-
diff --git a/dockerbuild/Dockerfile.ubuntu-bionic b/dockerbuild/Dockerfile.ubuntu-bionic
deleted file mode 100644
index 2bbc5b02e..000000000
--- a/dockerbuild/Dockerfile.ubuntu-bionic
+++ /dev/null
@@ -1,15 +0,0 @@
-FROM ubuntu:bionic-20200112
-
-ARG go_pkg_url
-
-RUN apt-get update && apt-get upgrade -y && apt-get -y install build-essential curl ca-certificates devscripts dh-systemd
-
-RUN curl -s -k $go_pkg_url -o go.tar.gz && \
- tar -C /usr/local -xzf go.tar.gz && \
- rm go.tar.gz
-
-RUN groupadd -g 1000 jenkins-build && useradd -u 1000 -g 1000 jenkins-build
-RUN chmod 777 /home
-
-CMD ["/usr/bin/sshd", "-D"]
-
diff --git a/dockerbuild/Dockerfile.ubuntu-eoan b/dockerbuild/Dockerfile.ubuntu-eoan
deleted file mode 100644
index 0fd5e33ca..000000000
--- a/dockerbuild/Dockerfile.ubuntu-eoan
+++ /dev/null
@@ -1,15 +0,0 @@
-FROM ubuntu:eoan-20200114
-
-ARG go_pkg_url
-
-RUN apt-get update && apt-get upgrade -y && apt-get -y install build-essential curl ca-certificates devscripts dh-systemd
-
-RUN curl -s -k $go_pkg_url -o go.tar.gz && \
- tar -C /usr/local -xzf go.tar.gz && \
- rm go.tar.gz
-
-RUN groupadd -g 1000 jenkins-build && useradd -u 1000 -g 1000 jenkins-build
-RUN chmod 777 /home
-
-CMD ["/usr/bin/sshd", "-D"]
-
diff --git a/dockerbuild/Dockerfile.ubuntu-trusty b/dockerbuild/Dockerfile.ubuntu-trusty
deleted file mode 100644
index 52a80c949..000000000
--- a/dockerbuild/Dockerfile.ubuntu-trusty
+++ /dev/null
@@ -1,15 +0,0 @@
-FROM ubuntu:trusty-20191217
-
-ARG go_pkg_url
-
-RUN apt-get update && apt-get upgrade -y && apt-get -y install build-essential curl ca-certificates devscripts dh-systemd
-
-RUN curl -s -k $go_pkg_url -o go.tar.gz && \
- tar -C /usr/local -xzf go.tar.gz && \
- rm go.tar.gz
-
-RUN groupadd -g 1000 jenkins-build && useradd -u 1000 -g 1000 jenkins-build
-RUN chmod 777 /home
-
-CMD ["/usr/bin/sshd", "-D"]
-
diff --git a/dockerbuild/Dockerfile.ubuntu-xenial b/dockerbuild/Dockerfile.ubuntu-xenial
deleted file mode 100644
index bda74f477..000000000
--- a/dockerbuild/Dockerfile.ubuntu-xenial
+++ /dev/null
@@ -1,15 +0,0 @@
-FROM ubuntu:xenial-20200114
-
-ARG go_pkg_url
-
-RUN apt-get update && apt-get -y install build-essential curl ca-certificates devscripts dh-systemd
-
-RUN curl -s -k $go_pkg_url -o go.tar.gz && \
- tar -C /usr/local -xzf go.tar.gz && \
- rm go.tar.gz
-
-RUN groupadd -g 1000 jenkins-build && useradd -u 1000 -g 1000 jenkins-build
-RUN chmod 777 /home
-
-CMD ["/usr/bin/sshd", "-D"]
-
diff --git a/dockerbuild/Makefile b/dockerbuild/Makefile
deleted file mode 100644
index 543d45d5a..000000000
--- a/dockerbuild/Makefile
+++ /dev/null
@@ -1,108 +0,0 @@
-.PHONY: all
-
-all: alpine centos debian ubuntu kali-rolling
-
-alpine:
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-arm64.tar.gz" --platform linux/arm64 -f Dockerfile.alpine . -t ztbuild/alpine-arm64 --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-386.tar.gz" --platform linux/386 -f Dockerfile.alpine . -t ztbuild/alpine-i386 --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-amd64.tar.gz" --platform linux/amd64 -f Dockerfile.alpine . -t ztbuild/alpine-amd64 --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-armv6l.tar.gz" --platform linux/arm/v6 -f Dockerfile.alpine . -t ztbuild/alpine-armel --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-armv6l.tar.gz" --platform linux/arm/v7 -f Dockerfile.alpine . -t ztbuild/alpine-armhf --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-ppc64le.tar.gz" --platform linux/ppc64le -f Dockerfile.alpine . -t ztbuild/alpine-ppc64le --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-s390x.tar.gz" --platform linux/s390x -f Dockerfile.alpine . -t ztbuild/alpine-s390x --load
-
-centos:
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-amd64.tar.gz" --platform linux/amd64 -f Dockerfile.centos7 . -t ztbuild/centos7-amd64 --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-386.tar.gz" --platform linux/386 -f Dockerfile.centos7-i386 . -t ztbuild/centos7-i386 --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-amd64.tar.gz" --platform linux/amd64 -f Dockerfile.centos6 . -t ztbuild/centos6-amd64 --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-386.tar.gz" --platform linux/386 -f Dockerfile.centos6-i386 . -t ztbuild/centos6-i386 --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-amd64.tar.gz" --platform linux/amd64 -f Dockerfile.centos8 . -t ztbuild/centos8-amd64 --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-arm64.tar.gz" --platform linux/arm64 -f Dockerfile.centos8 . -t ztbuild/centos8-arm64 --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-ppc64le.tar.gz" --platform linux/ppc64le -f Dockerfile.centos8 . -t ztbuild/centos8-ppc64le --load
-
-debian: debian-wheezy debian-jessie debian-buster debian-stretch debian-bullseye debian-sid
-
-debian-wheezy:
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-amd64.tar.gz" --platform linux/amd64 -f Dockerfile.debian-wheezy . -t ztbuild/debian-wheezy-amd64 --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-armv6l.tar.gz" --platform linux/arm/v7 -f Dockerfile.debian-wheezy . -t ztbuild/debian-wheezy-armhf --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-armv6l.tar.gz" --platform linux/arm/v6 -f Dockerfile.debian-wheezy . -t ztbuild/debian-wheezy-armel --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-386.tar.gz" --platform linux/386 -f Dockerfile.debian-wheezy . -t ztbuild/debian-wheezy-i386 --load
-
-debian-jessie:
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-amd64.tar.gz" --platform linux/amd64 -f Dockerfile.debian-jessie . -t ztbuild/debian-jessie-amd64 --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-armv6l.tar.gz" --platform linux/arm/v7 -f Dockerfile.debian-jessie . -t ztbuild/debian-jessie-armhf --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-armv6l.tar.gz" --platform linux/arm/v6 -f Dockerfile.debian-jessie . -t ztbuild/debian-jessie-armel --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-386.tar.gz" --platform linux/386 -f Dockerfile.debian-jessie . -t ztbuild/debian-jessie-i386 --load
-
-debian-buster:
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-amd64.tar.gz" --platform linux/amd64 -f Dockerfile.debian-buster . -t ztbuild/debian-buster-amd64 --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-arm64.tar.gz" --platform linux/arm64 -f Dockerfile.debian-buster . -t ztbuild/debian-buster-arm64 --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-armv6l.tar.gz" --platform linux/arm/v6 -f Dockerfile.debian-buster . -t ztbuild/debian-buster-armel --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-armv6l.tar.gz" --platform linux/arm/v7 -f Dockerfile.debian-buster . -t ztbuild/debian-buster-armhf --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-386.tar.gz" --platform linux/386 -f Dockerfile.debian-buster . -t ztbuild/debian-buster-i386 --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-ppc64le.tar.gz" --platform linux/ppc64le -f Dockerfile.debian-buster . -t ztbuild/debian-buster-ppc64le --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-s390x.tar.gz" --platform linux/s390x -f Dockerfile.debian-buster . -t ztbuild/debian-buster-s390x --load
-
-debian-stretch:
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-amd64.tar.gz" --platform linux/amd64 -f Dockerfile.debian-stretch . -t ztbuild/debian-stretch-amd64 --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-arm64.tar.gz" --platform linux/arm64 -f Dockerfile.debian-stretch . -t ztbuild/debian-stretch-arm64 --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-armv6l.tar.gz" --platform linux/arm/v6 -f Dockerfile.debian-stretch . -t ztbuild/debian-stretch-armel --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-armv6l.tar.gz" --platform linux/arm/v7 -f Dockerfile.debian-stretch . -t ztbuild/debian-stretch-armhf --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-386.tar.gz" --platform linux/386 -f Dockerfile.debian-stretch . -t ztbuild/debian-stretch-i386 --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-ppc64le.tar.gz" --platform linux/ppc64le -f Dockerfile.debian-stretch . -t ztbuild/debian-stretch-ppc64le --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-s390x.tar.gz" --platform linux/s390x -f Dockerfile.debian-stretch . -t ztbuild/debian-stretch-s390x --load
-
-debian-bullseye:
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-amd64.tar.gz" --platform linux/amd64 -f Dockerfile.debian-bullseye . -t ztbuild/debian-bullseye-amd64 --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-arm64.tar.gz" --platform linux/arm64 -f Dockerfile.debian-bullseye . -t ztbuild/debian-bullseye-arm64 --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-armv6l.tar.gz" --platform linux/arm/v6 -f Dockerfile.debian-bullseye . -t ztbuild/debian-bullseye-armel --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-armv6l.tar.gz" --platform linux/arm/v7 -f Dockerfile.debian-bullseye . -t ztbuild/debian-bullseye-armhf --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-386.tar.gz" --platform linux/386 -f Dockerfile.debian-bullseye . -t ztbuild/debian-bullseye-i386 --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-ppc64le.tar.gz" --platform linux/ppc64le -f Dockerfile.debian-bullseye . -t ztbuild/debian-bullseye-ppc64le --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-s390x.tar.gz" --platform linux/s390x -f Dockerfile.debian-bullseye . -t ztbuild/debian-bullseye-s390x --load
-
-debian-sid:
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-amd64.tar.gz" --platform linux/amd64 -f Dockerfile.debian-sid . -t ztbuild/debian-sid-amd64 --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-arm64.tar.gz" --platform linux/arm64 -f Dockerfile.debian-sid . -t ztbuild/debian-sid-arm64 --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-armv6l.tar.gz" --platform linux/arm/v6 -f Dockerfile.debian-sid . -t ztbuild/debian-sid-armel --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-armv6l.tar.gz" --platform linux/arm/v7 -f Dockerfile.debian-sid . -t ztbuild/debian-sid-armhf --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-386.tar.gz" --platform linux/386 -f Dockerfile.debian-sid . -t ztbuild/debian-sid-i386 --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-ppc64le.tar.gz" --platform linux/ppc64le -f Dockerfile.debian-sid . -t ztbuild/debian-sid-ppc64le --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-s390x.tar.gz" --platform linux/s390x -f Dockerfile.debian-sid . -t ztbuild/debian-sid-s390x --load
-
-ubuntu: ubuntu-trusty ubuntu-xenial ubuntu-bionic ubuntu-eoan
-
-ubuntu-trusty:
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-amd64.tar.gz" --platform linux/amd64 -f Dockerfile.ubuntu-trusty . -t ztbuild/ubuntu-trusty-amd64 --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-arm64.tar.gz" --platform linux/arm64 -f Dockerfile.ubuntu-trusty . -t ztbuild/ubuntu-trusty-arm64 --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-armv6l.tar.gz" --platform linux/arm/v7 -f Dockerfile.ubuntu-trusty . -t ztbuild/ubuntu-trusty-armhf --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-386.tar.gz" --platform linux/386 -f Dockerfile.ubuntu-trusty . -t ztbuild/ubuntu-trusty-i386 --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-ppc64le.tar.gz" --platform linux/ppc64le -f Dockerfile.ubuntu-trusty . -t ztbuild/ubuntu-trusty-ppc64le --load
-
-ubuntu-xenial:
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-amd64.tar.gz" --platform linux/amd64 -f Dockerfile.ubuntu-xenial . -t ztbuild/ubuntu-xenial-amd64 --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-arm64.tar.gz" --platform linux/arm64 -f Dockerfile.ubuntu-xenial . -t ztbuild/ubuntu-xenial-arm64 --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-armv6l.tar.gz" --platform linux/arm/v7 -f Dockerfile.ubuntu-xenial . -t ztbuild/ubuntu-xenial-armhf --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-386.tar.gz" --platform linux/386 -f Dockerfile.ubuntu-xenial . -t ztbuild/ubuntu-xenial-i386 --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-ppc64le.tar.gz" --platform linux/ppc64le -f Dockerfile.ubuntu-xenial . -t ztbuild/ubuntu-xenial-ppc64le --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-s390x.tar.gz" --platform linux/s390x -f Dockerfile.ubuntu-xenial . -t ztbuild/ubuntu-xenial-s390x --load
-
-ubuntu-bionic:
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-amd64.tar.gz" --platform linux/amd64 -f Dockerfile.ubuntu-bionic . -t ztbuild/ubuntu-bionic-amd64 --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-arm64.tar.gz" --platform linux/arm64 -f Dockerfile.ubuntu-bionic . -t ztbuild/ubuntu-bionic-arm64 --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-armv6l.tar.gz" --platform linux/arm/v7 -f Dockerfile.ubuntu-bionic . -t ztbuild/ubuntu-bionic-armhf --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-386.tar.gz" --platform linux/386 -f Dockerfile.ubuntu-bionic . -t ztbuild/ubuntu-bionic-i386 --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-ppc64le.tar.gz" --platform linux/ppc64le -f Dockerfile.ubuntu-bionic . -t ztbuild/ubuntu-bionic-ppc64le --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-s390x.tar.gz" --platform linux/s390x -f Dockerfile.ubuntu-bionic . -t ztbuild/ubuntu-bionic-s390x --load
-
-ubuntu-eoan:
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-amd64.tar.gz" --platform linux/amd64 -f Dockerfile.ubuntu-eoan . -t ztbuild/ubuntu-eoan-amd64 --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-arm64.tar.gz" --platform linux/arm64 -f Dockerfile.ubuntu-eoan . -t ztbuild/ubuntu-eoan-arm64 --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-armv6l.tar.gz" --platform linux/arm/v7 -f Dockerfile.ubuntu-eoan . -t ztbuild/ubuntu-eoan-armhf --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-386.tar.gz" --platform linux/386 -f Dockerfile.ubuntu-eoan . -t ztbuild/ubuntu-eoan-i386 --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-ppc64le.tar.gz" --platform linux/ppc64le -f Dockerfile.ubuntu-eoan . -t ztbuild/ubuntu-eoan-ppc64le --load
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-s390x.tar.gz" --platform linux/s390x -f Dockerfile.ubuntu-eoan . -t ztbuild/ubuntu-eoan-s390x --load
-
-kali-rolling:
- @docker buildx build --build-arg go_pkg_url="https://dl.google.com/go/go1.13.6.linux-amd64.tar.gz" --platform linux/amd64 -f Dockerfile.kali-rolling . -t ztbuild/kali-rolling-amd64 --load
-
diff --git a/dockerbuild/authorized_keys b/dockerbuild/authorized_keys
deleted file mode 100644
index 0dd35c7b7..000000000
--- a/dockerbuild/authorized_keys
+++ /dev/null
@@ -1,2 +0,0 @@
-ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8hgysbj2Luu3aN/Ya2wr4Y9LpUGqWWfn3k+UhIwOIE/Kd7/YpLjxHpseUA1hLnj9kHFShH8eiqoY0S6EDIYrTUwbXMMu8454lX/LcJOCJ9RlSeMMf7vpkxcI7cVRgOA430a3FR7M0Q8vKlyJzxxAEjMIxMyuVyinknfanNt+sQFiDUvOXoacqgZAHBWMlO7wOPyHWHNOzy7g8N0dHiJveKZqX/UUwuqJuS6UBq7MBMSU6TcMvJwHr+AbNvfyIUWCqlTByqFL9cmviRbIvQanxoRxi/5fVUGhtVBXUYvbCdFxDw5W2Svo9fDMm4Z5xWAD7rY1J3AM15RVyRTTtYvgD
-
diff --git a/dockerbuild/pipelint.sh b/dockerbuild/pipelint.sh
deleted file mode 100644
index 7fbd0de82..000000000
--- a/dockerbuild/pipelint.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-# curl (REST API)
-# User
-JENKINS_USER=grant
-
-# Api key from "/me/configure" on my Jenkins instance
-JENKINS_USER_KEY=11edf2d49321321119712c46c6349eaad7
-
-# Url for my local Jenkins instance.
-JENKINS_URL=http://$JENKINS_USER:$JENKINS_USER_KEY@jenkins.int.zerotier.com
-
-# JENKINS_CRUMB is needed if your Jenkins master has CRSF protection enabled (which it should)
-JENKINS_CRUMB=`curl "$JENKINS_URL/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,\":\",//crumb)"`
-curl -X POST -H $JENKINS_CRUMB -F "jenkinsfile=USE_HFS+_COMPRESSION
VERSION
- 1.10.1
+ 1.10.2
TYPE
0
diff --git a/ext/installfiles/windows/Prerequisites/Visual C++ Redistributable for Visual Studio 2015-2022/VC_redist.x64.exe b/ext/installfiles/windows/Prerequisites/Visual C++ Redistributable for Visual Studio 2015-2022/VC_redist.x64.exe
deleted file mode 100644
index 2a7fc6c95..000000000
Binary files a/ext/installfiles/windows/Prerequisites/Visual C++ Redistributable for Visual Studio 2015-2022/VC_redist.x64.exe and /dev/null differ
diff --git a/ext/installfiles/windows/Prerequisites/Visual C++ Redistributable for Visual Studio 2015-2022/VC_redist.x86.exe b/ext/installfiles/windows/Prerequisites/Visual C++ Redistributable for Visual Studio 2015-2022/VC_redist.x86.exe
deleted file mode 100644
index 189c5e21e..000000000
Binary files a/ext/installfiles/windows/Prerequisites/Visual C++ Redistributable for Visual Studio 2015-2022/VC_redist.x86.exe and /dev/null differ
diff --git a/ext/installfiles/windows/ZeroTier One.aip b/ext/installfiles/windows/ZeroTier One.aip
index 02a10108f..daaea8cc3 100644
--- a/ext/installfiles/windows/ZeroTier One.aip
+++ b/ext/installfiles/windows/ZeroTier One.aip
@@ -1,7 +1,7 @@
-
+
-
+
@@ -9,7 +9,7 @@
-
+
@@ -32,10 +32,10 @@
-
+
-
+
@@ -70,12 +70,10 @@
-
-
+
-
@@ -94,8 +92,6 @@
-
-
@@ -164,25 +160,19 @@
-
-
-
-
-
-
@@ -201,12 +191,10 @@
-
-
-
+
@@ -262,9 +250,6 @@
-
-
-
@@ -282,9 +267,7 @@
-
-
@@ -299,13 +282,11 @@
-
-
@@ -314,9 +295,6 @@
-
-
-
@@ -331,7 +309,6 @@
-
@@ -377,8 +354,6 @@
-
-
@@ -393,7 +368,7 @@
-
+
@@ -422,12 +397,9 @@
-
+
-
-
-
@@ -440,11 +412,6 @@
-
-
-
-
-
@@ -453,6 +420,7 @@
+
@@ -479,10 +447,8 @@
-
-
@@ -501,12 +467,9 @@
-
-
-
@@ -540,15 +503,7 @@
-
-
-
-
-
-
-
-
@@ -573,7 +528,7 @@
-
+
diff --git a/include/ZeroTierOne.h b/include/ZeroTierOne.h
index 2d103d847..23f97b388 100644
--- a/include/ZeroTierOne.h
+++ b/include/ZeroTierOne.h
@@ -86,6 +86,11 @@ extern "C" {
*/
#define ZT_MIN_PHYSMTU 1400
+/**
+ * Maximum physical interface name length. This number is gigantic because of Windows.
+ */
+#define ZT_MAX_PHYSIFNAME 256
+
/**
* Default UDP payload size (physical path MTU) not including UDP and IP overhead
*
@@ -1203,7 +1208,7 @@ typedef struct
bool ssoEnabled;
/**
- * SSO verison
+ * SSO version
*/
uint64_t ssoVersion;
@@ -1317,35 +1322,20 @@ typedef struct
*/
float packetErrorRatio;
- /**
- * Mean throughput
- */
- uint64_t throughputMean;
-
- /**
- * Maximum observed throughput
- */
- float throughputMax;
-
- /**
- * Throughput variance
- */
- float throughputVariance;
-
/**
* Address scope
*/
uint8_t scope;
/**
- * Percentage of traffic allocated to this path
+ * Relative quality value
*/
- float allocation;
+ float relativeQuality;
/**
- * Name of physical interface (for monitoring)
+ * Name of physical interface this path resides on
*/
- char ifname[32];
+ char ifname[ZT_MAX_PHYSIFNAME];
uint64_t localSocket;
@@ -1354,6 +1344,21 @@ typedef struct
*/
int expired;
+ /**
+ * Whether this path is currently included in the bond
+ */
+ uint8_t bonded;
+
+ /**
+ * Whether this path is currently eligible to be used in a bond
+ */
+ uint8_t eligible;
+
+ /**
+ * The capacity of this link (as given to bonding layer)
+ */
+ uint32_t linkSpeed;
+
/**
* Is path preferred?
*/
@@ -2061,7 +2066,7 @@ ZT_SDK_API int ZT_Node_sendUserMessage(ZT_Node *node,void *tptr,uint64_t dest,ui
* NetworkConfigMaster base class in node/. No type checking is performed,
* so a pointer to anything else will result in a crash.
*
- * @param node ZertTier One node
+ * @param node ZeroTier One node
* @param networkConfigMasterInstance Instance of NetworkConfigMaster C++ class or NULL to disable
* @return OK (0) or error code if a fatal error condition has occurred
*/
diff --git a/java/README.md b/java/README.md
index 2650ec3df..979101c5e 100644
--- a/java/README.md
+++ b/java/README.md
@@ -5,7 +5,7 @@ ZeroTier One SDK - Android JNI Wrapper
Building
-----
-Reqires:
+Requires:
* JDK
* ANT
diff --git a/java/jni/Android.mk b/java/jni/Android.mk
deleted file mode 100644
index 952bc4328..000000000
--- a/java/jni/Android.mk
+++ /dev/null
@@ -1,66 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := ZeroTierOneJNI
-LOCAL_C_INCLUDES := \
- $(ZT1)/include \
- $(ZT1)/node \
- $(ZT1)/osdep
-
-LOCAL_LDLIBS := -llog
-# LOCAL_CFLAGS := -g
-
-APP_UNIFIED_HEADERS := true
-
-LOCAL_CFLAGS := -DZT_USE_MINIUPNPC
-ifeq ($(TARGET_ARCH_ABI),x86_64)
- LOCAL_CXXFLAGS := -maes -mpclmul -msse3 -msse4.1
-endif
-ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
- LOCAL_ARM_NEON := true
- LOCAL_CXXFLAGS := -march=armv8-a+crypto -mfloat-abi=softfp -mfpu=neon -maes -isystem $NDK/sysroot/usr/include/$TRIPLE
-endif
-
-# ZeroTierOne SDK source files
-LOCAL_SRC_FILES := \
- $(ZT1)/node/AES.cpp \
- $(ZT1)/node/AES_aesni.cpp \
- $(ZT1)/node/AES_armcrypto.cpp \
- $(ZT1)/node/Bond.cpp \
- $(ZT1)/node/C25519.cpp \
- $(ZT1)/node/Capability.cpp \
- $(ZT1)/node/CertificateOfMembership.cpp \
- $(ZT1)/node/CertificateOfOwnership.cpp \
- $(ZT1)/node/Identity.cpp \
- $(ZT1)/node/IncomingPacket.cpp \
- $(ZT1)/node/InetAddress.cpp \
- $(ZT1)/node/Membership.cpp \
- $(ZT1)/node/Multicaster.cpp \
- $(ZT1)/node/Network.cpp \
- $(ZT1)/node/NetworkConfig.cpp \
- $(ZT1)/node/Node.cpp \
- $(ZT1)/node/OutboundMulticast.cpp \
- $(ZT1)/node/Packet.cpp \
- $(ZT1)/node/Path.cpp \
- $(ZT1)/node/Peer.cpp \
- $(ZT1)/node/Poly1305.cpp \
- $(ZT1)/node/Revocation.cpp \
- $(ZT1)/node/Salsa20.cpp \
- $(ZT1)/node/SelfAwareness.cpp \
- $(ZT1)/node/SHA512.cpp \
- $(ZT1)/node/Switch.cpp \
- $(ZT1)/node/Tag.cpp \
- $(ZT1)/node/Topology.cpp \
- $(ZT1)/node/Trace.cpp \
- $(ZT1)/node/Utils.cpp \
- $(ZT1)/osdep/OSUtils.cpp
-
-# JNI Files
-LOCAL_SRC_FILES += \
- com_zerotierone_sdk_Node.cpp \
- ZT_jniarray.cpp \
- ZT_jniutils.cpp \
- ZT_jnilookup.cpp
-
-include $(BUILD_SHARED_LIBRARY)
\ No newline at end of file
diff --git a/java/jni/Application.mk b/java/jni/Application.mk
deleted file mode 100644
index 8613c15ee..000000000
--- a/java/jni/Application.mk
+++ /dev/null
@@ -1,5 +0,0 @@
-# NDK_TOOLCHAIN_VERSION := clang3.5
-APP_STL := c++_static
-APP_CPPFLAGS := -Wall -fstack-protector -fexceptions -fno-strict-aliasing -frtti -Wno-deprecated-register -DZT_NO_TYPE_PUNNING=1
-APP_PLATFORM := android-21
-APP_ABI := all
diff --git a/java/jni/ZT_jniarray.cpp b/java/jni/ZT_jniarray.cpp
index 24ae97c71..a1cae76ed 100644
--- a/java/jni/ZT_jniarray.cpp
+++ b/java/jni/ZT_jniarray.cpp
@@ -5,6 +5,7 @@
#include "ZT_jniarray.h"
#include
#include
+#include
jclass java_util_ArrayList;
jmethodID java_util_ArrayList_;
diff --git a/java/jni/ZT_jnilookup.cpp b/java/jni/ZT_jnilookup.cpp
index 51d9c0739..4d867a35c 100644
--- a/java/jni/ZT_jnilookup.cpp
+++ b/java/jni/ZT_jnilookup.cpp
@@ -62,7 +62,7 @@ jclass JniLookup::findClass(const std::string &name)
JNIEnv *env = NULL;
if(m_jvm->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK)
{
- LOGE("Error retreiving JNI Environment");
+ LOGE("Error retrieving JNI Environment");
return NULL;
}
const char *c = name.c_str();
diff --git a/java/jni/ZT_jniutils.cpp b/java/jni/ZT_jniutils.cpp
index bcbd31916..bfb969abb 100644
--- a/java/jni/ZT_jniutils.cpp
+++ b/java/jni/ZT_jniutils.cpp
@@ -296,7 +296,7 @@ jobject newInetAddress(JNIEnv *env, const sockaddr_storage &addr)
inetAddressClass, "getByAddress", "([B)Ljava/net/InetAddress;");
if(env->ExceptionCheck() || inetAddress_getByAddress == NULL)
{
- LOGE("Erorr finding getByAddress() static method");
+ LOGE("Error finding getByAddress() static method");
return NULL;
}
diff --git a/java/jni/com_zerotierone_sdk_Node.cpp b/java/jni/com_zerotierone_sdk_Node.cpp
index 6ddc35565..75af18bc8 100644
--- a/java/jni/com_zerotierone_sdk_Node.cpp
+++ b/java/jni/com_zerotierone_sdk_Node.cpp
@@ -107,7 +107,7 @@ namespace {
enum ZT_VirtualNetworkConfigOperation operation,
const ZT_VirtualNetworkConfig *config)
{
- LOGV("VritualNetworkConfigFunctionCallback");
+ LOGV("VirtualNetworkConfigFunctionCallback");
JniRef *ref = (JniRef*)userData;
JNIEnv *env = NULL;
ref->jvm->GetEnv((void**)&env, JNI_VERSION_1_6);
@@ -573,7 +573,26 @@ namespace {
return true;
}
- struct sockaddr_storage nullAddress = {0};
+ //
+ // was:
+ // struct sockaddr_storage nullAddress = {0};
+ //
+ // but was getting this warning:
+ // warning: suggest braces around initialization of subobject
+ //
+ // when building ZeroTierOne
+ //
+ struct sockaddr_storage nullAddress;
+
+ //
+ // It is possible to assume knowledge about internals of sockaddr_storage and construct
+ // correct 0-initializer, but it is simpler to just treat sockaddr_storage as opaque and
+ // use memset here to fill with 0
+ //
+ // This is also done in InetAddress.hpp for InetAddress
+ //
+ memset(&nullAddress, 0, sizeof(sockaddr_storage));
+
jobject remoteAddressObj = NULL;
if(memcmp(remoteAddress, &nullAddress, sizeof(sockaddr_storage)) != 0)
@@ -1025,7 +1044,7 @@ JNIEXPORT jobject JNICALL Java_com_zerotier_sdk_Node_processWirePacket(
inetAddressClass, "getAddress", "()[B");
if(getAddressMethod == NULL)
{
- // cant find InetAddress.getAddres()
+ // cant find InetAddress.getAddress()
return createResultObject(env, ZT_RESULT_FATAL_ERROR_INTERNAL);
}
diff --git a/java/src/com/zerotier/sdk/NativeUtils.java b/java/src/com/zerotier/sdk/NativeUtils.java
index 07e1ef5bc..4932a6c71 100644
--- a/java/src/com/zerotier/sdk/NativeUtils.java
+++ b/java/src/com/zerotier/sdk/NativeUtils.java
@@ -43,7 +43,7 @@ public class NativeUtils {
String[] parts = path.split("/");
String filename = (parts.length > 1) ? parts[parts.length - 1] : null;
- // Split filename to prexif and suffix (extension)
+ // Split filename to prefix and suffix (extension)
String prefix = "";
String suffix = null;
if (filename != null) {
diff --git a/java/src/com/zerotier/sdk/Node.java b/java/src/com/zerotier/sdk/Node.java
index ef6ac9d2d..1b3a4901f 100644
--- a/java/src/com/zerotier/sdk/Node.java
+++ b/java/src/com/zerotier/sdk/Node.java
@@ -84,7 +84,7 @@ public class Node {
*
* @param now Current clock in milliseconds
* @param getListener User written instance of the {@link DataStoreGetListener} interface called to get objects from persistent storage. This instance must be unique per Node object.
- * @param putListener User written intstance of the {@link DataStorePutListener} interface called to put objects in persistent storage. This instance must be unique per Node object.
+ * @param putListener User written instance of the {@link DataStorePutListener} interface called to put objects in persistent storage. This instance must be unique per Node object.
* @param sender
* @param eventListener User written instance of the {@link EventListener} interface to receive status updates and non-fatal error notices. This instance must be unique per Node object.
* @param frameListener
@@ -197,7 +197,7 @@ public class Node {
* Join a network
*
* This may generate calls to the port config callback before it returns,
- * or these may be deffered if a netconf is not available yet.
+ * or these may be deferred if a netconf is not available yet.
*
* If we are already a member of the network, nothing is done and OK is
* returned.
diff --git a/java/src/com/zerotier/sdk/NodeStatus.java b/java/src/com/zerotier/sdk/NodeStatus.java
index 94376d85b..11e49ade1 100644
--- a/java/src/com/zerotier/sdk/NodeStatus.java
+++ b/java/src/com/zerotier/sdk/NodeStatus.java
@@ -38,7 +38,7 @@ public final class NodeStatus {
/**
* 40-bit ZeroTier address of this node
*/
- public final long getAddres() {
+ public final long getAddress() {
return address;
}
diff --git a/make-bsd.mk b/make-bsd.mk
index 889e0e093..8234f2fdb 100644
--- a/make-bsd.mk
+++ b/make-bsd.mk
@@ -133,7 +133,7 @@ endif
# Fail if system architecture could not be determined
ifeq ($(ZT_ARCHITECTURE),999)
-ERR=$(error FATAL: architecture could not be determined from $(CC) -dumpmachine: $CC_MACH)
+ERR=$(error FATAL: architecture could not be determined from $(CC) -dumpmachine: $(CC_MACH))
.PHONY: err
err: ; $(ERR)
endif
diff --git a/make-linux.mk b/make-linux.mk
index 3941573cf..e188d3e60 100644
--- a/make-linux.mk
+++ b/make-linux.mk
@@ -198,6 +198,11 @@ ifeq ($(CC_MACH),armv6kz)
override DEFS+=-DZT_NO_TYPE_PUNNING
ZT_USE_ARM32_NEON_ASM_CRYPTO=1
endif
+ifeq ($(CC_MACH),armv6k)
+ ZT_ARCHITECTURE=3
+ override DEFS+=-DZT_NO_TYPE_PUNNING
+ ZT_USE_ARM32_NEON_ASM_CRYPTO=1
+endif
ifeq ($(CC_MACH),armv7)
ZT_ARCHITECTURE=3
override DEFS+=-DZT_NO_TYPE_PUNNING
@@ -257,7 +262,7 @@ endif
# Fail if system architecture could not be determined
ifeq ($(ZT_ARCHITECTURE),999)
-ERR=$(error FATAL: architecture could not be determined from $(CC) -dumpmachine: $CC_MACH)
+ERR=$(error FATAL: architecture could not be determined from $(CC) -dumpmachine: $(CC_MACH))
.PHONY: err
err: ; $(ERR)
endif
@@ -498,15 +503,12 @@ snap-uninstall: FORCE
snap remove zerotier
snap-build-remote: FORCE
- cd pkg && snapcraft remote-build --build-on=amd64,arm64,s390x,ppc64el,armhf,i386
+ cd pkg && snapcraft remote-build --build-for=amd64,arm64,s390x,ppc64el,armhf,i386
-snap-upload-beta: FORCE
- snapcraft login --with-file=snapcraft-login-data
- pushd pkg
- for SNAPFILE in ./*.snap; do\
- snapcraft upload --release=stable,beta,edge,candidate $${SNAPFILE};\
+snap-upload: ./pkg/*.snap
+ for file in $^ ; do \
+ snapcraft upload --release=beta,edge,candidate $${file} ; \
done
- popd
synology-pkg: FORCE
cd pkg/synology ; ./build.sh build
diff --git a/node/Bond.cpp b/node/Bond.cpp
index 45b34976f..dc17e6bee 100644
--- a/node/Bond.cpp
+++ b/node/Bond.cpp
@@ -18,6 +18,7 @@
#include
#include
#include
+#include // for PRId64, etc. macros
namespace ZeroTier {
@@ -28,6 +29,8 @@ uint8_t Bond::_defaultPolicy = ZT_BOND_POLICY_NONE;
Phy* Bond::_phy;
+Binder* Bond::_binder;
+
Mutex Bond::_bonds_m;
Mutex Bond::_links_m;
@@ -138,12 +141,13 @@ SharedPtr Bond::createBond(const RuntimeEnvironment* renv, const SharedPtr
if (it->second->isUserSpecified() && it->second->userHasSpecifiedFailoverInstructions()) {
bond->_userHasSpecifiedFailoverInstructions = true;
}
- if (it->second->isUserSpecified() && (it->second->speed() > 0)) {
- bond->_userHasSpecifiedLinkSpeeds = true;
+ if (it->second->isUserSpecified() && (it->second->capacity() > 0)) {
+ bond->_userHasSpecifiedLinkCapacities = true;
}
++it;
}
}
+ bond->startBond();
return bond;
}
return SharedPtr();
@@ -152,19 +156,35 @@ SharedPtr Bond::createBond(const RuntimeEnvironment* renv, const SharedPtr
void Bond::destroyBond(uint64_t peerId)
{
Mutex::Lock _l(_bonds_m);
+ auto iter = _bonds.find(peerId);
+ if (iter != _bonds.end()) {
+ iter->second->stopBond();
+ }
_bonds.erase(peerId);
}
+void Bond::stopBond()
+{
+ debug("stopping bond");
+ _run = false;
+}
+
+void Bond::startBond()
+{
+ debug("starting bond");
+ _run = true;
+}
+
SharedPtr Bond::getLinkBySocket(const std::string& policyAlias, uint64_t localSocket, bool createIfNeeded = false)
{
Mutex::Lock _l(_links_m);
- char ifname[64] = { 0 };
- _phy->getIfName((PhySocket*)((uintptr_t)localSocket), ifname, sizeof(ifname) - 1);
+ char ifname[ZT_MAX_PHYSIFNAME] = {};
+ _binder->getIfName((PhySocket*)((uintptr_t)localSocket), ifname, sizeof(ifname) - 1);
std::string ifnameStr(ifname);
auto search = _interfaceToLinkMap[policyAlias].find(ifnameStr);
if (search == _interfaceToLinkMap[policyAlias].end()) {
if (createIfNeeded) {
- SharedPtr s = new Link(ifnameStr, 0, 0, true, ZT_BOND_SLAVE_MODE_SPARE, "", 0.0);
+ SharedPtr s = new Link(ifnameStr, 0, 0, true, ZT_BOND_SLAVE_MODE_PRIMARY, "");
_interfaceToLinkMap[policyAlias].insert(std::pair >(ifnameStr, s));
return s;
}
@@ -237,7 +257,7 @@ void Bond::nominatePathToBond(const SharedPtr& path, int64_t now)
* Ensure the link is allowed and the path is not already present
*/
if (! RR->bc->linkAllowed(_policyAlias, getLinkBySocket(_policyAlias, path->localSocket(), true))) {
- debug("link %s is not permitted according to user-specified rules", pathToStr(path).c_str());
+ debug("link %s is not allowed according to user-specified rules", pathToStr(path).c_str());
return;
}
bool alreadyPresent = false;
@@ -250,6 +270,12 @@ void Bond::nominatePathToBond(const SharedPtr& path, int64_t now)
}
}
if (! alreadyPresent) {
+ SharedPtr link = getLink(path);
+ if (link) {
+ std::string ifnameStr = std::string(link->ifname());
+ memset(path->_ifname, 0x0, ZT_MAX_PHYSIFNAME);
+ memcpy(path->_ifname, ifnameStr.c_str(), std::min((int)ifnameStr.length(), ZT_MAX_PHYSIFNAME));
+ }
/**
* Find somewhere to stick it
*/
@@ -267,7 +293,7 @@ void Bond::nominatePathToBond(const SharedPtr& path, int64_t now)
if (commonLink) {
for (unsigned int j = 0; j < ZT_MAX_PEER_NETWORK_PATHS; ++j) {
if (_paths[j].p && _paths[j].p.ptr() != _paths[i].p.ptr()) {
- if (RR->bc->getLinkBySocket(_policyAlias, _paths[j].p->localSocket()) == commonLink, true) {
+ if (RR->bc->getLinkBySocket(_policyAlias, _paths[j].p->localSocket(), true) == commonLink) {
bFoundCommonLink = true;
_paths[j].onlyPathOnLink = false;
}
@@ -291,8 +317,8 @@ void Bond::nominatePathToBond(const SharedPtr& path, int64_t now)
void Bond::addPathToBond(int nominatedIdx, int bondedIdx)
{
// Map bonded set to nominated set
- _bondIdxMap[bondedIdx] = nominatedIdx;
- // Tell the bonding layer that we can now use this bond for traffic
+ _realIdxMap[bondedIdx] = nominatedIdx;
+ // Tell the bonding layer that we can now use this path for traffic
_paths[nominatedIdx].bonded = true;
}
@@ -320,62 +346,57 @@ SharedPtr Bond::getAppropriatePath(int64_t now, int32_t flowId)
* balance-rr
*/
if (_policy == ZT_BOND_POLICY_BALANCE_RR) {
- if (! _allowFlowHashing) {
- if (_packetsPerLink == 0) {
- // Randomly select a path
- return _paths[_bondIdxMap[_freeRandomByte % _numBondedPaths]].p;
- }
- if (_rrPacketsSentOnCurrLink < _packetsPerLink) {
- // Continue to use this link
- ++_rrPacketsSentOnCurrLink;
- return _paths[_bondIdxMap[_rrIdx]].p;
- }
- // Reset striping counter
- _rrPacketsSentOnCurrLink = 0;
- if (_numBondedPaths == 1 || _rrIdx >= (ZT_MAX_PEER_NETWORK_PATHS - 1)) {
- _rrIdx = 0;
- }
- else {
- int _tempIdx = _rrIdx;
- for (int searchCount = 0; searchCount < (_numBondedPaths - 1); searchCount++) {
- _tempIdx = (_tempIdx == (_numBondedPaths - 1)) ? 0 : _tempIdx + 1;
- if (_bondIdxMap[_tempIdx] != ZT_MAX_PEER_NETWORK_PATHS) {
- if (_paths[_bondIdxMap[_tempIdx]].p && _paths[_bondIdxMap[_tempIdx]].eligible) {
- _rrIdx = _tempIdx;
- break;
- }
+ if (_packetsPerLink == 0) {
+ // Randomly select a path
+ return _paths[_realIdxMap[_freeRandomByte % _numBondedPaths]].p;
+ }
+ if (_rrPacketsSentOnCurrLink < _packetsPerLink) {
+ // Continue to use this link
+ ++_rrPacketsSentOnCurrLink;
+ return _paths[_realIdxMap[_rrIdx]].p;
+ }
+ // Reset striping counter
+ _rrPacketsSentOnCurrLink = 0;
+ if (_numBondedPaths == 1 || _rrIdx >= (ZT_MAX_PEER_NETWORK_PATHS - 1)) {
+ _rrIdx = 0;
+ }
+ else {
+ int _tempIdx = _rrIdx;
+ for (int searchCount = 0; searchCount < (_numBondedPaths - 1); searchCount++) {
+ _tempIdx = (_tempIdx == (_numBondedPaths - 1)) ? 0 : _tempIdx + 1;
+ if (_realIdxMap[_tempIdx] != ZT_MAX_PEER_NETWORK_PATHS) {
+ if (_paths[_realIdxMap[_tempIdx]].p && _paths[_realIdxMap[_tempIdx]].eligible) {
+ _rrIdx = _tempIdx;
+ break;
}
}
}
- if (_paths[_bondIdxMap[_rrIdx]].p) {
- return _paths[_bondIdxMap[_rrIdx]].p;
- }
+ }
+ if (_paths[_realIdxMap[_rrIdx]].p) {
+ return _paths[_realIdxMap[_rrIdx]].p;
}
}
/**
- * balance-xor
+ * balance-xor/aware
*/
if (_policy == ZT_BOND_POLICY_BALANCE_XOR || _policy == ZT_BOND_POLICY_BALANCE_AWARE) {
- if (! _allowFlowHashing || flowId == -1) {
+ if (flowId == -1) {
// No specific path required for unclassified traffic, send on anything
- int m_idx = _bondIdxMap[_freeRandomByte % _numBondedPaths];
+ int m_idx = _realIdxMap[_freeRandomByte % _numBondedPaths];
return _paths[m_idx].p;
}
- else if (_allowFlowHashing) {
- Mutex::Lock _l(_flows_m);
- SharedPtr flow;
- if (_flows.count(flowId)) {
- flow = _flows[flowId];
- flow->lastActivity = now;
- }
- else {
- unsigned char entropy;
- Utils::getSecureRandom(&entropy, 1);
- flow = createFlow(ZT_MAX_PEER_NETWORK_PATHS, flowId, entropy, now);
- }
- if (flow) {
- return _paths[flow->assignedPath].p;
- }
+ Mutex::Lock _l(_flows_m);
+ std::map >::iterator it = _flows.find(flowId);
+ if (likely(it != _flows.end())) {
+ it->second->lastActivity = now;
+ return _paths[it->second->assignedPath].p;
+ }
+ else {
+ unsigned char entropy;
+ Utils::getSecureRandom(&entropy, 1);
+ SharedPtr flow = createFlow(ZT_MAX_PEER_NETWORK_PATHS, flowId, entropy, now);
+ _flows[flowId] = flow;
+ return _paths[flow->assignedPath].p;
}
}
return SharedPtr();
@@ -408,14 +429,14 @@ void Bond::recordOutgoingPacket(const SharedPtr& path, uint64_t packetId,
}
if (shouldRecord) {
//_paths[pathIdx].expectingAckAsOf = now;
- //_paths[pathIdx].totalBytesSentSinceLastAckRecieved += payloadLength;
+ //_paths[pathIdx].totalBytesSentSinceLastAckReceived += payloadLength;
//_paths[pathIdx].unackedBytes += payloadLength;
if (_paths[pathIdx].qosStatsOut.size() < ZT_QOS_MAX_PENDING_RECORDS) {
_paths[pathIdx].qosStatsOut[packetId] = now;
}
}
}
- if (_allowFlowHashing && (flowId != ZT_QOS_NO_FLOW)) {
+ if (flowId != ZT_QOS_NO_FLOW) {
Mutex::Lock _l(_flows_m);
if (_flows.count(flowId)) {
_flows[flowId]->bytesOut += payloadLength;
@@ -450,7 +471,7 @@ void Bond::recordIncomingPacket(const SharedPtr& path, uint64_t packetId,
//_paths[pathIdx].packetValiditySamples.push(true);
}
else {
- debug("QoS buffer full, will not record information");
+ // debug("QoS buffer full, will not record information");
}
/*
if (_paths[pathIdx].ackStatsIn.size() < ZT_ACK_MAX_PENDING_RECORDS) {
@@ -493,13 +514,17 @@ void Bond::receivedQoS(const SharedPtr& path, int64_t now, int count, uint
if (pathIdx == ZT_MAX_PEER_NETWORK_PATHS) {
return;
}
+ _paths[pathIdx].lastQoSReceived = now;
// debug("received QoS packet (sampling %d frames) via %s", count, pathToStr(path).c_str());
- // Look up egress times and compute latency values for each record
+ // Look up egress times and compute latency values for each record
std::map::iterator it;
for (int j = 0; j < count; j++) {
it = _paths[pathIdx].qosStatsOut.find(rx_id[j]);
if (it != _paths[pathIdx].qosStatsOut.end()) {
_paths[pathIdx].latencySamples.push(((uint16_t)(now - it->second) - rx_ts[j]) / 2);
+ // if (_paths[pathIdx].shouldAvoid) {
+ // debug("RX sample on avoided path %d", pathIdx);
+ // }
_paths[pathIdx].qosStatsOut.erase(it);
}
}
@@ -522,6 +547,7 @@ int32_t Bond::generateQoSPacket(int pathIdx, int64_t now, char* qosBuffer)
std::map::iterator it = _paths[pathIdx].qosStatsIn.begin();
int i = 0;
int numRecords = std::min(_paths[pathIdx].packetsReceivedSinceLastQoS, ZT_QOS_TABLE_SIZE);
+ // debug("numRecords=%3d, packetsReceivedSinceLastQoS=%3d, _paths[pathIdx].qosStatsIn.size()=%3zu", numRecords, _paths[pathIdx].packetsReceivedSinceLastQoS, _paths[pathIdx].qosStatsIn.size());
while (i < numRecords && it != _paths[pathIdx].qosStatsIn.end()) {
uint64_t id = it->first;
memcpy(qosBuffer, &id, sizeof(uint64_t));
@@ -536,72 +562,93 @@ int32_t Bond::generateQoSPacket(int pathIdx, int64_t now, char* qosBuffer)
return len;
}
-bool Bond::assignFlowToBondedPath(SharedPtr& flow, int64_t now)
+bool Bond::assignFlowToBondedPath(SharedPtr& flow, int64_t now, bool reassign = false)
{
if (! _numBondedPaths) {
- debug("unable to assign flow %x (bond has no links)\n", flow->id);
+ debug("unable to assign flow %x (bond has no links)", flow->id);
return false;
}
- unsigned int idx = ZT_MAX_PEER_NETWORK_PATHS;
+ unsigned int bondedIdx = ZT_MAX_PEER_NETWORK_PATHS;
if (_policy == ZT_BOND_POLICY_BALANCE_XOR) {
- idx = abs((int)(flow->id % (_numBondedPaths)));
- flow->assignPath(_bondIdxMap[idx], now);
- ++(_paths[_bondIdxMap[idx]].assignedFlowCount);
+ bondedIdx = abs((int)(flow->id % _numBondedPaths));
+ flow->assignPath(_realIdxMap[bondedIdx], now);
+ ++(_paths[_realIdxMap[bondedIdx]].assignedFlowCount);
}
if (_policy == ZT_BOND_POLICY_BALANCE_AWARE) {
- unsigned char entropy;
- Utils::getSecureRandom(&entropy, 1);
- if (_totalBondUnderload) {
- entropy %= _totalBondUnderload;
- }
- /* Since there may be scenarios where a path is removed before we can re-estimate
- relative qualities (and thus allocations) we need to down-modulate the entropy
- value that we use to randomly assign among the surviving paths, otherwise we risk
- not being able to find a path to assign this flow to. */
- int totalIncompleteAllocation = 0;
- for (unsigned int i = 0; i < ZT_MAX_PEER_NETWORK_PATHS; ++i) {
- if (_paths[i].p && _paths[i].bonded) {
- totalIncompleteAllocation += _paths[i].allocation;
- }
- }
- entropy %= totalIncompleteAllocation;
- for (unsigned int i = 0; i < ZT_MAX_PEER_NETWORK_PATHS; ++i) {
- if (_paths[i].p && _paths[i].bonded) {
- uint8_t probabilitySegment = (_totalBondUnderload > 0) ? _paths[i].affinity : _paths[i].allocation;
- if (entropy <= probabilitySegment) {
- idx = i;
- break;
- }
- entropy -= probabilitySegment;
- }
- }
- if (idx < ZT_MAX_PEER_NETWORK_PATHS) {
- flow->assignPath(idx, now);
- ++(_paths[idx].assignedFlowCount);
+ /** balance-aware generally works like balance-xor except that it will try to
+ * take into account user preferences (or default sane limits) that will discourage
+ * allocating traffic to links with a lesser perceived "quality" */
+ int offset = 0;
+ float bestQuality = 0.0;
+ int nextBestQualIdx = ZT_MAX_PEER_NETWORK_PATHS;
+
+ if (reassign) {
+ log("attempting to re-assign out-flow %04x previously on idx %d (%u / %zu flows)", flow->id, flow->assignedPath, _paths[_realIdxMap[flow->assignedPath]].assignedFlowCount, _flows.size());
}
else {
- debug("unable to assign out-flow %x (unknown reason)", flow->id);
- return false;
+ debug("attempting to assign flow for the first time");
+ }
+
+ unsigned char entropy;
+ Utils::getSecureRandom(&entropy, 1);
+ float randomLinkCapacity = ((float)entropy / 255.0); // Used to random but proportional choices
+
+ while (offset < _numBondedPaths) {
+ unsigned char entropy;
+ Utils::getSecureRandom(&entropy, 1);
+
+ if (reassign) {
+ bondedIdx = (flow->assignedPath + offset) % (_numBondedPaths);
+ }
+ else {
+ bondedIdx = abs((int)((entropy + offset) % (_numBondedPaths)));
+ }
+ // debug("idx=%d, offset=%d, randomCap=%f, actualCap=%f", bondedIdx, offset, randomLinkCapacity, _paths[_realIdxMap[bondedIdx]].relativeLinkCapacity);
+ if (! _paths[_realIdxMap[bondedIdx]].p) {
+ continue;
+ }
+ if (! _paths[_realIdxMap[bondedIdx]].shouldAvoid && randomLinkCapacity <= _paths[_realIdxMap[bondedIdx]].relativeLinkCapacity) {
+ // debug(" assign out-flow %04x to link %s (%u / %zu flows)", flow->id, pathToStr(_paths[_realIdxMap[bondedIdx]].p).c_str(), _paths[_realIdxMap[bondedIdx]].assignedFlowCount, _flows.size());
+ break; // Acceptable -- No violation of quality spec
+ }
+ if (_paths[_realIdxMap[bondedIdx]].relativeQuality > bestQuality) {
+ bestQuality = _paths[_realIdxMap[bondedIdx]].relativeQuality;
+ nextBestQualIdx = bondedIdx;
+ // debug(" recording next-best link %f idx %d", _paths[_realIdxMap[bondedIdx]].relativeQuality, bondedIdx);
+ }
+ ++offset;
+ }
+ if (offset < _numBondedPaths) {
+ // We were (able) to find a path that didn't violate any of the user's quality requirements
+ flow->assignPath(_realIdxMap[bondedIdx], now);
+ ++(_paths[_realIdxMap[bondedIdx]].assignedFlowCount);
+ // debug(" ABLE to find optimal link %f idx %d", _paths[_realIdxMap[bondedIdx]].relativeQuality, bondedIdx);
+ }
+ else {
+ // We were (unable) to find a path that didn't violate at least one quality requirement, will choose next best option
+ flow->assignPath(_realIdxMap[nextBestQualIdx], now);
+ ++(_paths[_realIdxMap[nextBestQualIdx]].assignedFlowCount);
+ // debug(" UNABLE to find, will use link %f idx %d", _paths[_realIdxMap[nextBestQualIdx]].relativeQuality, nextBestQualIdx);
}
}
if (_policy == ZT_BOND_POLICY_ACTIVE_BACKUP) {
if (_abPathIdx == ZT_MAX_PEER_NETWORK_PATHS) {
- debug("unable to assign out-flow %x (no active backup link)", flow->id);
+ log("unable to assign out-flow %x (no active backup link)", flow->id);
}
flow->assignPath(_abPathIdx, now);
}
- debug("assign out-flow %04x to link %s (%lu / %lu flows)", flow->id, pathToStr(_paths[flow->assignedPath].p).c_str(), _paths[flow->assignedPath].assignedFlowCount, (unsigned long)_flows.size());
+ log("assign out-flow %04x to link %s (%u / %zu flows)", flow->id, pathToStr(_paths[flow->assignedPath].p).c_str(), _paths[flow->assignedPath].assignedFlowCount, _flows.size());
return true;
}
SharedPtr Bond::createFlow(int pathIdx, int32_t flowId, unsigned char entropy, int64_t now)
{
if (! _numBondedPaths) {
- debug("unable to assign flow %x (bond has no links)\n", flowId);
+ debug("unable to assign flow %04x (bond has no links)", flowId);
return SharedPtr();
}
if (_flows.size() >= ZT_FLOW_MAX_COUNT) {
- debug("forget oldest flow (max flows reached: %d)\n", ZT_FLOW_MAX_COUNT);
+ debug("forget oldest flow (max flows reached: %d)", ZT_FLOW_MAX_COUNT);
forgetFlowsWhenNecessary(0, true, now);
}
SharedPtr flow = new Flow(flowId, now);
@@ -614,7 +661,7 @@ SharedPtr Bond::createFlow(int pathIdx, int32_t flowId, unsigned cha
if (pathIdx != ZT_MAX_PEER_NETWORK_PATHS) {
flow->assignPath(pathIdx, now);
_paths[pathIdx].assignedFlowCount++;
- debug("assign in-flow %x to link %s (%lu / %lu)", flow->id, pathToStr(_paths[pathIdx].p).c_str(), _paths[pathIdx].assignedFlowCount, (unsigned long)_flows.size());
+ debug("assign in-flow %04x to link %s (%u / %zu)", flow->id, pathToStr(_paths[pathIdx].p).c_str(), _paths[pathIdx].assignedFlowCount, _flows.size());
}
/**
* Add a flow when no path was provided. This means that it is an outgoing packet
@@ -628,13 +675,13 @@ SharedPtr Bond::createFlow(int pathIdx, int32_t flowId, unsigned cha
void Bond::forgetFlowsWhenNecessary(uint64_t age, bool oldest, int64_t now)
{
- std::map >::iterator it = _flows.begin();
- std::map >::iterator oldestFlow = _flows.end();
+ std::map >::iterator it = _flows.begin();
+ std::map >::iterator oldestFlow = _flows.end();
SharedPtr expiredFlow;
if (age) { // Remove by specific age
while (it != _flows.end()) {
if (it->second->age(now) > age) {
- debug("forget flow %x (age %llu) (%lu / %lu)", it->first, (unsigned long long)it->second->age(now), _paths[it->second->assignedPath].assignedFlowCount, (unsigned long)(_flows.size() - 1));
+ debug("forget flow %04x (age %" PRId64 ") (%u / %zu)", it->first, it->second->age(now), _paths[it->second->assignedPath].assignedFlowCount, (_flows.size() - 1));
_paths[it->second->assignedPath].assignedFlowCount--;
it = _flows.erase(it);
}
@@ -653,7 +700,7 @@ void Bond::forgetFlowsWhenNecessary(uint64_t age, bool oldest, int64_t now)
++it;
}
if (oldestFlow != _flows.end()) {
- debug("forget oldest flow %x (age %llu) (total flows: %lu)", oldestFlow->first, (unsigned long long)oldestFlow->second->age(now), (unsigned long)(_flows.size() - 1));
+ debug("forget oldest flow %04x (age %" PRId64 ") (total flows: %zu)", oldestFlow->first, oldestFlow->second->age(now), _flows.size() - 1);
_paths[oldestFlow->second->assignedPath].assignedFlowCount--;
_flows.erase(oldestFlow);
}
@@ -778,7 +825,7 @@ void Bond::sendACK(void* tPtr, int pathIdx, int64_t localSocket, const InetAddre
bytesToAck += it->second;
++it;
}
- debug("sending ACK of %d bytes on path %s (table size = %d)", bytesToAck, pathToStr(_paths[pathIdx].p).c_str(), _paths[pathIdx].ackStatsIn.size());
+ debug("sending ACK of %d bytes on path %s (table size = %zu)", bytesToAck, pathToStr(_paths[pathIdx].p).c_str(), _paths[pathIdx].ackStatsIn.size());
outp.append(bytesToAck);
if (atAddress) {
outp.armor(_peer->key(), false, _peer->aesKeysIfSupported());
@@ -799,8 +846,8 @@ void Bond::sendQOS_MEASUREMENT(void* tPtr, int pathIdx, int64_t localSocket, con
Packet outp(_peer->_id.address(), RR->identity.address(), Packet::VERB_QOS_MEASUREMENT);
char qosData[ZT_QOS_MAX_PACKET_SIZE];
int16_t len = generateQoSPacket(pathIdx, _now, qosData);
- // debug("sending QOS via link %s (len=%d)", pathToStr(_paths[pathIdx].p).c_str(), len);
if (len) {
+ // debug("sending QOS via link %s (len=%d)", pathToStr(_paths[pathIdx].p).c_str(), len);
outp.append(qosData, len);
if (atAddress) {
outp.armor(_peer->key(), false, _peer->aesKeysIfSupported());
@@ -817,6 +864,9 @@ void Bond::sendQOS_MEASUREMENT(void* tPtr, int pathIdx, int64_t localSocket, con
void Bond::processBackgroundBondTasks(void* tPtr, int64_t now)
{
+ if (! _run) {
+ return;
+ }
if (! _peer->_localMultipathSupported || (now - _lastBackgroundTaskCheck) < ZT_BOND_BACKGROUND_TASK_MIN_INTERVAL) {
return;
}
@@ -842,7 +892,7 @@ void Bond::processBackgroundBondTasks(void* tPtr, int64_t now)
RR->node->putPacket(tPtr, _paths[i].p->localSocket(), _paths[i].p->address(), outp.data(), outp.size());
_paths[i].p->_lastOut = now;
_overheadBytes += outp.size();
- debug("tx: verb 0x%-2x of len %4d via %s (ECHO)", Packet::VERB_ECHO, outp.size(), pathToStr(_paths[i].p).c_str());
+ // debug("tx: verb 0x%-2x of len %4d via %s (ECHO)", Packet::VERB_ECHO, outp.size(), pathToStr(_paths[i].p).c_str());
}
}
// QOS
@@ -895,17 +945,21 @@ void Bond::curateBond(int64_t now, bool rebuildBond)
continue;
}
+ // Whether this path is still in its trial period
+ bool inTrial = (now - _paths[i].whenNominated) < ZT_BOND_OPTIMIZE_INTERVAL;
+
/**
* Remove expired or invalid links from bond
*/
SharedPtr link = getLink(_paths[i].p);
if (! link) {
log("link is no longer valid, removing from bond");
+ _paths[i].p->_valid = false;
_paths[i] = NominatedPath();
_paths[i].p = SharedPtr();
continue;
}
- if ((now - _paths[i].p->_lastIn) > (ZT_PEER_EXPIRED_PATH_TRIAL_PERIOD)) {
+ if ((now - _paths[i].lastEligibility) > (ZT_PEER_EXPIRED_PATH_TRIAL_PERIOD) && ! inTrial) {
log("link (%s) has expired or is invalid, removing from bond", pathToStr(_paths[i].p).c_str());
_paths[i] = NominatedPath();
_paths[i].p = SharedPtr();
@@ -930,14 +984,13 @@ void Bond::curateBond(int64_t now, bool rebuildBond)
bool acceptableAge = _isLeaf ? (_paths[i].p->age(now) < (_failoverInterval + _downDelay)) : _paths[i].alive;
// Whether we've waited long enough since the link last came online
bool satisfiedUpDelay = (now - _paths[i].lastAliveToggle) >= _upDelay;
- // Whether this path is still in its trial period
- bool inTrial = (now - _paths[i].whenNominated) < ZT_BOND_OPTIMIZE_INTERVAL;
- // if (includeRefractoryPeriod && _paths[i].refractoryPeriod) {
- // As long as the refractory period value has not fully drained this path is not eligible
- // currEligibility = false;
- //}
- currEligibility = _paths[i].allowed() && ((acceptableAge && satisfiedUpDelay) || inTrial);
- // debug("[%d] allowed=%d, acceptableAge=%d, satisfiedUpDelay=%d, inTrial=%d ==== %d", i, _paths[i].allowed(), acceptableAge, satisfiedUpDelay, inTrial, currEligibility);
+ // How long since the last QoS was received (Must be less than ZT_PEER_PATH_EXPIRATION since the remote peer's _qosSendInterval isn't known)
+ bool acceptableQoSAge = _paths[i].lastQoSReceived == 0 || ((now - _paths[i].lastQoSReceived) < ZT_PEER_EXPIRED_PATH_TRIAL_PERIOD);
+ currEligibility = _paths[i].allowed() && ((acceptableAge && satisfiedUpDelay && acceptableQoSAge) || inTrial);
+
+ if (currEligibility) {
+ _paths[i].lastEligibility = now;
+ }
/**
* Note eligibility state change (if any) and take appropriate action
@@ -949,6 +1002,7 @@ void Bond::curateBond(int64_t now, bool rebuildBond)
if (currEligibility == 1) {
log("link %s is eligible", pathToStr(_paths[i].p).c_str());
}
+ debug("\t[%d] allowed=%d, age=%d, qa=%d, ud=%d, trial=%d", i, _paths[i].allowed(), acceptableAge, acceptableQoSAge, satisfiedUpDelay, inTrial);
dumpPathStatus(now, i);
if (currEligibility) {
rebuildBond = true;
@@ -956,11 +1010,9 @@ void Bond::curateBond(int64_t now, bool rebuildBond)
if (! currEligibility) {
_paths[i].adjustRefractoryPeriod(now, _defaultPathRefractoryPeriod, ! currEligibility);
if (_paths[i].bonded) {
- if (_allowFlowHashing) {
- debug("link %s was bonded, flow reallocation will occur soon", pathToStr(_paths[i].p).c_str());
- rebuildBond = true;
- _paths[i].shouldReallocateFlows = _paths[i].bonded;
- }
+ debug("link %s was bonded, flow reallocation will occur soon", pathToStr(_paths[i].p).c_str());
+ rebuildBond = true;
+ _paths[i].shouldAvoid = true;
_paths[i].bonded = false;
}
}
@@ -980,6 +1032,18 @@ void Bond::curateBond(int64_t now, bool rebuildBond)
dumpInfo(now, true);
}
+ /**
+ * Check for failure of (all) primary links and inform bond to use spares if present
+ */
+ bool foundUsablePrimaryPath = false;
+ for (int i = 0; i < ZT_MAX_PEER_NETWORK_PATHS; ++i) {
+ // debug("[%d], bonded=%d, alive=%d", i, _paths[i].bonded , _paths[i].alive);
+ if (_paths[i].p && _paths[i].bonded && _paths[i].alive) {
+ foundUsablePrimaryPath = true;
+ }
+ }
+ rebuildBond = rebuildBond ? true : ! foundUsablePrimaryPath;
+
/**
* Curate the set of paths that are part of the bond proper. Select a set of paths
* per logical link according to eligibility and user-specified constraints.
@@ -989,7 +1053,12 @@ void Bond::curateBond(int64_t now, bool rebuildBond)
rebuildBond = true;
}
if (rebuildBond) {
- debug("rebuilding bond");
+ // Clear previous bonded index mapping
+ for (int i = 0; i < ZT_MAX_PEER_NETWORK_PATHS; ++i) {
+ _realIdxMap[i] = ZT_MAX_PEER_NETWORK_PATHS;
+ _paths[i].bonded = false;
+ }
+
int updatedBondedPathCount = 0;
// Build map associating paths with local physical links. Will be selected from in next step
std::map, std::vector > linkMap;
@@ -1005,13 +1074,28 @@ void Bond::curateBond(int64_t now, bool rebuildBond)
std::map, std::vector >::iterator it = linkMap.begin();
while (it != linkMap.end()) {
SharedPtr link = it->first;
+
+ // Bond a spare link if required (no viable primary links left)
+ if (! foundUsablePrimaryPath) {
+ debug("no usable primary links remain, will attempt to use spare if available");
+ for (int j = 0; j < it->second.size(); j++) {
+ int idx = it->second.at(j);
+ if (! _paths[idx].p || ! _paths[idx].eligible || ! _paths[idx].allowed() || ! _paths[idx].isSpare()) {
+ continue;
+ }
+ addPathToBond(idx, updatedBondedPathCount);
+ ++updatedBondedPathCount;
+ debug("add %s (spare)", pathToStr(_paths[idx].p).c_str());
+ }
+ }
+
int ipvPref = link->ipvPref();
// If user has no address type preference, then use every path we find on a link
if (ipvPref == 0) {
for (int j = 0; j < it->second.size(); j++) {
int idx = it->second.at(j);
- if (! _paths[idx].p || ! _paths[idx].eligible || ! _paths[idx].allowed()) {
+ if (! _paths[idx].p || ! _paths[idx].eligible || ! _paths[idx].allowed() || _paths[idx].isSpare()) {
continue;
}
addPathToBond(idx, updatedBondedPathCount);
@@ -1023,7 +1107,7 @@ void Bond::curateBond(int64_t now, bool rebuildBond)
if (ipvPref == 4 || ipvPref == 6) {
for (int j = 0; j < it->second.size(); j++) {
int idx = it->second.at(j);
- if (! _paths[idx].p || ! _paths[idx].eligible) {
+ if (! _paths[idx].p || ! _paths[idx].eligible || _paths[idx].isSpare()) {
continue;
}
if (! _paths[idx].allowed()) {
@@ -1042,7 +1126,7 @@ void Bond::curateBond(int64_t now, bool rebuildBond)
// Search for preferred paths
for (int j = 0; j < it->second.size(); j++) {
int idx = it->second.at(j);
- if (! _paths[idx].p || ! _paths[idx].eligible || ! _paths[idx].allowed()) {
+ if (! _paths[idx].p || ! _paths[idx].eligible || ! _paths[idx].allowed() || _paths[idx].isSpare()) {
continue;
}
if (_paths[idx].preferred()) {
@@ -1057,7 +1141,7 @@ void Bond::curateBond(int64_t now, bool rebuildBond)
debug("did not find first-choice path type on link %s (user preference %d)", link->ifname().c_str(), ipvPref);
for (int j = 0; j < it->second.size(); j++) {
int idx = it->second.at(j);
- if (! _paths[idx].p || ! _paths[idx].eligible) {
+ if (! _paths[idx].p || ! _paths[idx].eligible || _paths[idx].isSpare()) {
continue;
}
addPathToBond(idx, updatedBondedPathCount);
@@ -1073,6 +1157,7 @@ void Bond::curateBond(int64_t now, bool rebuildBond)
if (_policy == ZT_BOND_POLICY_BALANCE_RR) {
// Cause a RR reset since the current index might no longer be valid
_rrPacketsSentOnCurrLink = _packetsPerLink;
+ _rrIdx = 0;
}
}
}
@@ -1080,26 +1165,6 @@ void Bond::curateBond(int64_t now, bool rebuildBond)
void Bond::estimatePathQuality(int64_t now)
{
- uint32_t totUserSpecifiedLinkSpeed = 0;
- if (_numBondedPaths) { // Compute relative user-specified speeds of links
- for (unsigned int i = 0; i < _numBondedPaths; ++i) {
- if (_paths[i].p && _paths[i].allowed()) {
- SharedPtr link = RR->bc->getLinkBySocket(_policyAlias, _paths[i].p->localSocket());
- if (link) {
- totUserSpecifiedLinkSpeed += link->speed();
- }
- }
- }
- for (unsigned int i = 0; i < _numBondedPaths; ++i) {
- if (_paths[i].p && _paths[i].allowed()) {
- SharedPtr link = RR->bc->getLinkBySocket(_policyAlias, _paths[i].p->localSocket());
- if (link) {
- link->setRelativeSpeed((uint8_t)round(((float)link->speed() / (float)totUserSpecifiedLinkSpeed) * 255));
- }
- }
- }
- }
-
float lat[ZT_MAX_PEER_NETWORK_PATHS] = { 0 };
float pdv[ZT_MAX_PEER_NETWORK_PATHS] = { 0 };
float plr[ZT_MAX_PEER_NETWORK_PATHS] = { 0 };
@@ -1110,30 +1175,15 @@ void Bond::estimatePathQuality(int64_t now)
float maxPLR = 0;
float maxPER = 0;
- float quality[ZT_MAX_PEER_NETWORK_PATHS] = { 0 };
- uint8_t alloc[ZT_MAX_PEER_NETWORK_PATHS] = { 0 };
+ float absoluteQuality[ZT_MAX_PEER_NETWORK_PATHS] = { 0 };
float totQuality = 0.0f;
- // Compute initial summary statistics
+ // Process observation samples, compute summary statistics, and compute relative link qualities
for (unsigned int i = 0; i < ZT_MAX_PEER_NETWORK_PATHS; ++i) {
if (! _paths[i].p || ! _paths[i].allowed()) {
continue;
}
- // Compute/Smooth average of real-world observations
- _paths[i].latencyMean = _paths[i].latencySamples.mean();
- _paths[i].latencyVariance = _paths[i].latencySamples.stddev();
- //_paths[i].packetErrorRatio = 1.0 - (_paths[i].packetValiditySamples.count() ? _paths[i].packetValiditySamples.mean() : 1.0);
-
- if (userHasSpecifiedLinkSpeeds()) {
- // Use user-reported metrics
- SharedPtr link = RR->bc->getLinkBySocket(_policyAlias, _paths[i].p->localSocket());
- if (link) {
- _paths[i].throughputMean = link->speed();
- _paths[i].throughputVariance = 0;
- }
- }
-
// Drain unacknowledged QoS records
int qosRecordTimeout = (_qosSendInterval * 3);
std::map::iterator it = _paths[i].qosStatsOut.begin();
@@ -1148,7 +1198,7 @@ void Bond::estimatePathQuality(int64_t now)
}
}
if (numDroppedQosOutRecords) {
- log("Dropped %d QOS out-records", numDroppedQosOutRecords);
+ // debug("dropped %d QOS out-records", numDroppedQosOutRecords);
}
/*
@@ -1177,116 +1227,183 @@ void Bond::estimatePathQuality(int64_t now)
}
}
if (numDroppedQosInRecords) {
- log("Dropped %d QOS in-records", numDroppedQosInRecords);
+ // debug("dropped %d QOS in-records", numDroppedQosInRecords);
}
- quality[i] = 0;
+ absoluteQuality[i] = 0;
totQuality = 0;
// Normalize raw observations according to sane limits and/or user specified values
- lat[i] = 1.0 / expf(4 * Utils::normalize(_paths[i].latencyMean, 0, _maxAcceptableLatency, 0, 1));
- pdv[i] = 1.0 / expf(4 * Utils::normalize(_paths[i].latencyVariance, 0, _maxAcceptablePacketDelayVariance, 0, 1));
- plr[i] = 1.0 / expf(4 * Utils::normalize(_paths[i].packetLossRatio, 0, _maxAcceptablePacketLossRatio, 0, 1));
- per[i] = 1.0 / expf(4 * Utils::normalize(_paths[i].packetErrorRatio, 0, _maxAcceptablePacketErrorRatio, 0, 1));
+ lat[i] = 1.0 / expf(4 * Utils::normalize(_paths[i].latency, 0, _qw[ZT_QOS_LAT_MAX_IDX], 0, 1));
+ pdv[i] = 1.0 / expf(4 * Utils::normalize(_paths[i].latencyVariance, 0, _qw[ZT_QOS_PDV_MAX_IDX], 0, 1));
+ plr[i] = 1.0 / expf(4 * Utils::normalize(_paths[i].packetLossRatio, 0, _qw[ZT_QOS_PLR_MAX_IDX], 0, 1));
+ per[i] = 1.0 / expf(4 * Utils::normalize(_paths[i].packetErrorRatio, 0, _qw[ZT_QOS_PER_MAX_IDX], 0, 1));
// Record bond-wide maximums to determine relative values
maxLAT = lat[i] > maxLAT ? lat[i] : maxLAT;
maxPDV = pdv[i] > maxPDV ? pdv[i] : maxPDV;
maxPLR = plr[i] > maxPLR ? plr[i] : maxPLR;
maxPER = per[i] > maxPER ? per[i] : maxPER;
}
+
+ // Compute relative user-specified link capacities (may change during life of Bond)
+ int maxObservedLinkCap = 0;
+ // Find current maximum
+ for (unsigned int i = 0; i < ZT_MAX_PEER_NETWORK_PATHS; ++i) {
+ if (_paths[i].p && _paths[i].allowed()) {
+ SharedPtr link = RR->bc->getLinkBySocket(_policyAlias, _paths[i].p->localSocket());
+ if (link) {
+ int linkSpeed = link->capacity();
+ _paths[i].p->_givenLinkSpeed = linkSpeed;
+ maxObservedLinkCap = linkSpeed > maxObservedLinkCap ? linkSpeed : maxObservedLinkCap;
+ }
+ }
+ }
+ // Compute relative link capacity (Used for weighting traffic allocations)
+ for (unsigned int i = 0; i < ZT_MAX_PEER_NETWORK_PATHS; ++i) {
+ if (_paths[i].p && _paths[i].allowed()) {
+ SharedPtr link = RR->bc->getLinkBySocket(_policyAlias, _paths[i].p->localSocket());
+ if (link) {
+ float relativeCapacity = (link->capacity() / (float)maxObservedLinkCap);
+ link->setRelativeCapacity(relativeCapacity);
+ _paths[i].relativeLinkCapacity = relativeCapacity;
+ }
+ }
+ }
+
// Convert metrics to relative quantities and apply contribution weights
for (unsigned int i = 0; i < ZT_MAX_PEER_NETWORK_PATHS; ++i) {
if (_paths[i].p && _paths[i].bonded) {
- quality[i] += ((maxLAT > 0.0f ? lat[i] / maxLAT : 0.0f) * _qw[ZT_QOS_LAT_IDX]);
- quality[i] += ((maxPDV > 0.0f ? pdv[i] / maxPDV : 0.0f) * _qw[ZT_QOS_PDV_IDX]);
- quality[i] += ((maxPLR > 0.0f ? plr[i] / maxPLR : 0.0f) * _qw[ZT_QOS_PLR_IDX]);
- quality[i] += ((maxPER > 0.0f ? per[i] / maxPER : 0.0f) * _qw[ZT_QOS_PER_IDX]);
- totQuality += quality[i];
+ absoluteQuality[i] += ((maxLAT > 0.0f ? lat[i] / maxLAT : 0.0f) * _qw[ZT_QOS_LAT_WEIGHT_IDX]);
+ absoluteQuality[i] += ((maxPDV > 0.0f ? pdv[i] / maxPDV : 0.0f) * _qw[ZT_QOS_PDV_WEIGHT_IDX]);
+ absoluteQuality[i] += ((maxPLR > 0.0f ? plr[i] / maxPLR : 0.0f) * _qw[ZT_QOS_PLR_WEIGHT_IDX]);
+ absoluteQuality[i] += ((maxPER > 0.0f ? per[i] / maxPER : 0.0f) * _qw[ZT_QOS_PER_WEIGHT_IDX]);
+ absoluteQuality[i] *= _paths[i].relativeLinkCapacity;
+ totQuality += absoluteQuality[i];
}
}
- // Normalize to 8-bit allocation values
+
+ // Compute quality of link relative to all others in the bond (also accounting for stated link capacity)
+ if (totQuality > 0.0) {
+ for (unsigned int i = 0; i < ZT_MAX_PEER_NETWORK_PATHS; ++i) {
+ if (_paths[i].p && _paths[i].bonded) {
+ _paths[i].relativeQuality = absoluteQuality[i] / totQuality;
+ // debug("[%2d], abs=%f, tot=%f, rel=%f, relcap=%f", i, absoluteQuality[i], totQuality, _paths[i].relativeQuality, _paths[i].relativeLinkCapacity);
+ }
+ }
+ }
+
+ // Compute summary statistics
for (unsigned int i = 0; i < ZT_MAX_PEER_NETWORK_PATHS; ++i) {
- if (_paths[i].p && _paths[i].bonded) {
- alloc[i] = (uint8_t)(std::ceil((quality[i] / totQuality) * (float)255));
- _paths[i].allocation = alloc[i];
+ if (! _paths[i].p || ! _paths[i].allowed()) {
+ continue;
+ }
+ // Compute/Smooth average of real-world observations
+ if (_paths[i].latencySamples.count() == ZT_QOS_SHORTTERM_SAMPLE_WIN_SIZE) {
+ _paths[i].latency = _paths[i].latencySamples.mean();
+ }
+ if (_paths[i].latencySamples.count() == ZT_QOS_SHORTTERM_SAMPLE_WIN_SIZE) {
+ _paths[i].latencyVariance = _paths[i].latencySamples.stddev();
+ }
+
+ // Write values to external path object so that it can be propagated to the user
+ _paths[i].p->_latencyMean = _paths[i].latency;
+ _paths[i].p->_latencyVariance = _paths[i].latencyVariance;
+ _paths[i].p->_packetLossRatio = _paths[i].packetLossRatio;
+ _paths[i].p->_packetErrorRatio = _paths[i].packetErrorRatio;
+ _paths[i].p->_bonded = _paths[i].bonded;
+ _paths[i].p->_eligible = _paths[i].eligible;
+ //_paths[i].packetErrorRatio = 1.0 - (_paths[i].packetValiditySamples.count() ? _paths[i].packetValiditySamples.mean() : 1.0);
+ // _valid is written elsewhere
+ _paths[i].p->_relativeQuality = _paths[i].relativeQuality;
+ }
+
+ // Flag links for avoidance
+ for (unsigned int i = 0; i < ZT_MAX_PEER_NETWORK_PATHS; ++i) {
+ if (! _paths[i].p || ! _paths[i].allowed()) {
+ continue;
+ }
+ bool shouldAvoid = false;
+ if (! _paths[i].shouldAvoid) {
+ if (_paths[i].latency > _qw[ZT_QOS_LAT_MAX_IDX]) {
+ log("avoiding link %s because (lat %6.4f > %6.4f)", pathToStr(_paths[i].p).c_str(), _paths[i].latency, _qw[ZT_QOS_LAT_MAX_IDX]);
+ shouldAvoid = true;
+ }
+ if (_paths[i].latencyVariance > _qw[ZT_QOS_PDV_MAX_IDX]) {
+ log("avoiding link %s because (pdv %6.4f > %6.4f)", pathToStr(_paths[i].p).c_str(), _paths[i].latencyVariance, _qw[ZT_QOS_PDV_MAX_IDX]);
+ shouldAvoid = true;
+ }
+ if (_paths[i].packetErrorRatio > _qw[ZT_QOS_PER_MAX_IDX]) {
+ log("avoiding link %s because (per %6.4f > %6.4f)", pathToStr(_paths[i].p).c_str(), _paths[i].packetErrorRatio, _qw[ZT_QOS_PER_MAX_IDX]);
+ shouldAvoid = true;
+ }
+ if (_paths[i].packetLossRatio > _qw[ZT_QOS_PLR_MAX_IDX]) {
+ log("avoiding link %s because (plr %6.4f > %6.4f)", pathToStr(_paths[i].p).c_str(), _paths[i].packetLossRatio, _qw[ZT_QOS_PLR_MAX_IDX]);
+ shouldAvoid = true;
+ }
+ _paths[i].shouldAvoid = shouldAvoid;
+ }
+ else {
+ if (! shouldAvoid) {
+ log("no longer avoiding link %s", pathToStr(_paths[i].p).c_str());
+ _paths[i].shouldAvoid = false;
+ }
}
}
}
void Bond::processBalanceTasks(int64_t now)
{
- if (_allowFlowHashing) {
- /**
- * Clean up and reset flows if necessary
- */
- if ((now - _lastFlowExpirationCheck) > ZT_PEER_PATH_EXPIRATION) {
- Mutex::Lock _l(_flows_m);
- forgetFlowsWhenNecessary(ZT_PEER_PATH_EXPIRATION, false, now);
- std::map >::iterator it = _flows.begin();
- while (it != _flows.end()) {
- it->second->resetByteCounts();
- ++it;
- }
- _lastFlowExpirationCheck = now;
+ if (! _numBondedPaths) {
+ return;
+ }
+ /**
+ * Clean up and reset flows if necessary
+ */
+ if ((now - _lastFlowExpirationCheck) > ZT_PEER_PATH_EXPIRATION) {
+ Mutex::Lock _l(_flows_m);
+ forgetFlowsWhenNecessary(ZT_PEER_PATH_EXPIRATION, false, now);
+ std::map >::iterator it = _flows.begin();
+ while (it != _flows.end()) {
+ it->second->resetByteCounts();
+ ++it;
}
- /**
- * Re-allocate flows from dead paths
- */
- if (_policy == ZT_BOND_POLICY_BALANCE_XOR || _policy == ZT_BOND_POLICY_BALANCE_AWARE) {
- Mutex::Lock _l(_flows_m);
- for (int i = 0; i < ZT_MAX_PEER_NETWORK_PATHS; ++i) {
- if (! _paths[i].p) {
- continue;
- }
- if (! _paths[i].eligible && _paths[i].shouldReallocateFlows) {
- log("reallocate flows from dead link %s", pathToStr(_paths[i].p).c_str());
- std::map >::iterator flow_it = _flows.begin();
- while (flow_it != _flows.end()) {
- if (_paths[flow_it->second->assignedPath].p == _paths[i].p) {
- if (assignFlowToBondedPath(flow_it->second, now)) {
- _paths[i].assignedFlowCount--;
- }
- }
- ++flow_it;
+ _lastFlowExpirationCheck = now;
+ }
+ /**
+ * Move (all) flows from dead paths
+ */
+ if (_policy == ZT_BOND_POLICY_BALANCE_XOR || _policy == ZT_BOND_POLICY_BALANCE_AWARE) {
+ Mutex::Lock _l(_flows_m);
+ std::map >::iterator flow_it = _flows.begin();
+ while (flow_it != _flows.end()) {
+ if (_paths[flow_it->second->assignedPath].p) {
+ int originalPathIdx = flow_it->second->assignedPath;
+ if (! _paths[originalPathIdx].eligible) {
+ log("moving all flows from dead link %s", pathToStr(_paths[originalPathIdx].p).c_str());
+ if (assignFlowToBondedPath(flow_it->second, now, true)) {
+ _paths[originalPathIdx].assignedFlowCount--;
}
- _paths[i].shouldReallocateFlows = false;
}
}
+ ++flow_it;
}
- /**
- * Re-allocate flows from under-performing
- * NOTE: This could be part of the above block but was kept separate for clarity.
- */
- if (_policy == ZT_BOND_POLICY_BALANCE_AWARE) {
- int totalAllocation = 0;
- for (int i = 0; i < ZT_MAX_PEER_NETWORK_PATHS; ++i) {
- if (! _paths[i].p) {
- continue;
- }
- if (_paths[i].p && _paths[i].bonded && _paths[i].eligible) {
- totalAllocation += _paths[i].allocation;
- }
- }
- unsigned char minimumAllocationValue = (uint8_t)(0.33 * ((float)totalAllocation / (float)_numBondedPaths));
-
- Mutex::Lock _l(_flows_m);
- for (int i = 0; i < ZT_MAX_PEER_NETWORK_PATHS; ++i) {
- if (! _paths[i].p) {
- continue;
- }
- if (_paths[i].p && _paths[i].bonded && _paths[i].eligible && (_paths[i].allocation < minimumAllocationValue) && _paths[i].assignedFlowCount) {
- log("reallocate flows from under-performing link %s\n", pathToStr(_paths[i].p).c_str());
- std::map >::iterator flow_it = _flows.begin();
- while (flow_it != _flows.end()) {
- if (flow_it->second->assignedPath == _paths[i].p) {
- if (assignFlowToBondedPath(flow_it->second, now)) {
- _paths[i].assignedFlowCount--;
- }
- }
- ++flow_it;
+ }
+ /**
+ * Move (some) flows from low quality paths
+ */
+ if (_policy == ZT_BOND_POLICY_BALANCE_AWARE) {
+ Mutex::Lock _l(_flows_m);
+ std::map >::iterator flow_it = _flows.begin();
+ while (flow_it != _flows.end()) {
+ if (_paths[flow_it->second->assignedPath].p) {
+ int originalPathIdx = flow_it->second->assignedPath;
+ if (_paths[originalPathIdx].shouldAvoid) {
+ if (assignFlowToBondedPath(flow_it->second, now, true)) {
+ _paths[originalPathIdx].assignedFlowCount--;
+ return; // Only move one flow at a time
}
- _paths[i].shouldReallocateFlows = false;
}
}
+ ++flow_it;
}
}
}
@@ -1405,10 +1522,6 @@ void Bond::processActiveBackupTasks(void* tPtr, int64_t now)
log("found non-preferred primary link");
_abPathIdx = nonPreferredPathIdx;
}
- if (_abPathIdx == ZT_MAX_PEER_NETWORK_PATHS) {
- log("user-designated primary link is not available");
- // TODO: Should wait for some time (failover interval?) and then switch to spare link
- }
}
else if (! userHasSpecifiedPrimaryLink()) {
@@ -1486,7 +1599,7 @@ void Bond::processActiveBackupTasks(void* tPtr, int64_t now)
}
if (! _paths[i].failoverScore) {
// If we didn't inherit a failover score from a "parent" that wants to use this path as a failover
- int newHandicap = failoverScoreHandicap ? failoverScoreHandicap : _paths[i].allocation;
+ int newHandicap = failoverScoreHandicap ? failoverScoreHandicap : (_paths[i].relativeQuality * 255.0);
_paths[i].failoverScore = newHandicap;
}
SharedPtr failoverLink;
@@ -1555,7 +1668,7 @@ void Bond::processActiveBackupTasks(void* tPtr, int64_t now)
_paths[i].negotiated = false;
}
*/
- _paths[i].failoverScore = _paths[i].allocation + failoverScoreHandicap;
+ _paths[i].failoverScore = _paths[i].relativeQuality + failoverScoreHandicap;
if (_paths[i].p.ptr() != _paths[_abPathIdx].p.ptr()) {
bool bFoundPathInQueue = false;
for (std::deque::iterator it(_abFailoverQueue.begin()); it != _abFailoverQueue.end(); ++it) {
@@ -1655,7 +1768,7 @@ void Bond::processActiveBackupTasks(void* tPtr, int64_t now)
int prevFScore = _paths[_abPathIdx].failoverScore;
// Establish a minimum switch threshold to prevent flapping
int failoverScoreDifference = _paths[_abFailoverQueue.front()].failoverScore - _paths[_abPathIdx].failoverScore;
- int thresholdQuantity = (int)(ZT_BOND_ACTIVE_BACKUP_OPTIMIZE_MIN_THRESHOLD * (float)_paths[_abPathIdx].allocation);
+ int thresholdQuantity = (int)(ZT_BOND_ACTIVE_BACKUP_OPTIMIZE_MIN_THRESHOLD * (float)_paths[_abPathIdx].relativeQuality);
if ((failoverScoreDifference > 0) && (failoverScoreDifference > thresholdQuantity)) {
SharedPtr oldPath = _paths[_abPathIdx].p;
dequeueNextActiveBackupPath(now);
@@ -1689,17 +1802,14 @@ void Bond::setBondParameters(int policy, SharedPtr templateBond, bool useT
// Sanity check for policy
_defaultPolicy = (_defaultPolicy <= ZT_BOND_POLICY_NONE || _defaultPolicy > ZT_BOND_POLICY_BALANCE_AWARE) ? ZT_BOND_POLICY_NONE : _defaultPolicy;
- _policy = (policy <= ZT_BOND_POLICY_NONE || policy > ZT_BOND_POLICY_BALANCE_AWARE) ? ZT_BOND_POLICY_NONE : _defaultPolicy;
+ _policy = (policy <= ZT_BOND_POLICY_NONE || policy > ZT_BOND_POLICY_BALANCE_AWARE) ? _defaultPolicy : policy;
// Check if non-leaf to prevent spamming infrastructure
+ ZT_PeerRole role;
if (_peer) {
- ZT_PeerRole role = RR->topology->role(_peer->address());
- _isLeaf = (role != ZT_PEER_ROLE_PLANET && role != ZT_PEER_ROLE_MOON);
+ role = RR->topology->role(_peer->address());
}
-
- // Flows
-
- _allowFlowHashing = false;
+ _isLeaf = _peer ? (role != ZT_PEER_ROLE_PLANET && role != ZT_PEER_ROLE_MOON) : false;
// Path negotiation
@@ -1712,7 +1822,7 @@ void Bond::setBondParameters(int policy, SharedPtr templateBond, bool useT
_userHasSpecifiedPrimaryLink = false;
_userHasSpecifiedFailoverInstructions = false;
- _userHasSpecifiedLinkSpeeds = 0;
+ _userHasSpecifiedLinkCapacities = 0;
// Bond status
@@ -1720,63 +1830,36 @@ void Bond::setBondParameters(int policy, SharedPtr templateBond, bool useT
_numTotalLinks = 0;
_numBondedPaths = 0;
- // active-backup
-
- _abPathIdx = ZT_MAX_PEER_NETWORK_PATHS;
-
- // rr
-
- _rrPacketsSentOnCurrLink = 0;
- _rrIdx = 0;
-
// General parameters
_downDelay = 0;
_upDelay = 0;
_monitorInterval = 0;
- // (Sane?) limits
-
- _maxAcceptableLatency = 100;
- _maxAcceptablePacketDelayVariance = 50;
- _maxAcceptablePacketLossRatio = 0.10f;
- _maxAcceptablePacketErrorRatio = 0.10f;
-
// balance-aware
_totalBondUnderload = 0;
_overheadBytes = 0;
/**
- * Policy-specific defaults
+ * Policy defaults
*/
- switch (_policy) {
- case ZT_BOND_POLICY_ACTIVE_BACKUP:
- _abLinkSelectMethod = ZT_BOND_RESELECTION_POLICY_OPTIMIZE;
- break;
- case ZT_BOND_POLICY_BROADCAST:
- _downDelay = 30000;
- _upDelay = 0;
- break;
- case ZT_BOND_POLICY_BALANCE_RR:
- _packetsPerLink = 64;
- break;
- case ZT_BOND_POLICY_BALANCE_XOR:
- _allowFlowHashing = true;
- break;
- case ZT_BOND_POLICY_BALANCE_AWARE:
- _allowFlowHashing = true;
- break;
- default:
- break;
- }
+ _abPathIdx = ZT_MAX_PEER_NETWORK_PATHS;
+ _abLinkSelectMethod = ZT_BOND_RESELECTION_POLICY_OPTIMIZE;
+ _rrPacketsSentOnCurrLink = 0;
+ _rrIdx = 0;
+ _packetsPerLink = 64;
- _qw[ZT_QOS_LAT_IDX] = 0.3f;
- _qw[ZT_QOS_LTM_IDX] = 0.1f;
- _qw[ZT_QOS_PDV_IDX] = 0.3f;
- _qw[ZT_QOS_PLR_IDX] = 0.1f;
- _qw[ZT_QOS_PER_IDX] = 0.1f;
- _qw[ZT_QOS_SCP_IDX] = 0.1f;
+ // Sane quality defaults
+
+ _qw[ZT_QOS_LAT_MAX_IDX] = 500.0f;
+ _qw[ZT_QOS_PDV_MAX_IDX] = 100.0f;
+ _qw[ZT_QOS_PLR_MAX_IDX] = 0.001f;
+ _qw[ZT_QOS_PER_MAX_IDX] = 0.0001f;
+ _qw[ZT_QOS_LAT_WEIGHT_IDX] = 0.25f;
+ _qw[ZT_QOS_PDV_WEIGHT_IDX] = 0.25f;
+ _qw[ZT_QOS_PLR_WEIGHT_IDX] = 0.25f;
+ _qw[ZT_QOS_PER_WEIGHT_IDX] = 0.25f;
_failoverInterval = ZT_BOND_FAILOVER_DEFAULT_INTERVAL;
@@ -1788,7 +1871,8 @@ void Bond::setBondParameters(int policy, SharedPtr templateBond, bool useT
_downDelay = templateBond->_downDelay;
_upDelay = templateBond->_upDelay;
_abLinkSelectMethod = templateBond->_abLinkSelectMethod;
- memcpy(_qw, templateBond->_qw, ZT_QOS_WEIGHT_SIZE * sizeof(float));
+ memcpy(_qw, templateBond->_qw, ZT_QOS_PARAMETER_SIZE * sizeof(float));
+ debug("user link quality spec = {%6.3f, %6.3f, %6.3f, %6.3f, %6.3f, %6.3f, %6.3f, %6.3f}", _qw[0], _qw[1], _qw[2], _qw[3], _qw[4], _qw[5], _qw[6], _qw[7]);
}
if (! _isLeaf) {
@@ -1806,16 +1890,18 @@ void Bond::setBondParameters(int policy, SharedPtr templateBond, bool useT
_defaultPathRefractoryPeriod = 8000;
}
-void Bond::setUserQualityWeights(float weights[], int len)
+void Bond::setUserLinkQualitySpec(float weights[], int len)
{
- if (len == ZT_QOS_WEIGHT_SIZE) {
- float weightTotal = 0.0;
- for (unsigned int i = 0; i < ZT_QOS_WEIGHT_SIZE; ++i) {
- weightTotal += weights[i];
- }
- if (weightTotal > 0.99 && weightTotal < 1.01) {
- memcpy(_qw, weights, len * sizeof(float));
- }
+ if (len != ZT_QOS_PARAMETER_SIZE) {
+ debug("link quality spec has an invalid number of parameters (%d out of %d), ignoring", len, ZT_QOS_PARAMETER_SIZE);
+ return;
+ }
+ float weightTotal = 0.0;
+ for (unsigned int i = 4; i < ZT_QOS_PARAMETER_SIZE; ++i) {
+ weightTotal += weights[i];
+ }
+ if (weightTotal > 0.99 && weightTotal < 1.01) {
+ memcpy(_qw, weights, len * sizeof(float));
}
}
@@ -1834,7 +1920,7 @@ std::string Bond::pathToStr(const SharedPtr& path)
SharedPtr link = getLink(path);
if (link) {
std::string ifnameStr = std::string(link->ifname());
- snprintf(fullPathStr, 384, "%.16llx-%s/%s", (unsigned long long)(path->localSocket()), ifnameStr.c_str(), pathStr);
+ snprintf(fullPathStr, 384, "%.16" PRIx64 "-%s/%s", path->localSocket(), ifnameStr.c_str(), pathStr);
return std::string(fullPathStr);
}
}
@@ -1850,20 +1936,21 @@ void Bond::dumpPathStatus(int64_t now, int pathIdx)
std::string aliveOrDead = _paths[pathIdx].alive ? std::string("alive") : std::string("dead");
std::string eligibleOrNot = _paths[pathIdx].eligible ? std::string("eligible") : std::string("ineligible");
std::string bondedOrNot = _paths[pathIdx].bonded ? std::string("bonded") : std::string("unbonded");
- log("path[%2u] --- %5s (in %7lld, out: %7lld), %10s, %8s, flows=%-6u lat=%-8.3f pdv=%-7.3f err=%-6.4f loss=%-6.4f alloc=%-3u --- (%s)",
+ log("path[%2u] --- %5s (in %7" PRId64 ", out: %7" PRId64 "), %10s, %8s, flows=%-6u lat=%-8.3f pdv=%-7.3f err=%-6.4f loss=%-6.4f qual=%-6.4f --- (%s) spare=%d",
pathIdx,
aliveOrDead.c_str(),
- static_cast(_paths[pathIdx].p->age(now)),
- static_cast(_paths[pathIdx].p->_lastOut == 0 ? 0 : now - _paths[pathIdx].p->_lastOut),
+ _paths[pathIdx].p->age(now),
+ _paths[pathIdx].p->_lastOut == 0 ? static_cast(0) : now - _paths[pathIdx].p->_lastOut,
eligibleOrNot.c_str(),
bondedOrNot.c_str(),
_paths[pathIdx].assignedFlowCount,
- _paths[pathIdx].latencyMean,
+ _paths[pathIdx].latency,
_paths[pathIdx].latencyVariance,
_paths[pathIdx].packetErrorRatio,
_paths[pathIdx].packetLossRatio,
- _paths[pathIdx].allocation,
- pathToStr(_paths[pathIdx].p).c_str());
+ _paths[pathIdx].relativeQuality,
+ pathToStr(_paths[pathIdx].p).c_str(),
+ _paths[pathIdx].isSpare());
#endif
}
@@ -1877,13 +1964,13 @@ void Bond::dumpInfo(int64_t now, bool force)
_lastSummaryDump = now;
float overhead = (_overheadBytes / (timeSinceLastDump / 1000.0f) / 1000.0f);
_overheadBytes = 0;
- log("bond: bp=%d, fi=%d, mi=%d, ud=%d, dd=%d, flows=%lu, leaf=%d, overhead=%f KB/s, links=(%d/%d)",
+ log("bond: bp=%d, fi=%" PRIu64 ", mi=%d, ud=%d, dd=%d, flows=%zu, leaf=%d, overhead=%f KB/s, links=(%d/%d)",
_policy,
_failoverInterval,
_monitorInterval,
_upDelay,
_downDelay,
- (unsigned long)_flows.size(),
+ _flows.size(),
_isLeaf,
overhead,
_numAliveLinks,
diff --git a/node/Bond.hpp b/node/Bond.hpp
index bc7bd55c5..3419c8cfe 100644
--- a/node/Bond.hpp
+++ b/node/Bond.hpp
@@ -14,6 +14,7 @@
#ifndef ZT_BOND_HPP
#define ZT_BOND_HPP
+#include "../osdep/Binder.hpp"
#include "../osdep/Phy.hpp"
#include "Packet.hpp"
#include "Path.hpp"
@@ -28,7 +29,7 @@
/**
* Indices for the path quality weight vector
*/
-enum ZT_BondQualityWeightIndex { ZT_QOS_LAT_IDX, ZT_QOS_LTM_IDX, ZT_QOS_PDV_IDX, ZT_QOS_PLR_IDX, ZT_QOS_PER_IDX, ZT_QOS_THR_IDX, ZT_QOS_THM_IDX, ZT_QOS_THV_IDX, ZT_QOS_AGE_IDX, ZT_QOS_SCP_IDX, ZT_QOS_WEIGHT_SIZE };
+enum ZT_BondQualityWeightIndex { ZT_QOS_LAT_MAX_IDX, ZT_QOS_PDV_MAX_IDX, ZT_QOS_PLR_MAX_IDX, ZT_QOS_PER_MAX_IDX, ZT_QOS_LAT_WEIGHT_IDX, ZT_QOS_PDV_WEIGHT_IDX, ZT_QOS_PLR_WEIGHT_IDX, ZT_QOS_PER_WEIGHT_IDX, ZT_QOS_PARAMETER_SIZE };
/**
* Multipath bonding policy
@@ -116,21 +117,19 @@ class Link {
*
* @param ifnameStr
* @param ipvPref
- * @param speed
+ * @param capacity
* @param enabled
* @param mode
* @param failoverToLinkStr
- * @param userSpecifiedAlloc
*/
- Link(std::string ifnameStr, uint8_t ipvPref, uint32_t speed, bool enabled, uint8_t mode, std::string failoverToLinkStr, float userSpecifiedAlloc)
+ Link(std::string ifnameStr, uint8_t ipvPref, uint32_t capacity, bool enabled, uint8_t mode, std::string failoverToLinkStr)
: _ifnameStr(ifnameStr)
, _ipvPref(ipvPref)
- , _speed(speed)
- , _relativeSpeed(0)
+ , _capacity(capacity)
+ , _relativeCapacity(0.0)
, _enabled(enabled)
, _mode(mode)
, _failoverToLinkStr(failoverToLinkStr)
- , _userSpecifiedAlloc(userSpecifiedAlloc)
, _isUserSpecified(false)
{
}
@@ -194,29 +193,29 @@ class Link {
}
/**
- * @return The speed of the link relative to others in the bond.
+ * @return The capacity of the link relative to others in the bond.
*/
- inline uint8_t relativeSpeed()
+ inline float relativeCapacity()
{
- return _relativeSpeed;
+ return _relativeCapacity;
}
/**
- * Sets the speed of the link relative to others in the bond.
+ * Sets the capacity of the link relative to others in the bond.
*
- * @param relativeSpeed The speed relative to the rest of the link.
+ * @param relativeCapacity The capacity relative to the rest of the link.
*/
- inline void setRelativeSpeed(uint8_t relativeSpeed)
+ inline void setRelativeCapacity(float relativeCapacity)
{
- _relativeSpeed = relativeSpeed;
+ _relativeCapacity = relativeCapacity;
}
/**
- * @return The absolute speed of the link (as specified by the user.)
+ * @return The absolute capacity of the link (as specified by the user.)
*/
- inline uint32_t speed()
+ inline uint32_t capacity()
{
- return _speed;
+ return _capacity;
}
/**
@@ -262,14 +261,14 @@ class Link {
uint8_t _ipvPref;
/**
- * User-specified speed of this link
+ * User-specified capacity of this link
*/
- uint32_t _speed;
+ uint32_t _capacity;
/**
* Speed relative to other specified links (computed by Bond)
*/
- uint8_t _relativeSpeed;
+ float _relativeCapacity;
/**
* Whether this link is enabled, or (disabled (possibly bad config))
@@ -287,11 +286,6 @@ class Link {
*/
std::string _failoverToLinkStr;
- /**
- * User-specified allocation
- */
- float _userSpecifiedAlloc;
-
/**
* Whether or not this link was created as a result of manual user specification. This is
* important to know because certain policy decisions are dependent on whether the user
@@ -307,6 +301,17 @@ class Peer;
class Bond {
public:
+
+ /**
+ * Stop bond's internal functions (can be resumed)
+ */
+ void stopBond();
+
+ /**
+ * Start or resume a bond's internal functions
+ */
+ void startBond();
+
/**
* @return Whether this link is permitted to become a member of a bond.
*/
@@ -328,6 +333,14 @@ class Bond {
return ! _bondPolicyTemplates.empty() || _defaultPolicy;
}
+ /**
+ * Sets a pointer to an instance of _binder used by the Bond to get interface data
+ */
+ static void setBinder(Binder* b)
+ {
+ _binder = b;
+ }
+
/**
* @param basePolicyName Bonding policy name (See ZeroTierOne.h)
* @return The bonding policy code for a given human-readable bonding policy name
@@ -461,7 +474,7 @@ class Bond {
* @param createIfNeeded Whether a Link object is created if the name wasn't previously in the link map
* @return Physical link definition
*/
- static SharedPtr getLinkBySocket(const std::string& policyAlias, uint64_t localSocket, bool createIfNeeded);
+ SharedPtr getLinkBySocket(const std::string& policyAlias, uint64_t localSocket, bool createIfNeeded);
/**
* Gets a reference to a physical link definition given its human-readable system name.
@@ -573,6 +586,14 @@ class Bond {
return _policyAlias;
}
+ /**
+ * Return whether this bond is able to properly process traffic
+ */
+ bool isReady()
+ {
+ return _numBondedPaths;
+ }
+
/**
* Inform the bond about the path that its peer (owning object) just learned about.
* If the path is allowed to be used, it will be inducted into the bond on a trial
@@ -703,8 +724,9 @@ class Bond {
*
* @param flow Flow to be assigned
* @param now Current time
+ * @param reassign Whether this flow is being re-assigned to another path
*/
- bool assignFlowToBondedPath(SharedPtr& flow, int64_t now);
+ bool assignFlowToBondedPath(SharedPtr& flow, int64_t now, bool reassign);
/**
* Determine whether a path change should occur given the remote peer's reported utility and our
@@ -793,60 +815,12 @@ class Bond {
void setBondParameters(int policy, SharedPtr templateBond, bool useTemplate);
/**
- * Check and assign user-specified quality weights to this bond.
+ * Check and assign user-specified link quality parameters to this bond.
*
- * @param weights Set of user-specified weights
- * @param len Length of weight vector
+ * @param weights Set of user-specified parameters
+ * @param len Length of parameter vector
*/
- void setUserQualityWeights(float weights[], int len);
-
- /**
- * @param latencyInMilliseconds Maximum acceptable latency.
- */
- void setMaxAcceptableLatency(int16_t latencyInMilliseconds)
- {
- _maxAcceptableLatency = latencyInMilliseconds;
- }
-
- /**
- * @param latencyInMilliseconds Maximum acceptable (mean) latency.
- */
- void setMaxAcceptableMeanLatency(int16_t latencyInMilliseconds)
- {
- _maxAcceptableMeanLatency = latencyInMilliseconds;
- }
-
- /**
- * @param latencyVarianceInMilliseconds Maximum acceptable packet delay variance (jitter).
- */
- void setMaxAcceptablePacketDelayVariance(int16_t latencyVarianceInMilliseconds)
- {
- _maxAcceptablePacketDelayVariance = latencyVarianceInMilliseconds;
- }
-
- /**
- * @param lossRatio Maximum acceptable packet loss ratio (PLR).
- */
- void setMaxAcceptablePacketLossRatio(float lossRatio)
- {
- _maxAcceptablePacketLossRatio = lossRatio;
- }
-
- /**
- * @param errorRatio Maximum acceptable packet error ratio (PER).
- */
- void setMaxAcceptablePacketErrorRatio(float errorRatio)
- {
- _maxAcceptablePacketErrorRatio = errorRatio;
- }
-
- /**
- * @param errorRatio Maximum acceptable packet error ratio (PER).
- */
- void setMinAcceptableAllocation(float minAlloc)
- {
- _minAcceptableAllocation = (uint8_t)(minAlloc * 255);
- }
+ void setUserLinkQualitySpec(float weights[], int len);
/**
* @return Whether the user has defined links for use on this bond
@@ -873,11 +847,11 @@ class Bond {
}
/**
- * @return Whether the user has specified link speeds
+ * @return Whether the user has specified link capacities
*/
- inline bool userHasSpecifiedLinkSpeeds()
+ inline bool userHasSpecifiedLinkCapacities()
{
- return _userHasSpecifiedLinkSpeeds;
+ return _userHasSpecifiedLinkCapacities;
}
/**
@@ -916,10 +890,9 @@ class Bond {
*/
inline bool rateGateQoS(int64_t now, SharedPtr& path)
{
- // TODO: Verify before production
char pathStr[64] = { 0 };
path->address().toString(pathStr);
- int diff = now - _lastQoSRateCheck;
+ uint64_t diff = now - _lastQoSRateCheck;
if ((diff) <= (_qosSendInterval / ZT_MAX_PEER_NETWORK_PATHS)) {
++_qosCutoffCount;
}
@@ -927,7 +900,6 @@ class Bond {
_qosCutoffCount = 0;
}
_lastQoSRateCheck = now;
- // fprintf(stderr, "rateGateQoS (count=%d, send_interval=%d, diff=%d, path=%s)\n", _qosCutoffCount, _qosSendInterval, diff, pathStr);
return (_qosCutoffCount < (ZT_MAX_PEER_NETWORK_PATHS * 2));
}
@@ -939,7 +911,6 @@ class Bond {
*/
inline bool rateGatePathNegotiation(int64_t now, SharedPtr& path)
{
- // TODO: Verify before production
char pathStr[64] = { 0 };
path->address().toString(pathStr);
int diff = now - _lastPathNegotiationReceived;
@@ -950,7 +921,6 @@ class Bond {
_pathNegotiationCutoffCount = 0;
}
_lastPathNegotiationReceived = now;
- // fprintf(stderr, "rateGateNeg (count=%d, send_interval=%d, diff=%d, path=%s)\n", _pathNegotiationCutoffCount, (ZT_PATH_NEGOTIATION_CUTOFF_TIME / ZT_MAX_PEER_NETWORK_PATHS), diff, pathStr);
return (_pathNegotiationCutoffCount < (ZT_MAX_PEER_NETWORK_PATHS * 2));
}
@@ -970,14 +940,6 @@ class Bond {
return _failoverInterval;
}
- /**
- * @param strategy Strategy that the bond uses to re-assign protocol flows.
- */
- inline void setFlowRebalanceStrategy(uint32_t strategy)
- {
- _flowRebalanceStrategy = strategy;
- }
-
/**
* @param strategy Strategy that the bond uses to prob for path aliveness and quality
*/
@@ -1058,7 +1020,7 @@ class Bond {
}
/**
- * @return the number of links comprising this bond which are considered alive
+ * @return the number of links in this bond which are considered alive
*/
inline uint8_t getNumAliveLinks()
{
@@ -1066,7 +1028,7 @@ class Bond {
};
/**
- * @return the number of links comprising this bond
+ * @return the number of links in this bond
*/
inline uint8_t getNumTotalLinks()
{
@@ -1074,20 +1036,11 @@ class Bond {
}
/**
- *
- * @param allowFlowHashing
+ * @return Whether flow-hashing is currently supported for this bond.
*/
- inline void setFlowHashing(bool allowFlowHashing)
+ bool flowHashingSupported()
{
- _allowFlowHashing = allowFlowHashing;
- }
-
- /**
- * @return Whether flow-hashing is currently enabled for this bond.
- */
- bool flowHashingEnabled()
- {
- return _allowFlowHashing;
+ return _policy == ZT_BOND_POLICY_BALANCE_XOR || _policy == ZT_BOND_POLICY_BALANCE_AWARE;
}
/**
@@ -1150,25 +1103,8 @@ class Bond {
*/
bool abForciblyRotateLink();
- /**
- * @param now Current time
- * @return All known paths to this peer
- */
- inline std::vector > paths(const int64_t now) const
- {
- std::vector > pp;
- Mutex::Lock _l(_paths_m);
- for (unsigned int i = 0; i < ZT_MAX_PEER_NETWORK_PATHS; ++i) {
- if (! _paths[i].p)
- break;
- pp.push_back(_paths[i].p);
- }
- return pp;
- }
-
/**
* Emit message to tracing system but with added timestamp and subsystem info
- *
*/
void log(const char* fmt, ...)
#ifdef __GNUC__
@@ -1200,7 +1136,6 @@ class Bond {
/**
* Emit message to tracing system but with added timestamp and subsystem info
- *
*/
void debug(const char* fmt, ...)
#ifdef __GNUC__
@@ -1235,6 +1170,7 @@ class Bond {
NominatedPath()
: lastAckSent(0)
, lastAckReceived(0)
+ , lastQoSReceived(0)
, unackedBytes(0)
, packetsReceivedSinceLastAck(0)
, lastQoSMeasurement(0)
@@ -1243,6 +1179,7 @@ class Bond {
, lastAliveToggle(0)
, alive(false)
, eligible(true)
+ , lastEligibility(0)
, whenNominated(0)
, refractoryPeriod(0)
, ipvPref(0)
@@ -1250,19 +1187,14 @@ class Bond {
, onlyPathOnLink(false)
, bonded(false)
, negotiated(false)
- , shouldReallocateFlows(false)
+ , shouldAvoid(false)
, assignedFlowCount(0)
- , latencyMean(0)
+ , latency(0)
, latencyVariance(0)
, packetLossRatio(0)
, packetErrorRatio(0)
- , throughputMean(0)
- , throughputMax(0)
- , throughputVariance(0)
- , allocation(0)
- , byteLoad(0)
- , relativeByteLoad(0)
- , affinity(0)
+ , relativeQuality(0)
+ , relativeLinkCapacity(0)
, failoverScore(0)
, packetsReceivedSinceLastQoS(0)
, packetsIn(0)
@@ -1310,6 +1242,14 @@ class Bond {
return (! ipvPref || ((p->_addr.isV4() && (ipvPref == 4 || ipvPref == 46 || ipvPref == 64)) || ((p->_addr.isV6() && (ipvPref == 6 || ipvPref == 46 || ipvPref == 64)))));
}
+ /**
+ * @return True if a path exists on a link marked as a spare
+ */
+ inline bool isSpare()
+ {
+ return mode == ZT_BOND_SLAVE_MODE_SPARE;
+ }
+
/**
* @return True if a path is preferred over another on the same physical link (according to user pref.)
*/
@@ -1322,7 +1262,7 @@ class Bond {
* @param now Current time
* @return Whether a QoS (VERB_QOS_MEASUREMENT) packet needs to be emitted at this time
*/
- inline bool needsToSendQoS(int64_t now, int qosSendInterval)
+ inline bool needsToSendQoS(int64_t now, uint64_t qosSendInterval)
{
// fprintf(stderr, "QOS table (%d / %d)\n", packetsReceivedSinceLastQoS, ZT_QOS_TABLE_SIZE);
return ((packetsReceivedSinceLastQoS >= ZT_QOS_TABLE_SIZE) || ((now - lastQoSMeasurement) > qosSendInterval)) && packetsReceivedSinceLastQoS;
@@ -1332,7 +1272,7 @@ class Bond {
* @param now Current time
* @return Whether an ACK (VERB_ACK) packet needs to be emitted at this time
*/
- inline bool needsToSendAck(int64_t now, int ackSendInterval)
+ inline bool needsToSendAck(int64_t now, uint64_t ackSendInterval)
{
return ((now - lastAckSent) >= ackSendInterval || (packetsReceivedSinceLastAck == ZT_QOS_TABLE_SIZE)) && packetsReceivedSinceLastAck;
}
@@ -1359,6 +1299,7 @@ class Bond {
uint64_t lastAckSent;
uint64_t lastAckReceived;
+ uint64_t lastQoSReceived;
uint64_t unackedBytes;
uint64_t packetsReceivedSinceLastAck;
@@ -1367,28 +1308,25 @@ class Bond {
uint64_t lastRefractoryUpdate; // The last time that the refractory period was updated.
uint64_t lastAliveToggle; // The last time that the path was marked as "alive".
bool alive;
- bool eligible; // State of eligibility at last check. Used for determining state changes.
- uint64_t whenNominated; // Timestamp indicating when this path's trial period began.
- uint32_t refractoryPeriod; // Amount of time that this path will be prevented from becoming a member of a bond.
- uint8_t ipvPref; // IP version preference inherited from the physical link.
- uint8_t mode; // Mode inherited from the physical link.
- bool onlyPathOnLink; // IP version preference inherited from the physical link.
- bool enabled; // Enabled state inherited from the physical link.
- bool bonded; // Whether this path is currently part of a bond.
- bool negotiated; // Whether this path was intentionally negotiated by either peer.
- bool shouldReallocateFlows; // Whether flows should be moved from this path. Current traffic flows will be re-allocated immediately.
- uint16_t assignedFlowCount; // The number of flows currently assigned to this path.
- float latencyMean; // The mean latency (computed from a sliding window.)
- float latencyVariance; // Packet delay variance (computed from a sliding window.)
- float packetLossRatio; // The ratio of lost packets to received packets.
- float packetErrorRatio; // The ratio of packets that failed their MAC/CRC checks to those that did not.
- uint64_t throughputMean; // The estimated mean throughput of this path.
- uint64_t throughputMax; // The maximum observed throughput of this path.
- float throughputVariance; // The variance in the estimated throughput of this path.
- uint8_t allocation; // The relative quality of this path to all others in the bond, [0-255].
- uint64_t byteLoad; // How much load this path is under.
- uint8_t relativeByteLoad; // How much load this path is under (relative to other paths in the bond.)
- uint8_t affinity; // Relative value expressing how "deserving" this path is of new traffic.
+ bool eligible; // State of eligibility at last check. Used for determining state changes.
+ uint64_t lastEligibility; // The last time that this path was eligible
+ uint64_t whenNominated; // Timestamp indicating when this path's trial period began.
+ uint32_t refractoryPeriod; // Amount of time that this path will be prevented from becoming a member of a bond.
+ uint8_t ipvPref; // IP version preference inherited from the physical link.
+ uint8_t mode; // Mode inherited from the physical link.
+ bool onlyPathOnLink; // IP version preference inherited from the physical link.
+ bool enabled; // Enabled state inherited from the physical link.
+ bool bonded; // Whether this path is currently part of a bond.
+ bool negotiated; // Whether this path was intentionally negotiated by either peer.
+ bool shouldAvoid; // Whether flows should be moved from this path. Current traffic flows will be re-allocated immediately.
+ uint16_t assignedFlowCount; // The number of flows currently assigned to this path.
+ float latency; // The mean latency (computed from a sliding window.)
+ float latencyVariance; // Packet delay variance (computed from a sliding window.)
+ float packetLossRatio; // The ratio of lost packets to received packets.
+ float packetErrorRatio; // The ratio of packets that failed their MAC/CRC checks to those that did not.
+ float relativeQuality; // The relative quality of the link.
+ float relativeLinkCapacity; // The relative capacity of the link.
+
uint32_t failoverScore; // Score that indicates to what degree this path is preferred over others that are available to the bonding policy. (specifically for active-backup)
int32_t packetsReceivedSinceLastQoS; // Number of packets received since the last VERB_QOS_MEASUREMENT was sent to the remote peer.
@@ -1405,7 +1343,6 @@ class Bond {
{
p = path;
whenNominated = now;
- p->_bondingMetricPtr = (void*)this;
}
};
@@ -1480,15 +1417,19 @@ class Bond {
std::string _policyAlias; // Custom name given by the user to this bond type.
+ static Binder* _binder;
+
/**
* Set of indices corresponding to paths currently included in the bond proper. This
* may only be updated during a call to curateBond(). The reason for this is so that
* we can simplify the high frequency packet egress logic.
*/
- int _bondIdxMap[ZT_MAX_PEER_NETWORK_PATHS];
- int _numBondedPaths; // Number of paths currently included in the _bondIdxMap set.
- std::map > _flows; // Flows hashed according to port and protocol
- float _qw[ZT_QOS_WEIGHT_SIZE]; // How much each factor contributes to the "quality" score of a path.
+ int _realIdxMap[ZT_MAX_PEER_NETWORK_PATHS] = { ZT_MAX_PEER_NETWORK_PATHS };
+ int _numBondedPaths; // Number of paths currently included in the _realIdxMap set.
+ std::map > _flows; // Flows hashed according to port and protocol
+ float _qw[ZT_QOS_PARAMETER_SIZE]; // Link quality specification (can be customized by user)
+
+ bool _run;
uint8_t _policy;
uint32_t _upDelay;
@@ -1511,7 +1452,6 @@ class Bond {
// balance-aware
uint64_t _totalBondUnderload;
- uint8_t _flowRebalanceStrategy;
// dynamic link monitoring
uint8_t _linkMonitorStrategy;
@@ -1525,21 +1465,11 @@ class Bond {
/**
* Timers and intervals
*/
- uint32_t _failoverInterval;
- uint32_t _qosSendInterval;
- uint32_t _ackSendInterval;
- uint32_t throughputMeasurementInterval;
- uint32_t _qualityEstimationInterval;
-
- /**
- * Acceptable quality thresholds
- */
- float _maxAcceptablePacketLossRatio;
- float _maxAcceptablePacketErrorRatio;
- uint16_t _maxAcceptableLatency;
- uint16_t _maxAcceptableMeanLatency;
- uint16_t _maxAcceptablePacketDelayVariance;
- uint8_t _minAcceptableAllocation;
+ uint64_t _failoverInterval;
+ uint64_t _qosSendInterval;
+ uint64_t _ackSendInterval;
+ uint64_t throughputMeasurementInterval;
+ uint64_t _qualityEstimationInterval;
/**
* Link state reporting
@@ -1589,7 +1519,7 @@ class Bond {
bool _userHasSpecifiedLinks; // Whether the user has specified links for this bond.
bool _userHasSpecifiedPrimaryLink; // Whether the user has specified a primary link for this bond.
bool _userHasSpecifiedFailoverInstructions; // Whether the user has specified failover instructions for this bond.
- bool _userHasSpecifiedLinkSpeeds; // Whether the user has specified links speeds for this bond.
+ bool _userHasSpecifiedLinkCapacities; // Whether the user has specified links capacities for this bond.
/**
* How frequently (in ms) a VERB_ECHO is sent to a peer to verify that a
* path is still active. A value of zero (0) will disable active path
diff --git a/node/Constants.hpp b/node/Constants.hpp
index 6389bdcd3..e234d510f 100644
--- a/node/Constants.hpp
+++ b/node/Constants.hpp
@@ -390,7 +390,7 @@
/**
* Number of samples to consider when processing real-time path statistics
*/
-#define ZT_QOS_SHORTTERM_SAMPLE_WIN_SIZE 32
+#define ZT_QOS_SHORTTERM_SAMPLE_WIN_SIZE 64
/**
* Max allowable time spent in any queue (in ms)
@@ -517,7 +517,7 @@
#define ZT_ACK_CUTOFF_LIMIT 128
#define ZT_ACK_DRAINAGE_DIVISOR (1000 / ZT_ACK_CUTOFF_LIMIT)
-#define ZT_BOND_DEFAULT_REFRCTORY_PERIOD 8000
+#define ZT_BOND_DEFAULT_REFRACTORY_PERIOD 8000
#define ZT_BOND_MAX_REFRACTORY_PERIOD 600000
/**
diff --git a/node/DNS.hpp b/node/DNS.hpp
index b36d960d4..778680ff7 100644
--- a/node/DNS.hpp
+++ b/node/DNS.hpp
@@ -24,7 +24,7 @@
namespace ZeroTier {
/**
- * DNS data serealization methods
+ * DNS data serialization methods
*/
class DNS {
public:
@@ -44,6 +44,7 @@ public:
char *d = (char*)b.data()+p;
memset(dns, 0, sizeof(ZT_VirtualNetworkDNS));
memcpy(dns->domain, d, 128);
+ dns->domain[127] = 0;
p += 128;
for (unsigned int j = 0; j < ZT_MAX_DNS_SERVERS; ++j) {
p += reinterpret_cast(&(dns->server_addr[j]))->deserialize(b, p);
diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp
index 72cd4bde7..9080128b6 100644
--- a/node/IncomingPacket.cpp
+++ b/node/IncomingPacket.cpp
@@ -707,7 +707,7 @@ bool IncomingPacket::_doFRAME(const RuntimeEnvironment *RR,void *tPtr,const Shar
{
int32_t _flowId = ZT_QOS_NO_FLOW;
SharedPtr bond = peer->bond();
- if (bond && bond->flowHashingEnabled()) {
+ if (bond && bond->flowHashingSupported()) {
if (size() > ZT_PROTO_VERB_EXT_FRAME_IDX_PAYLOAD) {
const unsigned int etherType = at(ZT_PROTO_VERB_FRAME_IDX_ETHERTYPE);
const unsigned int frameLen = size() - ZT_PROTO_VERB_FRAME_IDX_PAYLOAD;
diff --git a/node/Multicaster.cpp b/node/Multicaster.cpp
index 4856b88ee..d93b2ae10 100644
--- a/node/Multicaster.cpp
+++ b/node/Multicaster.cpp
@@ -268,7 +268,8 @@ void Multicaster::send(
const unsigned int gatherLimit = (limit - (unsigned int)gs.members.size()) + 1;
- if ((gs.members.empty())||((now - gs.lastExplicitGather) >= ZT_MULTICAST_EXPLICIT_GATHER_DELAY)) {
+ int timerScale = RR->node->lowBandwidthModeEnabled() ? 3 : 1;
+ if ((gs.members.empty())||((now - gs.lastExplicitGather) >= (ZT_MULTICAST_EXPLICIT_GATHER_DELAY * timerScale))) {
gs.lastExplicitGather = now;
Address explicitGatherPeers[16];
diff --git a/node/NetworkConfig.hpp b/node/NetworkConfig.hpp
index 846f922da..0161b4fa9 100644
--- a/node/NetworkConfig.hpp
+++ b/node/NetworkConfig.hpp
@@ -177,7 +177,7 @@ namespace ZeroTier {
#define ZT_NETWORKCONFIG_DICT_KEY_CERTIFICATES_OF_OWNERSHIP "COO"
// dns (binary blobs)
#define ZT_NETWORKCONFIG_DICT_KEY_DNS "DNS"
-// sso enabld
+// sso enabled
#define ZT_NETWORKCONFIG_DICT_KEY_SSO_ENABLED "ssoe"
// so version
#define ZT_NETWORKCONFIG_DICT_KEY_SSO_VERSION "ssov"
@@ -200,7 +200,7 @@ namespace ZeroTier {
// AuthInfo Version
#define ZT_AUTHINFO_DICT_KEY_VERSION "aV"
-// authenticaiton URL
+// authentication URL
#define ZT_AUTHINFO_DICT_KEY_AUTHENTICATION_URL "aU"
// issuer URL
#define ZT_AUTHINFO_DICT_KEY_ISSUER_URL "iU"
@@ -659,7 +659,7 @@ public:
bool ssoEnabled;
/**
- * SSO verison
+ * SSO version
*/
uint64_t ssoVersion;
diff --git a/node/Node.cpp b/node/Node.cpp
index a5b7bd7ab..46f3a4add 100644
--- a/node/Node.cpp
+++ b/node/Node.cpp
@@ -50,7 +50,8 @@ Node::Node(void *uptr,void *tptr,const struct ZT_Node_Callbacks *callbacks,int64
_lastPingCheck(0),
_lastGratuitousPingCheck(0),
_lastHousekeepingRun(0),
- _lastMemoizedTraceSettings(0)
+ _lastMemoizedTraceSettings(0),
+ _lowBandwidthMode(false)
{
if (callbacks->version != 0)
throw ZT_EXCEPTION_INVALID_ARGUMENT;
@@ -202,6 +203,14 @@ public:
{
const std::vector *const alwaysContactEndpoints = _alwaysContact.get(p->address());
if (alwaysContactEndpoints) {
+
+ // Contact upstream peers as infrequently as possible
+ ZT_PeerRole role = RR->topology->role(p->address());
+ int roleBasedTimerScale = (role == ZT_PEER_ROLE_LEAF) ? 2 : 16;
+ if ((RR->node->now() - p->lastSentFullHello()) <= (ZT_PATH_HEARTBEAT_PERIOD * roleBasedTimerScale)) {
+ return;
+ }
+
const unsigned int sent = p->doPingAndKeepalive(_tPtr,_now);
bool contacted = (sent != 0);
@@ -262,7 +271,7 @@ ZT_ResultCode Node::processBackgroundTasks(void *tptr,int64_t now,volatile int64
}
}
- unsigned long timeUntilNextPingCheck = ZT_PING_CHECK_INVERVAL;
+ unsigned long timeUntilNextPingCheck = _lowBandwidthMode ? (ZT_PING_CHECK_INVERVAL * 5) : ZT_PING_CHECK_INVERVAL;
const int64_t timeSinceLastPingCheck = now - _lastPingCheck;
if (timeSinceLastPingCheck >= timeUntilNextPingCheck) {
try {
@@ -309,6 +318,7 @@ ZT_ResultCode Node::processBackgroundTasks(void *tptr,int64_t now,volatile int64
// Get peers we should stay connected to according to network configs
// Also get networks and whether they need config so we only have to do one pass over networks
+ int timerScale = _lowBandwidthMode ? 64 : 1;
std::vector< std::pair< SharedPtr,bool > > networkConfigNeeded;
{
Mutex::Lock l(_networks_m);
@@ -317,7 +327,7 @@ ZT_ResultCode Node::processBackgroundTasks(void *tptr,int64_t now,volatile int64
SharedPtr *network = (SharedPtr *)0;
while (i.next(nwid,network)) {
(*network)->config().alwaysContactAddresses(alwaysContact);
- networkConfigNeeded.push_back( std::pair< SharedPtr,bool >(*network,(((now - (*network)->lastConfigUpdate()) >= ZT_NETWORK_AUTOCONF_DELAY)||(!(*network)->hasConfig()))) );
+ networkConfigNeeded.push_back( std::pair< SharedPtr,bool >(*network,(((now - (*network)->lastConfigUpdate()) >= ZT_NETWORK_AUTOCONF_DELAY * timerScale)||(!(*network)->hasConfig()))) );
}
}
@@ -336,9 +346,12 @@ ZT_ResultCode Node::processBackgroundTasks(void *tptr,int64_t now,volatile int64
// Refresh network config or broadcast network updates to members as needed
for(std::vector< std::pair< SharedPtr,bool > >::const_iterator n(networkConfigNeeded.begin());n!=networkConfigNeeded.end();++n) {
- if (n->second)
+ if (n->second) {
n->first->requestConfiguration(tptr);
- n->first->sendUpdatesToMembers(tptr);
+ }
+ if (! _lowBandwidthMode) {
+ n->first->sendUpdatesToMembers(tptr);
+ }
}
// Update online status, post status change as event
@@ -496,15 +509,30 @@ ZT_PeerList *Node::peers() const
SharedPtr bestp(pi->second->getAppropriatePath(_now,false));
p->pathCount = 0;
for(std::vector< SharedPtr >::iterator path(paths.begin());path!=paths.end();++path) {
- memcpy(&(p->paths[p->pathCount].address),&((*path)->address()),sizeof(struct sockaddr_storage));
- p->paths[p->pathCount].localSocket = (*path)->localSocket();
- p->paths[p->pathCount].lastSend = (*path)->lastOut();
- p->paths[p->pathCount].lastReceive = (*path)->lastIn();
- p->paths[p->pathCount].trustedPathId = RR->topology->getOutboundPathTrust((*path)->address());
- p->paths[p->pathCount].expired = 0;
- p->paths[p->pathCount].preferred = ((*path) == bestp) ? 1 : 0;
- p->paths[p->pathCount].scope = (*path)->ipScope();
- ++p->pathCount;
+ if((*path)->valid()) {
+ memcpy(&(p->paths[p->pathCount].address),&((*path)->address()),sizeof(struct sockaddr_storage));
+ p->paths[p->pathCount].localSocket = (*path)->localSocket();
+ p->paths[p->pathCount].lastSend = (*path)->lastOut();
+ p->paths[p->pathCount].lastReceive = (*path)->lastIn();
+ p->paths[p->pathCount].trustedPathId = RR->topology->getOutboundPathTrust((*path)->address());
+ p->paths[p->pathCount].expired = 0;
+ p->paths[p->pathCount].preferred = ((*path) == bestp) ? 1 : 0;
+ p->paths[p->pathCount].scope = (*path)->ipScope();
+ if (pi->second->bond()) {
+ p->paths[p->pathCount].latencyMean = (*path)->latencyMean();
+ p->paths[p->pathCount].latencyVariance = (*path)->latencyVariance();
+ p->paths[p->pathCount].packetLossRatio = (*path)->packetLossRatio();
+ p->paths[p->pathCount].packetErrorRatio = (*path)->packetErrorRatio();
+ p->paths[p->pathCount].relativeQuality = (*path)->relativeQuality();
+ p->paths[p->pathCount].linkSpeed = (*path)->givenLinkSpeed();
+ p->paths[p->pathCount].bonded = (*path)->bonded();
+ p->paths[p->pathCount].eligible = (*path)->eligible();
+ std::string ifname = std::string((*path)->ifname());
+ memset(p->paths[p->pathCount].ifname, 0x0, std::min((int)ifname.length() + 1, ZT_MAX_PHYSIFNAME));
+ memcpy(p->paths[p->pathCount].ifname, ifname.c_str(), std::min((int)ifname.length(), ZT_MAX_PHYSIFNAME));
+ }
+ ++p->pathCount;
+ }
}
if (pi->second->bond()) {
p->isBonded = pi->second->bond();
diff --git a/node/Node.hpp b/node/Node.hpp
index 52506ed9e..0ddd5cb7b 100644
--- a/node/Node.hpp
+++ b/node/Node.hpp
@@ -35,6 +35,7 @@
#include "NetworkController.hpp"
#include "Hashtable.hpp"
#include "Bond.hpp"
+#include "SelfAwareness.hpp"
// Bit mask for "expecting reply" hash
#define ZT_EXPECTING_REPLIES_BUCKET_MASK1 255
@@ -187,6 +188,8 @@ public:
inline const Identity &identity() const { return _RR.identity; }
+ inline const std::vector SurfaceAddresses() const { return _RR.sa->whoami(); }
+
inline Bond *bondController() const { return _RR.bc; }
/**
@@ -266,6 +269,16 @@ public:
_stats.inVerbBytes[v] += (uint64_t)bytes;
}
+ inline void setLowBandwidthMode(bool isEnabled)
+ {
+ _lowBandwidthMode = isEnabled;
+ }
+
+ inline bool lowBandwidthModeEnabled()
+ {
+ return _lowBandwidthMode;
+ }
+
private:
RuntimeEnvironment _RR;
RuntimeEnvironment *RR;
@@ -313,6 +326,7 @@ private:
int64_t _lastMemoizedTraceSettings;
volatile int64_t _prngState[2];
bool _online;
+ bool _lowBandwidthMode;
};
} // namespace ZeroTier
diff --git a/node/Packet.hpp b/node/Packet.hpp
index 7219a3310..d40e5eb43 100644
--- a/node/Packet.hpp
+++ b/node/Packet.hpp
@@ -1249,6 +1249,14 @@ public:
return (((unsigned int)(*this)[ZT_PACKET_IDX_FLAGS] & 0x38) >> 3);
}
+ /**
+ * @return Whether this packet is currently encrypted
+ */
+ inline bool isEncrypted() const
+ {
+ return (cipher() == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012) || (cipher() == ZT_PROTO_CIPHER_SUITE__AES_GMAC_SIV);
+ }
+
/**
* Set this packet's cipher suite
*/
diff --git a/node/Path.hpp b/node/Path.hpp
index 3471e2d66..8304f27d8 100644
--- a/node/Path.hpp
+++ b/node/Path.hpp
@@ -85,6 +85,15 @@ public:
_lastTrustEstablishedPacketReceived(0),
_lastEchoRequestReceived(0),
_localSocket(-1),
+ _latencyMean(0.0),
+ _latencyVariance(0.0),
+ _packetLossRatio(0.0),
+ _packetErrorRatio(0.0),
+ _valid(true),
+ _eligible(false),
+ _bonded(false),
+ _givenLinkSpeed(0),
+ _relativeQuality(0),
_latency(0xffff),
_addr(),
_ipScope(InetAddress::IP_SCOPE_NONE)
@@ -96,6 +105,15 @@ public:
_lastTrustEstablishedPacketReceived(0),
_lastEchoRequestReceived(0),
_localSocket(localSocket),
+ _latencyMean(0.0),
+ _latencyVariance(0.0),
+ _packetLossRatio(0.0),
+ _packetErrorRatio(0.0),
+ _valid(true),
+ _eligible(false),
+ _bonded(false),
+ _givenLinkSpeed(0),
+ _relativeQuality(0),
_latency(0xffff),
_addr(addr),
_ipScope(addr.ipScope())
@@ -176,7 +194,7 @@ public:
*/
inline unsigned int preferenceRank() const
{
- // This causes us to rank paths in order of IP scope rank (see InetAdddress.hpp) but
+ // This causes us to rank paths in order of IP scope rank (see InetAddress.hpp) but
// within each IP scope class to prefer IPv6 over IPv4.
return ( ((unsigned int)_ipScope << 1) | (unsigned int)(_addr.ss_family == AF_INET6) );
}
@@ -280,10 +298,63 @@ public:
return false;
}
- void *_bondingMetricPtr;
+ /**
+ * @return Mean latency as reported by the bonding layer
+ */
+ inline unsigned int latencyMean() const { return _latencyMean; }
+
+ /**
+ * @return Latency variance as reported by the bonding layer
+ */
+ inline unsigned int latencyVariance() const { return _latencyVariance; }
+
+ /**
+ * @return Packet Loss Ratio as reported by the bonding layer
+ */
+ inline unsigned int packetLossRatio() const { return _packetLossRatio; }
+
+ /**
+ * @return Packet Error Ratio as reported by the bonding layer
+ */
+ inline unsigned int packetErrorRatio() const { return _packetErrorRatio; }
+
+ /**
+ * @return Whether this path is valid as reported by the bonding layer. The bonding layer
+ * actually checks with Phy to see if the interface is still up
+ */
+ inline unsigned int valid() const { return _valid; }
+
+ /**
+ * @return Whether this path is eligible for use in a bond as reported by the bonding layer
+ */
+ inline unsigned int eligible() const { return _eligible; }
+
+ /**
+ * @return Whether this path is bonded as reported by the bonding layer
+ */
+ inline unsigned int bonded() const { return _bonded; }
+
+ /**
+ * @return Given link capacity as reported by the bonding layer
+ */
+ inline unsigned int givenLinkSpeed() const { return _givenLinkSpeed; }
+
+ /**
+ * @return Path's quality as reported by the bonding layer
+ */
+ inline float relativeQuality() const { return _relativeQuality; }
+
+ /**
+ * @return Physical interface name that this path lives on
+ */
+ char *ifname() {
+ return _ifname;
+ }
private:
+ char _ifname[ZT_MAX_PHYSIFNAME] = { };
+
volatile int64_t _lastOut;
volatile int64_t _lastIn;
volatile int64_t _lastTrustEstablishedPacketReceived;
@@ -291,6 +362,17 @@ private:
int64_t _lastEchoRequestReceived;
int64_t _localSocket;
+
+ volatile float _latencyMean;
+ volatile float _latencyVariance;
+ volatile float _packetLossRatio;
+ volatile float _packetErrorRatio;
+ volatile bool _valid;
+ volatile bool _eligible;
+ volatile bool _bonded;
+ volatile uint32_t _givenLinkSpeed;
+ volatile float _relativeQuality;
+
volatile unsigned int _latency;
InetAddress _addr;
InetAddress::IpScope _ipScope; // memoize this since it's a computed value checked often
diff --git a/node/Peer.cpp b/node/Peer.cpp
index 963774d5e..c1dc124c6 100644
--- a/node/Peer.cpp
+++ b/node/Peer.cpp
@@ -219,11 +219,15 @@ void Peer::received(
// is done less frequently.
if (this->trustEstablished(now)) {
const int64_t sinceLastPush = now - _lastDirectPathPushSent;
- if (sinceLastPush >= ((hops == 0) ? ZT_DIRECT_PATH_PUSH_INTERVAL_HAVEPATH : ZT_DIRECT_PATH_PUSH_INTERVAL)) {
+ bool lowBandwidth = RR->node->lowBandwidthModeEnabled();
+ int timerScale = lowBandwidth ? 16 : 1;
+ if (sinceLastPush >= ((hops == 0) ? ZT_DIRECT_PATH_PUSH_INTERVAL_HAVEPATH * timerScale : ZT_DIRECT_PATH_PUSH_INTERVAL)) {
_lastDirectPathPushSent = now;
std::vector pathsToPush(RR->node->directPaths());
- std::vector ma = RR->sa->whoami();
- pathsToPush.insert(pathsToPush.end(), ma.begin(), ma.end());
+ if (! lowBandwidth) {
+ std::vector ma = RR->sa->whoami();
+ pathsToPush.insert(pathsToPush.end(), ma.begin(), ma.end());
+ }
if (!pathsToPush.empty()) {
std::vector::const_iterator p(pathsToPush.begin());
while (p != pathsToPush.end()) {
@@ -270,30 +274,30 @@ SharedPtr Peer::getAppropriatePath(int64_t now, bool includeExpired, int32
{
Mutex::Lock _l(_paths_m);
Mutex::Lock _lb(_bond_m);
- if (!_bond) {
- unsigned int bestPath = ZT_MAX_PEER_NETWORK_PATHS;
- /**
- * Send traffic across the highest quality path only. This algorithm will still
- * use the old path quality metric from protocol version 9.
- */
- long bestPathQuality = 2147483647;
- for(unsigned int i=0;iquality(now) / _paths[i].priority;
- if (q <= bestPathQuality) {
- bestPathQuality = q;
- bestPath = i;
- }
- }
- } else break;
- }
- if (bestPath != ZT_MAX_PEER_NETWORK_PATHS) {
- return _paths[bestPath].p;
- }
- return SharedPtr();
+ if(_bond && _bond->isReady()) {
+ return _bond->getAppropriatePath(now, flowId);
}
- return _bond->getAppropriatePath(now, flowId);
+ unsigned int bestPath = ZT_MAX_PEER_NETWORK_PATHS;
+ /**
+ * Send traffic across the highest quality path only. This algorithm will still
+ * use the old path quality metric from protocol version 9.
+ */
+ long bestPathQuality = 2147483647;
+ for(unsigned int i=0;iquality(now) / _paths[i].priority;
+ if (q <= bestPathQuality) {
+ bestPathQuality = q;
+ bestPath = i;
+ }
+ }
+ } else break;
+ }
+ if (bestPath != ZT_MAX_PEER_NETWORK_PATHS) {
+ return _paths[bestPath].p;
+ }
+ return SharedPtr();
}
void Peer::introduce(void *const tPtr,const int64_t now,const SharedPtr &other) const
@@ -453,7 +457,7 @@ void Peer::sendHELLO(void *tPtr,const int64_t localSocket,const InetAddress &atA
if (atAddress) {
outp.armor(_key,false,nullptr); // false == don't encrypt full payload, but add MAC
RR->node->expectReplyTo(outp.packetId());
- RR->node->putPacket(tPtr,-1,atAddress,outp.data(),outp.size());
+ RR->node->putPacket(tPtr,RR->node->lowBandwidthModeEnabled() ? localSocket : -1,atAddress,outp.data(),outp.size());
} else {
RR->node->expectReplyTo(outp.packetId());
RR->sw->send(tPtr,outp,false); // false == don't encrypt full payload, but add MAC
@@ -477,8 +481,9 @@ void Peer::tryMemorizedPath(void *tPtr,int64_t now)
if ((now - _lastTriedMemorizedPath) >= ZT_TRY_MEMORIZED_PATH_INTERVAL) {
_lastTriedMemorizedPath = now;
InetAddress mp;
- if (RR->node->externalPathLookup(tPtr,_id.address(),-1,mp))
+ if (RR->node->externalPathLookup(tPtr,_id.address(),-1,mp)) {
attemptToContactAt(tPtr,-1,mp,now,true);
+ }
}
}
diff --git a/node/Peer.hpp b/node/Peer.hpp
index 0192143e3..668bbbee9 100644
--- a/node/Peer.hpp
+++ b/node/Peer.hpp
@@ -302,6 +302,8 @@ public:
*/
inline int64_t isActive(int64_t now) const { return ((now - _lastNontrivialReceive) < ZT_PEER_ACTIVITY_TIMEOUT); }
+ inline int64_t lastSentFullHello() { return _lastSentFullHello; }
+
/**
* @return Latency in milliseconds of best/aggregate path or 0xffff if unknown / no paths
*/
diff --git a/node/SHA512.cpp b/node/SHA512.cpp
index 5c602673b..2fe126a84 100644
--- a/node/SHA512.cpp
+++ b/node/SHA512.cpp
@@ -1,5 +1,7 @@
// This code is public domain, taken from a PD crypto source file on GitHub.
+#include
+
#include "SHA512.hpp"
#include "Utils.hpp"
diff --git a/node/Switch.cpp b/node/Switch.cpp
index 2721cf92f..ae870a278 100644
--- a/node/Switch.cpp
+++ b/node/Switch.cpp
@@ -1045,7 +1045,9 @@ void Switch::_sendViaSpecificPath(void *tPtr,SharedPtr peer,SharedPtrkey(),encrypt,peer->aesKeysIfSupported());
+ if (!packet.isEncrypted()) {
+ packet.armor(peer->key(),encrypt,peer->aesKeysIfSupported());
+ }
RR->node->expectReplyTo(packet.packetId());
}
diff --git a/one.cpp b/one.cpp
index 828163896..62710547c 100644
--- a/one.cpp
+++ b/one.cpp
@@ -611,42 +611,50 @@ static int cli(int argc,char **argv)
} else {
int numAliveLinks = OSUtils::jsonInt(j["numAliveLinks"],0);
int numTotalLinks = OSUtils::jsonInt(j["numTotalLinks"],0);
- printf("Peer : %s\n", arg1.c_str());
- printf("Bond : %s\n", OSUtils::jsonString(j["bondingPolicy"],"-").c_str());
- //if (bondingPolicy == ZT_BOND_POLICY_ACTIVE_BACKUP) {
- printf("Link Select Method : %d\n", (int)OSUtils::jsonInt(j["linkSelectMethod"],0));
- //}
- printf("Links : %d/%d\n", numAliveLinks, numTotalLinks);
- printf("Failover Interval : %d (ms)\n", (int)OSUtils::jsonInt(j["failoverInterval"],0));
- printf("Up Delay : %d (ms)\n", (int)OSUtils::jsonInt(j["upDelay"],0));
- printf("Down Delay : %d (ms)\n", (int)OSUtils::jsonInt(j["downDelay"],0));
- printf("Packets Per Link : %d (ms)\n", (int)OSUtils::jsonInt(j["packetsPerLink"],0));
- nlohmann::json &p = j["links"];
+ printf("Peer : %s\n", arg1.c_str());
+ printf("Bond : %s\n", OSUtils::jsonString(j["bondingPolicyStr"],"-").c_str());
+ printf("Link Select Method : %d\n", (int)OSUtils::jsonInt(j["linkSelectMethod"],0));
+ printf("Links : %d/%d\n", numAliveLinks, numTotalLinks);
+ printf("Failover Interval (ms) : %d\n", (int)OSUtils::jsonInt(j["failoverInterval"],0));
+ printf("Up Delay (ms) : %d\n", (int)OSUtils::jsonInt(j["upDelay"],0));
+ printf("Down Delay (ms) : %d\n", (int)OSUtils::jsonInt(j["downDelay"],0));
+ printf("Packets Per Link : %d\n", (int)OSUtils::jsonInt(j["packetsPerLink"],0));
+ nlohmann::json &p = j["paths"];
if (p.is_array()) {
- printf("\n Interface Name\t\t\t\t\t Path\t Alive\n");
- for(int i=0; i<80; i++) { printf("-"); }
+ printf("\nidx"
+ " interface"
+ " "
+ "path socket\n");
+ for(int i=0; i<100; i++) { printf("-"); }
printf("\n");
for (int i=0; i
+#if ! defined(TARGET_OS_IOS)
#include
+#endif
#include
#endif
@@ -66,6 +68,9 @@
// Max number of bindings
#define ZT_BINDER_MAX_BINDINGS 256
+// Maximum physical interface name length. This number is gigantic because of Windows.
+#define ZT_MAX_PHYSIFNAME 256
+
namespace ZeroTier {
/**
@@ -88,6 +93,7 @@ class Binder {
PhySocket* udpSock;
PhySocket* tcpListenSock;
InetAddress address;
+ char ifname[256] = {};
};
public:
@@ -307,7 +313,14 @@ class Binder {
#else
const bool gotViaProc = false;
#endif
-#if ! defined(ZT_SDK) || ! defined(__ANDROID__) // getifaddrs() freeifaddrs() not available on Android
+
+ //
+ // prevent:
+ // warning: unused variable 'gotViaProc'
+ //
+ (void)gotViaProc;
+
+#if ! (defined(ZT_SDK) || defined(__ANDROID__)) // getifaddrs() freeifaddrs() not available on Android
if (! gotViaProc) {
struct ifaddrs* ifatbl = (struct ifaddrs*)0;
struct ifaddrs* ifa;
@@ -320,7 +333,7 @@ class Binder {
while (ifa) {
if ((ifa->ifa_name) && (ifa->ifa_addr)) {
InetAddress ip = *(ifa->ifa_addr);
-#if (defined(__unix__) || defined(__APPLE__)) && !defined(__LINUX__) && !defined(ZT_SDK)
+#if (defined(__unix__) || defined(__APPLE__)) && !defined(__LINUX__) && !defined(ZT_SDK) && !defined(TARGET_OS_IOS)
// Check if the address is an IPv6 Temporary Address, macOS/BSD version
if (ifa->ifa_addr->sa_family == AF_INET6) {
struct sockaddr_in6* sa6 = (struct sockaddr_in6*)ifa->ifa_addr;
@@ -443,7 +456,7 @@ class Binder {
_bindings[_bindingCount].udpSock = udps;
_bindings[_bindingCount].tcpListenSock = tcps;
_bindings[_bindingCount].address = ii->first;
- phy.setIfName(udps, (char*)ii->second.c_str(), (int)ii->second.length());
+ memcpy(_bindings[_bindingCount].ifname, (char*)ii->second.c_str(), (int)ii->second.length());
++_bindingCount;
}
}
@@ -514,6 +527,22 @@ class Binder {
return false;
}
+ /**
+ * @param s Socket object
+ * @param nameBuf Buffer to store name of interface which this Socket object is bound to
+ * @param buflen Length of buffer to copy name into
+ */
+ void getIfName(PhySocket* s, char* nameBuf, int buflen) const
+ {
+ Mutex::Lock _l(_lock);
+ for (unsigned int b = 0, c = _bindingCount; b < c; ++b) {
+ if (_bindings[b].udpSock == s) {
+ memcpy(nameBuf, _bindings[b].ifname, buflen);
+ break;
+ }
+ }
+ }
+
private:
_Binding _bindings[ZT_BINDER_MAX_BINDINGS];
std::atomic _bindingCount;
diff --git a/osdep/ManagedRoute.cpp b/osdep/ManagedRoute.cpp
index 325f4c803..a8f996839 100644
--- a/osdep/ManagedRoute.cpp
+++ b/osdep/ManagedRoute.cpp
@@ -477,7 +477,7 @@ bool ManagedRoute::sync()
if ((newSystemVia)&&(!newSystemDevice[0])) {
rtes = _getRTEs(newSystemVia,true);
for(std::vector<_RTE>::iterator r(rtes.begin());r!=rtes.end();++r) {
- if ( (r->device[0]) && (strcmp(r->device,_device) != 0) ) {
+ if ( (r->device[0]) && (strcmp(r->device,_device) != 0) && r->target.netmaskBits() != 0) {
Utils::scopy(newSystemDevice,sizeof(newSystemDevice),r->device);
break;
}
diff --git a/osdep/OSUtils.cpp b/osdep/OSUtils.cpp
index ab3f1078b..36814523a 100644
--- a/osdep/OSUtils.cpp
+++ b/osdep/OSUtils.cpp
@@ -43,6 +43,10 @@
#include "OSUtils.hpp"
+#ifdef __GCC__
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
+
namespace ZeroTier {
unsigned int OSUtils::ztsnprintf(char *buf,unsigned int len,const char *fmt,...)
diff --git a/osdep/Phy.hpp b/osdep/Phy.hpp
index 28aad4bef..7be6546fe 100644
--- a/osdep/Phy.hpp
+++ b/osdep/Phy.hpp
@@ -140,12 +140,11 @@ private:
};
struct PhySocketImpl {
- PhySocketImpl() { memset(ifname, 0, sizeof(ifname)); }
+ PhySocketImpl() {}
PhySocketType type;
ZT_PHY_SOCKFD_TYPE sock;
void *uptr; // user-settable pointer
ZT_PHY_SOCKADDR_STORAGE_TYPE saddr; // remote for TCP_OUT and TCP_IN, local for TCP_LISTEN, RAW, and UDP
- char ifname[256 + 4];
};
std::list _socks;
@@ -243,38 +242,6 @@ public:
return &(reinterpret_cast(s)->uptr);
}
- /**
- * @param s Socket object
- * @param nameBuf Buffer to store name of interface which this Socket object is bound to
- * @param buflen Length of buffer to copy name into
- */
- static inline void getIfName(PhySocket* s, char* nameBuf, int buflen)
- {
- PhySocketImpl& sws = *(reinterpret_cast(s));
- if (sws.type == ZT_PHY_SOCKET_CLOSED) {
- return;
- }
- if (s) {
- memcpy(nameBuf, reinterpret_cast(s)->ifname, buflen);
- }
- }
-
- /**
- * @param s Socket object
- * @param ifname Buffer containing name of interface that this Socket object is bound to
- * @param len Length of name of interface
- */
- static inline void setIfName(PhySocket* s, char* ifname, int len)
- {
- PhySocketImpl& sws = *(reinterpret_cast(s));
- if (sws.type == ZT_PHY_SOCKET_CLOSED) {
- return;
- }
- if (s) {
- memcpy(&(reinterpret_cast(s)->ifname), ifname, len);
- }
- }
-
/**
* Cause poll() to stop waiting immediately
*
diff --git a/osdep/WinFWHelper.cpp b/osdep/WinFWHelper.cpp
new file mode 100644
index 000000000..40f38977e
--- /dev/null
+++ b/osdep/WinFWHelper.cpp
@@ -0,0 +1,172 @@
+#include "WinFWHelper.hpp"
+
+
+namespace ZeroTier {
+
+
+
+void ZeroTier::WinFWHelper::newICMPRule(const InetAddress& ip, uint64_t nwid)
+{
+ char nwString[32] = { 0 };
+ char ipbuf[64];
+
+ sprintf(nwString, "%.16llx", nwid);
+ std::string nwString2 = { nwString };
+
+ ip.toString(ipbuf);
+
+ if (ip.isV4()) {
+ WinFWHelper::newICMPv4Rule(ipbuf, nwid);
+ }
+ else {
+ WinFWHelper::newICMPv6Rule(ipbuf, nwid);
+ }
+}
+
+void ZeroTier::WinFWHelper::removeICMPRule(const InetAddress& ip, uint64_t nwid)
+{
+ char nwString[32] = { 0 };
+ char ipbuf[64];
+
+ sprintf(nwString, "%.16llx", nwid);
+ std::string nwString2 = { nwString };
+
+ ip.toString(ipbuf);
+
+ if (ip.isV4()) {
+ WinFWHelper::removeICMPv4Rule(ipbuf, nwid);
+ }
+ else {
+ WinFWHelper::removeICMPv6Rule(ipbuf, nwid);
+ }
+}
+
+
+void WinFWHelper::newICMPv4Rule(std::string address, uint64_t nwid)
+{
+ // allows icmp, scoped to a specific ip address and interface name
+
+ char nwString[32] = { 0 };
+ sprintf(nwString, "%.16llx", nwid);
+ std::string nwString2 = { nwString };
+
+ std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "New-NetFirewallRule -DisplayName zerotier-icmpv4-)" + nwString2 + address +
+ R"( -InterfaceAlias 'ZeroTier One `[)" + nwString2 + R"(`]')" +
+ " -Protocol ICMPv4 -Action Allow" +
+ " -LocalAddress " + address + "\"\r\n";
+
+ _run(cmd);
+}
+
+void WinFWHelper::newICMPv6Rule(std::string address, uint64_t nwid)
+{
+ // allows icmp, scoped to a specific ip address and interface name
+
+ char nwString[32] = { 0 };
+ sprintf(nwString, "%.16llx", nwid);
+ std::string nwString2 = { nwString };
+
+ std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "New-NetFirewallRule -DisplayName zerotier-icmpv6-)" + nwString2 + address +
+ R"( -InterfaceAlias 'ZeroTier One `[)" + nwString2 + R"(`]')" +
+ " -Protocol ICMPv6 -Action Allow" +
+ " -LocalAddress " + address + "\"\r\n";
+
+ _run(cmd);
+}
+
+void WinFWHelper::removeICMPv4Rule(std::string addr, uint64_t nwid)
+{
+ // removes 1 icmp firewall rule
+
+ char nwString[32] = { 0 };
+ sprintf(nwString, "%.16llx", nwid);
+ std::string nwString2 = { nwString };
+
+ std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "Remove-NetFirewallRule -DisplayName zerotier-icmpv4-)" + nwString2 + addr +
+ "\"\r\n";
+
+ _run(cmd);
+}
+
+void WinFWHelper::removeICMPv6Rule(std::string addr, uint64_t nwid)
+{
+ // removes 1 icmp firewall rule
+
+ char nwString[32] = { 0 };
+ sprintf(nwString, "%.16llx", nwid);
+ std::string nwString2 = { nwString };
+
+ std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "Remove-NetFirewallRule -DisplayName zerotier-icmpv6-)" + nwString2 + addr +
+ "\"\r\n";
+
+ _run(cmd);
+}
+
+void WinFWHelper::removeICMPv4Rules(uint64_t nwid)
+{
+ // removes all icmp firewall rules for this network id
+
+ char nwString[32] = { 0 };
+ sprintf(nwString, "%.16llx", nwid);
+ std::string nwString2 = { nwString };
+
+ std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "Remove-NetFirewallRule -DisplayName zerotier-icmpv4-)" + nwString2 + "*\" \r\n";
+
+ _run(cmd);
+}
+
+void WinFWHelper::removeICMPv6Rules(uint64_t nwid)
+{
+ // removes all icmp firewall rules for this network id
+
+ char nwString[32] = { 0 };
+ sprintf(nwString, "%.16llx", nwid);
+ std::string nwString2 = { nwString };
+
+ std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "Remove-NetFirewallRule -DisplayName zerotier-icmpv6-)" + nwString2 + "*\" \r\n";
+
+ _run(cmd);
+}
+
+void WinFWHelper::removeICMPRules()
+{
+ // removes all icmp firewall rules for all networks
+
+ std::string cmd = R"(C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe "Remove-NetFirewallRule -DisplayName zerotier-icmp*)" + std::string("\r\n");
+
+ _run(cmd);
+}
+
+void WinFWHelper::removeICMPRules(uint64_t nwid)
+{
+ // removes all icmp firewall rules for this network
+ WinFWHelper::removeICMPv4Rules(nwid);
+ WinFWHelper::removeICMPv6Rules(nwid);
+}
+
+
+
+void WinFWHelper::_run(std::string cmd)
+{
+
+ #ifdef ZT_DEBUG
+ fprintf(stderr, cmd.c_str());
+ #endif
+
+ STARTUPINFOA startupInfo;
+ PROCESS_INFORMATION processInfo;
+ startupInfo.cb = sizeof(startupInfo);
+ memset(&startupInfo, 0, sizeof(STARTUPINFOA));
+ memset(&processInfo, 0, sizeof(PROCESS_INFORMATION));
+
+ if (CreateProcessA(NULL, (LPSTR)cmd.c_str(), NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &startupInfo, &processInfo)) {
+ WaitForSingleObject(processInfo.hProcess, INFINITE);
+
+ CloseHandle(processInfo.hProcess);
+ CloseHandle(processInfo.hThread);
+ }
+}
+
+
+
+} // namespace ZeroTier
\ No newline at end of file
diff --git a/osdep/WinFWHelper.hpp b/osdep/WinFWHelper.hpp
new file mode 100644
index 000000000..a8d9e27aa
--- /dev/null
+++ b/osdep/WinFWHelper.hpp
@@ -0,0 +1,31 @@
+#ifndef WIN_FW_HELPER_H_
+#define WIN_FW_HELPER_H_
+
+#include "../node/InetAddress.hpp"
+
+#include
+#include
+
+namespace ZeroTier {
+
+class WinFWHelper {
+ public:
+ static void newICMPRule(const InetAddress& ip, uint64_t nwid);
+ static void removeICMPRule(const InetAddress& ip, uint64_t nwid);
+ static void removeICMPRules(uint64_t nwid);
+ static void removeICMPRules();
+
+
+ private:
+ static void _run(std::string cmd);
+ static void newICMPv4Rule(std::string address, uint64_t nwid);
+ static void newICMPv6Rule(std::string address, uint64_t nwid);
+ static void removeICMPv4Rule(std::string address, uint64_t nwid);
+ static void removeICMPv6Rule(std::string address, uint64_t nwid);
+ static void removeICMPv4Rules(uint64_t nwid);
+ static void removeICMPv6Rules(uint64_t nwid);
+};
+
+} // namespace ZeroTier
+
+#endif
\ No newline at end of file
diff --git a/pkg/README.md b/pkg/README.md
index defc65112..0bd8ef00b 100644
--- a/pkg/README.md
+++ b/pkg/README.md
@@ -1,4 +1,4 @@
Third-party packaging
=====
-Builds packages for various embedded devices and appliances and platforms
+For package documentation see the `Devices` section here: [docs.zerotier.com](https://docs.zerotier.com/)
diff --git a/pkg/synology/dsm7-docker/Dockerfile b/pkg/synology/dsm7-docker/Dockerfile
index 56fd0b448..5441d37a7 100644
--- a/pkg/synology/dsm7-docker/Dockerfile
+++ b/pkg/synology/dsm7-docker/Dockerfile
@@ -2,13 +2,12 @@
FROM alpine:latest as builder
-RUN apk add --no-cache rust cargo
-RUN apk add openssl-dev
-
-RUN apk add --update alpine-sdk linux-headers \
+WORKDIR /src
+RUN apk add --no-cache rust cargo \
+ && apk add openssl-dev \
+ && apk add --update alpine-sdk linux-headers \
&& git clone --quiet https://github.com/zerotier/ZeroTierOne.git /src \
- && git -C src reset --quiet --hard ${ZTO_COMMIT} \
- && cd /src \
+ && git reset --quiet --hard ${ZTO_COMMIT} \
&& make -f make-linux.mk
FROM alpine:latest
@@ -18,6 +17,7 @@ LABEL description="ZeroTier One docker image for Synology NAS"
RUN apk add --update --no-cache bash jq libc6-compat libstdc++
EXPOSE 9993/udp
+ENV MAX_WAIT_SECS SLEEP_TIME
COPY --from=builder /src/zerotier-one /usr/sbin/
RUN mkdir -p /var/lib/zerotier-one \
diff --git a/pkg/synology/dsm7-docker/entrypoint.sh b/pkg/synology/dsm7-docker/entrypoint.sh
index 6b7c1187f..acc66d4dc 100755
--- a/pkg/synology/dsm7-docker/entrypoint.sh
+++ b/pkg/synology/dsm7-docker/entrypoint.sh
@@ -1,29 +1,81 @@
#!/bin/bash
+set -uo pipefail
+
+trap 'trap " " SIGTERM; kill 0; wait' SIGTERM SIGQUIT SIGINT
+
+echo "Starting Zerotier-One"
zerotier-one -d
-# Wait for ZT service to come online before attempting queries
-sleep 15
+echo "Wait for ZT service to come online before attempting queries..."
+MAX_WAIT_SECS="${MAX_WAIT_SECS:-90}"
+SLEEP_TIME="${SLEEP_TIME:-15}"
+if [[ "$SLEEP_TIME" -le 0 ]]
+then
+ SLEEP_TIME=1
+fi
+iterations=$((MAX_WAIT_SECS/SLEEP_TIME))
+online=false
+
+for ((s=0; s<=iterations; s++))
+do
+ online="$(zerotier-cli -j info | jq '.online' 2>/dev/null)"
+ if [[ "$online" == "true" ]]
+ then
+ break
+ fi
+ sleep "$SLEEP_TIME"
+ echo " ."
+done
+
+if [[ "$online" != "true" ]]
+then
+ echo "Waited $MAX_WAIT_SECS for zerotier-one to start, exiting." >&2
+ exit 1
+fi
+echo "done."
+
+(
+echo "Starting route helper"
while true
do
- NETWORK_COUNT=$(zerotier-cli -j listnetworks | jq -r '. | length')
- if [ "$NETWORK_COUNT" -gt 0 ]; then
+ if ! NETWORK_LIST="$(zerotier-cli -j listnetworks)"
+ then
+ echo "Route helper: $NETWORK_LIST" >&2
+ exit 1
+ fi
+ NETWORK_COUNT="$(jq -r '. | length' <<< "$NETWORK_LIST")"
+ if [[ "$NETWORK_COUNT" -gt 0 ]]
+ then
for ((j=0; j<=$((NETWORK_COUNT-1)); j++))
do
- ROUTE_COUNT=$(zerotier-cli -j listnetworks | jq -r '.['$j'].routes | length')
+ ALLOW_DEFAULT="$(jq -r '.['$j'].allowDefault' <<< "$NETWORK_LIST")"
+ ROUTE_COUNT="$(jq -r '.['$j'].routes | length' <<< "$NETWORK_LIST")"
for ((k=0; k<=$((ROUTE_COUNT-1)); k++))
do
- ROUTE=$(zerotier-cli -j listnetworks | jq -r '.['$j'].routes['$k'].target')
- EXIST=$(ip route show $ROUTE | wc -l)
- if [ $EXIST -eq 0 ];
+ ROUTE="$(jq -r '.['$j'].routes['$k'].target' <<< "$NETWORK_LIST")"
+ if [[ -n "$ROUTE" ]]
then
- IFNAME=$(zerotier-cli -j listnetworks | jq -r '.['$j'] | .portDeviceName')
- ip route add $ROUTE dev $IFNAME
- # Routes will be deleted when ZT brings the interface down
+ # check if route is default and allowDefault enabled for this network
+ if [[ "$ROUTE" == "0.0.0.0/0" && "$ALLOW_DEFAULT" == "false" ]]
+ then
+ continue
+ fi
+ EXIST="$(ip -o route show "$ROUTE")"
+ if [[ -z "${EXIST}" ]]
+ then
+ IFNAME="$(jq -r '.['$j'] | .portDeviceName' <<< "$NETWORK_LIST")"
+ echo " Adding route $ROUTE to dev $IFNAME"
+ ip route add "$ROUTE" dev "$IFNAME"
+ # Routes will be deleted when ZT brings the interface down
+ fi
fi
done
done
- sleep 15
fi
-done
+ sleep 15
+done ) &
+
+wait
+
diff --git a/selftest.cpp b/selftest.cpp
index f43cee1af..cc161777b 100644
--- a/selftest.cpp
+++ b/selftest.cpp
@@ -667,7 +667,7 @@ static int testPacket()
std::cout << "(compressed: " << complen << ", decompressed: " << a.size() << ") ";
if (a != b) {
- std::cout << "FAIL (compresssion)" << std::endl;
+ std::cout << "FAIL (compression)" << std::endl;
return -1;
}
diff --git a/service/OneService.cpp b/service/OneService.cpp
index a9cb229ec..c9c1ff3ea 100644
--- a/service/OneService.cpp
+++ b/service/OneService.cpp
@@ -78,6 +78,7 @@
#include "../osdep/MacDNSHelper.hpp"
#elif defined(__WINDOWS__)
#include "../osdep/WinDNSHelper.hpp"
+#include "../osdep/WinFWHelper.hpp"
#endif
#ifdef ZT_USE_SYSTEM_HTTP_PARSER
@@ -520,7 +521,7 @@ static void _networkToJson(nlohmann::json &nj,NetworkState &ns)
}
}
-static void _peerToJson(nlohmann::json &pj,const ZT_Peer *peer)
+static void _peerToJson(nlohmann::json &pj,const ZT_Peer *peer, SharedPtr &bond)
{
char tmp[256];
@@ -541,10 +542,15 @@ static void _peerToJson(nlohmann::json &pj,const ZT_Peer *peer)
pj["latency"] = peer->latency;
pj["role"] = prole;
pj["isBonded"] = peer->isBonded;
- if (peer->isBonded) {
- pj["bondingPolicy"] = peer->bondingPolicy;
+ if (bond && peer->isBonded) {
+ pj["bondingPolicyCode"] = peer->bondingPolicy;
+ pj["bondingPolicyStr"] = Bond::getPolicyStrByCode(peer->bondingPolicy);
pj["numAliveLinks"] = peer->numAliveLinks;
pj["numTotalLinks"] = peer->numTotalLinks;
+ pj["failoverInterval"] = bond->getFailoverInterval();
+ pj["downDelay"] = bond->getDownDelay();
+ pj["upDelay"] = bond->getUpDelay();
+ pj["packetsPerLink"] = bond->getPacketsPerLink();
}
nlohmann::json pa = nlohmann::json::array();
@@ -560,58 +566,25 @@ static void _peerToJson(nlohmann::json &pj,const ZT_Peer *peer)
j["expired"] = (bool)(peer->paths[i].expired != 0);
j["preferred"] = (bool)(peer->paths[i].preferred != 0);
j["localSocket"] = peer->paths[i].localSocket;
+ if (bond && peer->isBonded) {
+ uint64_t now = OSUtils::now();
+ j["ifname"] = std::string(peer->paths[i].ifname);
+ j["latencyMean"] = peer->paths[i].latencyMean;
+ j["latencyVariance"] = peer->paths[i].latencyVariance;
+ j["packetLossRatio"] = peer->paths[i].packetLossRatio;
+ j["packetErrorRatio"] = peer->paths[i].packetErrorRatio;
+ j["lastInAge"] = (now - lastReceive);
+ j["lastOutAge"] = (now - lastSend);
+ j["bonded"] = peer->paths[i].bonded;
+ j["eligible"] = peer->paths[i].eligible;
+ j["givenLinkSpeed"] = peer->paths[i].linkSpeed;
+ j["relativeQuality"] = peer->paths[i].relativeQuality;
+ }
pa.push_back(j);
}
pj["paths"] = pa;
}
-static void _bondToJson(nlohmann::json &pj, SharedPtr &bond)
-{
- uint64_t now = OSUtils::now();
-
- int bondingPolicy = bond->policy();
- pj["bondingPolicy"] = Bond::getPolicyStrByCode(bondingPolicy);
- if (bondingPolicy == ZT_BOND_POLICY_NONE) {
- return;
- }
-
- pj["numAliveLinks"] = bond->getNumAliveLinks();
- pj["numTotalLinks"] = bond->getNumTotalLinks();
- pj["failoverInterval"] = bond->getFailoverInterval();
- pj["downDelay"] = bond->getDownDelay();
- pj["upDelay"] = bond->getUpDelay();
- if (bondingPolicy == ZT_BOND_POLICY_BALANCE_RR) {
- pj["packetsPerLink"] = bond->getPacketsPerLink();
- }
- if (bondingPolicy == ZT_BOND_POLICY_ACTIVE_BACKUP) {
- pj["linkSelectMethod"] = bond->getLinkSelectMethod();
- }
-
- nlohmann::json pa = nlohmann::json::array();
- std::vector< SharedPtr > paths = bond->paths(now);
-
- for(unsigned int i=0;iaddress().toString(pathStr);
-
- nlohmann::json j;
- j["ifname"] = bond->getLink(paths[i])->ifname();
- j["path"] = pathStr;
- /*
- j["alive"] = paths[i]->alive(now,true);
- j["bonded"] = paths[i]->bonded();
- j["latencyMean"] = paths[i]->latencyMean();
- j["latencyVariance"] = paths[i]->latencyVariance();
- j["packetLossRatio"] = paths[i]->packetLossRatio();
- j["packetErrorRatio"] = paths[i]->packetErrorRatio();
- j["givenLinkSpeed"] = 1000;
- j["allocation"] = paths[i]->allocation();
- */
- pa.push_back(j);
- }
- pj["links"] = pa;
-}
-
static void _moonToJson(nlohmann::json &mj,const World &world)
{
char tmp[4096];
@@ -875,6 +848,9 @@ public:
virtual ~OneServiceImpl()
{
+#ifdef __WINDOWS__
+ WinFWHelper::removeICMPRules();
+#endif
_binder.closeAll(_phy);
_phy.close(_localControlSocket4);
_phy.close(_localControlSocket6);
@@ -883,6 +859,8 @@ public:
curl_global_cleanup();
#endif
+
+
#ifdef ZT_USE_MINIUPNPC
delete _portMapper;
#endif
@@ -927,6 +905,7 @@ public:
_node = new Node(this,(void *)0,&cb,OSUtils::now());
}
+
// local.conf
readLocalSettings();
applyLocalConfig();
@@ -1429,7 +1408,7 @@ public:
/* Note: this is kind of restricted in what it'll take. It does not support
* URL encoding, and /'s in URL args will screw it up. But the only URL args
- * it really uses in ?jsonp=funcionName, and otherwise it just takes simple
+ * it really uses in ?jsonp=functionName, and otherwise it just takes simple
* paths to simply-named resources. */
if (!ps.empty()) {
std::size_t qpos = ps[ps.size() - 1].find('?');
@@ -1498,23 +1477,27 @@ public:
if (ps[0] == "bond") {
if (_node->bondController()->inUse()) {
if (ps.size() == 3) {
- //fprintf(stderr, "ps[0]=%s\nps[1]=%s\nps[2]=%s\n", ps[0].c_str(), ps[1].c_str(), ps[2].c_str());
if (ps[2].length() == 10) {
// check if hex string
- const uint64_t id = Utils::hexStrToU64(ps[2].c_str());
- if (ps[1] == "show") {
- SharedPtr bond = _node->bondController()->getBondByPeerId(id);
- if (bond) {
- _bondToJson(res,bond);
- scode = 200;
- } else {
- fprintf(stderr, "unable to find bond to peer %llx\n", (unsigned long long)id);
- scode = 400;
+
+ ZT_PeerList *pl = _node->peers();
+ if (pl) {
+ uint64_t wantp = Utils::hexStrToU64(ps[2].c_str());
+ for(unsigned long i=0;ipeerCount;++i) {
+ if (pl->peers[i].address == wantp) {
+ if (ps[1] == "show") {
+ SharedPtr bond = _node->bondController()->getBondByPeerId(wantp);
+ if (bond) {
+ _peerToJson(res,&(pl->peers[i]),bond);
+ scode = 200;
+ } else {
+ scode = 400;
+ }
+ }
+ }
}
}
- if (ps[1] == "flows") {
- fprintf(stderr, "displaying flows\n");
- }
+ _node->freeQueryResult((void *)pl);
}
}
} else {
@@ -1550,7 +1533,7 @@ public:
settings["primaryPort"] = OSUtils::jsonInt(settings["primaryPort"],(uint64_t)_primaryPort) & 0xffff;
settings["secondaryPort"] = OSUtils::jsonInt(settings["secondaryPort"],(uint64_t)_secondaryPort) & 0xffff;
settings["tertiaryPort"] = OSUtils::jsonInt(settings["tertiaryPort"],(uint64_t)_tertiaryPort) & 0xffff;
- // Enumerate all external listening address/port pairs
+ // Enumerate all local address/port pairs that this node is listening on
std::vector boundAddrs(_binder.allBoundLocalInterfaceAddresses());
auto boundAddrArray = json::array();
for (int i = 0; i < boundAddrs.size(); i++) {
@@ -1559,6 +1542,15 @@ public:
boundAddrArray.push_back(ipBuf);
}
settings["listeningOn"] = boundAddrArray;
+ // Enumerate all external address/port pairs that are reported for this node
+ std::vector surfaceAddrs = _node->SurfaceAddresses();
+ auto surfaceAddrArray = json::array();
+ for (int i = 0; i < surfaceAddrs.size(); i++) {
+ char ipBuf[64] = { 0 };
+ surfaceAddrs[i].toString(ipBuf);
+ surfaceAddrArray.push_back(ipBuf);
+ }
+ settings["surfaceAddresses"] = surfaceAddrArray;
#ifdef ZT_USE_MINIUPNPC
settings["portMappingEnabled"] = OSUtils::jsonBool(settings["portMappingEnabled"],true);
@@ -1637,36 +1629,12 @@ public:
res = nlohmann::json::array();
for(unsigned long i=0;ipeerCount;++i) {
nlohmann::json pj;
- _peerToJson(pj,&(pl->peers[i]));
- res.push_back(pj);
- }
-
- scode = 200;
- } else if (ps.size() == 2) {
- // Return a single peer by ID or 404 if not found
-
- uint64_t wantp = Utils::hexStrToU64(ps[1].c_str());
- for(unsigned long i=0;ipeerCount;++i) {
- if (pl->peers[i].address == wantp) {
- _peerToJson(res,&(pl->peers[i]));
- scode = 200;
- break;
+ SharedPtr bond = SharedPtr();
+ if (pl->peers[i].isBonded) {
+ const uint64_t id = pl->peers[i].address;
+ bond = _node->bondController()->getBondByPeerId(id);
}
- }
-
- } else scode = 404;
- _node->freeQueryResult((void *)pl);
- } else scode = 500;
- } else if (ps[0] == "bonds") {
- ZT_PeerList *pl = _node->peers();
- if (pl) {
- if (ps.size() == 1) {
- // Return [array] of all peers
-
- res = nlohmann::json::array();
- for(unsigned long i=0;ipeerCount;++i) {
- nlohmann::json pj;
- _peerToJson(pj,&(pl->peers[i]));
+ _peerToJson(pj,&(pl->peers[i]),bond);
res.push_back(pj);
}
@@ -1677,7 +1645,11 @@ public:
uint64_t wantp = Utils::hexStrToU64(ps[1].c_str());
for(unsigned long i=0;ipeerCount;++i) {
if (pl->peers[i].address == wantp) {
- _peerToJson(res,&(pl->peers[i]));
+ SharedPtr bond = SharedPtr();
+ if (pl->peers[i].isBonded) {
+ bond = _node->bondController()->getBondByPeerId(wantp);
+ }
+ _peerToJson(res,&(pl->peers[i]),bond);
scode = 200;
break;
}
@@ -1771,11 +1743,11 @@ public:
if (ps[0] == "bond") {
if (_node->bondController()->inUse()) {
if (ps.size() == 3) {
- //fprintf(stderr, "ps[0]=%s\nps[1]=%s\nps[2]=%s\n", ps[0].c_str(), ps[1].c_str(), ps[2].c_str());
if (ps[2].length() == 10) {
// check if hex string
const uint64_t id = Utils::hexStrToU64(ps[2].c_str());
if (ps[1] == "rotate") {
+ exit(0);
SharedPtr bond = _node->bondController()->getBondByPeerId(id);
if (bond) {
scode = bond->abForciblyRotateLink() ? 200 : 400;
@@ -1784,9 +1756,6 @@ public:
scode = 400;
}
}
- if (ps[1] == "enable") {
- fprintf(stderr, "enabling bond\n");
- }
}
}
} else {
@@ -2041,6 +2010,7 @@ public:
json &settings = lc["settings"];
if (!_node->bondController()->inUse()) {
+ _node->bondController()->setBinder(&_binder);
// defaultBondingPolicy
std::string defaultBondingPolicyStr(OSUtils::jsonString(settings["defaultBondingPolicy"],""));
int defaultBondingPolicy = _node->bondController()->getPolicyCodeByStr(defaultBondingPolicyStr);
@@ -2068,32 +2038,24 @@ public:
}
// New bond, used as a copy template for new instances
SharedPtr newTemplateBond = new Bond(NULL, basePolicyStr, customPolicyStr, SharedPtr());
- // Acceptable ranges
newTemplateBond->setPolicy(basePolicyCode);
- newTemplateBond->setMaxAcceptableLatency(OSUtils::jsonInt(customPolicy["maxAcceptableLatency"],-1));
- newTemplateBond->setMaxAcceptableMeanLatency(OSUtils::jsonInt(customPolicy["maxAcceptableMeanLatency"],-1));
- newTemplateBond->setMaxAcceptablePacketDelayVariance(OSUtils::jsonInt(customPolicy["maxAcceptablePacketDelayVariance"],-1));
- newTemplateBond->setMaxAcceptablePacketLossRatio((float)OSUtils::jsonDouble(customPolicy["maxAcceptablePacketLossRatio"],-1));
- newTemplateBond->setMaxAcceptablePacketErrorRatio((float)OSUtils::jsonDouble(customPolicy["maxAcceptablePacketErrorRatio"],-1));
- newTemplateBond->setMinAcceptableAllocation((float)OSUtils::jsonDouble(customPolicy["minAcceptableAllocation"],0));
- // Quality weights
- json &qualityWeights = customPolicy["qualityWeights"];
- if (qualityWeights.size() == ZT_QOS_WEIGHT_SIZE) { // TODO: Generalize this
- float weights[ZT_QOS_WEIGHT_SIZE];
- weights[ZT_QOS_LAT_IDX] = (float)OSUtils::jsonDouble(qualityWeights["lat"],0.0);
- weights[ZT_QOS_LTM_IDX] = (float)OSUtils::jsonDouble(qualityWeights["ltm"],0.0);
- weights[ZT_QOS_PDV_IDX] = (float)OSUtils::jsonDouble(qualityWeights["pdv"],0.0);
- weights[ZT_QOS_PLR_IDX] = (float)OSUtils::jsonDouble(qualityWeights["plr"],0.0);
- weights[ZT_QOS_PER_IDX] = (float)OSUtils::jsonDouble(qualityWeights["per"],0.0);
- weights[ZT_QOS_THR_IDX] = (float)OSUtils::jsonDouble(qualityWeights["thr"],0.0);
- weights[ZT_QOS_THM_IDX] = (float)OSUtils::jsonDouble(qualityWeights["thm"],0.0);
- weights[ZT_QOS_THV_IDX] = (float)OSUtils::jsonDouble(qualityWeights["thv"],0.0);
- newTemplateBond->setUserQualityWeights(weights,ZT_QOS_WEIGHT_SIZE);
+ // Custom link quality spec
+ json &linkQualitySpec = customPolicy["linkQuality"];
+ if (linkQualitySpec.size() == ZT_QOS_PARAMETER_SIZE) {
+ float weights[ZT_QOS_PARAMETER_SIZE] = {};
+ weights[ZT_QOS_LAT_MAX_IDX] = (float)OSUtils::jsonDouble(linkQualitySpec["lat_max"],0.0);
+ weights[ZT_QOS_PDV_MAX_IDX] = (float)OSUtils::jsonDouble(linkQualitySpec["pdv_max"],0.0);
+ weights[ZT_QOS_PLR_MAX_IDX] = (float)OSUtils::jsonDouble(linkQualitySpec["plr_max"],0.0);
+ weights[ZT_QOS_PER_MAX_IDX] = (float)OSUtils::jsonDouble(linkQualitySpec["per_max"],0.0);
+ weights[ZT_QOS_LAT_WEIGHT_IDX] = (float)OSUtils::jsonDouble(linkQualitySpec["lat_weight"],0.0);
+ weights[ZT_QOS_PDV_WEIGHT_IDX] = (float)OSUtils::jsonDouble(linkQualitySpec["pdv_weight"],0.0);
+ weights[ZT_QOS_PLR_WEIGHT_IDX] = (float)OSUtils::jsonDouble(linkQualitySpec["plr_weight"],0.0);
+ weights[ZT_QOS_PER_WEIGHT_IDX] = (float)OSUtils::jsonDouble(linkQualitySpec["per_weight"],0.0);
+ newTemplateBond->setUserLinkQualitySpec(weights,ZT_QOS_PARAMETER_SIZE);
}
// Bond-specific properties
newTemplateBond->setUpDelay(OSUtils::jsonInt(customPolicy["upDelay"],-1));
newTemplateBond->setDownDelay(OSUtils::jsonInt(customPolicy["downDelay"],-1));
- newTemplateBond->setFlowRebalanceStrategy(OSUtils::jsonInt(customPolicy["flowRebalanceStrategy"],(uint64_t)0));
newTemplateBond->setFailoverInterval(OSUtils::jsonInt(customPolicy["failoverInterval"],ZT_BOND_FAILOVER_DEFAULT_INTERVAL));
newTemplateBond->setPacketsPerLink(OSUtils::jsonInt(customPolicy["packetsPerLink"],-1));
@@ -2102,16 +2064,8 @@ public:
for (json::iterator linkItr = links.begin(); linkItr != links.end();++linkItr) {
std::string linkNameStr(linkItr.key());
json &link = linkItr.value();
-
bool enabled = OSUtils::jsonInt(link["enabled"],true);
- uint32_t speed = OSUtils::jsonInt(link["speed"],0);
- float alloc = (float)OSUtils::jsonDouble(link["alloc"],0);
-
- if (speed && alloc) {
- fprintf(stderr, "error: cannot specify both speed (%d) and alloc (%f) for link (%s), pick one, link disabled.\n",
- speed, alloc, linkNameStr.c_str());
- enabled = false;
- }
+ uint32_t capacity = OSUtils::jsonInt(link["capacity"],0);
uint8_t ipvPref = OSUtils::jsonInt(link["ipvPref"],0);
std::string failoverToStr(OSUtils::jsonString(link["failoverTo"],""));
// Mode
@@ -2129,7 +2083,7 @@ public:
failoverToStr = "";
enabled = false;
}
- _node->bondController()->addCustomLink(customPolicyStr, new Link(linkNameStr,ipvPref,speed,enabled,linkMode,failoverToStr,alloc));
+ _node->bondController()->addCustomLink(customPolicyStr, new Link(linkNameStr,ipvPref,capacity,enabled,linkMode,failoverToStr));
}
std::string linkSelectMethodStr(OSUtils::jsonString(customPolicy["activeReselect"],"optimize"));
if (linkSelectMethodStr == "always") {
@@ -2147,12 +2101,6 @@ public:
if (newTemplateBond->getLinkSelectMethod() < 0 || newTemplateBond->getLinkSelectMethod() > 3) {
fprintf(stderr, "warning: invalid value (%s) for linkSelectMethod, assuming mode: always\n", linkSelectMethodStr.c_str());
}
- /*
- newBond->setPolicy(_node->bondController()->getPolicyCodeByStr(basePolicyStr));
- newBond->setFlowHashing((bool)OSUtils::jsonInt(userSpecifiedBondingPolicies[i]["allowFlowHashing"],(bool)allowFlowHashing));
- newBond->setBondMonitorInterval((unsigned int)OSUtils::jsonInt(userSpecifiedBondingPolicies[i]["monitorInterval"],(uint64_t)0));
- newBond->setAllowPathNegotiation((bool)OSUtils::jsonInt(userSpecifiedBondingPolicies[i]["allowPathNegotiation"],(bool)false));
- */
if (!_node->bondController()->addCustomPolicy(newTemplateBond)) {
fprintf(stderr, "error: a custom policy of this name (%s) already exists.\n", customPolicyStr.c_str());
}
@@ -2171,7 +2119,7 @@ public:
// bondingPolicy cannot be used with allowTcpFallbackRelay
_allowTcpFallbackRelay = OSUtils::jsonBool(settings["allowTcpFallbackRelay"],true);
#ifdef ZT_TCP_FALLBACK_RELAY
- _fallbackRelayAddress = InetAddress(OSUtils::jsonString("tcpFallbackRelay", ZT_TCP_FALLBACK_RELAY).c_str());
+ _fallbackRelayAddress = InetAddress(OSUtils::jsonString(settings["tcpFallbackRelay"], ZT_TCP_FALLBACK_RELAY).c_str());
#endif
_primaryPort = (unsigned int)OSUtils::jsonInt(settings["primaryPort"],(uint64_t)_primaryPort) & 0xffff;
_allowSecondaryPort = OSUtils::jsonBool(settings["allowSecondaryPort"],true);
@@ -2181,6 +2129,7 @@ public:
fprintf(stderr,"WARNING: using manually-specified secondary and/or tertiary ports. This can cause NAT issues." ZT_EOL_S);
}
_portMappingEnabled = OSUtils::jsonBool(settings["portMappingEnabled"],true);
+ _node->setLowBandwidthMode(OSUtils::jsonBool(settings["lowBandwidthMode"],false));
#ifndef ZT_SDK
const std::string up(OSUtils::jsonString(settings["softwareUpdate"],ZT_SOFTWARE_UPDATE_DEFAULT));
@@ -2321,6 +2270,10 @@ public:
if (std::find(newManagedIps.begin(),newManagedIps.end(),*ip) == newManagedIps.end()) {
if (!n.tap()->removeIp(*ip))
fprintf(stderr,"ERROR: unable to remove ip address %s" ZT_EOL_S, ip->toString(ipbuf));
+
+ #ifdef __WINDOWS__
+ WinFWHelper::removeICMPRule(*ip, n.config().nwid);
+ #endif
}
}
@@ -2328,6 +2281,10 @@ public:
if (std::find(n.managedIps().begin(),n.managedIps().end(),*ip) == n.managedIps().end()) {
if (!n.tap()->addIp(*ip))
fprintf(stderr,"ERROR: unable to add ip address %s" ZT_EOL_S, ip->toString(ipbuf));
+
+ #ifdef __WINDOWS__
+ WinFWHelper::newICMPRule(*ip, n.config().nwid);
+ #endif
}
}
@@ -2808,8 +2765,10 @@ public:
n.tap().reset();
_nets.erase(nwid);
#if defined(__WINDOWS__) && !defined(ZT_SDK)
- if ((op == ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY)&&(winInstanceId.length() > 0))
+ if ((op == ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY) && (winInstanceId.length() > 0)) {
WindowsEthernetTap::deletePersistentTapDevice(winInstanceId.c_str());
+ WinFWHelper::removeICMPRules(nwid);
+ }
#endif
if (op == ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY) {
char nlcpath[256];
diff --git a/tcp-proxy/Makefile b/tcp-proxy/Makefile
new file mode 100644
index 000000000..af4e71e3a
--- /dev/null
+++ b/tcp-proxy/Makefile
@@ -0,0 +1,7 @@
+CXX=$(shell which clang++ g++ c++ 2>/dev/null | head -n 1)
+
+all:
+ $(CXX) -O3 -fno-rtti -o tcp-proxy tcp-proxy.cpp
+
+clean:
+ rm -f *.o tcp-proxy *.dSYM
diff --git a/tcp-proxy/README.md b/tcp-proxy/README.md
new file mode 100644
index 000000000..0eccf23fe
--- /dev/null
+++ b/tcp-proxy/README.md
@@ -0,0 +1,35 @@
+TCP Proxy Server
+======
+
+This is the TCP proxy server we run for TCP tunneling from peers behind difficult NATs. Regular users won't have much use for this.
+
+## How to run your own
+Currently you must build it and distribute it to your server manually.
+
+To reduce latency, the tcp-relay should be as close as possible to the nodes it is serving. A datacenter in the same city or the LAN would be ideal.
+
+
+### Build
+`cd tcp-relay`
+`make`
+
+### Point your node at it
+ The default tcp relay is at `204.80.128.1/443` -an anycast address.
+
+#### Option 1 - local.conf configuration
+See [Service docs](https://github.com/zerotier/ZeroTierOne/blob/e0acccc3c918b59678033e585b31eb000c68fdf2/service/README.md) for more info on local.conf
+`{ "settings": { "tcpFallbackRelay": "198.51.100.123/443" } }`
+
+
+#### Option 2 - redirect 204.80.128.1 to your own IP
+
+If you are the admin of the network that is blocking ZeroTier UDP, you can transparently redirect 204.80.128.1 to one of your IP addresses. Users won't need to edit their local client configuration.
+
+Configuring this in your Enterprise Firewall is left as an exercise to the reader.
+
+Here is an iptables example for illustrative purposes:
+
+``` shell
+-A PREROUTING -p tcp -d 204.80.128.1 --dport 443 -j DNAT --to-destination 198.51.100.123
+-A POSTROUTING -p tcp -d 198.51.100.123 --dport 443 -j SNAT --to-source 204.80.128.1
+```
diff --git a/tcp-proxy/tcp-proxy.cpp b/tcp-proxy/tcp-proxy.cpp
new file mode 100644
index 000000000..d57351987
--- /dev/null
+++ b/tcp-proxy/tcp-proxy.cpp
@@ -0,0 +1,317 @@
+/*
+ * ZeroTier One - Network Virtualization Everywhere
+ * Copyright (C) 2011-2016 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 .
+ */
+
+// HACK! Will eventually use epoll() or something in Phy<> instead of select().
+// Also be sure to change ulimit -n and fs.file-max in /etc/sysctl.conf on relays.
+#if defined(__linux__) || defined(__LINUX__) || defined(__LINUX) || defined(LINUX)
+#include
+#include
+#undef __FD_SETSIZE
+#define __FD_SETSIZE 1048576
+#undef FD_SETSIZE
+#define FD_SETSIZE 1048576
+#endif
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include