Merge pull request #12 from nymtech/feature/client_packet_retrieval

Feature/client packet retrieval
This commit is contained in:
Dave Hrycyszyn
2019-12-12 15:25:40 +00:00
committed by GitHub
13 changed files with 1210 additions and 150 deletions
+2
View File
@@ -1,2 +1,4 @@
/target
**/*.rs.bk
/*/target
/test_inbox
Generated
+8
View File
@@ -514,6 +514,7 @@ dependencies = [
"futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hex 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"sfw-provider-requests 0.1.0",
"sphinx 0.1.0",
"tokio 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -653,6 +654,13 @@ name = "redox_syscall"
version = "0.1.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "sfw-provider-requests"
version = "0.1.0"
dependencies = [
"sphinx 0.1.0",
]
[[package]]
name = "sha2"
version = "0.8.0"
+1
View File
@@ -12,5 +12,6 @@ curve25519-dalek = "1.2.3"
hex = "0.4.0"
futures = "0.3.1"
rand = "0.7.2"
sfw-provider-requests = { path = "./sfw-provider-requests" }
sphinx = { path = "../sphinx" }
tokio = { version = "0.2.4", features = ["full"] }
+463
View File
@@ -0,0 +1,463 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "aes-ctr"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"aes-soft 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"aesni 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ctr 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"stream-cipher 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "aes-soft"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "aesni"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"stream-cipher 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "arrayref"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bitflags"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "blake2"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "block-buffer"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "block-cipher-trait"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "block-padding"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "byte-tools"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "byteorder"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "c2-chacha"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cc"
version = "1.0.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "chacha"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"keystream 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "clear_on_drop"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.48 (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.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crypto-mac"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
"subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ctr"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"stream-cipher 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "curve25519-dalek"
version = "1.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"subtle 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "digest"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fake-simd"
version = "0.1.2"
source = "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 = "generic-array"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "getrandom"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
"wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "hkdf"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "hmac"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "keystream"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libc"
version = "0.2.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "lioness"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"blake2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"chacha 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"keystream 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "opaque-debug"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ppv-lite86"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rand"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_chacha"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.5.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.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_core"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rand_core"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_distr"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_hc"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_os"
version = "0.1.3"
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.66 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.4.2 (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.8 (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 = "sfw-provider-requests"
version = "0.1.0"
dependencies = [
"sphinx 0.1.0",
]
[[package]]
name = "sha2"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "sphinx"
version = "0.1.0"
dependencies = [
"aes-ctr 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"blake2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"chacha 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"hkdf 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lioness 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_distr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "stream-cipher"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "subtle"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "subtle"
version = "2.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "typenum"
version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "wasi"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi"
version = "0.3.8"
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-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"
[metadata]
"checksum aes-ctr 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d2e5b0458ea3beae0d1d8c0f3946564f8e10f90646cf78c06b4351052058d1ee"
"checksum aes-soft 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cfd7e7ae3f9a1fb5c03b389fc6bb9a51400d0c13053f0dca698c832bfd893a0d"
"checksum aesni 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f70a6b5f971e473091ab7cfb5ffac6cde81666c4556751d8d5620ead8abf100"
"checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee"
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
"checksum blake2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330"
"checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
"checksum block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c924d49bd09e7c06003acda26cd9742e796e34282ec6c1189404dee0c1f4774"
"checksum block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
"checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
"checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb"
"checksum cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)" = "f52a465a666ca3d838ebbf08b241383421412fe7ebb463527bba275526d89f76"
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
"checksum chacha 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ddf3c081b5fba1e5615640aae998e0fbd10c24cbd897ee39ed754a77601a4862"
"checksum clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "97276801e127ffb46b66ce23f35cc96bd454fa311294bced4bbace7baa8b1d17"
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
"checksum crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5"
"checksum ctr 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "022cd691704491df67d25d006fe8eca083098253c4d43516c2206479c58c6736"
"checksum curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8b7dcd30ba50cdf88b55b033456138b7c0ac4afdc436d82e1b79f370f24cc66d"
"checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
"checksum getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407"
"checksum hkdf 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3fa08a006102488bd9cd5b8013aabe84955cf5ae22e304c2caf655b633aefae3"
"checksum hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695"
"checksum keystream 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c33070833c9ee02266356de0c43f723152bd38bd96ddf52c82b3af10c9138b28"
"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
"checksum lioness 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4ae926706ba42c425c9457121178330d75e273df2e82e28b758faf3de3a9acb9"
"checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
"checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
"checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412"
"checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853"
"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
"checksum rand_distr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "96977acbdd3a6576fb1d27391900035bf3863d4a16422973a409b488cf29ffb2"
"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
"checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
"checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d"
"checksum stream-cipher 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8131256a5896cabcf5eb04f4d6dacbe1aefda854b0d9896e09cb58829ec5638c"
"checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee"
"checksum subtle 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c65d530b10ccaeac294f349038a597e435b18fb456aadd0840a623f83b9e941"
"checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9"
"checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d"
"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
"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"
+10
View File
@@ -0,0 +1,10 @@
[package]
name = "sfw-provider-requests"
version = "0.1.0"
authors = ["Jedrzej Stuczynski <jedrzej.stuczynski@gmail.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
sphinx = { path = "../../sphinx" }
+5
View File
@@ -0,0 +1,5 @@
pub mod requests;
pub mod responses;
pub const DUMMY_MESSAGE_CONTENT: &[u8] =
b"[DUMMY MESSAGE] Wanting something does not give you the right to have it.";
+147
View File
@@ -0,0 +1,147 @@
const PULL_REQUEST_MESSAGE_PREFIX: [u8; 2] = [1, 0];
const REGISTER_MESSAGE_PREFIX: [u8; 2] = [0, 1];
// TODO: how to do it more nicely, considering all sfw-provider-requests implement same trait that is exercised here?
#[derive(Debug)]
pub enum ProviderRequests {
PullMessages(PullRequest),
Register(RegisterRequest),
}
impl ProviderRequests {
pub fn to_bytes(&self) -> Vec<u8> {
use ProviderRequests::*;
match self {
PullMessages(pr) => pr.to_bytes(),
Register(pr) => pr.to_bytes(),
}
}
pub fn from_bytes(bytes: &[u8]) -> Result<Self, ProviderRequestError> {
use ProviderRequests::*;
if bytes.len() < 2 {
return Err(ProviderRequestError::UnmarshalError);
}
let mut received_prefix = [0; 2];
received_prefix.copy_from_slice(&bytes[..2]);
match received_prefix {
PULL_REQUEST_MESSAGE_PREFIX => Ok(PullMessages(PullRequest::from_bytes(bytes)?)),
REGISTER_MESSAGE_PREFIX => Ok(Register(RegisterRequest::from_bytes(bytes)?)),
_ => Err(ProviderRequestError::UnmarshalErrorIncorrectPrefix),
}
}
}
#[derive(Debug)]
pub enum ProviderRequestError {
MarshalError,
UnmarshalError,
UnmarshalErrorIncorrectPrefix,
}
pub trait ProviderRequest
where
Self: Sized,
{
fn get_prefix() -> [u8; 2];
fn to_bytes(&self) -> Vec<u8>;
fn from_bytes(bytes: &[u8]) -> Result<Self, ProviderRequestError>;
}
#[derive(Debug)]
pub struct PullRequest {
// TODO: public keys, signatures, tokens, etc. basically some kind of authentication bs
pub destination_address: sphinx::route::DestinationAddressBytes,
}
impl PullRequest {
pub fn new(destination_address: sphinx::route::DestinationAddressBytes) -> Self {
PullRequest {
destination_address,
}
}
}
impl ProviderRequest for PullRequest {
fn get_prefix() -> [u8; 2] {
PULL_REQUEST_MESSAGE_PREFIX
}
fn to_bytes(&self) -> Vec<u8> {
Self::get_prefix()
.to_vec()
.into_iter()
.chain(self.destination_address.iter().cloned())
.collect()
}
fn from_bytes(bytes: &[u8]) -> Result<Self, ProviderRequestError> {
if bytes.len() != 2 + 32 {
return Err(ProviderRequestError::UnmarshalError);
}
let mut received_prefix = [0u8; 2];
received_prefix.copy_from_slice(&bytes[..2]);
if received_prefix != Self::get_prefix() {
return Err(ProviderRequestError::UnmarshalErrorIncorrectPrefix);
}
let mut destination_address = [0u8; 32];
destination_address.copy_from_slice(&bytes[2..]);
Ok(PullRequest {
destination_address,
})
}
}
#[derive(Debug)]
pub struct RegisterRequest {}
impl ProviderRequest for RegisterRequest {
fn get_prefix() -> [u8; 2] {
unimplemented!()
}
fn to_bytes(&self) -> Vec<u8> {
unimplemented!()
}
fn from_bytes(bytes: &[u8]) -> Result<Self, ProviderRequestError> {
unimplemented!()
}
}
#[cfg(test)]
mod creating_pull_request {
use super::*;
#[test]
fn it_is_possible_to_recover_it_from_bytes() {
let address = [
1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
0, 1, 2,
];
let pull_request = PullRequest::new(address);
let bytes = pull_request.to_bytes();
let recovered = PullRequest::from_bytes(&bytes).unwrap();
assert_eq!(address, recovered.destination_address);
}
#[test]
fn it_is_possible_to_recover_it_from_bytes_with_enum_wrapper() {
let address = [
1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
0, 1, 2,
];
let pull_request = PullRequest::new(address);
let bytes = pull_request.to_bytes();
let recovered = ProviderRequests::from_bytes(&bytes).unwrap();
match recovered {
ProviderRequests::PullMessages(req) => assert_eq!(address, req.destination_address),
_ => panic!("expected to recover pull request!"),
}
}
}
+122
View File
@@ -0,0 +1,122 @@
use std::convert::TryInto;
#[derive(Debug)]
pub enum ProviderResponseError {
MarshalError,
UnmarshalError,
UnmarshalErrorInvalidLength,
}
pub trait ProviderResponse
where
Self: Sized,
{
fn to_bytes(&self) -> Vec<u8>;
fn from_bytes(bytes: &[u8]) -> Result<Self, ProviderResponseError>;
}
#[derive(Debug)]
pub struct PullResponse {
pub messages: Vec<Vec<u8>>,
}
impl PullResponse {
pub fn new(messages: Vec<Vec<u8>>) -> Self {
PullResponse { messages }
}
}
// TODO: This should go into some kind of utils module/crate
fn read_be_u16(input: &mut &[u8]) -> u16 {
let (int_bytes, rest) = input.split_at(std::mem::size_of::<u16>());
*input = rest;
u16::from_be_bytes(int_bytes.try_into().unwrap())
}
// TODO: currently this allows for maximum 64kB payload - if we go over that in sphinx,
// we need to update this code.
impl ProviderResponse for PullResponse {
// num_msgs || len1 || len2 || ... || msg1 || msg2 || ...
fn to_bytes(&self) -> Vec<u8> {
let num_msgs = self.messages.len() as u16;
let msgs_lens: Vec<u16> = self.messages.iter().map(|msg| msg.len() as u16).collect();
num_msgs
.to_be_bytes()
.to_vec()
.into_iter()
.chain(
msgs_lens
.into_iter()
.flat_map(|len| len.to_be_bytes().to_vec().into_iter()),
)
.chain(self.messages.iter().flat_map(|msg| msg.clone().into_iter()))
.collect()
}
fn from_bytes(bytes: &[u8]) -> Result<Self, ProviderResponseError> {
// can we read number of messages?
if bytes.len() < 2 {
return Err(ProviderResponseError::UnmarshalErrorInvalidLength);
}
let mut bytes_copy = bytes.clone();
let num_msgs = read_be_u16(&mut bytes_copy);
// can we read all lengths of messages?
if bytes_copy.len() < (num_msgs * 2) as usize {
return Err(ProviderResponseError::UnmarshalErrorInvalidLength);
}
let msgs_lens: Vec<_> = (0..num_msgs)
.map(|_| read_be_u16(&mut bytes_copy))
.collect();
let required_remaining_len = msgs_lens
.iter()
.fold(0usize, |acc, &len| acc + (len as usize));
// can we read messages themselves?
if bytes_copy.len() != required_remaining_len {
return Err(ProviderResponseError::UnmarshalErrorInvalidLength);
}
let msgs = msgs_lens
.iter()
.scan(0usize, |i, &len| {
let j = *i + (len as usize);
let msg = bytes_copy[*i..j].to_vec();
*i = j;
Some(msg)
})
.collect();
Ok(PullResponse { messages: msgs })
}
}
#[cfg(test)]
mod creating_pull_response {
use super::*;
#[test]
fn it_is_possible_to_recover_it_from_bytes() {
let msg1 = vec![1, 2, 3, 4, 5];
let msg2 = vec![];
let msg3 = vec![
1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4,
5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3,
4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2,
3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1,
2, 3, 4, 5, 1, 2, 3, 4, 5,
];
let msg4 = vec![1, 2, 3, 4, 5, 6, 7];
let msgs = vec![msg1, msg2, msg3, msg4];
let pull_response = PullResponse::new(msgs.clone());
let bytes = pull_response.to_bytes();
let recovered = PullResponse::from_bytes(&bytes).unwrap();
assert_eq!(msgs, recovered.messages);
}
}
+54 -18
View File
@@ -17,9 +17,14 @@ fn execute(matches: ArgMatches) -> Result<(), String> {
fn run(matches: &ArgMatches) {
println!("Running the service provider!");
let host = matches.value_of("host").unwrap_or("0.0.0.0");
let mix_host = matches.value_of("mixHost").unwrap_or("0.0.0.0");
let mix_port = match matches.value_of("mixPort").unwrap().parse::<u16>() {
Ok(n) => n,
Err(err) => panic!("Invalid port value provided - {:?}", err),
};
let port = match matches.value_of("port").unwrap().parse::<u16>() {
let client_host = matches.value_of("clientHost").unwrap_or("0.0.0.0");
let client_port = match matches.value_of("clientPort").unwrap().parse::<u16>() {
Ok(n) => n,
Err(err) => panic!("Invalid port value provided - {:?}", err),
};
@@ -37,23 +42,43 @@ fn run(matches: &ArgMatches) {
let store_dir = PathBuf::from(matches.value_of("storeDir").unwrap());
println!("The value of host is: {:?}", host);
println!("The value of port is: {:?}", port);
println!("The value of mix_host is: {:?}", mix_host);
println!("The value of mix_port is: {:?}", mix_port);
println!("The value of client_host is: {:?}", client_host);
println!("The value of client_port is: {:?}", client_port);
println!("The value of key is: {:?}", secret_key);
println!("The value of storeDir is: {:?}", store_dir);
println!("The value of store_dir is: {:?}", store_dir);
let socket_address = (host, port)
let mix_socket_address = (mix_host, mix_port)
.to_socket_addrs()
.expect("Failed to combine host and port")
.next()
.expect("Failed to extract the socket address from the iterator");
println!("The full combined socket address is {}", socket_address);
let client_socket_address = (client_host, client_port)
.to_socket_addrs()
.expect("Failed to combine host and port")
.next()
.expect("Failed to extract the socket address from the iterator");
println!(
"The full combined mix socket address is {}",
mix_socket_address
);
println!(
"The full combined client socket address is {}",
client_socket_address
);
// make sure our socket_address is equal to our predefined-hardcoded value
assert_eq!("127.0.0.1:8081", socket_address.to_string());
assert_eq!("127.0.0.1:8081", mix_socket_address.to_string());
let provider = ServiceProvider::new(socket_address, secret_key, store_dir);
let provider = ServiceProvider::new(
mix_socket_address,
client_socket_address,
secret_key,
store_dir,
);
provider.start_listening().unwrap()
}
@@ -66,17 +91,28 @@ fn main() {
SubCommand::with_name("run")
.about("Starts the service provider")
.arg(
Arg::with_name("host")
.short("h")
.long("host")
.help("The custom host on which the service provider will be running")
Arg::with_name("mixHost")
.long("mixHost")
.help("The custom host on which the service provider will be running for receiving sphinx packets")
.takes_value(true),
)
.arg(
Arg::with_name("port")
.short("p")
.long("port")
.help("The port on which the service provider will be listening")
Arg::with_name("mixPort")
.long("mixPort")
.help("The port on which the service provider will be listening for sphinx packets")
.takes_value(true)
.required(true),
)
.arg(
Arg::with_name("clientHost")
.long("clientHost")
.help("The custom host on which the service provider will be running for receiving client sfw-provider-requests")
.takes_value(true),
)
.arg(
Arg::with_name("clientPort")
.long("clientPort")
.help("The port on which the service provider will be listening for client sfw-provider-requests")
.takes_value(true)
.required(true),
)
@@ -89,7 +125,7 @@ fn main() {
)
.arg(
Arg::with_name("storeDir")
.short("sdir")
.short("s")
.long("storeDir")
.help("Directory storing all packets for the clients")
.takes_value(true)
+76
View File
@@ -0,0 +1,76 @@
use crate::provider::storage::{ClientStorage, StoreError};
use sfw_provider_requests::requests::{ProviderRequestError, ProviderRequests, PullRequest};
use sfw_provider_requests::responses::{ProviderResponse, PullResponse};
use std::path::{Path, PathBuf};
use std::sync::{Arc, RwLock};
#[derive(Debug)]
pub enum ClientProcessingError {
ClientDoesntExistError,
StoreError,
InvalidRequest,
}
impl From<ProviderRequestError> for ClientProcessingError {
fn from(_: ProviderRequestError) -> Self {
use ClientProcessingError::*;
InvalidRequest
}
}
impl From<StoreError> for ClientProcessingError {
fn from(e: StoreError) -> Self {
match e {
StoreError::ClientDoesntExistError => ClientProcessingError::ClientDoesntExistError,
_ => ClientProcessingError::StoreError,
}
}
}
#[derive(Debug, Clone)]
pub(crate) struct ClientProcessingData {
store_dir: PathBuf,
}
impl ClientProcessingData {
pub(crate) fn new(store_dir: PathBuf) -> Self {
ClientProcessingData { store_dir }
}
pub(crate) fn add_arc_rwlock(self) -> Arc<RwLock<Self>> {
Arc::new(RwLock::new(self))
}
}
pub(crate) struct ClientRequestProcessor(());
impl ClientRequestProcessor {
pub(crate) fn process_client_request(
data: &[u8],
processing_data: &RwLock<ClientProcessingData>,
) -> Result<Vec<u8>, ClientProcessingError> {
let client_request = ProviderRequests::from_bytes(&data)?;
println!("received the following request: {:?}", client_request);
match client_request {
ProviderRequests::Register(req) => unimplemented!(),
ProviderRequests::PullMessages(req) => {
Ok(ClientRequestProcessor::process_pull_messages_request(
req,
processing_data.read().unwrap().store_dir.as_path(),
)?
.to_bytes())
}
}
}
fn process_pull_messages_request(
req: PullRequest,
store_dir: &Path,
) -> Result<PullResponse, ClientProcessingError> {
println!("processing pull!");
let retrieved_messages =
ClientStorage::retrieve_client_files(req.destination_address, store_dir)?;
Ok(PullResponse::new(retrieved_messages))
}
}
+83
View File
@@ -0,0 +1,83 @@
use crate::provider::storage::StoreData;
use curve25519_dalek::scalar::Scalar;
use sphinx::{ProcessedPacket, SphinxPacket};
use std::path::PathBuf;
use std::sync::{Arc, RwLock};
// TODO: this will probably need to be moved elsewhere I imagine
// DUPLICATE WITH MIXNODE CODE!!!
#[derive(Debug)]
pub enum MixProcessingError {
SphinxRecoveryError,
ReceivedForwardHopError,
InvalidPayload,
NonMatchingRecipient,
FileIOFailure,
}
impl From<sphinx::ProcessingError> for MixProcessingError {
// for time being just have a single error instance for all possible results of sphinx::ProcessingError
fn from(_: sphinx::ProcessingError) -> Self {
use MixProcessingError::*;
SphinxRecoveryError
}
}
impl From<std::io::Error> for MixProcessingError {
fn from(_: std::io::Error) -> Self {
use MixProcessingError::*;
FileIOFailure
}
}
// ProcessingData defines all data required to correctly unwrap sphinx packets
#[derive(Debug, Clone)]
pub(crate) struct MixProcessingData {
secret_key: Scalar,
pub(crate) store_dir: PathBuf,
}
impl MixProcessingData {
pub(crate) fn new(secret_key: Scalar, store_dir: PathBuf) -> Self {
MixProcessingData {
secret_key,
store_dir,
}
}
pub(crate) fn add_arc_rwlock(self) -> Arc<RwLock<Self>> {
Arc::new(RwLock::new(self))
}
}
pub(crate) struct MixPacketProcessor(());
impl MixPacketProcessor {
pub fn process_sphinx_data_packet(
packet_data: &[u8],
processing_data: &RwLock<MixProcessingData>,
) -> Result<StoreData, MixProcessingError> {
let packet = SphinxPacket::from_bytes(packet_data.to_vec())?;
let read_processing_data = processing_data.read().unwrap();
let (client_address, client_surb_id, payload) =
match packet.process(read_processing_data.secret_key) {
ProcessedPacket::ProcessedPacketFinalHop(client_address, surb_id, payload) => {
(client_address, surb_id, payload)
}
_ => return Err(MixProcessingError::ReceivedForwardHopError),
};
// TODO: should provider try to be recovering plaintext? this would potentially make client retrieve messages of non-constant length,
// perhaps provider should be re-padding them on retrieval or storing full data?
let (payload_destination, message) = payload
.try_recover_destination_and_plaintext()
.ok_or_else(|| MixProcessingError::InvalidPayload)?;
if client_address != payload_destination {
return Err(MixProcessingError::NonMatchingRecipient);
}
Ok(StoreData::new(client_address, client_surb_id, message))
}
}
+113 -132
View File
@@ -1,146 +1,45 @@
use std::fs::File;
use std::io::Write;
use std::net::SocketAddr;
use std::path::{Path, PathBuf};
use std::net::{Shutdown, SocketAddr};
use std::path::PathBuf;
use std::sync::Arc;
use std::sync::RwLock;
use curve25519_dalek::scalar::Scalar;
use rand::Rng;
use sphinx::{ProcessedPacket, SphinxPacket};
use sphinx::route::{DestinationAddressBytes, SURBIdentifier};
use tokio::prelude::*;
use tokio::runtime::Runtime;
use crate::provider::client_handling::{ClientProcessingData, ClientRequestProcessor};
use crate::provider::mix_handling::{MixPacketProcessor, MixProcessingData};
use crate::provider::storage::ClientStorage;
mod client_handling;
mod mix_handling;
mod storage;
// TODO: if we ever create config file, this should go there
const STORED_MESSAGE_FILENAME_LENGTH: usize = 16;
// TODO: this will probably need to be moved elsewhere I imagine
// DUPLICATE WITH MIXNODE CODE!!!
#[derive(Debug)]
pub enum MixProcessingError {
SphinxRecoveryError,
ReceivedForwardHopError,
InvalidPayload,
NonMatchingRecipient,
FileIOFailure,
}
impl From<sphinx::ProcessingError> for MixProcessingError {
// for time being just have a single error instance for all possible results of sphinx::ProcessingError
fn from(_: sphinx::ProcessingError) -> Self {
use MixProcessingError::*;
SphinxRecoveryError
}
}
impl From<std::io::Error> for MixProcessingError {
fn from(_: std::io::Error) -> Self {
use MixProcessingError::*;
FileIOFailure
}
}
// ProcessingData defines all data required to correctly unwrap sphinx packets
// Do note that we're copying this struct around and hence the secret_key.
// It might, or might not be, what we want
#[derive(Debug, Clone)]
struct ProcessingData {
secret_key: Scalar,
store_dir: PathBuf,
}
impl ProcessingData {
fn new(secret_key: Scalar, store_dir: PathBuf) -> Self {
ProcessingData {
secret_key,
store_dir,
}
}
fn add_arc_rwlock(self) -> Arc<RwLock<Self>> {
Arc::new(RwLock::new(self))
}
}
struct StoreData {
client_address: DestinationAddressBytes,
client_surb_id: SURBIdentifier,
message: Vec<u8>,
}
struct PacketProcessor(());
impl PacketProcessor {
fn process_sphinx_data_packet(packet_data: &[u8], processing_data: &RwLock<ProcessingData>) -> Result<StoreData, MixProcessingError> {
let packet = SphinxPacket::from_bytes(packet_data.to_vec())?;
let read_processing_data = processing_data.read().unwrap();
let (client_address, client_surb_id, payload) = match packet.process(read_processing_data.secret_key) {
ProcessedPacket::ProcessedPacketFinalHop(client_address, surb_id, payload) => (client_address, surb_id, payload),
_ => return Err(MixProcessingError::ReceivedForwardHopError),
};
let (payload_destination, message) = payload.try_recover_destination_and_plaintext().ok_or_else(|| MixProcessingError::InvalidPayload)?;
if client_address != payload_destination {
return Err(MixProcessingError::NonMatchingRecipient);
}
Ok(StoreData {
client_address,
client_surb_id,
message,
})
}
fn generate_random_file_name() -> String {
rand::thread_rng().sample_iter(&rand::distributions::Alphanumeric).take(STORED_MESSAGE_FILENAME_LENGTH).collect::<String>()
}
fn store_processed_data(store_data: StoreData, store_dir: &Path) -> Result<(), MixProcessingError> {
let client_dir_name = hex::encode(store_data.client_address);
let full_store_dir = store_dir.join(client_dir_name);
let full_store_path = full_store_dir.join(PacketProcessor::generate_random_file_name());
println!("going to store: {:?} in file: {:?}", store_data.message, full_store_path);
// TODO: what to do with surbIDs??
// we can use normal io here, no need for tokio as it's all happening in one thread per connection
std::fs::create_dir_all(full_store_dir)?;
let mut file = File::create(full_store_path)?;
file.write_all(store_data.message.as_ref())?;
Ok(())
}
}
const MESSAGE_RETRIEVAL_LIMIT: usize = 2;
pub struct ServiceProvider {
network_address: SocketAddr,
mix_network_address: SocketAddr,
client_network_address: SocketAddr,
secret_key: Scalar,
store_dir: PathBuf,
}
impl ServiceProvider {
pub fn new(network_address: SocketAddr, secret_key: Scalar, store_dir: PathBuf) -> Self {
pub fn new(mix_network_address: SocketAddr, client_network_address: SocketAddr, secret_key: Scalar, store_dir: PathBuf) -> Self {
ServiceProvider {
network_address,
mix_network_address,
client_network_address,
secret_key,
store_dir,
}
}
async fn process_socket_connection(mut socket: tokio::net::TcpStream, processing_data: Arc<RwLock<ProcessingData>>) {
// TODO: we will actually need to distinguish multiple types of requests here;
// either from mixnodes to store final hop information
// or from clients to pull messages
async fn process_mixnet_socket_connection(mut socket: tokio::net::TcpStream, processing_data: Arc<RwLock<MixProcessingData>>) {
let mut buf = [0u8; sphinx::PACKET_SIZE];
// In a loop, read data from the socket and write the data back.
@@ -152,15 +51,16 @@ impl ServiceProvider {
return;
}
Ok(_) => {
let store_data = match PacketProcessor::process_sphinx_data_packet(buf.as_ref(), processing_data.as_ref()) {
let store_data = match MixPacketProcessor::process_sphinx_data_packet(buf.as_ref(), processing_data.as_ref()) {
Ok(sd) => sd,
Err(e) => {
eprintln!("failed to process sphinx packet; err = {:?}", e);
return;
}
};
PacketProcessor::store_processed_data(store_data, processing_data.read().unwrap().store_dir.as_path()).unwrap_or_else(|e| {
eprintln!("failed to store processed sphinx message; err = {:?}", e)
ClientStorage::store_processed_data(store_data, processing_data.read().unwrap().store_dir.as_path()).unwrap_or_else(|e| {
eprintln!("failed to store processed sphinx message; err = {:?}", e);
return;
});
}
Err(e) => {
@@ -177,6 +77,91 @@ impl ServiceProvider {
}
}
async fn send_response(mut socket: tokio::net::TcpStream, data: &[u8]) {
if let Err(e) = socket.write_all(data).await {
eprintln!("failed to write reply to socket; err = {:?}", e)
}
if let Err(e) = socket.shutdown(Shutdown::Write) {
eprintln!("failed to close write part of the socket; err = {:?}", e)
}
}
// TODO: FIGURE OUT HOW TO SET READ_DEADLINES IN TOKIO
async fn process_client_socket_connection(mut socket: tokio::net::TcpStream, processing_data: Arc<RwLock<ClientProcessingData>>) {
let mut buf = [0; 1024];
// TODO: restore the for loop once we go back to persistent tcp socket connection
let response = match socket.read(&mut buf).await {
// socket closed
Ok(n) if n == 0 => {
println!("Remote connection closed.");
Err(())
}
Ok(n) => {
match ClientRequestProcessor::process_client_request(buf[..n].as_ref(), processing_data.as_ref()) {
Err(e) => {
eprintln!("failed to process client request; err = {:?}", e);
Err(())
}
Ok(res) => Ok(res),
}
}
Err(e) => {
eprintln!("failed to read from socket; err = {:?}", e);
Err(())
}
};
if let Err(e) = socket.shutdown(Shutdown::Read) {
eprintln!("failed to close read part of the socket; err = {:?}", e)
}
match response {
Ok(res) => {
println!("should send this response! {:?}", res);
ServiceProvider::send_response(socket, &res).await;
}
_ => {
println!("we failed...");
ServiceProvider::send_response(socket, b"bad foomp").await;
}
}
}
async fn start_mixnet_listening(&self) -> Result<(), Box<dyn std::error::Error>> {
let mut listener = tokio::net::TcpListener::bind(self.mix_network_address).await?;
let processing_data = MixProcessingData::new(self.secret_key, self.store_dir.clone()).add_arc_rwlock();
loop {
let (socket, _) = listener.accept().await?;
// do note that the underlying data is NOT copied here; arc is incremented and lock is shared
// (if I understand it all correctly)
let thread_processing_data = processing_data.clone();
tokio::spawn(async move {
ServiceProvider::process_mixnet_socket_connection(socket, thread_processing_data).await
});
}
}
async fn start_client_listening(&self) -> Result<(), Box<dyn std::error::Error>> {
let mut listener = tokio::net::TcpListener::bind(self.client_network_address).await?;
let processing_data = ClientProcessingData::new(self.store_dir.clone()).add_arc_rwlock();
loop {
let (socket, _) = listener.accept().await?;
// do note that the underlying data is NOT copied here; arc is incremented and lock is shared
// (if I understand it all correctly)
let thread_processing_data = processing_data.clone();
tokio::spawn(async move {
ServiceProvider::process_client_socket_connection(socket, thread_processing_data).await
});
}
}
async fn start_listeners(&self) -> (Result<(), Box<dyn std::error::Error>>, Result<(), Box<dyn std::error::Error>>) {
futures::future::join(self.start_mixnet_listening(), self.start_client_listening()).await
}
pub fn start_listening(&self) -> Result<(), Box<dyn std::error::Error>> {
// Create the runtime, probably later move it to Provider struct itself?
@@ -186,17 +171,13 @@ impl ServiceProvider {
// Spawn the root task
rt.block_on(async {
let mut listener = tokio::net::TcpListener::bind(self.network_address).await?;
let processing_data = ProcessingData::new(self.secret_key, self.store_dir.clone()).add_arc_rwlock();
let future_results = self.start_listeners().await;
assert!(future_results.0.is_ok() && future_results.1.is_ok())
});
loop {
let (socket, _) = listener.accept().await?;
let thread_processing_data = processing_data.clone();
tokio::spawn(async move {
ServiceProvider::process_socket_connection(socket, thread_processing_data).await
});
}
})
// this line in theory should never be reached as the runtime should be permanently blocked on listeners
eprintln!("The server went kaput...");
Ok(())
}
}
+126
View File
@@ -0,0 +1,126 @@
use crate::provider::{MESSAGE_RETRIEVAL_LIMIT, STORED_MESSAGE_FILENAME_LENGTH};
use rand::Rng;
use sfw_provider_requests::DUMMY_MESSAGE_CONTENT;
use sphinx::route::{DestinationAddressBytes, SURBIdentifier};
use std::fs::File;
use std::io;
use std::io::Write;
use std::path::{Path, PathBuf};
pub enum StoreError {
ClientDoesntExistError,
FileIOFailure,
}
impl From<std::io::Error> for StoreError {
fn from(_: std::io::Error) -> Self {
use StoreError::*;
FileIOFailure
}
}
pub struct StoreData {
client_address: DestinationAddressBytes,
client_surb_id: SURBIdentifier,
message: Vec<u8>,
}
impl StoreData {
pub(crate) fn new(
client_address: DestinationAddressBytes,
client_surb_id: SURBIdentifier,
message: Vec<u8>,
) -> Self {
StoreData {
client_address,
client_surb_id,
message,
}
}
}
// TODO: replace with database
pub struct ClientStorage(());
// TODO: change it to some generic implementation to inject fs
impl ClientStorage {
fn generate_random_file_name() -> String {
rand::thread_rng()
.sample_iter(&rand::distributions::Alphanumeric)
.take(STORED_MESSAGE_FILENAME_LENGTH)
.collect::<String>()
}
fn dummy_message() -> Vec<u8> {
// TODO: should it be padded to constant length?
DUMMY_MESSAGE_CONTENT.to_vec()
}
pub fn store_processed_data(store_data: StoreData, store_dir: &Path) -> io::Result<()> {
let client_dir_name = hex::encode(store_data.client_address);
let full_store_dir = store_dir.join(client_dir_name);
let full_store_path = full_store_dir.join(ClientStorage::generate_random_file_name());
println!(
"going to store: {:?} in file: {:?}",
store_data.message, full_store_path
);
// TODO: what to do with surbIDs??
// TODO: this should be called when client sends 'register' request!
std::fs::create_dir_all(full_store_dir)?;
// we can use normal io here, no need for tokio as it's all happening in one thread per connection
let mut file = File::create(full_store_path)?;
file.write_all(store_data.message.as_ref())?;
Ok(())
}
pub fn retrieve_client_files(
client_address: DestinationAddressBytes,
store_dir: &Path,
) -> Result<Vec<Vec<u8>>, StoreError> {
let client_dir_name = hex::encode(client_address);
let full_store_dir = store_dir.join(client_dir_name);
println!("going to lookup: {:?}!", full_store_dir);
if !full_store_dir.exists() {
return Err(StoreError::ClientDoesntExistError);
}
let msgs: Vec<_> = std::fs::read_dir(full_store_dir)?
.map(|entry| entry.unwrap())
.filter(|entry| {
let is_file = entry.metadata().unwrap().is_file();
if !is_file {
eprintln!(
"potentially corrupted client inbox! - found a non-file - {:?}",
entry.path()
);
}
is_file
})
.map(|entry| {
let content = std::fs::read(entry.path()).unwrap();
ClientStorage::delete_file(entry.path());
content
}) // TODO: THIS MAP IS UNSAFE (BOTH READING AND DELETING)!!
.chain(std::iter::repeat(ClientStorage::dummy_message()))
.take(MESSAGE_RETRIEVAL_LIMIT)
.collect();
println!("retrieved the following data: {:?}", msgs);
Ok(msgs)
}
// TODO: THIS NEEDS A LOCKING MECHANISM!!! (or a db layer on top - basically 'ClientStorage' on steroids)
// TODO 2: This should only be called AFTER we sent the reply. Because if client's connection failed after sending request
// the messages would be deleted but he wouldn't have received them
fn delete_file(path: PathBuf) {
println!("Here {:?} will be deleted!", path);
std::fs::remove_file(path); // another argument for db layer -> remove_file is NOT guaranteed to immediately get rid of the file
}
}