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