Add Rust bindings (WIP)
This commit is contained in:
336
pkg/crate/libzt/Cargo.lock
generated
Normal file
336
pkg/crate/libzt/Cargo.lock
generated
Normal file
@@ -0,0 +1,336 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bindgen"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd4865004a46a0aafb2a0a5eb19d3c9fc46ee5f063a6cfc605c69ac9ecf5263d"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cexpr",
|
||||
"clang-sys",
|
||||
"clap",
|
||||
"env_logger",
|
||||
"lazy_static",
|
||||
"lazycell",
|
||||
"log",
|
||||
"peeking_take_while",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"rustc-hash",
|
||||
"shlex",
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
|
||||
[[package]]
|
||||
name = "cexpr"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27"
|
||||
dependencies = [
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "clang-sys"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "853eda514c284c2287f4bf20ae614f8781f40a81d32ecda6e91449304dfe077c"
|
||||
dependencies = [
|
||||
"glob",
|
||||
"libc",
|
||||
"libloading",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.33.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"atty",
|
||||
"bitflags",
|
||||
"strsim",
|
||||
"textwrap",
|
||||
"unicode-width",
|
||||
"vec_map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17392a012ea30ef05a610aa97dfb49496e71c9f676b27879922ea5bdf60d9d3f"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"humantime",
|
||||
"log",
|
||||
"regex",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "lazycell"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.94"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f84d96438c15fcd6c3f244c8fce01d1e2b9c6b5623e9c711dc9286d8fc92d6a"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libzt"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bindgen",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "5.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "peeking_take_while"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce5f1ceb7f74abbce32601642fcf8e8508a8a8991e0621c7d750295b9095702b"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||
dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
|
||||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "3.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
27
pkg/crate/libzt/Cargo.toml
Normal file
27
pkg/crate/libzt/Cargo.toml
Normal file
@@ -0,0 +1,27 @@
|
||||
[package]
|
||||
name = "libzt"
|
||||
version = "0.1.0"
|
||||
authors = ["Joseph Henry <joseph.henry@zerotier.com>"]
|
||||
edition = "2018"
|
||||
description = "Encrypted P2P SD-WAN library by ZeroTier"
|
||||
documentation = "https://github.com/zerotier/libzt"
|
||||
readme = "README.md"
|
||||
homepage = "https://www.zerotier.com"
|
||||
license-file = "LICENSE.txt"
|
||||
keywords = ["zerotier", "p2p", "vpn", "socket", "network"]
|
||||
categories = ["network-programming", "cryptography"]
|
||||
|
||||
[dependencies]
|
||||
|
||||
[build-dependencies]
|
||||
bindgen = "0.57"
|
||||
libc = "0.2"
|
||||
|
||||
[lib]
|
||||
name = "libzt"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "libzt-test-app"
|
||||
path = "src/bin/libzt-test-app.rs"
|
||||
|
||||
631
pkg/crate/libzt/LICENSE.txt
Normal file
631
pkg/crate/libzt/LICENSE.txt
Normal file
@@ -0,0 +1,631 @@
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
Business Source License 1.1
|
||||
|
||||
License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved.
|
||||
"Business Source License" is a trademark of MariaDB Corporation Ab.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
Parameters
|
||||
|
||||
Licensor: ZeroTier, Inc.
|
||||
Licensed Work: ZeroTier Network Virtualization Engine 1.4.4
|
||||
The Licensed Work is (c)2019 ZeroTier, Inc.
|
||||
Additional Use Grant: You may make use of the Licensed Work, provided you
|
||||
do not use it in any of the following ways:
|
||||
|
||||
* Sell hosted ZeroTier services as a "SaaS" Product
|
||||
|
||||
(1) Operate or sell access to ZeroTier root servers,
|
||||
network controllers, or authorization key or certificate
|
||||
generation components of the Licensed Work as a
|
||||
for-profit service, regardless of whether the use of
|
||||
these components is sold alone or is bundled with other
|
||||
services. Note that this does not apply to the use of
|
||||
ZeroTier behind the scenes to operate a service not
|
||||
related to ZeroTier network administration.
|
||||
|
||||
* Create Non-Open-Source Commercial Derviative Works
|
||||
|
||||
(2) Link or directly include the Licensed Work in a
|
||||
commercial or for-profit application or other product
|
||||
not distributed under an Open Source Initiative (OSI)
|
||||
compliant license. See: https://opensource.org/licenses
|
||||
|
||||
(3) Remove the name, logo, copyright, or other branding
|
||||
material from the Licensed Work to create a "rebranded"
|
||||
or "white labeled" version to distribute as part of
|
||||
any commercial or for-profit product or service.
|
||||
|
||||
* Certain Government Uses
|
||||
|
||||
(4) Use or deploy the Licensed Work in a government
|
||||
setting in support of any active government function
|
||||
or operation with the exception of the following:
|
||||
physical or mental health care, family and social
|
||||
services, social welfare, senior care, child care, and
|
||||
the care of persons with disabilities.
|
||||
|
||||
Change Date: 2023-01-01
|
||||
|
||||
Change License: Apache License version 2.0 as published by the Apache
|
||||
Software Foundation
|
||||
https://www.apache.org/licenses/
|
||||
|
||||
Alternative Licensing
|
||||
|
||||
If you would like to use the Licensed Work in any way that conflicts with
|
||||
the stipulations of the Additional Use Grant, contact ZeroTier, Inc. to
|
||||
obtain an alternative commercial license.
|
||||
|
||||
Visit us on the web at: https://www.zerotier.com/
|
||||
|
||||
Notice
|
||||
|
||||
The Business Source License (this document, or the "License") is not an Open
|
||||
Source license. However, the Licensed Work will eventually be made available
|
||||
under an Open Source License, as stated in this License.
|
||||
|
||||
For more information on the use of the Business Source License for ZeroTier
|
||||
products, please visit our pricing page which contains license details and
|
||||
and license FAQ: https://zerotier.com/pricing
|
||||
|
||||
For more information on the use of the Business Source License generally,
|
||||
please visit the Adopting and Developing Business Source License FAQ at
|
||||
https://mariadb.com/bsl-faq-adopting.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
Business Source License 1.1
|
||||
|
||||
Terms
|
||||
|
||||
The Licensor hereby grants you the right to copy, modify, create derivative
|
||||
works, redistribute, and make non-production use of the Licensed Work. The
|
||||
Licensor may make an Additional Use Grant, above, permitting limited
|
||||
production use.
|
||||
|
||||
Effective on the Change Date, or the fourth anniversary of the first publicly
|
||||
available distribution of a specific version of the Licensed Work under this
|
||||
License, whichever comes first, the Licensor hereby grants you rights under
|
||||
the terms of the Change License, and the rights granted in the paragraph
|
||||
above terminate.
|
||||
|
||||
If your use of the Licensed Work does not comply with the requirements
|
||||
currently in effect as described in this License, you must purchase a
|
||||
commercial license from the Licensor, its affiliated entities, or authorized
|
||||
resellers, or you must refrain from using the Licensed Work.
|
||||
|
||||
All copies of the original and modified Licensed Work, and derivative works
|
||||
of the Licensed Work, are subject to this License. This License applies
|
||||
separately for each version of the Licensed Work and the Change Date may vary
|
||||
for each version of the Licensed Work released by Licensor.
|
||||
|
||||
You must conspicuously display this License on each original or modified copy
|
||||
of the Licensed Work. If you receive the Licensed Work in original or
|
||||
modified form from a third party, the terms and conditions set forth in this
|
||||
License apply to your use of that work.
|
||||
|
||||
Any use of the Licensed Work in violation of this License will automatically
|
||||
terminate your rights under this License for the current and all other
|
||||
versions of the Licensed Work.
|
||||
|
||||
This License does not grant you any right in any trademark or logo of
|
||||
Licensor or its affiliates (provided that you may use a trademark or logo of
|
||||
Licensor as expressly required by this License).
|
||||
|
||||
TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
|
||||
AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
|
||||
EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
|
||||
TITLE.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
MariaDB hereby grants you permission to use this License’s text to license
|
||||
your works, and to refer to it using the trademark "Business Source License",
|
||||
as long as you comply with the Covenants of Licensor below.
|
||||
|
||||
Covenants of Licensor
|
||||
|
||||
In consideration of the right to use this License’s text and the "Business
|
||||
Source License" name and trademark, Licensor covenants to MariaDB, and to all
|
||||
other recipients of the licensed work to be provided by Licensor:
|
||||
|
||||
1. To specify as the Change License the GPL Version 2.0 or any later version,
|
||||
or a license that is compatible with GPL Version 2.0 or a later version,
|
||||
where "compatible" means that software provided under the Change License can
|
||||
be included in a program with software provided under GPL Version 2.0 or a
|
||||
later version. Licensor may specify additional Change Licenses without
|
||||
limitation.
|
||||
|
||||
2. To either: (a) specify an additional grant of rights to use that does not
|
||||
impose any additional restriction on the right granted in this License, as
|
||||
the Additional Use Grant; or (b) insert the text "None".
|
||||
|
||||
3. To specify a Change Date.
|
||||
|
||||
4. Not to modify this License in any other way.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
END OF Business Source License 1.1
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Portions of the Rust crate that wraps the functionality of libzt into an
|
||||
idiomatic interface are derived from the Rust standard library. The standard
|
||||
library's copyright and associated licenses are reproduced below. The copyright
|
||||
and its licenses only apply to the code derived from the Rust standard library
|
||||
and not libzt or ZeroTier. libzt and ZeroTier are subject to the BUSL-1.1
|
||||
license reproduced above.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Short version for non-lawyers:
|
||||
|
||||
The Rust Project is dual-licensed under Apache 2.0 and MIT
|
||||
terms.
|
||||
|
||||
|
||||
Longer version:
|
||||
|
||||
Copyrights in the Rust project are retained by their contributors. No
|
||||
copyright assignment is required to contribute to the Rust project.
|
||||
|
||||
Some files include explicit copyright notices and/or license notices.
|
||||
For full authorship information, see the version control history or
|
||||
https://thanks.rust-lang.org
|
||||
|
||||
Except as otherwise noted (below and/or in individual files), Rust is
|
||||
licensed under the Apache License, Version 2.0 <LICENSE-APACHE> or
|
||||
<http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
<LICENSE-MIT> or <http://opensource.org/licenses/MIT>, at your option.
|
||||
|
||||
|
||||
The Rust Project includes packages written by third parties.
|
||||
The following third party packages are included, and carry
|
||||
their own copyright notices and license terms:
|
||||
|
||||
* LLVM. Code for this package is found in src/llvm-project.
|
||||
|
||||
Copyright (c) 2003-2013 University of Illinois at
|
||||
Urbana-Champaign. All rights reserved.
|
||||
|
||||
Developed by:
|
||||
|
||||
LLVM Team
|
||||
|
||||
University of Illinois at Urbana-Champaign
|
||||
|
||||
http://llvm.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any
|
||||
person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal with the
|
||||
Software without restriction, including without
|
||||
limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software
|
||||
is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
* Redistributions of source code must retain the
|
||||
above copyright notice, this list of conditions
|
||||
and the following disclaimers.
|
||||
|
||||
* Redistributions in binary form must reproduce the
|
||||
above copyright notice, this list of conditions
|
||||
and the following disclaimers in the documentation
|
||||
and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
* Neither the names of the LLVM Team, University of
|
||||
Illinois at Urbana-Champaign, nor the names of its
|
||||
contributors may be used to endorse or promote
|
||||
products derived from this Software without
|
||||
specific prior written permission.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS WITH THE SOFTWARE.
|
||||
|
||||
* Additional libraries included in LLVM carry separate
|
||||
BSD-compatible licenses. See src/llvm-project/llvm/LICENSE.TXT
|
||||
for details.
|
||||
|
||||
* compiler-rt, in src/compiler-rt is dual licensed under
|
||||
LLVM's license and MIT:
|
||||
|
||||
Copyright (c) 2009-2014 by the contributors listed in
|
||||
CREDITS.TXT
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Developed by:
|
||||
|
||||
LLVM Team
|
||||
|
||||
University of Illinois at Urbana-Champaign
|
||||
|
||||
http://llvm.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any
|
||||
person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal with the
|
||||
Software without restriction, including without
|
||||
limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software
|
||||
is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
* Redistributions of source code must retain the
|
||||
above copyright notice, this list of conditions
|
||||
and the following disclaimers.
|
||||
|
||||
* Redistributions in binary form must reproduce the
|
||||
above copyright notice, this list of conditions
|
||||
and the following disclaimers in the documentation
|
||||
and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
* Neither the names of the LLVM Team, University of
|
||||
Illinois at Urbana-Champaign, nor the names of its
|
||||
contributors may be used to endorse or promote
|
||||
products derived from this Software without
|
||||
specific prior written permission.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS WITH THE SOFTWARE.
|
||||
|
||||
========================================================
|
||||
|
||||
Copyright (c) 2009-2014 by the contributors listed in
|
||||
CREDITS.TXT
|
||||
|
||||
Permission is hereby granted, free of charge, to any
|
||||
person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without
|
||||
limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software
|
||||
is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
* Portions of the FFI code for interacting with the native ABI
|
||||
is derived from the Clay programming language, which carries
|
||||
the following license.
|
||||
|
||||
Copyright (C) 2008-2010 Tachyon Technologies.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with
|
||||
or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the
|
||||
above copyright notice, this list of conditions and
|
||||
the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
OF SUCH DAMAGE.
|
||||
|
||||
* libbacktrace, under src/libbacktrace:
|
||||
|
||||
Copyright (C) 2012-2014 Free Software Foundation, Inc.
|
||||
Written by Ian Lance Taylor, Google.
|
||||
|
||||
Redistribution and use in source and binary forms, with
|
||||
or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
(1) Redistributions of source code must retain the
|
||||
above copyright notice, this list of conditions and
|
||||
the following disclaimer.
|
||||
|
||||
(2) Redistributions in binary form must reproduce
|
||||
the above copyright notice, this list of conditions
|
||||
and the following disclaimer in the documentation
|
||||
and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
(3) The name of the author may not be used to
|
||||
endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
OF SUCH DAMAGE. */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any
|
||||
person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without
|
||||
limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software
|
||||
is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
3
pkg/crate/libzt/README.md
Normal file
3
pkg/crate/libzt/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Unsafe bindings for ZeroTier SDK
|
||||
|
||||
This crate is a pre-Alpha work in progress intended as a placeholder as development continues. Currently only basic creation and management of a node and unsafe BSD-style socket operations are supported. An idiomatic wrapper will eventually replace this.
|
||||
19
pkg/crate/libzt/build.rs
Normal file
19
pkg/crate/libzt/build.rs
Normal file
@@ -0,0 +1,19 @@
|
||||
extern crate bindgen;
|
||||
|
||||
fn main() {
|
||||
println!("cargo:rustc-link-lib=zt");
|
||||
println!("cargo:rustc-env=LLVM_CONFIG_PATH=/usr/local/opt/llvm/bin/llvm-config");
|
||||
|
||||
//println!("cargo:rerun-if-changed=../../../include/ZeroTierSockets.h");
|
||||
//println!("cargo:include=/usr/local/include");
|
||||
|
||||
let bindings = bindgen::Builder::default()
|
||||
.header("../../../include/ZeroTierSockets.h")
|
||||
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
|
||||
.generate()
|
||||
.expect("Unable to generate bindings");
|
||||
|
||||
bindings
|
||||
.write_to_file("./src/libzt.rs")
|
||||
.expect("Couldn't write bindings!");
|
||||
}
|
||||
24
pkg/crate/libzt/src/lib.rs
Normal file
24
pkg/crate/libzt/src/lib.rs
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c)2013-2021 ZeroTier, Inc.
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file in the project's root directory.
|
||||
*
|
||||
* Change Date: 2026-01-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2.0 of the Apache License.
|
||||
*/
|
||||
/****/
|
||||
|
||||
#![allow(non_upper_case_globals)]
|
||||
#![allow(non_camel_case_types)]
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
include!(concat!("./libzt.rs"));
|
||||
|
||||
pub mod node;
|
||||
pub mod socket;
|
||||
pub mod tcp;
|
||||
pub mod udp;
|
||||
pub mod utils;
|
||||
6872
pkg/crate/libzt/src/libzt.rs
Normal file
6872
pkg/crate/libzt/src/libzt.rs
Normal file
File diff suppressed because it is too large
Load Diff
115
pkg/crate/libzt/src/node.rs
Normal file
115
pkg/crate/libzt/src/node.rs
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (c)2013-2021 ZeroTier, Inc.
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file in the project's root directory.
|
||||
*
|
||||
* Change Date: 2026-01-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2.0 of the Apache License.
|
||||
*/
|
||||
/****/
|
||||
|
||||
#![allow(non_upper_case_globals)]
|
||||
#![allow(non_camel_case_types)]
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
include!(concat!("./libzt.rs"));
|
||||
|
||||
use std::ffi::{c_void, CStr, CString};
|
||||
|
||||
extern "C" fn native_event_handler(msg: *mut c_void) {
|
||||
let event: &mut zts_event_msg_t = unsafe { &mut *(msg as *mut zts_event_msg_t) };
|
||||
println!("event: {}", event.event_code);
|
||||
//user_event_handler(event.event_code);
|
||||
}
|
||||
|
||||
pub struct ZeroTierNode {
|
||||
// TODO
|
||||
}
|
||||
|
||||
impl ZeroTierNode {
|
||||
pub fn init_set_event_handler(&self, user_event_handler: impl Fn(i16) -> ()) -> i32 {
|
||||
unsafe {
|
||||
return zts_init_set_event_handler(Some(native_event_handler));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init_set_port(&self, port: u16) -> i32 {
|
||||
unsafe {
|
||||
return zts_init_set_port(port);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init_from_storage(&self, storage_path: &str) -> i32 {
|
||||
unsafe {
|
||||
// This is a false-positive by the linter
|
||||
// See: https://github.com/rust-lang/rust/issues/78691
|
||||
#[allow(temporary_cstring_as_ptr)]
|
||||
return zts_init_from_storage(CString::new(storage_path).unwrap().as_ptr());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start(&self) -> i32 {
|
||||
unsafe {
|
||||
return zts_node_start();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn stop(&self) -> i32 {
|
||||
unsafe {
|
||||
return zts_node_stop();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn free(&self) -> i32 {
|
||||
unsafe {
|
||||
return zts_node_free();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn net_join(&self, net_id: u64) -> i32 {
|
||||
unsafe {
|
||||
return zts_net_join(net_id);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn net_leave(&self, net_id: u64) -> i32 {
|
||||
unsafe {
|
||||
return zts_net_leave(net_id);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn net_transport_is_ready(&self, net_id: u64) -> bool {
|
||||
unsafe {
|
||||
return zts_net_transport_is_ready(net_id) == 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_online(&self) -> bool {
|
||||
unsafe {
|
||||
return zts_node_is_online() == 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn id(&self) -> u64 {
|
||||
unsafe {
|
||||
return zts_node_get_id();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn delay(&self, interval_ms: u64) -> () {
|
||||
unsafe { zts_util_delay(interval_ms) }
|
||||
}
|
||||
|
||||
pub fn addr_get(&self, net_id: u64) -> String {
|
||||
unsafe {
|
||||
let mut v = vec![0; (ZTS_INET6_ADDRSTRLEN as usize) + 1];
|
||||
let ptr = v.as_mut_ptr() as *mut i8;
|
||||
zts_addr_get_str(net_id, ZTS_AF_INET, ptr, ZTS_INET6_ADDRSTRLEN);
|
||||
let c_str = CStr::from_ptr(ptr);
|
||||
return c_str.to_string_lossy().into_owned();
|
||||
}
|
||||
}
|
||||
}
|
||||
329
pkg/crate/libzt/src/socket.rs
Normal file
329
pkg/crate/libzt/src/socket.rs
Normal file
@@ -0,0 +1,329 @@
|
||||
/*
|
||||
* Copyright (c)2013-2021 ZeroTier, Inc.
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file in the project's root directory.
|
||||
*
|
||||
* Change Date: 2026-01-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2.0 of the Apache License.
|
||||
*/
|
||||
/****/
|
||||
|
||||
use std::convert::TryInto;
|
||||
use std::ffi::c_void;
|
||||
use std::io::{Error, ErrorKind};
|
||||
use std::net::{Shutdown, SocketAddr};
|
||||
use std::os::raw::c_int;
|
||||
use std::time::Duration;
|
||||
use std::{io, mem};
|
||||
|
||||
use crate::utils::*;
|
||||
|
||||
// Note: FileDesc and c_int in libc are private so we can't use that. Use i32 instead
|
||||
pub struct Socket(c_int);
|
||||
|
||||
impl Socket {
|
||||
pub fn new(addr: &SocketAddr, sock_type: c_int) -> io::Result<Socket> {
|
||||
let family = match *addr {
|
||||
SocketAddr::V4(..) => ZTS_AF_INET,
|
||||
SocketAddr::V6(..) => ZTS_AF_INET6,
|
||||
};
|
||||
Socket::new_raw(family as i32, sock_type)
|
||||
}
|
||||
|
||||
pub fn new_raw(family: c_int, sock_type: c_int) -> io::Result<Socket> {
|
||||
unsafe {
|
||||
// TODO: Set O_CLOEXEC (this is done in the Rust netc implementation)
|
||||
let fd = zts_bsd_socket(family, sock_type, 0);
|
||||
Ok(Socket(fd))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn accept(
|
||||
&self,
|
||||
storage: *mut zts_sockaddr,
|
||||
len: *mut zts_socklen_t,
|
||||
) -> io::Result<Socket> {
|
||||
let fd = unsafe { zts_bsd_accept(self.0, storage, len) };
|
||||
Ok(Socket(fd))
|
||||
}
|
||||
|
||||
pub fn as_inner(&self) -> &c_int {
|
||||
&self.0
|
||||
//.as_inner()
|
||||
}
|
||||
|
||||
/*
|
||||
pub fn connect_timeout(&self, addr: &SocketAddr, timeout: Duration) -> io::Result<()> {
|
||||
self.set_nonblocking(true)?;
|
||||
let r = unsafe {
|
||||
let (addrp, len) = addr.into_inner();
|
||||
cvt(zts_bsd_connect(self.0, addrp, len))
|
||||
};
|
||||
self.set_nonblocking(false)?;
|
||||
|
||||
match r {
|
||||
Ok(_) => return Ok(()),
|
||||
// there's no ErrorKind for EINPROGRESS :(
|
||||
Err(ref e) if e.raw_os_error() == Some(ZTS_EINPROGRESS) => {}
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
|
||||
let mut pollfd = zts_pollfd { fd: self.0, events: ZTS_POLLOUT, revents: 0 };
|
||||
|
||||
if timeout.as_secs() == 0 && timeout.subsec_nanos() == 0 {
|
||||
return Err(io::Error::new_const(
|
||||
io::ErrorKind::InvalidInput,
|
||||
&"cannot set a 0 duration timeout",
|
||||
));
|
||||
}
|
||||
|
||||
let start = Instant::now();
|
||||
|
||||
loop {
|
||||
let elapsed = start.elapsed();
|
||||
if elapsed >= timeout {
|
||||
return Err(io::Error::new_const(io::ErrorKind::TimedOut, &"connection timed out"));
|
||||
}
|
||||
|
||||
let timeout = timeout - elapsed;
|
||||
let mut timeout = timeout
|
||||
.as_secs()
|
||||
.saturating_mul(1_000)
|
||||
.saturating_add(timeout.subsec_nanos() as u64 / 1_000_000);
|
||||
if timeout == 0 {
|
||||
timeout = 1;
|
||||
}
|
||||
|
||||
let timeout = cmp::min(timeout, c_int::MAX as u64) as c_int;
|
||||
|
||||
match unsafe { zts_bsd_poll(&mut pollfd, 1, timeout) } {
|
||||
-1 => {
|
||||
let err = io::Error::last_os_error();
|
||||
if err.kind() != io::ErrorKind::Interrupted {
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
0 => {}
|
||||
_ => {
|
||||
// linux returns POLLOUT|POLLERR|POLLHUP for refused connections (!), so look
|
||||
// for POLLHUP rather than read readiness
|
||||
if pollfd.revents & ZTS_POLLHUP != 0 {
|
||||
let e = self.take_error()?.unwrap_or_else(|| {
|
||||
io::Error::new_const(
|
||||
io::ErrorKind::Other,
|
||||
&"no error set after POLLHUP",
|
||||
)
|
||||
});
|
||||
return Err(e);
|
||||
}
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
fn recv_with_flags(&self, buf: &mut [u8], flags: c_int) -> io::Result<usize> {
|
||||
unsafe {
|
||||
let raw = zts_bsd_recv(
|
||||
self.0,
|
||||
buf.as_mut_ptr() as *mut c_void,
|
||||
(buf.len() as usize).try_into().unwrap(),
|
||||
flags,
|
||||
);
|
||||
Ok(raw as usize)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
self.recv_with_flags(buf, 0)
|
||||
}
|
||||
|
||||
pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
self.recv_with_flags(buf, ZTS_MSG_PEEK as i32)
|
||||
}
|
||||
/*
|
||||
pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
|
||||
self.0.read_vectored(bufs)
|
||||
}
|
||||
*/
|
||||
#[inline]
|
||||
pub fn is_read_vectored(&self) -> bool {
|
||||
// TODO: In principle this is possible but is not hooked up yet
|
||||
return false;
|
||||
}
|
||||
|
||||
fn recv_from_with_flags(
|
||||
&self,
|
||||
buf: &mut [u8],
|
||||
flags: c_int,
|
||||
) -> io::Result<(usize, SocketAddr)> {
|
||||
let mut storage: zts_sockaddr_storage = unsafe { mem::zeroed() };
|
||||
let mut addrlen = mem::size_of_val(&storage) as zts_socklen_t;
|
||||
|
||||
unsafe {
|
||||
let n = zts_bsd_recvfrom(
|
||||
self.0,
|
||||
buf.as_mut_ptr() as *mut c_void,
|
||||
buf.len().try_into().unwrap(),
|
||||
flags,
|
||||
&mut storage as *mut _ as *mut _,
|
||||
&mut addrlen,
|
||||
);
|
||||
Ok((n as usize, sockaddr_to_addr(&storage, addrlen as usize)?))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
|
||||
self.recv_from_with_flags(buf, 0)
|
||||
}
|
||||
|
||||
pub fn recv_msg(&self, msg: &mut zts_msghdr) -> io::Result<usize> {
|
||||
unsafe {
|
||||
let n = zts_bsd_recvmsg(self.0, msg, 0 /*ZTS_MSG_CMSG_CLOEXEC*/);
|
||||
Ok(n as usize)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
|
||||
self.recv_from_with_flags(buf, ZTS_MSG_PEEK as i32)
|
||||
}
|
||||
|
||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
unsafe {
|
||||
let raw = zts_bsd_write(
|
||||
self.0,
|
||||
buf.as_ptr() as *const c_void,
|
||||
buf.len().try_into().unwrap(),
|
||||
);
|
||||
if raw >= 0 {
|
||||
Ok(raw.try_into().unwrap())
|
||||
} else {
|
||||
Err(io::Error::from_raw_os_error(raw as i32))
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||
self.0.write_vectored(bufs)
|
||||
}
|
||||
*/
|
||||
#[inline]
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
// TODO: In principle this is possible but is not hooked up yet
|
||||
return false;
|
||||
}
|
||||
|
||||
pub fn send_msg(&self, msg: &mut zts_msghdr) -> io::Result<usize> {
|
||||
unsafe {
|
||||
let n = zts_bsd_sendmsg(self.0, msg, 0);
|
||||
Ok(n as usize)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_timeout(&self, dur: Option<Duration>, kind: c_int) -> io::Result<()> {
|
||||
let timeout = match dur {
|
||||
Some(dur) => {
|
||||
if dur.as_secs() == 0 && dur.subsec_nanos() == 0 {
|
||||
// TODO: Use new_const to avoid allocations
|
||||
return Err(Error::new(
|
||||
ErrorKind::InvalidInput,
|
||||
"Cannot set a 0 duration timeout",
|
||||
));
|
||||
}
|
||||
|
||||
let secs = if dur.as_secs() > time_t::MAX as u64 {
|
||||
time_t::MAX
|
||||
} else {
|
||||
dur.as_secs() as time_t
|
||||
};
|
||||
let mut timeout = zts_timeval {
|
||||
tv_sec: secs,
|
||||
tv_usec: dur.subsec_micros() as std::os::raw::c_long,
|
||||
};
|
||||
if timeout.tv_sec == 0 && timeout.tv_usec == 0 {
|
||||
timeout.tv_usec = 1;
|
||||
}
|
||||
timeout
|
||||
}
|
||||
None => zts_timeval {
|
||||
tv_sec: 0,
|
||||
tv_usec: 0,
|
||||
},
|
||||
};
|
||||
setsockopt(self, ZTS_SOL_SOCKET as i32, kind, timeout)
|
||||
}
|
||||
|
||||
pub fn timeout(&self, kind: c_int) -> io::Result<Option<Duration>> {
|
||||
let raw: zts_timeval = getsockopt(self, ZTS_SOL_SOCKET as i32, kind)?;
|
||||
if raw.tv_sec == 0 && raw.tv_usec == 0 {
|
||||
Ok(None)
|
||||
} else {
|
||||
let sec = raw.tv_sec as u64;
|
||||
let nsec = (raw.tv_usec as u32) * 1000;
|
||||
Ok(Some(Duration::new(sec, nsec)))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
|
||||
let how = match how {
|
||||
Shutdown::Write => ZTS_SHUT_WR as i32,
|
||||
Shutdown::Read => ZTS_SHUT_RD as i32,
|
||||
Shutdown::Both => ZTS_SHUT_RDWR as i32,
|
||||
};
|
||||
unsafe {
|
||||
let raw: c_int = zts_bsd_shutdown(self.0, how);
|
||||
if raw == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(io::Error::from_raw_os_error(raw as i32))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
|
||||
let nodelay = nodelay as c_int;
|
||||
unsafe {
|
||||
let raw: c_int = zts_set_no_delay(self.0, nodelay);
|
||||
if raw == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(io::Error::from_raw_os_error(raw as i32))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn nodelay(&self) -> io::Result<bool> {
|
||||
unsafe {
|
||||
let raw: c_int = zts_get_no_delay(self.0);
|
||||
Ok(raw != 0)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
|
||||
let nonblocking = nonblocking as c_int;
|
||||
unsafe {
|
||||
let raw: c_int = zts_set_blocking(self.0, !nonblocking);
|
||||
if raw == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(io::Error::from_raw_os_error(raw as i32))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
|
||||
unsafe {
|
||||
let raw: c_int = zts_get_last_socket_error(self.0);
|
||||
if raw == 0 {
|
||||
Ok(None)
|
||||
} else {
|
||||
Err(io::Error::from_raw_os_error(raw as i32))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
518
pkg/crate/libzt/src/tcp.rs
Normal file
518
pkg/crate/libzt/src/tcp.rs
Normal file
@@ -0,0 +1,518 @@
|
||||
/*
|
||||
* Copyright (c)2013-2021 ZeroTier, Inc.
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file in the project's root directory.
|
||||
*
|
||||
* Change Date: 2026-01-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2.0 of the Apache License.
|
||||
*/
|
||||
/****/
|
||||
|
||||
use std::ffi::{c_void, CString};
|
||||
use std::io;
|
||||
use std::io::{Read, Write};
|
||||
use std::net::{Shutdown, SocketAddr, ToSocketAddrs};
|
||||
use std::os::raw::c_int;
|
||||
use std::time::Duration;
|
||||
use std::{cmp, mem};
|
||||
|
||||
use crate::socket::Socket;
|
||||
use crate::utils::*;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// TcpStream //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
pub struct TcpStreamImpl {
|
||||
inner: Socket,
|
||||
}
|
||||
|
||||
impl TcpStreamImpl {
|
||||
pub fn connect(addr: io::Result<&SocketAddr>) -> io::Result<TcpStreamImpl> {
|
||||
let addr = addr?;
|
||||
let socket = Socket::new(addr, ZTS_SOCK_STREAM as i32)?;
|
||||
//let (addrp, len) = addr.into_inner();
|
||||
unsafe {
|
||||
// TODO: Find a better way to split this address string
|
||||
let full_str = addr.to_string();
|
||||
let full_vec = full_str.split(":");
|
||||
let lvec: Vec<&str> = full_vec.collect();
|
||||
let addr_str = lvec[0];
|
||||
let port = addr.port();
|
||||
let timeout_ms = 0;
|
||||
// TODO: Handle native error code, consider cvt?
|
||||
// This is a false-positive by the linter
|
||||
// See: https://github.com/rust-lang/rust/issues/78691
|
||||
#[allow(temporary_cstring_as_ptr)]
|
||||
zts_connect(
|
||||
*socket.as_inner(),
|
||||
CString::new(addr_str).unwrap().as_ptr(),
|
||||
port,
|
||||
timeout_ms,
|
||||
);
|
||||
}
|
||||
Ok(TcpStreamImpl { inner: socket })
|
||||
}
|
||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
let len = cmp::min(buf.len(), <size_t>::MAX as usize) as size_t;
|
||||
// TODO: Handle native error code, consider cvt?
|
||||
let ret =
|
||||
unsafe { zts_bsd_write(*self.inner.as_inner(), buf.as_ptr() as *const c_void, len) };
|
||||
Ok(ret as usize)
|
||||
}
|
||||
/*
|
||||
pub fn connect_timeout(addr: &SocketAddr, timeout: Duration) -> io::Result<TcpStream> {
|
||||
init();
|
||||
|
||||
let sock = Socket::new(addr, c::SOCK_STREAM)?;
|
||||
sock.connect_timeout(addr, timeout)?;
|
||||
Ok(TcpStream { inner: sock })
|
||||
}
|
||||
*/
|
||||
pub fn socket(&self) -> &Socket {
|
||||
&self.inner
|
||||
}
|
||||
|
||||
pub fn into_socket(self) -> Socket {
|
||||
self.inner
|
||||
}
|
||||
|
||||
pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
|
||||
self.inner.set_timeout(dur, ZTS_SO_RCVTIMEO as i32)
|
||||
}
|
||||
|
||||
pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
|
||||
self.inner.set_timeout(dur, ZTS_SO_SNDTIMEO as i32)
|
||||
}
|
||||
|
||||
pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
|
||||
self.inner.timeout(ZTS_SO_RCVTIMEO as i32)
|
||||
}
|
||||
|
||||
pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
|
||||
self.inner.timeout(ZTS_SO_SNDTIMEO as i32)
|
||||
}
|
||||
|
||||
pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
self.inner.peek(buf)
|
||||
}
|
||||
|
||||
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
self.inner.read(buf)
|
||||
}
|
||||
/*
|
||||
pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
|
||||
self.inner.read_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_read_vectored(&self) -> bool {
|
||||
self.inner.is_read_vectored()
|
||||
}
|
||||
|
||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
let len = cmp::min(buf.len(), <wrlen_t>::MAX as usize) as wrlen_t;
|
||||
let ret = cvt(unsafe {
|
||||
zts_bsd_send(*self.inner.as_inner(), buf.as_ptr() as *const c_void, len, ZTS_MSG_NOSIGNAL)
|
||||
})?;
|
||||
Ok(ret as usize)
|
||||
}
|
||||
|
||||
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||
self.inner.write_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
self.inner.is_write_vectored()
|
||||
}
|
||||
*/
|
||||
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
|
||||
sockname(|buf, len| unsafe { zts_bsd_getpeername(*self.inner.as_inner(), buf, len) })
|
||||
}
|
||||
|
||||
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
|
||||
sockname(|buf, len| unsafe { zts_bsd_getsockname(*self.inner.as_inner(), buf, len) })
|
||||
}
|
||||
|
||||
pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
|
||||
self.inner.shutdown(how)
|
||||
}
|
||||
|
||||
pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
|
||||
self.inner.set_nodelay(nodelay)
|
||||
}
|
||||
|
||||
pub fn nodelay(&self) -> io::Result<bool> {
|
||||
self.inner.nodelay()
|
||||
}
|
||||
|
||||
pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
|
||||
setsockopt(
|
||||
&self.inner,
|
||||
ZTS_IPPROTO_IP as i32,
|
||||
ZTS_IP_TTL as i32,
|
||||
ttl as c_int,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn ttl(&self) -> io::Result<u32> {
|
||||
let raw: c_int = getsockopt(&self.inner, ZTS_IPPROTO_IP as i32, ZTS_IP_TTL as i32)?;
|
||||
Ok(raw as u32)
|
||||
}
|
||||
|
||||
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
|
||||
self.inner.take_error()
|
||||
}
|
||||
|
||||
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
|
||||
self.inner.set_nonblocking(nonblocking)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TcpStream(TcpStreamImpl);
|
||||
|
||||
impl TcpStream {
|
||||
pub fn connect<A: ToSocketAddrs>(addr: A) -> io::Result<TcpStream> {
|
||||
each_addr(addr, TcpStreamImpl::connect).map(TcpStream)
|
||||
}
|
||||
/*
|
||||
pub fn connect_timeout(addr: &SocketAddr, timeout: Duration) -> io::Result<TcpStream> {
|
||||
TcpStreamImpl::connect_timeout(addr, timeout).map(TcpStream)
|
||||
}
|
||||
*/
|
||||
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
|
||||
self.0.peer_addr()
|
||||
}
|
||||
|
||||
pub fn local_addr(&self) -> io::Result<SocketAddr> {
|
||||
self.0.socket_addr()
|
||||
}
|
||||
|
||||
pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
|
||||
self.0.shutdown(how)
|
||||
}
|
||||
|
||||
pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
|
||||
self.0.set_read_timeout(dur)
|
||||
}
|
||||
|
||||
pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
|
||||
self.0.set_write_timeout(dur)
|
||||
}
|
||||
|
||||
pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
|
||||
self.0.read_timeout()
|
||||
}
|
||||
|
||||
pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
|
||||
self.0.write_timeout()
|
||||
}
|
||||
|
||||
pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
self.0.peek(buf)
|
||||
}
|
||||
|
||||
pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
|
||||
self.0.set_nodelay(nodelay)
|
||||
}
|
||||
|
||||
pub fn nodelay(&self) -> io::Result<bool> {
|
||||
self.0.nodelay()
|
||||
}
|
||||
|
||||
pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
|
||||
self.0.set_ttl(ttl)
|
||||
}
|
||||
|
||||
pub fn ttl(&self) -> io::Result<u32> {
|
||||
self.0.ttl()
|
||||
}
|
||||
|
||||
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
|
||||
self.0.take_error()
|
||||
}
|
||||
|
||||
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
|
||||
self.0.set_nonblocking(nonblocking)
|
||||
}
|
||||
}
|
||||
|
||||
impl Read for TcpStream {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
self.0.read(buf)
|
||||
}
|
||||
/*
|
||||
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
|
||||
self.0.read_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_read_vectored(&self) -> bool {
|
||||
self.0.is_read_vectored()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn initializer(&self) -> Initializer {
|
||||
// SAFETY: Read is guaranteed to work on uninitialized memory
|
||||
unsafe { Initializer::nop() }
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
impl Write for TcpStream {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.0.write(buf)
|
||||
}
|
||||
/*
|
||||
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||
self.0.write_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
self.0.is_write_vectored()
|
||||
}
|
||||
*/
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Read for &TcpStream {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
self.0.read(buf)
|
||||
}
|
||||
/*
|
||||
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
|
||||
self.0.read_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_read_vectored(&self) -> bool {
|
||||
self.0.is_read_vectored()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn initializer(&self) -> Initializer {
|
||||
// SAFETY: Read is guaranteed to work on uninitialized memory
|
||||
unsafe { Initializer::nop() }
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
impl Write for &TcpStream {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.0.write(buf)
|
||||
}
|
||||
/*
|
||||
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||
self.0.write_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
self.0.is_write_vectored()
|
||||
}
|
||||
*/
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl AsInner<TcpStreamImpl> for TcpStream {
|
||||
fn as_inner(&self) -> &TcpStreamImpl {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl FromInner<TcpStreamImpl> for TcpStream {
|
||||
fn from_inner(inner: TcpStreamImpl) -> TcpStream {
|
||||
TcpStream(inner)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoInner<TcpStreamImpl> for TcpStream {
|
||||
fn into_inner(self) -> TcpStreamImpl {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
/*
|
||||
impl fmt::Debug for TcpStream {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// TcpListener //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
pub struct TcpListenerImpl {
|
||||
inner: Socket,
|
||||
}
|
||||
|
||||
impl TcpListenerImpl {
|
||||
pub fn bind(addr: io::Result<&SocketAddr>) -> io::Result<TcpListenerImpl> {
|
||||
let addr = addr?;
|
||||
let socket = Socket::new(addr, ZTS_SOCK_STREAM as i32)?;
|
||||
// TODO: Possibly set SO_REUSEADDR
|
||||
//let (addrp, len) = addr.into_inner();
|
||||
unsafe {
|
||||
//zts_bsd_bind(*socket.as_inner(), addrp, len as _);
|
||||
// TODO: Find a better way to split this address string
|
||||
let full_str = addr.to_string();
|
||||
let full_vec = full_str.split(":");
|
||||
let lvec: Vec<&str> = full_vec.collect();
|
||||
let addr_str = lvec[0];
|
||||
let port = addr.port();
|
||||
// TODO: Handle native error code, consider cvt?
|
||||
// This is a false-positive by the linter
|
||||
// See: https://github.com/rust-lang/rust/issues/78691
|
||||
#[allow(temporary_cstring_as_ptr)]
|
||||
zts_bind(
|
||||
*socket.as_inner(),
|
||||
CString::new(addr_str).unwrap().as_ptr(),
|
||||
port,
|
||||
);
|
||||
// TODO: Handle native error code, consider cvt?
|
||||
zts_bsd_listen(*socket.as_inner(), 128);
|
||||
}
|
||||
Ok(TcpListenerImpl { inner: socket })
|
||||
}
|
||||
|
||||
pub fn accept(&self) -> io::Result<(TcpStreamImpl, SocketAddr)> {
|
||||
let mut storage: zts_sockaddr_storage = unsafe { mem::zeroed() };
|
||||
let mut len = mem::size_of_val(&storage) as zts_socklen_t;
|
||||
// TODO: Handle native error code, consider cvt?
|
||||
let socket = self
|
||||
.inner
|
||||
.accept(&mut storage as *mut _ as *mut _, &mut len)?;
|
||||
let addr = sockaddr_to_addr(&storage, len as usize)?;
|
||||
Ok((TcpStreamImpl { inner: socket }, addr))
|
||||
}
|
||||
|
||||
pub fn socket(&self) -> &Socket {
|
||||
&self.inner
|
||||
}
|
||||
|
||||
pub fn into_socket(self) -> Socket {
|
||||
self.inner
|
||||
}
|
||||
|
||||
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
|
||||
sockname(|buf, len| unsafe { zts_bsd_getsockname(*self.inner.as_inner(), buf, len) })
|
||||
}
|
||||
|
||||
pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
|
||||
setsockopt(
|
||||
&self.inner,
|
||||
ZTS_IPPROTO_IP as i32,
|
||||
ZTS_IP_TTL as i32,
|
||||
ttl as c_int,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn ttl(&self) -> io::Result<u32> {
|
||||
let raw: c_int = getsockopt(&self.inner, ZTS_IPPROTO_IP as i32, ZTS_IP_TTL as i32)?;
|
||||
Ok(raw as u32)
|
||||
}
|
||||
|
||||
pub fn set_only_v6(&self, only_v6: bool) -> io::Result<()> {
|
||||
setsockopt(
|
||||
&self.inner,
|
||||
ZTS_IPPROTO_IPV6 as i32,
|
||||
ZTS_IPV6_V6ONLY as i32,
|
||||
only_v6 as c_int,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn only_v6(&self) -> io::Result<bool> {
|
||||
let raw: c_int = getsockopt(&self.inner, ZTS_IPPROTO_IPV6 as i32, ZTS_IPV6_V6ONLY as i32)?;
|
||||
Ok(raw != 0)
|
||||
}
|
||||
|
||||
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
|
||||
self.inner.take_error()
|
||||
}
|
||||
|
||||
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
|
||||
self.inner.set_nonblocking(nonblocking)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TcpListener(TcpListenerImpl);
|
||||
|
||||
pub struct Incoming<'a> {
|
||||
listener: &'a TcpListener,
|
||||
}
|
||||
|
||||
impl<'a> Iterator for Incoming<'a> {
|
||||
type Item = io::Result<TcpStream>;
|
||||
fn next(&mut self) -> Option<io::Result<TcpStream>> {
|
||||
Some(self.listener.accept().map(|p| p.0))
|
||||
}
|
||||
}
|
||||
|
||||
impl TcpListener {
|
||||
pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<TcpListener> {
|
||||
each_addr(addr, TcpListenerImpl::bind).map(TcpListener)
|
||||
}
|
||||
|
||||
pub fn incoming(&self) -> Incoming<'_> {
|
||||
Incoming { listener: self }
|
||||
}
|
||||
|
||||
pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
|
||||
self.0.accept().map(|(a, b)| (TcpStream(a), b))
|
||||
}
|
||||
|
||||
pub fn local_addr(&self) -> io::Result<SocketAddr> {
|
||||
self.0.socket_addr()
|
||||
}
|
||||
|
||||
pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
|
||||
self.0.set_ttl(ttl)
|
||||
}
|
||||
|
||||
pub fn ttl(&self) -> io::Result<u32> {
|
||||
self.0.ttl()
|
||||
}
|
||||
|
||||
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
|
||||
self.0.take_error()
|
||||
}
|
||||
|
||||
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
|
||||
self.0.set_nonblocking(nonblocking)
|
||||
}
|
||||
}
|
||||
|
||||
impl AsInner<TcpListenerImpl> for TcpListener {
|
||||
fn as_inner(&self) -> &TcpListenerImpl {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl FromInner<TcpListenerImpl> for TcpListener {
|
||||
fn from_inner(inner: TcpListenerImpl) -> TcpListener {
|
||||
TcpListener(inner)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoInner<TcpListenerImpl> for TcpListener {
|
||||
fn into_inner(self) -> TcpListenerImpl {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
/*
|
||||
impl fmt::Debug for TcpListener {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
||||
*/
|
||||
459
pkg/crate/libzt/src/udp.rs
Normal file
459
pkg/crate/libzt/src/udp.rs
Normal file
@@ -0,0 +1,459 @@
|
||||
/*
|
||||
* Copyright (c)2013-2021 ZeroTier, Inc.
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file in the project's root directory.
|
||||
*
|
||||
* Change Date: 2026-01-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2.0 of the Apache License.
|
||||
*/
|
||||
/****/
|
||||
|
||||
use std::convert::TryInto;
|
||||
use std::ffi::{c_void, CString};
|
||||
use std::io::{self, Error, ErrorKind};
|
||||
use std::net::{/*Ipv4Addr, Ipv6Addr,*/ SocketAddr, ToSocketAddrs};
|
||||
use std::os::raw::c_int;
|
||||
use std::time::Duration;
|
||||
//use std::cmp;
|
||||
|
||||
use crate::socket::Socket;
|
||||
use crate::utils::*;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// UdpSocketImpl //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
pub struct UdpSocketImpl {
|
||||
inner: Socket,
|
||||
}
|
||||
|
||||
impl UdpSocketImpl {
|
||||
pub fn bind(addr: io::Result<&SocketAddr>) -> io::Result<UdpSocketImpl> {
|
||||
let addr = addr?;
|
||||
let socket = Socket::new(addr, ZTS_SOCK_DGRAM as i32)?;
|
||||
// TODO: Possibly set SO_REUSEADDR
|
||||
//let (addrp, len) = addr.into_inner();
|
||||
unsafe {
|
||||
//zts_bsd_bind(*socket.as_inner(), addrp, len as _);
|
||||
// TODO: Find a better way to split this address string
|
||||
let full_str = addr.to_string();
|
||||
let full_vec = full_str.split(":");
|
||||
let lvec: Vec<&str> = full_vec.collect();
|
||||
let addr_str = lvec[0];
|
||||
let port = addr.port();
|
||||
// TODO: Handle native error code, consider cvt?
|
||||
// This is a false-positive by the linter
|
||||
// See: https://github.com/rust-lang/rust/issues/78691
|
||||
#[allow(temporary_cstring_as_ptr)]
|
||||
zts_bind(
|
||||
*socket.as_inner(),
|
||||
CString::new(addr_str).unwrap().as_ptr(),
|
||||
port,
|
||||
);
|
||||
}
|
||||
Ok(UdpSocketImpl { inner: socket })
|
||||
}
|
||||
|
||||
pub fn socket(&self) -> &Socket {
|
||||
&self.inner
|
||||
}
|
||||
|
||||
pub fn into_socket(self) -> Socket {
|
||||
self.inner
|
||||
}
|
||||
|
||||
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
|
||||
sockname(|buf, len| unsafe { zts_bsd_getpeername(*self.inner.as_inner(), buf, len) })
|
||||
}
|
||||
|
||||
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
|
||||
sockname(|buf, len| unsafe { zts_bsd_getsockname(*self.inner.as_inner(), buf, len) })
|
||||
}
|
||||
|
||||
pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
|
||||
self.inner.recv_from(buf)
|
||||
}
|
||||
|
||||
pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
|
||||
self.inner.peek_from(buf)
|
||||
}
|
||||
|
||||
pub fn send_to(&self, buf: &[u8], dst: &SocketAddr) -> io::Result<usize> {
|
||||
/*
|
||||
let len = cmp::min(buf.len(), <size_t>::MAX as usize) as size_t;
|
||||
let (dstp, dstlen) = dst.into_inner();
|
||||
let ret = cvt(unsafe {
|
||||
zts_bsd_sendto(
|
||||
*self.inner.as_inner(),
|
||||
buf.as_ptr() as *const c_void,
|
||||
len,
|
||||
ZTS_MSG_NOSIGNAL,
|
||||
dstp,
|
||||
dstlen,
|
||||
)
|
||||
})?;
|
||||
Ok(ret as usize)
|
||||
*/
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
|
||||
self.inner.set_timeout(dur, ZTS_SO_RCVTIMEO as i32)
|
||||
}
|
||||
|
||||
pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
|
||||
self.inner.set_timeout(dur, ZTS_SO_SNDTIMEO as i32)
|
||||
}
|
||||
|
||||
pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
|
||||
self.inner.timeout(ZTS_SO_RCVTIMEO as i32)
|
||||
}
|
||||
|
||||
pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
|
||||
self.inner.timeout(ZTS_SO_SNDTIMEO as i32)
|
||||
}
|
||||
|
||||
pub fn set_broadcast(&self, broadcast: bool) -> io::Result<()> {
|
||||
setsockopt(
|
||||
&self.inner,
|
||||
ZTS_SOL_SOCKET as i32,
|
||||
ZTS_SO_BROADCAST as i32,
|
||||
broadcast as c_int,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn broadcast(&self) -> io::Result<bool> {
|
||||
let raw: c_int = getsockopt(&self.inner, ZTS_SOL_SOCKET as i32, ZTS_SO_BROADCAST as i32)?;
|
||||
Ok(raw != 0)
|
||||
}
|
||||
/*
|
||||
pub fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()> {
|
||||
setsockopt(
|
||||
&self.inner,
|
||||
ZTS_IPPROTO_IP,
|
||||
ZTS_IP_MULTICAST_LOOP,
|
||||
multicast_loop_v4 as IpV4MultiCastType,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn multicast_loop_v4(&self) -> io::Result<bool> {
|
||||
let raw: IpV4MultiCastType = getsockopt(&self.inner, ZTS_IPPROTO_IP, ZTS_IP_MULTICAST_LOOP)?;
|
||||
Ok(raw != 0)
|
||||
}
|
||||
|
||||
pub fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()> {
|
||||
setsockopt(
|
||||
&self.inner,
|
||||
ZTS_IPPROTO_IP,
|
||||
ZTS_IP_MULTICAST_TTL,
|
||||
multicast_ttl_v4 as IpV4MultiCastType,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
|
||||
let raw: IpV4MultiCastType = getsockopt(&self.inner, ZTS_IPPROTO_IP, ZTS_IP_MULTICAST_TTL)?;
|
||||
Ok(raw as u32)
|
||||
}
|
||||
|
||||
pub fn set_multicast_loop_v6(&self, multicast_loop_v6: bool) -> io::Result<()> {
|
||||
setsockopt(&self.inner, ZTS_IPPROTO_IPV6, ZTS_IPV6_MULTICAST_LOOP, multicast_loop_v6 as c_int)
|
||||
}
|
||||
|
||||
pub fn multicast_loop_v6(&self) -> io::Result<bool> {
|
||||
let raw: c_int = getsockopt(&self.inner, ZTS_IPPROTO_IPV6, ZTS_IPV6_MULTICAST_LOOP)?;
|
||||
Ok(raw != 0)
|
||||
}
|
||||
|
||||
pub fn join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> {
|
||||
let mreq = zts_ip_mreq {
|
||||
imr_multiaddr: multiaddr.into_inner(),
|
||||
imr_interface: interface.into_inner(),
|
||||
};
|
||||
setsockopt(&self.inner, ZTS_IPPROTO_IP, ZTS_IP_ADD_MEMBERSHIP, mreq)
|
||||
}
|
||||
|
||||
pub fn join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
|
||||
let mreq = zts_ipv6_mreq {
|
||||
ipv6mr_multiaddr: *multiaddr.as_inner(),
|
||||
ipv6mr_interface: to_ipv6mr_interface(interface),
|
||||
};
|
||||
setsockopt(&self.inner, ZTS_IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, mreq)
|
||||
}
|
||||
|
||||
pub fn leave_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> {
|
||||
let mreq = zts_ip_mreq {
|
||||
imr_multiaddr: multiaddr.into_inner(),
|
||||
imr_interface: interface.into_inner(),
|
||||
};
|
||||
setsockopt(&self.inner, ZTS_IPPROTO_IP, ZTS_IP_DROP_MEMBERSHIP, mreq)
|
||||
}
|
||||
|
||||
pub fn leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
|
||||
let mreq = zts_ipv6_mreq {
|
||||
ipv6mr_multiaddr: *multiaddr.as_inner(),
|
||||
ipv6mr_interface: to_ipv6mr_interface(interface),
|
||||
};
|
||||
setsockopt(&self.inner, ZTS_IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, mreq)
|
||||
}
|
||||
*/
|
||||
pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
|
||||
setsockopt(
|
||||
&self.inner,
|
||||
ZTS_IPPROTO_IP as i32,
|
||||
ZTS_IP_TTL as i32,
|
||||
ttl as c_int,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn ttl(&self) -> io::Result<u32> {
|
||||
let raw: c_int = getsockopt(&self.inner, ZTS_IPPROTO_IP as i32, ZTS_IP_TTL as i32)?;
|
||||
Ok(raw as u32)
|
||||
}
|
||||
|
||||
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
|
||||
self.inner.take_error()
|
||||
}
|
||||
|
||||
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
|
||||
self.inner.set_nonblocking(nonblocking)
|
||||
}
|
||||
|
||||
pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
self.inner.read(buf)
|
||||
}
|
||||
|
||||
pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
self.inner.peek(buf)
|
||||
}
|
||||
|
||||
pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
/*
|
||||
let len = cmp::min(buf.len(), <wrlen_t>::MAX as usize) as wrlen_t;
|
||||
let ret = cvt(unsafe {
|
||||
zts_bsd_send(*self.inner.as_inner(), buf.as_ptr() as *const c_void, len, ZTS_MSG_NOSIGNAL)
|
||||
})?;
|
||||
Ok(ret as usize)
|
||||
*/
|
||||
unsafe {
|
||||
let raw = zts_bsd_write(
|
||||
*self.inner.as_inner(),
|
||||
buf.as_ptr() as *const c_void,
|
||||
buf.len().try_into().unwrap(),
|
||||
);
|
||||
if raw >= 0 {
|
||||
Ok(raw.try_into().unwrap())
|
||||
} else {
|
||||
Err(io::Error::from_raw_os_error(raw as i32))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn connect(&self, addr: io::Result<&SocketAddr>) -> io::Result<()> {
|
||||
let addr = addr?;
|
||||
//let (addrp, len) = addr?.into_inner();
|
||||
unsafe {
|
||||
let full_str = addr.to_string();
|
||||
let full_vec = full_str.split(":");
|
||||
let lvec: Vec<&str> = full_vec.collect();
|
||||
let addr_str = lvec[0];
|
||||
let port = addr.port();
|
||||
let timeout_ms = 0;
|
||||
// TODO: Handle native error code, consider cvt?
|
||||
// This is a false-positive by the linter
|
||||
// See: https://github.com/rust-lang/rust/issues/78691
|
||||
#[allow(temporary_cstring_as_ptr)]
|
||||
cvt(zts_connect(
|
||||
*self.inner.as_inner(),
|
||||
CString::new(addr_str).unwrap().as_ptr(),
|
||||
port,
|
||||
timeout_ms,
|
||||
))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl FromInner<Socket> for UdpSocketImpl {
|
||||
fn from_inner(socket: Socket) -> UdpSocketImpl {
|
||||
UdpSocketImpl { inner: socket }
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
impl fmt::Debug for UdpSocketImpl {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let mut res = f.debug_struct("UdpSocketImpl");
|
||||
|
||||
if let Ok(addr) = self.socket_addr() {
|
||||
res.field("addr", &addr);
|
||||
}
|
||||
|
||||
let name = if cfg!(windows) { "socket" } else { "fd" };
|
||||
res.field(name, &self.inner.as_inner()).finish()
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// UdpSocket //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
pub struct UdpSocket(UdpSocketImpl);
|
||||
|
||||
impl UdpSocket {
|
||||
pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<UdpSocket> {
|
||||
each_addr(addr, UdpSocketImpl::bind).map(UdpSocket)
|
||||
}
|
||||
|
||||
pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
|
||||
self.0.recv_from(buf)
|
||||
}
|
||||
|
||||
pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
|
||||
self.0.peek_from(buf)
|
||||
}
|
||||
|
||||
pub fn send_to<A: ToSocketAddrs>(&self, buf: &[u8], addr: A) -> io::Result<usize> {
|
||||
match addr.to_socket_addrs()?.next() {
|
||||
Some(addr) => self.0.send_to(buf, &addr),
|
||||
None => Err(Error::new(
|
||||
ErrorKind::InvalidInput,
|
||||
"No address to send data to",
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
|
||||
self.0.peer_addr()
|
||||
}
|
||||
|
||||
pub fn local_addr(&self) -> io::Result<SocketAddr> {
|
||||
self.0.socket_addr()
|
||||
}
|
||||
|
||||
pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
|
||||
self.0.set_read_timeout(dur)
|
||||
}
|
||||
|
||||
pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
|
||||
self.0.set_write_timeout(dur)
|
||||
}
|
||||
|
||||
pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
|
||||
self.0.read_timeout()
|
||||
}
|
||||
|
||||
pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
|
||||
self.0.write_timeout()
|
||||
}
|
||||
|
||||
pub fn set_broadcast(&self, broadcast: bool) -> io::Result<()> {
|
||||
self.0.set_broadcast(broadcast)
|
||||
}
|
||||
|
||||
pub fn broadcast(&self) -> io::Result<bool> {
|
||||
self.0.broadcast()
|
||||
}
|
||||
/*
|
||||
pub fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()> {
|
||||
self.0.set_multicast_loop_v4(multicast_loop_v4)
|
||||
}
|
||||
|
||||
pub fn multicast_loop_v4(&self) -> io::Result<bool> {
|
||||
self.0.multicast_loop_v4()
|
||||
}
|
||||
|
||||
pub fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()> {
|
||||
self.0.set_multicast_ttl_v4(multicast_ttl_v4)
|
||||
}
|
||||
|
||||
pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
|
||||
self.0.multicast_ttl_v4()
|
||||
}
|
||||
|
||||
pub fn set_multicast_loop_v6(&self, multicast_loop_v6: bool) -> io::Result<()> {
|
||||
self.0.set_multicast_loop_v6(multicast_loop_v6)
|
||||
}
|
||||
|
||||
pub fn multicast_loop_v6(&self) -> io::Result<bool> {
|
||||
self.0.multicast_loop_v6()
|
||||
}
|
||||
*/
|
||||
pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
|
||||
self.0.set_ttl(ttl)
|
||||
}
|
||||
|
||||
pub fn ttl(&self) -> io::Result<u32> {
|
||||
self.0.ttl()
|
||||
}
|
||||
/*
|
||||
pub fn join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> {
|
||||
self.0.join_multicast_v4(multiaddr, interface)
|
||||
}
|
||||
|
||||
pub fn join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
|
||||
self.0.join_multicast_v6(multiaddr, interface)
|
||||
}
|
||||
|
||||
pub fn leave_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> {
|
||||
self.0.leave_multicast_v4(multiaddr, interface)
|
||||
}
|
||||
|
||||
pub fn leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
|
||||
self.0.leave_multicast_v6(multiaddr, interface)
|
||||
}
|
||||
*/
|
||||
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
|
||||
self.0.take_error()
|
||||
}
|
||||
|
||||
pub fn connect<A: ToSocketAddrs>(&self, addr: A) -> io::Result<()> {
|
||||
each_addr(addr, |addr| self.0.connect(addr))
|
||||
}
|
||||
|
||||
pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.0.send(buf)
|
||||
}
|
||||
|
||||
pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
self.0.recv(buf)
|
||||
}
|
||||
|
||||
pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
self.0.peek(buf)
|
||||
}
|
||||
|
||||
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
|
||||
self.0.set_nonblocking(nonblocking)
|
||||
}
|
||||
}
|
||||
|
||||
impl AsInner<UdpSocketImpl> for UdpSocket {
|
||||
fn as_inner(&self) -> &UdpSocketImpl {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl FromInner<UdpSocketImpl> for UdpSocket {
|
||||
fn from_inner(inner: UdpSocketImpl) -> UdpSocket {
|
||||
UdpSocket(inner)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoInner<UdpSocketImpl> for UdpSocket {
|
||||
fn into_inner(self) -> UdpSocketImpl {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
impl fmt::Debug for UdpSocket {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
||||
*/
|
||||
213
pkg/crate/libzt/src/utils.rs
Normal file
213
pkg/crate/libzt/src/utils.rs
Normal file
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* Copyright (c)2013-2021 ZeroTier, Inc.
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file in the project's root directory.
|
||||
*
|
||||
* Change Date: 2026-01-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2.0 of the Apache License.
|
||||
*/
|
||||
/****/
|
||||
|
||||
#![allow(non_upper_case_globals)]
|
||||
#![allow(non_camel_case_types)]
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
include!(concat!("./libzt.rs"));
|
||||
|
||||
use std::ffi::c_void;
|
||||
use std::io::{Error, ErrorKind};
|
||||
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs};
|
||||
use std::os::raw::c_int;
|
||||
use std::{io, mem};
|
||||
|
||||
use crate::socket::Socket;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// Utilities //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
/*
|
||||
|
||||
The following utility functions were lifted directly from the Rust standard
|
||||
library and tweaked to accommodate ZeroTier sockets. See their original
|
||||
implementations here:
|
||||
|
||||
- https://doc.rust-lang.org/src/std/net/tcp.rs.html#95-97
|
||||
- https://github.com/rust-lang/rust/blob/master/library/std/src/sys_common/net.rs
|
||||
- https://github.com/rust-lang/rust/blob/db492ecd5ba6bd82205612cebb9034710653f0c2/library/std/src/net/mod.rs
|
||||
*/
|
||||
|
||||
pub trait IsMinusOne {
|
||||
fn is_minus_one(&self) -> bool;
|
||||
}
|
||||
|
||||
macro_rules! impl_is_minus_one {
|
||||
($($t:ident)*) => ($(impl IsMinusOne for $t {
|
||||
fn is_minus_one(&self) -> bool {
|
||||
*self == -1
|
||||
}
|
||||
})*)
|
||||
}
|
||||
|
||||
impl_is_minus_one! { i8 i16 i32 i64 isize }
|
||||
|
||||
pub fn cvt<T: IsMinusOne>(t: T) -> std::io::Result<T> {
|
||||
if t.is_minus_one() {
|
||||
Err(std::io::Error::last_os_error())
|
||||
} else {
|
||||
Ok(t)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cvt_r<T, F>(mut f: F) -> std::io::Result<T>
|
||||
where
|
||||
T: IsMinusOne,
|
||||
F: FnMut() -> T,
|
||||
{
|
||||
loop {
|
||||
match cvt(f()) {
|
||||
Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
|
||||
other => return other,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn setsockopt<T>(sock: &Socket, opt: c_int, val: c_int, payload: T) -> io::Result<()> {
|
||||
unsafe {
|
||||
let payload = &payload as *const T as *const c_void;
|
||||
cvt(zts_bsd_setsockopt(
|
||||
*sock.as_inner(),
|
||||
opt,
|
||||
val,
|
||||
payload,
|
||||
mem::size_of::<T>() as zts_socklen_t,
|
||||
))?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn getsockopt<T: Copy>(sock: &Socket, opt: c_int, val: c_int) -> io::Result<T> {
|
||||
unsafe {
|
||||
let mut slot: T = mem::zeroed();
|
||||
let mut len = mem::size_of::<T>() as zts_socklen_t;
|
||||
cvt(zts_bsd_getsockopt(
|
||||
*sock.as_inner(),
|
||||
opt,
|
||||
val,
|
||||
&mut slot as *mut _ as *mut _,
|
||||
&mut len,
|
||||
))?;
|
||||
Ok(slot)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait AsInner<Inner: ?Sized> {
|
||||
fn as_inner(&self) -> &Inner;
|
||||
}
|
||||
|
||||
pub trait AsInnerMut<Inner: ?Sized> {
|
||||
fn as_inner_mut(&mut self) -> &mut Inner;
|
||||
}
|
||||
|
||||
pub trait IntoInner<Inner> {
|
||||
fn into_inner(self) -> Inner;
|
||||
}
|
||||
|
||||
pub trait FromInner<Inner> {
|
||||
fn from_inner(inner: Inner) -> Self;
|
||||
}
|
||||
|
||||
pub fn each_addr<A: ToSocketAddrs, F, T>(addr: A, mut f: F) -> io::Result<T>
|
||||
where
|
||||
F: FnMut(io::Result<&SocketAddr>) -> io::Result<T>,
|
||||
{
|
||||
let addrs = match addr.to_socket_addrs() {
|
||||
Ok(addrs) => addrs,
|
||||
Err(e) => return f(Err(e)),
|
||||
};
|
||||
let mut last_err = None;
|
||||
for addr in addrs {
|
||||
match f(Ok(&addr)) {
|
||||
Ok(l) => return Ok(l),
|
||||
Err(e) => last_err = Some(e),
|
||||
}
|
||||
}
|
||||
// TODO: Should ideally use new_const as is used in std::net to avoid allocations
|
||||
Err(last_err.unwrap_or_else(|| {
|
||||
Error::new(
|
||||
ErrorKind::InvalidInput,
|
||||
"Could not resolve to any addresses",
|
||||
)
|
||||
}))
|
||||
}
|
||||
|
||||
pub const fn ntohs(i: u16) -> u16 {
|
||||
u16::from_be(i)
|
||||
}
|
||||
|
||||
pub const fn htons(i: u16) -> u16 {
|
||||
i.to_be()
|
||||
}
|
||||
|
||||
pub fn ipv4_addr(addr: zts_in_addr) -> u32 {
|
||||
(addr.s_addr as u32).to_be()
|
||||
}
|
||||
|
||||
// Copied from: https://docs.rs/pnet_sys/0.28.0/src/pnet_sys/unix.rs.html#162-201
|
||||
pub fn sockaddr_to_addr(storage: &zts_sockaddr_storage, len: usize) -> io::Result<SocketAddr> {
|
||||
// See: https://github.com/rust-lang/rust/issues/76191
|
||||
match storage.ss_family as c_int {
|
||||
// ZTS_AF_INET
|
||||
0x2 => {
|
||||
assert!(len as usize >= mem::size_of::<zts_sockaddr_in>());
|
||||
let storage: &zts_sockaddr_in = unsafe { mem::transmute(storage) };
|
||||
let ip = ipv4_addr(storage.sin_addr);
|
||||
let a = (ip >> 24) as u8;
|
||||
let b = (ip >> 16) as u8;
|
||||
let c = (ip >> 8) as u8;
|
||||
let d = ip as u8;
|
||||
let sockaddrv4 = SocketAddrV4::new(Ipv4Addr::new(a, b, c, d), ntohs(storage.sin_port));
|
||||
Ok(SocketAddr::V4(sockaddrv4))
|
||||
}
|
||||
// ZTS_AF_INET6
|
||||
0xA => {
|
||||
assert!(len as usize >= mem::size_of::<zts_sockaddr_in6>());
|
||||
let storage: &zts_sockaddr_in6 = unsafe { mem::transmute(storage) };
|
||||
let arr: [u16; 8] = unsafe { mem::transmute(storage.sin6_addr.un.u8_addr) };
|
||||
let a = ntohs(arr[0]);
|
||||
let b = ntohs(arr[1]);
|
||||
let c = ntohs(arr[2]);
|
||||
let d = ntohs(arr[3]);
|
||||
let e = ntohs(arr[4]);
|
||||
let f = ntohs(arr[5]);
|
||||
let g = ntohs(arr[6]);
|
||||
let h = ntohs(arr[7]);
|
||||
let ip = Ipv6Addr::new(a, b, c, d, e, f, g, h);
|
||||
Ok(SocketAddr::V6(SocketAddrV6::new(
|
||||
ip,
|
||||
ntohs(storage.sin6_port),
|
||||
u32::from_be(storage.sin6_flowinfo),
|
||||
storage.sin6_scope_id,
|
||||
)))
|
||||
}
|
||||
_ => Err(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
"expected IPv4 or IPv6 socket",
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sockname<F>(f: F) -> io::Result<SocketAddr>
|
||||
where
|
||||
F: FnOnce(*mut zts_sockaddr, *mut zts_socklen_t) -> c_int,
|
||||
{
|
||||
unsafe {
|
||||
let mut storage: zts_sockaddr_storage = mem::zeroed();
|
||||
let mut len = mem::size_of_val(&storage) as zts_socklen_t;
|
||||
f(&mut storage as *mut _ as *mut _, &mut len);
|
||||
sockaddr_to_addr(&storage, len as usize)
|
||||
}
|
||||
}
|
||||
1
pkg/crate/libzt/wrapper.h
Normal file
1
pkg/crate/libzt/wrapper.h
Normal file
@@ -0,0 +1 @@
|
||||
#include "../../../include/ZeroTierSockets.h"
|
||||
Reference in New Issue
Block a user