Browse Source

Low-level protocol tests.

Mathias Gottschlag 5 years ago
parent
commit
1582be81c0
5 changed files with 151 additions and 8 deletions
  1. 37
    0
      Cargo.lock
  2. 1
    0
      Cargo.toml
  3. 82
    0
      src/bin/protocol-tests.rs
  4. 1
    0
      src/lib.rs
  5. 30
    8
      src/protocol.rs

+ 37
- 0
Cargo.lock View File

53
 version = "0.1.7"
53
 version = "0.1.7"
54
 source = "registry+https://github.com/rust-lang/crates.io-index"
54
 source = "registry+https://github.com/rust-lang/crates.io-index"
55
 
55
 
56
+[[package]]
57
+name = "autocfg"
58
+version = "1.0.0"
59
+source = "registry+https://github.com/rust-lang/crates.io-index"
60
+
56
 [[package]]
61
 [[package]]
57
 name = "base64"
62
 name = "base64"
58
 version = "0.11.0"
63
 version = "0.11.0"
520
  "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
525
  "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
521
 ]
526
 ]
522
 
527
 
528
+[[package]]
529
+name = "num-traits"
530
+version = "0.2.11"
531
+source = "registry+https://github.com/rust-lang/crates.io-index"
532
+dependencies = [
533
+ "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
534
+]
535
+
523
 [[package]]
536
 [[package]]
524
 name = "num_cpus"
537
 name = "num_cpus"
525
 version = "1.12.0"
538
 version = "1.12.0"
700
 version = "0.6.14"
713
 version = "0.6.14"
701
 source = "registry+https://github.com/rust-lang/crates.io-index"
714
 source = "registry+https://github.com/rust-lang/crates.io-index"
702
 
715
 
716
+[[package]]
717
+name = "rmp"
718
+version = "0.8.9"
719
+source = "registry+https://github.com/rust-lang/crates.io-index"
720
+dependencies = [
721
+ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
722
+ "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
723
+]
724
+
725
+[[package]]
726
+name = "rmp-serde"
727
+version = "0.14.3"
728
+source = "registry+https://github.com/rust-lang/crates.io-index"
729
+dependencies = [
730
+ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
731
+ "rmp 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)",
732
+ "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
733
+]
734
+
703
 [[package]]
735
 [[package]]
704
 name = "rust-argon2"
736
 name = "rust-argon2"
705
 version = "0.7.0"
737
 version = "0.7.0"
906
  "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
938
  "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
907
  "futures-tokio-compat 0.1.0 (git+https://github.com/mgottschlag/futures-tokio-compat.git)",
939
  "futures-tokio-compat 0.1.0 (git+https://github.com/mgottschlag/futures-tokio-compat.git)",
908
  "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
940
  "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
941
+ "rmp-serde 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)",
909
  "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
942
  "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
910
  "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)",
943
  "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)",
911
  "structopt 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
944
  "structopt 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
1027
 "checksum async-tungstenite 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37250bc739b253cf2d861047a7bcaad1d46d1d027070b44dbeab9168b40cf407"
1060
 "checksum async-tungstenite 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37250bc739b253cf2d861047a7bcaad1d46d1d027070b44dbeab9168b40cf407"
1028
 "checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
1061
 "checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
1029
 "checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
1062
 "checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
1063
+"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
1030
 "checksum base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
1064
 "checksum base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
1031
 "checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
1065
 "checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
1032
 "checksum blake2b_simd 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a"
1066
 "checksum blake2b_simd 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a"
1083
 "checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125"
1117
 "checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125"
1084
 "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
1118
 "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
1085
 "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
1119
 "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
1120
+"checksum num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096"
1086
 "checksum num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6"
1121
 "checksum num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6"
1087
 "checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
1122
 "checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
1088
 "checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
1123
 "checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
1106
 "checksum redox_users 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431"
1141
 "checksum redox_users 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431"
1107
 "checksum regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "322cf97724bea3ee221b78fe25ac9c46114ebb51747ad5babd51a2fc6a8235a8"
1142
 "checksum regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "322cf97724bea3ee221b78fe25ac9c46114ebb51747ad5babd51a2fc6a8235a8"
1108
 "checksum regex-syntax 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)" = "b28dfe3fe9badec5dbf0a79a9cccad2cfc2ab5484bdb3e44cbd1ae8b3ba2be06"
