diff --git a/Cargo.lock b/Cargo.lock index ee733098ef..bbeab0af36 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,11 +2,35 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[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 = "arg_parser" version = "0.1.0" source = "git+https://gitlab.redox-os.org/redox-os/arg-parser.git#1c434b55f3e1a0375ebcca85b3e88db7378e82fa" +[[package]] +name = "atomic-polyfill" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ff7eb3f316534d83a8a2c3d1674ace8a5a71198eba31e2e2b597833f699b28" +dependencies = [ + "critical-section", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -19,6 +43,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bumpalo" +version = "3.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" + [[package]] name = "byteorder" version = "0.5.3" @@ -31,6 +61,15 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + [[package]] name = "cfg-if" version = "0.1.10" @@ -43,6 +82,33 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95ed24df0632f708f5f6d8082675bef2596f7084dee3dd55f632290bf35bfe0f" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "time", + "wasm-bindgen", + "windows-targets", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + +[[package]] +name = "critical-section" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" + [[package]] name = "crossbeam-channel" version = "0.5.8" @@ -62,6 +128,38 @@ dependencies = [ "cfg-if 1.0.0", ] +[[package]] +name = "defmt" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8a2d011b2fee29fb7d659b83c43fce9a2cb4df453e16d441a51448e448f3f98" +dependencies = [ + "bitflags", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54f0216f6c5acb5ae1a47050a6645024e6edafc2ee32d421955eccfef12ef92e" +dependencies = [ + "defmt-parser", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.29", +] + +[[package]] +name = "defmt-parser" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "269924c02afd7f94bc4cecbfa5c379f6ffcf9766b3408fe63d22c728654eccd0" +dependencies = [ + "thiserror", +] + [[package]] name = "dns-parser" version = "0.7.1" @@ -73,25 +171,49 @@ dependencies = [ ] [[package]] -name = "extra" -version = "0.1.0" -source = "git+https://gitlab.redox-os.org/redox-os/libextra.git#cf213969493db8667052a591e32a1e26d43c4234" - -[[package]] -name = "fuchsia-zircon" -version = "0.3.3" +name = "hash32" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" dependencies = [ - "bitflags", - "fuchsia-zircon-sys", + "byteorder 1.4.3", ] [[package]] -name = "fuchsia-zircon-sys" -version = "0.3.3" +name = "heapless" +version = "0.7.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" +checksum = "db04bc24a18b9ea980628ecf00e6c0264f3c1426dac36c00cb49b6fbad8b0743" +dependencies = [ + "atomic-polyfill", + "hash32", + "rustc_version", + "spin", + "stable_deref_trait", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] [[package]] name = "idna" @@ -105,30 +227,14 @@ dependencies = [ ] [[package]] -name = "iovec" -version = "0.1.4" +name = "js-sys" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" dependencies = [ - "libc", + "wasm-bindgen", ] -[[package]] -name = "kernel32-sys" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -dependencies = [ - "winapi 0.2.8", - "winapi-build", -] - -[[package]] -name = "lazycell" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef" - [[package]] name = "libc" version = "0.2.147" @@ -136,12 +242,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] -name = "log" -version = "0.3.9" +name = "lock_api" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" dependencies = [ - "log 0.4.20", + "autocfg", + "scopeguard", ] [[package]] @@ -152,9 +259,9 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "managed" -version = "0.7.2" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75de51135344a4f8ed3cfe2720dc27736f7711989703a0b43aadf3753c55577" +checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d" [[package]] name = "matches" @@ -162,36 +269,6 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" -[[package]] -name = "mio" -version = "0.6.14" -source = "git+https://gitlab.redox-os.org/redox-os/mio.git?branch=redox-unix#c9a70849ced97387e2607c9c466d23b130ec8901" -dependencies = [ - "fuchsia-zircon", - "fuchsia-zircon-sys", - "iovec", - "kernel32-sys", - "lazycell", - "libc", - "log 0.4.20", - "miow", - "net2", - "slab", - "winapi 0.2.8", -] - -[[package]] -name = "miow" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" -dependencies = [ - "kernel32-sys", - "net2", - "winapi 0.2.8", - "ws2_32-sys", -] - [[package]] name = "net2" version = "0.2.37" @@ -199,24 +276,22 @@ source = "git+https://gitlab.redox-os.org/redox-os/net2-rs.git?branch=master#db0 dependencies = [ "cfg-if 0.1.10", "libc", - "winapi 0.3.9", + "winapi", ] [[package]] name = "netutils" version = "0.1.0" -source = "git+https://gitlab.redox-os.org/redox-os/netutils.git?branch=redox-unix#105ed1ea43413a91152b289fbe76e7efc996e933" +source = "git+https://gitlab.redox-os.org/redox-os/netutils.git#fc11b9bb3c1f5eefccb93ae670e4ec8b3d6fad4f" dependencies = [ "arg_parser", - "extra", "libc", - "mio", "net2", "ntpclient", "pbr", "redox-daemon", "redox_event", - "redox_syscall 0.2.16", + "redox_syscall 0.3.5", "redox_termios", "termion", "url", @@ -231,12 +306,27 @@ dependencies = [ "time", ] +[[package]] +name = "num-traits" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +dependencies = [ + "autocfg", +] + [[package]] name = "numtoa" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + [[package]] name = "pbr" version = "1.1.1" @@ -245,7 +335,7 @@ checksum = "ed5827dfa0d69b6c92493d6c38e633bbaa5937c153d0d7c28bf12313f8c6d514" dependencies = [ "crossbeam-channel", "libc", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -254,12 +344,54 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +dependencies = [ + "unicode-ident", +] + [[package]] name = "quick-error" version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + [[package]] name = "redox-daemon" version = "0.1.1" @@ -270,6 +402,18 @@ dependencies = [ "redox_syscall 0.3.5", ] +[[package]] +name = "redox-log" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf6d33a003a5c0b94ec11f10c7c797303f236592964ddb1bfb93e1b438a1557" +dependencies = [ + "chrono", + "log", + "smallvec", + "termion", +] + [[package]] name = "redox_event" version = "0.1.0" @@ -284,9 +428,10 @@ version = "0.1.0" dependencies = [ "byteorder 1.4.3", "dns-parser", - "log 0.3.9", + "log", "netutils", "redox-daemon", + "redox-log", "redox_event", "redox_syscall 0.3.5", "smoltcp", @@ -320,23 +465,83 @@ dependencies = [ ] [[package]] -name = "slab" -version = "0.4.9" +name = "rustc_version" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "autocfg", + "semver", ] +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "semver" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" + +[[package]] +name = "smallvec" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" + [[package]] name = "smoltcp" -version = "0.5.0" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d2e3a36ac8fea7b94e666dfa3871063d6e0a5c9d5d4fec9a1a6b7b6760f0229" dependencies = [ "bitflags", "byteorder 1.4.3", + "cfg-if 1.0.0", + "defmt", + "heapless", + "log", "managed", ] +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "termion" version = "1.5.6" @@ -349,6 +554,26 @@ dependencies = [ "redox_termios", ] +[[package]] +name = "thiserror" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97a802ec30afc17eee47b2855fc72e0c4cd62be9b4efe6591edde0ec5bd68d8f" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bb623b56e39ab7dcd4b1b98bb6c8f8d907ed255b18de254088016b27a8ee19b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.29", +] + [[package]] name = "time" version = "0.1.45" @@ -357,7 +582,7 @@ checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" dependencies = [ "libc", "wasi", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -381,6 +606,12 @@ version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +[[package]] +name = "unicode-ident" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" + [[package]] name = "unicode-normalization" version = "0.1.22" @@ -401,6 +632,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + [[package]] name = "wasi" version = "0.10.0+wasi-snapshot-preview1" @@ -408,10 +645,58 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" [[package]] -name = "winapi" -version = "0.2.8" +name = "wasm-bindgen" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.29", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.29", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "winapi" @@ -423,12 +708,6 @@ dependencies = [ "winapi-x86_64-pc-windows-gnu", ] -[[package]] -name = "winapi-build" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" - [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" @@ -442,11 +721,72 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "ws2_32-sys" -version = "0.2.1" +name = "windows" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "winapi 0.2.8", - "winapi-build", + "windows-targets", ] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[patch.unused]] +name = "mio" +version = "0.6.14" +source = "git+https://gitlab.redox-os.org/redox-os/mio.git?branch=redox-unix#c9a70849ced97387e2607c9c466d23b130ec8901" diff --git a/Cargo.toml b/Cargo.toml index e6d2d024d1..50e95a2aa1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,16 +27,17 @@ dns-parser = "0.7.1" [dependencies.log] version = "0.4" default-features = false -features = ["release_max_level_warn"] +features = ["release_max_level_debug"] [dependencies.smoltcp] version = "0.10.0" default-features = false features = [ "std", - "medium-ethernet", + "medium-ethernet", "medium-ip", "proto-ipv4", "socket-raw", "socket-icmp", "socket-udp", "socket-tcp", + "iface-max-addr-count-8", "log" ] #For debugging: "log", "verbose" diff --git a/src/smolnetd/device.rs b/src/smolnetd/device.rs deleted file mode 100644 index 3c276fe558..0000000000 --- a/src/smolnetd/device.rs +++ /dev/null @@ -1,123 +0,0 @@ -use smoltcp; -use std::cell::RefCell; -use std::collections::VecDeque; -use std::fs::File; -use std::io::Write; -use std::rc::Rc; - -use smoltcp::time::Instant; -use smoltcp::wire::EthernetAddress; -use crate::buffer_pool::{Buffer, BufferPool}; - -struct NetworkDeviceData { - network_file: Rc>, - input_queue: Rc>>, - local_hwaddr: smoltcp::wire::EthernetAddress, - buffer_pool: Rc>, -} - -pub struct NetworkDevice { - data: Rc>, -} - -impl NetworkDevice { - pub const MTU: usize = 1520; - - pub fn new( - network_file: Rc>, - input_queue: Rc>>, - local_hwaddr: smoltcp::wire::EthernetAddress, - buffer_pool: Rc>, - ) -> NetworkDevice { - NetworkDevice { - data: Rc::new(RefCell::new(NetworkDeviceData { - network_file, - input_queue, - local_hwaddr, - buffer_pool, - })), - } - } -} - -pub struct RxToken { - buffer: Buffer, -} - -impl smoltcp::phy::RxToken for RxToken { - fn consume(mut self, f: F) -> R - where - F: FnOnce(&mut [u8]) -> R, - { - f(&mut self.buffer) - } -} - -pub struct TxToken { - data: Rc>, -} - -impl smoltcp::phy::TxToken for TxToken { - fn consume(self, len: usize, f: F) -> R - where - F: FnOnce(&mut [u8]) -> R, - { - let data = self.data.borrow_mut(); - let mut buffer = data.buffer_pool.borrow_mut().get_buffer(); - buffer.resize(len); - let res = f(&mut buffer); - - let mut loopback = false; - if let Ok(mut frame) = smoltcp::wire::EthernetFrame::new_checked(&mut buffer) { - if frame.dst_addr() == EthernetAddress::default() { - frame.set_dst_addr(data.local_hwaddr); - loopback = true; - } - } - - if loopback { - data.input_queue.borrow_mut().push_back(buffer.move_out()); - } else { - // TODO: Handle error - data.network_file - .borrow_mut() - .write(&buffer); - } - - res - } -} - -impl smoltcp::phy::Device for NetworkDevice { - type RxToken<'a> = RxToken; - type TxToken<'a> = TxToken; - - fn capabilities(&self) -> smoltcp::phy::DeviceCapabilities { - let mut limits = smoltcp::phy::DeviceCapabilities::default(); - limits.max_transmission_unit = Self::MTU; - limits.max_burst_size = Some(20); - limits - } - - fn receive(&mut self, _timestamp: Instant) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { - let data = self.data.borrow_mut(); - let buffer = data.input_queue.borrow_mut().pop_front(); - - if let Some(buffer) = buffer { - Some(( - RxToken { buffer }, - TxToken { - data: Rc::clone(&self.data), - }, - )) - } else { - None - } - } - - fn transmit(&mut self, _timestamp: Instant) -> Option> { - Some(TxToken { - data: Rc::clone(&self.data), - }) - } -} diff --git a/src/smolnetd/link/ethernet.rs b/src/smolnetd/link/ethernet.rs new file mode 100644 index 0000000000..13e916cc25 --- /dev/null +++ b/src/smolnetd/link/ethernet.rs @@ -0,0 +1,355 @@ +use std::collections::btree_map::Entry; +use std::collections::BTreeMap; +use std::fs::File; +use std::io::{ErrorKind, Read, Write}; +use std::rc::Rc; + +use smoltcp::storage::PacketMetadata; +use smoltcp::time::{Duration, Instant}; +use smoltcp::wire::{ + ArpOperation, ArpPacket, ArpRepr, EthernetAddress, EthernetFrame, EthernetProtocol, + EthernetRepr, IpAddress, Ipv4Address, Ipv4Cidr, +}; + +use super::LinkDevice; + +struct Neighbor { + hardware_address: EthernetAddress, + expires_at: Instant, +} + +#[derive(Debug, Default)] +enum ArpState { + #[default] + Discovered, + Discovering { + target: Ipv4Address, + tries: u32, + silent_until: Instant, + }, +} + +type PacketBuffer = smoltcp::storage::PacketBuffer<'static, IpAddress>; + +pub struct EthernetLink { + name: Rc, + neighbor_cache: BTreeMap, + arp_state: ArpState, + waiting_packets: PacketBuffer, + input_buffer: Vec, + output_buffer: Vec, + network_file: File, + hardware_address: EthernetAddress, + ip_address: Ipv4Cidr, +} + +impl EthernetLink { + // TODO: Review these constants + const MAX_WAITING_PACKET_COUNT: usize = 10; + const MTU: usize = 1500; + const WAITING_PACKET_BUFFER_SIZE: usize = Self::MTU * Self::MAX_WAITING_PACKET_COUNT; + + const NEIGHBOR_LIVE_TIME: Duration = Duration::from_secs(60); + const ARP_SILENCE_TIME: Duration = Duration::from_secs(1); + + pub fn new( + name: &str, + network_file: File, + hardware_address: EthernetAddress, + ip_address: Ipv4Cidr, + ) -> Self { + let waiting_packets = PacketBuffer::new( + vec![PacketMetadata::EMPTY; Self::MAX_WAITING_PACKET_COUNT], + vec![0u8; Self::WAITING_PACKET_BUFFER_SIZE], + ); + + Self { + name: name.into(), + network_file, + waiting_packets, + hardware_address, + ip_address, + input_buffer: vec![0u8; Self::MTU], + output_buffer: Vec::with_capacity(Self::MTU), + arp_state: Default::default(), + neighbor_cache: Default::default(), + } + } + + fn send_to(&mut self, dst: EthernetAddress, size: usize, f: F, proto: EthernetProtocol) + where + F: FnOnce(&mut [u8]), + { + let repr = EthernetRepr { + src_addr: self.hardware_address, + dst_addr: dst, + ethertype: proto, + }; + + self.output_buffer.clear(); + self.output_buffer.resize(repr.buffer_len() + size, 0); + let mut frame = EthernetFrame::new_unchecked(&mut self.output_buffer); + repr.emit(&mut frame); + + f(frame.payload_mut()); + + if let Err(_) = self.network_file.write_all(&self.output_buffer) { + error!( + "Dropped outboud packet on {} (failed to write to network file)", + self.name + ) + } + } + + fn process_arp(&mut self, packet: &[u8], now: Instant) { + let Ok(repr) = ArpPacket::new_checked(packet).and_then(|packet| ArpRepr::parse(&packet)) else { + debug!("Dropped incomming arp packet on {} (Malformed)", self.name); + return; + }; + + match repr { + ArpRepr::EthernetIpv4 { + operation, + source_hardware_addr, + source_protocol_addr, + target_hardware_addr, + target_protocol_addr, + } => { + if self.hardware_address != target_hardware_addr { + // Only process packet that are for us + return; + } + + if let ArpOperation::Unknown(_) = operation { + return; + } + + if !source_hardware_addr.is_unicast() || !source_protocol_addr.is_unicast() { + return; + } + + if !self.ip_address.contains_addr(&target_protocol_addr) { + return; + } + + self.neighbor_cache.insert( + IpAddress::Ipv4(source_protocol_addr), + Neighbor { + hardware_address: source_hardware_addr, + expires_at: now + Self::NEIGHBOR_LIVE_TIME, + }, + ); + + if let ArpOperation::Request = operation { + let response = ArpRepr::EthernetIpv4 { + operation: ArpOperation::Reply, + source_hardware_addr: self.hardware_address, + source_protocol_addr: self.ip_address.address(), + target_hardware_addr: source_hardware_addr, + target_protocol_addr: source_protocol_addr, + }; + + self.send_to( + source_hardware_addr, + response.buffer_len(), + |buf| response.emit(&mut ArpPacket::new_unchecked(buf)), + EthernetProtocol::Arp, + ); + } + self.check_waiting_packets(source_protocol_addr, source_hardware_addr, now); + } + _ => {} + } + } + + fn check_waiting_packets(&mut self, ip: Ipv4Address, mac: EthernetAddress, now: Instant) { + let mut waiting_packets = + std::mem::replace(&mut self.waiting_packets, PacketBuffer::new(vec![], vec![])); + loop { + match waiting_packets.peek() { + Ok((IpAddress::Ipv4(dst), _)) if dst == &ip => {} + Ok((IpAddress::Ipv4(dst), _)) => { + self.arp_state = ArpState::Discovering { + target: *dst, + tries: 0, + silent_until: Instant::ZERO, + }; + self.send_arp(now); + break; + } + Err(_) => { + self.arp_state = ArpState::Discovered; + break; + } + } + + let (_, packet) = waiting_packets.dequeue().unwrap(); + self.send_to( + mac, + packet.len(), + |buf| buf.copy_from_slice(packet), + EthernetProtocol::Ipv4, + ); + } + + self.waiting_packets = waiting_packets; + } + + fn drop_waiting_packets(&mut self, ip: Ipv4Address, now: Instant) { + loop { + match self.waiting_packets.peek() { + Ok((IpAddress::Ipv4(dst), _)) if dst == &ip => {} + Ok((IpAddress::Ipv4(dst), _)) => { + self.arp_state = ArpState::Discovering { + target: *dst, + tries: 0, + silent_until: Instant::ZERO, + }; + + self.send_arp(now); + + return; + } + Err(_) => { + self.arp_state = ArpState::Discovered; + return; + } + } + + let _ = self.waiting_packets.dequeue(); + debug!( + "Dropped packet on {} because neighbor was not found", + self.name + ) + } + } + + fn handle_missing_neighbor(&mut self, next_hop: IpAddress, packet: &[u8], now: Instant) { + let Ok(buf) = self.waiting_packets.enqueue(packet.len(), next_hop) else { + warn!("Dropped packet on {} because waiting queue was full", self.name); + return; + }; + buf.copy_from_slice(packet); + + let IpAddress::Ipv4(next_hop) = next_hop; + if let ArpState::Discovered = self.arp_state { + self.arp_state = ArpState::Discovering { + target: next_hop, + tries: 0, + silent_until: Instant::ZERO, + }; + + self.send_arp(now) + } + } + + fn send_arp(&mut self, now: Instant) { + match self.arp_state { + ArpState::Discovered => {} + ArpState::Discovering { silent_until, .. } if silent_until > now => {} + ArpState::Discovering { target, tries, .. } if tries >= 3 => { + self.drop_waiting_packets(target, now) + } + ArpState::Discovering { + target, + ref mut tries, + ref mut silent_until, + } => { + let arp_repr = ArpRepr::EthernetIpv4 { + operation: ArpOperation::Request, + source_hardware_addr: self.hardware_address, + source_protocol_addr: self.ip_address.address(), + target_hardware_addr: EthernetAddress::BROADCAST, + target_protocol_addr: target, + }; + + *tries += 1; + *silent_until = now + Self::ARP_SILENCE_TIME; + + self.send_to( + EthernetAddress::BROADCAST, + arp_repr.buffer_len(), + |buf| arp_repr.emit(&mut ArpPacket::new_unchecked(buf)), + EthernetProtocol::Arp, + ); + } + } + } +} + +impl LinkDevice for EthernetLink { + fn send(&mut self, next_hop: IpAddress, packet: &[u8], now: Instant) { + + let local_broadcast = match self.ip_address.broadcast() { + Some(addr) => IpAddress::Ipv4(addr) == next_hop, + None => false + }; + + if local_broadcast || next_hop.is_broadcast() { + self.send_to( + EthernetAddress::BROADCAST, + packet.len(), + |buf| buf.copy_from_slice(packet), + EthernetProtocol::Ipv4, + ); + return; + } + + match self.neighbor_cache.entry(next_hop) { + Entry::Vacant(_) => self.handle_missing_neighbor(next_hop, packet, now), + Entry::Occupied(e) => { + if e.get().expires_at < now { + e.remove(); + self.handle_missing_neighbor(next_hop, packet, now) + } else { + let mac = e.get().hardware_address; + self.send_to( + mac, + packet.len(), + |buf| buf.copy_from_slice(packet), + EthernetProtocol::Ipv4, + ) + } + } + } + } + + fn recv(&mut self, now: Instant) -> Option<&[u8]> { + let mut input_buffer = std::mem::replace(&mut self.input_buffer, Vec::new()); + loop { + if let Err(e) = self.network_file.read(&mut input_buffer) { + if e.kind() != ErrorKind::WouldBlock { + error!("Failed to read ethernet device on link {}", self.name); + } else { + // No packet to read but we check if we have arp to send + self.send_arp(now); + } + self.input_buffer = input_buffer; + return None; + } + let packet = EthernetFrame::new_unchecked(&input_buffer[..]); + let Ok(repr) = EthernetRepr::parse(&packet) else { + debug!("Dropped incomming frame on {} (Malformed)", self.name); + continue; + }; + + if !repr.dst_addr.is_broadcast() && repr.dst_addr != self.hardware_address { + // Drop packets which are not for us + continue; + } + + match repr.ethertype { + EthernetProtocol::Ipv4 => { + self.input_buffer = input_buffer; + return Some(EthernetFrame::new_unchecked(&self.input_buffer[..]).payload()); + } + EthernetProtocol::Arp => self.process_arp(packet.payload(), now), + _ => continue, + } + } + } + + fn name(&self) -> &Rc { + &self.name + } +} diff --git a/src/smolnetd/link/loopback.rs b/src/smolnetd/link/loopback.rs new file mode 100644 index 0000000000..ff2bf019bf --- /dev/null +++ b/src/smolnetd/link/loopback.rs @@ -0,0 +1,45 @@ +use std::rc::Rc; + +use smoltcp::storage::PacketMetadata; +use smoltcp::time::Instant; + +use crate::scheme::Smolnetd; + +use super::LinkDevice; + +pub type PacketBuffer = smoltcp::storage::PacketBuffer<'static, ()>; + +pub struct LoopbackDevice { + name: Rc, + buffer: PacketBuffer, +} + +impl Default for LoopbackDevice { + fn default() -> Self { + let buffer = PacketBuffer::new( + vec![PacketMetadata::EMPTY; Smolnetd::SOCKET_BUFFER_SIZE], + vec![0u8; 1500 * Smolnetd::SOCKET_BUFFER_SIZE], + ); + LoopbackDevice { + name: "loopback".into(), + buffer, + } + } +} + +impl LinkDevice for LoopbackDevice { + fn send(&mut self, _next_hop: smoltcp::wire::IpAddress, packet: &[u8], _now: Instant) { + match self.buffer.enqueue(packet.len(), ()) { + Err(_) => warn!("loopback dropped packet because buffer was full"), + Ok(buf) => buf.copy_from_slice(packet), + } + } + + fn recv(&mut self, _now: Instant) -> Option<&[u8]> { + self.buffer.dequeue().ok().map(|((), buf)| &*buf) + } + + fn name(&self) -> &std::rc::Rc { + &self.name + } +} diff --git a/src/smolnetd/link/mod.rs b/src/smolnetd/link/mod.rs new file mode 100644 index 0000000000..e550ef1b6e --- /dev/null +++ b/src/smolnetd/link/mod.rs @@ -0,0 +1,57 @@ +pub mod loopback; +pub mod ethernet; + +use std::rc::Rc; + +use smoltcp::time::Instant; +use smoltcp::wire::IpAddress; + +/// Represent a link layer device (eth0, loopback...) +pub trait LinkDevice { + + /// Send the given packet to the machine with the `next_hop` ip address + /// This method cannot fail so it's the implementor responsability + /// to buffer packets which can't be sent immediatly or decide to + /// drop them if necessary + fn send(&mut self, next_hop: IpAddress, packet: &[u8], now: Instant); + + /// Returns None if nothing is received. + /// Returns an Ip packet otherwise + fn recv(&mut self, now: Instant) -> Option<&[u8]>; + + /// Returns the LinkDevice display name used to refer to it and for lookups + fn name(&self) -> &Rc; +} + +#[derive(Default)] +pub struct DeviceList { + inner: Vec>, +} + +impl DeviceList { + pub fn push(&mut self, dev: T) { + self.inner.push(Box::new(dev)) + } + + pub fn get(&self, device_name: &str) -> Option<&dyn LinkDevice> { + self.inner + .iter() + .find(|dev| dev.name().as_ref() == device_name) + .map(|device| device.as_ref()) + } + + pub fn get_mut(&mut self, device_name: &str) -> Option<&mut (dyn LinkDevice + 'static)> { + self.inner + .iter_mut() + .find(|dev| dev.name().as_ref() == device_name) + .map(|device| device.as_mut()) + } + + pub fn iter(&self) -> impl Iterator { + self.inner.iter().map(|b| b.as_ref()) + } + + pub fn iter_mut(&mut self) -> impl Iterator { + self.inner.iter_mut().map(|b| b.as_mut()) + } +} diff --git a/src/smolnetd/main.rs b/src/smolnetd/main.rs index b1b6ebb8ce..3f1ac9c2d3 100644 --- a/src/smolnetd/main.rs +++ b/src/smolnetd/main.rs @@ -3,11 +3,11 @@ extern crate event; #[macro_use] extern crate log; +extern crate byteorder; extern crate netutils; extern crate redox_netstack; extern crate smoltcp; extern crate syscall; -extern crate byteorder; use std::cell::RefCell; use std::fs::File; @@ -15,14 +15,15 @@ use std::os::unix::io::{FromRawFd, RawFd}; use std::process; use std::rc::Rc; +use event::EventQueue; use redox_netstack::error::{Error, Result}; use redox_netstack::logger; -use event::EventQueue; use scheme::Smolnetd; mod buffer_pool; -mod device; +mod link; mod port_set; +mod router; mod scheme; fn run(daemon: redox_daemon::Daemon) -> Result<()> { @@ -143,7 +144,7 @@ fn run(daemon: redox_daemon::Daemon) -> Result<()> { event_queue.trigger_all(event::Event { fd: 0, - flags: EventFlags::empty() + flags: EventFlags::empty(), })?; event_queue.run() @@ -158,5 +159,6 @@ fn main() { process::exit(1); } process::exit(0); - }).expect("smoltcp: failed to daemonize"); + }) + .expect("smoltcp: failed to daemonize"); } diff --git a/src/smolnetd/router/mod.rs b/src/smolnetd/router/mod.rs new file mode 100644 index 0000000000..c72331948d --- /dev/null +++ b/src/smolnetd/router/mod.rs @@ -0,0 +1,187 @@ +use std::cell::RefCell; +use std::rc::Rc; + +use smoltcp::phy::{Device, DeviceCapabilities, Medium}; +use smoltcp::storage::PacketMetadata; +use smoltcp::time::Instant; +use smoltcp::wire::IpAddress; + +use self::route_table::RouteTable; +use crate::link::DeviceList; +use crate::scheme::Smolnetd; + +pub mod route_table; + +pub type PacketBuffer = smoltcp::storage::PacketBuffer<'static, ()>; + +pub struct Router { + rx_buffer: PacketBuffer, + tx_buffer: PacketBuffer, + devices: Rc>, + route_table: Rc>, +} + +impl Router { + pub fn new(devices: Rc>, route_table: Rc>) -> Self { + let rx_buffer = PacketBuffer::new( + vec![PacketMetadata::EMPTY; Smolnetd::SOCKET_BUFFER_SIZE], + vec![0u8; Router::MTU * Smolnetd::SOCKET_BUFFER_SIZE], + ); + let tx_buffer = PacketBuffer::new( + vec![PacketMetadata::EMPTY; Smolnetd::SOCKET_BUFFER_SIZE], + vec![0u8; Router::MTU * Smolnetd::SOCKET_BUFFER_SIZE], + ); + Self { + rx_buffer, + tx_buffer, + devices, + route_table, + } + } + + pub const MTU: usize = 1486; + + pub fn poll(&mut self, now: Instant) { + self.dispatch_outgoing(now); + self.process_incoming(now); + } + + fn process_incoming(&mut self, now: Instant) { + for dev in self.devices.borrow_mut().iter_mut() { + if self.rx_buffer.is_full() { + break; + } + + loop { + if self.rx_buffer.is_full() { + break; + } + + let Some(buf) = dev.recv(now) else { + break; + }; + + self.rx_buffer + .enqueue(buf.len(), ()) + .expect("We checked if it was full") + .copy_from_slice(buf); + } + } + } + + fn dispatch_outgoing(&mut self, now: Instant) { + while let Ok(((), packet)) = self.tx_buffer.dequeue() { + if let Ok(mut packet) = smoltcp::wire::Ipv4Packet::new_checked(packet) { + let dst_addr = IpAddress::Ipv4(packet.dst_addr()); + if packet.dst_addr().is_broadcast() { + let buf = packet.into_inner(); + for dev in self.devices.borrow_mut().iter_mut() { + dev.send(dst_addr, buf, now) + } + } else { + let route_table = self.route_table.borrow(); + let Some(rule) = route_table.lookup_rule(&dst_addr) else { + warn!("No route found for destination: {}", dst_addr); + continue; + }; + + let next_hop = match rule.via { + Some(via) => via, + None => dst_addr, + }; + + let mut devices = self.devices.borrow_mut(); + let Some(dev) = devices.get_mut(&rule.dev) else { + warn!("Device {} not found", rule.dev); + // TODO: Remove route if device doesn't exist anymore ? + continue; + }; + + let IpAddress::Ipv4(src) = rule.src; + if src != packet.src_addr() { + packet.set_src_addr(src); + packet.fill_checksum() + } + + dev.send(next_hop, packet.into_inner(), now); + } + } + } + } +} + +impl Device for Router { + type RxToken<'a> = RxToken<'a>; + + type TxToken<'a> = TxToken<'a>; + + fn receive( + &mut self, + _timestamp: smoltcp::time::Instant, + ) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { + if self.rx_buffer.is_empty() || self.tx_buffer.is_full() { + None + } else { + Some(( + RxToken { + rx_buffer: &mut self.rx_buffer, + }, + TxToken { + tx_buffer: &mut self.tx_buffer, + }, + )) + } + } + + fn transmit(&mut self, _timestamp: smoltcp::time::Instant) -> Option> { + if self.tx_buffer.is_full() { + None + } else { + Some(TxToken { + tx_buffer: &mut self.tx_buffer, + }) + } + } + + fn capabilities(&self) -> smoltcp::phy::DeviceCapabilities { + let mut caps = DeviceCapabilities::default(); + caps.medium = Medium::Ip; + caps.max_transmission_unit = Router::MTU; + caps.max_burst_size = Some(Smolnetd::SOCKET_BUFFER_SIZE); + caps + } +} + +pub struct TxToken<'a> { + tx_buffer: &'a mut PacketBuffer, +} + +impl smoltcp::phy::TxToken for TxToken<'_> { + fn consume(self, len: usize, f: F) -> R + where + F: FnOnce(&mut [u8]) -> R, + { + f(self + .tx_buffer + .enqueue(len, ()) + .expect("This was checked before creating the TxToken")) + } +} + +pub struct RxToken<'a> { + rx_buffer: &'a mut PacketBuffer, +} + +impl<'a> smoltcp::phy::RxToken for RxToken<'a> { + fn consume(self, f: F) -> R + where + F: FnOnce(&mut [u8]) -> R, + { + let ((), buf) = self + .rx_buffer + .dequeue() + .expect("This was checked before creating the RxToken"); + + f(buf) + } +} diff --git a/src/smolnetd/router/route_table.rs b/src/smolnetd/router/route_table.rs new file mode 100644 index 0000000000..e51127720a --- /dev/null +++ b/src/smolnetd/router/route_table.rs @@ -0,0 +1,55 @@ +use std::rc::Rc; + +use smoltcp::wire::{IpAddress, IpCidr}; + +#[derive(Debug)] +pub struct Rule { + pub filter: IpCidr, + pub via: Option, + pub dev: Rc, + pub src: IpAddress, +} + +impl Rule { + pub fn new(filter: IpCidr, via: Option, dev: Rc, src: IpAddress) -> Self { + Self { + filter, + via, + dev, + src, + } + } +} + +#[derive(Debug, Default)] +pub struct RouteTable { + rules: Vec, +} + +impl RouteTable { + pub fn lookup_rule(&self, dst: &IpAddress) -> Option<&Rule> { + self.rules + .iter() + .rev() + .find(|rule| rule.filter.contains_addr(dst)) + } + + pub fn lookup_src_addr(&self, dst: &IpAddress) -> Option { + Some(self.lookup_rule(dst)?.src) + } + + pub fn lookup_gateway(&self, dst: &IpAddress) -> Option { + self.lookup_rule(dst)?.via + } + + pub fn insert_rule(&mut self, new_rule: Rule) { + let i = match self + .rules + .binary_search_by_key(&new_rule.filter.prefix_len(), |rule| { + rule.filter.prefix_len() + }) { + Ok(i) | Err(i) => i, + }; + self.rules.insert(i, new_rule); + } +} diff --git a/src/smolnetd/scheme/icmp.rs b/src/smolnetd/scheme/icmp.rs index 5ecd94fc8c..2f2fc680fe 100644 --- a/src/smolnetd/scheme/icmp.rs +++ b/src/smolnetd/scheme/icmp.rs @@ -7,10 +7,10 @@ use syscall::{Error as SyscallError, Result as SyscallResult}; use syscall; use byteorder::{ByteOrder, NetworkEndian}; -use crate::device::NetworkDevice; use crate::port_set::PortSet; -use super::socket::{DupResult, SchemeFile, SchemeSocket, SocketFile, SocketScheme}; -use super::{Smolnetd, SocketSet, Interface}; +use crate::router::Router; +use super::socket::{DupResult, SchemeFile, SchemeSocket, SocketFile, SocketScheme, Context}; +use super::{Smolnetd, SocketSet}; pub type IcmpScheme = SocketScheme>; @@ -75,7 +75,7 @@ impl<'a> SchemeSocket for IcmpSocket<'a> { path: &str, _uid: u32, ident_set: &mut Self::SchemeDataT, - iface: &Interface + _context: &Context ) -> SyscallResult<(SocketHandle, Self::DataT)> { use std::str::FromStr; @@ -95,11 +95,11 @@ impl<'a> SchemeSocket for IcmpSocket<'a> { let socket = IcmpSocket::new( IcmpSocketBuffer::new( vec![IcmpPacketMetadata::EMPTY; Smolnetd::SOCKET_BUFFER_SIZE], - vec![0; NetworkDevice::MTU * Smolnetd::SOCKET_BUFFER_SIZE] + vec![0; Router::MTU * Smolnetd::SOCKET_BUFFER_SIZE] ), IcmpSocketBuffer::new( vec![IcmpPacketMetadata::EMPTY; Smolnetd::SOCKET_BUFFER_SIZE], - vec![0; NetworkDevice::MTU * Smolnetd::SOCKET_BUFFER_SIZE] + vec![0; Router::MTU * Smolnetd::SOCKET_BUFFER_SIZE] ) ); let handle = socket_set.add(socket); @@ -127,11 +127,11 @@ impl<'a> SchemeSocket for IcmpSocket<'a> { let socket = IcmpSocket::new( IcmpSocketBuffer::new( vec![IcmpPacketMetadata::EMPTY; Smolnetd::SOCKET_BUFFER_SIZE], - vec![0; NetworkDevice::MTU * Smolnetd::SOCKET_BUFFER_SIZE] + vec![0; Router::MTU * Smolnetd::SOCKET_BUFFER_SIZE] ), IcmpSocketBuffer::new( vec![IcmpPacketMetadata::EMPTY; Smolnetd::SOCKET_BUFFER_SIZE], - vec![0; NetworkDevice::MTU * Smolnetd::SOCKET_BUFFER_SIZE] + vec![0; Router::MTU * Smolnetd::SOCKET_BUFFER_SIZE] ) ); let handle = socket_set.add(socket); diff --git a/src/smolnetd/scheme/ip.rs b/src/smolnetd/scheme/ip.rs index 4f0d0d3254..149b173599 100644 --- a/src/smolnetd/scheme/ip.rs +++ b/src/smolnetd/scheme/ip.rs @@ -5,9 +5,10 @@ use std::str; use syscall::{Error as SyscallError, Result as SyscallResult}; use syscall; -use crate::device::NetworkDevice; -use super::{Smolnetd, SocketSet, Interface}; -use super::socket::{DupResult, SchemeFile, SchemeSocket, SocketFile, SocketScheme}; +use crate::router::Router; + +use super::{Smolnetd, SocketSet}; +use super::socket::{DupResult, SchemeFile, SchemeSocket, SocketFile, SocketScheme, Context}; pub type IpScheme = SocketScheme>; @@ -59,7 +60,7 @@ impl<'a> SchemeSocket for RawSocket<'a> { path: &str, uid: u32, _: &mut Self::SchemeDataT, - iface: &Interface + _context: &Context ) -> SyscallResult<(SocketHandle, Self::DataT)> { if uid != 0 { return Err(SyscallError::new(syscall::EACCES)); @@ -69,11 +70,11 @@ impl<'a> SchemeSocket for RawSocket<'a> { let rx_buffer = RawSocketBuffer::new( vec![RawPacketMetadata::EMPTY; Smolnetd::SOCKET_BUFFER_SIZE], - vec![0; NetworkDevice::MTU * Smolnetd::SOCKET_BUFFER_SIZE] + vec![0; Router::MTU * Smolnetd::SOCKET_BUFFER_SIZE] ); let tx_buffer = RawSocketBuffer::new( vec![RawPacketMetadata::EMPTY; Smolnetd::SOCKET_BUFFER_SIZE], - vec![0; NetworkDevice::MTU * Smolnetd::SOCKET_BUFFER_SIZE] + vec![0; Router::MTU * Smolnetd::SOCKET_BUFFER_SIZE] ); let ip_socket = RawSocket::new( IpVersion::Ipv4, diff --git a/src/smolnetd/scheme/mod.rs b/src/smolnetd/scheme/mod.rs index fdf60b012c..b0e01f9ddd 100644 --- a/src/smolnetd/scheme/mod.rs +++ b/src/smolnetd/scheme/mod.rs @@ -1,35 +1,41 @@ +use crate::link::ethernet::EthernetLink; +use crate::link::LinkDevice; +use crate::link::{loopback::LoopbackDevice, DeviceList}; +use crate::router::route_table::{RouteTable, Rule}; +use crate::router::Router; +use crate::scheme::smoltcp::iface::SocketSet as SmoltcpSocketSet; use netutils::getcfg; use smoltcp; -use smoltcp::iface::{Interface as SmoltcpInterface, Routes, Config}; +use smoltcp::iface::{Config, Interface as SmoltcpInterface}; use smoltcp::phy::Tracer; -use crate::scheme::smoltcp::iface::SocketSet as SmoltcpSocketSet; use smoltcp::time::{Duration, Instant}; -use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr, Ipv4Address, IpListenEndpoint, HardwareAddress}; +use smoltcp::wire::{ + EthernetAddress, HardwareAddress, IpAddress, IpCidr, IpListenEndpoint, Ipv4Address, Ipv4Cidr, +}; use std::cell::RefCell; use std::collections::VecDeque; use std::fs::File; -use std::io::{self, Read, Write}; +use std::io::{Read, Write}; use std::mem::size_of; use std::rc::Rc; use std::str::FromStr; -use syscall::data::TimeSpec; use syscall; +use syscall::data::TimeSpec; -use crate::buffer_pool::{Buffer, BufferPool}; -use crate::device::NetworkDevice; -use redox_netstack::error::{Error, Result}; +use self::icmp::IcmpScheme; use self::ip::IpScheme; +use self::netcfg::NetCfgScheme; use self::tcp::TcpScheme; use self::udp::UdpScheme; -use self::icmp::IcmpScheme; -use self::netcfg::NetCfgScheme; +use crate::buffer_pool::{Buffer, BufferPool}; +use redox_netstack::error::{Error, Result}; +mod icmp; mod ip; +mod netcfg; mod socket; mod tcp; mod udp; -mod icmp; -mod netcfg; type SocketSet = SmoltcpSocketSet<'static>; type Interface = Rc>; @@ -38,11 +44,12 @@ const MAX_DURATION: Duration = Duration::from_millis(u64::MAX); const MIN_DURATION: Duration = Duration::from_millis(0); pub struct Smolnetd { - network_file: Rc>, - network_device: Tracer, + router_device: Tracer, + iface: Interface, + link_devices: Rc>, + route_table: Rc>, time_file: File, - iface: Interface, socket_set: Rc>, timer: ::std::time::Instant, @@ -57,10 +64,10 @@ pub struct Smolnetd { } impl Smolnetd { - const MAX_PACKET_SIZE: usize = 2048; - const SOCKET_BUFFER_SIZE: usize = 128; //packets - const MIN_CHECK_TIMEOUT: Duration = Duration::from_millis(10); - const MAX_CHECK_TIMEOUT: Duration = Duration::from_millis(500); + pub const MAX_PACKET_SIZE: usize = 2048; + pub const SOCKET_BUFFER_SIZE: usize = 128; //packets + pub const MIN_CHECK_TIMEOUT: Duration = Duration::from_millis(10); + pub const MAX_CHECK_TIMEOUT: Duration = Duration::from_millis(500); pub fn new( network_file: File, @@ -79,48 +86,104 @@ impl Smolnetd { IpCidr::new(local_ip, 24), IpCidr::new(IpAddress::v4(127, 0, 0, 1), 8), ]; + let default_gw = Ipv4Address::from_str(getcfg("ip_router").unwrap().trim()) .expect("Can't parse the 'ip_router' cfg."); let buffer_pool = Rc::new(RefCell::new(BufferPool::new(Self::MAX_PACKET_SIZE))); let input_queue = Rc::new(RefCell::new(VecDeque::new())); - let network_file = Rc::new(RefCell::new(network_file)); - let mut network_device = Tracer::new(NetworkDevice::new( - Rc::clone(&network_file), - Rc::clone(&input_queue), - hardware_addr, - Rc::clone(&buffer_pool), - ), |_timestamp, printer| { - trace!("{}", printer) - }); - let config = Config::new(HardwareAddress::Ethernet(hardware_addr)); + + let devices = Rc::new(RefCell::new(DeviceList::default())); + let route_table = Rc::new(RefCell::new(RouteTable::default())); + let mut network_device = Tracer::new( + Router::new(Rc::clone(&devices), Rc::clone(&route_table)), + |_timestamp, printer| trace!("{}", printer), + ); + + let config = Config::new(HardwareAddress::Ip); let mut iface = SmoltcpInterface::new(config, &mut network_device, Instant::now()); iface.update_ip_addrs(|ip_addrs| ip_addrs.extend(protocol_addrs)); - iface.routes_mut().add_default_ipv4_route(default_gw).expect("Failed to add default gateway"); + iface + .routes_mut() + .add_default_ipv4_route(default_gw) + .expect("Failed to add default gateway"); let iface = Rc::new(RefCell::new(iface)); let socket_set = Rc::new(RefCell::new(SocketSet::new(vec![]))); + + let loopback = LoopbackDevice::default(); + route_table.borrow_mut().insert_rule(Rule::new( + "127.0.0.0/8".parse().unwrap(), + None, + Rc::clone(loopback.name()), + "127.0.0.1".parse().unwrap(), + )); + + let IpAddress::Ipv4(local_ip) = local_ip; + let eth0 = EthernetLink::new( + "eth0", + network_file, + hardware_addr, + Ipv4Cidr::new(local_ip, 24), + ); + + route_table.borrow_mut().insert_rule(Rule::new( + IpCidr::new(IpAddress::Ipv4(local_ip), 24), + None, + Rc::clone(eth0.name()), + IpAddress::Ipv4(local_ip), + )); + + route_table.borrow_mut().insert_rule(Rule::new( + "0.0.0.0/0".parse().unwrap(), + Some(IpAddress::Ipv4(default_gw)), + Rc::clone(eth0.name()), + IpAddress::Ipv4(local_ip), + )); + + devices.borrow_mut().push(loopback); + devices.borrow_mut().push(eth0); + Smolnetd { iface: Rc::clone(&iface), - network_device, + router_device: network_device, + route_table: Rc::clone(&route_table), socket_set: Rc::clone(&socket_set), timer: ::std::time::Instant::now(), + link_devices: devices, time_file, - ip_scheme: IpScheme::new(Rc::clone(&iface), Rc::clone(&socket_set), ip_file), - udp_scheme: UdpScheme::new(Rc::clone(&iface), Rc::clone(&socket_set), udp_file), - tcp_scheme: TcpScheme::new(Rc::clone(&iface), Rc::clone(&socket_set), tcp_file), - icmp_scheme: IcmpScheme::new(Rc::clone(&iface), Rc::clone(&socket_set), icmp_file), + ip_scheme: IpScheme::new( + Rc::clone(&iface), + Rc::clone(&route_table), + Rc::clone(&socket_set), + ip_file, + ), + udp_scheme: UdpScheme::new( + Rc::clone(&iface), + Rc::clone(&route_table), + Rc::clone(&socket_set), + udp_file, + ), + tcp_scheme: TcpScheme::new( + Rc::clone(&iface), + Rc::clone(&route_table), + Rc::clone(&socket_set), + tcp_file, + ), + icmp_scheme: IcmpScheme::new( + Rc::clone(&iface), + Rc::clone(&route_table), + Rc::clone(&socket_set), + icmp_file, + ), netcfg_scheme: NetCfgScheme::new(Rc::clone(&iface), netcfg_file), input_queue, - network_file, buffer_pool, } } pub fn on_network_scheme_event(&mut self) -> Result> { - if self.read_frames()? > 0 { - self.poll()?; - } + self.poll()?; Ok(None) } @@ -183,22 +246,23 @@ impl Smolnetd { let mut iter_limit = 10usize; let mut iface = self.iface.borrow_mut(); let mut socket_set = self.socket_set.borrow_mut(); - let timestamp = Instant::from(self.timer); + loop { + let timestamp = Instant::from(self.timer); if iter_limit == 0 { break MIN_DURATION; } iter_limit -= 1; - // TODO: Check what if the bool returned by poll can be useful - iface.poll(timestamp, &mut self.network_device, &mut socket_set); + self.router_device.get_mut().poll(timestamp); + + // TODO: Check what if the bool returned by poll can be useful + iface.poll(timestamp, &mut self.router_device, &mut socket_set); match iface.poll_delay(timestamp, &socket_set) { - Some(delay) if delay == Duration::ZERO => { } - Some(delay) => { - break ::std::cmp::min(MAX_DURATION, delay) - } - None => break MAX_DURATION + Some(delay) if delay == Duration::ZERO => {} + Some(delay) => break ::std::cmp::min(MAX_DURATION, delay), + None => break MAX_DURATION, }; } }; @@ -211,26 +275,6 @@ impl Smolnetd { )) } - fn read_frames(&mut self) -> Result { - let mut total_frames = 0; - loop { - let mut buffer = self.buffer_pool.borrow_mut().get_buffer(); - let count = match self.network_file.borrow_mut().read(&mut buffer) { - Ok(count) => count, - Err(err) => match err.kind() { - io::ErrorKind::WouldBlock => break, - _ => return Err( - Error::from_io_error(err, "Failed to read from network file") - ) - } - }; - buffer.resize(count); - self.input_queue.borrow_mut().push_back(buffer); - total_frames += 1; - } - Ok(total_frames) - } - fn notify_sockets(&mut self) -> Result<()> { self.ip_scheme.notify_sockets()?; self.udp_scheme.notify_sockets()?; @@ -257,14 +301,15 @@ fn post_fevent(scheme_file: &mut File, fd: usize, event: usize, data_len: usize) fn parse_endpoint(socket: &str) -> IpListenEndpoint { let mut socket_parts = socket.split(':'); - let host = - Ipv4Address::from_str(socket_parts.next().unwrap_or("")).ok().filter(|addr| !addr.is_unspecified()).map(IpAddress::Ipv4); - + let host = Ipv4Address::from_str(socket_parts.next().unwrap_or("")) + .ok() + .filter(|addr| !addr.is_unspecified()) + .map(IpAddress::Ipv4); let port = socket_parts .next() .unwrap_or("") .parse::() .unwrap_or(0); - IpListenEndpoint{ addr: host, port} + IpListenEndpoint { addr: host, port } } diff --git a/src/smolnetd/scheme/netcfg/mod.rs b/src/smolnetd/scheme/netcfg/mod.rs index d41dee0a44..888f4830e9 100644 --- a/src/smolnetd/scheme/netcfg/mod.rs +++ b/src/smolnetd/scheme/netcfg/mod.rs @@ -158,7 +158,8 @@ fn mk_root_node(iface: Interface, notifier: NotifierRef, dns_config: DNSConfigRe "mac" => { rw [iface, notifier] (Option, None) || { - format!("{}\n", iface.borrow().hardware_addr()) + // format!("{}\n", iface.borrow().hardware_addr()) + String::new() } |cur_value, line| { if cur_value.is_none() { @@ -175,7 +176,7 @@ fn mk_root_node(iface: Interface, notifier: NotifierRef, dns_config: DNSConfigRe } |cur_value| { if let Some(mac) = *cur_value { - iface.borrow_mut().set_hardware_addr(smoltcp::wire::HardwareAddress::Ethernet(mac)); + // iface.borrow_mut().set_hardware_addr(smoltcp::wire::HardwareAddress::Ethernet(mac)); notifier.borrow_mut().schedule_notify("ifaces/eth0/mac"); } Ok(()) diff --git a/src/smolnetd/scheme/socket.rs b/src/smolnetd/scheme/socket.rs index c40dda1406..45c64cfeeb 100644 --- a/src/smolnetd/scheme/socket.rs +++ b/src/smolnetd/scheme/socket.rs @@ -19,12 +19,18 @@ use syscall::{ }; use super::Interface; +use crate::router::route_table::RouteTable; use crate::scheme::smoltcp::iface::SocketHandle; use redox_netstack::error::{Error, Result}; use smoltcp::socket::AnySocket; use super::{post_fevent, SocketSet}; +pub struct Context { + pub iface: Interface, + pub route_table: Rc>, +} + pub struct NullFile { pub flags: usize, pub uid: u32, @@ -192,7 +198,7 @@ where path: &str, uid: u32, data: &mut Self::SchemeDataT, - iface: &Interface, + context: &Context, ) -> SyscallResult<(SocketHandle, Self::DataT)>; fn close_file( @@ -231,7 +237,7 @@ where nulls: BTreeMap, files: BTreeMap>, ref_counts: BTreeMap, - iface: Interface, + context: Context, socket_set: Rc>, scheme_file: File, wait_queue: WaitQueue, @@ -245,13 +251,13 @@ where { pub fn new( iface: Interface, + route_table: Rc>, socket_set: Rc>, scheme_file: File, ) -> SocketScheme { SocketScheme { next_fd: 1, nulls: BTreeMap::new(), - iface, files: BTreeMap::new(), ref_counts: BTreeMap::new(), socket_set, @@ -259,6 +265,7 @@ where scheme_file, wait_queue: Vec::new(), _phantom_socket: PhantomData, + context: Context { iface, route_table }, } } @@ -514,7 +521,7 @@ where path, uid, &mut self.scheme_data, - &self.iface, + &self.context, )?; let file = SchemeFile::Socket(SocketFile { @@ -606,7 +613,12 @@ where SchemeFile::Socket(ref mut file) => { let mut socket_set = self.socket_set.borrow_mut(); let socket = socket_set.get_mut::(file.socket_handle); - return SocketT::write_buf(socket, file, buf); + let ret = SocketT::write_buf(socket, file, buf); + match ret { + Ok(None) => {} + _ => file.write_notified = false, + } + return ret; } } }; @@ -626,7 +638,14 @@ where SchemeFile::Socket(ref mut file) => { let mut socket_set = self.socket_set.borrow_mut(); let socket = socket_set.get_mut::(file.socket_handle); - return SocketT::read_buf(socket, file, buf); + + let ret = SocketT::read_buf(socket, file, buf); + match ret { + Ok(None) => {} + _ => file.read_notified = false + } + + return ret; } } }; diff --git a/src/smolnetd/scheme/tcp.rs b/src/smolnetd/scheme/tcp.rs index e5cf327dfe..5f9f9a3c26 100644 --- a/src/smolnetd/scheme/tcp.rs +++ b/src/smolnetd/scheme/tcp.rs @@ -6,8 +6,8 @@ use std::str; use syscall; use syscall::{Error as SyscallError, Result as SyscallResult}; -use super::socket::{DupResult, SchemeFile, SchemeSocket, SocketFile, SocketScheme}; -use super::{parse_endpoint, Interface, SocketSet}; +use super::socket::{Context, DupResult, SchemeFile, SchemeSocket, SocketFile, SocketScheme}; +use super::{parse_endpoint, SocketSet}; use crate::port_set::PortSet; pub type TcpScheme = SocketScheme>; @@ -62,7 +62,7 @@ impl<'a> SchemeSocket for TcpSocket<'a> { path: &str, uid: u32, port_set: &mut Self::SchemeDataT, - iface: &Interface, + context: &Context, ) -> SyscallResult<(SocketHandle, Self::DataT)> { trace!("TCP open {}", path); let mut parts = path.split('/'); @@ -92,10 +92,27 @@ impl<'a> SchemeSocket for TcpSocket<'a> { let tcp_socket = socket_set.get_mut::(socket_handle); let listen_enpoint = if remote_endpoint.is_specified() { + let local_endpoint_addr = match local_endpoint.addr { + Some(addr) if !addr.is_unspecified() => Some(addr), + _ => { + let route_table = context.route_table.borrow(); + let addr = route_table + .lookup_src_addr(&remote_endpoint.addr.expect("Checked in is_specified")); + if matches!(addr, None) { + error!("Opening a TCP connection with a probably invalid source IP as no route have been found for destination: {}", remote_endpoint); + } + addr + } + }; + let local_endpoint = IpListenEndpoint { + addr: local_endpoint_addr, + port: local_endpoint.port, + }; + trace!("Connecting tcp {} {}", local_endpoint, remote_endpoint); tcp_socket .connect( - iface.borrow_mut().context(), + context.iface.borrow_mut().context(), IpEndpoint::new(remote_endpoint.addr.unwrap(), remote_endpoint.port), local_endpoint, ) @@ -264,11 +281,13 @@ impl<'a> SchemeSocket for TcpSocket<'a> { data: Some(endpoint), .. }), - ) => if endpoint.is_specified() { - write!(&mut path, "{}", endpoint).unwrap() - } else { - write!(&mut path, "0.0.0.0:{}", endpoint.port).unwrap() - }, + ) => { + if endpoint.is_specified() { + write!(&mut path, "{}", endpoint).unwrap() + } else { + write!(&mut path, "0.0.0.0:{}", endpoint.port).unwrap() + } + } _ => path.push_str(unspecified), } trace!("fpath: {}", path); diff --git a/src/smolnetd/scheme/udp.rs b/src/smolnetd/scheme/udp.rs index 4f0ce8ccd8..a36636b029 100644 --- a/src/smolnetd/scheme/udp.rs +++ b/src/smolnetd/scheme/udp.rs @@ -5,9 +5,9 @@ use std::str; use syscall::{Error as SyscallError, Result as SyscallResult}; use syscall; -use crate::device::NetworkDevice; use crate::port_set::PortSet; -use super::socket::{DupResult, SchemeFile, SchemeSocket, SocketFile, SocketScheme}; +use crate::router::Router; +use super::socket::{DupResult, SchemeFile, SchemeSocket, SocketFile, SocketScheme, Context}; use super::{parse_endpoint, Smolnetd, SocketSet, Interface}; pub type UdpScheme = SocketScheme>; @@ -62,7 +62,7 @@ impl<'a> SchemeSocket for UdpSocket<'a> { path: &str, uid: u32, port_set: &mut Self::SchemeDataT, - _iface: &Interface + _context: &Context ) -> SyscallResult<(SocketHandle, Self::DataT)> { let mut parts = path.split('/'); let remote_endpoint = parse_endpoint(parts.next().unwrap_or("")); @@ -74,11 +74,11 @@ impl<'a> SchemeSocket for UdpSocket<'a> { let rx_buffer = UdpSocketBuffer::new( vec![UdpPacketMetadata::EMPTY; Smolnetd::SOCKET_BUFFER_SIZE], - vec![0; NetworkDevice::MTU * Smolnetd::SOCKET_BUFFER_SIZE] + vec![0; Router::MTU * Smolnetd::SOCKET_BUFFER_SIZE] ); let tx_buffer = UdpSocketBuffer::new( vec![UdpPacketMetadata::EMPTY; Smolnetd::SOCKET_BUFFER_SIZE], - vec![0; NetworkDevice::MTU * Smolnetd::SOCKET_BUFFER_SIZE] + vec![0; Router::MTU * Smolnetd::SOCKET_BUFFER_SIZE] ); let udp_socket = UdpSocket::new(rx_buffer, tx_buffer);