diff options
| -rw-r--r-- | Cargo.lock | 394 | ||||
| -rw-r--r-- | Cargo.toml | 2 | ||||
| -rw-r--r-- | src/client/mod.rs | 219 | ||||
| -rw-r--r-- | src/main.rs | 21 | ||||
| -rw-r--r-- | src/net.rs | 148 | ||||
| -rw-r--r-- | src/protocol/error/mod.rs | 49 | ||||
| -rw-r--r-- | src/protocol/message/handshake.rs | 122 | ||||
| -rw-r--r-- | src/protocol/message/handshake/types.rs | 20 | ||||
| -rw-r--r-- | src/protocol/primitive/basic.rs | 58 | ||||
| -rw-r--r-- | src/protocol/primitive/mod.rs | 19 | ||||
| -rw-r--r-- | src/protocol/primitive/variant.rs | 31 | ||||
| -rw-r--r-- | src/util.rs | 12 |
12 files changed, 787 insertions, 308 deletions
@@ -6,11 +6,51 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] +name = "arc-swap" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "backtrace" +version = "0.3.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "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)", + "rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "backtrace-sys" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (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 = "byteorder" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] +name = "bytes" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cc" +version = "1.0.50" +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" @@ -24,6 +64,26 @@ dependencies = [ ] [[package]] +name = "failure" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)", + "failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "failure_derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", + "synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "flate2" version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -35,6 +95,60 @@ dependencies = [ ] [[package]] +name = "fnv" +version = "1.0.6" +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.2.1 (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-core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "hermit-abi" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "iovec" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.66 (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.4.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" @@ -44,8 +158,10 @@ name = "libquassel" version = "0.1.0" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -57,6 +173,11 @@ dependencies = [ ] [[package]] +name = "memchr" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] name = "miniz_oxide" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -64,12 +185,285 @@ dependencies = [ "adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "mio" +version = "0.6.21" +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)", + "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.4 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (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-named-pipes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", + "miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.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.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (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 = "miow" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (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.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num_cpus" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "pin-project-lite" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "proc-macro2" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "quote" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "redox_syscall" +version = "0.1.56" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rustc-demangle" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "signal-hook-registry" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arc-swap 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (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 = "socket2" +version = "0.3.11" +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)", + "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syn" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "synstructure" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", + "mio-named-pipes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-macros 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-xid" +version = "0.2.0" +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.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-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 adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" +"checksum arc-swap 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d7b8a9123b8027467bce0099fe556c628a53c8d83df0507084c31e9ba2e39aff" +"checksum backtrace 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b4b1549d804b6c73f4817df2ba073709e96e426f12987127c48e6745568c350b" +"checksum backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491" +"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" "checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" +"checksum bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "10004c15deb332055f7a4a208190aed362cf9a7c2f6ab70a305fba50e1105f38" +"checksum cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)" = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd" "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" "checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" +"checksum failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9" +"checksum failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08" "checksum flate2 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6bd6d6f4752952feb71363cffc9ebac9411b75b87c6ab6058c40c8900cf43c0f" +"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" +"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-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "79564c427afefab1dfb3298535b21eda083ef7935b4f0ecbfcb121f0aec10866" +"checksum hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eff2656d88f158ce120947499e971d743c05dbcbed62e5bd2f38f1698bbc3772" +"checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" "checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558" "checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" +"checksum memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3197e20c7edb283f87c071ddfc7a2cca8f8e0b888c242959846a6fce03c72223" "checksum miniz_oxide 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6f3f74f726ae935c3f514300cc6773a0c9492abc5e972d42ba0c0ebb88757625" +"checksum mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)" = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f" +"checksum mio-named-pipes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f5e374eff525ce1c5b7687c4cef63943e7686524a387933ad27ca7ec43779cb3" +"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 miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "396aa0f2003d7df8395cb93e09871561ccc3e785f0acb369170e8cc74ddf9226" +"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" +"checksum num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6" +"checksum pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "237844750cfbb86f67afe27eee600dfbbcb6188d734139b534cbfbf4f96792ae" +"checksum proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548" +"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" +"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" +"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" +"checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" +"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" +"checksum socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85" +"checksum syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5" +"checksum synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" +"checksum tokio 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "ffa2fdcfa937b20cb3c822a635ceecd5fc1a27a6a474527e5516aa24b8c8820a" +"checksum tokio-macros 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "50a61f268a3db2acee8dcab514efc813dc6dbe8a00e86076f935f94304b59a7a" +"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" +"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" +"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" +"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" @@ -10,3 +10,5 @@ edition = "2018" log = "0.4" byteorder = "1.3.2" flate2 = "1.0" +tokio = { version = "0.2", features = ["full"] } +failure = "0.1" diff --git a/src/client/mod.rs b/src/client/mod.rs new file mode 100644 index 0000000..fdd9a56 --- /dev/null +++ b/src/client/mod.rs @@ -0,0 +1,219 @@ +//use std::io::BufWriter; +use std::result::Result; +use std::vec::Vec; +use std::convert::TryInto; +use std::io::Cursor; + +use flate2::Compress; +use flate2::Decompress; +use flate2::Compression; +use flate2::FlushCompress; +use flate2::FlushDecompress; +use flate2::read::ZlibDecoder; + +use tokio::net::TcpStream; +use tokio::prelude::*; + +use failure::Error; + +extern crate log; +// use log::{info, warn, debug}; + +use crate::protocol::message; + +pub enum State { + Handshake, + Connected +} + +pub struct Client { + tcp_stream: TcpStream, + encoder: Compress, + decoder: Decompress, + state: State, + pub tls: bool, + pub compression: bool, +} + +impl Client { + pub async fn handler(mut self) -> Result<(), Error> { +// let (recv, send) = self.tcp_stream.split(); + loop { + let mut buf: Vec<u8> = vec![0; 2048]; + match self.tcp_stream.read(&mut buf).await { + Ok(n) => { + buf.truncate(n); + let mut cbuf: Vec<u8> = vec![0; n * 2]; + + println!("buf: {:?}", &buf[0..]); + let before_in = self.decoder.total_in(); + let before_out = self.decoder.total_out(); + self.decoder.decompress(&buf, &mut cbuf, FlushDecompress::None)?; + let after_in = self.decoder.total_in(); + let after_out = self.decoder.total_out(); + + cbuf.truncate(after_out.try_into()?); + + println!("in: {:?} / {:?}\nout: {:?} / {:?}", before_in, after_in, before_out, after_out); + + println!("buf: {:?}", cbuf); + + match self.state { + State::Handshake => handle_login_message(&mut self, &cbuf), + State::Connected => handle_login_message(&mut self, &cbuf) + }.await?; + } + Err(e) => { panic!(e) } + } + } + } + + pub async fn connect(address: &'static str, port: u64, tls: bool, compression: bool) -> Result<Client, Error> { + use crate::protocol::primitive::deserialize::Deserialize; + use crate::protocol::message::ConnAck; + use crate::protocol::primitive::{StringList}; + use crate::protocol::message::ClientInit; + use crate::protocol::message::handshake::HandshakeSerialize; + + let mut s = TcpStream::connect(format!("{}:{}", address, port)).await?; + + // Set Features + let mut init: Vec<u8> = vec![]; + let mut handshake: u32 = 0x42b33f00; + if tls { + handshake |= 0x01; + } + if compression { + handshake |= 0x02; + } + let mut proto: u32 = 0x00000002; + let fin: u32 = 0x80000000; + proto |= fin; + init.extend(handshake.to_be_bytes().iter()); + init.extend(proto.to_be_bytes().iter()); + s.write(&init).await?; + + + let mut buf = [0; 4]; + s.read(&mut buf).await?; + let (_, val) = ConnAck::parse(&buf).unwrap(); + println!("Received: {:?}", val); + + let mut client = Client { + tcp_stream: s, + state: State::Handshake, + encoder: Compress::new(Compression::best(), true), + decoder: Decompress::new(true), + tls: tls, + compression: compression, + }; + + let mut features = StringList::new(); + features.push("SynchronizedMarkerLine".to_string()); + features.push("Authenticators".to_string()); + features.push("ExtendedFeatures".to_string()); + let client_init = ClientInit { + client_version:String::from("Rust 0.0.0"), + client_date: String::from("1579009211"), + feature_list: features, + client_features: 0x00008000, + }; + write_to_stream(&mut client, &client_init.serialize()?).await?; + + return Ok(client); + } + +// pub fn login(&mut self, user: &'static str, pass: &'static str, client: message::ClientInit) { +// use crate::protocol::message::handshake::{HandshakeDeserialize, HandshakeSerialize, HandshakeQRead, VariantMap}; +// use crate::protocol::message::handshake::{ClientInitAck, ClientLogin, ClientLoginAck, SessionInit}; +// +// self.write(&client.serialize().unwrap()).unwrap(); +// +// let mut buf: Vec<u8> = [0; 2048].to_vec(); +// let len = VariantMap::read(self, &mut buf).unwrap(); +// buf.truncate(len); +// let res = ClientInitAck::parse(&buf).unwrap(); +// println!("res: {:?}", res); +// +// let login = ClientLogin {user: user.to_string(), password: pass.to_string()}; +// self.write(&login.serialize().unwrap()).unwrap(); +// println!("res: {:?}", res); +// +// let mut buf: Vec<u8> = [0; 2048].to_vec(); +// let len = VariantMap::read(self, &mut buf).unwrap(); +// buf.truncate(len); +// let _res = ClientLoginAck::parse(&buf).unwrap(); +// +// let mut buf: Vec<u8> = [0; 2048].to_vec(); +// let len = VariantMap::read(self, &mut buf).unwrap(); +// buf.truncate(len); +// let res = SessionInit::parse(&buf).unwrap(); +// +// println!("res: {:?}", res); +// } +} + +// impl std::io::Read for Client { +// fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> { +// let mut cbuf = [0; 2048].to_vec(); +// let read_bytes = self.tcp_stream.read(&mut cbuf)?; +// println!("read bytes: {:?}", read_bytes); +// cbuf.truncate(read_bytes); +// println!("cbuf: {:?}", &cbuf[0..]); +// let before_in = self.decoder.total_in(); +// let before_out = self.decoder.total_out(); +// self.decoder.decompress(&cbuf, buf, FlushDecompress::None)?; +// let after_in = self.decoder.total_in(); +// let after_out = self.decoder.total_out(); +// +// println!("in: {:?} / {:?}\nout: {:?} / {:?}", before_in, after_in, before_out, after_out); +// +// println!("buf: {:?}", buf); +// return Ok(((after_in - after_out)).try_into().unwrap()); +// // +// // let res = self.tcp_stream.read(buf); +// // println!("buf: {:?}, total in: {:?}, total out: {:?}", buf, self.tcp_stream.total_in(), self.tcp_stream.total_out()); +// // return res; +// } +// } +// +// impl std::io::Write for Client { +// fn write(&mut self, buf: &[u8]) -> Result<usize, Error> { +// let mut cbuf = Vec::with_capacity(buf.len()); +// self.encoder.compress_vec(buf, &mut cbuf, FlushCompress::Finish)?; +// return self.tcp_stream.write(&cbuf); +// } +// +// fn flush(&mut self) -> Result<(), Error> { +// return self.tcp_stream.flush(); +// } +// } + +pub async fn write_to_stream(client: &mut Client, buf: &[u8]) -> Result<usize, Error> { + let mut cbuf = Vec::with_capacity(buf.len()); + client.encoder.compress_vec(buf, &mut cbuf, FlushCompress::Finish)?; + return Ok(client.tcp_stream.write(&cbuf).await?); +} + +pub async fn handle_login_message(client: &mut Client, buf: &[u8]) -> Result<(), Error> { + use crate::protocol::primitive::{Variant, VariantMap, StringList}; + use crate::protocol::message::ClientLogin; + use crate::protocol::message::handshake::HandshakeSerialize; + use crate::protocol::primitive::deserialize::Deserialize; + use crate::protocol::error::ProtocolError; + use crate::util::get_msg_type; + + let (_, res) = VariantMap::parse(buf)?; + let msgtype = get_msg_type(&res["MsgType"])?; + match msgtype { + "ClientInitAck" => { + let login = ClientLogin {user: "audron".to_string(), password: "audron".to_string()}; + write_to_stream(client, &login.serialize()?).await?; + }, + "ClientInitReject" => { println!("init failed: {:?}", res) }, + "ClientLoginAck" => { println!("login done: {:?}", res) }, + "ClientLoginReject" => { println!("login failed: {:?}", res)}, + _ => bail!(ProtocolError::WrongMsgType) + } + return Ok(()); +} diff --git a/src/main.rs b/src/main.rs index 4a0de93..d496270 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,13 @@ mod consts; -mod net; - +mod client; mod protocol; #[macro_use] mod util; +#[macro_use] +extern crate failure; + #[cfg(test)] mod tests; @@ -13,26 +15,31 @@ mod tests; use protocol::primitive::{String, StringList}; use protocol::message::{ClientInit}; -fn main() -> std::io::Result<()> { +use failure::Error; - let mut server = net::connect( +#[tokio::main] +async fn main() -> Result<(), Error> { + + let mut client = client::Client::connect( "localhost", 4242, false, true, - )?; + ).await.unwrap(); let mut features = StringList::new(); features.push("SynchronizedMarkerLine".to_string()); features.push("Authenticators".to_string()); features.push("ExtendedFeatures".to_string()); - let client = ClientInit { + let client_init = ClientInit { client_version:String::from("Rust 0.0.0"), client_date: String::from("1579009211"), feature_list: features, client_features: 0x00008000, }; - server.login("audron", "audron", client); + + client.handler().await?; +// client.login("audron", "audron", client_init); Ok(()) } // the stream is closed here diff --git a/src/net.rs b/src/net.rs deleted file mode 100644 index a4c74fb..0000000 --- a/src/net.rs +++ /dev/null @@ -1,148 +0,0 @@ -use std::io::prelude::*; -//use std::io::BufWriter; -use std::io::{Error}; -use std::result::Result; -use std::net::TcpStream; -use std::vec::Vec; -use std::convert::TryInto; -use std::io::Cursor; - -use flate2::Compress; -use flate2::Decompress; -use flate2::Compression; -use flate2::FlushCompress; -use flate2::FlushDecompress; -use flate2::read::ZlibDecoder; - -extern crate log; -// use log::{info, warn, debug}; - -use crate::protocol::message; -use crate::protocol::error::ErrorKind; - -pub struct Client { - tcp_stream: ZlibDecoder<TcpStream>, - encoder: Compress, - decoder: Decompress, - pub tls: bool, - pub compression: bool, -} - -impl Client { - pub fn login(&mut self, user: &'static str, pass: &'static str, client: message::ClientInit) { - use crate::protocol::message::handshake::{HandshakeDeserialize, HandshakeSerialize, HandshakeQRead, VariantMap}; - use crate::protocol::message::handshake::{ClientInitAck, ClientLogin, ClientLoginAck, SessionInit}; - - self.write(&client.serialize().unwrap()).unwrap(); - - let mut buf: Vec<u8> = [0; 2048].to_vec(); - let len = VariantMap::read(self, &mut buf).unwrap(); - buf.truncate(len); - let res = ClientInitAck::parse(&buf).unwrap(); - println!("res: {:?}", res); - - let login = ClientLogin {user: user.to_string(), password: pass.to_string()}; - self.write(&login.serialize().unwrap()).unwrap(); - println!("res: {:?}", res); - - let mut buf: Vec<u8> = [0; 2048].to_vec(); - let len = VariantMap::read(self, &mut buf).unwrap(); - buf.truncate(len); - let _res = ClientLoginAck::parse(&buf).unwrap(); - - let mut buf: Vec<u8> = [0; 2048].to_vec(); - let len = VariantMap::read(self, &mut buf).unwrap(); - buf.truncate(len); - let res = SessionInit::parse(&buf).unwrap(); - - println!("res: {:?}", res); - } -} - -impl std::io::Read for Client { - fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> { -// let mut cbuf = buf.to_vec(); -// let read_bytes = self.tcp_stream.peek(&mut cbuf); -// println!("read bytes: {:?}", read_bytes); -// println!("cbuf: {:?}", cbuf); -// let decompressed_bytes_pre = self.decoder.total_out(); -// self.decoder.decompress(&cbuf, buf, FlushDecompress::None)?; -// let decompressed_bytes = self.decoder.total_out(); -// let in_bytes = self.decoder.total_in(); -// println!("in bytes: {:?}", in_bytes); -// println!("decompressed bytes: {:?}", decompressed_bytes); -// println!("buf: {:?}", buf); -// return Ok(((decompressed_bytes - decompressed_bytes_pre)).try_into().unwrap()); - let res = self.tcp_stream.read(buf); - println!("buf: {:?}, total in: {:?}, total out: {:?}", buf, self.tcp_stream.total_in(), self.tcp_stream.total_out()); - return res; - } -} - -impl std::io::Write for Client { - fn write(&mut self, buf: &[u8]) -> Result<usize, Error> { - let mut cbuf = Vec::with_capacity(buf.len()); - self.encoder.compress_vec(buf, &mut cbuf, FlushCompress::Finish)?; - return self.tcp_stream.write(&cbuf); - } - - fn flush(&mut self) -> Result<(), Error> { - return self.tcp_stream.flush(); - } -} - -pub fn connect(address: &'static str, port: u32, tls: bool, compression: bool) -> Result<Client, Error> { - use crate::protocol::primitive::deserialize::Deserialize; - - let mut s = TcpStream::connect(format!("{}:{}", address, port)).unwrap(); - - // Set Features - let mut init: Vec<u8> = vec![]; - let mut handshake: u32 = 0x42b33f00; - if tls { - handshake |= 0x01; - } - if compression { - handshake |= 0x02; - } - let mut proto: u32 = 0x00000002; - let fin: u32 = 0x80000000; - proto |= fin; - init.extend(handshake.to_be_bytes().iter()); - init.extend(proto.to_be_bytes().iter()); - s.write(&init)?; - - #[derive(Debug)] - struct ConnAck { - flags: u8, - extra: i16, - version: i8 - } - - impl Deserialize for ConnAck { - fn parse(b: &[u8]) -> Result<(usize, Self), ErrorKind> { - let (flen, flags) = u8::parse(b)?; - let (elen, extra) = i16::parse(&b[flen..])?; - let (vlen, version) = i8::parse(&b[(flen+elen)..])?; - - return Ok((flen+elen+vlen, Self {flags, extra, version})); - } - } - - let mut buf = [0; 4]; - s.read(&mut buf)?; - let (_, val) = ConnAck::parse(&buf).unwrap(); - println!("Received: {:?}", val); - -// let sock = ZlibDecoder::new_with_buf(s, [0; 1].to_vec()); - let sock = ZlibDecoder::new(s); - let server: Client = Client { - tcp_stream: sock, - encoder: Compress::new(Compression::best(), true), - decoder: Decompress::new(true), - tls: tls, - compression: compression, - }; - - Ok(server) -} diff --git a/src/protocol/error/mod.rs b/src/protocol/error/mod.rs index 488ae0d..72a9e59 100644 --- a/src/protocol/error/mod.rs +++ b/src/protocol/error/mod.rs @@ -1,28 +1,37 @@ -#[derive(Debug)] -pub enum ErrorKind { + #[derive(Debug, Fail)] +pub enum ProtocolError { + #[fail(display = "message has wrong type")] WrongMsgType, + #[fail(display = "bool value is neither 0 nor 1")] BoolOutOfRange, + #[fail(display = "QVariant is not known")] UnknownVariant, + #[fail(display = "wrong variant has been given")] WrongVariant, + #[fail(display = "io error")] IOError(std::io::Error), + #[fail(display = "could not convert from int")] TryFromIntError(std::num::TryFromIntError), + #[fail(display = "utf8 error")] Utf8Error(std::string::FromUtf8Error), -} + } -impl std::convert::From<std::io::Error> for ErrorKind { - fn from(error: std::io::Error) -> Self { - ErrorKind::IOError(error) - } -} - -impl std::convert::From<std::num::TryFromIntError> for ErrorKind { - fn from(error: std::num::TryFromIntError) -> Self { - ErrorKind::TryFromIntError(error) - } -} - -impl std::convert::From<std::string::FromUtf8Error> for ErrorKind { - fn from(error: std::string::FromUtf8Error) -> Self { - ErrorKind::Utf8Error(error) - } -} +// impl std::error::Error for ErrorKind {} +// +// impl std::convert::From<std::io::Error> for ErrorKind { +// fn from(error: std::io::Error) -> Self { +// ErrorKind::IOError(error) +// } +// } +// +// impl std::convert::From<std::num::TryFromIntError> for ErrorKind { +// fn from(error: std::num::TryFromIntError) -> Self { +// ErrorKind::TryFromIntError(error) +// } +// } +// +// impl std::convert::From<std::string::FromUtf8Error> for ErrorKind { +// fn from(error: std::string::FromUtf8Error) -> Self { +// ErrorKind::Utf8Error(error) +// } +// } diff --git a/src/protocol/message/handshake.rs b/src/protocol/message/handshake.rs index 44c1073..b38d03f 100644 --- a/src/protocol/message/handshake.rs +++ b/src/protocol/message/handshake.rs @@ -1,12 +1,34 @@ use std::result::Result; +use failure::Error; -use crate::protocol::error::ErrorKind; +use crate::protocol::error::ProtocolError; use crate::protocol::primitive::{String, StringList, Variant, VariantList}; +use crate::util::get_msg_type; mod types; pub use types::{VariantMap, HandshakeDeserialize, HandshakeSerialize, HandshakeQRead}; use crate::match_variant; + + +#[derive(Debug)] +pub struct ConnAck { + flags: u8, + extra: i16, + version: i8 +} + +impl crate::protocol::primitive::deserialize::Deserialize for ConnAck { + fn parse(b: &[u8]) -> Result<(usize, Self), Error> { + let (flen, flags) = u8::parse(b)?; + let (elen, extra) = i16::parse(&b[flen..])?; + let (vlen, version) = i8::parse(&b[(flen+elen)..])?; + + return Ok((flen+elen+vlen, Self {flags, extra, version})); + } +} + + #[derive(Debug)] pub struct ClientInit { pub client_version: String, // Version of the client @@ -16,7 +38,7 @@ pub struct ClientInit { } impl HandshakeSerialize for ClientInit { - fn serialize(&self) -> Result<Vec<u8>, ErrorKind> { + fn serialize(&self) -> Result<Vec<u8>, Error> { let mut values: VariantMap = VariantMap::with_capacity(5); values.insert("MsgType".to_string(), Variant::String("ClientInit".to_string())); values.insert("ClientVersion".to_string(), Variant::String(self.client_version.clone())); @@ -28,16 +50,10 @@ impl HandshakeSerialize for ClientInit { } impl HandshakeDeserialize for ClientInit { - fn parse(b: &[u8]) -> Result<(usize, Self), ErrorKind> { + fn parse(b: &[u8]) -> Result<(usize, Self), Error> { let (len, values): (usize, VariantMap) = HandshakeDeserialize::parse(b)?; - let msgtypev = &values["MsgType"]; - let msgtype; - match msgtypev { - Variant::String(x) => msgtype = x, - Variant::StringUTF8(x) => msgtype = x, - _ => return Err(ErrorKind::WrongVariant) - }; + let msgtype = get_msg_type(&values["MsgType"])?; if msgtype == "ClientInit" { return Ok((len, Self { @@ -47,7 +63,7 @@ impl HandshakeDeserialize for ClientInit { client_features: match_variant!(values, Variant::u32, "Features") })); } else { - return Err(ErrorKind::WrongMsgType); + bail!(ProtocolError::WrongMsgType); } } } @@ -58,7 +74,7 @@ pub struct ClientInitReject { } impl HandshakeSerialize for ClientInitReject { - fn serialize(&self) -> Result<Vec<u8>, ErrorKind> { + fn serialize(&self) -> Result<Vec<u8>, Error> { let mut values: VariantMap = VariantMap::with_capacity(2); values.insert("MsgType".to_string(), Variant::String("ClientInitReject".to_string())); values.insert("ErrorString".to_string(), Variant::String(self.error_string.clone())); @@ -67,23 +83,17 @@ impl HandshakeSerialize for ClientInitReject { } impl HandshakeDeserialize for ClientInitReject { - fn parse(b: &[u8]) -> Result<(usize, Self), ErrorKind> { + fn parse(b: &[u8]) -> Result<(usize, Self), Error> { let (len, values): (usize, VariantMap) = HandshakeDeserialize::parse(b)?; - let msgtypev = &values["MsgType"]; - let msgtype; - match msgtypev { - Variant::String(x) => msgtype = x, - Variant::StringUTF8(x) => msgtype = x, - _ => return Err(ErrorKind::WrongVariant) - }; + let msgtype = get_msg_type(&values["MsgType"])?; if msgtype == "ClientInitReject" { return Ok((len, Self { error_string: match_variant!(values, Variant::String, "ErrorString") })); } else { - return Err(ErrorKind::WrongMsgType); + bail!(ProtocolError::WrongMsgType); } } } @@ -98,7 +108,7 @@ pub struct ClientInitAck { } impl HandshakeSerialize for ClientInitAck { - fn serialize(&self) -> Result<Vec<u8>, ErrorKind> { + fn serialize(&self) -> Result<Vec<u8>, Error> { let mut values: VariantMap = VariantMap::with_capacity(6); values.insert("MsgType".to_string(), Variant::String("ClientInitAck".to_string())); values.insert("CoreFeatures".to_string(), Variant::u32(self.core_features)); @@ -111,16 +121,10 @@ impl HandshakeSerialize for ClientInitAck { } impl HandshakeDeserialize for ClientInitAck { - fn parse(b: &[u8]) -> Result<(usize, Self), ErrorKind> { + fn parse(b: &[u8]) -> Result<(usize, Self), Error> { let (len, values): (usize, VariantMap) = HandshakeDeserialize::parse(b)?; - let msgtypev = &values["MsgType"]; - let msgtype; - match msgtypev { - Variant::String(x) => msgtype = x, - Variant::StringUTF8(x) => msgtype = x, - _ => return Err(ErrorKind::WrongVariant) - }; + let msgtype = get_msg_type(&values["MsgType"])?; if msgtype == "ClientInitAck" { return Ok((len, Self { @@ -131,7 +135,7 @@ impl HandshakeDeserialize for ClientInitAck { feature_list: match_variant!(values, Variant::StringList, "FeatureList") })); } else { - return Err(ErrorKind::WrongMsgType); + bail!(ProtocolError::WrongMsgType); } } } @@ -143,7 +147,7 @@ pub struct ClientLogin { } impl HandshakeSerialize for ClientLogin { - fn serialize(&self) -> Result<Vec<u8>, ErrorKind> { + fn serialize(&self) -> Result<Vec<u8>, Error> { let mut values: VariantMap = VariantMap::new(); values.insert("MsgType".to_string(), Variant::String("ClientLogin".to_string())); values.insert("User".to_string(), Variant::String(self.user.clone())); @@ -153,16 +157,10 @@ impl HandshakeSerialize for ClientLogin { } impl HandshakeDeserialize for ClientLogin { - fn parse(b: &[u8]) -> Result<(usize, Self), ErrorKind> { + fn parse(b: &[u8]) -> Result<(usize, Self), Error> { let (len, values): (usize, VariantMap) = HandshakeDeserialize::parse(b)?; - let msgtypev = &values["MsgType"]; - let msgtype; - match msgtypev { - Variant::String(x) => msgtype = x, - Variant::StringUTF8(x) => msgtype = x, - _ => return Err(ErrorKind::WrongVariant) - }; + let msgtype = get_msg_type(&values["MsgType"])?; if msgtype == "ClientLogin" { return Ok((len, Self { @@ -170,7 +168,7 @@ impl HandshakeDeserialize for ClientLogin { password: match_variant!(values, Variant::String, "Password") })); } else { - return Err(ErrorKind::WrongMsgType); + bail!(ProtocolError::WrongMsgType); } } } @@ -179,7 +177,7 @@ impl HandshakeDeserialize for ClientLogin { pub struct ClientLoginAck; impl HandshakeSerialize for ClientLoginAck { - fn serialize(&self) -> Result<Vec<u8>, ErrorKind> { + fn serialize(&self) -> Result<Vec<u8>, Error> { let mut values: VariantMap = VariantMap::with_capacity(1); values.insert("MsgType".to_string(), Variant::String("ClientLoginAck".to_string())); return HandshakeSerialize::serialize(&values); @@ -187,21 +185,15 @@ impl HandshakeSerialize for ClientLoginAck { } impl HandshakeDeserialize for ClientLoginAck { - fn parse(b: &[u8]) -> Result<(usize, Self), ErrorKind> { + fn parse(b: &[u8]) -> Result<(usize, Self), Error> { let (len, values): (usize, VariantMap) = HandshakeDeserialize::parse(b)?; - let msgtypev = &values["MsgType"]; - let msgtype; - match msgtypev { - Variant::String(x) => msgtype = x, - Variant::StringUTF8(x) => msgtype = x, - _ => return Err(ErrorKind::WrongVariant) - }; + let msgtype = get_msg_type(&values["MsgType"])?; if msgtype == "ClientLogin" { return Ok((len, Self {})); } else { - return Err(ErrorKind::WrongMsgType); + bail!(ProtocolError::WrongMsgType); } } } @@ -212,7 +204,7 @@ pub struct ClientLoginReject { } impl HandshakeSerialize for ClientLoginReject { - fn serialize(&self) -> Result<Vec<u8>, ErrorKind> { + fn serialize(&self) -> Result<Vec<u8>, Error> { let mut values: VariantMap = VariantMap::with_capacity(1); values.insert("MsgType".to_string(), Variant::String("ClientLoginReject".to_string())); values.insert("ErrorString".to_string(), Variant::String(self.error.clone())); @@ -221,21 +213,15 @@ impl HandshakeSerialize for ClientLoginReject { } impl HandshakeDeserialize for ClientLoginReject { - fn parse(b: &[u8]) -> Result<(usize, Self), ErrorKind> { + fn parse(b: &[u8]) -> Result<(usize, Self), Error> { let (len, values): (usize, VariantMap) = HandshakeDeserialize::parse(b)?; - let msgtypev = &values["MsgType"]; - let msgtype; - match msgtypev { - Variant::String(x) => msgtype = x, - Variant::StringUTF8(x) => msgtype = x, - _ => return Err(ErrorKind::WrongVariant) - }; + let msgtype = get_msg_type(&values["MsgType"])?; if msgtype == "ClientLogin" { return Ok((len, Self { error: match_variant!(values, Variant::String, "ErrorString")})); } else { - return Err(ErrorKind::WrongMsgType); + bail!(ProtocolError::WrongMsgType); } } } @@ -248,7 +234,7 @@ pub struct SessionInit { } impl HandshakeSerialize for SessionInit { - fn serialize(&self) -> Result<Vec<u8>, ErrorKind> { + fn serialize(&self) -> Result<Vec<u8>, Error> { let mut values: VariantMap = VariantMap::with_capacity(1); values.insert("MsgType".to_string(), Variant::String("SessionInit".to_string())); values.insert("Identities".to_string(), Variant::VariantList(self.identities.clone())); @@ -259,16 +245,10 @@ impl HandshakeSerialize for SessionInit { } impl HandshakeDeserialize for SessionInit { - fn parse(b: &[u8]) -> Result<(usize, Self), ErrorKind> { + fn parse(b: &[u8]) -> Result<(usize, Self), Error> { let (len, values): (usize, VariantMap) = HandshakeDeserialize::parse(b)?; - let msgtypev = &values["MsgType"]; - let msgtype; - match msgtypev { - Variant::String(x) => msgtype = x, - Variant::StringUTF8(x) => msgtype = x, - _ => return Err(ErrorKind::WrongVariant) - }; + let msgtype = get_msg_type(&values["MsgType"])?; if msgtype == "ClientLogin" { return Ok((len, Self { @@ -277,7 +257,7 @@ impl HandshakeDeserialize for SessionInit { network_ids: match_variant!(values, Variant::VariantList, "NetworkIds") })); } else { - return Err(ErrorKind::WrongMsgType); + bail!(ProtocolError::WrongMsgType); } } } diff --git a/src/protocol/message/handshake/types.rs b/src/protocol/message/handshake/types.rs index 3c5d019..643b376 100644 --- a/src/protocol/message/handshake/types.rs +++ b/src/protocol/message/handshake/types.rs @@ -4,29 +4,31 @@ use std::result::Result; use std::convert::TryInto; use std::collections::HashMap; +use failure::Error; + use crate::util; use crate::protocol::primitive::{String, Variant}; use crate::protocol::primitive::serialize::Serialize; use crate::protocol::primitive::deserialize::Deserialize; use crate::protocol::primitive::qread::QRead; -use crate::protocol::error::ErrorKind; +use crate::protocol::error::ProtocolError; pub trait HandshakeSerialize { - fn serialize(&self) -> Result<Vec<u8>, ErrorKind>; + fn serialize(&self) -> Result<Vec<u8>, Error>; } pub trait HandshakeDeserialize { - fn parse(b: &[u8]) -> Result<(usize, Self), ErrorKind> where Self: std::marker::Sized ; + fn parse(b: &[u8]) -> Result<(usize, Self), Error> where Self: std::marker::Sized ; } pub trait HandshakeQRead { - fn read<T: Read>(stream: &mut T, buf: &mut [u8]) -> Result<usize, ErrorKind>; + fn read<T: Read>(stream: &mut T, buf: &mut [u8]) -> Result<usize, Error>; } pub type VariantMap = HashMap<String, Variant>; impl HandshakeSerialize for VariantMap { - fn serialize<'a>(&'a self) -> Result<Vec<u8>, ErrorKind> { + fn serialize<'a>(&'a self) -> Result<Vec<u8>, Error> { let mut res: Vec<u8> = Vec::new(); for (k, v) in self { @@ -37,7 +39,7 @@ impl HandshakeSerialize for VariantMap { util::insert_bytes(0, &mut res, &mut [0, 0, 0, 10]); - let len: i32 = res.len().try_into()?; + let len: i32 = res.len().try_into().unwrap(); util::insert_bytes(0, &mut res, &mut ((len).to_be_bytes())); return Ok(res); @@ -45,7 +47,7 @@ impl HandshakeSerialize for VariantMap { } impl HandshakeDeserialize for VariantMap { - fn parse(b: &[u8]) -> Result<(usize, Self), ErrorKind> { + fn parse(b: &[u8]) -> Result<(usize, Self), Error> { let (_, len) = i32::parse(&b[0..4])?; let mut pos: usize = 8; @@ -62,7 +64,7 @@ impl HandshakeDeserialize for VariantMap { match name { Variant::String(x) => map.insert(x, value), Variant::StringUTF8(x) => map.insert(x, value), - _ => return Err(ErrorKind::WrongVariant) + _ => bail!(ProtocolError::WrongVariant) }; } @@ -71,7 +73,7 @@ impl HandshakeDeserialize for VariantMap { } impl HandshakeQRead for VariantMap { - fn read<T: Read>(s: &mut T, b: &mut [u8]) -> Result<usize, ErrorKind> { + fn read<T: Read>(s: &mut T, b: &mut [u8]) -> Result<usize, Error> { s.read(&mut b[0..4])?; let (_, len) = i32::parse(&b[0..4])?; let ulen = len as usize; diff --git a/src/protocol/primitive/basic.rs b/src/protocol/primitive/basic.rs index 15b712f..c9f462d 100644 --- a/src/protocol/primitive/basic.rs +++ b/src/protocol/primitive/basic.rs @@ -35,126 +35,128 @@ use std::vec::Vec; use std::result::Result; use std::convert::TryInto; +use failure::Error; + use crate::util; -use crate::protocol::error::ErrorKind; +use crate::protocol::error::ProtocolError; use crate::protocol::primitive::{deserialize, serialize, qread}; impl deserialize::Deserialize for bool { - fn parse(b: &[u8]) -> Result<(usize, Self), ErrorKind> { + fn parse(b: &[u8]) -> Result<(usize, Self), Error> { if b[0] == 0 { return Ok((1, false)) } else if b[0] == 1 { return Ok((1, true)) } else { - return Err(ErrorKind::BoolOutOfRange); + bail!(ProtocolError::BoolOutOfRange); }; } } impl qread::QRead for bool { - fn read<T: std::io::Read>(s: &mut T, b: &mut [u8]) -> Result<usize, ErrorKind> { + fn read<T: std::io::Read>(s: &mut T, b: &mut [u8]) -> Result<usize, Error> { Ok(s.read(&mut b[0..1])?) } } impl deserialize::Deserialize for u64 { - fn parse(b: &[u8]) -> Result<(usize, Self), ErrorKind> { + fn parse(b: &[u8]) -> Result<(usize, Self), Error> { let mut rdr = Cursor::new(&b[0..8]); return Ok((8, rdr.read_u64::<BigEndian>()?)); } } impl qread::QRead for u64 { - fn read<T: std::io::Read>(s: &mut T, b: &mut [u8]) -> Result<usize, ErrorKind> { + fn read<T: std::io::Read>(s: &mut T, b: &mut [u8]) -> Result<usize, Error> { Ok(s.read(&mut b[0..8])?) } } impl deserialize::Deserialize for u32 { - fn parse(b: &[u8]) -> Result<(usize, Self), ErrorKind> { + fn parse(b: &[u8]) -> Result<(usize, Self), Error> { let mut rdr = Cursor::new(&b[0..4]); return Ok((4, rdr.read_u32::<BigEndian>()?)); } } impl qread::QRead for u32 { - fn read<T: std::io::Read>(s: &mut T, b: &mut [u8]) -> Result<usize, ErrorKind> { + fn read<T: std::io::Read>(s: &mut T, b: &mut [u8]) -> Result<usize, Error> { Ok(s.read(&mut b[0..4])?) } } impl deserialize::Deserialize for u16 { - fn parse(b: &[u8]) -> Result<(usize, Self), ErrorKind> { + fn parse(b: &[u8]) -> Result<(usize, Self), Error> { let mut rdr = Cursor::new(&b[0..2]); return Ok((2, rdr.read_u16::<BigEndian>()?)); } } impl qread::QRead for u16 { - fn read<T: std::io::Read>(s: &mut T, b: &mut [u8]) -> Result<usize, ErrorKind> { + fn read<T: std::io::Read>(s: &mut T, b: &mut [u8]) -> Result<usize, Error> { Ok(s.read(&mut b[0..2])?) } } impl deserialize::Deserialize for u8 { - fn parse(b: &[u8]) -> Result<(usize, Self), ErrorKind> { + fn parse(b: &[u8]) -> Result<(usize, Self), Error> { return Ok((1, b[0])); } } impl qread::QRead for u8 { - fn read<T: std::io::Read>(s: &mut T, b: &mut [u8]) -> Result<usize, ErrorKind> { + fn read<T: std::io::Read>(s: &mut T, b: &mut [u8]) -> Result<usize, Error> { Ok(s.read(&mut [b[0]])?) } } impl deserialize::Deserialize for i64 { - fn parse(b: &[u8]) -> Result<(usize, Self), ErrorKind> { + fn parse(b: &[u8]) -> Result<(usize, Self), Error> { let mut rdr = Cursor::new(&b[0..8]); return Ok((8, rdr.read_i64::<BigEndian>()?)); } } impl qread::QRead for i64 { - fn read<T: std::io::Read>(s: &mut T, b: &mut [u8]) -> Result<usize, ErrorKind> { + fn read<T: std::io::Read>(s: &mut T, b: &mut [u8]) -> Result<usize, Error> { Ok(s.read(&mut b[0..8])?) } } impl deserialize::Deserialize for i32 { - fn parse(b: &[u8]) -> Result<(usize, Self), ErrorKind> { + fn parse(b: &[u8]) -> Result<(usize, Self), Error> { let mut rdr = Cursor::new(&b[0..4]); return Ok((4, rdr.read_i32::<BigEndian>()?)); } } impl qread::QRead for i32 { - fn read<T: std::io::Read>(s: &mut T, b: &mut [u8]) -> Result<usize, ErrorKind> { + fn read<T: std::io::Read>(s: &mut T, b: &mut [u8]) -> Result<usize, Error> { Ok(s.read(&mut b[0..4])?) } } impl deserialize::Deserialize for i16 { - fn parse(b: &[u8]) -> Result<(usize, Self), ErrorKind> { + fn parse(b: &[u8]) -> Result<(usize, Self), Error> { let mut rdr = Cursor::new(&b[0..2]); return Ok((2, rdr.read_i16::<BigEndian>()?)); } } impl qread::QRead for i16 { - fn read<T: std::io::Read>(s: &mut T, b: &mut [u8]) -> Result<usize, ErrorKind> { + fn read<T: std::io::Read>(s: &mut T, b: &mut [u8]) -> Result<usize, Error> { Ok(s.read(&mut b[0..2])?) } } impl deserialize::Deserialize for i8 { - fn parse(b: &[u8]) -> Result<(usize, Self), ErrorKind> { + fn parse(b: &[u8]) -> Result<(usize, Self), Error> { return Ok((1, b[0].try_into()?)); } } impl qread::QRead for i8 { - fn read<T: std::io::Read>(s: &mut T, b: &mut [u8]) -> Result<usize, ErrorKind> { + fn read<T: std::io::Read>(s: &mut T, b: &mut [u8]) -> Result<usize, Error> { return Ok(s.read(&mut [b[0]])?) } } @@ -163,7 +165,7 @@ impl qread::QRead for i8 { pub type String = std::string::String; impl serialize::Serialize for String { - fn serialize(&self) -> Result<Vec<u8>, ErrorKind> { + fn serialize(&self) -> Result<Vec<u8>, Error> { let mut res: Vec<u8> = Vec::new(); let utf16: Vec<u16> = self.encode_utf16().collect(); @@ -177,7 +179,7 @@ impl serialize::Serialize for String { } impl serialize::SerializeUTF8 for String { - fn serialize_utf8(&self) -> Result<Vec<u8>, ErrorKind> { + fn serialize_utf8(&self) -> Result<Vec<u8>, Error> { let mut res: Vec<u8> = Vec::new(); res.extend(self.clone().into_bytes()); util::prepend_byte_len(&mut res); @@ -186,7 +188,7 @@ impl serialize::SerializeUTF8 for String { } impl deserialize::Deserialize for String { - fn parse(b: &[u8]) -> Result<(usize, Self), ErrorKind> { + fn parse(b: &[u8]) -> Result<(usize, Self), Error> { let (_, len) = i32::parse(&b[0..4])?; let ulen = len as usize; @@ -205,7 +207,7 @@ impl deserialize::Deserialize for String { } impl deserialize::DeserializeUTF8 for String { - fn parse_utf8(b: &[u8]) -> Result<(usize, Self), ErrorKind> { + fn parse_utf8(b: &[u8]) -> Result<(usize, Self), Error> { use crate::protocol::primitive::deserialize::Deserialize; let (_, len) = i32::parse(&b[0..4])?; @@ -217,7 +219,7 @@ impl deserialize::DeserializeUTF8 for String { } impl qread::QRead for String { - fn read<T: std::io::Read>(s: &mut T, b: &mut [u8]) -> Result<usize, ErrorKind> { + fn read<T: std::io::Read>(s: &mut T, b: &mut [u8]) -> Result<usize, Error> { use crate::protocol::primitive::deserialize::Deserialize; s.read(&mut b[0..4])?; @@ -232,7 +234,7 @@ impl qread::QRead for String { pub type StringList = Vec<String>; impl serialize::Serialize for StringList { - fn serialize(&self) -> Result<Vec<u8>, ErrorKind> { + fn serialize(&self) -> Result<Vec<u8>, Error> { let len: i32 = self.len().try_into()?; let mut res: Vec<u8> = Vec::new(); @@ -246,7 +248,7 @@ impl serialize::Serialize for StringList { } impl deserialize::Deserialize for StringList { - fn parse(b: &[u8]) -> Result<(usize, Self), ErrorKind> { + fn parse(b: &[u8]) -> Result<(usize, Self), Error> { let (_, len) = i32::parse(&b[0..4])?; let mut res: StringList = StringList::new(); @@ -264,7 +266,7 @@ impl deserialize::Deserialize for StringList { } impl qread::QRead for StringList { - fn read<T: std::io::Read>(s: &mut T, b: &mut [u8]) -> Result<usize, ErrorKind> { + fn read<T: std::io::Read>(s: &mut T, b: &mut [u8]) -> Result<usize, Error> { use crate::protocol::primitive::deserialize::Deserialize; s.read(&mut b[0..4])?; diff --git a/src/protocol/primitive/mod.rs b/src/protocol/primitive/mod.rs index 42f6aae..fb843ad 100644 --- a/src/protocol/primitive/mod.rs +++ b/src/protocol/primitive/mod.rs @@ -7,31 +7,28 @@ pub use variant::*; pub mod serialize { - use crate::protocol::error::ErrorKind; - + use failure::Error; pub trait Serialize { - fn serialize(&self) -> Result<Vec<u8>, ErrorKind>; + fn serialize(&self) -> Result<Vec<u8>, Error>; } pub trait SerializeUTF8 { - fn serialize_utf8(&self) -> Result<Vec<u8>, ErrorKind>; + fn serialize_utf8(&self) -> Result<Vec<u8>, Error>; } } pub mod deserialize { - use crate::protocol::error::ErrorKind; - + use failure::Error; pub trait Deserialize { - fn parse(b: &[u8]) -> Result<(usize, Self), ErrorKind> where Self: std::marker::Sized ; + fn parse(b: &[u8]) -> Result<(usize, Self), Error> where Self: std::marker::Sized ; } pub trait DeserializeUTF8 { - fn parse_utf8(b: &[u8]) -> Result<(usize, Self), ErrorKind> where Self: std::marker::Sized ; + fn parse_utf8(b: &[u8]) -> Result<(usize, Self), Error> where Self: std::marker::Sized ; } } pub mod qread { - use crate::protocol::error::ErrorKind; - + use failure::Error; pub trait QRead { - fn read<T: std::io::Read>(stream: &mut T, buf: &mut [u8]) -> Result<usize, ErrorKind>; + fn read<T: std::io::Read>(stream: &mut T, buf: &mut [u8]) -> Result<usize, Error>; } } diff --git a/src/protocol/primitive/variant.rs b/src/protocol/primitive/variant.rs index 8c6173f..24305ca 100644 --- a/src/protocol/primitive/variant.rs +++ b/src/protocol/primitive/variant.rs @@ -1,20 +1,22 @@ +use std::io::Read; use std::vec::Vec; use std::convert::TryInto; use std::collections::HashMap; -use std::io::Read; +use failure::Error; + use crate::util; use crate::protocol::primitive::serialize::{Serialize, SerializeUTF8}; use crate::protocol::primitive::deserialize::{Deserialize, DeserializeUTF8}; use crate::protocol::primitive::qread::QRead; use crate::protocol::primitive::{String,StringList}; -use crate::protocol::error::ErrorKind; +use crate::protocol::error::ProtocolError; use crate::protocol::primitive; pub type VariantMap = HashMap<String, Variant>; impl Serialize for VariantMap { - fn serialize<'a>(&'a self) -> Result<Vec<u8>, ErrorKind> { + fn serialize<'a>(&'a self) -> Result<Vec<u8>, Error> { let mut res: Vec<u8> = Vec::new(); for (k, v) in self { @@ -30,7 +32,7 @@ impl Serialize for VariantMap { } impl Deserialize for VariantMap { - fn parse(b: &[u8]) -> Result<(usize, Self), ErrorKind> { + fn parse(b: &[u8]) -> Result<(usize, Self), Error> { let (_, len) = i32::parse(&b[0..4])?; let mut pos = 4; @@ -50,7 +52,7 @@ impl Deserialize for VariantMap { } impl QRead for VariantMap { - fn read<T: Read>(s: &mut T, b: &mut [u8]) -> Result<usize, ErrorKind> { + fn read<T: Read>(s: &mut T, b: &mut [u8]) -> Result<usize, Error> { s.read(&mut b[0..4])?; @@ -70,7 +72,7 @@ impl QRead for VariantMap { pub type VariantList = Vec<Variant>; impl Serialize for VariantList { - fn serialize(&self) -> Result<Vec<u8>, ErrorKind> { + fn serialize(&self) -> Result<Vec<u8>, Error> { let len: i32 = self.len().try_into()?; let mut res: Vec<u8> = Vec::new(); @@ -84,7 +86,7 @@ impl Serialize for VariantList { } impl Deserialize for VariantList { - fn parse(b: &[u8]) -> Result<(usize, Self), ErrorKind> { + fn parse(b: &[u8]) -> Result<(usize, Self), Error> { let (_, len) = i32::parse(&b[0..4])?; let mut res: VariantList = VariantList::new(); @@ -100,7 +102,7 @@ impl Deserialize for VariantList { } impl QRead for VariantList { - fn read<T: Read>(s: &mut T, b: &mut [u8]) -> Result<usize, ErrorKind> { + fn read<T: Read>(s: &mut T, b: &mut [u8]) -> Result<usize, Error> { s.read(&mut b[0..4])?; let (_, len) = i32::parse(&b[0..4])?; @@ -136,13 +138,13 @@ pub enum Variant { } impl Serialize for Variant { - fn serialize(&self) -> Result<Vec<u8>, ErrorKind> { + fn serialize(&self) -> Result<Vec<u8>, Error> { let unknown: u8 = 0x00; let mut res: Vec<u8> = Vec::new(); match self { Variant::Unknown => { - return Err(ErrorKind::UnknownVariant); + bail!(ProtocolError::UnknownVariant); }, Variant::VariantMap(v) => { res.extend(primitive::QVARIANTMAP.to_be_bytes().iter()); @@ -222,9 +224,10 @@ impl Serialize for Variant { } impl Deserialize for Variant { - fn parse(b: &[u8]) -> Result<(usize, Self), ErrorKind> { + fn parse(b: &[u8]) -> Result<(usize, Self), Error> { let (_, qtype) = i32::parse(&b[0..4])?; let qtype = qtype as u32; + println!("type: {:?}", &b[0..4]); #[allow(unused_variables)] let unknown: u8 = b[4]; @@ -288,14 +291,14 @@ impl Deserialize for Variant { return Ok((len+vlen, Variant::i8(value))); }, _ => { - return Err(ErrorKind::UnknownVariant); + bail!(ProtocolError::UnknownVariant); } } } } impl QRead for Variant { - fn read<T: Read>(s: &mut T, b: &mut [u8]) -> Result<usize, ErrorKind> { + fn read<T: Read>(s: &mut T, b: &mut [u8]) -> Result<usize, Error> { s.read(&mut b[0..4])?; let (_, qtype) = i32::parse(&b[0..4])?; @@ -319,7 +322,7 @@ impl QRead for Variant { primitive::INT => len += i32::read(s, &mut b[len..])?, primitive::SHORT => len += i16::read(s, &mut b[len..])?, primitive::CHAR => len += i8::read(s, &mut b[len..])?, - _ => return Err(ErrorKind::UnknownVariant) + _ => bail!(ProtocolError::UnknownVariant) } return Ok(len); diff --git a/src/util.rs b/src/util.rs index 48ab55e..7c26ec5 100644 --- a/src/util.rs +++ b/src/util.rs @@ -24,6 +24,18 @@ macro_rules! match_variant { } } +use crate::protocol::primitive::{Variant, String}; +use crate::protocol::error::ProtocolError; +use failure::Error; + +pub fn get_msg_type(val: &Variant) -> Result<&str, Error> { + match val { + Variant::String(x) => return Ok(x), + Variant::StringUTF8(x) => return Ok(x), + _ => bail!(ProtocolError::WrongVariant) + }; +} + pub fn prepend_byte_len(buf: &mut Vec<u8>) { use std::convert::TryInto; let len: i32 = buf.len().try_into().unwrap(); |