1143
 "checksum regex-syntax 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)" = "b28dfe3fe9badec5dbf0a79a9cccad2cfc2ab5484bdb3e44cbd1ae8b3ba2be06"
1144
+"checksum rmp 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)" = "0f10b46df14cf1ee1ac7baa4d2fbc2c52c0622a4b82fa8740e37bc452ac0184f"
1145
+"checksum rmp-serde 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4c1ee98f14fe8b8e9c5ea13d25da7b2a1796169202c57a09d7288de90d56222b"
1109
 "checksum rust-argon2 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017"
1146
 "checksum rust-argon2 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017"
1110
 "checksum rustversion 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b3bba175698996010c4f6dce5e7f173b6eb781fce25d2cfc45e27091ce0b79f6"
1147
 "checksum rustversion 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b3bba175698996010c4f6dce5e7f173b6eb781fce25d2cfc45e27091ce0b79f6"
1111
 "checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8"
1148
 "checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8"

+ 1
- 0
Cargo.toml View File

16
 async-tungstenite = { version = "0.3", features = ["tokio-runtime"] }
16
 async-tungstenite = { version = "0.3", features = ["tokio-runtime"] }
17
 env_logger = "0.7"
17
 env_logger = "0.7"
18
 log = "0.4"
18
 log = "0.4"
19
+rmp-serde = "0.14"
19
 fswatcher = { git = "https://github.com/mgottschlag/fswatcher-rs.git" }
20
 fswatcher = { git = "https://github.com/mgottschlag/fswatcher-rs.git" }

+ 82
- 0
src/bin/protocol-tests.rs View File

1
+extern crate rmp_serde as rmps;
2
+extern crate serde;
3
+
4
+use rmps::Serializer;
5
+use serde::Serialize;
6
+use twfss::protocol;
7
+
8
+fn print_serialized_deserialized(packet: protocol::Packet) {
9
+    let mut buf = Vec::new();
10
+    packet
11
+        .serialize(
12
+            &mut Serializer::new(&mut buf)
13
+                .with_struct_map()
14
+                .with_string_variants(),
15
+        )
16
+        .unwrap();
17
+    println!("Serialized: {:?}", buf);
18
+    let packet: protocol::Packet = rmps::decode::from_slice(&buf).unwrap();
19
+    println!("Deserialized: {:?}\n", packet);
20
+}
21
+
22
+fn main() {
23
+    // Open questions:
24
+    // - Do we actually need the "response" field? Actually, separating the ID range so that
25
+    //   server->client events get IDs from the range between 2^31 and above would be enough.
26
+
27
+    // The low-level protocol needs to implement two basic pieces of functionality: It needs to be
28
+    // able to implement remote procedure calls from the client to the server, and it needs to
29
+    // provide a method for the server to send asynchronous events. A protocol for both cases is
30
+    // outlined below, where each packet is sent as one WebSocket message.
31
+    //
32
+    // Remote procedure call:
33
+    // - The client allocates an ID from the range between 0..2^31-1 that is not currently in use
34
+    //   for another RPC in progress.
35
+    // - The client prepares a packet with this ID, "response = false", and the appropriate
36
+    //   payload and sends the packet to the server.
37
+    // - The server receives the packet, processes the request and sends a packet back with the
38
+    //   identical ID and "response = true".
39
+    // - In case of an error, the payload has the type "Error" which in turn contains the error
40
+    //   type.
41
+    // - Unpon reception of the response, the client is free to reuse the ID for further RPCs.
42
+    // Note that this protocol does not allow the client to cancel an RPC that is currently in
43
+    // progress - implementing such functionality is difficult, error-prone, and most likely not
44
+    // worth the effort.
45
+    //
46
+    // Server-side event:
47
+    // - The server creates a packet with the ID 2^31 and the event content and sends it to the
48
+    //   client.
49
+    // Note that the client does not have any method to acknowledge event reception. As events are
50
+    // asynchronous compared to RPCs on the same connection, the event type needs to be designed in
51
+    // a way that no such temporal information is necessary to process the events.
52
+    // TODO: Example to demonstrate the problem.
53
+
54
+    println!("Without request content:");
55
+    let packet = protocol::Packet {
56
+        id: 42,
57
+        response: false,
58
+        payload: protocol::PacketPayload::ServerInfo,
59
+    };
60
+    print_serialized_deserialized(packet);
61
+    // Should be: [131, 162, 105, 100, 42, 168, 114, 101, 115, 112, 111, 110, 115, 101, 194, 167, 112, 97, 121, 108, 111, 97, 100, 129, 170, 83, 101, 114, 118, 101, 114, 73, 110, 102, 111, 192]
62
+
63
+    println!("\nWith request content:");
64
+    let packet = protocol::Packet {
65
+        id: 42,
66
+        response: true,
67
+        payload: protocol::PacketPayload::ServerInfoResponse(protocol::ServerInfoResponse {
68
+            version: "0.1".to_owned(),
69
+        }),
70
+    };
71
+    print_serialized_deserialized(packet);
72
+    // Should be: [131, 162, 105, 100, 42, 168, 114, 101, 115, 112, 111, 110, 115, 101, 194, 167, 112, 97, 121, 108, 111, 97, 100, 129, 178, 83, 101, 114, 118, 101, 114, 73, 110, 102, 111, 82, 101, 115, 112, 111, 110, 115, 101, 129, 167, 118, 101, 114, 115, 105, 111, 110, 163, 48, 46, 49]
73
+
74
+    println!("Error:");
75
+    let packet = protocol::Packet {
76
+        id: 42,
77
+        response: true,
78
+        payload: protocol::PacketPayload::Error(protocol::Error::InvalidParameter),
79
+    };
80
+    print_serialized_deserialized(packet);
81
+    // Should be: [131, 162, 105, 100, 42, 168, 114, 101, 115, 112, 111, 110, 115, 101, 195, 167, 112, 97, 121, 108, 111, 97, 100, 129, 165, 69, 114, 114, 111, 114, 129, 176, 73, 110, 118, 97, 108, 105, 100, 80, 97, 114, 97, 109, 101, 116, 101, 114, 192]
82
+}

