diff --git a/Cargo.lock b/Cargo.lock index 1a4fe8b4f..9e04c4150 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,13 +21,28 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.7.18" +version = "0.7.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" dependencies = [ "memchr", ] +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + [[package]] name = "ansi_term" version = "0.12.1" @@ -61,9 +76,9 @@ checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" [[package]] name = "async-trait" -version = "0.1.53" +version = "0.1.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed6aa3524a2dfcf9fe180c51eae2b58738348d819517ceadf95789c51fff7600" +checksum = "1e805d94e6b5001b651426cf4cd446b1ab5f319d27bab5c644f61de0a804360c" dependencies = [ "proc-macro2", "quote", @@ -89,15 +104,15 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "base-x" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc19a4937b4fbd3fe3379793130e42060d10627a360f2127802b10b87e7baf74" +checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" [[package]] name = "base64" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "bigdecimal" @@ -126,7 +141,7 @@ dependencies = [ "bitflags", "cexpr", "clang-sys", - "clap", + "clap 2.34.0", "env_logger", "lazy_static", "lazycell", @@ -169,13 +184,23 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" +checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" dependencies = [ "generic-array", ] +[[package]] +name = "blowfish" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e412e2cd0f2b2d93e02543ceae7917b3c70331573df19ee046bcbc35e45e87d7" +dependencies = [ + "byteorder", + "cipher", +] + [[package]] name = "buf_redux" version = "0.8.4" @@ -206,9 +231,15 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.1.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" +checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" + +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" @@ -233,23 +264,62 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.19" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +checksum = "bfd4d1b31faaa3a89d7934dbded3111da0d2ef28e3ebccdb4f0179f5929d1ef1" dependencies = [ - "libc", + "iana-time-zone", + "js-sys", "num-integer", "num-traits 0.2.15", "serde 1.0.137", "time 0.1.44", + "wasm-bindgen", "winapi", ] +[[package]] +name = "ciborium" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c137568cc60b904a7724001b35ce2630fd00d5d84805fbb608ab89509d788f" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde 1.0.137", +] + +[[package]] +name = "ciborium-io" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "346de753af073cc87b52b2083a506b38ac176a44cfb05497b622e27be899b369" + +[[package]] +name = "ciborium-ll" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213030a2b5a4e0c0892b6652260cf6ccac84827b83a85a534e178e3906c4cf1b" +dependencies = [ + "ciborium-io", + "half", +] + +[[package]] +name = "cipher" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1873270f8f7942c191139cb8a40fd228da6c3fd2fc376d7e92d47aa14aeb59e" +dependencies = [ + "crypto-common", + "inout", +] + [[package]] name = "clang-sys" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cc00842eed744b858222c4c9faf7243aafc6d33f92f96935263ef4d8a41ce21" +checksum = "fa2e27ae6ab525c3d369ded447057bca5438d86dc3a68f6faafb8269ba82ebf3" dependencies = [ "glob", "libc", @@ -266,11 +336,32 @@ dependencies = [ "atty", "bitflags", "strsim 0.8.0", - "textwrap", + "textwrap 0.11.0", "unicode-width", "vec_map", ] +[[package]] +name = "clap" +version = "3.2.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86447ad904c7fb335a790c9d7fe3d0d971dc523b8ccd1561a520de9a85302750" +dependencies = [ + "bitflags", + "clap_lex", + "indexmap", + "textwrap 0.15.1", +] + +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", +] + [[package]] name = "cmake" version = "0.1.48" @@ -280,6 +371,16 @@ dependencies = [ "cc", ] +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + [[package]] name = "config" version = "0.11.0" @@ -326,9 +427,9 @@ checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" [[package]] name = "cpufeatures" -version = "0.2.2" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" +checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" dependencies = [ "libc", ] @@ -342,16 +443,140 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "criterion" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c76e09c1aae2bc52b3d2f29e13c6572553b30c4aa1b8a49fd70de6412654cb" +dependencies = [ + "anes", + "atty", + "cast", + "ciborium", + "clap 3.2.22", + "criterion-plot", + "itertools", + "lazy_static", + "num-traits 0.2.15", + "oorandom", + "plotters", + "rayon", + "regex", + "serde 1.0.137", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" +dependencies = [ + "cast", + "itertools", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f916dfc5d356b0ed9dae65f1db9fc9770aa2851d2662b988ccf4fe3516e86348" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac" +dependencies = [ + "cfg-if", +] + [[package]] name = "crypto-common" -version = "0.1.3" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", + "rand_core", "typenum", ] +[[package]] +name = "cxx" +version = "1.0.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b7d4e43b25d3c994662706a1d4fcfc32aaa6afd287502c111b237093bb23f3a" +dependencies = [ + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84f8829ddc213e2c1368e51a2564c552b65a8cb6a28f31e576270ac81d5e5827" +dependencies = [ + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2", + "quote", + "scratch", + "syn", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e72537424b474af1460806647c41d4b6d35d09ef7fe031c5c2fa5766047cc56a" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "309e4fb93eed90e1e14bea0da16b209f81813ba9fc7830c20ed151dd7bc0a4d7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "darling" version = "0.14.1" @@ -422,11 +647,11 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.3" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" +checksum = "adfbc57365a37acbd2ebf2b64d7e69bb766e2fea813521ed536f5d0520dcf86c" dependencies = [ - "block-buffer 0.10.2", + "block-buffer 0.10.3", "crypto-common", ] @@ -469,9 +694,9 @@ checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" [[package]] name = "fastrand" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" +checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" dependencies = [ "instant", ] @@ -487,13 +712,11 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.23" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39522e96686d38f4bc984b9198e3a0613264abaebaff2c5c918bfa6b6da09af" +checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" dependencies = [ - "cfg-if", "crc32fast", - "libc", "libz-sys", "miniz_oxide", ] @@ -521,11 +744,10 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" dependencies = [ - "matches", "percent-encoding", ] @@ -601,9 +823,9 @@ checksum = "1847abb9cb65d566acd5942e94aea9c8f547ad02c98e1649326fc0e8910b8b1e" [[package]] name = "futures" -version = "0.3.21" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" +checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0" dependencies = [ "futures-channel", "futures-core", @@ -616,9 +838,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.21" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" +checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" dependencies = [ "futures-core", "futures-sink", @@ -626,15 +848,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.21" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" +checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" [[package]] name = "futures-executor" -version = "0.3.21" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" +checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2" dependencies = [ "futures-core", "futures-task", @@ -643,15 +865,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.21" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" +checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" [[package]] name = "futures-macro" -version = "0.3.21" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" +checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" dependencies = [ "proc-macro2", "quote", @@ -660,21 +882,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.21" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" +checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" [[package]] name = "futures-task" -version = "0.3.21" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" +checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" [[package]] name = "futures-util" -version = "0.3.21" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" dependencies = [ "futures-channel", "futures-core", @@ -690,9 +912,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.5" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" +checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" dependencies = [ "typenum", "version_check", @@ -700,13 +922,13 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.6" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ "cfg-if", "libc", - "wasi 0.10.0+wasi-snapshot-preview1", + "wasi 0.11.0+wasi-snapshot-preview1", ] [[package]] @@ -717,9 +939,9 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] name = "h2" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57" +checksum = "5ca32592cf21ac7ccab1825cd87f6c9b3d9022c44d086172ed0966bec8af30be" dependencies = [ "bytes", "fnv", @@ -730,10 +952,16 @@ dependencies = [ "indexmap", "slab", "tokio", - "tokio-util 0.7.1", + "tokio-util", "tracing", ] +[[package]] +name = "half" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" + [[package]] name = "hashbrown" version = "0.11.2" @@ -754,18 +982,18 @@ dependencies = [ [[package]] name = "hashlink" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d452c155cb93fecdfb02a73dd57b5d8e442c2063bd7aac72f1bc5e4263a43086" +checksum = "69fe1fcf8b4278d860ad0548329f892a3631fb63f82574df68275f34cdbe0ffa" dependencies = [ "hashbrown 0.12.3", ] [[package]] name = "headers" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cff78e5788be1e0ab65b04d306b2ed5092c815ec97ec70f4ebd5aee158aa55d" +checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584" dependencies = [ "base64", "bitflags", @@ -774,7 +1002,7 @@ dependencies = [ "http", "httpdate", "mime", - "sha-1 0.10.0", + "sha1 0.10.5", ] [[package]] @@ -803,9 +1031,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "http" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff8670570af52249509a86f5e3e18a08c60b177071826898fde8997cf5f6bfbb" +checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" dependencies = [ "bytes", "fnv", @@ -814,9 +1042,9 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ "bytes", "http", @@ -825,9 +1053,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.7.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" @@ -843,9 +1071,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.18" +version = "0.14.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b26ae0a80afebe130861d90abf98e3814a4f28a4c6ffeb5ab8ebb2be311e0ef2" +checksum = "02c929dc5c39e335a03c405292728118860721b10190d98c2a0f0efd5baafbac" dependencies = [ "bytes", "futures-channel", @@ -865,6 +1093,30 @@ dependencies = [ "want", ] +[[package]] +name = "iana-time-zone" +version = "0.1.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5a6ef98976b22b3b7f2f3a806f858cb862044cfa66805aa3ad84cb3d3b785ed" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +dependencies = [ + "cxx", + "cxx-build", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -873,11 +1125,10 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.2.3" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" dependencies = [ - "matches", "unicode-bidi", "unicode-normalization", ] @@ -893,6 +1144,15 @@ dependencies = [ "serde 1.0.137", ] +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + [[package]] name = "instant" version = "0.1.12" @@ -914,6 +1174,15 @@ dependencies = [ "syn", ] +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.1" @@ -966,9 +1235,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.125" +version = "0.2.135" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b" +checksum = "68783febc7782c6c5cb401fbda4de5a9898be1762314da0bb2c10ced61f18b0c" [[package]] name = "libloading" @@ -993,26 +1262,35 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.6" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e7e15d7610cce1d9752e137625f14e61a28cd45929b6e12e47b50fe154ee2e" +checksum = "9702761c3935f8cc2f101793272e202c72b99da8f4224a19ddcf1279a6450bbf" dependencies = [ "cc", "pkg-config", "vcpkg", ] +[[package]] +name = "link-cplusplus" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369" +dependencies = [ + "cc", +] + [[package]] name = "linked-hash-map" -version = "0.5.4" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "lock_api" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" dependencies = [ "autocfg", "scopeguard", @@ -1036,12 +1314,6 @@ dependencies = [ "hashbrown 0.11.2", ] -[[package]] -name = "matches" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" - [[package]] name = "memchr" version = "2.5.0" @@ -1075,34 +1347,23 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.5.1" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2b29bd4bc3f33391105ebee3589c19197c4271e3e5a9ec9bfe8127eeff8f082" +checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34" dependencies = [ "adler", ] [[package]] name = "mio" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9" +checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" dependencies = [ "libc", "log", - "miow", - "ntapi", "wasi 0.11.0+wasi-snapshot-preview1", - "winapi", -] - -[[package]] -name = "miow" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" -dependencies = [ - "winapi", + "windows-sys 0.36.1", ] [[package]] @@ -1177,7 +1438,7 @@ dependencies = [ "saturating", "serde 1.0.137", "serde_json", - "sha1", + "sha1 0.6.1", "sha2", "smallvec", "subprocess", @@ -1237,15 +1498,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "ntapi" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f" -dependencies = [ - "winapi", -] - [[package]] name = "num-bigint" version = "0.3.3" @@ -1321,6 +1573,12 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" +[[package]] +name = "oorandom" +version = "11.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" + [[package]] name = "opaque-debug" version = "0.3.0" @@ -1329,9 +1587,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.41" +version = "0.10.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "618febf65336490dfcf20b73f885f5651a0c89c64c2d4a8c3662585a70bf5bd0" +checksum = "12fc0523e3bd51a692c8850d075d74dc062ccf251c0110668cbd921917118a13" dependencies = [ "bitflags", "cfg-if", @@ -1370,9 +1628,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.75" +version = "0.9.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5f9bd0c2710541a3cda73d6f9ac4f1b240de4ae261065d309dbe73d9dceb42f" +checksum = "b03b84c3b2d099b81f0953422b4d4ad58761589d0229b5506356afca05a3670a" dependencies = [ "autocfg", "cc", @@ -1382,29 +1640,33 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "os_str_bytes" +version = "6.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff" + [[package]] name = "parking_lot" -version = "0.11.2" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ - "instant", "lock_api", "parking_lot_core", ] [[package]] name = "parking_lot_core" -version = "0.8.5" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" +checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0" dependencies = [ "cfg-if", - "instant", "libc", "redox_syscall", "smallvec", - "winapi", + "windows-sys 0.42.0", ] [[package]] @@ -1426,24 +1688,24 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "pin-project" -version = "1.0.10" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e" +checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.0.10" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb" +checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" dependencies = [ "proc-macro2", "quote", @@ -1468,6 +1730,34 @@ version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" +[[package]] +name = "plotters" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2538b639e642295546c50fcd545198c9d64ee2a38620a628724a3b266d5fbf97" +dependencies = [ + "num-traits 0.2.15", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "193228616381fecdc1224c62e96946dfbc73ff4384fba576e052ff8c1bea8142" + +[[package]] +name = "plotters-svg" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9a81d2759aae1dae668f783c308bc5c8ebd191ff4184aaa1b37f65a6ae5a56f" +dependencies = [ + "plotters-backend", +] + [[package]] name = "ppv-lite86" version = "0.2.16" @@ -1482,11 +1772,11 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" [[package]] name = "proc-macro2" -version = "1.0.38" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9027b48e9d4c9175fa2218adf3557f91c1137021739951d4932f5f8268ac48aa" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] @@ -1506,9 +1796,9 @@ dependencies = [ [[package]] name = "r2d2" -version = "0.8.9" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "545c5bc2b880973c9c10e4067418407a0ccaa3091781d1671d46eb35107cb26f" +checksum = "51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93" dependencies = [ "log", "parking_lot", @@ -1564,18 +1854,42 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ "getrandom", ] +[[package]] +name = "rayon" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "num_cpus", +] + [[package]] name = "redox_syscall" -version = "0.2.13" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ "bitflags", ] @@ -1643,9 +1957,9 @@ checksum = "3e52c148ef37f8c375d49d5a73aa70713125b7f19095948a923f80afdeb22ec2" [[package]] name = "rust_decimal" -version = "1.23.1" +version = "1.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22dc69eadbf0ee2110b8d20418c0c6edbaefec2811c4963dc17b6344e11fe0f8" +checksum = "ee9164faf726e4f3ece4978b25ca877ddc6802fa77f38cdccb32c7f805ecd70c" dependencies = [ "arrayvec 0.7.2", "num-traits 0.2.15", @@ -1673,22 +1987,30 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.9", + "semver 1.0.14", ] [[package]] name = "rustls" -version = "0.19.1" +version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" +checksum = "539a2bfe908f471bfa933876bd1eb6a19cf2176d375f82ef7f99530a40e48c2c" dependencies = [ - "base64", "log", "ring", "sct", "webpki", ] +[[package]] +name = "rustls-pemfile" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eebeaeb360c87bfb72e84abdb3447159c0eaececf1bef2aecd65a8be949d1c9" +dependencies = [ + "base64", +] + [[package]] name = "ryu" version = "1.0.9" @@ -1701,6 +2023,15 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "saturating" version = "0.1.0" @@ -1709,19 +2040,19 @@ checksum = "ece8e78b2f38ec51c51f5d475df0a7187ba5111b2a28bdc761ee05b075d40a71" [[package]] name = "schannel" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" +checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" dependencies = [ "lazy_static", - "winapi", + "windows-sys 0.36.1", ] [[package]] name = "scheduled-thread-pool" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc6f74fd1204073fa02d5d5d68bec8021be4c38690b61264b2fdb48083d0e7d7" +checksum = "977a7519bff143a44f842fd07e80ad1329295bd71686457f18e496736f4bf9bf" dependencies = [ "parking_lot", ] @@ -1738,11 +2069,17 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "scratch" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" + [[package]] name = "sct" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" dependencies = [ "ring", "untrusted", @@ -1750,9 +2087,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.6.1" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc" +checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" dependencies = [ "bitflags", "core-foundation", @@ -1782,9 +2119,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.9" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cb243bdfdb5936c8dc3c45762a19d12ab4550cdc753bc247637d4ec35a040fd" +checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" [[package]] name = "semver-parser" @@ -1831,9 +2168,9 @@ dependencies = [ [[package]] name = "serde_bytes" -version = "0.11.6" +version = "0.11.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212e73464ebcde48d723aa02eb270ba62eff38a9b732df31f33f1b4e145f3a54" +checksum = "cfc50e8183eeeb6178dcb167ae34a8051d63535023ae38b5d8d12beae193d37b" dependencies = [ "serde 1.0.137", ] @@ -1874,9 +2211,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89df7a26519371a3cce44fbb914c2819c84d9b897890987fa3ab096491cc0ea8" +checksum = "368f2d60d049ea019a84dcd6687b0d1e0030fe663ae105039bdf967ed5e6a9a7" dependencies = [ "base64", "chrono", @@ -1885,14 +2222,14 @@ dependencies = [ "serde 1.0.137", "serde_json", "serde_with_macros", - "time 0.3.13", + "time 0.3.15", ] [[package]] name = "serde_with_macros" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de337f322382fcdfbb21a014f7c224ee041a23785651db67b9827403178f698f" +checksum = "1ccadfacf6cf10faad22bbadf55986bdd0856edfb5d9210aa1dcf1f516e84e93" dependencies = [ "darling", "proc-macro2", @@ -1900,19 +2237,6 @@ dependencies = [ "syn", ] -[[package]] -name = "sha-1" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", -] - [[package]] name = "sha-1" version = "0.10.0" @@ -1921,7 +2245,7 @@ checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.3", + "digest 0.10.5", ] [[package]] @@ -1933,6 +2257,17 @@ dependencies = [ "sha1_smol", ] +[[package]] +name = "sha1" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.5", +] + [[package]] name = "sha1_smol" version = "1.0.0" @@ -1969,15 +2304,18 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg", +] [[package]] name = "smallvec" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "socket2" @@ -2049,7 +2387,7 @@ dependencies = [ "serde 1.0.137", "serde_derive", "serde_json", - "sha1", + "sha1 0.6.1", "syn", ] @@ -2073,9 +2411,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "subprocess" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "055cf3ebc2981ad8f0a5a17ef6652f652d87831f79fddcba2ac57bcb9a0aa407" +checksum = "0c2e86926081dda636c546d8c5e641661049d7562a68f5488be4a1f7f66f6086" dependencies = [ "libc", "winapi", @@ -2083,13 +2421,13 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.92" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff7c592601f11445996a06f8ad0c27f094a58857c2f89e97974ab9235b92c52" +checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] @@ -2130,20 +2468,26 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "textwrap" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "949517c0cf1bf4ee812e2e07e08ab448e3ae0d23472aee8a06c985f0c8815b16" + [[package]] name = "thiserror" -version = "1.0.31" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" +checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.31" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" +checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" dependencies = [ "proc-macro2", "quote", @@ -2178,9 +2522,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.13" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db76ff9fa4b1458b3c7f077f3ff9887394058460d21e634355b273aaf11eea45" +checksum = "d634a985c4d4238ec39cacaed2e7ae552fbd3c476b552c1deac3021b7d7eaf0c" dependencies = [ "itoa", "libc", @@ -2211,6 +2555,16 @@ dependencies = [ "syn", ] +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde 1.0.137", + "serde_json", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -2228,16 +2582,16 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.18.1" +version = "1.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce653fb475565de9f6fb0614b28bca8df2c430c0cf84bcd9c843f15de5414cc" +checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099" dependencies = [ + "autocfg", "bytes", "libc", "memchr", "mio", "num_cpus", - "once_cell", "pin-project-lite", "signal-hook-registry", "socket2", @@ -2258,9 +2612,9 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.22.0" +version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6" +checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" dependencies = [ "rustls", "tokio", @@ -2269,9 +2623,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.8" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50145484efff8818b5ccd256697f36863f587da82cf8b409c53adf1e840798e3" +checksum = "d660770404473ccd7bc9f8b28494a811bc18542b915c0855c51e8f419d5223ce" dependencies = [ "futures-core", "pin-project-lite", @@ -2280,36 +2634,21 @@ dependencies = [ [[package]] name = "tokio-tungstenite" -version = "0.15.0" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "511de3f85caf1c98983545490c3d09685fa8eb634e57eec22bb4db271f46cbd8" +checksum = "f714dd15bead90401d77e04243611caec13726c2408afd5b31901dfcdcb3b181" dependencies = [ "futures-util", "log", - "pin-project", "tokio", "tungstenite", ] [[package]] name = "tokio-util" -version = "0.6.9" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "log", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0edfdeb067411dba2044da6d1cb2df793dd35add7888d73c16e3381ded401764" +checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" dependencies = [ "bytes", "futures-core", @@ -2335,8 +2674,12 @@ dependencies = [ "aquatic_udp_protocol", "async-trait", "binascii", + "blowfish", "chrono", + "cipher", "config", + "criterion", + "crypto-common", "derive_more", "fern", "futures", @@ -2356,15 +2699,15 @@ dependencies = [ "thiserror", "tokio", "toml", - "uuid 1.1.2", + "uuid 1.2.1", "warp", ] [[package]] name = "tower-service" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" @@ -2375,21 +2718,9 @@ dependencies = [ "cfg-if", "log", "pin-project-lite", - "tracing-attributes", "tracing-core", ] -[[package]] -name = "tracing-attributes" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6b8ad3567499f98a1db7a752b07a7c8c7c7c34c332ec00effb2b0027974b7c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "tracing-core" version = "0.1.26" @@ -2407,9 +2738,9 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] name = "tungstenite" -version = "0.14.0" +version = "0.17.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0b2d8558abd2e276b0a8df5c05a2ec762609344191e5fd23e292c910e9165b5" +checksum = "e27992fd6a8c29ee7eef28fc78349aa244134e10ad447ce3b9f0ac0ed0fa4ce0" dependencies = [ "base64", "byteorder", @@ -2418,7 +2749,7 @@ dependencies = [ "httparse", "log", "rand", - "sha-1 0.9.8", + "sha-1", "thiserror", "url", "utf-8", @@ -2465,26 +2796,26 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" +[[package]] +name = "unicode-ident" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" + [[package]] name = "unicode-normalization" -version = "0.1.19" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" dependencies = [ "tinyvec", ] [[package]] name = "unicode-width" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" - -[[package]] -name = "unicode-xid" -version = "0.2.3" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" [[package]] name = "untrusted" @@ -2494,13 +2825,12 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "url" -version = "2.2.2" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" dependencies = [ "form_urlencoded", "idna", - "matches", "percent-encoding", ] @@ -2518,9 +2848,9 @@ checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" [[package]] name = "uuid" -version = "1.1.2" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd6469f4314d5f1ffec476e05f17cc9a78bc7a27a6a857842170bdf8d6f98d2f" +checksum = "feb41e78f93363bb2df8b0e86a2ca30eed7806ea16ea0c790d757cf93f79be83" dependencies = [ "getrandom", ] @@ -2543,6 +2873,17 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "walkdir" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +dependencies = [ + "same-file", + "winapi", + "winapi-util", +] + [[package]] name = "want" version = "0.3.0" @@ -2555,9 +2896,9 @@ dependencies = [ [[package]] name = "warp" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cef4e1e9114a4b7f1ac799f16ce71c14de5778500c5450ec6b7b920c55b587e" +checksum = "ed7b8be92646fc3d18b06147664ebc5f48d222686cb11a8755e561a735aacc6d" dependencies = [ "bytes", "futures-channel", @@ -2571,6 +2912,7 @@ dependencies = [ "multipart", "percent-encoding", "pin-project", + "rustls-pemfile", "scoped-tls", "serde 1.0.137", "serde_json", @@ -2579,7 +2921,7 @@ dependencies = [ "tokio-rustls", "tokio-stream", "tokio-tungstenite", - "tokio-util 0.6.9", + "tokio-util", "tower-service", "tracing", ] @@ -2662,9 +3004,9 @@ dependencies = [ [[package]] name = "webpki" -version = "0.21.4" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" +checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" dependencies = [ "ring", "untrusted", @@ -2710,6 +3052,106 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-sys" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +dependencies = [ + "windows_aarch64_msvc 0.36.1", + "windows_i686_gnu 0.36.1", + "windows_i686_msvc 0.36.1", + "windows_x86_64_gnu 0.36.1", + "windows_x86_64_msvc 0.36.1", +] + +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.42.0", + "windows_i686_gnu 0.42.0", + "windows_i686_msvc 0.42.0", + "windows_x86_64_gnu 0.42.0", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.42.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" + +[[package]] +name = "windows_i686_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" + +[[package]] +name = "windows_i686_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" + [[package]] name = "wyz" version = "0.4.0" diff --git a/Cargo.toml b/Cargo.toml index 89fdffa99..5352d0760 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,13 @@ opt-level = 3 lto = "fat" strip = true +[dev-dependencies] +criterion = "0.4" + +[[bench]] +name = "bench_connection_cookie" +harness = false + [dependencies] tokio = { version = "1.7", features = [ "rt-multi-thread", @@ -35,6 +42,9 @@ hex = "0.4.3" percent-encoding = "2.1.0" binascii = "0.1" lazy_static = "1.4.0" +blowfish = "0.9.1" +cipher = "0.4.3" +crypto-common = {version = "0.1.6", features = ["rand_core"] } openssl = { version = "0.10.41", features = ["vendored"] } diff --git a/benches/bench_connection_cookie.rs b/benches/bench_connection_cookie.rs new file mode 100644 index 000000000..9ec04f4bc --- /dev/null +++ b/benches/bench_connection_cookie.rs @@ -0,0 +1,71 @@ +use std::net::{IpAddr, Ipv4Addr, SocketAddr}; + +use criterion::{criterion_group, criterion_main, Criterion}; +use torrust_tracker::udp::connection_cookie::{ + ConnectionCookie, EncryptedConnectionCookie, HashedConnectionCookie, WitnessConnectionCookie, +}; + +pub fn benchmark_hashed_connection_cookie(bench: &mut Criterion) { + use HashedConnectionCookie as BenchConnectionCookie; + + let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); + let cookie = BenchConnectionCookie::make_connection_cookie(&remote_address); + + bench.bench_function("Make Hashed Cookie", |b| { + b.iter(|| { + let _ = BenchConnectionCookie::make_connection_cookie(&remote_address); + }) + }); + + bench.bench_function("Check Hashed Cookie", |b| { + b.iter(|| { + let _ = BenchConnectionCookie::check_connection_cookie(&remote_address, &cookie).unwrap(); + }) + }); +} + +pub fn benchmark_witness_connection_cookie(bench: &mut Criterion) { + use WitnessConnectionCookie as BenchConnectionCookie; + + let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); + let cookie = BenchConnectionCookie::make_connection_cookie(&remote_address); + + bench.bench_function("Make Witness Cookie", |b| { + b.iter(|| { + let _ = BenchConnectionCookie::make_connection_cookie(&remote_address); + }) + }); + + bench.bench_function("Check Witness Cookie", |b| { + b.iter(|| { + let _ = BenchConnectionCookie::check_connection_cookie(&remote_address, &cookie).unwrap(); + }) + }); +} + +pub fn benchmark_encrypted_connection_cookie(bench: &mut Criterion) { + use EncryptedConnectionCookie as BenchConnectionCookie; + + let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); + let cookie = BenchConnectionCookie::make_connection_cookie(&remote_address); + + bench.bench_function("Make Encrypted Cookie", |b| { + b.iter(|| { + let _ = BenchConnectionCookie::make_connection_cookie(&remote_address); + }) + }); + + bench.bench_function("Check Encrypted Cookie", |b| { + b.iter(|| { + let _ = BenchConnectionCookie::check_connection_cookie(&remote_address, &cookie).unwrap(); + }) + }); +} + +criterion_group!( + benches, + benchmark_hashed_connection_cookie, + benchmark_witness_connection_cookie, + benchmark_encrypted_connection_cookie, +); +criterion_main!(benches); diff --git a/src/lib.rs b/src/lib.rs index 5f003b5fd..cde283052 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -38,3 +38,34 @@ pub mod ephemeral_instance_keys { pub static ref RANDOM_SEED: Seed = Rng::gen(&mut ThreadRng::default()); } } + +pub mod block_ciphers { + + use blowfish::BlowfishLE; + use cipher::KeyInit; + use rand::rngs::StdRng; + use rand::SeedableRng; + + pub type Cipher = BlowfishLE; + + pub mod ephemeral_instance { + use super::*; + use crate::ephemeral_instance_keys::RANDOM_SEED; + + lazy_static! { + pub static ref BLOCK_CIPHER_BLOWFISH: Cipher = ::new(&::generate_key( + ::from_seed(*RANDOM_SEED) + )); + } + } + + pub mod testing { + use super::*; + + lazy_static! { + pub static ref TEST_BLOCK_CIPHER_BLOWFISH: Cipher = ::new( + &::generate_key(::from_seed([0u8; 32])) + ); + } + } +} diff --git a/src/main.rs b/src/main.rs index dcb92acb8..6c56e09ba 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use log::info; use torrust_tracker::tracker::statistics::StatsTracker; use torrust_tracker::tracker::tracker::TorrentTracker; -use torrust_tracker::{ephemeral_instance_keys, logging, setup, static_time, Configuration}; +use torrust_tracker::{block_ciphers, ephemeral_instance_keys, logging, setup, static_time, Configuration}; #[tokio::main] async fn main() { @@ -15,6 +15,11 @@ async fn main() { // Initialize the Ephemeral Instance Random Seed lazy_static::initialize(&ephemeral_instance_keys::RANDOM_SEED); + // Initialize the Block Ciphers + lazy_static::initialize(&block_ciphers::ephemeral_instance::BLOCK_CIPHER_BLOWFISH); + #[cfg(test)] + lazy_static::initialize(&block_ciphers::testing::TEST_BLOCK_CIPHER_BLOWFISH); + // Initialize Torrust config let config = match Configuration::load_from_file(CONFIG_PATH) { Ok(config) => Arc::new(config), diff --git a/src/protocol/crypto.rs b/src/protocol/crypto.rs index 18cfaf5e6..987e39c62 100644 --- a/src/protocol/crypto.rs +++ b/src/protocol/crypto.rs @@ -95,4 +95,85 @@ pub mod keys { } } } + + pub mod block_ciphers { + use cipher::generic_array::GenericArray; + use cipher::BlockSizeUser; + + pub(super) use crate::block_ciphers::ephemeral_instance::BLOCK_CIPHER_BLOWFISH as INSTANCE_BLOCK_CIPHER; + #[allow(unused_imports)] + pub(super) use crate::block_ciphers::testing::TEST_BLOCK_CIPHER_BLOWFISH as TEST_BLOCK_CIPHER; + use crate::block_ciphers::Cipher; + + pub trait BlockCipherKeeper { + type BlockCipher: cipher::BlockCipher; + fn get_block_cipher() -> &'static Self::BlockCipher; + } + + pub type CipherArray = GenericArray::BlockSize>; + + pub struct DefaultBlockCipher; + pub struct InstanceBlockCipher; + + impl BlockCipherKeeper for DefaultBlockCipher { + type BlockCipher = Cipher; + fn get_block_cipher() -> &'static Self::BlockCipher { + &self::detail::DEFAULT_BLOCK_CIPHER + } + } + + impl BlockCipherKeeper for InstanceBlockCipher { + type BlockCipher = Cipher; + fn get_block_cipher() -> &'static Self::BlockCipher { + &INSTANCE_BLOCK_CIPHER + } + } + + #[cfg(test)] + mod tests { + use cipher::BlockEncrypt; + + use super::{BlockCipherKeeper, CipherArray, DefaultBlockCipher, InstanceBlockCipher, TEST_BLOCK_CIPHER}; + use crate::block_ciphers::Cipher; + + pub struct TestBlockCipher; + + impl BlockCipherKeeper for TestBlockCipher { + type BlockCipher = Cipher; + + fn get_block_cipher() -> &'static Self::BlockCipher { + &TEST_BLOCK_CIPHER + } + } + + #[test] + fn when_testing_the_default_and_test_block_ciphers_should_be_the_same() { + let mut array = CipherArray::from([0u8; 8]); + let mut array2 = CipherArray::from([0u8; 8]); + + DefaultBlockCipher::get_block_cipher().encrypt_block(&mut array); + TestBlockCipher::get_block_cipher().encrypt_block(&mut array2); + + assert_eq!(array, array2) + } + + #[test] + fn when_testing_the_default_and_instance_block_ciphers_should_be_the_different() { + let mut array = CipherArray::from([0u8; 8]); + let mut array2 = CipherArray::from([0u8; 8]); + + DefaultBlockCipher::get_block_cipher().encrypt_block(&mut array); + InstanceBlockCipher::get_block_cipher().encrypt_block(&mut array2); + + assert_ne!(array, array2) + } + } + + mod detail { + #[cfg(not(test))] + pub(super) use super::INSTANCE_BLOCK_CIPHER as DEFAULT_BLOCK_CIPHER; + #[cfg(test)] + pub(super) use super::TEST_BLOCK_CIPHER as DEFAULT_BLOCK_CIPHER; + } + } } diff --git a/src/tracker/peer.rs b/src/tracker/peer.rs index 7ac35179a..22acf9f7f 100644 --- a/src/tracker/peer.rs +++ b/src/tracker/peer.rs @@ -130,7 +130,7 @@ mod test { }; use crate::peer::TorrentPeer; - use crate::udp::connection_cookie::{into_connection_id, make_connection_cookie}; + use crate::udp::connection_cookie::{into_connection_id, ConnectionCookie, DefaultConnectionCookie}; // todo: duplicate functions is PR 82. Remove duplication once both PR are merged. fn sample_ipv4_remote_addr() -> SocketAddr { @@ -152,7 +152,9 @@ mod test { let info_hash_aquatic = aquatic_udp_protocol::InfoHash([0u8; 20]); let default_request = AnnounceRequest { - connection_id: into_connection_id(&make_connection_cookie(&sample_ipv4_remote_addr())), + connection_id: into_connection_id(&DefaultConnectionCookie::make_connection_cookie( + &sample_ipv4_remote_addr(), + )), transaction_id: TransactionId(0i32), info_hash: info_hash_aquatic, peer_id: AquaticPeerId(*b"-qB00000000000000000"), diff --git a/src/udp/connection_cookie.rs b/src/udp/connection_cookie.rs index a17431b9c..3f3433eb6 100644 --- a/src/udp/connection_cookie.rs +++ b/src/udp/connection_cookie.rs @@ -1,8 +1,14 @@ +use std::collections::hash_map::DefaultHasher; +use std::hash::{Hash, Hasher}; use std::net::SocketAddr; use aquatic_udp_protocol::ConnectionId; +use cipher::{BlockDecrypt, BlockEncrypt}; -use crate::protocol::clock::time_extent::{Extent, TimeExtent}; +use crate::protocol::clock::time_extent::{DefaultTimeExtentMaker, Extent, MakeTimeExtent, TimeExtent}; +use crate::protocol::clock::{DefaultClock, Time, TimeNow}; +use crate::protocol::crypto::keys::block_ciphers::{BlockCipherKeeper, CipherArray, DefaultBlockCipher}; +use crate::protocol::crypto::keys::seeds::{DefaultSeed, SeedKeeper}; use crate::udp::ServerError; pub type Cookie = [u8; 8]; @@ -19,43 +25,46 @@ pub fn into_connection_id(connection_cookie: &Cookie) -> ConnectionId { ConnectionId(i64::from_le_bytes(*connection_cookie)) } -pub fn make_connection_cookie(remote_address: &SocketAddr) -> Cookie { - let time_extent = cookie_builder::get_last_time_extent(); - - let cookie = cookie_builder::build(remote_address, &time_extent); - //println!("remote_address: {remote_address:?}, time_extent: {time_extent:?}, cookie: {cookie:?}"); - cookie +pub trait ConnectionCookie { + fn make_connection_cookie(remote_address: &SocketAddr) -> Cookie; + fn check_connection_cookie( + remote_address: &SocketAddr, + connection_cookie: &Cookie, + ) -> Result; } -pub fn check_connection_cookie( - remote_address: &SocketAddr, - connection_cookie: &Cookie, -) -> Result { - // we loop backwards testing each time_extent until we find one that matches. - // (or the lifetime of time_extents is exhausted) - for offset in 0..=COOKIE_LIFETIME.amount { - let checking_time_extent = cookie_builder::get_last_time_extent().decrease(offset).unwrap(); +pub type DefaultConnectionCookie = EncryptedConnectionCookie; - let checking_cookie = cookie_builder::build(remote_address, &checking_time_extent); - //println!("remote_address: {remote_address:?}, time_extent: {checking_time_extent:?}, cookie: {checking_cookie:?}"); +pub struct HashedConnectionCookie; - if *connection_cookie == checking_cookie { - return Ok(checking_time_extent); - } +impl ConnectionCookie for HashedConnectionCookie { + fn make_connection_cookie(remote_address: &SocketAddr) -> Cookie { + let time_extent = HashedConnectionCookie::get_last_time_extent(); + + HashedConnectionCookie::build(remote_address, &time_extent) } - Err(ServerError::InvalidConnectionId) -} -mod cookie_builder { - use std::collections::hash_map::DefaultHasher; - use std::hash::{Hash, Hasher}; - use std::net::SocketAddr; + fn check_connection_cookie( + remote_address: &SocketAddr, + connection_cookie: &Cookie, + ) -> Result { + // we loop backwards testing each time_extent until we find one that matches. + // (or the lifetime of time_extents is exhausted) + for offset in 0..=COOKIE_LIFETIME.amount { + let checking_time_extent = HashedConnectionCookie::get_last_time_extent().decrease(offset).unwrap(); - use super::{Cookie, SinceUnixEpochTimeExtent, COOKIE_LIFETIME}; - use crate::protocol::clock::time_extent::{DefaultTimeExtentMaker, Extent, MakeTimeExtent, TimeExtent}; - use crate::protocol::crypto::keys::seeds::{DefaultSeed, SeedKeeper}; + let checking_cookie = HashedConnectionCookie::build(remote_address, &checking_time_extent); - pub(super) fn get_last_time_extent() -> SinceUnixEpochTimeExtent { + if *connection_cookie == checking_cookie { + return Ok(checking_time_extent); + } + } + Err(ServerError::InvalidConnectionId) + } +} + +impl HashedConnectionCookie { + fn get_last_time_extent() -> SinceUnixEpochTimeExtent { DefaultTimeExtentMaker::now(&COOKIE_LIFETIME.increment) .unwrap() .unwrap() @@ -63,7 +72,7 @@ mod cookie_builder { .unwrap() } - pub(super) fn build(remote_address: &SocketAddr, time_extent: &TimeExtent) -> Cookie { + fn build(remote_address: &SocketAddr, time_extent: &TimeExtent) -> Cookie { let seed = DefaultSeed::get_seed(); let mut hasher = DefaultHasher::new(); @@ -76,170 +85,488 @@ mod cookie_builder { } } -#[cfg(test)] -mod tests { - use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; +pub struct WitnessConnectionCookie; - use super::cookie_builder::{self}; - use crate::protocol::clock::time_extent::{self, Extent}; - use crate::protocol::clock::{StoppedClock, StoppedTime}; - use crate::udp::connection_cookie::{check_connection_cookie, make_connection_cookie, Cookie, COOKIE_LIFETIME}; +impl ConnectionCookie for WitnessConnectionCookie { + fn make_connection_cookie(remote_address: &SocketAddr) -> Cookie { + // get the time that the cookie will expire. + let expiry_time = DefaultClock::add(&COOKIE_LIFETIME.total().unwrap().unwrap()) + .unwrap() + .as_secs_f32() + .to_le_bytes(); - // #![feature(const_socketaddr)] - // const REMOTE_ADDRESS_IPV4_ZERO: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); + WitnessConnectionCookie::build(remote_address, expiry_time) + } - #[test] - fn it_should_make_a_connection_cookie() { - let cookie = make_connection_cookie(&SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0)); + fn check_connection_cookie( + remote_address: &SocketAddr, + connection_cookie: &Cookie, + ) -> Result { + let expiry_time = WitnessConnectionCookie::extract_time(connection_cookie); + let time_clock = DefaultClock::now().as_secs_f32(); - // Note: This constant may need to be updated in the future as the hash is not guaranteed to to be stable between versions. - const ID_COOKIE: Cookie = [23, 204, 198, 29, 48, 180, 62, 19]; + //println!("expiry_time: {expiry_time:?}, time_clock: {time_clock:?}"); + + // lets check if the cookie has expired. + if expiry_time < time_clock { + return Err(ServerError::ExpiredConnectionId); + } - assert_eq!(cookie, ID_COOKIE) + if *connection_cookie != WitnessConnectionCookie::build(remote_address, expiry_time.to_le_bytes()) { + return Err(ServerError::BadWitnessConnectionId); + } + + Ok(TimeExtent::from_sec(1, &(expiry_time.round() as u64))) } +} - #[test] - fn it_should_make_the_same_connection_cookie_for_the_same_input_data() { - let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); - let time_extent_zero = time_extent::ZERO; +impl WitnessConnectionCookie { + fn build(remote_address: &SocketAddr, expiry: [u8; 4]) -> Cookie { + let seed = DefaultSeed::get_seed(); - let cookie = cookie_builder::build(&remote_address, &time_extent_zero); - let cookie_2 = cookie_builder::build(&remote_address, &time_extent_zero); + let mut hasher = DefaultHasher::new(); - println!("remote_address: {remote_address:?}, time_extent: {time_extent_zero:?}, cookie: {cookie:?}"); - println!("remote_address: {remote_address:?}, time_extent: {time_extent_zero:?}, cookie: {cookie_2:?}"); + remote_address.hash(&mut hasher); + seed.hash(&mut hasher); + expiry.hash(&mut hasher); - //remote_address: 127.0.0.1:8080, time_extent: TimeExtent { increment: 0ns, amount: 0 }, cookie: [212, 9, 204, 223, 176, 190, 150, 153] - //remote_address: 127.0.0.1:8080, time_extent: TimeExtent { increment: 0ns, amount: 0 }, cookie: [212, 9, 204, 223, 176, 190, 150, 153] + let witness = hasher.finish().to_le_bytes(); - assert_eq!(cookie, cookie_2) + [ + witness[0], witness[1], witness[2], witness[3], expiry[0], expiry[1], expiry[2], expiry[3], + ] } + fn extract_time(cookie: &Cookie) -> f32 { + f32::from_le_bytes([cookie[4], cookie[5], cookie[6], cookie[7]]) + } +} - #[test] - fn it_should_make_the_different_connection_cookie_for_different_ip() { - let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); - let remote_address_2 = SocketAddr::new(IpAddr::V4(Ipv4Addr::BROADCAST), 0); - let time_extent_zero = time_extent::ZERO; +pub struct EncryptedConnectionCookie; - let cookie = cookie_builder::build(&remote_address, &time_extent_zero); - let cookie_2 = cookie_builder::build(&remote_address_2, &time_extent_zero); +impl ConnectionCookie for EncryptedConnectionCookie { + fn make_connection_cookie(remote_address: &SocketAddr) -> Cookie { + // get the time that the cookie will expire. + let expiry_time = DefaultClock::add(&COOKIE_LIFETIME.total().unwrap().unwrap()) + .unwrap() + .as_secs_f32() + .to_le_bytes(); - println!("remote_address: {remote_address:?}, time_extent: {time_extent_zero:?}, cookie: {cookie:?}"); - println!("remote_address: {remote_address_2:?}, time_extent: {time_extent_zero:?}, cookie: {cookie_2:?}"); + EncryptedConnectionCookie::build(&EncryptedConnectionCookie::get_remote_hash(remote_address), expiry_time) + } - //remote_address: 0.0.0.0:0, time_extent: TimeExtent { increment: 0ns, amount: 0 }, cookie: [151, 130, 30, 157, 190, 41, 179, 135] - //remote_address: 255.255.255.255:0, time_extent: TimeExtent { increment: 0ns, amount: 0 }, cookie: [217, 87, 239, 178, 182, 126, 66, 166] + fn check_connection_cookie( + remote_address: &SocketAddr, + connection_cookie: &Cookie, + ) -> Result { + let cookie = EncryptedConnectionCookie::decode_cookie(connection_cookie); + let expiry_time = EncryptedConnectionCookie::extract_time(&cookie); + let time_clock = DefaultClock::now().as_secs_f32(); + let time_clock_expiry = DefaultClock::add(&COOKIE_LIFETIME.total().unwrap().unwrap()) + .unwrap() + .as_secs_f32(); + let remote_hash = EncryptedConnectionCookie::get_remote_hash(remote_address); - assert_ne!(cookie, cookie_2) - } + //println!("expiry_time: {expiry_time:?}, time_clock: {time_clock:?}"); - #[test] - fn it_should_make_the_different_connection_cookie_for_different_ip_version() { - let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); - let remote_address_2 = SocketAddr::new(IpAddr::V6(Ipv6Addr::UNSPECIFIED), 0); - let time_extent_zero = time_extent::ZERO; + // cannot to be too old. + if expiry_time < time_clock { + return Err(ServerError::ExpiredConnectionId); + } - let cookie = cookie_builder::build(&remote_address, &time_extent_zero); - let cookie_2 = cookie_builder::build(&remote_address_2, &time_extent_zero); + // or impossibly new. + if expiry_time > time_clock_expiry { + return Err(ServerError::BadWitnessConnectionId); + } - println!("remote_address: {remote_address:?}, time_extent: {time_extent_zero:?}, cookie: {cookie:?}"); - println!("remote_address: {remote_address_2:?}, time_extent: {time_extent_zero:?}, cookie: {cookie_2:?}"); + // and the remote hash should match + if cookie[0..4] != remote_hash[0..4] { + return Err(ServerError::BadWitnessConnectionId); + } - //remote_address: 0.0.0.0:0, time_extent: TimeExtent { increment: 0ns, amount: 0 }, cookie: [151, 130, 30, 157, 190, 41, 179, 135] - //remote_address: [::]:0, time_extent: TimeExtent { increment: 0ns, amount: 0 }, cookie: [99, 119, 230, 177, 20, 220, 163, 187] + Ok(TimeExtent::from_sec(1, &(expiry_time.round() as u64))) + } +} + +impl EncryptedConnectionCookie { + fn get_remote_hash(remote_address: &SocketAddr) -> [u8; 8] { + let mut hasher = DefaultHasher::new(); + + remote_address.hash(&mut hasher); - assert_ne!(cookie, cookie_2) + hasher.finish().to_le_bytes() } - #[test] - fn it_should_make_the_different_connection_cookie_for_different_socket() { - let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); - let remote_address_2 = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 1); - let time_extent_zero = time_extent::ZERO; + fn build(remote_hash: &[u8; 8], expiry: [u8; 4]) -> Cookie { + let mut array = CipherArray::from([ + remote_hash[0], + remote_hash[1], + remote_hash[2], + remote_hash[3], + expiry[0], + expiry[1], + expiry[2], + expiry[3], + ]); + + DefaultBlockCipher::get_block_cipher().encrypt_block(&mut array); + + array.into() + } - let cookie = cookie_builder::build(&remote_address, &time_extent_zero); - let cookie_2 = cookie_builder::build(&remote_address_2, &time_extent_zero); + fn decode_cookie(encoded_cookie: &Cookie) -> Cookie { + let mut array = CipherArray::from(*encoded_cookie); - println!("remote_address: {remote_address:?}, time_extent: {time_extent_zero:?}, cookie: {cookie:?}"); - println!("remote_address: {remote_address_2:?}, time_extent: {time_extent_zero:?}, cookie: {cookie_2:?}"); + DefaultBlockCipher::get_block_cipher().decrypt_block(&mut array); - //remote_address: 0.0.0.0:0, time_extent: TimeExtent { increment: 0ns, amount: 0 }, cookie: [151, 130, 30, 157, 190, 41, 179, 135] - //remote_address: 0.0.0.0:1, time_extent: TimeExtent { increment: 0ns, amount: 0 }, cookie: [38, 8, 0, 102, 92, 170, 220, 11] + array.into() + } - assert_ne!(cookie, cookie_2) + fn extract_time(cookie: &Cookie) -> f32 { + f32::from_le_bytes([cookie[4], cookie[5], cookie[6], cookie[7]]) } +} - #[test] - fn it_should_make_the_different_connection_cookie_for_different_time_extents() { - let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); - let time_extent_zero = time_extent::ZERO; - let time_extent_max = time_extent::MAX; +#[cfg(test)] +mod tests { + mod hashed_connection_cookie { + use std::net::{IpAddr, Ipv4Addr, SocketAddr}; - let cookie = cookie_builder::build(&remote_address, &time_extent_zero); - let cookie_2 = cookie_builder::build(&remote_address, &time_extent_max); + use crate::protocol::clock::time_extent::Extent; + use crate::protocol::clock::{StoppedClock, StoppedTime}; + use crate::udp::connection_cookie::{ + ConnectionCookie, Cookie, HashedConnectionCookie as TestConnectionCookie, COOKIE_LIFETIME, + }; - println!("remote_address: {remote_address:?}, time_extent: {time_extent_zero:?}, cookie: {cookie:?}"); - println!("remote_address: {remote_address:?}, time_extent: {time_extent_max:?}, cookie: {cookie_2:?}"); + #[test] + fn it_should_make_a_connection_cookie() { + let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); + let cookie = TestConnectionCookie::make_connection_cookie(&remote_address); - //remote_address: 0.0.0.0:0, time_extent: TimeExtent { increment: 0ns, amount: 0 }, cookie: [151, 130, 30, 157, 190, 41, 179, 135] - //remote_address: 0.0.0.0:0, time_extent: TimeExtent { increment: 18446744073709551615.999999999s, amount: 18446744073709551615 }, cookie: [87, 111, 109, 125, 182, 206, 3, 201] + // Note: This constant may need to be updated in the future as the hash is not guaranteed to to be stable between versions. + const ID_COOKIE: Cookie = [23, 204, 198, 29, 48, 180, 62, 19]; - assert_ne!(cookie, cookie_2) - } + assert_eq!(cookie, ID_COOKIE) + } + + #[test] + fn it_should_make_different_cookies_for_the_next_time_extent() { + let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); + let cookie = TestConnectionCookie::make_connection_cookie(&remote_address); - #[test] - fn it_should_make_different_cookies_for_the_next_time_extent() { - let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); + StoppedClock::local_add(&COOKIE_LIFETIME.increment).unwrap(); - let cookie = make_connection_cookie(&remote_address); + let cookie_next = TestConnectionCookie::make_connection_cookie(&remote_address); - StoppedClock::local_add(&COOKIE_LIFETIME.increment).unwrap(); + assert_ne!(cookie, cookie_next) + } - let cookie_next = make_connection_cookie(&remote_address); + #[test] + fn it_should_be_valid_for_this_time_extent() { + let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); - assert_ne!(cookie, cookie_next) - } + let cookie = TestConnectionCookie::make_connection_cookie(&remote_address); - #[test] - fn it_should_be_valid_for_this_time_extent() { - let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); + TestConnectionCookie::check_connection_cookie(&remote_address, &cookie).unwrap(); + } - let cookie = make_connection_cookie(&remote_address); + #[test] + fn it_should_be_valid_for_the_next_time_extent() { + let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); - check_connection_cookie(&remote_address, &cookie).unwrap(); - } + let cookie = TestConnectionCookie::make_connection_cookie(&remote_address); + + StoppedClock::local_add(&COOKIE_LIFETIME.increment).unwrap(); + + TestConnectionCookie::check_connection_cookie(&remote_address, &cookie).unwrap(); + } + + #[test] + fn it_should_be_valid_for_the_last_time_extent() { + let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); + + let cookie = TestConnectionCookie::make_connection_cookie(&remote_address); + + StoppedClock::local_set(&COOKIE_LIFETIME.total().unwrap().unwrap()); + + TestConnectionCookie::check_connection_cookie(&remote_address, &cookie).unwrap(); + } + + #[test] + #[should_panic] + fn it_should_be_not_valid_after_their_last_time_extent() { + let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); + + let cookie = TestConnectionCookie::make_connection_cookie(&remote_address); + + StoppedClock::local_set(&COOKIE_LIFETIME.total_next().unwrap().unwrap()); + + TestConnectionCookie::check_connection_cookie(&remote_address, &cookie).unwrap(); + } + + mod detail { + use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; + + use crate::protocol::clock::time_extent; + use crate::udp::connection_cookie::HashedConnectionCookie; + + #[test] + fn it_should_build_the_same_connection_cookie_for_the_same_input_data() { + let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); + let time_extent_zero = time_extent::ZERO; + + let cookie = HashedConnectionCookie::build(&remote_address, &time_extent_zero); + let cookie_2 = HashedConnectionCookie::build(&remote_address, &time_extent_zero); + + assert_eq!(cookie, cookie_2) + } + + #[test] + fn it_should_build_the_different_connection_cookie_for_different_ip() { + let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); + let remote_address_2 = SocketAddr::new(IpAddr::V4(Ipv4Addr::BROADCAST), 0); + let time_extent_zero = time_extent::ZERO; + + let cookie = HashedConnectionCookie::build(&remote_address, &time_extent_zero); + let cookie_2 = HashedConnectionCookie::build(&remote_address_2, &time_extent_zero); + + assert_ne!(cookie, cookie_2) + } + + #[test] + fn it_should_build_the_different_connection_cookie_for_different_ip_version() { + let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); + let remote_address_2 = SocketAddr::new(IpAddr::V6(Ipv6Addr::UNSPECIFIED), 0); + let time_extent_zero = time_extent::ZERO; - #[test] - fn it_should_be_valid_for_the_next_time_extent() { - let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); + let cookie = HashedConnectionCookie::build(&remote_address, &time_extent_zero); + let cookie_2 = HashedConnectionCookie::build(&remote_address_2, &time_extent_zero); - let cookie = make_connection_cookie(&remote_address); + assert_ne!(cookie, cookie_2) + } - StoppedClock::local_add(&COOKIE_LIFETIME.increment).unwrap(); + #[test] + fn it_should_build_the_different_connection_cookie_for_different_socket() { + let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); + let remote_address_2 = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 1); + let time_extent_zero = time_extent::ZERO; - check_connection_cookie(&remote_address, &cookie).unwrap(); + let cookie = HashedConnectionCookie::build(&remote_address, &time_extent_zero); + let cookie_2 = HashedConnectionCookie::build(&remote_address_2, &time_extent_zero); + + assert_ne!(cookie, cookie_2) + } + + #[test] + fn it_should_build_the_different_connection_cookie_for_different_time_extents() { + let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); + let time_extent_zero = time_extent::ZERO; + let time_extent_max = time_extent::MAX; + + let cookie = HashedConnectionCookie::build(&remote_address, &time_extent_zero); + let cookie_2 = HashedConnectionCookie::build(&remote_address, &time_extent_max); + + assert_ne!(cookie, cookie_2) + } + } } + mod witness_connection_cookie { + use std::net::{IpAddr, Ipv4Addr, SocketAddr}; + + use crate::protocol::clock::time_extent::Extent; + use crate::protocol::clock::{StoppedClock, StoppedTime}; + use crate::udp::connection_cookie::{ + ConnectionCookie, Cookie, WitnessConnectionCookie as TestConnectionCookie, COOKIE_LIFETIME, + }; + + #[test] + fn it_should_make_a_connection_cookie() { + let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); + let cookie = TestConnectionCookie::make_connection_cookie(&remote_address); + + // Note: This constant may need to be updated in the future as the hash is not guaranteed to to be stable between versions. + const ID_COOKIE: Cookie = [72, 245, 201, 136, 0, 0, 240, 66]; + + assert_eq!(cookie, ID_COOKIE) + } + + #[test] + fn it_should_make_different_cookies_for_the_next_time_extent() { + let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); + + let cookie = TestConnectionCookie::make_connection_cookie(&remote_address); + + StoppedClock::local_add(&COOKIE_LIFETIME.increment).unwrap(); + + let cookie_next = TestConnectionCookie::make_connection_cookie(&remote_address); + + assert_ne!(cookie, cookie_next) + } + + #[test] + fn it_should_be_valid_for_this_time_extent() { + let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); + + let cookie = TestConnectionCookie::make_connection_cookie(&remote_address); + + TestConnectionCookie::check_connection_cookie(&remote_address, &cookie).unwrap(); + } + + #[test] + fn it_should_be_valid_for_the_next_time_extent() { + let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); + + let cookie = TestConnectionCookie::make_connection_cookie(&remote_address); + + StoppedClock::local_add(&COOKIE_LIFETIME.increment).unwrap(); + + TestConnectionCookie::check_connection_cookie(&remote_address, &cookie).unwrap(); + } + + #[test] + fn it_should_be_valid_for_the_last_time_extent() { + let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); + + let cookie = TestConnectionCookie::make_connection_cookie(&remote_address); + + StoppedClock::local_set(&COOKIE_LIFETIME.total().unwrap().unwrap()); + + TestConnectionCookie::check_connection_cookie(&remote_address, &cookie).unwrap(); + } + + #[test] + #[should_panic] + fn it_should_be_not_valid_after_their_last_time_extent() { + let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); + + let cookie = TestConnectionCookie::make_connection_cookie(&remote_address); + + StoppedClock::local_set(&COOKIE_LIFETIME.total_next().unwrap().unwrap()); + + TestConnectionCookie::check_connection_cookie(&remote_address, &cookie).unwrap(); + } - #[test] - fn it_should_be_valid_for_the_last_time_extent() { - let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); + mod detail { + use std::net::{IpAddr, Ipv4Addr, SocketAddr}; - let cookie = make_connection_cookie(&remote_address); + use crate::udp::connection_cookie::WitnessConnectionCookie; - StoppedClock::local_set(&COOKIE_LIFETIME.total().unwrap().unwrap()); + #[test] + fn it_should_build_the_same_connection_cookie_for_the_same_input_data() { + let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); + let expiry_zero = [0u8; 4]; - check_connection_cookie(&remote_address, &cookie).unwrap(); + let cookie = WitnessConnectionCookie::build(&remote_address, expiry_zero); + let cookie_2 = WitnessConnectionCookie::build(&remote_address, expiry_zero); + + // witness is the same, and the times are the same. + assert_eq!(cookie[0..4], cookie_2[0..4]); + assert_eq!(cookie[5..8], cookie_2[5..8]); + } + + #[test] + fn it_should_build_the_different_connection_cookie_for_different_ip() { + let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); + let remote_address_2 = SocketAddr::new(IpAddr::V4(Ipv4Addr::BROADCAST), 0); + let expiry_zero = [0u8; 4]; + + let cookie = WitnessConnectionCookie::build(&remote_address, expiry_zero); + let cookie_2 = WitnessConnectionCookie::build(&remote_address_2, expiry_zero); + + // witness is different, but the times are the same. + assert_ne!(cookie[0..4], cookie_2[0..4]); + assert_eq!(cookie[5..8], cookie_2[5..8]); + } + + #[test] + fn it_should_build_the_different_connection_cookie_for_different_expires() { + let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); + let expiry_zero = [0u8; 4]; + let expiry_max = [255u8; 4]; + + let cookie = WitnessConnectionCookie::build(&remote_address, expiry_zero); + let cookie_2 = WitnessConnectionCookie::build(&remote_address, expiry_max); + + // witness is different, and the times are different. + assert_ne!(cookie[0..4], cookie_2[0..4]); + assert_ne!(cookie[5..8], cookie_2[5..8]); + } + } } - #[test] - #[should_panic] - fn it_should_be_not_valid_after_their_last_time_extent() { - let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); + mod encrypted_connection_cookie { + use std::net::{IpAddr, Ipv4Addr, SocketAddr}; + + use crate::protocol::clock::time_extent::Extent; + use crate::protocol::clock::{StoppedClock, StoppedTime}; + use crate::udp::connection_cookie::{ + ConnectionCookie, Cookie, EncryptedConnectionCookie as TestConnectionCookie, COOKIE_LIFETIME, + }; - let cookie = make_connection_cookie(&remote_address); + #[test] + fn it_should_make_a_connection_cookie() { + let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); + let cookie = TestConnectionCookie::make_connection_cookie(&remote_address); + + // Note: This constant may need to be updated in the future as the hash is not guaranteed to to be stable between versions. + const ID_COOKIE: Cookie = [234, 229, 134, 15, 217, 77, 208, 204]; + + assert_eq!(cookie, ID_COOKIE) + } + + #[test] + fn it_should_make_different_cookies_for_the_next_time_extent() { + let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); + + let cookie = TestConnectionCookie::make_connection_cookie(&remote_address); + + StoppedClock::local_add(&COOKIE_LIFETIME.increment).unwrap(); + + let cookie_next = TestConnectionCookie::make_connection_cookie(&remote_address); + + assert_ne!(cookie, cookie_next) + } - StoppedClock::local_set(&COOKIE_LIFETIME.total_next().unwrap().unwrap()); + #[test] + fn it_should_be_valid_for_this_time_extent() { + let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); - check_connection_cookie(&remote_address, &cookie).unwrap(); + let cookie = TestConnectionCookie::make_connection_cookie(&remote_address); + + TestConnectionCookie::check_connection_cookie(&remote_address, &cookie).unwrap(); + } + + #[test] + fn it_should_be_valid_for_the_next_time_extent() { + let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); + + let cookie = TestConnectionCookie::make_connection_cookie(&remote_address); + + StoppedClock::local_add(&COOKIE_LIFETIME.increment).unwrap(); + + TestConnectionCookie::check_connection_cookie(&remote_address, &cookie).unwrap(); + } + + #[test] + fn it_should_be_valid_for_the_last_time_extent() { + let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); + + let cookie = TestConnectionCookie::make_connection_cookie(&remote_address); + + StoppedClock::local_set(&COOKIE_LIFETIME.total().unwrap().unwrap()); + + TestConnectionCookie::check_connection_cookie(&remote_address, &cookie).unwrap(); + } + + #[test] + #[should_panic] + fn it_should_be_not_valid_after_their_last_time_extent() { + let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); + + let cookie = TestConnectionCookie::make_connection_cookie(&remote_address); + + StoppedClock::local_set(&COOKIE_LIFETIME.total_next().unwrap().unwrap()); + + TestConnectionCookie::check_connection_cookie(&remote_address, &cookie).unwrap(); + } } } diff --git a/src/udp/errors.rs b/src/udp/errors.rs index 8d7b04b4f..b6ecd886e 100644 --- a/src/udp/errors.rs +++ b/src/udp/errors.rs @@ -11,6 +11,12 @@ pub enum ServerError { #[error("connection id could not be verified")] InvalidConnectionId, + #[error("connection id expired")] + ExpiredConnectionId, + + #[error("connection bad witness")] + BadWitnessConnectionId, + #[error("could not find remote address")] AddressNotFound, diff --git a/src/udp/handlers.rs b/src/udp/handlers.rs index 845b860e9..c2405cdea 100644 --- a/src/udp/handlers.rs +++ b/src/udp/handlers.rs @@ -6,7 +6,7 @@ use aquatic_udp_protocol::{ NumberOfPeers, Port, Request, Response, ResponsePeer, ScrapeRequest, ScrapeResponse, TorrentScrapeStatistics, TransactionId, }; -use super::connection_cookie::{check_connection_cookie, from_connection_id, into_connection_id, make_connection_cookie}; +use super::connection_cookie::{from_connection_id, into_connection_id, ConnectionCookie, DefaultConnectionCookie}; use crate::peer::TorrentPeer; use crate::tracker::statistics::TrackerStatisticsEvent; use crate::tracker::torrent::TorrentError; @@ -69,7 +69,7 @@ pub async fn handle_connect( request: &ConnectRequest, tracker: Arc, ) -> Result { - let connection_cookie = make_connection_cookie(&remote_addr); + let connection_cookie = DefaultConnectionCookie::make_connection_cookie(&remote_addr); let connection_id = into_connection_id(&connection_cookie); let response = Response::from(ConnectResponse { @@ -95,7 +95,7 @@ pub async fn handle_announce( announce_request: &AnnounceRequest, tracker: Arc, ) -> Result { - match check_connection_cookie(&remote_addr, &from_connection_id(&announce_request.connection_id)) { + match DefaultConnectionCookie::check_connection_cookie(&remote_addr, &from_connection_id(&announce_request.connection_id)) { Ok(_) => {} Err(e) => { return Err(e); @@ -411,7 +411,7 @@ mod tests { use super::{default_tracker_config, sample_ipv4_socket_address, sample_ipv6_remote_addr, TrackerStatsServiceMock}; use crate::statistics::TrackerStatisticsEvent; use crate::tracker::tracker::TorrentTracker; - use crate::udp::connection_cookie::{into_connection_id, make_connection_cookie}; + use crate::udp::connection_cookie::{into_connection_id, ConnectionCookie, DefaultConnectionCookie}; use crate::udp::handle_connect; use crate::udp::handlers::tests::{initialized_public_tracker, sample_ipv4_remote_addr}; @@ -434,7 +434,9 @@ mod tests { assert_eq!( response, Response::Connect(ConnectResponse { - connection_id: into_connection_id(&make_connection_cookie(&sample_ipv4_remote_addr())), + connection_id: into_connection_id(&DefaultConnectionCookie::make_connection_cookie( + &sample_ipv4_remote_addr() + )), transaction_id: request.transaction_id }) ); @@ -453,7 +455,9 @@ mod tests { assert_eq!( response, Response::Connect(ConnectResponse { - connection_id: into_connection_id(&make_connection_cookie(&sample_ipv4_remote_addr())), + connection_id: into_connection_id(&DefaultConnectionCookie::make_connection_cookie( + &sample_ipv4_remote_addr() + )), transaction_id: request.transaction_id }) ); @@ -494,7 +498,7 @@ mod tests { TransactionId, }; - use crate::udp::connection_cookie::{into_connection_id, make_connection_cookie}; + use crate::udp::connection_cookie::{into_connection_id, ConnectionCookie, DefaultConnectionCookie}; use crate::udp::handlers::tests::sample_ipv4_remote_addr; struct AnnounceRequestBuilder { @@ -508,7 +512,9 @@ mod tests { let info_hash_aquatic = aquatic_udp_protocol::InfoHash([0u8; 20]); let default_request = AnnounceRequest { - connection_id: into_connection_id(&make_connection_cookie(&sample_ipv4_remote_addr())), + connection_id: into_connection_id(&DefaultConnectionCookie::make_connection_cookie( + &sample_ipv4_remote_addr(), + )), transaction_id: TransactionId(0i32), info_hash: info_hash_aquatic, peer_id: AquaticPeerId([255u8; 20]), @@ -568,7 +574,7 @@ mod tests { use crate::statistics::TrackerStatisticsEvent; use crate::tracker::tracker::TorrentTracker; - use crate::udp::connection_cookie::{into_connection_id, make_connection_cookie}; + use crate::udp::connection_cookie::{into_connection_id, ConnectionCookie, DefaultConnectionCookie}; use crate::udp::handle_announce; use crate::udp::handlers::tests::announce_request::AnnounceRequestBuilder; use crate::udp::handlers::tests::{ @@ -589,7 +595,9 @@ mod tests { let remote_addr = SocketAddr::new(IpAddr::V4(client_ip), client_port); let request = AnnounceRequestBuilder::default() - .with_connection_id(into_connection_id(&make_connection_cookie(&remote_addr))) + .with_connection_id(into_connection_id(&DefaultConnectionCookie::make_connection_cookie( + &remote_addr, + ))) .with_info_hash(info_hash) .with_peer_id(peer_id) .with_ip_address(client_ip) @@ -613,7 +621,9 @@ mod tests { let remote_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(126, 0, 0, 1)), 8080); let request = AnnounceRequestBuilder::default() - .with_connection_id(into_connection_id(&make_connection_cookie(&remote_addr))) + .with_connection_id(into_connection_id(&DefaultConnectionCookie::make_connection_cookie( + &remote_addr, + ))) .into(); let response = handle_announce(remote_addr, &request, initialized_public_tracker()) @@ -652,7 +662,9 @@ mod tests { let remote_addr = SocketAddr::new(IpAddr::V4(remote_client_ip), remote_client_port); let request = AnnounceRequestBuilder::default() - .with_connection_id(into_connection_id(&make_connection_cookie(&remote_addr))) + .with_connection_id(into_connection_id(&DefaultConnectionCookie::make_connection_cookie( + &remote_addr, + ))) .with_info_hash(info_hash) .with_peer_id(peer_id) .with_ip_address(peer_address) @@ -687,7 +699,9 @@ mod tests { async fn announce_a_new_peer_using_ipv4(tracker: Arc) -> Response { let remote_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(126, 0, 0, 1)), 8080); let request = AnnounceRequestBuilder::default() - .with_connection_id(into_connection_id(&make_connection_cookie(&remote_addr))) + .with_connection_id(into_connection_id(&DefaultConnectionCookie::make_connection_cookie( + &remote_addr, + ))) .into(); let response = handle_announce(remote_addr, &request, tracker.clone()).await.unwrap(); response @@ -731,7 +745,7 @@ mod tests { use aquatic_udp_protocol::{InfoHash as AquaticInfoHash, PeerId as AquaticPeerId}; - use crate::udp::connection_cookie::{into_connection_id, make_connection_cookie}; + use crate::udp::connection_cookie::{into_connection_id, ConnectionCookie, DefaultConnectionCookie}; use crate::udp::handle_announce; use crate::udp::handlers::tests::announce_request::AnnounceRequestBuilder; use crate::udp::handlers::tests::{initialized_public_tracker, TorrentPeerBuilder}; @@ -749,7 +763,9 @@ mod tests { let remote_addr = SocketAddr::new(IpAddr::V4(client_ip), client_port); let request = AnnounceRequestBuilder::default() - .with_connection_id(into_connection_id(&make_connection_cookie(&remote_addr))) + .with_connection_id(into_connection_id(&DefaultConnectionCookie::make_connection_cookie( + &remote_addr, + ))) .with_info_hash(info_hash) .with_peer_id(peer_id) .with_ip_address(client_ip) @@ -785,7 +801,7 @@ mod tests { use crate::statistics::TrackerStatisticsEvent; use crate::tracker::tracker::TorrentTracker; - use crate::udp::connection_cookie::{into_connection_id, make_connection_cookie}; + use crate::udp::connection_cookie::{into_connection_id, ConnectionCookie, DefaultConnectionCookie}; use crate::udp::handle_announce; use crate::udp::handlers::tests::announce_request::AnnounceRequestBuilder; use crate::udp::handlers::tests::{ @@ -807,7 +823,9 @@ mod tests { let remote_addr = SocketAddr::new(IpAddr::V6(client_ip_v6), client_port); let request = AnnounceRequestBuilder::default() - .with_connection_id(into_connection_id(&make_connection_cookie(&remote_addr))) + .with_connection_id(into_connection_id(&DefaultConnectionCookie::make_connection_cookie( + &remote_addr, + ))) .with_info_hash(info_hash) .with_peer_id(peer_id) .with_ip_address(client_ip_v4) @@ -834,7 +852,9 @@ mod tests { let remote_addr = SocketAddr::new(IpAddr::V6(client_ip_v6), 8080); let request = AnnounceRequestBuilder::default() - .with_connection_id(into_connection_id(&make_connection_cookie(&remote_addr))) + .with_connection_id(into_connection_id(&DefaultConnectionCookie::make_connection_cookie( + &remote_addr, + ))) .into(); let response = handle_announce(remote_addr, &request, initialized_public_tracker()) @@ -873,7 +893,9 @@ mod tests { let remote_addr = SocketAddr::new(IpAddr::V6(remote_client_ip), remote_client_port); let request = AnnounceRequestBuilder::default() - .with_connection_id(into_connection_id(&make_connection_cookie(&remote_addr))) + .with_connection_id(into_connection_id(&DefaultConnectionCookie::make_connection_cookie( + &remote_addr, + ))) .with_info_hash(info_hash) .with_peer_id(peer_id) .with_ip_address(peer_address) @@ -911,7 +933,9 @@ mod tests { let client_port = 8080; let remote_addr = SocketAddr::new(IpAddr::V6(client_ip_v6), client_port); let request = AnnounceRequestBuilder::default() - .with_connection_id(into_connection_id(&make_connection_cookie(&remote_addr))) + .with_connection_id(into_connection_id(&DefaultConnectionCookie::make_connection_cookie( + &remote_addr, + ))) .into(); let response = handle_announce(remote_addr, &request, tracker.clone()).await.unwrap(); response @@ -945,7 +969,9 @@ mod tests { let remote_addr = sample_ipv6_remote_addr(); let announce_request = AnnounceRequestBuilder::default() - .with_connection_id(into_connection_id(&make_connection_cookie(&remote_addr))) + .with_connection_id(into_connection_id(&DefaultConnectionCookie::make_connection_cookie( + &remote_addr, + ))) .into(); handle_announce(remote_addr, &announce_request, tracker.clone()) @@ -961,7 +987,7 @@ mod tests { use crate::statistics::StatsTracker; use crate::tracker::tracker::TorrentTracker; - use crate::udp::connection_cookie::{into_connection_id, make_connection_cookie}; + use crate::udp::connection_cookie::{into_connection_id, ConnectionCookie, DefaultConnectionCookie}; use crate::udp::handle_announce; use crate::udp::handlers::tests::announce_request::AnnounceRequestBuilder; use crate::udp::handlers::tests::TrackerConfigurationBuilder; @@ -985,7 +1011,9 @@ mod tests { let remote_addr = SocketAddr::new(IpAddr::V6(client_ip_v6), client_port); let request = AnnounceRequestBuilder::default() - .with_connection_id(into_connection_id(&make_connection_cookie(&remote_addr))) + .with_connection_id(into_connection_id(&DefaultConnectionCookie::make_connection_cookie( + &remote_addr, + ))) .with_info_hash(info_hash) .with_peer_id(peer_id) .with_ip_address(client_ip_v4) @@ -1021,7 +1049,7 @@ mod tests { use super::TorrentPeerBuilder; use crate::tracker::tracker::TorrentTracker; - use crate::udp::connection_cookie::{into_connection_id, make_connection_cookie}; + use crate::udp::connection_cookie::{into_connection_id, ConnectionCookie, DefaultConnectionCookie}; use crate::udp::handle_scrape; use crate::udp::handlers::tests::{initialized_public_tracker, sample_ipv4_remote_addr}; use crate::PeerId; @@ -1042,7 +1070,7 @@ mod tests { let info_hashes = vec![info_hash]; let request = ScrapeRequest { - connection_id: into_connection_id(&make_connection_cookie(&remote_addr)), + connection_id: into_connection_id(&DefaultConnectionCookie::make_connection_cookie(&remote_addr)), transaction_id: TransactionId(0i32), info_hashes, }; @@ -1080,7 +1108,7 @@ mod tests { let info_hashes = vec![*info_hash]; ScrapeRequest { - connection_id: into_connection_id(&make_connection_cookie(&remote_addr)), + connection_id: into_connection_id(&DefaultConnectionCookie::make_connection_cookie(&remote_addr)), transaction_id: TransactionId(0i32), info_hashes, } @@ -1225,7 +1253,7 @@ mod tests { let info_hashes = vec![info_hash]; ScrapeRequest { - connection_id: into_connection_id(&make_connection_cookie(&remote_addr)), + connection_id: into_connection_id(&DefaultConnectionCookie::make_connection_cookie(&remote_addr)), transaction_id: TransactionId(0i32), info_hashes, }