feat: add rust tcp
This commit is contained in:
776
__network/rust_tcp/Cargo.lock
generated
Normal file
776
__network/rust_tcp/Cargo.lock
generated
Normal file
@@ -0,0 +1,776 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
[[package]]
|
||||||
|
name = "arrayvec"
|
||||||
|
version = "0.4.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byteorder"
|
||||||
|
version = "1.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bytes"
|
||||||
|
version = "0.4.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cc"
|
||||||
|
version = "1.0.29"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cloudabi"
|
||||||
|
version = "0.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-channel"
|
||||||
|
version = "0.3.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-deque"
|
||||||
|
version = "0.6.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-epoch"
|
||||||
|
version = "0.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-utils"
|
||||||
|
version = "0.6.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "etherparse"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fuchsia-cprng"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fuchsia-zircon"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fuchsia-zircon-sys"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures"
|
||||||
|
version = "0.1.25"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "iovec"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "kernel32-sys"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazycell"
|
||||||
|
version = "1.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.49"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lock_api"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "log"
|
||||||
|
version = "0.4.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memoffset"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mio"
|
||||||
|
version = "0.6.16"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mio-uds"
|
||||||
|
version = "0.6.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "miow"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "net2"
|
||||||
|
version = "0.2.33"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nix"
|
||||||
|
version = "0.13.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nodrop"
|
||||||
|
version = "0.1.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num_cpus"
|
||||||
|
version = "1.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "owning_ref"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parking_lot"
|
||||||
|
version = "0.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parking_lot_core"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.6.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand_jitter 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand_os 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_chacha"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_hc"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_isaac"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_jitter"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_os"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_pcg"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_xorshift"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rdrand"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc_version"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scoped-tls"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scopeguard"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver-parser"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "slab"
|
||||||
|
version = "0.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "smallvec"
|
||||||
|
version = "0.6.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "stable_deref_trait"
|
||||||
|
version = "1.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio"
|
||||||
|
version = "0.1.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-current-thread 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-fs 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-sync 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-threadpool 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-codec"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-core"
|
||||||
|
version = "0.1.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-current-thread"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-executor"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-fs"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-threadpool 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-io"
|
||||||
|
version = "0.1.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-reactor"
|
||||||
|
version = "0.1.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-sync"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-tcp"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-threadpool"
|
||||||
|
version = "0.1.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-timer"
|
||||||
|
version = "0.2.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-udp"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-uds"
|
||||||
|
version = "0.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "trust"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"etherparse 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"nix 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tun-tap 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tun-tap"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "void"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi"
|
||||||
|
version = "0.2.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi"
|
||||||
|
version = "0.3.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-build"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-i686-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ws2_32-sys"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
"checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71"
|
||||||
|
"checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799"
|
||||||
|
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
|
||||||
|
"checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb"
|
||||||
|
"checksum bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "40ade3d27603c2cb345eb0912aec461a6dec7e06a4ae48589904e808335c7afa"
|
||||||
|
"checksum cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)" = "4390a3b5f4f6bce9c1d0c00128379df433e53777fdd30e92f16a529332baec4e"
|
||||||
|
"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4"
|
||||||
|
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
||||||
|
"checksum crossbeam 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad4c7ea749d9fb09e23c5cb17e3b70650860553a0e2744e38446b1803bf7db94"
|
||||||
|
"checksum crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0f0ed1a4de2235cabda8558ff5840bffb97fcb64c97827f354a451307df5f72b"
|
||||||
|
"checksum crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "05e44b8cf3e1a625844d1750e1f7820da46044ff6d28f4d43e455ba3e5bb2c13"
|
||||||
|
"checksum crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "04c9e3102cc2d69cd681412141b390abd55a362afc1540965dad0ad4d34280b4"
|
||||||
|
"checksum crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c"
|
||||||
|
"checksum etherparse 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4ed59db6e54d52a22309fe2fa4f26f6e356b68e76d4a53c272699ee1e9b812e"
|
||||||
|
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||||
|
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
|
||||||
|
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
|
||||||
|
"checksum futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "49e7653e374fe0d0c12de4250f0bdb60680b8c80eed558c5c7538eec9c89e21b"
|
||||||
|
"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08"
|
||||||
|
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||||
|
"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1"
|
||||||
|
"checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
|
||||||
|
"checksum libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)" = "413f3dfc802c5dc91dc570b05125b6cda9855edfaa9825c9849807876376e70e"
|
||||||
|
"checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c"
|
||||||
|
"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
|
||||||
|
"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
|
||||||
|
"checksum mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "71646331f2619b1026cc302f87a2b8b648d5c6dd6937846a16cc8ce0f347f432"
|
||||||
|
"checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125"
|
||||||
|
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
|
||||||
|
"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
|
||||||
|
"checksum nix 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46f0f3210768d796e8fa79ec70ee6af172dacbe7147f5e69be5240a47778302b"
|
||||||
|
"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
|
||||||
|
"checksum num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a23f0ed30a54abaa0c7e83b1d2d87ada7c3c23078d1d87815af3e3b6385fbba"
|
||||||
|
"checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13"
|
||||||
|
"checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337"
|
||||||
|
"checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9"
|
||||||
|
"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
|
||||||
|
"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
|
||||||
|
"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
||||||
|
"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0"
|
||||||
|
"checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
|
||||||
|
"checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
|
||||||
|
"checksum rand_jitter 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b9ea758282efe12823e0d952ddb269d2e1897227e464919a554f2a03ef1b832"
|
||||||
|
"checksum rand_os 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b7c690732391ae0abafced5015ffb53656abfaec61b342290e5eb56b286a679d"
|
||||||
|
"checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
|
||||||
|
"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
|
||||||
|
"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
|
||||||
|
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||||
|
"checksum scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28"
|
||||||
|
"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
|
||||||
|
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||||
|
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||||
|
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
|
||||||
|
"checksum smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c4488ae950c49d403731982257768f48fada354a5203fe81f9bb6f43ca9002be"
|
||||||
|
"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
|
||||||
|
"checksum tokio 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "e0500b88064f08bebddd0c0bed39e19f5c567a5f30975bee52b0c0d3e2eeb38c"
|
||||||
|
"checksum tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c501eceaf96f0e1793cf26beb63da3d11c738c4a943fdf3746d81d64684c39f"
|
||||||
|
"checksum tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "aeeffbbb94209023feaef3c196a41cbcdafa06b4a6f893f68779bb5e53796f71"
|
||||||
|
"checksum tokio-current-thread 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "331c8acc267855ec06eb0c94618dcbbfea45bed2d20b77252940095273fb58f6"
|
||||||
|
"checksum tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "30c6dbf2d1ad1de300b393910e8a3aa272b724a400b6531da03eed99e329fbf0"
|
||||||
|
"checksum tokio-fs 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0e9cbbc8a3698b7ab652340f46633364f9eaa928ddaaee79d8b8f356dd79a09d"
|
||||||
|
"checksum tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b53aeb9d3f5ccf2ebb29e19788f96987fa1355f8fe45ea193928eaaaf3ae820f"
|
||||||
|
"checksum tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "afbcdb0f0d2a1e4c440af82d7bbf0bf91a8a8c0575bcd20c05d15be7e9d3a02f"
|
||||||
|
"checksum tokio-sync 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c73850a5ad497d73ccfcfc0ffb494a4502d93f35cb475cfeef4fcf2916d26040"
|
||||||
|
"checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119"
|
||||||
|
"checksum tokio-threadpool 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c3fd86cb15547d02daa2b21aadaf4e37dee3368df38a526178a5afa3c034d2fb"
|
||||||
|
"checksum tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2910970404ba6fa78c5539126a9ae2045d62e3713041e447f695f41405a120c6"
|
||||||
|
"checksum tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "66268575b80f4a4a710ef83d087fdfeeabdce9b74c797535fbac18a2cb906e92"
|
||||||
|
"checksum tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "037ffc3ba0e12a0ab4aca92e5234e0dedeb48fddf6ccd260f1f150a36a9f2445"
|
||||||
|
"checksum tun-tap 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53ccbe9cfffdaa7eefd36538bb26f228d4bd319a8aeca044d54377612a646bcd"
|
||||||
|
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||||
|
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
|
||||||
|
"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0"
|
||||||
|
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
|
||||||
|
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
|
||||||
17
__network/rust_tcp/Cargo.toml
Normal file
17
__network/rust_tcp/Cargo.toml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
[package]
|
||||||
|
name = "trust"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Jon Gjengset <jon@thesquareplanet.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
tun-tap = "0.1.2"
|
||||||
|
etherparse = "0.8"
|
||||||
|
bitflags = "1.0"
|
||||||
|
nix = "0.13"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "trust"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "trust"
|
||||||
5
__network/rust_tcp/README.md
Normal file
5
__network/rust_tcp/README.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
Code copied from:
|
||||||
|
https://github.com/jonhoo/rust-tcp
|
||||||
|
|
||||||
|
|
||||||
13
__network/rust_tcp/run.sh
Executable file
13
__network/rust_tcp/run.sh
Executable file
@@ -0,0 +1,13 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
cargo b --release
|
||||||
|
ext=$?
|
||||||
|
if [[ $ext -ne 0 ]]; then
|
||||||
|
exit $ext
|
||||||
|
fi
|
||||||
|
sudo setcap cap_net_admin=eip $CARGO_TARGET_DIR/release/trust
|
||||||
|
$CARGO_TARGET_DIR/release/trust &
|
||||||
|
pid=$!
|
||||||
|
sudo ip addr add 192.168.0.1/24 dev tun0
|
||||||
|
sudo ip link set up dev tun0
|
||||||
|
trap "kill $pid" INT TERM
|
||||||
|
wait $pid
|
||||||
347
__network/rust_tcp/src/lib.rs
Normal file
347
__network/rust_tcp/src/lib.rs
Normal file
@@ -0,0 +1,347 @@
|
|||||||
|
use std::collections::{HashMap, VecDeque};
|
||||||
|
use std::io;
|
||||||
|
use std::io::prelude::*;
|
||||||
|
use std::net::Ipv4Addr;
|
||||||
|
use std::sync::{Arc, Condvar, Mutex};
|
||||||
|
use std::thread;
|
||||||
|
|
||||||
|
mod tcp;
|
||||||
|
|
||||||
|
const SENDQUEUE_SIZE: usize = 1024;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
|
||||||
|
struct Quad {
|
||||||
|
src: (Ipv4Addr, u16),
|
||||||
|
dst: (Ipv4Addr, u16),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct Foobar {
|
||||||
|
manager: Mutex<ConnectionManager>,
|
||||||
|
pending_var: Condvar,
|
||||||
|
rcv_var: Condvar,
|
||||||
|
}
|
||||||
|
|
||||||
|
type InterfaceHandle = Arc<Foobar>;
|
||||||
|
|
||||||
|
pub struct Interface {
|
||||||
|
ih: Option<InterfaceHandle>,
|
||||||
|
jh: Option<thread::JoinHandle<io::Result<()>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for Interface {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
self.ih.as_mut().unwrap().manager.lock().unwrap().terminate = true;
|
||||||
|
|
||||||
|
drop(self.ih.take());
|
||||||
|
self.jh
|
||||||
|
.take()
|
||||||
|
.expect("interface dropped more than once")
|
||||||
|
.join()
|
||||||
|
.unwrap()
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct ConnectionManager {
|
||||||
|
terminate: bool,
|
||||||
|
connections: HashMap<Quad, tcp::Connection>,
|
||||||
|
pending: HashMap<u16, VecDeque<Quad>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn packet_loop(mut nic: tun_tap::Iface, ih: InterfaceHandle) -> io::Result<()> {
|
||||||
|
let mut buf = [0u8; 1504];
|
||||||
|
|
||||||
|
loop {
|
||||||
|
// we want to read from nic, but we want to make sure that we'll wake up when the next
|
||||||
|
// timer has to be triggered!
|
||||||
|
use std::os::unix::io::AsRawFd;
|
||||||
|
let mut pfd = [nix::poll::PollFd::new(
|
||||||
|
nic.as_raw_fd(),
|
||||||
|
nix::poll::EventFlags::POLLIN,
|
||||||
|
)];
|
||||||
|
let n = nix::poll::poll(&mut pfd[..], 10).map_err(|e| e.as_errno().unwrap())?;
|
||||||
|
assert_ne!(n, -1);
|
||||||
|
if n == 0 {
|
||||||
|
let mut cmg = ih.manager.lock().unwrap();
|
||||||
|
for connection in cmg.connections.values_mut() {
|
||||||
|
// XXX: don't die on errors?
|
||||||
|
connection.on_tick(&mut nic)?;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
assert_eq!(n, 1);
|
||||||
|
let nbytes = nic.recv(&mut buf[..])?;
|
||||||
|
|
||||||
|
// TODO: if self.terminate && Arc::get_strong_refs(ih) == 1; then tear down all connections and return.
|
||||||
|
|
||||||
|
// if s/without_packet_info/new/:
|
||||||
|
//
|
||||||
|
// let _eth_flags = u16::from_be_bytes([buf[0], buf[1]]);
|
||||||
|
// let eth_proto = u16::from_be_bytes([buf[2], buf[3]]);
|
||||||
|
// if eth_proto != 0x0800 {
|
||||||
|
// // not ipv4
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// and also include on send
|
||||||
|
|
||||||
|
match etherparse::Ipv4HeaderSlice::from_slice(&buf[..nbytes]) {
|
||||||
|
Ok(iph) => {
|
||||||
|
let src = iph.source_addr();
|
||||||
|
let dst = iph.destination_addr();
|
||||||
|
if iph.protocol() != 0x06 {
|
||||||
|
eprintln!("BAD PROTOCOL");
|
||||||
|
// not tcp
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
match etherparse::TcpHeaderSlice::from_slice(&buf[iph.slice().len()..nbytes]) {
|
||||||
|
Ok(tcph) => {
|
||||||
|
use std::collections::hash_map::Entry;
|
||||||
|
let datai = iph.slice().len() + tcph.slice().len();
|
||||||
|
let mut cmg = ih.manager.lock().unwrap();
|
||||||
|
let cm = &mut *cmg;
|
||||||
|
let q = Quad {
|
||||||
|
src: (src, tcph.source_port()),
|
||||||
|
dst: (dst, tcph.destination_port()),
|
||||||
|
};
|
||||||
|
|
||||||
|
match cm.connections.entry(q) {
|
||||||
|
Entry::Occupied(mut c) => {
|
||||||
|
eprintln!("got packet for known quad {:?}", q);
|
||||||
|
let a = c.get_mut().on_packet(
|
||||||
|
&mut nic,
|
||||||
|
iph,
|
||||||
|
tcph,
|
||||||
|
&buf[datai..nbytes],
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// TODO: compare before/after
|
||||||
|
drop(cmg);
|
||||||
|
if a.contains(tcp::Available::READ) {
|
||||||
|
ih.rcv_var.notify_all()
|
||||||
|
}
|
||||||
|
if a.contains(tcp::Available::WRITE) {
|
||||||
|
// TODO: ih.snd_var.notify_all()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Entry::Vacant(e) => {
|
||||||
|
eprintln!("got packet for unknown quad {:?}", q);
|
||||||
|
if let Some(pending) = cm.pending.get_mut(&tcph.destination_port())
|
||||||
|
{
|
||||||
|
eprintln!("listening, so accepting");
|
||||||
|
if let Some(c) = tcp::Connection::accept(
|
||||||
|
&mut nic,
|
||||||
|
iph,
|
||||||
|
tcph,
|
||||||
|
&buf[datai..nbytes],
|
||||||
|
)? {
|
||||||
|
e.insert(c);
|
||||||
|
pending.push_back(q);
|
||||||
|
drop(cmg);
|
||||||
|
ih.pending_var.notify_all()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("ignoring weird tcp packet {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
// eprintln!("ignoring weird packet {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Interface {
|
||||||
|
pub fn new() -> io::Result<Self> {
|
||||||
|
let nic = tun_tap::Iface::without_packet_info("tun0", tun_tap::Mode::Tun)?;
|
||||||
|
|
||||||
|
let ih: InterfaceHandle = Arc::default();
|
||||||
|
|
||||||
|
let jh = {
|
||||||
|
let ih = ih.clone();
|
||||||
|
thread::spawn(move || packet_loop(nic, ih))
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Interface {
|
||||||
|
ih: Some(ih),
|
||||||
|
jh: Some(jh),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bind(&mut self, port: u16) -> io::Result<TcpListener> {
|
||||||
|
use std::collections::hash_map::Entry;
|
||||||
|
let mut cm = self.ih.as_mut().unwrap().manager.lock().unwrap();
|
||||||
|
match cm.pending.entry(port) {
|
||||||
|
Entry::Vacant(v) => {
|
||||||
|
v.insert(VecDeque::new());
|
||||||
|
}
|
||||||
|
Entry::Occupied(_) => {
|
||||||
|
return Err(io::Error::new(
|
||||||
|
io::ErrorKind::AddrInUse,
|
||||||
|
"port already bound",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
drop(cm);
|
||||||
|
Ok(TcpListener {
|
||||||
|
port,
|
||||||
|
h: self.ih.as_mut().unwrap().clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct TcpListener {
|
||||||
|
port: u16,
|
||||||
|
h: InterfaceHandle,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for TcpListener {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
let mut cm = self.h.manager.lock().unwrap();
|
||||||
|
|
||||||
|
let pending = cm
|
||||||
|
.pending
|
||||||
|
.remove(&self.port)
|
||||||
|
.expect("port closed while listener still active");
|
||||||
|
|
||||||
|
for quad in pending {
|
||||||
|
// TODO: terminate cm.connections[quad]
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TcpListener {
|
||||||
|
pub fn accept(&mut self) -> io::Result<TcpStream> {
|
||||||
|
let mut cm = self.h.manager.lock().unwrap();
|
||||||
|
loop {
|
||||||
|
if let Some(quad) = cm
|
||||||
|
.pending
|
||||||
|
.get_mut(&self.port)
|
||||||
|
.expect("port closed while listener still active")
|
||||||
|
.pop_front()
|
||||||
|
{
|
||||||
|
return Ok(TcpStream {
|
||||||
|
quad,
|
||||||
|
h: self.h.clone(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
cm = self.h.pending_var.wait(cm).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct TcpStream {
|
||||||
|
quad: Quad,
|
||||||
|
h: InterfaceHandle,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for TcpStream {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
let cm = self.h.manager.lock().unwrap();
|
||||||
|
// TODO: send FIN on cm.connections[quad]
|
||||||
|
// TODO: _eventually_ remove self.quad from cm.connections
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Read for TcpStream {
|
||||||
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
|
let mut cm = self.h.manager.lock().unwrap();
|
||||||
|
loop {
|
||||||
|
let c = cm.connections.get_mut(&self.quad).ok_or_else(|| {
|
||||||
|
io::Error::new(
|
||||||
|
io::ErrorKind::ConnectionAborted,
|
||||||
|
"stream was terminated unexpectedly",
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
if c.is_rcv_closed() && c.incoming.is_empty() {
|
||||||
|
// no more data to read, and no need to block, because there won't be any more
|
||||||
|
return Ok(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if !c.incoming.is_empty() {
|
||||||
|
let mut nread = 0;
|
||||||
|
let (head, tail) = c.incoming.as_slices();
|
||||||
|
let hread = std::cmp::min(buf.len(), head.len());
|
||||||
|
buf[..hread].copy_from_slice(&head[..hread]);
|
||||||
|
nread += hread;
|
||||||
|
let tread = std::cmp::min(buf.len() - nread, tail.len());
|
||||||
|
buf[hread..(hread + tread)].copy_from_slice(&tail[..tread]);
|
||||||
|
nread += tread;
|
||||||
|
drop(c.incoming.drain(..nread));
|
||||||
|
return Ok(nread);
|
||||||
|
}
|
||||||
|
|
||||||
|
cm = self.h.rcv_var.wait(cm).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Write for TcpStream {
|
||||||
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||||
|
let mut cm = self.h.manager.lock().unwrap();
|
||||||
|
let c = cm.connections.get_mut(&self.quad).ok_or_else(|| {
|
||||||
|
io::Error::new(
|
||||||
|
io::ErrorKind::ConnectionAborted,
|
||||||
|
"stream was terminated unexpectedly",
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
if c.unacked.len() >= SENDQUEUE_SIZE {
|
||||||
|
// TODO: block
|
||||||
|
return Err(io::Error::new(
|
||||||
|
io::ErrorKind::WouldBlock,
|
||||||
|
"too many bytes buffered",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
let nwrite = std::cmp::min(buf.len(), SENDQUEUE_SIZE - c.unacked.len());
|
||||||
|
c.unacked.extend(buf[..nwrite].iter());
|
||||||
|
|
||||||
|
Ok(nwrite)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flush(&mut self) -> io::Result<()> {
|
||||||
|
let mut cm = self.h.manager.lock().unwrap();
|
||||||
|
let c = cm.connections.get_mut(&self.quad).ok_or_else(|| {
|
||||||
|
io::Error::new(
|
||||||
|
io::ErrorKind::ConnectionAborted,
|
||||||
|
"stream was terminated unexpectedly",
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
if c.unacked.is_empty() {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
// TODO: block
|
||||||
|
Err(io::Error::new(
|
||||||
|
io::ErrorKind::WouldBlock,
|
||||||
|
"too many bytes buffered",
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TcpStream {
|
||||||
|
pub fn shutdown(&self, how: std::net::Shutdown) -> io::Result<()> {
|
||||||
|
let mut cm = self.h.manager.lock().unwrap();
|
||||||
|
let c = cm.connections.get_mut(&self.quad).ok_or_else(|| {
|
||||||
|
io::Error::new(
|
||||||
|
io::ErrorKind::ConnectionAborted,
|
||||||
|
"stream was terminated unexpectedly",
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
c.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
27
__network/rust_tcp/src/main.rs
Normal file
27
__network/rust_tcp/src/main.rs
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
use std::io::prelude::*;
|
||||||
|
use std::{io, thread};
|
||||||
|
|
||||||
|
fn main() -> io::Result<()> {
|
||||||
|
let mut i = trust::Interface::new()?;
|
||||||
|
eprintln!("created interface");
|
||||||
|
let mut listener = i.bind(8000)?;
|
||||||
|
while let Ok(mut stream) = listener.accept() {
|
||||||
|
eprintln!("got connection!");
|
||||||
|
thread::spawn(move || {
|
||||||
|
stream.write(b"hello from rust-tcp!\n").unwrap();
|
||||||
|
stream.shutdown(std::net::Shutdown::Write).unwrap();
|
||||||
|
loop {
|
||||||
|
let mut buf = [0; 512];
|
||||||
|
let n = stream.read(&mut buf[..]).unwrap();
|
||||||
|
eprintln!("read {}b of data", n);
|
||||||
|
if n == 0 {
|
||||||
|
eprintln!("no more data!");
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
println!("{}", std::str::from_utf8(&buf[..n]).unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
568
__network/rust_tcp/src/tcp.rs
Normal file
568
__network/rust_tcp/src/tcp.rs
Normal file
@@ -0,0 +1,568 @@
|
|||||||
|
use bitflags::bitflags;
|
||||||
|
use std::collections::{BTreeMap, VecDeque};
|
||||||
|
use std::{io, time};
|
||||||
|
|
||||||
|
bitflags! {
|
||||||
|
pub(crate) struct Available: u8 {
|
||||||
|
const READ = 0b00000001;
|
||||||
|
const WRITE = 0b00000010;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum State {
|
||||||
|
//Listen,
|
||||||
|
SynRcvd,
|
||||||
|
Estab,
|
||||||
|
FinWait1,
|
||||||
|
FinWait2,
|
||||||
|
TimeWait,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl State {
|
||||||
|
fn is_synchronized(&self) -> bool {
|
||||||
|
match *self {
|
||||||
|
State::SynRcvd => false,
|
||||||
|
State::Estab | State::FinWait1 | State::FinWait2 | State::TimeWait => true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Connection {
|
||||||
|
state: State,
|
||||||
|
send: SendSequenceSpace,
|
||||||
|
recv: RecvSequenceSpace,
|
||||||
|
ip: etherparse::Ipv4Header,
|
||||||
|
tcp: etherparse::TcpHeader,
|
||||||
|
timers: Timers,
|
||||||
|
|
||||||
|
pub(crate) incoming: VecDeque<u8>,
|
||||||
|
pub(crate) unacked: VecDeque<u8>,
|
||||||
|
|
||||||
|
pub(crate) closed: bool,
|
||||||
|
closed_at: Option<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Timers {
|
||||||
|
send_times: BTreeMap<u32, time::Instant>,
|
||||||
|
srtt: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Connection {
|
||||||
|
pub(crate) fn is_rcv_closed(&self) -> bool {
|
||||||
|
if let State::TimeWait = self.state {
|
||||||
|
// TODO: any state after rcvd FIN, so also CLOSE-WAIT, LAST-ACK, CLOSED, CLOSING
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn availability(&self) -> Available {
|
||||||
|
let mut a = Available::empty();
|
||||||
|
if self.is_rcv_closed() || !self.incoming.is_empty() {
|
||||||
|
a |= Available::READ;
|
||||||
|
}
|
||||||
|
// TODO: take into account self.state
|
||||||
|
// TODO: set Available::WRITE
|
||||||
|
a
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// State of the Send Sequence Space (RFC 793 S3.2 F4)
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// 1 2 3 4
|
||||||
|
/// ----------|----------|----------|----------
|
||||||
|
/// SND.UNA SND.NXT SND.UNA
|
||||||
|
/// +SND.WND
|
||||||
|
///
|
||||||
|
/// 1 - old sequence numbers which have been acknowledged
|
||||||
|
/// 2 - sequence numbers of unacknowledged data
|
||||||
|
/// 3 - sequence numbers allowed for new data transmission
|
||||||
|
/// 4 - future sequence numbers which are not yet allowed
|
||||||
|
/// ```
|
||||||
|
struct SendSequenceSpace {
|
||||||
|
/// send unacknowledged
|
||||||
|
una: u32,
|
||||||
|
/// send next
|
||||||
|
nxt: u32,
|
||||||
|
/// send window
|
||||||
|
wnd: u16,
|
||||||
|
/// send urgent pointer
|
||||||
|
up: bool,
|
||||||
|
/// segment sequence number used for last window update
|
||||||
|
wl1: usize,
|
||||||
|
/// segment acknowledgment number used for last window update
|
||||||
|
wl2: usize,
|
||||||
|
/// initial send sequence number
|
||||||
|
iss: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// State of the Receive Sequence Space (RFC 793 S3.2 F5)
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// 1 2 3
|
||||||
|
/// ----------|----------|----------
|
||||||
|
/// RCV.NXT RCV.NXT
|
||||||
|
/// +RCV.WND
|
||||||
|
///
|
||||||
|
/// 1 - old sequence numbers which have been acknowledged
|
||||||
|
/// 2 - sequence numbers allowed for new reception
|
||||||
|
/// 3 - future sequence numbers which are not yet allowed
|
||||||
|
/// ```
|
||||||
|
struct RecvSequenceSpace {
|
||||||
|
/// receive next
|
||||||
|
nxt: u32,
|
||||||
|
/// receive window
|
||||||
|
wnd: u16,
|
||||||
|
/// receive urgent pointer
|
||||||
|
up: bool,
|
||||||
|
/// initial receive sequence number
|
||||||
|
irs: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Connection {
|
||||||
|
pub fn accept<'a>(
|
||||||
|
nic: &mut tun_tap::Iface,
|
||||||
|
iph: etherparse::Ipv4HeaderSlice<'a>,
|
||||||
|
tcph: etherparse::TcpHeaderSlice<'a>,
|
||||||
|
data: &'a [u8],
|
||||||
|
) -> io::Result<Option<Self>> {
|
||||||
|
let buf = [0u8; 1500];
|
||||||
|
if !tcph.syn() {
|
||||||
|
// only expected SYN packet
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
|
||||||
|
let iss = 0;
|
||||||
|
let wnd = 1024;
|
||||||
|
let mut c = Connection {
|
||||||
|
timers: Timers {
|
||||||
|
send_times: Default::default(),
|
||||||
|
srtt: time::Duration::from_secs(1 * 60).as_secs_f64(),
|
||||||
|
},
|
||||||
|
state: State::SynRcvd,
|
||||||
|
send: SendSequenceSpace {
|
||||||
|
iss,
|
||||||
|
una: iss,
|
||||||
|
nxt: iss,
|
||||||
|
wnd: wnd,
|
||||||
|
up: false,
|
||||||
|
|
||||||
|
wl1: 0,
|
||||||
|
wl2: 0,
|
||||||
|
},
|
||||||
|
recv: RecvSequenceSpace {
|
||||||
|
irs: tcph.sequence_number(),
|
||||||
|
nxt: tcph.sequence_number() + 1,
|
||||||
|
wnd: tcph.window_size(),
|
||||||
|
up: false,
|
||||||
|
},
|
||||||
|
tcp: etherparse::TcpHeader::new(tcph.destination_port(), tcph.source_port(), iss, wnd),
|
||||||
|
ip: etherparse::Ipv4Header::new(
|
||||||
|
0,
|
||||||
|
64,
|
||||||
|
etherparse::IpTrafficClass::Tcp,
|
||||||
|
[
|
||||||
|
iph.destination()[0],
|
||||||
|
iph.destination()[1],
|
||||||
|
iph.destination()[2],
|
||||||
|
iph.destination()[3],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
iph.source()[0],
|
||||||
|
iph.source()[1],
|
||||||
|
iph.source()[2],
|
||||||
|
iph.source()[3],
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
incoming: Default::default(),
|
||||||
|
unacked: Default::default(),
|
||||||
|
|
||||||
|
closed: false,
|
||||||
|
closed_at: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
// need to start establishing a connection
|
||||||
|
c.tcp.syn = true;
|
||||||
|
c.tcp.ack = true;
|
||||||
|
c.write(nic, c.send.nxt, 0)?;
|
||||||
|
Ok(Some(c))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write(&mut self, nic: &mut tun_tap::Iface, seq: u32, mut limit: usize) -> io::Result<usize> {
|
||||||
|
let mut buf = [0u8; 1500];
|
||||||
|
self.tcp.sequence_number = seq;
|
||||||
|
self.tcp.acknowledgment_number = self.recv.nxt;
|
||||||
|
|
||||||
|
// TODO: return +1 for SYN/FIN
|
||||||
|
println!(
|
||||||
|
"write(ack: {}, seq: {}, limit: {}) syn {:?} fin {:?}",
|
||||||
|
self.recv.nxt - self.recv.irs, seq, limit, self.tcp.syn, self.tcp.fin,
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut offset = seq.wrapping_sub(self.send.una) as usize;
|
||||||
|
// we need to special-case the two "virtual" bytes SYN and FIN
|
||||||
|
if let Some(closed_at) = self.closed_at {
|
||||||
|
if seq == closed_at.wrapping_add(1) {
|
||||||
|
// trying to write following FIN
|
||||||
|
offset = 0;
|
||||||
|
limit = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println!(
|
||||||
|
"using offset {} base {} in {:?}",
|
||||||
|
offset,
|
||||||
|
self.send.una,
|
||||||
|
self.unacked.as_slices()
|
||||||
|
);
|
||||||
|
let (mut h, mut t) = self.unacked.as_slices();
|
||||||
|
if h.len() >= offset {
|
||||||
|
h = &h[offset..];
|
||||||
|
} else {
|
||||||
|
let skipped = h.len();
|
||||||
|
h = &[];
|
||||||
|
t = &t[(offset - skipped)..];
|
||||||
|
}
|
||||||
|
|
||||||
|
let max_data = std::cmp::min(limit, h.len() + t.len());
|
||||||
|
let size = std::cmp::min(
|
||||||
|
buf.len(),
|
||||||
|
self.tcp.header_len() as usize + self.ip.header_len() as usize + max_data,
|
||||||
|
);
|
||||||
|
self.ip
|
||||||
|
.set_payload_len(size - self.ip.header_len() as usize);
|
||||||
|
|
||||||
|
// write out the headers and the payload
|
||||||
|
use std::io::Write;
|
||||||
|
let buf_len = buf.len();
|
||||||
|
let mut unwritten = &mut buf[..];
|
||||||
|
|
||||||
|
self.ip.write(&mut unwritten);
|
||||||
|
let ip_header_ends_at = buf_len - unwritten.len();
|
||||||
|
|
||||||
|
// postpone writing the tcp header because we need the payload as one contiguous slice to calculate the tcp checksum
|
||||||
|
unwritten = &mut unwritten[self.tcp.header_len() as usize..];
|
||||||
|
let tcp_header_ends_at = buf_len - unwritten.len();
|
||||||
|
|
||||||
|
// write out the payload
|
||||||
|
let payload_bytes = {
|
||||||
|
let mut written = 0;
|
||||||
|
let mut limit = max_data;
|
||||||
|
|
||||||
|
// first, write as much as we can from h
|
||||||
|
let p1l = std::cmp::min(limit, h.len());
|
||||||
|
written += unwritten.write(&h[..p1l])?;
|
||||||
|
limit -= written;
|
||||||
|
|
||||||
|
// then, write more (if we can) from t
|
||||||
|
let p2l = std::cmp::min(limit, t.len());
|
||||||
|
written += unwritten.write(&t[..p2l])?;
|
||||||
|
written
|
||||||
|
};
|
||||||
|
let payload_ends_at = buf_len - unwritten.len();
|
||||||
|
|
||||||
|
// finally we can calculate the tcp checksum and write out the tcp header
|
||||||
|
self.tcp.checksum = self
|
||||||
|
.tcp
|
||||||
|
.calc_checksum_ipv4(&self.ip, &buf[tcp_header_ends_at..payload_ends_at])
|
||||||
|
.expect("failed to compute checksum");
|
||||||
|
|
||||||
|
let mut tcp_header_buf = &mut buf[ip_header_ends_at..tcp_header_ends_at];
|
||||||
|
self.tcp.write(&mut tcp_header_buf);
|
||||||
|
|
||||||
|
let mut next_seq = seq.wrapping_add(payload_bytes as u32);
|
||||||
|
if self.tcp.syn {
|
||||||
|
next_seq = next_seq.wrapping_add(1);
|
||||||
|
self.tcp.syn = false;
|
||||||
|
}
|
||||||
|
if self.tcp.fin {
|
||||||
|
next_seq = next_seq.wrapping_add(1);
|
||||||
|
self.tcp.fin = false;
|
||||||
|
}
|
||||||
|
if wrapping_lt(self.send.nxt, next_seq) {
|
||||||
|
self.send.nxt = next_seq;
|
||||||
|
}
|
||||||
|
self.timers.send_times.insert(seq, time::Instant::now());
|
||||||
|
|
||||||
|
nic.send(&buf[..payload_ends_at])?;
|
||||||
|
Ok(payload_bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn send_rst(&mut self, nic: &mut tun_tap::Iface) -> io::Result<()> {
|
||||||
|
self.tcp.rst = true;
|
||||||
|
// TODO: fix sequence numbers here
|
||||||
|
// If the incoming segment has an ACK field, the reset takes its
|
||||||
|
// sequence number from the ACK field of the segment, otherwise the
|
||||||
|
// reset has sequence number zero and the ACK field is set to the sum
|
||||||
|
// of the sequence number and segment length of the incoming segment.
|
||||||
|
// The connection remains in the same state.
|
||||||
|
//
|
||||||
|
// TODO: handle synchronized RST
|
||||||
|
// 3. If the connection is in a synchronized state (ESTABLISHED,
|
||||||
|
// FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, CLOSING, LAST-ACK, TIME-WAIT),
|
||||||
|
// any unacceptable segment (out of window sequence number or
|
||||||
|
// unacceptible acknowledgment number) must elicit only an empty
|
||||||
|
// acknowledgment segment containing the current send-sequence number
|
||||||
|
// and an acknowledgment indicating the next sequence number expected
|
||||||
|
// to be received, and the connection remains in the same state.
|
||||||
|
self.tcp.sequence_number = 0;
|
||||||
|
self.tcp.acknowledgment_number = 0;
|
||||||
|
self.write(nic, self.send.nxt, 0)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn on_tick(&mut self, nic: &mut tun_tap::Iface) -> io::Result<()> {
|
||||||
|
if let State::FinWait2 | State::TimeWait = self.state {
|
||||||
|
// we have shutdown our write side and the other side acked, no need to (re)transmit anything
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
// eprintln!("ON TICK: state {:?} una {} nxt {} unacked {:?}",
|
||||||
|
// self.state, self.send.una, self.send.nxt, self.unacked);
|
||||||
|
|
||||||
|
let nunacked_data = self.closed_at.unwrap_or(self.send.nxt).wrapping_sub(self.send.una);
|
||||||
|
let nunsent_data = self.unacked.len() as u32 - nunacked_data;
|
||||||
|
|
||||||
|
let waited_for = self
|
||||||
|
.timers
|
||||||
|
.send_times
|
||||||
|
.range(self.send.una..)
|
||||||
|
.next()
|
||||||
|
.map(|t| t.1.elapsed());
|
||||||
|
|
||||||
|
let should_retransmit = if let Some(waited_for) = waited_for {
|
||||||
|
waited_for > time::Duration::from_secs(1)
|
||||||
|
&& waited_for.as_secs_f64() > 1.5 * self.timers.srtt
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
|
|
||||||
|
if should_retransmit {
|
||||||
|
let resend = std::cmp::min(self.unacked.len() as u32, self.send.wnd as u32);
|
||||||
|
if resend < self.send.wnd as u32 && self.closed {
|
||||||
|
// can we include the FIN?
|
||||||
|
self.tcp.fin = true;
|
||||||
|
self.closed_at = Some(self.send.una.wrapping_add(self.unacked.len() as u32));
|
||||||
|
}
|
||||||
|
self.write(nic, self.send.una, resend as usize)?;
|
||||||
|
} else {
|
||||||
|
// we should send new data if we have new data and space in the window
|
||||||
|
if nunsent_data == 0 && self.closed_at.is_some() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let allowed = self.send.wnd as u32 - nunacked_data;
|
||||||
|
if allowed == 0 {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let send = std::cmp::min(nunsent_data, allowed);
|
||||||
|
if send < allowed && self.closed && self.closed_at.is_none() {
|
||||||
|
self.tcp.fin = true;
|
||||||
|
self.closed_at = Some(self.send.una.wrapping_add(self.unacked.len() as u32));
|
||||||
|
}
|
||||||
|
|
||||||
|
self.write(nic, self.send.nxt, send as usize)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn on_packet<'a>(
|
||||||
|
&mut self,
|
||||||
|
nic: &mut tun_tap::Iface,
|
||||||
|
iph: etherparse::Ipv4HeaderSlice<'a>,
|
||||||
|
tcph: etherparse::TcpHeaderSlice<'a>,
|
||||||
|
data: &'a [u8],
|
||||||
|
) -> io::Result<Available> {
|
||||||
|
// first, check that sequence numbers are valid (RFC 793 S3.3)
|
||||||
|
let seqn = tcph.sequence_number();
|
||||||
|
let mut slen = data.len() as u32;
|
||||||
|
if tcph.fin() {
|
||||||
|
slen += 1;
|
||||||
|
};
|
||||||
|
if tcph.syn() {
|
||||||
|
slen += 1;
|
||||||
|
};
|
||||||
|
let wend = self.recv.nxt.wrapping_add(self.recv.wnd as u32);
|
||||||
|
let okay = if slen == 0 {
|
||||||
|
// zero-length segment has separate rules for acceptance
|
||||||
|
if self.recv.wnd == 0 {
|
||||||
|
if seqn != self.recv.nxt {
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
} else if !is_between_wrapped(self.recv.nxt.wrapping_sub(1), seqn, wend) {
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if self.recv.wnd == 0 {
|
||||||
|
false
|
||||||
|
} else if !is_between_wrapped(self.recv.nxt.wrapping_sub(1), seqn, wend)
|
||||||
|
&& !is_between_wrapped(
|
||||||
|
self.recv.nxt.wrapping_sub(1),
|
||||||
|
seqn.wrapping_add(slen - 1),
|
||||||
|
wend,
|
||||||
|
)
|
||||||
|
{
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if !okay {
|
||||||
|
eprintln!("NOT OKAY");
|
||||||
|
self.write(nic, self.send.nxt, 0)?;
|
||||||
|
return Ok(self.availability());
|
||||||
|
}
|
||||||
|
|
||||||
|
if !tcph.ack() {
|
||||||
|
if tcph.syn() {
|
||||||
|
// got SYN part of initial handshake
|
||||||
|
assert!(data.is_empty());
|
||||||
|
self.recv.nxt = seqn.wrapping_add(1);
|
||||||
|
}
|
||||||
|
return Ok(self.availability());
|
||||||
|
}
|
||||||
|
|
||||||
|
let ackn = tcph.acknowledgment_number();
|
||||||
|
if let State::SynRcvd = self.state {
|
||||||
|
if is_between_wrapped(
|
||||||
|
self.send.una.wrapping_sub(1),
|
||||||
|
ackn,
|
||||||
|
self.send.nxt.wrapping_add(1),
|
||||||
|
) {
|
||||||
|
// must have ACKed our SYN, since we detected at least one acked byte,
|
||||||
|
// and we have only sent one byte (the SYN).
|
||||||
|
self.state = State::Estab;
|
||||||
|
} else {
|
||||||
|
// TODO: <SEQ=SEG.ACK><CTL=RST>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let State::Estab | State::FinWait1 | State::FinWait2 = self.state {
|
||||||
|
if is_between_wrapped(self.send.una, ackn, self.send.nxt.wrapping_add(1)) {
|
||||||
|
println!(
|
||||||
|
"ack for {} (last: {}); prune in {:?}",
|
||||||
|
ackn, self.send.una, self.unacked
|
||||||
|
);
|
||||||
|
if !self.unacked.is_empty() {
|
||||||
|
let data_start = if self.send.una == self.send.iss {
|
||||||
|
// send.una hasn't been updated yet with ACK for our SYN, so data starts just beyond it
|
||||||
|
self.send.una.wrapping_add(1)
|
||||||
|
} else {
|
||||||
|
self.send.una
|
||||||
|
};
|
||||||
|
let acked_data_end = std::cmp::min(ackn.wrapping_sub(data_start) as usize, self.unacked.len());
|
||||||
|
self.unacked.drain(..acked_data_end);
|
||||||
|
|
||||||
|
let old = std::mem::replace(&mut self.timers.send_times, BTreeMap::new());
|
||||||
|
|
||||||
|
let una = self.send.una;
|
||||||
|
let mut srtt = &mut self.timers.srtt;
|
||||||
|
self.timers
|
||||||
|
.send_times
|
||||||
|
.extend(old.into_iter().filter_map(|(seq, sent)| {
|
||||||
|
if is_between_wrapped(una, seq, ackn) {
|
||||||
|
*srtt = 0.8 * *srtt + (1.0 - 0.8) * sent.elapsed().as_secs_f64();
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some((seq, sent))
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
self.send.una = ackn;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: if unacked empty and waiting flush, notify
|
||||||
|
// TODO: update window
|
||||||
|
}
|
||||||
|
|
||||||
|
if let State::FinWait1 = self.state {
|
||||||
|
if let Some(closed_at) = self.closed_at {
|
||||||
|
if self.send.una == closed_at.wrapping_add(1) {
|
||||||
|
// our FIN has been ACKed!
|
||||||
|
self.state = State::FinWait2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !data.is_empty() {
|
||||||
|
if let State::Estab | State::FinWait1 | State::FinWait2 = self.state {
|
||||||
|
let mut unread_data_at = self.recv.nxt.wrapping_sub(seqn) as usize;
|
||||||
|
if unread_data_at > data.len() {
|
||||||
|
// we must have received a re-transmitted FIN that we have already seen
|
||||||
|
// nxt points to beyond the fin, but the fin is not in data!
|
||||||
|
assert_eq!(unread_data_at, data.len() + 1);
|
||||||
|
unread_data_at = 0;
|
||||||
|
}
|
||||||
|
self.incoming.extend(&data[unread_data_at..]);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Once the TCP takes responsibility for the data it advances
|
||||||
|
RCV.NXT over the data accepted, and adjusts RCV.WND as
|
||||||
|
apporopriate to the current buffer availability. The total of
|
||||||
|
RCV.NXT and RCV.WND should not be reduced.
|
||||||
|
*/
|
||||||
|
self.recv.nxt = seqn.wrapping_add(data.len() as u32);
|
||||||
|
|
||||||
|
// Send an acknowledgment of the form: <SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK>
|
||||||
|
// TODO: maybe just tick to piggyback ack on data?
|
||||||
|
self.write(nic, self.send.nxt, 0)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if tcph.fin() {
|
||||||
|
match self.state {
|
||||||
|
State::FinWait2 => {
|
||||||
|
// we're done with the connection!
|
||||||
|
self.recv.nxt = self.recv.nxt.wrapping_add(1);
|
||||||
|
self.write(nic, self.send.nxt, 0)?;
|
||||||
|
self.state = State::TimeWait;
|
||||||
|
}
|
||||||
|
_ => unimplemented!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(self.availability())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn close(&mut self) -> io::Result<()> {
|
||||||
|
self.closed = true;
|
||||||
|
match self.state {
|
||||||
|
State::SynRcvd | State::Estab => {
|
||||||
|
self.state = State::FinWait1;
|
||||||
|
}
|
||||||
|
State::FinWait1 | State::FinWait2 => {}
|
||||||
|
_ => {
|
||||||
|
return Err(io::Error::new(
|
||||||
|
io::ErrorKind::NotConnected,
|
||||||
|
"already closing",
|
||||||
|
))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn wrapping_lt(lhs: u32, rhs: u32) -> bool {
|
||||||
|
// From RFC1323:
|
||||||
|
// TCP determines if a data segment is "old" or "new" by testing
|
||||||
|
// whether its sequence number is within 2**31 bytes of the left edge
|
||||||
|
// of the window, and if it is not, discarding the data as "old". To
|
||||||
|
// insure that new data is never mistakenly considered old and vice-
|
||||||
|
// versa, the left edge of the sender's window has to be at most
|
||||||
|
// 2**31 away from the right edge of the receiver's window.
|
||||||
|
lhs.wrapping_sub(rhs) > (1 << 31)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_between_wrapped(start: u32, x: u32, end: u32) -> bool {
|
||||||
|
wrapping_lt(start, x) && wrapping_lt(x, end)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user