+ 1
- 0
src/lib.rs View File

4
 mod file_system_watcher;
4
 mod file_system_watcher;
5
 mod file_tree;
5
 mod file_tree;
6
 pub mod network;
6
 pub mod network;
7
+pub mod protocol;
7
 
8
 
8
 pub use database::Database;
9
 pub use database::Database;
9
 pub use file_system_watcher::FileSystemWatcher;
10
 pub use file_system_watcher::FileSystemWatcher;

+ 30
- 8
src/protocol.rs View File

1
+use serde::{Deserialize, Serialize};
2
+
1
 /*pub trait Protocol {
3
 /*pub trait Protocol {
2
     fn login_password(&mut self, user: &str, password: &str) -> Result<String, Error>;
4
     fn login_password(&mut self, user: &str, password: &str) -> Result<String, Error>;
3
     fn login_app_key(&mut self, user: &str, key: &str) -> Result<(), Error>;
5
     fn login_app_key(&mut self, user: &str, key: &str) -> Result<(), Error>;
11
     // TODO
13
     // TODO
12
 }*/
14
 }*/
13
 
15
 
14
-pub struct DirectoryListing {
16
+/*pub struct DirectoryListing {
15
     own_version: u64,
17
     own_version: u64,
16
     entries: Vec<FileMetadata>,
18
     entries: Vec<FileMetadata>,
17
     // TODO
19
     // TODO
28
     Directory,
30
     Directory,
29
     File,
31
     File,
30
     SymbolicLink,
32
     SymbolicLink,
31
-}
33
+}*/
32
 
34
 
35
+#[derive(Debug, Deserialize, Serialize)]
33
 pub struct Packet {
36
 pub struct Packet {
34
-    pub serial_number: u32,
35
-    pub type_: PacketContent,
37
+    pub id: u32,
38
+    pub response: bool,
39
+    pub payload: PacketPayload,
36
 }
40
 }
37
 
41
 
38
-pub enum PacketContent {
39
-    Keepalive,
42
+#[derive(Debug, Deserialize, Serialize)]
43
+pub enum PacketPayload {
40
     Error(Error),
44
     Error(Error),
41
     ServerInfo,
45
     ServerInfo,
42
-    ServerInfoResponse(ServerInfoResponse,
46
+    ServerInfoResponse(ServerInfoResponse),
43
     PasswordLogin(PasswordLogin),
47
     PasswordLogin(PasswordLogin),
44
     PasswordLoginResponse(PasswordLoginResponse),
48
     PasswordLoginResponse(PasswordLoginResponse),
45
     AppKeyLogin(AppKeyLogin),
49
     AppKeyLogin(AppKeyLogin),
59
     FinishFileUpdate,
63
     FinishFileUpdate,
60
 }
64
 }
61
 
65
 
66
+#[derive(Debug, Deserialize, Serialize)]
62
 pub enum Error {
67
 pub enum Error {
63
-    // TODO
68
+    InvalidParameter,
64
 }
69
 }
65
 
70
 
71
+#[derive(Debug, Deserialize, Serialize)]
66
 pub struct ServerInfoResponse {
72
 pub struct ServerInfoResponse {
67
     // TODO: Version of the protocol, type of the server (encrypted/unencrypted).
73
     // TODO: Version of the protocol, type of the server (encrypted/unencrypted).
74
+    pub version: String,
68
 }
75
 }
69
 
76
 
77
+#[derive(Debug, Deserialize, Serialize)]
70
 pub struct PasswordLogin {
78
 pub struct PasswordLogin {
71
     // TODO
79
     // TODO
72
 }
80
 }
73
 
81
 
82
+#[derive(Debug, Deserialize, Serialize)]
74
 pub struct PasswordLoginResponse {
83
 pub struct PasswordLoginResponse {
75
     // TODO
84
     // TODO
76
 }
85
 }
77
 
86
 
87
+#[derive(Debug, Deserialize, Serialize)]
78
 pub struct AppKeyLogin {
88
 pub struct AppKeyLogin {
79
     // TODO
89
     // TODO
80
 }
90
 }
91
+
92
+#[derive(Debug, Deserialize, Serialize)]
81
 pub struct AppKeyLoginResponse {
93
 pub struct AppKeyLoginResponse {
82
     // TODO
94
     // TODO
83
 }
95
 }
84
 
96
 
97
+#[derive(Debug, Deserialize, Serialize)]
85
 pub struct RegisterInterest {
98
 pub struct RegisterInterest {
86
     // TODO
99
     // TODO
87
 }
100
 }
88
 
101
 
102
+#[derive(Debug, Deserialize, Serialize)]
89
 pub struct RegisterInterestResponse {
103
 pub struct RegisterInterestResponse {
90
     // TODO
104
     // TODO
91
 }
105
 }
92
 
106
 
107
+#[derive(Debug, Deserialize, Serialize)]
93
 pub struct UnregisterInterest {
108
 pub struct UnregisterInterest {
94
     // TODO
109
     // TODO
95
 }
110
 }
96
 
111
 
112
+#[derive(Debug, Deserialize, Serialize)]
97
 pub struct UnregisterInterestResponse {
113
 pub struct UnregisterInterestResponse {
98
     // TODO
114
     // TODO
99
 }
115
 }
100
 
116
 
117
+#[derive(Debug, Deserialize, Serialize)]
101
 pub struct ListDirectory {
118
 pub struct ListDirectory {
102
     // TODO
119
     // TODO
103
 }
120
 }
104
 
121
 
122
+#[derive(Debug, Deserialize, Serialize)]
105
 pub struct ListDirectoryResponse {
123
 pub struct ListDirectoryResponse {
106
     // TODO
124
     // TODO
107
 }
125
 }
108
 
126
 
127
+#[derive(Debug, Deserialize, Serialize)]
109
 pub struct GetFileMetadata {
128
 pub struct GetFileMetadata {
110
     // TODO
129
     // TODO
111
 }
130
 }
112
 
131
 
132
+#[derive(Debug, Deserialize, Serialize)]
113
 pub struct GetFileMetadataResponse {
133
 pub struct GetFileMetadataResponse {
114
     // TODO
134
     // TODO
115
 }
135
 }
116
 
136
 
137
+#[derive(Debug, Deserialize, Serialize)]
117
 pub struct GetFileContent {
138
 pub struct GetFileContent {
118
     // TODO
139
     // TODO
119
 }
140
 }
120
 
141
 
142
+#[derive(Debug, Deserialize, Serialize)]
121
 pub struct GetFileContentResponse {
143
 pub struct GetFileContentResponse {
122
     // TODO
144
     // TODO
123
 }
145
 }

Loading…
Cancel
Save