tfclient 0.2, nebula-ffi 0.1
This commit is contained in:
parent
0ffb04c1e7
commit
b7811f7531
|
@ -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_entities/src" isTestSource="false" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/trifid-api/trifid_api_migration/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$/tfcli/src" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/nebula-ffi/src" isTestSource="false" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
|
|
|
@ -14,7 +14,7 @@ version = "0.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "617a8268e3537fe1d8c9ead925fca49ef6400927ee7bc26750e90ecee14ce4b8"
|
checksum = "617a8268e3537fe1d8c9ead925fca49ef6400927ee7bc26750e90ecee14ce4b8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags 1.3.2",
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-sink",
|
"futures-sink",
|
||||||
|
@ -52,7 +52,7 @@ dependencies = [
|
||||||
"actix-utils",
|
"actix-utils",
|
||||||
"ahash 0.8.3",
|
"ahash 0.8.3",
|
||||||
"base64 0.21.0",
|
"base64 0.21.0",
|
||||||
"bitflags",
|
"bitflags 1.3.2",
|
||||||
"brotli",
|
"brotli",
|
||||||
"bytes",
|
"bytes",
|
||||||
"bytestring",
|
"bytestring",
|
||||||
|
@ -609,12 +609,41 @@ dependencies = [
|
||||||
"num-traits",
|
"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]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.3.2"
|
version = "1.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "2.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6dbe3c979c178231552ecba20214a8272df4e09f232a87aef4320cf06539aded"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitvec"
|
name = "bitvec"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
|
@ -775,6 +804,15 @@ dependencies = [
|
||||||
"jobserver",
|
"jobserver",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cexpr"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
|
||||||
|
dependencies = [
|
||||||
|
"nom",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
|
@ -813,13 +851,24 @@ dependencies = [
|
||||||
"inout",
|
"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]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "3.2.25"
|
version = "3.2.25"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123"
|
checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags 1.3.2",
|
||||||
"clap_derive 3.2.25",
|
"clap_derive 3.2.25",
|
||||||
"clap_lex 0.2.4",
|
"clap_lex 0.2.4",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
|
@ -846,7 +895,7 @@ checksum = "914c8c79fb560f238ef6429439a30023c862f7a28e688c58f7203f12b29970bd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anstream",
|
"anstream",
|
||||||
"anstyle",
|
"anstyle",
|
||||||
"bitflags",
|
"bitflags 1.3.2",
|
||||||
"clap_lex 0.4.1",
|
"clap_lex 0.4.1",
|
||||||
"strsim",
|
"strsim",
|
||||||
]
|
]
|
||||||
|
@ -1005,7 +1054,7 @@ version = "0.25.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67"
|
checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags 1.3.2",
|
||||||
"crossterm_winapi",
|
"crossterm_winapi",
|
||||||
"libc",
|
"libc",
|
||||||
"mio",
|
"mio",
|
||||||
|
@ -1511,6 +1560,12 @@ dependencies = [
|
||||||
"polyval",
|
"polyval",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "glob"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gloo-timers"
|
name = "gloo-timers"
|
||||||
version = "0.2.6"
|
version = "0.2.6"
|
||||||
|
@ -1523,6 +1578,15 @@ dependencies = [
|
||||||
"wasm-bindgen",
|
"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]]
|
[[package]]
|
||||||
name = "h2"
|
name = "h2"
|
||||||
version = "0.3.19"
|
version = "0.3.19"
|
||||||
|
@ -1860,12 +1924,28 @@ version = "1.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazycell"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.144"
|
version = "0.2.144"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1"
|
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]]
|
[[package]]
|
||||||
name = "libm"
|
name = "libm"
|
||||||
version = "0.1.4"
|
version = "0.1.4"
|
||||||
|
@ -1991,13 +2071,21 @@ dependencies = [
|
||||||
"tempfile",
|
"tempfile",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nebula-ffi"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"bindgen",
|
||||||
|
"gobuild",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nix"
|
name = "nix"
|
||||||
version = "0.26.2"
|
version = "0.26.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a"
|
checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags 1.3.2",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
"static_assertions",
|
"static_assertions",
|
||||||
|
@ -2080,7 +2168,7 @@ version = "0.10.52"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "01b8574602df80f7b85fdfc5392fa884a4e3b3f4f35402c070ab34c3d3f78d56"
|
checksum = "01b8574602df80f7b85fdfc5392fa884a4e3b3f4f35402c070ab34c3d3f78d56"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags 1.3.2",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"foreign-types",
|
"foreign-types",
|
||||||
"libc",
|
"libc",
|
||||||
|
@ -2233,6 +2321,12 @@ version = "1.0.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79"
|
checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "peeking_take_while"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pem"
|
name = "pem"
|
||||||
version = "1.1.1"
|
version = "1.1.1"
|
||||||
|
@ -2289,7 +2383,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce"
|
checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"bitflags",
|
"bitflags 1.3.2",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"concurrent-queue",
|
"concurrent-queue",
|
||||||
"libc",
|
"libc",
|
||||||
|
@ -2316,6 +2410,16 @@ version = "0.2.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
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]]
|
[[package]]
|
||||||
name = "proc-macro-crate"
|
name = "proc-macro-crate"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
|
@ -2457,7 +2561,7 @@ version = "0.2.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
|
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags 1.3.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2466,7 +2570,7 @@ version = "0.3.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
|
checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags 1.3.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2619,6 +2723,12 @@ dependencies = [
|
||||||
"serde_json",
|
"serde_json",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-hash"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc_version"
|
name = "rustc_version"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
|
@ -2634,7 +2744,7 @@ version = "0.37.19"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d"
|
checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags 1.3.2",
|
||||||
"errno",
|
"errno",
|
||||||
"io-lifetimes",
|
"io-lifetimes",
|
||||||
"libc",
|
"libc",
|
||||||
|
@ -2875,7 +2985,7 @@ version = "2.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ca2855b3715770894e67cbfa3df957790aa0c9edc3bf06efa1a84d77fa0839d1"
|
checksum = "ca2855b3715770894e67cbfa3df957790aa0c9edc3bf06efa1a84d77fa0839d1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags 1.3.2",
|
||||||
"core-foundation",
|
"core-foundation",
|
||||||
"core-foundation-sys",
|
"core-foundation-sys",
|
||||||
"libc",
|
"libc",
|
||||||
|
@ -3022,6 +3132,12 @@ dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "shlex"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "signal-hook"
|
name = "signal-hook"
|
||||||
version = "0.3.15"
|
version = "0.3.15"
|
||||||
|
@ -3149,7 +3265,7 @@ dependencies = [
|
||||||
"atoi",
|
"atoi",
|
||||||
"base64 0.13.1",
|
"base64 0.13.1",
|
||||||
"bigdecimal",
|
"bigdecimal",
|
||||||
"bitflags",
|
"bitflags 1.3.2",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"bytes",
|
"bytes",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
@ -3330,7 +3446,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tfclient"
|
name = "tfclient"
|
||||||
version = "0.1.8"
|
version = "0.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.21.0",
|
"base64 0.21.0",
|
||||||
"base64-serde",
|
"base64-serde",
|
||||||
|
@ -3343,6 +3459,7 @@ dependencies = [
|
||||||
"hex",
|
"hex",
|
||||||
"ipnet",
|
"ipnet",
|
||||||
"log",
|
"log",
|
||||||
|
"nebula-ffi",
|
||||||
"openssl-sys",
|
"openssl-sys",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -3956,6 +4073,17 @@ dependencies = [
|
||||||
"webpki",
|
"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]]
|
[[package]]
|
||||||
name = "whoami"
|
name = "whoami"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
|
|
|
@ -6,5 +6,6 @@ members = [
|
||||||
"tfclient",
|
"tfclient",
|
||||||
"trifid-pki",
|
"trifid-pki",
|
||||||
"dnapi-rs",
|
"dnapi-rs",
|
||||||
"tfcli"
|
"tfcli",
|
||||||
|
"nebula-ffi"
|
||||||
]
|
]
|
|
@ -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"
|
|
@ -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.
|
|
@ -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!");
|
||||||
|
}
|
|
@ -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
|
||||||
|
)
|
|
@ -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=
|
|
@ -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() {}
|
|
@ -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() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "tfclient"
|
name = "tfclient"
|
||||||
version = "0.1.8"
|
version = "0.2.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "An open-source reimplementation of a Defined Networking-compatible client"
|
description = "An open-source reimplementation of a Defined Networking-compatible client"
|
||||||
license = "GPL-3.0-or-later"
|
license = "GPL-3.0-or-later"
|
||||||
|
@ -31,6 +31,7 @@ base64-serde = "0.7.0"
|
||||||
dnapi-rs = { version = "0.1", path = "../dnapi-rs" }
|
dnapi-rs = { version = "0.1", path = "../dnapi-rs" }
|
||||||
serde_yaml = "0.9.19"
|
serde_yaml = "0.9.19"
|
||||||
openssl-sys = { version = "0.9.83", features = ["vendored"] }
|
openssl-sys = { version = "0.9.83", features = ["vendored"] }
|
||||||
|
nebula-ffi = { version = "0.1", path = "../nebula-ffi" }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
serde = { version = "1.0.157", features = ["derive"] }
|
serde = { version = "1.0.157", features = ["derive"] }
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -7,7 +7,7 @@ use url::Url;
|
||||||
|
|
||||||
use crate::config::{load_cdata, save_cdata, TFClientConfig};
|
use crate::config::{load_cdata, save_cdata, TFClientConfig};
|
||||||
use crate::daemon::ThreadMessageSender;
|
use crate::daemon::ThreadMessageSender;
|
||||||
use crate::dirs::get_nebulaconfig_file;
|
use crate::dirs::nebula_yml;
|
||||||
use crate::nebulaworker::NebulaWorkerMessage;
|
use crate::nebulaworker::NebulaWorkerMessage;
|
||||||
|
|
||||||
pub enum APIWorkerMessage {
|
pub enum APIWorkerMessage {
|
||||||
|
@ -113,8 +113,7 @@ pub fn apiworker_main(
|
||||||
cdata.dh_privkey = Some(dh_privkey);
|
cdata.dh_privkey = Some(dh_privkey);
|
||||||
|
|
||||||
match fs::write(
|
match fs::write(
|
||||||
get_nebulaconfig_file(&instance)
|
nebula_yml(&instance),
|
||||||
.expect("Unable to determine nebula config file location"),
|
|
||||||
config,
|
config,
|
||||||
) {
|
) {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
|
@ -177,8 +176,7 @@ pub fn apiworker_main(
|
||||||
};
|
};
|
||||||
|
|
||||||
match fs::write(
|
match fs::write(
|
||||||
get_nebulaconfig_file(&instance)
|
nebula_yml(&instance),
|
||||||
.expect("Unable to determine nebula config file location"),
|
|
||||||
config,
|
config,
|
||||||
) {
|
) {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
|
|
|
@ -8,8 +8,7 @@ use dnapi_rs::client_blocking::EnrollMeta;
|
||||||
use dnapi_rs::credentials::Credentials;
|
use dnapi_rs::credentials::Credentials;
|
||||||
use log::{debug, info};
|
use log::{debug, info};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use crate::dirs::{config_dir, tfclient_toml, tfdata_toml};
|
||||||
use crate::dirs::{get_cdata_dir, get_cdata_file, get_config_dir, get_config_file};
|
|
||||||
|
|
||||||
pub const DEFAULT_PORT: u16 = 8157;
|
pub const DEFAULT_PORT: u16 = 8157;
|
||||||
fn default_port() -> u16 {
|
fn default_port() -> u16 {
|
||||||
|
@ -33,7 +32,7 @@ pub struct TFClientData {
|
||||||
|
|
||||||
pub fn create_config(instance: &str) -> Result<(), Box<dyn Error>> {
|
pub fn create_config(instance: &str) -> Result<(), Box<dyn Error>> {
|
||||||
info!("Creating config directory...");
|
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...");
|
info!("Copying default config file to config directory...");
|
||||||
let config = TFClientConfig {
|
let config = TFClientConfig {
|
||||||
listen_port: DEFAULT_PORT,
|
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)?;
|
let config_str = toml::to_string(&config)?;
|
||||||
fs::write(
|
fs::write(
|
||||||
get_config_file(instance).ok_or("Unable to load config dir")?,
|
tfclient_toml(instance),
|
||||||
config_str,
|
config_str,
|
||||||
)?;
|
)?;
|
||||||
Ok(())
|
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>> {
|
pub fn load_config(instance: &str) -> Result<TFClientConfig, Box<dyn Error>> {
|
||||||
info!("Loading config...");
|
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() {
|
if !config_file.exists() {
|
||||||
create_config(instance)?;
|
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>> {
|
pub fn create_cdata(instance: &str) -> Result<(), Box<dyn Error>> {
|
||||||
info!("Creating data directory...");
|
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...");
|
info!("Copying default data file to config directory...");
|
||||||
let config = TFClientData {
|
let config = TFClientData {
|
||||||
dh_privkey: None,
|
dh_privkey: None,
|
||||||
|
@ -74,7 +73,7 @@ pub fn create_cdata(instance: &str) -> Result<(), Box<dyn Error>> {
|
||||||
};
|
};
|
||||||
let config_str = toml::to_string(&config)?;
|
let config_str = toml::to_string(&config)?;
|
||||||
fs::write(
|
fs::write(
|
||||||
get_cdata_file(instance).ok_or("Unable to load data dir")?,
|
tfdata_toml(instance),
|
||||||
config_str,
|
config_str,
|
||||||
)?;
|
)?;
|
||||||
Ok(())
|
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>> {
|
pub fn load_cdata(instance: &str) -> Result<TFClientData, Box<dyn Error>> {
|
||||||
info!("Loading cdata...");
|
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() {
|
if !config_file.exists() {
|
||||||
create_cdata(instance)?;
|
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>> {
|
pub fn save_cdata(instance: &str, data: TFClientData) -> Result<(), Box<dyn Error>> {
|
||||||
info!("Saving cdata...");
|
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() {
|
if !config_file.exists() {
|
||||||
create_cdata(instance)?;
|
create_cdata(instance)?;
|
||||||
|
|
|
@ -9,7 +9,7 @@ use crate::config::load_config;
|
||||||
use crate::nebulaworker::{NebulaWorkerMessage, nebulaworker_main};
|
use crate::nebulaworker::{NebulaWorkerMessage, nebulaworker_main};
|
||||||
use crate::socketworker::{socketworker_main, SocketWorkerMessage};
|
use crate::socketworker::{socketworker_main, SocketWorkerMessage};
|
||||||
use crate::timerworker::{timer_main, TimerWorkerMessage};
|
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) {
|
pub fn daemon_main(name: String, server: String) {
|
||||||
// Validate the `server`
|
// Validate the `server`
|
||||||
|
@ -44,51 +44,7 @@ pub fn daemon_main(name: String, server: String) {
|
||||||
|
|
||||||
match ctrlc::set_handler(move || {
|
match ctrlc::set_handler(move || {
|
||||||
info!("Ctrl-C detected. Stopping threads...");
|
info!("Ctrl-C detected. Stopping threads...");
|
||||||
match mainthread_transmitter
|
shutdown(&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
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}) {
|
}) {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
@ -124,23 +80,21 @@ pub fn daemon_main(name: String, server: String) {
|
||||||
});
|
});
|
||||||
|
|
||||||
info!("Starting timer thread...");
|
info!("Starting timer thread...");
|
||||||
if !config.disable_automatic_config_updates {
|
|
||||||
let timer_transmitter = transmitter;
|
let timer_transmitter = transmitter;
|
||||||
let timer_thread = thread::spawn(move || {
|
let timer_thread = thread::spawn(move || {
|
||||||
timer_main(timer_transmitter, rx_timer);
|
timer_main(timer_transmitter, rx_timer, config.disable_automatic_config_updates);
|
||||||
});
|
});
|
||||||
info!("Waiting for timer thread to exit...");
|
info!("Waiting for timer thread to exit...");
|
||||||
match timer_thread.join() {
|
match timer_thread.join() {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
error!("Error waiting for timer thread to exit.");
|
error!("Error waiting for timer thread to exit.");
|
||||||
std::process::exit(1);
|
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...");
|
info!("Waiting for socket thread to exit...");
|
||||||
match socket_thread.join() {
|
match socket_thread.join() {
|
||||||
|
|
|
@ -1,25 +1,44 @@
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
pub fn get_data_dir() -> Option<PathBuf> {
|
#[cfg(target_os = "linux")]
|
||||||
dirs::data_dir().map(|f| f.join("tfclient/"))
|
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> {
|
pub fn tfclient_toml(instance: &str) -> PathBuf {
|
||||||
dirs::config_dir().map(|f| f.join("tfclient/").join(format!("{}/", instance)))
|
config_base().join(format!("{}/", instance)).join("tfclient.toml")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_config_file(instance: &str) -> Option<PathBuf> {
|
pub fn tfdata_toml(instance: &str) -> PathBuf {
|
||||||
get_config_dir(instance).map(|f| f.join("tfclient.toml"))
|
config_base().join(format!("{}/", instance)).join("tfdata.toml")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_cdata_dir(instance: &str) -> Option<PathBuf> {
|
pub fn nebula_yml(instance: &str) -> PathBuf {
|
||||||
dirs::config_dir().map(|f| f.join("tfclient_data/").join(format!("{}/", instance)))
|
config_base().join(format!("{}/", instance)).join("nebula.yml")
|
||||||
}
|
|
||||||
|
|
||||||
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"))
|
|
||||||
}
|
}
|
|
@ -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()?)
|
|
||||||
}
|
|
|
@ -18,25 +18,13 @@ pub mod apiworker;
|
||||||
pub mod config;
|
pub mod config;
|
||||||
pub mod daemon;
|
pub mod daemon;
|
||||||
pub mod dirs;
|
pub mod dirs;
|
||||||
pub mod embedded_nebula;
|
|
||||||
pub mod nebulaworker;
|
pub mod nebulaworker;
|
||||||
pub mod socketclient;
|
pub mod socketclient;
|
||||||
pub mod socketworker;
|
pub mod socketworker;
|
||||||
pub mod timerworker;
|
pub mod timerworker;
|
||||||
pub mod util;
|
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::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 clap::{ArgAction, Parser, Subcommand};
|
||||||
use log::{error, info};
|
use log::{error, info};
|
||||||
use simple_logger::SimpleLogger;
|
use simple_logger::SimpleLogger;
|
||||||
|
@ -56,20 +44,6 @@ struct Cli {
|
||||||
|
|
||||||
#[derive(Subcommand)]
|
#[derive(Subcommand)]
|
||||||
enum Commands {
|
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 the tfclient daemon in the foreground
|
||||||
Run {
|
Run {
|
||||||
|
@ -109,77 +83,6 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
match args.subcommand {
|
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 } => {
|
Commands::Run { name, server } => {
|
||||||
daemon::daemon_main(name, server);
|
daemon::daemon_main(name, server);
|
||||||
}
|
}
|
||||||
|
@ -222,10 +125,8 @@ fn main() {
|
||||||
|
|
||||||
fn print_version() {
|
fn print_version() {
|
||||||
println!(
|
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"),
|
env!("CARGO_PKG_VERSION"),
|
||||||
trifid_pki::TRIFID_PKI_VERSION,
|
trifid_pki::TRIFID_PKI_VERSION
|
||||||
crate::nebula_bin::NEBULA_VERSION,
|
|
||||||
crate::nebula_cert_bin::NEBULA_CERT_VERSION
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
|
|
||||||
use crate::config::{load_cdata, NebulaConfig, TFClientConfig};
|
use crate::config::{load_cdata, NebulaConfig, TFClientConfig};
|
||||||
use crate::daemon::ThreadMessageSender;
|
use crate::daemon::ThreadMessageSender;
|
||||||
use crate::dirs::get_nebulaconfig_file;
|
use crate::dirs::{nebula_yml};
|
||||||
use crate::embedded_nebula::run_embedded_nebula;
|
|
||||||
use log::{debug, error, info};
|
use log::{debug, error, info};
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::sync::mpsc::Receiver;
|
use std::sync::mpsc::Receiver;
|
||||||
use std::time::{Duration, SystemTime};
|
use nebula_ffi::NebulaInstance;
|
||||||
|
use crate::util::shutdown;
|
||||||
|
|
||||||
pub enum NebulaWorkerMessage {
|
pub enum NebulaWorkerMessage {
|
||||||
Shutdown,
|
Shutdown,
|
||||||
|
@ -17,17 +17,14 @@ pub enum NebulaWorkerMessage {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert_private_key(instance: &str) -> Result<(), Box<dyn Error>> {
|
fn insert_private_key(instance: &str) -> Result<(), Box<dyn Error>> {
|
||||||
if !get_nebulaconfig_file(instance)
|
if !nebula_yml(instance).exists() {
|
||||||
.ok_or("Could not get config file location")?
|
|
||||||
.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
|
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 cdata = load_cdata(instance)?;
|
||||||
let key = cdata.dh_privkey.ok_or("Missing private key")?;
|
let key = cdata.dh_privkey.ok_or("Missing private key")?;
|
||||||
|
|
||||||
let config_str = fs::read_to_string(
|
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)?;
|
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)?;
|
let config_str = serde_yaml::to_string(&config)?;
|
||||||
fs::write(
|
fs::write(
|
||||||
get_nebulaconfig_file(instance).ok_or("Could not get config file location")?,
|
nebula_yml(instance),
|
||||||
config_str,
|
config_str,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -47,10 +44,10 @@ fn insert_private_key(instance: &str) -> Result<(), Box<dyn Error>> {
|
||||||
pub fn nebulaworker_main(
|
pub fn nebulaworker_main(
|
||||||
_config: TFClientConfig,
|
_config: TFClientConfig,
|
||||||
instance: String,
|
instance: String,
|
||||||
_transmitter: ThreadMessageSender,
|
transmitter: ThreadMessageSender,
|
||||||
rx: Receiver<NebulaWorkerMessage>,
|
rx: Receiver<NebulaWorkerMessage>,
|
||||||
) {
|
) {
|
||||||
let _cdata = match load_cdata(&instance) {
|
let cdata = match load_cdata(&instance) {
|
||||||
Ok(data) => data,
|
Ok(data) => data,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("unable to load cdata: {}", e);
|
error!("unable to load cdata: {}", e);
|
||||||
|
@ -70,50 +67,41 @@ pub fn nebulaworker_main(
|
||||||
return;
|
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
|
if cdata.creds.is_none() {
|
||||||
loop {
|
error!("not enrolled, cannot start nebula");
|
||||||
if let Ok(e) = child.try_wait() {
|
} else {
|
||||||
if e.is_some() && SystemTime::now() > last_restart_time + Duration::from_secs(5) {
|
info!("setting up nebula...");
|
||||||
info!("nebula process has exited, restarting");
|
nebula = Some(match NebulaInstance::new(nebula_yml(&instance).as_path(), false) {
|
||||||
child = match run_embedded_nebula(&[
|
Ok(i) => {
|
||||||
"-config".to_string(),
|
info!("nebula setup");
|
||||||
get_nebulaconfig_file(&instance)
|
info!("starting nebula...");
|
||||||
.unwrap()
|
match i.start() {
|
||||||
.to_str()
|
Ok(_) => (),
|
||||||
.unwrap()
|
|
||||||
.to_string(),
|
|
||||||
]) {
|
|
||||||
Ok(c) => c,
|
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("unable to start embedded nebula binary: {}", e);
|
error!("error starting Nebula: {}", e);
|
||||||
error!("nebula thread exiting with error");
|
error!("nebula thread exiting with error");
|
||||||
|
shutdown(&transmitter);
|
||||||
return;
|
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() {
|
match rx.recv() {
|
||||||
Ok(msg) => match msg {
|
Ok(msg) => match msg {
|
||||||
NebulaWorkerMessage::WakeUp => {
|
NebulaWorkerMessage::WakeUp => {
|
||||||
|
@ -121,29 +109,25 @@ pub fn nebulaworker_main(
|
||||||
}
|
}
|
||||||
NebulaWorkerMessage::Shutdown => {
|
NebulaWorkerMessage::Shutdown => {
|
||||||
info!("recv on command socket: shutdown, stopping");
|
info!("recv on command socket: shutdown, stopping");
|
||||||
info!("shutting down nebula binary");
|
info!("shutting down nebula");
|
||||||
match child.kill() {
|
|
||||||
Ok(_) => {
|
if let Some(i) = nebula.as_ref() {
|
||||||
debug!("nebula process exited");
|
match i.stop() {
|
||||||
}
|
Ok(_) => (),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("nebula process already exited: {}", e);
|
error!("error stopping Nebula: {}", e);
|
||||||
|
error!("nebula thread exiting with error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
info!("nebula shut down");
|
info!("nebula shut down");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
NebulaWorkerMessage::ConfigUpdated => {
|
NebulaWorkerMessage::ConfigUpdated => {
|
||||||
info!("our configuration has been updated - restarting");
|
info!("our configuration has been updated - reloading");
|
||||||
debug!("killing existing process");
|
|
||||||
match child.kill() {
|
|
||||||
Ok(_) => {
|
|
||||||
debug!("nebula process exited");
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
error!("nebula process already exited: {}", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
debug!("fixing config...");
|
debug!("fixing config...");
|
||||||
match insert_private_key(&instance) {
|
match insert_private_key(&instance) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
|
@ -155,28 +139,57 @@ pub fn nebulaworker_main(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
debug!("restarting nebula process");
|
|
||||||
child = match run_embedded_nebula(&[
|
if let Some(i) = nebula.as_ref() {
|
||||||
"-config".to_string(),
|
debug!("reloading nebula");
|
||||||
get_nebulaconfig_file(&instance)
|
|
||||||
.unwrap()
|
match i.reload_config() {
|
||||||
.to_str()
|
Ok(_) => (),
|
||||||
.unwrap()
|
Err(e) => {
|
||||||
.to_string(),
|
error!("error reloading Nebula config: {}", e);
|
||||||
]) {
|
error!("nebula thread exiting with error");
|
||||||
Ok(c) => c,
|
shutdown(&transmitter);
|
||||||
Err(e) => {
|
return;
|
||||||
error!("unable to start embedded nebula binary: {}", e);
|
}
|
||||||
error!("nebula thread exiting with error");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
last_restart_time = SystemTime::now();
|
debug!("config reloaded");
|
||||||
debug!("nebula process restarted");
|
} 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) => {
|
Err(e) => {
|
||||||
error!("nebulaworker command socket errored: {}", e);
|
error!("nebulaworker command socket errored: {}", e);
|
||||||
|
shutdown(&transmitter);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,11 +12,11 @@ pub enum TimerWorkerMessage {
|
||||||
Shutdown,
|
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));
|
let mut api_reload_timer = SystemTime::now().add(Duration::from_secs(60));
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
thread::sleep(Duration::from_secs(10));
|
thread::sleep(Duration::from_secs(3));
|
||||||
|
|
||||||
match rx.try_recv() {
|
match rx.try_recv() {
|
||||||
Ok(msg) => match msg {
|
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");
|
info!("Timer triggered: API_RELOAD_TIMER");
|
||||||
api_reload_timer = SystemTime::now().add(Duration::from_secs(60));
|
api_reload_timer = SystemTime::now().add(Duration::from_secs(60));
|
||||||
match tx.api_thread.send(APIWorkerMessage::Timer) {
|
match tx.api_thread.send(APIWorkerMessage::Timer) {
|
||||||
|
|
|
@ -2,6 +2,11 @@ use log::{error, warn};
|
||||||
use sha2::Digest;
|
use sha2::Digest;
|
||||||
use sha2::Sha256;
|
use sha2::Sha256;
|
||||||
use url::Url;
|
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 {
|
pub fn sha256(bytes: &[u8]) -> String {
|
||||||
let mut hasher = Sha256::new();
|
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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue