tfclient 0.2, nebula-ffi 0.1

This commit is contained in:
c0repwn3r 2023-06-25 22:00:36 -04:00
parent 0ffb04c1e7
commit b7811f7531
Signed by: core
GPG Key ID: FDBF740DADDCEECF
21 changed files with 999 additions and 631 deletions

View File

@ -9,6 +9,7 @@
<sourceFolder url="file://$MODULE_DIR$/trifid-api/trifid_api_entities/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/trifid-api/trifid_api_migration/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/tfcli/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/nebula-ffi/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />

156
Cargo.lock generated
View File

@ -14,7 +14,7 @@ version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "617a8268e3537fe1d8c9ead925fca49ef6400927ee7bc26750e90ecee14ce4b8"
dependencies = [
"bitflags",
"bitflags 1.3.2",
"bytes",
"futures-core",
"futures-sink",
@ -52,7 +52,7 @@ dependencies = [
"actix-utils",
"ahash 0.8.3",
"base64 0.21.0",
"bitflags",
"bitflags 1.3.2",
"brotli",
"bytes",
"bytestring",
@ -609,12 +609,41 @@ dependencies = [
"num-traits",
]
[[package]]
name = "bindgen"
version = "0.66.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2b84e06fc203107bfbad243f4aba2af864eb7db3b1cf46ea0a023b0b433d2a7"
dependencies = [
"bitflags 2.3.2",
"cexpr",
"clang-sys",
"lazy_static",
"lazycell",
"log",
"peeking_take_while",
"prettyplease",
"proc-macro2",
"quote",
"regex",
"rustc-hash",
"shlex",
"syn 2.0.16",
"which",
]
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6dbe3c979c178231552ecba20214a8272df4e09f232a87aef4320cf06539aded"
[[package]]
name = "bitvec"
version = "1.0.1"
@ -775,6 +804,15 @@ dependencies = [
"jobserver",
]
[[package]]
name = "cexpr"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
dependencies = [
"nom",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
@ -813,13 +851,24 @@ dependencies = [
"inout",
]
[[package]]
name = "clang-sys"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f"
dependencies = [
"glob",
"libc",
"libloading",
]
[[package]]
name = "clap"
version = "3.2.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123"
dependencies = [
"bitflags",
"bitflags 1.3.2",
"clap_derive 3.2.25",
"clap_lex 0.2.4",
"indexmap",
@ -846,7 +895,7 @@ checksum = "914c8c79fb560f238ef6429439a30023c862f7a28e688c58f7203f12b29970bd"
dependencies = [
"anstream",
"anstyle",
"bitflags",
"bitflags 1.3.2",
"clap_lex 0.4.1",
"strsim",
]
@ -1005,7 +1054,7 @@ version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67"
dependencies = [
"bitflags",
"bitflags 1.3.2",
"crossterm_winapi",
"libc",
"mio",
@ -1511,6 +1560,12 @@ dependencies = [
"polyval",
]
[[package]]
name = "glob"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]]
name = "gloo-timers"
version = "0.2.6"
@ -1523,6 +1578,15 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "gobuild"
version = "0.1.0-alpha.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71e156a4ddbf3deb5e8116946c111413bd9a5679bdc1536c78a60618a7a9ac9e"
dependencies = [
"cc",
]
[[package]]
name = "h2"
version = "0.3.19"
@ -1860,12 +1924,28 @@ version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "lazycell"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "libc"
version = "0.2.144"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1"
[[package]]
name = "libloading"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
dependencies = [
"cfg-if",
"winapi",
]
[[package]]
name = "libm"
version = "0.1.4"
@ -1991,13 +2071,21 @@ dependencies = [
"tempfile",
]
[[package]]
name = "nebula-ffi"
version = "0.1.0"
dependencies = [
"bindgen",
"gobuild",
]
[[package]]
name = "nix"
version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a"
dependencies = [
"bitflags",
"bitflags 1.3.2",
"cfg-if",
"libc",
"static_assertions",
@ -2080,7 +2168,7 @@ version = "0.10.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01b8574602df80f7b85fdfc5392fa884a4e3b3f4f35402c070ab34c3d3f78d56"
dependencies = [
"bitflags",
"bitflags 1.3.2",
"cfg-if",
"foreign-types",
"libc",
@ -2233,6 +2321,12 @@ version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79"
[[package]]
name = "peeking_take_while"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
[[package]]
name = "pem"
version = "1.1.1"
@ -2289,7 +2383,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce"
dependencies = [
"autocfg",
"bitflags",
"bitflags 1.3.2",
"cfg-if",
"concurrent-queue",
"libc",
@ -2316,6 +2410,16 @@ version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "prettyplease"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9825a04601d60621feed79c4e6b56d65db77cdca55cef43b46b0de1096d1c282"
dependencies = [
"proc-macro2",
"syn 2.0.16",
]
[[package]]
name = "proc-macro-crate"
version = "0.1.5"
@ -2457,7 +2561,7 @@ version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
dependencies = [
"bitflags",
"bitflags 1.3.2",
]
[[package]]
@ -2466,7 +2570,7 @@ version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
dependencies = [
"bitflags",
"bitflags 1.3.2",
]
[[package]]
@ -2619,6 +2723,12 @@ dependencies = [
"serde_json",
]
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustc_version"
version = "0.4.0"
@ -2634,7 +2744,7 @@ version = "0.37.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d"
dependencies = [
"bitflags",
"bitflags 1.3.2",
"errno",
"io-lifetimes",
"libc",
@ -2875,7 +2985,7 @@ version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca2855b3715770894e67cbfa3df957790aa0c9edc3bf06efa1a84d77fa0839d1"
dependencies = [
"bitflags",
"bitflags 1.3.2",
"core-foundation",
"core-foundation-sys",
"libc",
@ -3022,6 +3132,12 @@ dependencies = [
"lazy_static",
]
[[package]]
name = "shlex"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
[[package]]
name = "signal-hook"
version = "0.3.15"
@ -3149,7 +3265,7 @@ dependencies = [
"atoi",
"base64 0.13.1",
"bigdecimal",
"bitflags",
"bitflags 1.3.2",
"byteorder",
"bytes",
"chrono",
@ -3330,7 +3446,7 @@ dependencies = [
[[package]]
name = "tfclient"
version = "0.1.8"
version = "0.2.0"
dependencies = [
"base64 0.21.0",
"base64-serde",
@ -3343,6 +3459,7 @@ dependencies = [
"hex",
"ipnet",
"log",
"nebula-ffi",
"openssl-sys",
"reqwest",
"serde",
@ -3956,6 +4073,17 @@ dependencies = [
"webpki",
]
[[package]]
name = "which"
version = "4.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269"
dependencies = [
"either",
"libc",
"once_cell",
]
[[package]]
name = "whoami"
version = "1.4.0"

View File

@ -6,5 +6,6 @@ members = [
"tfclient",
"trifid-pki",
"dnapi-rs",
"tfcli"
"tfcli",
"nebula-ffi"
]

15
nebula-ffi/Cargo.toml Normal file
View File

@ -0,0 +1,15 @@
[package]
name = "nebula-ffi"
version = "0.1.0"
edition = "2021"
description = "A Rust wrapper crate for communicating with Nebula via a CGO FFI."
license = "GPL-3.0-or-later"
documentation = "https://docs.rs/nebula-ffi"
homepage = "https://man.e3t.cc/~core/trifid-docs"
repository = "https://git.e3t.cc/~core/trifid"
[dependencies]
[build-dependencies]
gobuild = "0.1.0-alpha.2"
bindgen = "0.66.1"

3
nebula-ffi/README.md Normal file
View File

@ -0,0 +1,3 @@
# Nebula-FFI
A CGO FFI interface for [Nebula](https://github.com/slackhq/nebula) and a Rust crate for communicating with it.

26
nebula-ffi/build.rs Normal file
View File

@ -0,0 +1,26 @@
use std::env;
use std::path::PathBuf;
use bindgen::CargoCallbacks;
fn main() {
gobuild::Build::new().file("main.go").compile("nebulaffi");
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
println!("cargo:rustc-link-search={}", out_path.display());
println!("cargo:rustc-link-lib=static=nebulaffi");
println!("cargo:rerun-if-changed=go.mod");
println!("cargo:rerun-if-changed=go.sum");
println!("cargo:rerun-if-changed=main.go");
let bindings = bindgen::Builder::default()
.header(out_path.join("libnebulaffi.h").display().to_string())
.parse_callbacks(Box::new(CargoCallbacks))
.generate()
.expect("Error generating CFFI bindings");
bindings
.write_to_file(out_path.join("bindings.rs"))
.expect("Couldn't write bindings!");
}

39
nebula-ffi/go.mod Normal file
View File

@ -0,0 +1,39 @@
module main
go 1.20
require (
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect
github.com/armon/go-radix v1.0.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/cyberdelia/go-metrics-graphite v0.0.0-20161219230853-39f87cc3b432 // indirect
github.com/flynn/noise v1.0.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/gopacket v1.1.19 // indirect
github.com/imdario/mergo v0.3.15 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/miekg/dns v1.1.54 // indirect
github.com/nbrownus/go-metrics-prometheus v0.0.0-20210712211119-974a6260965f // indirect
github.com/prometheus/client_golang v1.15.1 // indirect
github.com/prometheus/client_model v0.4.0 // indirect
github.com/prometheus/common v0.42.0 // indirect
github.com/prometheus/procfs v0.9.0 // indirect
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
github.com/sirupsen/logrus v1.9.0 // indirect
github.com/slackhq/nebula v1.7.2 // indirect
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8 // indirect
github.com/vishvananda/netlink v1.1.0 // indirect
github.com/vishvananda/netns v0.0.4 // indirect
golang.org/x/crypto v0.8.0 // indirect
golang.org/x/mod v0.10.0 // indirect
golang.org/x/net v0.9.0 // indirect
golang.org/x/sys v0.8.0 // indirect
golang.org/x/term v0.8.0 // indirect
golang.org/x/tools v0.8.0 // indirect
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
golang.zx2c4.com/wireguard/windows v0.5.3 // indirect
google.golang.org/protobuf v1.30.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)

231
nebula-ffi/go.sum Normal file
View File

@ -0,0 +1,231 @@
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cyberdelia/go-metrics-graphite v0.0.0-20161219230853-39f87cc3b432 h1:M5QgkYacWj0Xs8MhpIK/5uwU02icXpEoSo9sM2aRCps=
github.com/cyberdelia/go-metrics-graphite v0.0.0-20161219230853-39f87cc3b432/go.mod h1:xwIwAxMvYnVrGJPe2FKx5prTrnAjGOD8zvDOnxnrrkM=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ=
github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM=
github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI=
github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nbrownus/go-metrics-prometheus v0.0.0-20210712211119-974a6260965f h1:8dM0ilqKL0Uzl42GABzzC4Oqlc3kGRILz0vgoff7nwg=
github.com/nbrownus/go-metrics-prometheus v0.0.0-20210712211119-974a6260965f/go.mod h1:nwPd6pDNId/Xi16qtKrFHrauSwMNuvk+zcjk89wrnlA=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI=
github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY=
github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM=
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/slackhq/nebula v1.7.2 h1:Rko1Mlksz/nC0c919xjGpB8uOSrTJ5e6KPgZx+lVfYw=
github.com/slackhq/nebula v1.7.2/go.mod h1:cnaoahkUipDs1vrNoIszyp0QPRIQN9Pm68ppQEW1Fhg=
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8 h1:TG/diQgUe0pntT/2D9tmUCz4VNwm9MfrtPr0SU2qSX8=
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8/go.mod h1:P5HUIBuIWKbyjl083/loAegFkfbFNx5i2qEP4CNbm7E=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0=
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ=
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y=
golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg=
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
golang.zx2c4.com/wireguard/windows v0.5.3 h1:On6j2Rpn3OEMXqBq00QEDC7bWSZrPIHKIus8eIuExIE=
golang.zx2c4.com/wireguard/windows v0.5.3/go.mod h1:9TEe8TJmtwyQebdFwAkEWOPr3prrtqm+REGFifP60hI=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

106
nebula-ffi/main.go Normal file
View File

@ -0,0 +1,106 @@
package main
import "C"
import (
"os"
"fmt"
"github.com/sirupsen/logrus"
"github.com/slackhq/nebula"
"github.com/slackhq/nebula/config"
)
// A version string that can be set with
//
// -ldflags "-X main.Build=SOMEVERSION"
//
// at compile-time.
var Build string
var neb_config *config.C
var control *nebula.Control
//export NebulaSetup
func NebulaSetup(configPathCStr *C.char, configTest bool) (reterr *C.char) {
configPath := C.GoString(configPathCStr)
if configPath == "" {
fmt.Println("a config path must be provided")
return C.CString("a config path must be provided")
}
fmt.Println(configPath)
fmt.Println("Loading configuration from", configPath)
l := logrus.New()
l.Out = os.Stdout
neb_config = config.NewC(l)
err := neb_config.Load(configPath)
if err != nil {
fmt.Println(err.Error())
return C.CString(err.Error())
}
ctrl, err := nebula.Main(neb_config, configTest, Build, l, nil)
control = ctrl
if err != nil {
fmt.Println(err.Error())
return C.CString(err.Error())
}
fmt.Println("NO_FAILURE")
return C.CString("NO_FAILURE")
}
//export NebulaReloadConfig
func NebulaReloadConfig() (reterr *C.char) {
if neb_config == nil {
fmt.Println("NebulaSetup has not yet been called")
return C.CString("NebulaSetup has not yet been called")
}
neb_config.ReloadConfig()
return C.CString("NO_FAILURE")
}
//export NebulaStart
func NebulaStart() (reterr *C.char) {
if control == nil {
fmt.Println("NebulaSetup has not yet been called")
return C.CString("NebulaSetup has not yet been called")
}
control.Start()
return C.CString("NO_FAILURE")
}
//export NebulaStop
func NebulaStop() (reterr *C.char) {
if control == nil {
fmt.Println("NebulaSetup has not yet been called")
return C.CString("NebulaSetup has not yet been called")
}
control.Stop()
return C.CString("NO_FAILURE")
}
//export NebulaShutdownBlock
func NebulaShutdownBlock() (reterr *C.char) {
if control == nil {
fmt.Println("NebulaSetup has not yet been called")
return C.CString("NebulaSetup has not yet been called")
}
control.ShutdownBlock()
return C.CString("NO_FAILURE")
}
//export NebulaRebindUDP
func NebulaRebindUDP() (reterr *C.char) {
if control == nil {
fmt.Println("NebulaSetup has not yet been called")
return C.CString("NebulaSetup has not yet been called")
}
control.RebindUDPServer()
return C.CString("NO_FAILURE")
}
func main() {}

217
nebula-ffi/src/lib.rs Normal file
View File

@ -0,0 +1,217 @@
//! # nebula-ffi
#![warn(clippy::pedantic)]
#![warn(clippy::nursery)]
#![deny(clippy::unwrap_used)]
#![deny(clippy::expect_used)]
#![deny(missing_docs)]
#![deny(clippy::missing_errors_doc)]
#![deny(clippy::missing_panics_doc)]
#![deny(clippy::missing_safety_doc)]
#[allow(non_upper_case_globals)]
#[allow(non_camel_case_types)]
#[allow(non_snake_case)]
#[allow(missing_docs)]
#[allow(unused)]
#[allow(clippy::derive_partial_eq_without_eq)]
pub mod generated {
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
}
use std::error::Error;
use std::ffi::{c_char, CString};
use std::fmt::{Display, Formatter};
use std::path::{Path};
use generated::GoString;
impl From<&str> for GoString {
#[allow(clippy::cast_possible_wrap)]
#[allow(clippy::expect_used)]
fn from(value: &str) -> Self {
let c_str = CString::new(value).expect("CString::new() failed");
let ptr = c_str.as_ptr();
let go_string = GoString {
p: ptr,
n: c_str.as_bytes().len() as isize
};
go_string
}
}
#[allow(clippy::expect_used)]
fn cstring_to_string(cstr_ptr: *mut c_char) -> String {
let cstr = unsafe { CString::from_raw(cstr_ptr) };
cstr.to_string_lossy().to_string()
}
/// An instance of a Nebula Control and Config object. This struct does not actually store any information - it is stored in globals in the Go wrapper, however this struct is used to provide typesafety.
pub struct NebulaInstance {}
impl NebulaInstance {
/// Creates a new `NebulaInstance` by calling `NebulaSetup` with the given config path and configTest parameters.
/// # Errors
/// This function will return errors in many, many circumstances. It is not fully documented the scope of errors that may occur.
/// # Panics
/// This function will panic if memory is corrupted while communicating with Go.
pub fn new(config_path: &Path, config_test: bool) -> Result<Self, Box<dyn Error>> {
let mut config_path_bytes = unsafe { config_path.display().to_string().as_bytes_mut().to_vec() };
config_path_bytes.push(0u8);
let config_test_u8 = u8::from(config_test);
let res;
unsafe {
res = generated::NebulaSetup(config_path_bytes.as_mut_ptr().cast::<i8>(), config_test_u8);
}
let res = cstring_to_string(res);
if res == "NO_FAILURE" {
Ok(Self {})
} else {
Err(NebulaError::from_string(&res).into())
}
}
/// Reloads the Nebula configuration file. Not all configuration values can be reloaded, some may require a full stop and re-setup of Nebula to be applied.
/// # Errors
/// This function will return an error if an error is returned by the CGOFFI layer.
pub fn reload_config(&self) -> Result<(), Box<dyn Error>> {
let res;
unsafe {
res = generated::NebulaReloadConfig();
}
let res = cstring_to_string(res);
if res == "NO_FAILURE" {
Ok(())
} else {
Err(NebulaError::from_string(&res).into())
}
}
/// Starts the Nebula packet listener server if it is not already running.
/// # Errors
/// This function will return an error if an error is returned by the CGOFFI layer.
pub fn start(&self) -> Result<(), Box<dyn Error>> {
let res;
unsafe {
res = generated::NebulaStart();
}
let res = cstring_to_string(res);
if res == "NO_FAILURE" {
Ok(())
} else {
Err(NebulaError::from_string(&res).into())
}
}
/// Signals nebula to shutdown, returns after the shutdown is complete
/// # Errors
/// This function will return an error if an error is returned by the CGOFFI layer.
pub fn stop(&self) -> Result<(), Box<dyn Error>> {
let res;
unsafe {
res = generated::NebulaStop();
}
let res = cstring_to_string(res);
if res == "NO_FAILURE" {
Ok(())
} else {
Err(NebulaError::from_string(&res).into())
}
}
/// This function blocks until a SIGTERM or SIGINT is received, then stops the Nebula packet listener server if it is not already stopped.
/// # Errors
/// This function will return an error if an error is returned by the CGOFFI layer.
pub fn block_and_stop(&self) -> Result<(), Box<dyn Error>> {
let res;
unsafe {
res = generated::NebulaShutdownBlock();
}
let res = cstring_to_string(res);
if res == "NO_FAILURE" {
Ok(())
} else {
Err(NebulaError::from_string(&res).into())
}
}
/// Asks the UDP listener to rebind it's listener. Mainly used on mobile clients when interfaces change
/// # Errors
/// This function will return an error if an error is returned by the CGOFFI layer.
pub fn rebind_udp(&self) -> Result<(), Box<dyn Error>> {
let res;
unsafe {
res = generated::NebulaRebindUDP();
}
let res = cstring_to_string(res);
if res == "NO_FAILURE" {
Ok(())
} else {
Err(NebulaError::from_string(&res).into())
}
}
}
#[derive(Debug)]
/// An enumeration of all known errors that can be returned by Nebula. As errors are passed by string, this can be a little bit janky, but it works most of the time.
pub enum NebulaError {
/// Returned by nebula when the TUN/TAP device already exists
DeviceOrResourceBusy {
/// The complete error string returned by the Nebula wrapper
error_str: String
},
/// An unknown error that the error parser couldn't figure out how to parse.
Unknown {
/// The complete error string returned by the Nebula wrapper
error_str: String
},
/// Occurs if you call a function before NebulaSetup has been called
NebulaNotSetup {
/// The complete error string returned by the Nebula wrapper
error_str: String
}
}
impl Display for NebulaError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Self::DeviceOrResourceBusy { error_str } => write!(f, "device or resource busy ({error_str})"),
Self::Unknown { error_str } => write!(f, "unknown error ({error_str})"),
Self::NebulaNotSetup { error_str } => write!(f, "attempted to call a function depending on global variable before NebulaSetup ({error_str})")
}
}
}
impl Error for NebulaError {}
impl NebulaError {
/// Converts a string error from the Nebula CGO wrapper into a Rust strongtyped error.
#[must_use]
pub fn from_string(string: &str) -> Self {
if string.starts_with("device or resource busy") {
Self::DeviceOrResourceBusy { error_str: string.to_string() }
} else if string.starts_with("NebulaSetup has not yet been called") {
Self::NebulaNotSetup { error_str: string.to_string() }
} else {
Self::Unknown { error_str: string.to_string() }
}
}
}

View File

@ -1,6 +1,6 @@
[package]
name = "tfclient"
version = "0.1.8"
version = "0.2.0"
edition = "2021"
description = "An open-source reimplementation of a Defined Networking-compatible client"
license = "GPL-3.0-or-later"
@ -31,6 +31,7 @@ base64-serde = "0.7.0"
dnapi-rs = { version = "0.1", path = "../dnapi-rs" }
serde_yaml = "0.9.19"
openssl-sys = { version = "0.9.83", features = ["vendored"] }
nebula-ffi = { version = "0.1", path = "../nebula-ffi" }
[build-dependencies]
serde = { version = "1.0.157", features = ["derive"] }

View File

@ -1,222 +0,0 @@
use flate2::read::GzDecoder;
use reqwest::blocking::Response;
use reqwest::header::HeaderMap;
use std::fs;
use std::fs::{remove_file, File};
use std::io::{Read, Write};
use std::os::unix::fs::PermissionsExt;
use std::path::Path;
use std::process::{Command, Output};
use tar::Archive;
#[derive(serde::Deserialize, Debug)]
struct GithubRelease {
name: String,
assets: Vec<GithubReleaseAsset>,
}
#[derive(serde::Deserialize, Debug)]
struct GithubUser {}
#[derive(serde::Deserialize, Debug)]
struct GithubReleaseAsset {
browser_download_url: String,
name: String,
size: i64,
}
fn main() {
if Path::new(&format!(
"{}/{}",
std::env::var("OUT_DIR").unwrap(),
"noredownload"
))
.exists()
&& std::env::var("TFBUILD_FORCE_REDOWNLOAD").is_err()
{
println!("noredownload exists and TFBUILD_FORCE_REDOWNLOAD is not set. Not redoing build process.");
return;
}
println!("[*] Fetching nebula releaseinfo...");
let mut headers = HeaderMap::new();
let mut has_api_key = false;
if let Ok(api_key) = std::env::var("GH_API_KEY") {
headers.insert(
"Authorization",
format!("Bearer {}", api_key).parse().unwrap(),
);
has_api_key = true;
}
let client = reqwest::blocking::Client::builder()
.user_agent("curl/7.57.1")
.default_headers(headers)
.build()
.unwrap();
let resp: Response = client
.get("https://api.github.com/repos/slackhq/nebula/releases/latest")
.send()
.unwrap();
if resp
.headers()
.get("X-Ratelimit-Remaining")
.unwrap()
.to_str()
.unwrap()
== "0"
{
println!("You've been ratelimited from the GitHub API. Wait a while (1 hour)");
if !has_api_key {
println!("You can also set a GitHub API key with the environment variable GH_API_KEY, which will increase your ratelimit ( a lot )");
}
panic!("Ratelimited");
}
let release: GithubRelease = resp.json().unwrap();
println!("[*] Fetching target triplet...");
let target = std::env::var("TARGET").unwrap();
println!("[*] Compiling for target {}", target);
let target_file = match target.as_str() {
"x86_64-apple-darwin" | "aarch64-apple-darwin" => "nebula-darwin",
"x86_64-unknown-freebsd" => "nebula-freebsd-amd64",
"x86_64-unknown-linux-gnu" | "x86_64-unknown-linux-musl" => "nebula-linux-amd64",
"armv5te-unknown-linux-gnueabi" => "nebula-linux-arm-5",
"arm-unknown-linux-gnueabi" | "arm-unknown-linux-gnueabihf" => "nebula-linux-arm-6",
"armv7-unknown-linux-gnueabihf" | "armv7-unknown-linux-gnueabi" => "nebula-linux-arm-7",
"aarch64-unknown-linux-gnu" | "aarch64-unknown-linux-musl" => "nebula-linux-arm64",
"x86_64-pc-windows-msvc" => "nebula-windows-amd64",
"aarch64-pc-windows-msvc" => "nebula-windows-arm64",
_ => {
println!("This architecture is not supported yet :(");
println!("Nebula has a limited set of architectures it is able to function on.");
println!("tfclient can only be compiled on these architectures.");
println!("See https://github.com/slackhq/nebula/releases for a list of supported architectures");
println!("Is your system supported by Nebula? Shoot a message to the mailing list. Include the target triplet (above) in your response, as well as a link to the functioning Nebula binary. We will happily add your machine to the list!");
panic!("Unsupported architecture");
}
};
println!("[*] Embedding {} {}", target_file, release.name);
let download = release
.assets
.iter()
.find(|r| r.name == format!("{}.tar.gz", target_file))
.expect("That architecture isn't avaliable :(");
println!(
"[*] Downloading {}.tar.gz ({}, {} bytes) from {}",
target_file, target, download.size, download.browser_download_url
);
let response = reqwest::blocking::get(&download.browser_download_url).unwrap();
let content = response.bytes().unwrap().to_vec();
let bytes = content.as_slice();
let tar = GzDecoder::new(bytes);
let mut archive = Archive::new(tar);
let entries = archive.entries().unwrap();
let mut nebula_bin = vec![];
let mut nebula_cert_bin = vec![];
let mut shasum = vec![];
for entry in entries {
let mut entry = entry.unwrap();
if entry.path().unwrap() == Path::new("nebula")
|| entry.path().unwrap() == Path::new("nebula.exe")
{
nebula_bin.reserve(entry.size() as usize);
entry.read_to_end(&mut nebula_bin).unwrap();
} else if entry.path().unwrap() == Path::new("nebula-cert")
|| entry.path().unwrap() == Path::new("nebula-cert.exe")
{
nebula_cert_bin.reserve(entry.size() as usize);
entry.read_to_end(&mut nebula_cert_bin).unwrap();
} else if entry.path().unwrap() == Path::new("SHASUM256.txt") {
shasum.reserve(entry.size() as usize);
entry.read_to_end(&mut shasum).unwrap();
}
}
if nebula_bin.is_empty() {
panic!("[x] Release did not contain nebula binary");
}
if nebula_cert_bin.is_empty() {
panic!("[x] Release did not contain nebula_cert binary");
}
let mut nebula_file =
File::create(format!("{}/nebula.bin", std::env::var("OUT_DIR").unwrap())).unwrap();
nebula_file.write_all(&nebula_bin).unwrap();
codegen_version(&nebula_bin, "nebula.bin", "NEBULA");
let mut nebula_cert_file = File::create(format!(
"{}/nebula_cert.bin",
std::env::var("OUT_DIR").unwrap()
))
.unwrap();
nebula_cert_file.write_all(&nebula_cert_bin).unwrap();
codegen_version(&nebula_cert_bin, "nebula_cert.bin", "NEBULA_CERT");
// Indicate to cargo and ourselves that we have already downloaded and codegenned
File::create(format!(
"{}/{}",
std::env::var("OUT_DIR").unwrap(),
"noredownload"
))
.unwrap();
println!("cargo:rerun-if-changed=build.rs");
}
fn codegen_version(bin: &[u8], fp: &str, name: &str) {
// get version
let output = execim(bin, &vec!["-version"]);
let stdout = output.stdout;
let stdout_str = String::from_utf8(stdout).unwrap();
if !stdout_str.starts_with("Version: ") {
panic!("Binary did not have expected version output. Unable to get version info.");
}
let mut version = stdout_str.split(' ').collect::<Vec<&str>>()[1].to_string();
version.pop();
let code = format!("// This code was automatically @generated by build.rs. It should not be modified.\npub const {}_BIN: &[u8] = include_bytes!(concat!(env!(\"OUT_DIR\"), \"/{}\"));\npub const {}_VERSION: &str = \"{}\";", name, fp, name, version);
let mut file =
File::create(format!("{}/{}.rs", std::env::var("OUT_DIR").unwrap(), fp)).unwrap();
file.write_all(code.as_bytes()).unwrap();
}
#[cfg(not(unix))]
fn execim(buf: &[u8], args: &Vec<&str>) -> Output {
let mut file = File::create("tmpexec.bin").unwrap();
file.write_all(buf).unwrap();
std::mem::drop(file);
let output = Command::new("./tmpexec.bin").args(args).output().unwrap();
remove_file("./tmpexec.bin").unwrap();
output
}
#[cfg(unix)]
fn execim(buf: &[u8], args: &Vec<&str>) -> Output {
let mut file = File::create("tmpexec.bin").unwrap();
file.write_all(buf).unwrap();
let metadata = file.metadata().unwrap();
let mut permissions = metadata.permissions();
permissions.set_mode(0o0755);
fs::set_permissions("./tmpexec.bin", permissions).unwrap();
std::mem::drop(file);
let output = Command::new("./tmpexec.bin").args(args).output().unwrap();
remove_file("./tmpexec.bin").unwrap();
output
}

View File

@ -7,7 +7,7 @@ use url::Url;
use crate::config::{load_cdata, save_cdata, TFClientConfig};
use crate::daemon::ThreadMessageSender;
use crate::dirs::get_nebulaconfig_file;
use crate::dirs::nebula_yml;
use crate::nebulaworker::NebulaWorkerMessage;
pub enum APIWorkerMessage {
@ -113,8 +113,7 @@ pub fn apiworker_main(
cdata.dh_privkey = Some(dh_privkey);
match fs::write(
get_nebulaconfig_file(&instance)
.expect("Unable to determine nebula config file location"),
nebula_yml(&instance),
config,
) {
Ok(_) => (),
@ -177,8 +176,7 @@ pub fn apiworker_main(
};
match fs::write(
get_nebulaconfig_file(&instance)
.expect("Unable to determine nebula config file location"),
nebula_yml(&instance),
config,
) {
Ok(_) => (),

View File

@ -8,8 +8,7 @@ use dnapi_rs::client_blocking::EnrollMeta;
use dnapi_rs::credentials::Credentials;
use log::{debug, info};
use serde::{Deserialize, Serialize};
use crate::dirs::{get_cdata_dir, get_cdata_file, get_config_dir, get_config_file};
use crate::dirs::{config_dir, tfclient_toml, tfdata_toml};
pub const DEFAULT_PORT: u16 = 8157;
fn default_port() -> u16 {
@ -33,7 +32,7 @@ pub struct TFClientData {
pub fn create_config(instance: &str) -> Result<(), Box<dyn Error>> {
info!("Creating config directory...");
fs::create_dir_all(get_config_dir(instance).ok_or("Unable to load config dir")?)?;
fs::create_dir_all(config_dir(instance))?;
info!("Copying default config file to config directory...");
let config = TFClientConfig {
listen_port: DEFAULT_PORT,
@ -41,7 +40,7 @@ pub fn create_config(instance: &str) -> Result<(), Box<dyn Error>> {
};
let config_str = toml::to_string(&config)?;
fs::write(
get_config_file(instance).ok_or("Unable to load config dir")?,
tfclient_toml(instance),
config_str,
)?;
Ok(())
@ -49,7 +48,7 @@ pub fn create_config(instance: &str) -> Result<(), Box<dyn Error>> {
pub fn load_config(instance: &str) -> Result<TFClientConfig, Box<dyn Error>> {
info!("Loading config...");
let config_file = get_config_file(instance).ok_or("Unable to load config dir")?;
let config_file = tfclient_toml(instance);
if !config_file.exists() {
create_config(instance)?;
@ -65,7 +64,7 @@ pub fn load_config(instance: &str) -> Result<TFClientConfig, Box<dyn Error>> {
pub fn create_cdata(instance: &str) -> Result<(), Box<dyn Error>> {
info!("Creating data directory...");
fs::create_dir_all(get_cdata_dir(instance).ok_or("Unable to load data dir")?)?;
fs::create_dir_all(config_dir(instance))?;
info!("Copying default data file to config directory...");
let config = TFClientData {
dh_privkey: None,
@ -74,7 +73,7 @@ pub fn create_cdata(instance: &str) -> Result<(), Box<dyn Error>> {
};
let config_str = toml::to_string(&config)?;
fs::write(
get_cdata_file(instance).ok_or("Unable to load data dir")?,
tfdata_toml(instance),
config_str,
)?;
Ok(())
@ -82,7 +81,7 @@ pub fn create_cdata(instance: &str) -> Result<(), Box<dyn Error>> {
pub fn load_cdata(instance: &str) -> Result<TFClientData, Box<dyn Error>> {
info!("Loading cdata...");
let config_file = get_cdata_file(instance).ok_or("Unable to load cdata dir")?;
let config_file = tfdata_toml(instance);
if !config_file.exists() {
create_cdata(instance)?;
@ -98,7 +97,7 @@ pub fn load_cdata(instance: &str) -> Result<TFClientData, Box<dyn Error>> {
pub fn save_cdata(instance: &str, data: TFClientData) -> Result<(), Box<dyn Error>> {
info!("Saving cdata...");
let config_file = get_cdata_file(instance).ok_or("Unable to load cdata dir")?;
let config_file = tfdata_toml(instance);
if !config_file.exists() {
create_cdata(instance)?;

View File

@ -9,7 +9,7 @@ use crate::config::load_config;
use crate::nebulaworker::{NebulaWorkerMessage, nebulaworker_main};
use crate::socketworker::{socketworker_main, SocketWorkerMessage};
use crate::timerworker::{timer_main, TimerWorkerMessage};
use crate::util::check_server_url;
use crate::util::{check_server_url, shutdown};
pub fn daemon_main(name: String, server: String) {
// Validate the `server`
@ -44,51 +44,7 @@ pub fn daemon_main(name: String, server: String) {
match ctrlc::set_handler(move || {
info!("Ctrl-C detected. Stopping threads...");
match mainthread_transmitter
.nebula_thread
.send(NebulaWorkerMessage::Shutdown)
{
Ok(_) => (),
Err(e) => {
error!(
"Error sending shutdown message to nebula worker thread: {}",
e
);
}
}
match mainthread_transmitter
.api_thread
.send(APIWorkerMessage::Shutdown)
{
Ok(_) => (),
Err(e) => {
error!("Error sending shutdown message to api worker thread: {}", e);
}
}
match mainthread_transmitter
.socket_thread
.send(SocketWorkerMessage::Shutdown)
{
Ok(_) => (),
Err(e) => {
error!(
"Error sending shutdown message to socket worker thread: {}",
e
);
}
}
match mainthread_transmitter
.timer_thread
.send(TimerWorkerMessage::Shutdown)
{
Ok(_) => (),
Err(e) => {
error!(
"Error sending shutdown message to timer worker thread: {}",
e
);
}
}
shutdown(&mainthread_transmitter);
}) {
Ok(_) => (),
Err(e) => {
@ -124,23 +80,21 @@ pub fn daemon_main(name: String, server: String) {
});
info!("Starting timer thread...");
if !config.disable_automatic_config_updates {
let timer_transmitter = transmitter;
let timer_thread = thread::spawn(move || {
timer_main(timer_transmitter, rx_timer);
});
info!("Waiting for timer thread to exit...");
match timer_thread.join() {
Ok(_) => (),
Err(_) => {
error!("Error waiting for timer thread to exit.");
std::process::exit(1);
}
let timer_transmitter = transmitter;
let timer_thread = thread::spawn(move || {
timer_main(timer_transmitter, rx_timer, config.disable_automatic_config_updates);
});
info!("Waiting for timer thread to exit...");
match timer_thread.join() {
Ok(_) => (),
Err(_) => {
error!("Error waiting for timer thread to exit.");
std::process::exit(1);
}
info!("Timer thread exited");
} else {
info!("automatic config updates have been disabled - not starting timer thread");
}
info!("Timer thread exited");
info!("Waiting for socket thread to exit...");
match socket_thread.join() {

View File

@ -1,25 +1,44 @@
use std::path::PathBuf;
pub fn get_data_dir() -> Option<PathBuf> {
dirs::data_dir().map(|f| f.join("tfclient/"))
#[cfg(target_os = "linux")]
pub fn config_base() -> PathBuf {
PathBuf::from("/etc/tfclient")
}
#[cfg(target_os = "windows")]
pub fn config_base() -> PathBuf {
PathBuf::from("C:\\Program Data\\e3team\\tfclient")
}
#[cfg(target_os = "macos")]
pub fn config_base() -> PathBuf {
PathBuf::from("/Library/Application Support/e3team/tfclient")
}
#[cfg(target_os = "ios")]
compile_error!("tfclient cannot be compiled for iOS");
#[cfg(target_os = "android")]
compile_error!("tfclient cannot be compiled for Android");
#[cfg(target_os = "freebsd")]
pub fn config_base() -> PathBuf {
PathBuf::from("/etc/tfclient")
}
#[cfg(target_os = "dragonfly")]
compile_error!("tfclient cannot be compiled for dragonfly");
#[cfg(target_os = "openbsd")]
compile_error!("tfclient cannot be compiled for openbsd");
#[cfg(target_os = "netbsd")]
compile_error!("tfclient cannot be compiled for netbsd");
pub fn config_dir(instance: &str) -> PathBuf {
config_base().join(format!("{}/", instance))
}
pub fn get_config_dir(instance: &str) -> Option<PathBuf> {
dirs::config_dir().map(|f| f.join("tfclient/").join(format!("{}/", instance)))
pub fn tfclient_toml(instance: &str) -> PathBuf {
config_base().join(format!("{}/", instance)).join("tfclient.toml")
}
pub fn get_config_file(instance: &str) -> Option<PathBuf> {
get_config_dir(instance).map(|f| f.join("tfclient.toml"))
pub fn tfdata_toml(instance: &str) -> PathBuf {
config_base().join(format!("{}/", instance)).join("tfdata.toml")
}
pub fn get_cdata_dir(instance: &str) -> Option<PathBuf> {
dirs::config_dir().map(|f| f.join("tfclient_data/").join(format!("{}/", instance)))
}
pub fn get_cdata_file(instance: &str) -> Option<PathBuf> {
get_cdata_dir(instance).map(|f| f.join("tfclient.toml"))
}
pub fn get_nebulaconfig_file(instance: &str) -> Option<PathBuf> {
get_cdata_dir(instance).map(|f| f.join("nebula.sk_embedded.yml"))
pub fn nebula_yml(instance: &str) -> PathBuf {
config_base().join(format!("{}/", instance)).join("nebula.yml")
}

View File

@ -1,115 +0,0 @@
use crate::dirs::get_data_dir;
use crate::util::sha256;
use log::debug;
use std::error::Error;
use std::fs;
use std::fs::File;
use std::io::Write;
use std::os::unix::fs::PermissionsExt;
use std::path::PathBuf;
use std::process::{Child, Command};
pub fn extract_embedded_nebula() -> Result<PathBuf, Box<dyn Error>> {
let data_dir = get_data_dir().ok_or("Unable to get platform-specific data dir")?;
if !data_dir.exists() {
fs::create_dir_all(&data_dir)?;
debug!("Created data directory {}", data_dir.as_path().display());
}
let bin_dir = data_dir.join("cache/");
let hash_dir = bin_dir.join(format!("{}/", sha256(crate::nebula_bin::NEBULA_BIN)));
if !hash_dir.exists() {
fs::create_dir_all(&hash_dir)?;
debug!("Created directory {}", hash_dir.as_path().display());
}
let executable_postfix = if cfg!(windows) { ".exe" } else { "" };
let executable_name = format!(
"nebula-{}{}",
crate::nebula_bin::NEBULA_VERSION,
executable_postfix
);
let file_path = hash_dir.join(executable_name);
if file_path.exists() {
// Already extracted
return Ok(file_path);
}
let mut file = File::create(&file_path)?;
file.write_all(crate::nebula_bin::NEBULA_BIN)?;
debug!("Extracted nebula to {}", file_path.as_path().display());
Ok(file_path)
}
pub fn extract_embedded_nebula_cert() -> Result<PathBuf, Box<dyn Error>> {
let data_dir = get_data_dir().ok_or("Unable to get platform-specific data dir")?;
if !data_dir.exists() {
fs::create_dir_all(&data_dir)?;
debug!("Created data directory {}", data_dir.as_path().display());
}
let bin_dir = data_dir.join("cache/");
let hash_dir = bin_dir.join(format!(
"{}/",
sha256(crate::nebula_cert_bin::NEBULA_CERT_BIN)
));
if !hash_dir.exists() {
fs::create_dir_all(&hash_dir)?;
debug!("Created directory {}", hash_dir.as_path().display());
}
let executable_postfix = if cfg!(windows) { ".exe" } else { "" };
let executable_name = format!(
"nebula-cert-{}{}",
crate::nebula_cert_bin::NEBULA_CERT_VERSION,
executable_postfix
);
let file_path = hash_dir.join(executable_name);
if file_path.exists() {
// Already extracted
return Ok(file_path);
}
let mut file = File::create(&file_path)?;
file.write_all(crate::nebula_cert_bin::NEBULA_CERT_BIN)?;
debug!("Extracted nebula-cert to {}", file_path.as_path().display());
Ok(file_path)
}
#[cfg(unix)]
pub fn _setup_permissions(path: &PathBuf) -> Result<(), Box<dyn Error>> {
let meta = path.metadata()?;
let mut perms = meta.permissions();
perms.set_mode(0o0755);
debug!("Setting permissions on {} to 755", path.as_path().display());
fs::set_permissions(path, perms)?;
Ok(())
}
#[cfg(windows)]
pub fn _setup_permissions() -> Result<(), Box<dyn Error>> {
Ok(())
}
pub fn run_embedded_nebula(args: &[String]) -> Result<Child, Box<dyn Error>> {
let path = extract_embedded_nebula()?;
debug!("Running {} with args {:?}", path.as_path().display(), args);
_setup_permissions(&path)?;
Ok(Command::new(path).args(args).spawn()?)
}
pub fn run_embedded_nebula_cert(args: &[String]) -> Result<Child, Box<dyn Error>> {
let path = extract_embedded_nebula_cert()?;
debug!("Running {} with args {:?}", path.as_path().display(), args);
_setup_permissions(&path)?;
Ok(Command::new(path).args(args).spawn()?)
}

View File

@ -18,25 +18,13 @@ pub mod apiworker;
pub mod config;
pub mod daemon;
pub mod dirs;
pub mod embedded_nebula;
pub mod nebulaworker;
pub mod socketclient;
pub mod socketworker;
pub mod timerworker;
pub mod util;
pub mod nebula_bin {
include!(concat!(env!("OUT_DIR"), "/nebula.bin.rs"));
}
pub mod nebula_cert_bin {
include!(concat!(env!("OUT_DIR"), "/nebula_cert.bin.rs"));
}
use std::fs;
use crate::config::load_config;
use crate::dirs::get_data_dir;
use crate::embedded_nebula::{run_embedded_nebula, run_embedded_nebula_cert};
use clap::{ArgAction, Parser, Subcommand};
use log::{error, info};
use simple_logger::SimpleLogger;
@ -56,20 +44,6 @@ struct Cli {
#[derive(Subcommand)]
enum Commands {
/// Run the `nebula` binary. This is useful if you want to do debugging with tfclient's internal nebula.
RunNebula {
/// Arguments to pass to the `nebula` binary
#[clap(trailing_var_arg = true, allow_hyphen_values = true)]
args: Vec<String>,
},
/// Run the `nebula-cert` binary. This is useful if you want to mess with certificates. Note: tfclient does not actually use nebula-cert for certificate operations, and instead uses trifid-pki internally
RunNebulaCert {
/// Arguments to pass to the `nebula-cert` binary
#[clap(trailing_var_arg = true, allow_hyphen_values = true)]
args: Vec<String>,
},
/// Clear any cached data that tfclient may have added
ClearCache {},
/// Run the tfclient daemon in the foreground
Run {
@ -109,77 +83,6 @@ fn main() {
}
match args.subcommand {
Commands::RunNebula { args } => match run_embedded_nebula(&args) {
Ok(mut c) => match c.wait() {
Ok(stat) => match stat.code() {
Some(code) => {
if code != 0 {
error!("Nebula process exited with nonzero status code {}", code);
}
std::process::exit(code);
}
None => {
info!("Nebula process terminated by signal");
std::process::exit(0);
}
},
Err(e) => {
error!("Unable to wait for child to exit: {}", e);
std::process::exit(1);
}
},
Err(e) => {
error!("Unable to start nebula binary: {}", e);
std::process::exit(1);
}
},
Commands::ClearCache { .. } => {
let data_dir = match get_data_dir() {
Some(dir) => dir,
None => {
error!("Unable to get platform-specific data dir");
std::process::exit(1);
}
};
match fs::remove_dir_all(&data_dir) {
Ok(_) => (),
Err(e) => {
error!("Unable to delete data dir: {}", e);
std::process::exit(0);
}
}
info!("Removed data dir {}", data_dir.as_path().display());
info!("Removed all cached data.");
std::process::exit(0);
}
Commands::RunNebulaCert { args } => match run_embedded_nebula_cert(&args) {
Ok(mut c) => match c.wait() {
Ok(stat) => match stat.code() {
Some(code) => {
if code != 0 {
error!(
"nebula-cert process exited with nonzero status code {}",
code
);
}
std::process::exit(code);
}
None => {
info!("nebula-cert process terminated by signal");
std::process::exit(0);
}
},
Err(e) => {
error!("Unable to wait for child to exit: {}", e);
std::process::exit(1);
}
},
Err(e) => {
error!("Unable to start nebula-cert binary: {}", e);
std::process::exit(1);
}
},
Commands::Run { name, server } => {
daemon::daemon_main(name, server);
}
@ -222,10 +125,8 @@ fn main() {
fn print_version() {
println!(
"tfclient v{} linked to trifid-pki v{}, embedding nebula v{} and nebula-cert v{}",
"tfclient v{} linked to trifid-pki v{}",
env!("CARGO_PKG_VERSION"),
trifid_pki::TRIFID_PKI_VERSION,
crate::nebula_bin::NEBULA_VERSION,
crate::nebula_cert_bin::NEBULA_CERT_VERSION
trifid_pki::TRIFID_PKI_VERSION
);
}

View File

@ -2,13 +2,13 @@
use crate::config::{load_cdata, NebulaConfig, TFClientConfig};
use crate::daemon::ThreadMessageSender;
use crate::dirs::get_nebulaconfig_file;
use crate::embedded_nebula::run_embedded_nebula;
use crate::dirs::{nebula_yml};
use log::{debug, error, info};
use std::error::Error;
use std::fs;
use std::sync::mpsc::Receiver;
use std::time::{Duration, SystemTime};
use nebula_ffi::NebulaInstance;
use crate::util::shutdown;
pub enum NebulaWorkerMessage {
Shutdown,
@ -17,17 +17,14 @@ pub enum NebulaWorkerMessage {
}
fn insert_private_key(instance: &str) -> Result<(), Box<dyn Error>> {
if !get_nebulaconfig_file(instance)
.ok_or("Could not get config file location")?
.exists()
{
if !nebula_yml(instance).exists() {
return Ok(()); // cant insert private key into a file that does not exist - BUT. we can gracefully handle nebula crashing - we cannot gracefully handle this fn failing
}
let cdata = load_cdata(instance)?;
let key = cdata.dh_privkey.ok_or("Missing private key")?;
let config_str = fs::read_to_string(
get_nebulaconfig_file(instance).ok_or("Could not get config file location")?,
nebula_yml(instance),
)?;
let mut config: NebulaConfig = serde_yaml::from_str(&config_str)?;
@ -37,7 +34,7 @@ fn insert_private_key(instance: &str) -> Result<(), Box<dyn Error>> {
let config_str = serde_yaml::to_string(&config)?;
fs::write(
get_nebulaconfig_file(instance).ok_or("Could not get config file location")?,
nebula_yml(instance),
config_str,
)?;
@ -47,10 +44,10 @@ fn insert_private_key(instance: &str) -> Result<(), Box<dyn Error>> {
pub fn nebulaworker_main(
_config: TFClientConfig,
instance: String,
_transmitter: ThreadMessageSender,
transmitter: ThreadMessageSender,
rx: Receiver<NebulaWorkerMessage>,
) {
let _cdata = match load_cdata(&instance) {
let cdata = match load_cdata(&instance) {
Ok(data) => data,
Err(e) => {
error!("unable to load cdata: {}", e);
@ -70,50 +67,41 @@ pub fn nebulaworker_main(
return;
}
}
info!("starting nebula child...");
let mut child = match run_embedded_nebula(&[
"-config".to_string(),
get_nebulaconfig_file(&instance)
.unwrap()
.to_str()
.unwrap()
.to_string(),
]) {
Ok(c) => c,
Err(e) => {
error!("unable to start embedded nebula binary: {}", e);
error!("nebula thread exiting with error");
return;
}
};
info!("nebula process started");
let mut last_restart_time = SystemTime::now();
let mut nebula: Option<NebulaInstance> = None;
// dont need to save it, because we do not, in any circumstance, write to it
loop {
if let Ok(e) = child.try_wait() {
if e.is_some() && SystemTime::now() > last_restart_time + Duration::from_secs(5) {
info!("nebula process has exited, restarting");
child = match run_embedded_nebula(&[
"-config".to_string(),
get_nebulaconfig_file(&instance)
.unwrap()
.to_str()
.unwrap()
.to_string(),
]) {
Ok(c) => c,
if cdata.creds.is_none() {
error!("not enrolled, cannot start nebula");
} else {
info!("setting up nebula...");
nebula = Some(match NebulaInstance::new(nebula_yml(&instance).as_path(), false) {
Ok(i) => {
info!("nebula setup");
info!("starting nebula...");
match i.start() {
Ok(_) => (),
Err(e) => {
error!("unable to start embedded nebula binary: {}", e);
error!("error starting Nebula: {}", e);
error!("nebula thread exiting with error");
shutdown(&transmitter);
return;
}
};
info!("nebula process started");
last_restart_time = SystemTime::now();
}
i
},
Err(e) => {
error!("error setting up Nebula: {}", e);
error!("nebula thread exiting with error");
shutdown(&transmitter);
return;
}
}
});
info!("nebula process started");
}
loop {
match rx.recv() {
Ok(msg) => match msg {
NebulaWorkerMessage::WakeUp => {
@ -121,29 +109,25 @@ pub fn nebulaworker_main(
}
NebulaWorkerMessage::Shutdown => {
info!("recv on command socket: shutdown, stopping");
info!("shutting down nebula binary");
match child.kill() {
Ok(_) => {
debug!("nebula process exited");
}
Err(e) => {
error!("nebula process already exited: {}", e);
info!("shutting down nebula");
if let Some(i) = nebula.as_ref() {
match i.stop() {
Ok(_) => (),
Err(e) => {
error!("error stopping Nebula: {}", e);
error!("nebula thread exiting with error");
return;
}
}
}
info!("nebula shut down");
break;
}
NebulaWorkerMessage::ConfigUpdated => {
info!("our configuration has been updated - restarting");
debug!("killing existing process");
match child.kill() {
Ok(_) => {
debug!("nebula process exited");
}
Err(e) => {
error!("nebula process already exited: {}", e);
}
}
info!("our configuration has been updated - reloading");
debug!("fixing config...");
match insert_private_key(&instance) {
Ok(_) => {
@ -155,28 +139,57 @@ pub fn nebulaworker_main(
return;
}
}
debug!("restarting nebula process");
child = match run_embedded_nebula(&[
"-config".to_string(),
get_nebulaconfig_file(&instance)
.unwrap()
.to_str()
.unwrap()
.to_string(),
]) {
Ok(c) => c,
Err(e) => {
error!("unable to start embedded nebula binary: {}", e);
error!("nebula thread exiting with error");
return;
if let Some(i) = nebula.as_ref() {
debug!("reloading nebula");
match i.reload_config() {
Ok(_) => (),
Err(e) => {
error!("error reloading Nebula config: {}", e);
error!("nebula thread exiting with error");
shutdown(&transmitter);
return;
}
}
};
last_restart_time = SystemTime::now();
debug!("nebula process restarted");
debug!("config reloaded");
} else {
debug!("detected enrollment, starting nebula for the first time");
info!("setting up nebula...");
nebula = Some(match NebulaInstance::new(nebula_yml(&instance).as_path(), false) {
Ok(i) => {
info!("nebula setup");
info!("starting nebula...");
match i.start() {
Ok(_) => (),
Err(e) => {
error!("error starting Nebula: {}", e);
error!("nebula thread exiting with error");
shutdown(&transmitter);
return;
}
}
i
},
Err(e) => {
error!("error setting up Nebula: {}", e);
error!("nebula thread exiting with error");
shutdown(&transmitter);
return;
}
});
info!("nebula process started");
}
debug!("nebula process reloaded");
}
},
Err(e) => {
error!("nebulaworker command socket errored: {}", e);
shutdown(&transmitter);
return;
}
}

View File

@ -12,11 +12,11 @@ pub enum TimerWorkerMessage {
Shutdown,
}
pub fn timer_main(tx: ThreadMessageSender, rx: Receiver<TimerWorkerMessage>) {
pub fn timer_main(tx: ThreadMessageSender, rx: Receiver<TimerWorkerMessage>, disable_config_updates: bool) {
let mut api_reload_timer = SystemTime::now().add(Duration::from_secs(60));
loop {
thread::sleep(Duration::from_secs(10));
thread::sleep(Duration::from_secs(3));
match rx.try_recv() {
Ok(msg) => match msg {
@ -34,7 +34,7 @@ pub fn timer_main(tx: ThreadMessageSender, rx: Receiver<TimerWorkerMessage>) {
},
}
if SystemTime::now().gt(&api_reload_timer) {
if SystemTime::now().gt(&api_reload_timer) && !disable_config_updates {
info!("Timer triggered: API_RELOAD_TIMER");
api_reload_timer = SystemTime::now().add(Duration::from_secs(60));
match tx.api_thread.send(APIWorkerMessage::Timer) {

View File

@ -2,6 +2,11 @@ use log::{error, warn};
use sha2::Digest;
use sha2::Sha256;
use url::Url;
use crate::apiworker::APIWorkerMessage;
use crate::daemon::ThreadMessageSender;
use crate::nebulaworker::NebulaWorkerMessage;
use crate::socketworker::SocketWorkerMessage;
use crate::timerworker::TimerWorkerMessage;
pub fn sha256(bytes: &[u8]) -> String {
let mut hasher = Sha256::new();
@ -32,3 +37,51 @@ pub fn check_server_url(server: &str) {
}
}
}
pub fn shutdown(transmitter: &ThreadMessageSender) {
match transmitter
.nebula_thread
.send(NebulaWorkerMessage::Shutdown)
{
Ok(_) => (),
Err(e) => {
error!(
"Error sending shutdown message to nebula worker thread: {}",
e
);
}
}
match transmitter
.api_thread
.send(APIWorkerMessage::Shutdown)
{
Ok(_) => (),
Err(e) => {
error!("Error sending shutdown message to api worker thread: {}", e);
}
}
match transmitter
.socket_thread
.send(SocketWorkerMessage::Shutdown)
{
Ok(_) => (),
Err(e) => {
error!(
"Error sending shutdown message to socket worker thread: {}",
e
);
}
}
match transmitter
.timer_thread
.send(TimerWorkerMessage::Shutdown)
{
Ok(_) => (),
Err(e) => {
error!(
"Error sending shutdown message to timer worker thread: {}",
e
);
}
}
}