diff options
23 files changed, 596 insertions, 241 deletions
diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index d7eaaf3..279e16d 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml | |||
@@ -19,21 +19,9 @@ jobs: | |||
19 | uses: mozilla-actions/[email protected] | 19 | uses: mozilla-actions/[email protected] |
20 | 20 | ||
21 | - uses: actions/checkout@v4 | 21 | - uses: actions/checkout@v4 |
22 | - uses: actions-rs/toolchain@v1 | 22 | |
23 | with: | 23 | - run: cargo check |
24 | toolchain: stable | 24 | - run: cargo clippy |
25 | components: rustfmt, clippy | ||
26 | override: true | ||
27 | |||
28 | - name: run cargo check | ||
29 | uses: actions-rs/cargo@v1 | ||
30 | with: | ||
31 | command: check | ||
32 | |||
33 | - name: run clippy | ||
34 | uses: actions-rs/cargo@v1 | ||
35 | with: | ||
36 | command: clippy | ||
37 | 25 | ||
38 | check-release: | 26 | check-release: |
39 | runs-on: ubuntu-latest | 27 | runs-on: ubuntu-latest |
@@ -42,20 +30,6 @@ jobs: | |||
42 | uses: mozilla-actions/[email protected] | 30 | uses: mozilla-actions/[email protected] |
43 | 31 | ||
44 | - uses: actions/checkout@v4 | 32 | - uses: actions/checkout@v4 |
45 | - uses: actions-rs/toolchain@v1 | 33 | |
46 | with: | 34 | - run: cargo check --release |
47 | toolchain: stable | 35 | - run: cargo clippy --release \ No newline at end of file |
48 | components: rustfmt, clippy | ||
49 | override: true | ||
50 | |||
51 | - name: run cargo check | ||
52 | uses: actions-rs/cargo@v1 | ||
53 | with: | ||
54 | command: check | ||
55 | args: --release | ||
56 | |||
57 | - name: run clippy | ||
58 | uses: actions-rs/cargo@v1 | ||
59 | with: | ||
60 | command: clippy | ||
61 | args: --release | ||
diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 93b6edb..d41941b 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml | |||
@@ -19,23 +19,9 @@ jobs: | |||
19 | uses: mozilla-actions/[email protected] | 19 | uses: mozilla-actions/[email protected] |
20 | 20 | ||
21 | - uses: actions/checkout@v4 | 21 | - uses: actions/checkout@v4 |
22 | - uses: actions-rs/toolchain@v1 | ||
23 | with: | ||
24 | toolchain: stable | ||
25 | components: rustfmt, clippy | ||
26 | override: true | ||
27 | 22 | ||
28 | - name: Run cargo check | 23 | - run: cargo check --release |
29 | uses: actions-rs/cargo@v1 | 24 | - run: cargo clippy --release |
30 | with: | ||
31 | command: check | ||
32 | args: --release | ||
33 | |||
34 | - name: Run Clippy | ||
35 | uses: actions-rs/cargo@v1 | ||
36 | with: | ||
37 | command: clippy | ||
38 | args: --release | ||
39 | 25 | ||
40 | build: | 26 | build: |
41 | runs-on: ubuntu-latest | 27 | runs-on: ubuntu-latest |
diff --git a/.sqlx/query-3ed66b56b7e78a6b6bad9d49c49607520a8d09f902b996467dddf58737a3757f.json b/.sqlx/query-3ed66b56b7e78a6b6bad9d49c49607520a8d09f902b996467dddf58737a3757f.json deleted file mode 100644 index feedac8..0000000 --- a/.sqlx/query-3ed66b56b7e78a6b6bad9d49c49607520a8d09f902b996467dddf58737a3757f.json +++ /dev/null | |||
@@ -1,16 +0,0 @@ | |||
1 | { | ||
2 | "db_name": "PostgreSQL", | ||
3 | "query": "\n INSERT INTO devices (id, mac, broadcast_addr)\n VALUES ($1, $2, $3);\n ", | ||
4 | "describe": { | ||
5 | "columns": [], | ||
6 | "parameters": { | ||
7 | "Left": [ | ||
8 | "Text", | ||
9 | "Text", | ||
10 | "Text" | ||
11 | ] | ||
12 | }, | ||
13 | "nullable": [] | ||
14 | }, | ||
15 | "hash": "3ed66b56b7e78a6b6bad9d49c49607520a8d09f902b996467dddf58737a3757f" | ||
16 | } | ||
diff --git a/.sqlx/query-82c11b5a47389884e4ed945b87dfcee9067933c4df892609700c0766c20fc5c5.json b/.sqlx/query-82c11b5a47389884e4ed945b87dfcee9067933c4df892609700c0766c20fc5c5.json new file mode 100644 index 0000000..c0a933d --- /dev/null +++ b/.sqlx/query-82c11b5a47389884e4ed945b87dfcee9067933c4df892609700c0766c20fc5c5.json | |||
@@ -0,0 +1,40 @@ | |||
1 | { | ||
2 | "db_name": "PostgreSQL", | ||
3 | "query": "\n SELECT id, mac, broadcast_addr, ip\n FROM devices\n WHERE id = $1;\n ", | ||
4 | "describe": { | ||
5 | "columns": [ | ||
6 | { | ||
7 | "ordinal": 0, | ||
8 | "name": "id", | ||
9 | "type_info": "Varchar" | ||
10 | }, | ||
11 | { | ||
12 | "ordinal": 1, | ||
13 | "name": "mac", | ||
14 | "type_info": "Varchar" | ||
15 | }, | ||
16 | { | ||
17 | "ordinal": 2, | ||
18 | "name": "broadcast_addr", | ||
19 | "type_info": "Varchar" | ||
20 | }, | ||
21 | { | ||
22 | "ordinal": 3, | ||
23 | "name": "ip", | ||
24 | "type_info": "Varchar" | ||
25 | } | ||
26 | ], | ||
27 | "parameters": { | ||
28 | "Left": [ | ||
29 | "Text" | ||
30 | ] | ||
31 | }, | ||
32 | "nullable": [ | ||
33 | false, | ||
34 | false, | ||
35 | false, | ||
36 | false | ||
37 | ] | ||
38 | }, | ||
39 | "hash": "82c11b5a47389884e4ed945b87dfcee9067933c4df892609700c0766c20fc5c5" | ||
40 | } | ||
diff --git a/.sqlx/query-adead45e1a6b02d5eabd68b8cf06394a302d288e91f5eedde65db6630021f737.json b/.sqlx/query-adead45e1a6b02d5eabd68b8cf06394a302d288e91f5eedde65db6630021f737.json new file mode 100644 index 0000000..bc4bdd3 --- /dev/null +++ b/.sqlx/query-adead45e1a6b02d5eabd68b8cf06394a302d288e91f5eedde65db6630021f737.json | |||
@@ -0,0 +1,17 @@ | |||
1 | { | ||
2 | "db_name": "PostgreSQL", | ||
3 | "query": "\n INSERT INTO devices (id, mac, broadcast_addr, ip)\n VALUES ($1, $2, $3, $4);\n ", | ||
4 | "describe": { | ||
5 | "columns": [], | ||
6 | "parameters": { | ||
7 | "Left": [ | ||
8 | "Varchar", | ||
9 | "Varchar", | ||
10 | "Varchar", | ||
11 | "Varchar" | ||
12 | ] | ||
13 | }, | ||
14 | "nullable": [] | ||
15 | }, | ||
16 | "hash": "adead45e1a6b02d5eabd68b8cf06394a302d288e91f5eedde65db6630021f737" | ||
17 | } | ||
diff --git a/.sqlx/query-bb9c6a42084b92c339a85f9b1c094959a49c6b7383f1a0b49df242e2720a9185.json b/.sqlx/query-bb9c6a42084b92c339a85f9b1c094959a49c6b7383f1a0b49df242e2720a9185.json deleted file mode 100644 index efd2830..0000000 --- a/.sqlx/query-bb9c6a42084b92c339a85f9b1c094959a49c6b7383f1a0b49df242e2720a9185.json +++ /dev/null | |||
@@ -1,34 +0,0 @@ | |||
1 | { | ||
2 | "db_name": "PostgreSQL", | ||
3 | "query": "\n SELECT id, mac, broadcast_addr\n FROM devices\n WHERE id = $1;\n ", | ||
4 | "describe": { | ||
5 | "columns": [ | ||
6 | { | ||
7 | "ordinal": 0, | ||
8 | "name": "id", | ||
9 | "type_info": "Text" | ||
10 | }, | ||
11 | { | ||
12 | "ordinal": 1, | ||
13 | "name": "mac", | ||
14 | "type_info": "Text" | ||
15 | }, | ||
16 | { | ||
17 | "ordinal": 2, | ||
18 | "name": "broadcast_addr", | ||
19 | "type_info": "Text" | ||
20 | } | ||
21 | ], | ||
22 | "parameters": { | ||
23 | "Left": [ | ||
24 | "Text" | ||
25 | ] | ||
26 | }, | ||
27 | "nullable": [ | ||
28 | false, | ||
29 | false, | ||
30 | false | ||
31 | ] | ||
32 | }, | ||
33 | "hash": "bb9c6a42084b92c339a85f9b1c094959a49c6b7383f1a0b49df242e2720a9185" | ||
34 | } | ||
diff --git a/.sqlx/query-6a81887a8b44b527ad04c8963d5186b764ec9125d597f9fba566e280bd09d352.json b/.sqlx/query-f179f38584f97842cd41159dd2293fa19e5f1975ea8810526924e77683ba92c4.json index 89f6bbe..322db91 100644 --- a/.sqlx/query-6a81887a8b44b527ad04c8963d5186b764ec9125d597f9fba566e280bd09d352.json +++ b/.sqlx/query-f179f38584f97842cd41159dd2293fa19e5f1975ea8810526924e77683ba92c4.json | |||
@@ -1,36 +1,43 @@ | |||
1 | { | 1 | { |
2 | "db_name": "PostgreSQL", | 2 | "db_name": "PostgreSQL", |
3 | "query": "\n UPDATE devices\n SET mac = $1, broadcast_addr = $2 WHERE id = $3\n RETURNING id, mac, broadcast_addr;\n ", | 3 | "query": "\n UPDATE devices\n SET mac = $1, broadcast_addr = $2, ip = $3 WHERE id = $4\n RETURNING id, mac, broadcast_addr, ip;\n ", |
4 | "describe": { | 4 | "describe": { |
5 | "columns": [ | 5 | "columns": [ |
6 | { | 6 | { |
7 | "ordinal": 0, | 7 | "ordinal": 0, |
8 | "name": "id", | 8 | "name": "id", |
9 | "type_info": "Text" | 9 | "type_info": "Varchar" |
10 | }, | 10 | }, |
11 | { | 11 | { |
12 | "ordinal": 1, | 12 | "ordinal": 1, |
13 | "name": "mac", | 13 | "name": "mac", |
14 | "type_info": "Text" | 14 | "type_info": "Varchar" |
15 | }, | 15 | }, |
16 | { | 16 | { |
17 | "ordinal": 2, | 17 | "ordinal": 2, |
18 | "name": "broadcast_addr", | 18 | "name": "broadcast_addr", |
19 | "type_info": "Text" | 19 | "type_info": "Varchar" |
20 | }, | ||
21 | { | ||
22 | "ordinal": 3, | ||
23 | "name": "ip", | ||
24 | "type_info": "Varchar" | ||
20 | } | 25 | } |
21 | ], | 26 | ], |
22 | "parameters": { | 27 | "parameters": { |
23 | "Left": [ | 28 | "Left": [ |
24 | "Text", | 29 | "Varchar", |
25 | "Text", | 30 | "Varchar", |
31 | "Varchar", | ||
26 | "Text" | 32 | "Text" |
27 | ] | 33 | ] |
28 | }, | 34 | }, |
29 | "nullable": [ | 35 | "nullable": [ |
30 | false, | 36 | false, |
31 | false, | 37 | false, |
38 | false, | ||
32 | false | 39 | false |
33 | ] | 40 | ] |
34 | }, | 41 | }, |
35 | "hash": "6a81887a8b44b527ad04c8963d5186b764ec9125d597f9fba566e280bd09d352" | 42 | "hash": "f179f38584f97842cd41159dd2293fa19e5f1975ea8810526924e77683ba92c4" |
36 | } | 43 | } |
@@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" | |||
19 | 19 | ||
20 | [[package]] | 20 | [[package]] |
21 | name = "ahash" | 21 | name = "ahash" |
22 | version = "0.7.6" | 22 | version = "0.7.7" |
23 | source = "registry+https://github.com/rust-lang/crates.io-index" | 23 | source = "registry+https://github.com/rust-lang/crates.io-index" |
24 | checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" | 24 | checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" |
25 | dependencies = [ | 25 | dependencies = [ |
26 | "getrandom", | 26 | "getrandom", |
27 | "once_cell", | 27 | "once_cell", |
@@ -30,14 +30,15 @@ dependencies = [ | |||
30 | 30 | ||
31 | [[package]] | 31 | [[package]] |
32 | name = "ahash" | 32 | name = "ahash" |
33 | version = "0.8.3" | 33 | version = "0.8.6" |
34 | source = "registry+https://github.com/rust-lang/crates.io-index" | 34 | source = "registry+https://github.com/rust-lang/crates.io-index" |
35 | checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" | 35 | checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" |
36 | dependencies = [ | 36 | dependencies = [ |
37 | "cfg-if", | 37 | "cfg-if", |
38 | "getrandom", | 38 | "getrandom", |
39 | "once_cell", | 39 | "once_cell", |
40 | "version_check", | 40 | "version_check", |
41 | "zerocopy", | ||
41 | ] | 42 | ] |
42 | 43 | ||
43 | [[package]] | 44 | [[package]] |
@@ -89,6 +90,7 @@ checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" | |||
89 | dependencies = [ | 90 | dependencies = [ |
90 | "async-trait", | 91 | "async-trait", |
91 | "axum-core", | 92 | "axum-core", |
93 | "base64 0.21.5", | ||
92 | "bitflags 1.3.2", | 94 | "bitflags 1.3.2", |
93 | "bytes", | 95 | "bytes", |
94 | "futures-util", | 96 | "futures-util", |
@@ -107,8 +109,10 @@ dependencies = [ | |||
107 | "serde_json", | 109 | "serde_json", |
108 | "serde_path_to_error", | 110 | "serde_path_to_error", |
109 | "serde_urlencoded", | 111 | "serde_urlencoded", |
112 | "sha1", | ||
110 | "sync_wrapper", | 113 | "sync_wrapper", |
111 | "tokio", | 114 | "tokio", |
115 | "tokio-tungstenite", | ||
112 | "tower", | 116 | "tower", |
113 | "tower-layer", | 117 | "tower-layer", |
114 | "tower-service", | 118 | "tower-service", |
@@ -132,6 +136,18 @@ dependencies = [ | |||
132 | ] | 136 | ] |
133 | 137 | ||
134 | [[package]] | 138 | [[package]] |
139 | name = "axum-macros" | ||
140 | version = "0.3.8" | ||
141 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
142 | checksum = "cdca6a10ecad987bda04e95606ef85a5417dcaac1a78455242d72e031e2b6b62" | ||
143 | dependencies = [ | ||
144 | "heck", | ||
145 | "proc-macro2", | ||
146 | "quote", | ||
147 | "syn 2.0.38", | ||
148 | ] | ||
149 | |||
150 | [[package]] | ||
135 | name = "backtrace" | 151 | name = "backtrace" |
136 | version = "0.3.69" | 152 | version = "0.3.69" |
137 | source = "registry+https://github.com/rust-lang/crates.io-index" | 153 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -154,9 +170,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" | |||
154 | 170 | ||
155 | [[package]] | 171 | [[package]] |
156 | name = "base64" | 172 | name = "base64" |
157 | version = "0.21.4" | 173 | version = "0.21.5" |
158 | source = "registry+https://github.com/rust-lang/crates.io-index" | 174 | source = "registry+https://github.com/rust-lang/crates.io-index" |
159 | checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" | 175 | checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" |
160 | 176 | ||
161 | [[package]] | 177 | [[package]] |
162 | name = "base64ct" | 178 | name = "base64ct" |
@@ -242,9 +258,9 @@ checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" | |||
242 | 258 | ||
243 | [[package]] | 259 | [[package]] |
244 | name = "cpufeatures" | 260 | name = "cpufeatures" |
245 | version = "0.2.10" | 261 | version = "0.2.11" |
246 | source = "registry+https://github.com/rust-lang/crates.io-index" | 262 | source = "registry+https://github.com/rust-lang/crates.io-index" |
247 | checksum = "3fbc60abd742b35f2492f808e1abbb83d45f72db402e14c55057edc9c7b1e9e4" | 263 | checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" |
248 | dependencies = [ | 264 | dependencies = [ |
249 | "libc", | 265 | "libc", |
250 | ] | 266 | ] |
@@ -260,9 +276,9 @@ dependencies = [ | |||
260 | 276 | ||
261 | [[package]] | 277 | [[package]] |
262 | name = "crc-catalog" | 278 | name = "crc-catalog" |
263 | version = "2.2.0" | 279 | version = "2.3.0" |
264 | source = "registry+https://github.com/rust-lang/crates.io-index" | 280 | source = "registry+https://github.com/rust-lang/crates.io-index" |
265 | checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" | 281 | checksum = "4939f9ed1444bd8c896d37f3090012fa6e7834fe84ef8c9daa166109515732f9" |
266 | 282 | ||
267 | [[package]] | 283 | [[package]] |
268 | name = "crossbeam-queue" | 284 | name = "crossbeam-queue" |
@@ -294,6 +310,25 @@ dependencies = [ | |||
294 | ] | 310 | ] |
295 | 311 | ||
296 | [[package]] | 312 | [[package]] |
313 | name = "dashmap" | ||
314 | version = "5.5.3" | ||
315 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
316 | checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" | ||
317 | dependencies = [ | ||
318 | "cfg-if", | ||
319 | "hashbrown 0.14.2", | ||
320 | "lock_api", | ||
321 | "once_cell", | ||
322 | "parking_lot_core", | ||
323 | ] | ||
324 | |||
325 | [[package]] | ||
326 | name = "data-encoding" | ||
327 | version = "2.4.0" | ||
328 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
329 | checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" | ||
330 | |||
331 | [[package]] | ||
297 | name = "der" | 332 | name = "der" |
298 | version = "0.7.8" | 333 | version = "0.7.8" |
299 | source = "registry+https://github.com/rust-lang/crates.io-index" | 334 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -419,9 +454,9 @@ dependencies = [ | |||
419 | 454 | ||
420 | [[package]] | 455 | [[package]] |
421 | name = "futures-channel" | 456 | name = "futures-channel" |
422 | version = "0.3.28" | 457 | version = "0.3.29" |
423 | source = "registry+https://github.com/rust-lang/crates.io-index" | 458 | source = "registry+https://github.com/rust-lang/crates.io-index" |
424 | checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" | 459 | checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" |
425 | dependencies = [ | 460 | dependencies = [ |
426 | "futures-core", | 461 | "futures-core", |
427 | "futures-sink", | 462 | "futures-sink", |
@@ -429,15 +464,15 @@ dependencies = [ | |||
429 | 464 | ||
430 | [[package]] | 465 | [[package]] |
431 | name = "futures-core" | 466 | name = "futures-core" |
432 | version = "0.3.28" | 467 | version = "0.3.29" |
433 | source = "registry+https://github.com/rust-lang/crates.io-index" | 468 | source = "registry+https://github.com/rust-lang/crates.io-index" |
434 | checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" | 469 | checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" |
435 | 470 | ||
436 | [[package]] | 471 | [[package]] |
437 | name = "futures-executor" | 472 | name = "futures-executor" |
438 | version = "0.3.28" | 473 | version = "0.3.29" |
439 | source = "registry+https://github.com/rust-lang/crates.io-index" | 474 | source = "registry+https://github.com/rust-lang/crates.io-index" |
440 | checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" | 475 | checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" |
441 | dependencies = [ | 476 | dependencies = [ |
442 | "futures-core", | 477 | "futures-core", |
443 | "futures-task", | 478 | "futures-task", |
@@ -457,27 +492,27 @@ dependencies = [ | |||
457 | 492 | ||
458 | [[package]] | 493 | [[package]] |
459 | name = "futures-io" | 494 | name = "futures-io" |
460 | version = "0.3.28" | 495 | version = "0.3.29" |
461 | source = "registry+https://github.com/rust-lang/crates.io-index" | 496 | source = "registry+https://github.com/rust-lang/crates.io-index" |
462 | checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" | 497 | checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" |
463 | 498 | ||
464 | [[package]] | 499 | [[package]] |
465 | name = "futures-sink" | 500 | name = "futures-sink" |
466 | version = "0.3.28" | 501 | version = "0.3.29" |
467 | source = "registry+https://github.com/rust-lang/crates.io-index" | 502 | source = "registry+https://github.com/rust-lang/crates.io-index" |
468 | checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" | 503 | checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" |
469 | 504 | ||
470 | [[package]] | 505 | [[package]] |
471 | name = "futures-task" | 506 | name = "futures-task" |
472 | version = "0.3.28" | 507 | version = "0.3.29" |
473 | source = "registry+https://github.com/rust-lang/crates.io-index" | 508 | source = "registry+https://github.com/rust-lang/crates.io-index" |
474 | checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" | 509 | checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" |
475 | 510 | ||
476 | [[package]] | 511 | [[package]] |
477 | name = "futures-util" | 512 | name = "futures-util" |
478 | version = "0.3.28" | 513 | version = "0.3.29" |
479 | source = "registry+https://github.com/rust-lang/crates.io-index" | 514 | source = "registry+https://github.com/rust-lang/crates.io-index" |
480 | checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" | 515 | checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" |
481 | dependencies = [ | 516 | dependencies = [ |
482 | "futures-core", | 517 | "futures-core", |
483 | "futures-io", | 518 | "futures-io", |
@@ -517,12 +552,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
517 | checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" | 552 | checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" |
518 | 553 | ||
519 | [[package]] | 554 | [[package]] |
555 | name = "glob" | ||
556 | version = "0.3.1" | ||
557 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
558 | checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" | ||
559 | |||
560 | [[package]] | ||
520 | name = "hashbrown" | 561 | name = "hashbrown" |
521 | version = "0.12.3" | 562 | version = "0.12.3" |
522 | source = "registry+https://github.com/rust-lang/crates.io-index" | 563 | source = "registry+https://github.com/rust-lang/crates.io-index" |
523 | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" | 564 | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" |
524 | dependencies = [ | 565 | dependencies = [ |
525 | "ahash 0.7.6", | 566 | "ahash 0.7.7", |
526 | ] | 567 | ] |
527 | 568 | ||
528 | [[package]] | 569 | [[package]] |
@@ -531,7 +572,7 @@ version = "0.14.2" | |||
531 | source = "registry+https://github.com/rust-lang/crates.io-index" | 572 | source = "registry+https://github.com/rust-lang/crates.io-index" |
532 | checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" | 573 | checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" |
533 | dependencies = [ | 574 | dependencies = [ |
534 | "ahash 0.8.3", | 575 | "ahash 0.8.6", |
535 | "allocator-api2", | 576 | "allocator-api2", |
536 | ] | 577 | ] |
537 | 578 | ||
@@ -550,7 +591,7 @@ version = "0.3.9" | |||
550 | source = "registry+https://github.com/rust-lang/crates.io-index" | 591 | source = "registry+https://github.com/rust-lang/crates.io-index" |
551 | checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" | 592 | checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" |
552 | dependencies = [ | 593 | dependencies = [ |
553 | "base64 0.21.4", | 594 | "base64 0.21.5", |
554 | "bytes", | 595 | "bytes", |
555 | "headers-core", | 596 | "headers-core", |
556 | "http", | 597 | "http", |
@@ -685,9 +726,9 @@ dependencies = [ | |||
685 | 726 | ||
686 | [[package]] | 727 | [[package]] |
687 | name = "indexmap" | 728 | name = "indexmap" |
688 | version = "2.0.2" | 729 | version = "2.1.0" |
689 | source = "registry+https://github.com/rust-lang/crates.io-index" | 730 | source = "registry+https://github.com/rust-lang/crates.io-index" |
690 | checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" | 731 | checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" |
691 | dependencies = [ | 732 | dependencies = [ |
692 | "equivalent", | 733 | "equivalent", |
693 | "hashbrown 0.14.2", | 734 | "hashbrown 0.14.2", |
@@ -833,9 +874,9 @@ dependencies = [ | |||
833 | 874 | ||
834 | [[package]] | 875 | [[package]] |
835 | name = "mio" | 876 | name = "mio" |
836 | version = "0.8.8" | 877 | version = "0.8.9" |
837 | source = "registry+https://github.com/rust-lang/crates.io-index" | 878 | source = "registry+https://github.com/rust-lang/crates.io-index" |
838 | checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" | 879 | checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" |
839 | dependencies = [ | 880 | dependencies = [ |
840 | "libc", | 881 | "libc", |
841 | "wasi", | 882 | "wasi", |
@@ -843,6 +884,12 @@ dependencies = [ | |||
843 | ] | 884 | ] |
844 | 885 | ||
845 | [[package]] | 886 | [[package]] |
887 | name = "no-std-net" | ||
888 | version = "0.6.0" | ||
889 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
890 | checksum = "43794a0ace135be66a25d3ae77d41b91615fb68ae937f904090203e81f755b65" | ||
891 | |||
892 | [[package]] | ||
846 | name = "nom" | 893 | name = "nom" |
847 | version = "7.1.3" | 894 | version = "7.1.3" |
848 | source = "registry+https://github.com/rust-lang/crates.io-index" | 895 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -978,7 +1025,7 @@ checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" | |||
978 | dependencies = [ | 1025 | dependencies = [ |
979 | "cfg-if", | 1026 | "cfg-if", |
980 | "libc", | 1027 | "libc", |
981 | "redox_syscall 0.4.1", | 1028 | "redox_syscall", |
982 | "smallvec", | 1029 | "smallvec", |
983 | "windows-targets", | 1030 | "windows-targets", |
984 | ] | 1031 | ] |
@@ -1012,9 +1059,9 @@ checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" | |||
1012 | 1059 | ||
1013 | [[package]] | 1060 | [[package]] |
1014 | name = "pest" | 1061 | name = "pest" |
1015 | version = "2.7.4" | 1062 | version = "2.7.5" |
1016 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1063 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1017 | checksum = "c022f1e7b65d6a24c0dbbd5fb344c66881bc01f3e5ae74a1c8100f2f985d98a4" | 1064 | checksum = "ae9cee2a55a544be8b89dc6848072af97a20f2422603c10865be2a42b580fff5" |
1018 | dependencies = [ | 1065 | dependencies = [ |
1019 | "memchr", | 1066 | "memchr", |
1020 | "thiserror", | 1067 | "thiserror", |
@@ -1023,9 +1070,9 @@ dependencies = [ | |||
1023 | 1070 | ||
1024 | [[package]] | 1071 | [[package]] |
1025 | name = "pest_derive" | 1072 | name = "pest_derive" |
1026 | version = "2.7.4" | 1073 | version = "2.7.5" |
1027 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1074 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1028 | checksum = "35513f630d46400a977c4cb58f78e1bfbe01434316e60c37d27b9ad6139c66d8" | 1075 | checksum = "81d78524685f5ef2a3b3bd1cafbc9fcabb036253d9b1463e726a91cd16e2dfc2" |
1029 | dependencies = [ | 1076 | dependencies = [ |
1030 | "pest", | 1077 | "pest", |
1031 | "pest_generator", | 1078 | "pest_generator", |
@@ -1033,9 +1080,9 @@ dependencies = [ | |||
1033 | 1080 | ||
1034 | [[package]] | 1081 | [[package]] |
1035 | name = "pest_generator" | 1082 | name = "pest_generator" |
1036 | version = "2.7.4" | 1083 | version = "2.7.5" |
1037 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1084 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1038 | checksum = "bc9fc1b9e7057baba189b5c626e2d6f40681ae5b6eb064dc7c7834101ec8123a" | 1085 | checksum = "68bd1206e71118b5356dae5ddc61c8b11e28b09ef6a31acbd15ea48a28e0c227" |
1039 | dependencies = [ | 1086 | dependencies = [ |
1040 | "pest", | 1087 | "pest", |
1041 | "pest_meta", | 1088 | "pest_meta", |
@@ -1046,9 +1093,9 @@ dependencies = [ | |||
1046 | 1093 | ||
1047 | [[package]] | 1094 | [[package]] |
1048 | name = "pest_meta" | 1095 | name = "pest_meta" |
1049 | version = "2.7.4" | 1096 | version = "2.7.5" |
1050 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1097 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1051 | checksum = "1df74e9e7ec4053ceb980e7c0c8bd3594e977fde1af91daba9c928e8e8c6708d" | 1098 | checksum = "7c747191d4ad9e4a4ab9c8798f1e82a39affe7ef9648390b7e5548d18e099de6" |
1052 | dependencies = [ | 1099 | dependencies = [ |
1053 | "once_cell", | 1100 | "once_cell", |
1054 | "pest", | 1101 | "pest", |
@@ -1115,6 +1162,48 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
1115 | checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" | 1162 | checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" |
1116 | 1163 | ||
1117 | [[package]] | 1164 | [[package]] |
1165 | name = "pnet_base" | ||
1166 | version = "0.33.0" | ||
1167 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
1168 | checksum = "872e46346144ebf35219ccaa64b1dffacd9c6f188cd7d012bd6977a2a838f42e" | ||
1169 | dependencies = [ | ||
1170 | "no-std-net", | ||
1171 | ] | ||
1172 | |||
1173 | [[package]] | ||
1174 | name = "pnet_macros" | ||
1175 | version = "0.33.0" | ||
1176 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
1177 | checksum = "2a780e80005c2e463ec25a6e9f928630049a10b43945fea83207207d4a7606f4" | ||
1178 | dependencies = [ | ||
1179 | "proc-macro2", | ||
1180 | "quote", | ||
1181 | "regex", | ||
1182 | "syn 1.0.109", | ||
1183 | ] | ||
1184 | |||
1185 | [[package]] | ||
1186 | name = "pnet_macros_support" | ||
1187 | version = "0.33.0" | ||
1188 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
1189 | checksum = "e6d932134f32efd7834eb8b16d42418dac87086347d1bc7d142370ef078582bc" | ||
1190 | dependencies = [ | ||
1191 | "pnet_base", | ||
1192 | ] | ||
1193 | |||
1194 | [[package]] | ||
1195 | name = "pnet_packet" | ||
1196 | version = "0.33.0" | ||
1197 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
1198 | checksum = "8bde678bbd85cb1c2d99dc9fc596e57f03aa725f84f3168b0eaf33eeccb41706" | ||
1199 | dependencies = [ | ||
1200 | "glob", | ||
1201 | "pnet_base", | ||
1202 | "pnet_macros", | ||
1203 | "pnet_macros_support", | ||
1204 | ] | ||
1205 | |||
1206 | [[package]] | ||
1118 | name = "powerfmt" | 1207 | name = "powerfmt" |
1119 | version = "0.2.0" | 1208 | version = "0.2.0" |
1120 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1209 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -1176,15 +1265,6 @@ dependencies = [ | |||
1176 | 1265 | ||
1177 | [[package]] | 1266 | [[package]] |
1178 | name = "redox_syscall" | 1267 | name = "redox_syscall" |
1179 | version = "0.3.5" | ||
1180 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
1181 | checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" | ||
1182 | dependencies = [ | ||
1183 | "bitflags 1.3.2", | ||
1184 | ] | ||
1185 | |||
1186 | [[package]] | ||
1187 | name = "redox_syscall" | ||
1188 | version = "0.4.1" | 1268 | version = "0.4.1" |
1189 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1269 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1190 | checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" | 1270 | checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" |
@@ -1249,16 +1329,14 @@ dependencies = [ | |||
1249 | 1329 | ||
1250 | [[package]] | 1330 | [[package]] |
1251 | name = "rsa" | 1331 | name = "rsa" |
1252 | version = "0.9.2" | 1332 | version = "0.9.3" |
1253 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1333 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1254 | checksum = "6ab43bb47d23c1a631b4b680199a45255dce26fa9ab2fa902581f624ff13e6a8" | 1334 | checksum = "86ef35bf3e7fe15a53c4ab08a998e42271eab13eb0db224126bc7bc4c4bad96d" |
1255 | dependencies = [ | 1335 | dependencies = [ |
1256 | "byteorder", | ||
1257 | "const-oid", | 1336 | "const-oid", |
1258 | "digest", | 1337 | "digest", |
1259 | "num-bigint-dig", | 1338 | "num-bigint-dig", |
1260 | "num-integer", | 1339 | "num-integer", |
1261 | "num-iter", | ||
1262 | "num-traits", | 1340 | "num-traits", |
1263 | "pkcs1", | 1341 | "pkcs1", |
1264 | "pkcs8", | 1342 | "pkcs8", |
@@ -1287,9 +1365,9 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" | |||
1287 | 1365 | ||
1288 | [[package]] | 1366 | [[package]] |
1289 | name = "rustix" | 1367 | name = "rustix" |
1290 | version = "0.38.20" | 1368 | version = "0.38.21" |
1291 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1369 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1292 | checksum = "67ce50cb2e16c2903e30d1cbccfd8387a74b9d4c938b6a4c5ec6cc7556f7a8a0" | 1370 | checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" |
1293 | dependencies = [ | 1371 | dependencies = [ |
1294 | "bitflags 2.4.1", | 1372 | "bitflags 2.4.1", |
1295 | "errno", | 1373 | "errno", |
@@ -1318,18 +1396,18 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" | |||
1318 | 1396 | ||
1319 | [[package]] | 1397 | [[package]] |
1320 | name = "serde" | 1398 | name = "serde" |
1321 | version = "1.0.189" | 1399 | version = "1.0.190" |
1322 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1400 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1323 | checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537" | 1401 | checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" |
1324 | dependencies = [ | 1402 | dependencies = [ |
1325 | "serde_derive", | 1403 | "serde_derive", |
1326 | ] | 1404 | ] |
1327 | 1405 | ||
1328 | [[package]] | 1406 | [[package]] |
1329 | name = "serde_derive" | 1407 | name = "serde_derive" |
1330 | version = "1.0.189" | 1408 | version = "1.0.190" |
1331 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1409 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1332 | checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" | 1410 | checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" |
1333 | dependencies = [ | 1411 | dependencies = [ |
1334 | "proc-macro2", | 1412 | "proc-macro2", |
1335 | "quote", | 1413 | "quote", |
@@ -1338,9 +1416,9 @@ dependencies = [ | |||
1338 | 1416 | ||
1339 | [[package]] | 1417 | [[package]] |
1340 | name = "serde_json" | 1418 | name = "serde_json" |
1341 | version = "1.0.107" | 1419 | version = "1.0.108" |
1342 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1420 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1343 | checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" | 1421 | checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" |
1344 | dependencies = [ | 1422 | dependencies = [ |
1345 | "itoa", | 1423 | "itoa", |
1346 | "ryu", | 1424 | "ryu", |
@@ -1500,7 +1578,7 @@ version = "0.7.2" | |||
1500 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1578 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1501 | checksum = "8d6753e460c998bbd4cd8c6f0ed9a64346fcca0723d6e75e52fdc351c5d2169d" | 1579 | checksum = "8d6753e460c998bbd4cd8c6f0ed9a64346fcca0723d6e75e52fdc351c5d2169d" |
1502 | dependencies = [ | 1580 | dependencies = [ |
1503 | "ahash 0.8.3", | 1581 | "ahash 0.8.6", |
1504 | "atoi", | 1582 | "atoi", |
1505 | "byteorder", | 1583 | "byteorder", |
1506 | "bytes", | 1584 | "bytes", |
@@ -1580,7 +1658,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
1580 | checksum = "864b869fdf56263f4c95c45483191ea0af340f9f3e3e7b4d57a61c7c87a970db" | 1658 | checksum = "864b869fdf56263f4c95c45483191ea0af340f9f3e3e7b4d57a61c7c87a970db" |
1581 | dependencies = [ | 1659 | dependencies = [ |
1582 | "atoi", | 1660 | "atoi", |
1583 | "base64 0.21.4", | 1661 | "base64 0.21.5", |
1584 | "bitflags 2.4.1", | 1662 | "bitflags 2.4.1", |
1585 | "byteorder", | 1663 | "byteorder", |
1586 | "bytes", | 1664 | "bytes", |
@@ -1622,7 +1700,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
1622 | checksum = "eb7ae0e6a97fb3ba33b23ac2671a5ce6e3cabe003f451abd5a56e7951d975624" | 1700 | checksum = "eb7ae0e6a97fb3ba33b23ac2671a5ce6e3cabe003f451abd5a56e7951d975624" |
1623 | dependencies = [ | 1701 | dependencies = [ |
1624 | "atoi", | 1702 | "atoi", |
1625 | "base64 0.21.4", | 1703 | "base64 0.21.5", |
1626 | "bitflags 2.4.1", | 1704 | "bitflags 2.4.1", |
1627 | "byteorder", | 1705 | "byteorder", |
1628 | "crc", | 1706 | "crc", |
@@ -1694,6 +1772,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
1694 | checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" | 1772 | checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" |
1695 | 1773 | ||
1696 | [[package]] | 1774 | [[package]] |
1775 | name = "surge-ping" | ||
1776 | version = "0.8.0" | ||
1777 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
1778 | checksum = "af341b2be485d647b5dc4cfb2da99efac35b5c95748a08fb7233480fedc5ead3" | ||
1779 | dependencies = [ | ||
1780 | "hex", | ||
1781 | "parking_lot", | ||
1782 | "pnet_packet", | ||
1783 | "rand", | ||
1784 | "socket2 0.5.5", | ||
1785 | "thiserror", | ||
1786 | "tokio", | ||
1787 | "tracing", | ||
1788 | ] | ||
1789 | |||
1790 | [[package]] | ||
1697 | name = "syn" | 1791 | name = "syn" |
1698 | version = "1.0.109" | 1792 | version = "1.0.109" |
1699 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1793 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -1723,13 +1817,13 @@ checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" | |||
1723 | 1817 | ||
1724 | [[package]] | 1818 | [[package]] |
1725 | name = "tempfile" | 1819 | name = "tempfile" |
1726 | version = "3.8.0" | 1820 | version = "3.8.1" |
1727 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1821 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1728 | checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" | 1822 | checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" |
1729 | dependencies = [ | 1823 | dependencies = [ |
1730 | "cfg-if", | 1824 | "cfg-if", |
1731 | "fastrand", | 1825 | "fastrand", |
1732 | "redox_syscall 0.3.5", | 1826 | "redox_syscall", |
1733 | "rustix", | 1827 | "rustix", |
1734 | "windows-sys", | 1828 | "windows-sys", |
1735 | ] | 1829 | ] |
@@ -1850,6 +1944,18 @@ dependencies = [ | |||
1850 | ] | 1944 | ] |
1851 | 1945 | ||
1852 | [[package]] | 1946 | [[package]] |
1947 | name = "tokio-tungstenite" | ||
1948 | version = "0.20.1" | ||
1949 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
1950 | checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" | ||
1951 | dependencies = [ | ||
1952 | "futures-util", | ||
1953 | "log", | ||
1954 | "tokio", | ||
1955 | "tungstenite", | ||
1956 | ] | ||
1957 | |||
1958 | [[package]] | ||
1853 | name = "toml" | 1959 | name = "toml" |
1854 | version = "0.5.11" | 1960 | version = "0.5.11" |
1855 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1961 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -1921,12 +2027,12 @@ dependencies = [ | |||
1921 | 2027 | ||
1922 | [[package]] | 2028 | [[package]] |
1923 | name = "tracing-log" | 2029 | name = "tracing-log" |
1924 | version = "0.1.3" | 2030 | version = "0.1.4" |
1925 | source = "registry+https://github.com/rust-lang/crates.io-index" | 2031 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1926 | checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" | 2032 | checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2" |
1927 | dependencies = [ | 2033 | dependencies = [ |
1928 | "lazy_static", | ||
1929 | "log", | 2034 | "log", |
2035 | "once_cell", | ||
1930 | "tracing-core", | 2036 | "tracing-core", |
1931 | ] | 2037 | ] |
1932 | 2038 | ||
@@ -1956,6 +2062,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
1956 | checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" | 2062 | checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" |
1957 | 2063 | ||
1958 | [[package]] | 2064 | [[package]] |
2065 | name = "tungstenite" | ||
2066 | version = "0.20.1" | ||
2067 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
2068 | checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" | ||
2069 | dependencies = [ | ||
2070 | "byteorder", | ||
2071 | "bytes", | ||
2072 | "data-encoding", | ||
2073 | "http", | ||
2074 | "httparse", | ||
2075 | "log", | ||
2076 | "rand", | ||
2077 | "sha1", | ||
2078 | "thiserror", | ||
2079 | "url", | ||
2080 | "utf-8", | ||
2081 | ] | ||
2082 | |||
2083 | [[package]] | ||
1959 | name = "typenum" | 2084 | name = "typenum" |
1960 | version = "1.17.0" | 2085 | version = "1.17.0" |
1961 | source = "registry+https://github.com/rust-lang/crates.io-index" | 2086 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -2012,6 +2137,22 @@ dependencies = [ | |||
2012 | ] | 2137 | ] |
2013 | 2138 | ||
2014 | [[package]] | 2139 | [[package]] |
2140 | name = "utf-8" | ||
2141 | version = "0.7.6" | ||
2142 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
2143 | checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" | ||
2144 | |||
2145 | [[package]] | ||
2146 | name = "uuid" | ||
2147 | version = "1.5.0" | ||
2148 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
2149 | checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" | ||
2150 | dependencies = [ | ||
2151 | "getrandom", | ||
2152 | "rand", | ||
2153 | ] | ||
2154 | |||
2155 | [[package]] | ||
2015 | name = "valuable" | 2156 | name = "valuable" |
2016 | version = "0.1.0" | 2157 | version = "0.1.0" |
2017 | source = "registry+https://github.com/rust-lang/crates.io-index" | 2158 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -2046,18 +2187,22 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" | |||
2046 | 2187 | ||
2047 | [[package]] | 2188 | [[package]] |
2048 | name = "webol" | 2189 | name = "webol" |
2049 | version = "0.1.0" | 2190 | version = "0.2.0" |
2050 | dependencies = [ | 2191 | dependencies = [ |
2051 | "axum", | 2192 | "axum", |
2193 | "axum-macros", | ||
2052 | "config", | 2194 | "config", |
2195 | "dashmap", | ||
2053 | "once_cell", | 2196 | "once_cell", |
2054 | "serde", | 2197 | "serde", |
2055 | "serde_json", | 2198 | "serde_json", |
2056 | "sqlx", | 2199 | "sqlx", |
2200 | "surge-ping", | ||
2057 | "time", | 2201 | "time", |
2058 | "tokio", | 2202 | "tokio", |
2059 | "tracing", | 2203 | "tracing", |
2060 | "tracing-subscriber", | 2204 | "tracing-subscriber", |
2205 | "uuid", | ||
2061 | ] | 2206 | ] |
2062 | 2207 | ||
2063 | [[package]] | 2208 | [[package]] |
@@ -2164,6 +2309,26 @@ dependencies = [ | |||
2164 | ] | 2309 | ] |
2165 | 2310 | ||
2166 | [[package]] | 2311 | [[package]] |
2312 | name = "zerocopy" | ||
2313 | version = "0.7.23" | ||
2314 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
2315 | checksum = "e50cbb27c30666a6108abd6bc7577556265b44f243e2be89a8bc4e07a528c107" | ||
2316 | dependencies = [ | ||
2317 | "zerocopy-derive", | ||
2318 | ] | ||
2319 | |||
2320 | [[package]] | ||
2321 | name = "zerocopy-derive" | ||
2322 | version = "0.7.23" | ||
2323 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
2324 | checksum = "a25f293fe55f0a48e7010d65552bb63704f6ceb55a1a385da10d41d8f78e4a3d" | ||
2325 | dependencies = [ | ||
2326 | "proc-macro2", | ||
2327 | "quote", | ||
2328 | "syn 2.0.38", | ||
2329 | ] | ||
2330 | |||
2331 | [[package]] | ||
2167 | name = "zeroize" | 2332 | name = "zeroize" |
2168 | version = "1.6.0" | 2333 | version = "1.6.0" |
2169 | source = "registry+https://github.com/rust-lang/crates.io-index" | 2334 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -1,18 +1,22 @@ | |||
1 | [package] | 1 | [package] |
2 | name = "webol" | 2 | name = "webol" |
3 | version = "0.1.0" | 3 | version = "0.2.0" |
4 | edition = "2021" | 4 | edition = "2021" |
5 | 5 | ||
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html |
7 | 7 | ||
8 | [dependencies] | 8 | [dependencies] |
9 | axum = { version = "0.6.20", features = ["headers"] } | 9 | axum = { version = "0.6.20", features = ["headers", "ws"] } |
10 | tokio = { version = "1.32.0", features = ["macros", "rt-multi-thread"] } | 10 | tokio = { version = "1.33.0", features = ["macros", "rt-multi-thread"] } |
11 | tracing = "0.1.37" | 11 | tracing = "0.1.40" |
12 | tracing-subscriber = { version = "0.3.17", features = ["env-filter", "local-time", "time"] } | 12 | tracing-subscriber = { version = "0.3.17", features = ["env-filter", "local-time", "time"] } |
13 | time = { version = "0.3.29", features = ["macros"] } | 13 | time = { version = "0.3.30", features = ["macros"] } |
14 | serde = { version = "1.0.188", features = ["derive"] } | 14 | serde = { version = "1.0.190", features = ["derive"] } |
15 | serde_json = "1.0.107" | 15 | serde_json = "1.0.107" |
16 | config = "0.13.3" | 16 | config = "0.13.3" |
17 | once_cell = "1.18.0" | 17 | once_cell = "1.18.0" |
18 | sqlx = { version = "0.7.1", features = ["postgres", "runtime-tokio"]} | 18 | sqlx = { version = "0.7.2", features = ["postgres", "runtime-tokio"]} |
19 | surge-ping = "0.8.0" | ||
20 | axum-macros = "0.3.8" | ||
21 | uuid = { version = "1.5.0", features = ["v4", "fast-rng"] } | ||
22 | dashmap = "5.5.3" | ||
@@ -0,0 +1,21 @@ | |||
1 | MIT License | ||
2 | |||
3 | Copyright (c) 2023 FxQnLr | ||
4 | |||
5 | Permission is hereby granted, free of charge, to any person obtaining a copy | ||
6 | of this software and associated documentation files (the "Software"), to deal | ||
7 | in the Software without restriction, including without limitation the rights | ||
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
9 | copies of the Software, and to permit persons to whom the Software is | ||
10 | furnished to do so, subject to the following conditions: | ||
11 | |||
12 | The above copyright notice and this permission notice shall be included in all | ||
13 | copies or substantial portions of the Software. | ||
14 | |||
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
21 | SOFTWARE. | ||
@@ -7,3 +7,5 @@ WEBOL_APIKEY: `String` | |||
7 | WEBOL_SERVERADDR: `Option<String>` (0.0.0.0:7229) | 7 | WEBOL_SERVERADDR: `Option<String>` (0.0.0.0:7229) |
8 | 8 | ||
9 | WEBOL_BINDADDR: `Option<String>` (0.0.0.0:1111) | 9 | WEBOL_BINDADDR: `Option<String>` (0.0.0.0:1111) |
10 | |||
11 | WEBOL_PINGTIMEOUT: `Option<i64>` (10) \ No newline at end of file | ||
diff --git a/migrations/20231009123228_devices.sql b/migrations/20231009123228_devices.sql index 9d0c7ca..b911b19 100644 --- a/migrations/20231009123228_devices.sql +++ b/migrations/20231009123228_devices.sql | |||
@@ -1,7 +1,8 @@ | |||
1 | -- Add migration script here | 1 | -- Add migration script here |
2 | CREATE TABLE IF NOT EXISTS "devices" | 2 | CREATE TABLE IF NOT EXISTS "devices" |
3 | ( | 3 | ( |
4 | "id" TEXT PRIMARY KEY NOT NULL, | 4 | "id" VARCHAR(255) PRIMARY KEY NOT NULL, |
5 | "mac" TEXT NOT NULL, | 5 | "mac" VARCHAR(17) NOT NULL, |
6 | "broadcast_addr" TEXT NOT NULL | 6 | "broadcast_addr" VARCHAR(39) NOT NULL, |
7 | "ip" VARCHAR(39) NOT NULL | ||
7 | ) | 8 | ) |
diff --git a/src/auth.rs b/src/auth.rs index 0fffa60..e4b1c2f 100644 --- a/src/auth.rs +++ b/src/auth.rs | |||
@@ -1,8 +1,8 @@ | |||
1 | use std::error::Error; | ||
2 | use axum::headers::HeaderValue; | 1 | use axum::headers::HeaderValue; |
3 | use axum::http::StatusCode; | 2 | use axum::http::StatusCode; |
3 | use axum::http::header::ToStrError; | ||
4 | use tracing::{debug, error, trace}; | 4 | use tracing::{debug, error, trace}; |
5 | use crate::auth::AuthError::{MissingSecret, ServerError, WrongSecret}; | 5 | use crate::auth::AuthError::{MissingSecret, WrongSecret}; |
6 | use crate::config::SETTINGS; | 6 | use crate::config::SETTINGS; |
7 | 7 | ||
8 | pub fn auth(secret: Option<&HeaderValue>) -> Result<bool, AuthError> { | 8 | pub fn auth(secret: Option<&HeaderValue>) -> Result<bool, AuthError> { |
@@ -11,8 +11,8 @@ pub fn auth(secret: Option<&HeaderValue>) -> Result<bool, AuthError> { | |||
11 | trace!("value exists"); | 11 | trace!("value exists"); |
12 | let key = SETTINGS | 12 | let key = SETTINGS |
13 | .get_string("apikey") | 13 | .get_string("apikey") |
14 | .map_err(|err| ServerError(Box::new(err)))?; | 14 | .map_err(AuthError::Config)?; |
15 | if value.to_str().map_err(|err| ServerError(Box::new(err)))? == key.as_str() { | 15 | if value.to_str().map_err(AuthError::HeaderToStr)? == key.as_str() { |
16 | debug!("successful auth"); | 16 | debug!("successful auth"); |
17 | Ok(true) | 17 | Ok(true) |
18 | } else { | 18 | } else { |
@@ -29,15 +29,20 @@ pub fn auth(secret: Option<&HeaderValue>) -> Result<bool, AuthError> { | |||
29 | pub enum AuthError { | 29 | pub enum AuthError { |
30 | WrongSecret, | 30 | WrongSecret, |
31 | MissingSecret, | 31 | MissingSecret, |
32 | ServerError(Box<dyn Error>), | 32 | Config(config::ConfigError), |
33 | HeaderToStr(ToStrError) | ||
33 | } | 34 | } |
34 | 35 | ||
35 | impl AuthError { | 36 | impl AuthError { |
36 | pub fn get(self) -> (StatusCode, &'static str) { | 37 | pub fn get(self) -> (StatusCode, &'static str) { |
37 | match self { | 38 | match self { |
38 | AuthError::WrongSecret => (StatusCode::UNAUTHORIZED, "Wrong credentials"), | 39 | Self::WrongSecret => (StatusCode::UNAUTHORIZED, "Wrong credentials"), |
39 | AuthError::MissingSecret => (StatusCode::BAD_REQUEST, "Missing credentials"), | 40 | Self::MissingSecret => (StatusCode::BAD_REQUEST, "Missing credentials"), |
40 | AuthError::ServerError(err) => { | 41 | Self::Config(err) => { |
42 | error!("server error: {}", err.to_string()); | ||
43 | (StatusCode::INTERNAL_SERVER_ERROR, "Server Error") | ||
44 | }, | ||
45 | Self::HeaderToStr(err) => { | ||
41 | error!("server error: {}", err.to_string()); | 46 | error!("server error: {}", err.to_string()); |
42 | (StatusCode::INTERNAL_SERVER_ERROR, "Server Error") | 47 | (StatusCode::INTERNAL_SERVER_ERROR, "Server Error") |
43 | }, | 48 | }, |
@@ -8,11 +8,12 @@ use tracing::{debug, info}; | |||
8 | #[cfg(not(debug_assertions))] | 8 | #[cfg(not(debug_assertions))] |
9 | use crate::config::SETTINGS; | 9 | use crate::config::SETTINGS; |
10 | 10 | ||
11 | #[derive(Serialize)] | 11 | #[derive(Serialize, Debug)] |
12 | pub struct Device { | 12 | pub struct Device { |
13 | pub id: String, | 13 | pub id: String, |
14 | pub mac: String, | 14 | pub mac: String, |
15 | pub broadcast_addr: String | 15 | pub broadcast_addr: String, |
16 | pub ip: String | ||
16 | } | 17 | } |
17 | 18 | ||
18 | pub async fn init_db_pool() -> PgPool { | 19 | pub async fn init_db_pool() -> PgPool { |
diff --git a/src/error.rs b/src/error.rs index db2fc86..5b82534 100644 --- a/src/error.rs +++ b/src/error.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | use std::error::Error; | 1 | use std::io; |
2 | use axum::http::StatusCode; | 2 | use axum::http::StatusCode; |
3 | use axum::Json; | 3 | use axum::Json; |
4 | use axum::response::{IntoResponse, Response}; | 4 | use axum::response::{IntoResponse, Response}; |
@@ -8,25 +8,41 @@ use crate::auth::AuthError; | |||
8 | 8 | ||
9 | #[derive(Debug)] | 9 | #[derive(Debug)] |
10 | pub enum WebolError { | 10 | pub enum WebolError { |
11 | Auth(AuthError), | ||
12 | Generic, | 11 | Generic, |
13 | Server(Box<dyn Error>), | 12 | Auth(AuthError), |
13 | DB(sqlx::Error), | ||
14 | IpParse(<std::net::IpAddr as std::str::FromStr>::Err), | ||
15 | BufferParse(std::num::ParseIntError), | ||
16 | Broadcast(io::Error), | ||
14 | } | 17 | } |
15 | 18 | ||
16 | impl IntoResponse for WebolError { | 19 | impl IntoResponse for WebolError { |
17 | fn into_response(self) -> Response { | 20 | fn into_response(self) -> Response { |
18 | let (status, error_message) = match self { | 21 | let (status, error_message) = match self { |
19 | WebolError::Auth(err) => err.get(), | 22 | Self::Auth(err) => { |
20 | WebolError::Generic => (StatusCode::INTERNAL_SERVER_ERROR, ""), | 23 | err.get() |
21 | WebolError::Server(err) => { | 24 | }, |
25 | Self::Generic => (StatusCode::INTERNAL_SERVER_ERROR, ""), | ||
26 | Self::IpParse(err) => { | ||
27 | error!("server error: {}", err.to_string()); | ||
28 | (StatusCode::INTERNAL_SERVER_ERROR, "Server Error") | ||
29 | }, | ||
30 | Self::DB(err) => { | ||
31 | error!("server error: {}", err.to_string()); | ||
32 | (StatusCode::INTERNAL_SERVER_ERROR, "Server Error") | ||
33 | }, | ||
34 | Self::Broadcast(err) => { | ||
35 | error!("server error: {}", err.to_string()); | ||
36 | (StatusCode::INTERNAL_SERVER_ERROR, "Server Error") | ||
37 | }, | ||
38 | Self::BufferParse(err) => { | ||
22 | error!("server error: {}", err.to_string()); | 39 | error!("server error: {}", err.to_string()); |
23 | (StatusCode::INTERNAL_SERVER_ERROR, "Server Error") | 40 | (StatusCode::INTERNAL_SERVER_ERROR, "Server Error") |
24 | }, | 41 | }, |
25 | |||
26 | }; | 42 | }; |
27 | let body = Json(json!({ | 43 | let body = Json(json!({ |
28 | "error": error_message, | 44 | "error": error_message, |
29 | })); | 45 | })); |
30 | (status, body).into_response() | 46 | (status, body).into_response() |
31 | } | 47 | } |
32 | } | 48 | } \ No newline at end of file |
diff --git a/src/main.rs b/src/main.rs index ce12cf6..e96b736 100644 --- a/src/main.rs +++ b/src/main.rs | |||
@@ -2,14 +2,18 @@ use std::env; | |||
2 | use std::sync::Arc; | 2 | use std::sync::Arc; |
3 | use axum::{Router, routing::post}; | 3 | use axum::{Router, routing::post}; |
4 | use axum::routing::{get, put}; | 4 | use axum::routing::{get, put}; |
5 | use dashmap::DashMap; | ||
5 | use sqlx::PgPool; | 6 | use sqlx::PgPool; |
6 | use time::util::local_offset; | 7 | use time::util::local_offset; |
8 | use tokio::sync::broadcast::{channel, Sender}; | ||
7 | use tracing::{info, level_filters::LevelFilter}; | 9 | use tracing::{info, level_filters::LevelFilter}; |
8 | use tracing_subscriber::{EnvFilter, fmt::{self, time::LocalTime}, prelude::*}; | 10 | use tracing_subscriber::{EnvFilter, fmt::{self, time::LocalTime}, prelude::*}; |
9 | use crate::config::SETTINGS; | 11 | use crate::config::SETTINGS; |
10 | use crate::db::init_db_pool; | 12 | use crate::db::init_db_pool; |
11 | use crate::routes::device::{get_device, post_device, put_device}; | 13 | use crate::routes::device::{get_device, post_device, put_device}; |
12 | use crate::routes::start::start; | 14 | use crate::routes::start::start; |
15 | use crate::routes::status::status; | ||
16 | use crate::services::ping::{BroadcastCommands, PingMap}; | ||
13 | 17 | ||
14 | mod auth; | 18 | mod auth; |
15 | mod config; | 19 | mod config; |
@@ -17,6 +21,7 @@ mod routes; | |||
17 | mod wol; | 21 | mod wol; |
18 | mod db; | 22 | mod db; |
19 | mod error; | 23 | mod error; |
24 | mod services; | ||
20 | 25 | ||
21 | #[tokio::main] | 26 | #[tokio::main] |
22 | async fn main() { | 27 | async fn main() { |
@@ -43,13 +48,18 @@ async fn main() { | |||
43 | let db = init_db_pool().await; | 48 | let db = init_db_pool().await; |
44 | sqlx::migrate!().run(&db).await.unwrap(); | 49 | sqlx::migrate!().run(&db).await.unwrap(); |
45 | 50 | ||
46 | let shared_state = Arc::new(AppState { db }); | 51 | let (tx, _) = channel(32); |
52 | |||
53 | let ping_map: PingMap = DashMap::new(); | ||
54 | |||
55 | let shared_state = Arc::new(AppState { db, ping_send: tx, ping_map }); | ||
47 | 56 | ||
48 | let app = Router::new() | 57 | let app = Router::new() |
49 | .route("/start", post(start)) | 58 | .route("/start", post(start)) |
50 | .route("/device", get(get_device)) | 59 | .route("/device", get(get_device)) |
51 | .route("/device", put(put_device)) | 60 | .route("/device", put(put_device)) |
52 | .route("/device", post(post_device)) | 61 | .route("/device", post(post_device)) |
62 | .route("/status", get(status)) | ||
53 | .with_state(shared_state); | 63 | .with_state(shared_state); |
54 | 64 | ||
55 | let addr = SETTINGS.get_string("serveraddr").unwrap_or("0.0.0.0:7229".to_string()); | 65 | let addr = SETTINGS.get_string("serveraddr").unwrap_or("0.0.0.0:7229".to_string()); |
@@ -61,5 +71,7 @@ async fn main() { | |||
61 | } | 71 | } |
62 | 72 | ||
63 | pub struct AppState { | 73 | pub struct AppState { |
64 | db: PgPool | 74 | db: PgPool, |
65 | } | 75 | ping_send: Sender<BroadcastCommands>, |
76 | ping_map: PingMap, | ||
77 | } \ No newline at end of file | ||
diff --git a/src/routes/device.rs b/src/routes/device.rs index 025c7d0..1eeff0b 100644 --- a/src/routes/device.rs +++ b/src/routes/device.rs | |||
@@ -4,24 +4,26 @@ use axum::headers::HeaderMap; | |||
4 | use axum::Json; | 4 | use axum::Json; |
5 | use serde::{Deserialize, Serialize}; | 5 | use serde::{Deserialize, Serialize}; |
6 | use serde_json::{json, Value}; | 6 | use serde_json::{json, Value}; |
7 | use tracing::info; | 7 | use tracing::{debug, info}; |
8 | use crate::auth::auth; | 8 | use crate::auth::auth; |
9 | use crate::db::Device; | 9 | use crate::db::Device; |
10 | use crate::error::WebolError; | 10 | use crate::error::WebolError; |
11 | 11 | ||
12 | pub async fn get_device(State(state): State<Arc<crate::AppState>>, headers: HeaderMap, Json(payload): Json<GetDevicePayload>) -> Result<Json<Value>, WebolError> { | 12 | pub async fn get_device(State(state): State<Arc<crate::AppState>>, headers: HeaderMap, Json(payload): Json<GetDevicePayload>) -> Result<Json<Value>, WebolError> { |
13 | info!("GET request"); | 13 | info!("add device {}", payload.id); |
14 | let secret = headers.get("authorization"); | 14 | let secret = headers.get("authorization"); |
15 | if auth(secret).map_err(WebolError::Auth)? { | 15 | if auth(secret).map_err(WebolError::Auth)? { |
16 | let device = sqlx::query_as!( | 16 | let device = sqlx::query_as!( |
17 | Device, | 17 | Device, |
18 | r#" | 18 | r#" |
19 | SELECT id, mac, broadcast_addr | 19 | SELECT id, mac, broadcast_addr, ip |
20 | FROM devices | 20 | FROM devices |
21 | WHERE id = $1; | 21 | WHERE id = $1; |
22 | "#, | 22 | "#, |
23 | payload.id | 23 | payload.id |
24 | ).fetch_one(&state.db).await.map_err(|err| WebolError::Server(Box::new(err)))?; | 24 | ).fetch_one(&state.db).await.map_err(WebolError::DB)?; |
25 | |||
26 | debug!("got device {:?}", device); | ||
25 | 27 | ||
26 | Ok(Json(json!(device))) | 28 | Ok(Json(json!(device))) |
27 | } else { | 29 | } else { |
@@ -35,18 +37,19 @@ pub struct GetDevicePayload { | |||
35 | } | 37 | } |
36 | 38 | ||
37 | pub async fn put_device(State(state): State<Arc<crate::AppState>>, headers: HeaderMap, Json(payload): Json<PutDevicePayload>) -> Result<Json<Value>, WebolError> { | 39 | pub async fn put_device(State(state): State<Arc<crate::AppState>>, headers: HeaderMap, Json(payload): Json<PutDevicePayload>) -> Result<Json<Value>, WebolError> { |
38 | info!("PUT request"); | 40 | info!("add device {} ({}, {}, {})", payload.id, payload.mac, payload.broadcast_addr, payload.ip); |
39 | let secret = headers.get("authorization"); | 41 | let secret = headers.get("authorization"); |
40 | if auth(secret).map_err(WebolError::Auth)? { | 42 | if auth(secret).map_err(WebolError::Auth)? { |
41 | sqlx::query!( | 43 | sqlx::query!( |
42 | r#" | 44 | r#" |
43 | INSERT INTO devices (id, mac, broadcast_addr) | 45 | INSERT INTO devices (id, mac, broadcast_addr, ip) |
44 | VALUES ($1, $2, $3); | 46 | VALUES ($1, $2, $3, $4); |
45 | "#, | 47 | "#, |
46 | payload.id, | 48 | payload.id, |
47 | payload.mac, | 49 | payload.mac, |
48 | payload.broadcast_addr | 50 | payload.broadcast_addr, |
49 | ).execute(&state.db).await.map_err(|err| WebolError::Server(Box::new(err)))?; | 51 | payload.ip |
52 | ).execute(&state.db).await.map_err(WebolError::DB)?; | ||
50 | 53 | ||
51 | Ok(Json(json!(PutDeviceResponse { success: true }))) | 54 | Ok(Json(json!(PutDeviceResponse { success: true }))) |
52 | } else { | 55 | } else { |
@@ -59,6 +62,7 @@ pub struct PutDevicePayload { | |||
59 | id: String, | 62 | id: String, |
60 | mac: String, | 63 | mac: String, |
61 | broadcast_addr: String, | 64 | broadcast_addr: String, |
65 | ip: String | ||
62 | } | 66 | } |
63 | 67 | ||
64 | #[derive(Serialize)] | 68 | #[derive(Serialize)] |
@@ -67,20 +71,21 @@ pub struct PutDeviceResponse { | |||
67 | } | 71 | } |
68 | 72 | ||
69 | pub async fn post_device(State(state): State<Arc<crate::AppState>>, headers: HeaderMap, Json(payload): Json<PostDevicePayload>) -> Result<Json<Value>, WebolError> { | 73 | pub async fn post_device(State(state): State<Arc<crate::AppState>>, headers: HeaderMap, Json(payload): Json<PostDevicePayload>) -> Result<Json<Value>, WebolError> { |
70 | info!("POST request"); | 74 | info!("edit device {} ({}, {}, {})", payload.id, payload.mac, payload.broadcast_addr, payload.ip); |
71 | let secret = headers.get("authorization"); | 75 | let secret = headers.get("authorization"); |
72 | if auth(secret).map_err(WebolError::Auth)? { | 76 | if auth(secret).map_err(WebolError::Auth)? { |
73 | let device = sqlx::query_as!( | 77 | let device = sqlx::query_as!( |
74 | Device, | 78 | Device, |
75 | r#" | 79 | r#" |
76 | UPDATE devices | 80 | UPDATE devices |
77 | SET mac = $1, broadcast_addr = $2 WHERE id = $3 | 81 | SET mac = $1, broadcast_addr = $2, ip = $3 WHERE id = $4 |
78 | RETURNING id, mac, broadcast_addr; | 82 | RETURNING id, mac, broadcast_addr, ip; |
79 | "#, | 83 | "#, |
80 | payload.mac, | 84 | payload.mac, |
81 | payload.broadcast_addr, | 85 | payload.broadcast_addr, |
86 | payload.ip, | ||
82 | payload.id | 87 | payload.id |
83 | ).fetch_one(&state.db).await.map_err(|err| WebolError::Server(Box::new(err)))?; | 88 | ).fetch_one(&state.db).await.map_err(WebolError::DB)?; |
84 | 89 | ||
85 | Ok(Json(json!(device))) | 90 | Ok(Json(json!(device))) |
86 | } else { | 91 | } else { |
@@ -93,4 +98,5 @@ pub struct PostDevicePayload { | |||
93 | id: String, | 98 | id: String, |
94 | mac: String, | 99 | mac: String, |
95 | broadcast_addr: String, | 100 | broadcast_addr: String, |
96 | } \ No newline at end of file | 101 | ip: String, |
102 | } | ||
diff --git a/src/routes/mod.rs b/src/routes/mod.rs index 12fbfab..d5ab0d6 100644 --- a/src/routes/mod.rs +++ b/src/routes/mod.rs | |||
@@ -1,2 +1,3 @@ | |||
1 | pub mod start; | 1 | pub mod start; |
2 | pub mod device; \ No newline at end of file | 2 | pub mod device; |
3 | pub mod status; \ No newline at end of file | ||
diff --git a/src/routes/start.rs b/src/routes/start.rs index 163d58c..271f924 100644 --- a/src/routes/start.rs +++ b/src/routes/start.rs | |||
@@ -4,26 +4,30 @@ use serde::{Deserialize, Serialize}; | |||
4 | use std::sync::Arc; | 4 | use std::sync::Arc; |
5 | use axum::extract::State; | 5 | use axum::extract::State; |
6 | use serde_json::{json, Value}; | 6 | use serde_json::{json, Value}; |
7 | use tracing::info; | 7 | use tracing::{debug, info}; |
8 | use uuid::Uuid; | ||
8 | use crate::auth::auth; | 9 | use crate::auth::auth; |
9 | use crate::config::SETTINGS; | 10 | use crate::config::SETTINGS; |
10 | use crate::wol::{create_buffer, send_packet}; | 11 | use crate::wol::{create_buffer, send_packet}; |
11 | use crate::db::Device; | 12 | use crate::db::Device; |
12 | use crate::error::WebolError; | 13 | use crate::error::WebolError; |
14 | use crate::services::ping::PingValue; | ||
13 | 15 | ||
16 | #[axum_macros::debug_handler] | ||
14 | pub async fn start(State(state): State<Arc<crate::AppState>>, headers: HeaderMap, Json(payload): Json<StartPayload>) -> Result<Json<Value>, WebolError> { | 17 | pub async fn start(State(state): State<Arc<crate::AppState>>, headers: HeaderMap, Json(payload): Json<StartPayload>) -> Result<Json<Value>, WebolError> { |
15 | info!("POST request"); | 18 | info!("POST request"); |
16 | let secret = headers.get("authorization"); | 19 | let secret = headers.get("authorization"); |
17 | if auth(secret).map_err(WebolError::Auth)? { | 20 | let authorized = auth(secret).map_err(WebolError::Auth)?; |
21 | if authorized { | ||
18 | let device = sqlx::query_as!( | 22 | let device = sqlx::query_as!( |
19 | Device, | 23 | Device, |
20 | r#" | 24 | r#" |
21 | SELECT id, mac, broadcast_addr | 25 | SELECT id, mac, broadcast_addr, ip |
22 | FROM devices | 26 | FROM devices |
23 | WHERE id = $1; | 27 | WHERE id = $1; |
24 | "#, | 28 | "#, |
25 | payload.id | 29 | payload.id |
26 | ).fetch_one(&state.db).await.map_err(|err| WebolError::Server(Box::new(err)))?; | 30 | ).fetch_one(&state.db).await.map_err(WebolError::DB)?; |
27 | 31 | ||
28 | info!("starting {}", device.id); | 32 | info!("starting {}", device.id); |
29 | 33 | ||
@@ -32,11 +36,23 @@ pub async fn start(State(state): State<Arc<crate::AppState>>, headers: HeaderMap | |||
32 | .unwrap_or("0.0.0.0:1111".to_string()); | 36 | .unwrap_or("0.0.0.0:1111".to_string()); |
33 | 37 | ||
34 | let _ = send_packet( | 38 | let _ = send_packet( |
35 | &bind_addr.parse().map_err(|err| WebolError::Server(Box::new(err)))?, | 39 | &bind_addr.parse().map_err(WebolError::IpParse)?, |
36 | &device.broadcast_addr.parse().map_err(|err| WebolError::Server(Box::new(err)))?, | 40 | &device.broadcast_addr.parse().map_err(WebolError::IpParse)?, |
37 | create_buffer(&device.mac).map_err(|err| WebolError::Server(Box::new(err)))? | 41 | create_buffer(&device.mac)? |
38 | ).map_err(|err| WebolError::Server(Box::new(err))); | 42 | )?; |
39 | Ok(Json(json!(StartResponse { id: device.id, boot: true }))) | 43 | |
44 | let uuid = if payload.ping.is_some_and(|ping| ping) { | ||
45 | let uuid_gen = Uuid::new_v4().to_string(); | ||
46 | let uuid_genc = uuid_gen.clone(); | ||
47 | tokio::spawn(async move { | ||
48 | debug!("init ping service"); | ||
49 | state.ping_map.insert(uuid_gen.clone(), PingValue { ip: device.ip.clone(), online: false }); | ||
50 | |||
51 | crate::services::ping::spawn(state.ping_send.clone(), device.ip, uuid_gen.clone(), &state.ping_map).await | ||
52 | }); | ||
53 | Some(uuid_genc) | ||
54 | } else { None }; | ||
55 | Ok(Json(json!(StartResponse { id: device.id, boot: true, uuid }))) | ||
40 | } else { | 56 | } else { |
41 | Err(WebolError::Generic) | 57 | Err(WebolError::Generic) |
42 | } | 58 | } |
@@ -45,11 +61,12 @@ pub async fn start(State(state): State<Arc<crate::AppState>>, headers: HeaderMap | |||
45 | #[derive(Deserialize)] | 61 | #[derive(Deserialize)] |
46 | pub struct StartPayload { | 62 | pub struct StartPayload { |
47 | id: String, | 63 | id: String, |
48 | _test: Option<bool>, | 64 | ping: Option<bool>, |
49 | } | 65 | } |
50 | 66 | ||
51 | #[derive(Serialize)] | 67 | #[derive(Serialize)] |
52 | struct StartResponse { | 68 | struct StartResponse { |
53 | id: String, | 69 | id: String, |
54 | boot: bool, | 70 | boot: bool, |
55 | } \ No newline at end of file | 71 | uuid: Option<String>, |
72 | } | ||
diff --git a/src/routes/status.rs b/src/routes/status.rs new file mode 100644 index 0000000..45f3e51 --- /dev/null +++ b/src/routes/status.rs | |||
@@ -0,0 +1,10 @@ | |||
1 | use std::sync::Arc; | ||
2 | use axum::extract::{State, WebSocketUpgrade}; | ||
3 | use axum::response::Response; | ||
4 | use crate::AppState; | ||
5 | use crate::services::ping::status_websocket; | ||
6 | |||
7 | #[axum_macros::debug_handler] | ||
8 | pub async fn status(State(state): State<Arc<AppState>>, ws: WebSocketUpgrade) -> Response { | ||
9 | ws.on_upgrade(move |socket| status_websocket(socket, state)) | ||
10 | } \ No newline at end of file | ||
diff --git a/src/services/mod.rs b/src/services/mod.rs new file mode 100644 index 0000000..a766209 --- /dev/null +++ b/src/services/mod.rs | |||
@@ -0,0 +1 @@ | |||
pub mod ping; | |||
diff --git a/src/services/ping.rs b/src/services/ping.rs new file mode 100644 index 0000000..d900acb --- /dev/null +++ b/src/services/ping.rs | |||
@@ -0,0 +1,118 @@ | |||
1 | use std::sync::Arc; | ||
2 | |||
3 | use axum::extract::{ws::WebSocket}; | ||
4 | use axum::extract::ws::Message; | ||
5 | use dashmap::DashMap; | ||
6 | use time::{Duration, Instant}; | ||
7 | use tokio::sync::broadcast::{Sender}; | ||
8 | use tracing::{debug, error, trace}; | ||
9 | use crate::AppState; | ||
10 | use crate::config::SETTINGS; | ||
11 | |||
12 | pub type PingMap = DashMap<String, PingValue>; | ||
13 | |||
14 | #[derive(Debug, Clone)] | ||
15 | pub struct PingValue { | ||
16 | pub ip: String, | ||
17 | pub online: bool | ||
18 | } | ||
19 | |||
20 | pub async fn spawn(tx: Sender<BroadcastCommands>, ip: String, uuid: String, ping_map: &PingMap) { | ||
21 | let timer = Instant::now(); | ||
22 | let payload = [0; 8]; | ||
23 | |||
24 | let mut cont = true; | ||
25 | while cont { | ||
26 | let ping = surge_ping::ping( | ||
27 | ip.parse().expect("bad ip"), | ||
28 | &payload | ||
29 | ).await; | ||
30 | |||
31 | if let Err(ping) = ping { | ||
32 | cont = matches!(ping, surge_ping::SurgeError::Timeout { .. }); | ||
33 | if !cont { | ||
34 | error!("{}", ping.to_string()); | ||
35 | } | ||
36 | if timer.elapsed() >= Duration::minutes(SETTINGS.get_int("pingtimeout").unwrap_or(10)) { | ||
37 | let _ = tx.send(BroadcastCommands::PingTimeout(uuid.clone())); | ||
38 | trace!("remove {} from ping_map after timeout", uuid); | ||
39 | ping_map.remove(&uuid); | ||
40 | cont = false; | ||
41 | } | ||
42 | } else { | ||
43 | let (_, duration) = ping.map_err(|err| error!("{}", err.to_string())).expect("fatal error"); | ||
44 | debug!("ping took {:?}", duration); | ||
45 | cont = false; | ||
46 | handle_broadcast_send(&tx, ip.clone(), ping_map, uuid.clone()).await; | ||
47 | }; | ||
48 | } | ||
49 | } | ||
50 | |||
51 | async fn handle_broadcast_send(tx: &Sender<BroadcastCommands>, ip: String, ping_map: &PingMap, uuid: String) { | ||
52 | debug!("send pingsuccess message"); | ||
53 | let _ = tx.send(BroadcastCommands::PingSuccess(uuid.clone())); | ||
54 | trace!("sent message"); | ||
55 | ping_map.insert(uuid.clone(), PingValue { ip: ip.clone(), online: true }); | ||
56 | trace!("updated ping_map"); | ||
57 | tokio::time::sleep(tokio::time::Duration::from_secs(60)).await; | ||
58 | debug!("remove {} from ping_map after success", uuid); | ||
59 | ping_map.remove(&uuid); | ||
60 | } | ||
61 | |||
62 | #[derive(Clone, Debug)] | ||
63 | pub enum BroadcastCommands { | ||
64 | PingSuccess(String), | ||
65 | PingTimeout(String) | ||
66 | } | ||
67 | |||
68 | pub async fn status_websocket(mut socket: WebSocket, state: Arc<AppState>) { | ||
69 | trace!("wait for ws message (uuid)"); | ||
70 | let msg = socket.recv().await; | ||
71 | let uuid = msg.unwrap().unwrap().into_text().unwrap(); | ||
72 | |||
73 | trace!("Search for uuid: {:?}", uuid); | ||
74 | |||
75 | let device_exists = state.ping_map.contains_key(&uuid); | ||
76 | match device_exists { | ||
77 | true => { | ||
78 | let _ = socket.send(process_device(state.clone(), uuid).await).await; | ||
79 | }, | ||
80 | false => { | ||
81 | debug!("didn't find any device"); | ||
82 | let _ = socket.send(Message::Text(format!("notfound_{}", uuid))).await; | ||
83 | }, | ||
84 | }; | ||
85 | |||
86 | let _ = socket.close().await; | ||
87 | } | ||
88 | |||
89 | async fn process_device(state: Arc<AppState>, uuid: String) -> Message { | ||
90 | let pm = state.ping_map.clone().into_read_only(); | ||
91 | let device = pm.get(&uuid).expect("fatal error"); | ||
92 | debug!("got device: {} (online: {})", device.ip, device.online); | ||
93 | match device.online { | ||
94 | true => { | ||
95 | debug!("already started"); | ||
96 | Message::Text(format!("start_{}", uuid)) | ||
97 | }, | ||
98 | false => { | ||
99 | loop{ | ||
100 | trace!("wait for tx message"); | ||
101 | let message = state.ping_send.subscribe().recv().await.expect("fatal error"); | ||
102 | trace!("got message {:?}", message); | ||
103 | return match message { | ||
104 | BroadcastCommands::PingSuccess(msg_uuid) => { | ||
105 | if msg_uuid != uuid { continue; } | ||
106 | trace!("message == uuid success"); | ||
107 | Message::Text(format!("start_{}", uuid)) | ||
108 | }, | ||
109 | BroadcastCommands::PingTimeout(msg_uuid) => { | ||
110 | if msg_uuid != uuid { continue; } | ||
111 | trace!("message == uuid timeout"); | ||
112 | Message::Text(format!("timeout_{}", uuid)) | ||
113 | } | ||
114 | } | ||
115 | } | ||
116 | } | ||
117 | } | ||
118 | } \ No newline at end of file | ||
@@ -1,16 +1,17 @@ | |||
1 | use std::net::{SocketAddr, UdpSocket}; | 1 | use std::net::{SocketAddr, UdpSocket}; |
2 | use std::num::ParseIntError; | 2 | |
3 | use crate::error::WebolError; | ||
3 | 4 | ||
4 | /// Creates the magic packet from a mac address | 5 | /// Creates the magic packet from a mac address |
5 | /// | 6 | /// |
6 | /// # Panics | 7 | /// # Panics |
7 | /// | 8 | /// |
8 | /// Panics if `mac_addr` is an invalid mac | 9 | /// Panics if `mac_addr` is an invalid mac |
9 | pub fn create_buffer(mac_addr: &str) -> Result<Vec<u8>, ParseIntError> { | 10 | pub fn create_buffer(mac_addr: &str) -> Result<Vec<u8>, WebolError> { |
10 | let mut mac = Vec::new(); | 11 | let mut mac = Vec::new(); |
11 | let sp = mac_addr.split(':'); | 12 | let sp = mac_addr.split(':'); |
12 | for f in sp { | 13 | for f in sp { |
13 | mac.push(u8::from_str_radix(f, 16)?); | 14 | mac.push(u8::from_str_radix(f, 16).map_err(WebolError::BufferParse)?) |
14 | }; | 15 | }; |
15 | let mut buf = vec![255; 6]; | 16 | let mut buf = vec![255; 6]; |
16 | for _ in 0..16 { | 17 | for _ in 0..16 { |
@@ -22,8 +23,8 @@ pub fn create_buffer(mac_addr: &str) -> Result<Vec<u8>, ParseIntError> { | |||
22 | } | 23 | } |
23 | 24 | ||
24 | /// Sends a buffer on UDP broadcast | 25 | /// Sends a buffer on UDP broadcast |
25 | pub fn send_packet(bind_addr: &SocketAddr, broadcast_addr: &SocketAddr, buffer: Vec<u8>) -> Result<usize, std::io::Error> { | 26 | pub fn send_packet(bind_addr: &SocketAddr, broadcast_addr: &SocketAddr, buffer: Vec<u8>) -> Result<usize, WebolError> { |
26 | let socket = UdpSocket::bind(bind_addr)?; | 27 | let socket = UdpSocket::bind(bind_addr).map_err(WebolError::Broadcast)?; |
27 | socket.set_broadcast(true)?; | 28 | socket.set_broadcast(true).map_err(WebolError::Broadcast)?; |
28 | socket.send_to(&buffer, broadcast_addr) | 29 | socket.send_to(&buffer, broadcast_addr).map_err(WebolError::Broadcast) |
29 | } \ No newline at end of file | 30 | } |