diff --git a/Cargo.lock b/Cargo.lock index 188963b..39ab21b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,18 +4,18 @@ version = 3 [[package]] name = "addr2line" -version = "0.22.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "aes" @@ -82,15 +82,15 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "atoi" @@ -114,23 +114,23 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "backtrace" -version = "0.3.73" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", + "windows-targets 0.52.6", ] [[package]] @@ -192,9 +192,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.6.0" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" [[package]] name = "c2rust-bitfields" @@ -227,9 +227,12 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.104" +version = "1.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74b6a57f98764a267ff415d50a25e6e166f3831a5071af4995296ea97d210490" +checksum = "677207f6eaec43fcfd092a718c847fc38aa261d0e19b8ef6797e0ccbe789e738" +dependencies = [ + "shlex", +] [[package]] name = "cfg-if" @@ -284,15 +287,15 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "core-foundation-sys" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" dependencies = [ "libc", ] @@ -353,7 +356,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if", - "hashbrown", + "hashbrown 0.14.5", "lock_api", "once_cell", "parking_lot_core", @@ -361,13 +364,13 @@ dependencies = [ [[package]] name = "dashmap" -version = "6.0.1" +version = "6.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "804c8821570c3f8b70230c2ba75ffa5c0f9a4189b9a432b6656c536712acae28" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" dependencies = [ "cfg-if", "crossbeam-utils", - "hashbrown", + "hashbrown 0.14.5", "lock_api", "once_cell", "parking_lot_core", @@ -476,9 +479,9 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "fastrand" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "fixedbitset" @@ -508,9 +511,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -523,9 +526,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -533,15 +536,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", @@ -561,38 +564,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.79", ] [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-channel", "futures-core", @@ -629,9 +632,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.29.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "hashbrown" @@ -643,13 +646,19 @@ dependencies = [ "allocator-api2", ] +[[package]] +name = "hashbrown" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" + [[package]] name = "hashlink" version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" dependencies = [ - "hashbrown", + "hashbrown 0.14.5", ] [[package]] @@ -726,9 +735,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.60" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -759,12 +768,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.6" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.15.0", ] [[package]] @@ -794,9 +803,9 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "js-sys" -version = "0.3.69" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" dependencies = [ "wasm-bindgen", ] @@ -812,15 +821,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.155" +version = "0.2.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" [[package]] name = "libloading" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e310b3a6b5907f99202fcdb4960ff45b93735d7c7d96b760fcff8db2dc0e103d" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", "windows-targets 0.52.6", @@ -851,14 +860,14 @@ checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "local-ip-address" -version = "0.6.1" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136ef34e18462b17bf39a7826f8f3bbc223341f8e83822beb8b77db9a3d49696" +checksum = "3669cf5561f8d27e8fc84cc15e58350e70f557d4d65f70e3154e54cd2f8e1782" dependencies = [ "libc", "neli", "thiserror", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -901,22 +910,23 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.4" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" dependencies = [ - "adler", + "adler2", ] [[package]] name = "mio" -version = "0.8.11" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ + "hermit-abi 0.3.9", "libc", "wasi", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -1023,51 +1033,41 @@ dependencies = [ "libm", ] -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi 0.3.9", - "libc", -] - [[package]] name = "num_enum" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" +checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" dependencies = [ "num_enum_derive", ] [[package]] name = "num_enum_derive" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" +checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.79", ] [[package]] name = "object" -version = "0.36.1" +version = "0.36.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "overload" @@ -1093,7 +1093,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.2", + "redox_syscall", "smallvec", "windows-targets 0.52.6", ] @@ -1164,9 +1164,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "powerfmt" @@ -1176,25 +1176,28 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] [[package]] name = "prettyplease" -version = "0.2.20" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" +checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba" dependencies = [ "proc-macro2", - "syn 2.0.68", + "syn 2.0.79", ] [[package]] name = "proc-macro-crate" -version = "3.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" dependencies = [ "toml_edit", ] @@ -1259,7 +1262,7 @@ dependencies = [ "prost", "prost-types", "regex", - "syn 2.0.68", + "syn 2.0.79", "tempfile", ] @@ -1273,7 +1276,7 @@ dependencies = [ "itertools", "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.79", ] [[package]] @@ -1287,9 +1290,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -1326,27 +1329,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "redox_syscall" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ "bitflags 2.6.0", ] [[package]] name = "regex" -version = "1.10.5" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" dependencies = [ "aho-corasick", "memchr", @@ -1356,9 +1350,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" dependencies = [ "aho-corasick", "memchr", @@ -1367,14 +1361,14 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rolling-file" version = "0.1.0" -source = "git+https://git.asxalex.pw/rust/rolling-file#cc5f7e57bc84d09a1c69f3f3e302d8024299b1f2" +source = "git+ssh://git@git.asxalex.pw/rust/rolling-file.git#cc5f7e57bc84d09a1c69f3f3e302d8024299b1f2" dependencies = [ "anyhow", "chrono", @@ -1412,9 +1406,9 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ "bitflags 2.6.0", "errno", @@ -1439,7 +1433,7 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" name = "sdlan-rs" version = "0.1.0" dependencies = [ - "dashmap 6.0.1", + "dashmap 6.1.0", "dns-lookup", "etherparse", "futures-util", @@ -1460,7 +1454,7 @@ dependencies = [ [[package]] name = "sdlan-sn-rs" version = "0.1.0" -source = "git+ssh://git@git.asxalex.pw/sdlan-v2/sdlan-rs.git#f320526f2dc1f6c3154b9ade81c556af0d068378" +source = "git+ssh://git@git.asxalex.pw/sdlan-v2/sdlan-rs.git#b7aafc68d67812bace203c2368553f70da771ee7" dependencies = [ "aes", "byteorder", @@ -1484,31 +1478,32 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.203" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.79", ] [[package]] name = "serde_json" -version = "1.0.120" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] @@ -1521,7 +1516,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.79", ] [[package]] @@ -1555,6 +1550,12 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "signal-hook-registry" version = "1.4.2" @@ -1620,9 +1621,9 @@ dependencies = [ [[package]] name = "sqlformat" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f895e3734318cc55f1fe66258926c9b910c124d47520339efecbb6c59cec7c1f" +checksum = "7bba3a93db0cc4f7bdece8bb09e77e2e785c20bfebf79eb8340ed80708048790" dependencies = [ "nom", "unicode_categories", @@ -1878,9 +1879,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.68" +version = "2.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "901fa70d88b9d6c98022e23b4136f9f3e54e4662c3bc1bd1d84a42a9a0f0c1e9" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" dependencies = [ "proc-macro2", "quote", @@ -1889,14 +1890,15 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.10.1" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" dependencies = [ "cfg-if", "fastrand", + "once_cell", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1910,22 +1912,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.61" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.61" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.79", ] [[package]] @@ -1971,9 +1973,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c55115c6fbe2d2bef26eb09ad74bde02d8255476fc0c7b515ef09fbb35742d82" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -1986,39 +1988,38 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.38.0" +version = "1.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" +checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" dependencies = [ "backtrace", "bytes", "libc", "mio", - "num_cpus", "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "tokio-macros" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.79", ] [[package]] name = "tokio-util" -version = "0.7.11" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" dependencies = [ "bytes", "futures-core", @@ -2029,15 +2030,15 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" [[package]] name = "toml_edit" -version = "0.21.1" +version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ "indexmap", "toml_datetime", @@ -2076,7 +2077,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.79", ] [[package]] @@ -2123,42 +2124,42 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-bidi" -version = "0.3.15" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-normalization" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ "tinyvec", ] [[package]] name = "unicode-properties" -version = "0.1.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4259d9d4425d9f0661581b804cb85fe66a4c631cadd8f490d1c13a35d5d9291" +checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" [[package]] name = "unicode-segmentation" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-width" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "unicode_categories" @@ -2185,9 +2186,9 @@ checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" [[package]] name = "uuid" -version = "1.9.1" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de17fd2f7da591098415cff336e12965a28061ddace43b59cb3c430179c9439" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" dependencies = [ "getrandom", ] @@ -2212,9 +2213,9 @@ checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "wasi" @@ -2230,34 +2231,35 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" dependencies = [ "cfg-if", + "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.79", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2265,30 +2267,30 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.79", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" [[package]] name = "whoami" -version = "1.5.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44ab49fad634e88f55bf8f9bb3abd2f27d7204172a112c7c9987e01c1c94ea9" +checksum = "372d5b87f58ec45c384ba03563b03544dc5fadc3983e434b286913f5b4a9bb6d" dependencies = [ - "redox_syscall 0.4.1", + "redox_syscall", "wasite", ] @@ -2351,6 +2353,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-targets" version = "0.48.5" @@ -2474,9 +2485,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.5.40" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" dependencies = [ "memchr", ] @@ -2500,6 +2511,7 @@ version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ + "byteorder", "zerocopy-derive", ] @@ -2511,7 +2523,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.79", ] [[package]] diff --git a/message.proto b/message.proto index 86e2401..cf45ab1 100644 --- a/message.proto +++ b/message.proto @@ -16,8 +16,9 @@ message SDLV6Info { // 设备网络地址信息 message SDLDevAddr { uint32 network_id = 1; - uint32 net_addr = 2; - uint32 net_bit_len = 3; + bytes mac = 2; + uint32 net_addr = 3; + uint32 net_bit_len = 4; } // tcp通讯消息 @@ -37,7 +38,7 @@ message SDLRegisterSuper { message SDLRegisterSuperAck { SDLDevAddr dev_addr = 1; bytes aes_key = 2; - bytes known_ips = 3; + map known_macs = 3; uint32 upgrade_type = 4; optional string upgrade_prompt = 5; optional string upgrade_address = 6; @@ -51,31 +52,34 @@ message SDLRegisterSuperNak { // 网络地址查询 message SDLQueryInfo { - uint32 dst_ip = 1; + bytes dst_mac = 1; } message SDLPeerInfo { - uint32 dst_ip = 1; + bytes dst_mac = 1; SDLV4Info v4_info = 2; optional SDLV6Info v6_info = 3; } // 事件定义 -message SDLKnownIpEvent { - uint32 ip = 1; +message SDLKnownMacEvent { + bytes mac = 1; + uint32 ip = 2; } -message SDLDropIpEvent { - uint32 ip = 1; +message SDLDropMacEvent { + bytes mac = 1; + uint32 ip = 2; } message SDLNatChangedEvent { - uint32 ip = 1; + bytes mac = 1; + uint32 ip = 2; } message SDLSendRegisterEvent { - uint32 dst_ip = 1; + bytes dst_mac = 1; uint32 nat_ip = 2; uint32 nat_port = 3; optional SDLV6Info v6_info = 4; @@ -90,7 +94,7 @@ message SDLNetworkShutdownEvent { message SDLChangeNetworkCommand { SDLDevAddr dev_addr = 1; bytes aes_key = 2; - bytes known_ips = 3; + map known_macs = 3; } message SDLCommandAck { @@ -114,9 +118,10 @@ message SDLStunRequest { uint32 cookie = 1; string client_id = 2; uint32 network_id = 3; - uint32 ip = 4; - uint32 nat_type = 5; - optional SDLV6Info v6_info = 6; + bytes mac = 4; + uint32 ip = 5; + uint32 nat_type = 6; + optional SDLV6Info v6_info = 7; } message SDLStunReply { @@ -125,8 +130,8 @@ message SDLStunReply { message SDLData { uint32 network_id = 1; - uint32 src_ip = 2; - uint32 dst_ip = 3; + bytes src_mac = 2; + bytes dst_mac = 3; bool is_p2p = 4; uint32 ttl = 5; bytes data = 6; @@ -134,14 +139,14 @@ message SDLData { message SDLRegister { uint32 network_id = 1; - uint32 src_ip = 2; - uint32 dst_ip = 3; + bytes src_mac = 2; + bytes dst_mac = 3; } message SDLRegisterAck { uint32 network_id = 1; - uint32 src_ip = 2; - uint32 dst_ip = 3; + bytes src_mac = 2; + bytes dst_mac = 3; } // 网络类型探测 diff --git a/src/config/mod.rs b/src/config/mod.rs index f093ce4..1289d49 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -1,3 +1,5 @@ +use sdlan_sn_rs::utils::Mac; + pub const REGISTER_INTERVAL: u8 = 20; pub const REGISTER_SUPER_INTERVAL: u16 = 20; @@ -7,3 +9,5 @@ pub const MULTICAST_PORT: u16 = 1970; // pub const SUPER_ATTEMPTS_DEFAULT: u8 = 3; pub const TCP_PING_TIME: u64 = 7; + +pub const NULL_MAC: Mac = [0, 0, 0, 0, 0, 0]; diff --git a/src/lib.rs b/src/lib.rs index 3798ba4..7cac1bc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,12 +9,12 @@ use std::{sync::atomic::AtomicU8, time::Duration}; use std::net::{SocketAddr, ToSocketAddrs}; pub use network::get_edge; -use network::{async_main, init_edge, NodeConfig}; +pub use network::get_install_channel; +use network::{async_main, init_arp, init_edge, NodeConfig}; use tokio::sync::mpsc::{channel, Sender}; use tokio_util::sync::CancellationToken; use tracing::{debug, error}; pub use utils::{CommandLine, CommandLineInput}; -pub use network::get_install_channel; use sdlan_sn_rs::{ peer::SdlanSock, @@ -34,14 +34,15 @@ pub async fn run_sdlan( sender: std::sync::mpsc::Sender, install_channel: &str, - connecting_chan: Option> - // start_stop_sender: Sender, - // start_stop_receiver: Receiver, + connecting_chan: Option>, // start_stop_sender: Sender, + // start_stop_receiver: Receiver, ) -> Result<()> { let (start_stop_sender, start_stop_chan) = channel(20); let edge_uuid = create_or_load_uuid("")?; let node_conf = parse_config(edge_uuid, &args).await?; + init_arp(); + if let Err(e) = init_edge(&args.token, node_conf, args.tos, start_stop_sender).await { panic!("failed to init edge: {:?}", e); } @@ -51,7 +52,9 @@ pub async fn run_sdlan( let cancel = CancellationToken::new(); let install_chan = install_channel.to_owned(); tokio::spawn(async move { - if let Err(e) = async_main(install_chan, args, start_stop_chan, cancel, connecting_chan).await { + if let Err(e) = + async_main(install_chan, args, start_stop_chan, cancel, connecting_chan).await + { error!("failed to run async main: {}", e.as_str()); } }); diff --git a/src/network/arp.rs b/src/network/arp.rs new file mode 100644 index 0000000..efa63ef --- /dev/null +++ b/src/network/arp.rs @@ -0,0 +1,367 @@ +use std::{ + array, + sync::atomic::{AtomicU8, Ordering}, + time::Duration, +}; + +use tracing::error; + +use once_cell::sync::OnceCell; +use sdlan_sn_rs::utils::{net_bit_len_to_mask, Mac, BROADCAST_MAC, MULTICAST_MAC}; +use tokio::sync::{ + mpsc::{channel, Receiver, Sender}, + oneshot, +}; + +use super::{get_edge, get_route_table}; + +static GLOBAL_ARP: OnceCell = OnceCell::new(); +pub fn init_arp() { + let actor = ArpActor::new(); + GLOBAL_ARP.set(actor).unwrap(); +} + +pub fn get_arp() -> &'static ArpActor { + GLOBAL_ARP.get().unwrap() +} + +const ETHER_TYPE_ARP: u16 = 0x0806; +const ETHER_TYPE_IP: u16 = 0x0800; +const ETHER_TYPE_IP6: u16 = 0x86dd; + +const ARP_MAX_AGE: u8 = 128; + +const ARP_HWTYPE_ETH: u16 = 1; + +pub const ARP_REQUEST: u16 = 1; +pub const ARP_REPLY: u16 = 2; + +#[repr(C)] +pub struct EthHdr { + pub dest: [u8; 6], + pub src: [u8; 6], + pub eth_type: u16, +} + +#[repr(C)] +pub struct ArpHdr { + pub ethhdr: EthHdr, + pub hwtype: u16, + pub protocol: u16, + pub hwlen: u8, + pub protolen: u8, + pub opcode: u16, + pub shwaddr: [u8; 6], + pub sipaddr: [u16; 2], + pub dhwaddr: [u8; 6], + pub dipaddr: [u16; 2], +} + +impl ArpHdr { + pub fn from_slice(data: &[u8]) -> Self { + if data.len() < 42 { + panic!("data size error"); + } + Self { + ethhdr: EthHdr { + dest: data[0..6].try_into().unwrap(), + src: data[6..12].try_into().unwrap(), + eth_type: u16::from_be_bytes(data[12..14].try_into().unwrap()), + }, + hwtype: u16::from_be_bytes(data[14..16].try_into().unwrap()), + protocol: u16::from_be_bytes(data[16..18].try_into().unwrap()), + hwlen: data[18], + protolen: data[19], + opcode: u16::from_be_bytes(data[20..22].try_into().unwrap()), + shwaddr: data[22..28].try_into().unwrap(), + sipaddr: [ + u16::from_be_bytes(data[28..30].try_into().unwrap()), + u16::from_be_bytes(data[30..32].try_into().unwrap()), + ], + dhwaddr: data[32..38].try_into().unwrap(), + dipaddr: [ + u16::from_be_bytes(data[38..40].try_into().unwrap()), + u16::from_be_bytes(data[40..42].try_into().unwrap()), + ], + } + } + + pub fn marshal_to_bytes(&self) -> Vec { + let mut result = Vec::with_capacity(42); + result.extend_from_slice(&self.ethhdr.dest); + result.extend_from_slice(&self.ethhdr.src); + result.extend_from_slice(&self.ethhdr.eth_type.to_be_bytes()); + result.extend_from_slice(&self.hwtype.to_be_bytes()); + result.extend_from_slice(&self.protocol.to_be_bytes()); + result.push(self.hwlen); + result.push(self.protolen); + result.extend_from_slice(&self.opcode.to_be_bytes()); + result.extend_from_slice(&self.shwaddr); + result.extend_from_slice(&self.sipaddr[0].to_be_bytes()); + result.extend_from_slice(&self.sipaddr[1].to_be_bytes()); + + result.extend_from_slice(&self.dhwaddr); + result.extend_from_slice(&self.dipaddr[0].to_be_bytes()); + result.extend_from_slice(&self.dipaddr[1].to_be_bytes()); + + result + } + + pub fn new() -> Self { + Self { + ethhdr: EthHdr { + dest: [0; 6], + src: [0; 6], + eth_type: ETHER_TYPE_ARP, + }, + hwtype: ARP_HWTYPE_ETH, + protocol: ETHER_TYPE_IP, + hwlen: 6, + protolen: 4, + opcode: ARP_REQUEST, + shwaddr: [0; 6], + sipaddr: [0; 2], + dhwaddr: [0; 6], + dipaddr: [0; 2], + } + } +} + +const ARP_TABLE_SIZE: usize = 8; +static ARPTIME: AtomicU8 = AtomicU8::new(0); +const BROADCAST_IPADDR: u32 = 0xffffffff; + +#[derive(Debug)] +pub struct ArpEntry { + ip_addr: u32, + arptime: u8, + hw_addr: [u8; 6], +} + +impl ArpEntry { + pub fn new() -> Self { + Self { + ip_addr: 0, + arptime: 0, + hw_addr: [0; 6], + } + } +} + +pub struct ArpInfo { + // host_ip: AtomicU32, + // ip representation of mask + // host_netmask: AtomicU32, + entry: [ArpEntry; ARP_TABLE_SIZE], +} + +impl ArpInfo { + fn lookup_ip_mac(&self, ip: u32) -> ([u8; 6], u32, bool) { + if ip == BROADCAST_IPADDR { + return (BROADCAST_MAC, ip, false); + } + let first_ip = (ip >> 24) as u8 & 0xff; + if first_ip >= 224 && first_ip <= 239 { + return (MULTICAST_MAC, ip, false); + } + let mut target_ip = 0; + let edge = get_edge(); + + let host_ip = edge.device_config.get_ip(); + let host_netmask = net_bit_len_to_mask(edge.device_config.get_net_bit()); + + if (ip & host_netmask) == (host_ip & host_netmask) { + println!( + "hostip = {:?}\nhostmac={:?}\nip={:?}", + host_netmask.to_be_bytes(), + host_ip.to_be_bytes(), + ip.to_be_bytes(), + ); + target_ip = ip; + } + + if target_ip == 0 { + let route_table = get_route_table(); + if let Some(gateway_ip) = route_table.get_gateway_ip(ip) { + target_ip = gateway_ip; + } + } + if target_ip == 0 { + panic!("target should not route to me"); + } + for i in 0..ARP_TABLE_SIZE { + let item = &self.entry[i]; + if item.ip_addr == target_ip { + return (item.hw_addr, target_ip, false); + } + } + return (BROADCAST_MAC, target_ip, true); + } + + fn set_arp(&mut self, mac: [u8; 6], ip: u32) { + println!("setting ip: {:?} is at {:?}", ip.to_be_bytes(), mac); + for i in 0..ARP_TABLE_SIZE { + let item = &mut self.entry[i]; + if item.ip_addr != 0 { + if item.ip_addr == ip { + item.hw_addr = mac; + let nowage = ARPTIME.load(Ordering::Relaxed); + item.arptime = nowage; + return; + } + } + } + println!("set_arp 1"); + + let mut itemindex = ARP_TABLE_SIZE; + for i in 0..ARP_TABLE_SIZE { + let temp = &self.entry[i]; + println!("set arp 2"); + if temp.ip_addr == 0 { + itemindex = i; + println!("set arp 3: itemindex = {}", itemindex); + break; + } + } + let arptime = ARPTIME.load(Ordering::Relaxed); + if itemindex == ARP_TABLE_SIZE { + println!("set_arp 4"); + let mut tmpage = 0; + let mut idx = 0; + for i in 0..ARP_TABLE_SIZE { + let temp = &self.entry[i]; + if (arptime - temp.arptime) > tmpage { + tmpage = arptime - temp.arptime; + idx = i; + } + } + itemindex = idx; + } + println!("set_arp 5"); + let temp = &mut self.entry[itemindex]; + temp.arptime = arptime; + temp.ip_addr = ip; + temp.hw_addr = mac; + println!("set arp 6: idx={} => {:?}", itemindex, temp); + } + + fn timer(&mut self) { + let timer = ARPTIME.fetch_add(1, Ordering::Relaxed); + for i in 0..ARP_TABLE_SIZE { + let item = &mut self.entry[i]; + if item.ip_addr != 0 && (timer - item.arptime) >= ARP_MAX_AGE { + item.ip_addr = 0; + } + } + } +} + +pub enum ArpRequestInfo { + Lookup { ip: u32 }, + Set { ip: u32, mac: Mac }, +} + +pub struct ArpRequest { + req: ArpRequestInfo, + tx: oneshot::Sender, +} + +#[derive(Debug)] +pub enum ArpResponse { + LookupResp { + mac: Mac, + ip: u32, + do_arp_request: bool, + }, + SetResp { + ok: bool, + }, + ArpRespError { + msg: String, + }, +} + +#[derive(Debug)] +pub struct ArpActor { + pub tx: Sender, +} + +impl ArpActor { + pub fn new() -> Self { + let (tx, rx) = channel(20); + tokio::spawn(loop_arp_info(rx)); + Self { tx } + } +} + +async fn loop_arp_info(mut rx: Receiver) { + let mut arp = ArpInfo { + entry: array::from_fn(|_i| ArpEntry::new()), + }; + loop { + tokio::select! { + data = rx.recv() => { + if let Some(d) = data { + match d.req { + ArpRequestInfo::Lookup{ip} => { + let mac = arp.lookup_ip_mac(ip); + if let Err(e) = d.tx.send(ArpResponse::LookupResp { + mac: mac.0, ip: mac.1, do_arp_request: mac.2 } + ) { + error!("failed to send back arp lookup feedback: {:?}", e); + }; + } + ArpRequestInfo::Set{ip, mac} => { + arp.set_arp(mac, ip); + if let Err(e) = d.tx.send(ArpResponse::SetResp { ok: true }) { + error!("failed to send back arp set feedback: {:?}", e); + } + } + } + } + } + _ = tokio::time::sleep(Duration::from_secs(10)) => { + arp.timer(); + } + } + } +} + +pub async fn send_arp_request(data: ArpRequestInfo) -> ArpResponse { + let (tx, rx) = oneshot::channel(); + let arp = get_arp(); + if let Err(e) = arp.tx.send(ArpRequest { tx, req: data }).await { + error!("failed to send arp request: {}", e); + return ArpResponse::ArpRespError { + msg: "failed to send arp request".to_owned(), + }; + } + match rx.await { + Ok(res) => res, + Err(e) => ArpResponse::ArpRespError { msg: e.to_string() }, + } +} + +pub fn generate_arp_request(srcmac: [u8; 6], dstip: u32, srcip: u32) -> Vec { + let mut arphdr = ArpHdr::new(); + arphdr.ethhdr.dest = [0xff; 6]; + arphdr.dhwaddr = [0; 6]; + arphdr.ethhdr.src = srcmac; + arphdr.shwaddr = srcmac; + + arphdr.dipaddr = [(dstip >> 16) as u16, (dstip & 0xffff) as u16]; + arphdr.sipaddr = [(srcip >> 16) as u16, (srcip & 0xffff) as u16]; + + println!( + "arphdr.sipaddr: {:?}, {:?}", + arphdr.sipaddr[0].to_be_bytes(), + arphdr.sipaddr[1].to_be_bytes() + ); + println!( + "arphdr.dipaddr: {:?}, {:?}", + arphdr.dipaddr[0].to_be_bytes(), + arphdr.dipaddr[1].to_be_bytes() + ); + + arphdr.marshal_to_bytes() +} diff --git a/src/network/async_main.rs b/src/network/async_main.rs index aa0ed24..611e763 100644 --- a/src/network/async_main.rs +++ b/src/network/async_main.rs @@ -3,9 +3,12 @@ use std::sync::atomic::Ordering; use std::sync::Arc; use std::time::Duration; -use crate::config::TCP_PING_TIME; +use crate::config::{NULL_MAC, TCP_PING_TIME}; use crate::network::ipv6::run_ipv6; -use crate::network::{get_edge, ping_to_sn, read_and_parse_packet, RegisterSuperFeedback}; +use crate::network::{ + generate_arp_request, get_edge, ping_to_sn, read_and_parse_packet, send_arp_request, ArpHdr, + ArpRequestInfo, ArpResponse, RegisterSuperFeedback, ARP_REPLY, ARP_REQUEST, +}; use crate::pb::{ encode_to_tcp_message, encode_to_udp_message, SdlData, SdlDevAddr, SdlRegisterSuper, SdlRegisterSuperAck, SdlRegisterSuperNak, SdlSendRegisterEvent, SdlStunRequest, Sdlv6Info, @@ -13,13 +16,15 @@ use crate::pb::{ use crate::tcp::{init_tcp_conn, EventType, NakMsgCode, PacketType, SdlanTcp}; use crate::utils::{send_to_sock, CommandLine}; use crate::ConnectionState; -use etherparse::IpHeaders; +use etherparse::ether_type::ARP; +use etherparse::{Ethernet2Header, IpHeaders}; use sdlan_sn_rs::config::{AF_INET, AF_INET6, SDLAN_DEFAULT_TTL}; use sdlan_sn_rs::peer::{SdlanSock, V6Info}; -use sdlan_sn_rs::utils::Result; use sdlan_sn_rs::utils::{ aes_encrypt, get_current_timestamp, ip_to_string, is_multi_broadcast, rsa_decrypt, + BROADCAST_MAC, }; +use sdlan_sn_rs::utils::{Mac, Result}; use tokio::io::AsyncWriteExt; use tokio::sync::mpsc::{channel, Receiver, Sender}; use tokio_util::sync::CancellationToken; @@ -67,6 +72,11 @@ async fn handle_tcp_message(msg: SdlanTcp) { .ip .net_addr .store(dev.net_addr, Ordering::Relaxed); + let mac = match dev.mac.try_into() { + Err(_) => NULL_MAC, + Ok(m) => m, + }; + *edge.device_config.mac.write().unwrap() = mac; edge.device_config .ip .net_bit_len @@ -200,10 +210,16 @@ async fn handle_tcp_event(edge: &Node, eventtype: EventType, eventprotobuf: &[u8 }); } } + + let dst_mac = match reg.dst_mac.try_into() { + Ok(m) => m, + Err(e) => NULL_MAC, + }; + check_peer_registration_needed( edge, true, - reg.dst_ip, + dst_mac, // &v6_sock, &v6_sock, &SdlanSock { @@ -288,6 +304,7 @@ pub async fn async_main( installed_channel, client_id: edge.config.node_uuid.clone(), dev_addr: Some(SdlDevAddr { + mac: vec![], net_addr: 0, network_id: 0, net_bit_len: 0, @@ -429,6 +446,7 @@ async fn send_stun_request(eee: &Node) { client_id: eee.config.node_uuid.clone(), network_id: eee.network_id.load(Ordering::Relaxed), ip: eee.device_config.get_ip(), + mac: Vec::from(eee.device_config.get_mac()), nat_type: eee.get_nat_type() as u32, v6_info: sdl_v6_info, }; @@ -574,6 +592,14 @@ async fn read_and_parse_tun_packet(eee: &'static Node, buf: Vec) { async fn edge_send_packet_to_net(eee: &Node, data: &[u8]) { debug!("edge send packet to net({} bytes): {:?}", data.len(), data); + + let encrypt_key = eee.get_encrypt_key(); + if encrypt_key.len() == 0 { + error!("drop tun packet due to encrypt key len is 0"); + return; + } + let src_mac = eee.device_config.get_mac(); + match IpHeaders::from_slice(&data) { Ok((iphdr, _payload)) => { let Some(ipv4hdr) = iphdr.ipv4() else { @@ -594,32 +620,76 @@ async fn edge_send_packet_to_net(eee: &Node, data: &[u8]) { debug!("drop tun packet due to not authed"); return; } - let encrypt_key = eee.get_encrypt_key(); - if encrypt_key.len() == 0 { - error!("drop tun packet due to encrypt key len is 0"); - return; - } - let msg_size = data.len() as u64; - let Ok(encrypted_flow) = aes_encrypt(encrypt_key.as_slice(), data) else { - error!("failed to encrypt flow"); - return; - }; + match send_arp_request(ArpRequestInfo::Lookup { ip: dstip }).await { + ArpResponse::LookupResp { + mac, + ip, + do_arp_request, + } => { + if do_arp_request { + println!( + "find ip: {:?} => {:?}", + ip.to_be_bytes(), + dstip.to_be_bytes() + ); + let arp_msg = generate_arp_request(src_mac, ip, eee.device_config.get_ip()); + let Ok(encrypted) = aes_encrypt(&encrypt_key, &arp_msg) else { + error!("failed to encrypt arp request"); + return; + }; + // println!("arp_msg: {:?}", arp_msg); + let data = SdlData { + network_id: eee.network_id.load(Ordering::Relaxed), + src_mac: Vec::from(src_mac), + dst_mac: Vec::from([0xff; 6]), + is_p2p: true, + ttl: SDLAN_DEFAULT_TTL as u32, + data: encrypted, + }; + let data = + encode_to_udp_message(Some(data), PacketType::Data as u8).unwrap(); + // let data = marshal_message(&data); + send_packet_to_net(eee, BROADCAST_MAC, &data, arp_msg.len() as u64).await; + // edge.sock.send(data).await; + // println!("should send arp"); + return; + } - let message = SdlData { - // TODO: network id should be stored in - network_id: eee.network_id.load(Ordering::Relaxed), - src_ip: eee.device_config.get_ip(), - dst_ip: dstip, - is_p2p: true, - ttl: SDLAN_DEFAULT_TTL as u32, - data: encrypted_flow, - }; - debug!("sending SdlData: {:?}", message); - let Ok(flow) = encode_to_udp_message(Some(message), PacketType::Data as u8) else { - error!("failed to encode to udp message"); - return; - }; - send_packet_to_net(eee, dstip, &flow, msg_size).await; + // prepend the ether header + let mut etherheader = Ethernet2Header::default(); + etherheader.destination = mac; + etherheader.ether_type = etherparse::EtherType::IPV4; + etherheader.source = src_mac; + let mut packet = Vec::with_capacity(14 + data.len()); + packet.extend_from_slice(ðerheader.to_bytes()[..]); + packet.extend_from_slice(&data); + + let pkt_size = packet.len(); + println!("sending data with mac"); + + let Ok(encrypted) = aes_encrypt(&encrypt_key, &packet) else { + error!("failed to encrypt packet request"); + return; + }; + let data = SdlData { + is_p2p: true, + network_id: eee.network_id.load(Ordering::Relaxed), + ttl: SDLAN_DEFAULT_TTL as u32, + src_mac: Vec::from(src_mac), + dst_mac: Vec::from(mac), + data: Vec::from(encrypted), + }; + let msg = encode_to_udp_message(Some(data), PacketType::Data as u8).unwrap(); + let size = msg.len(); + send_packet_to_net(eee, mac, &msg, pkt_size as u64).await; + // let dstip = u32::from_be_bytes(ipv4hdr.0.destination); + println!( + "{:?} => {:?}, size={}", + ipv4hdr.0.source, ipv4hdr.0.destination, size + ); + } + _ => {} + } } Err(e) => { error!("failed to parse ip packet: {}", e.to_string()); @@ -627,13 +697,13 @@ async fn edge_send_packet_to_net(eee: &Node, data: &[u8]) { } } -async fn send_packet_to_net(eee: &Node, dst_ip: u32, pkt: &[u8], size: u64) { - let (dest_sock, is_p2p) = find_peer_destination(eee, dst_ip).await; +async fn send_packet_to_net(eee: &Node, dst_mac: Mac, pkt: &[u8], size: u64) { + let (dest_sock, is_p2p) = find_peer_destination(eee, dst_mac).await; if is_p2p { eee.stats.tx_p2p.fetch_add(size, Ordering::Relaxed); } else { eee.stats.tx_sup.fetch_add(size, Ordering::Relaxed); - if is_multi_broadcast(dst_ip) { + if is_multi_broadcast(&dst_mac) { eee.stats.tx_broadcast.fetch_add(size, Ordering::Relaxed); } } @@ -643,8 +713,8 @@ async fn send_packet_to_net(eee: &Node, dst_ip: u32, pkt: &[u8], size: u64) { } } -async fn find_peer_destination(eee: &Node, dst_ip: u32) -> (SdlanSock, bool) { - if is_multi_broadcast(dst_ip) { +async fn find_peer_destination(eee: &Node, dst_mac: Mac) -> (SdlanSock, bool) { + if is_multi_broadcast(&dst_mac) { return ( eee.config.super_nodes[eee.config.super_node_index.load(Ordering::Relaxed) as usize] .deepcopy(), @@ -653,11 +723,11 @@ async fn find_peer_destination(eee: &Node, dst_ip: u32) -> (SdlanSock, bool) { } let mut is_p2p = false; let result: SdlanSock; - if let Some(dst) = eee.known_peers.get_peer(&dst_ip) { + if let Some(dst) = eee.known_peers.get_peer(&dst_mac) { let now = get_current_timestamp(); if now - dst.last_p2p.load(Ordering::Relaxed) >= ((dst.timeout / 2) as u64) { // too much time elapsed since we saw the peer, need to register again - eee.known_peers.delete_peer_with_ip(&dst_ip); + eee.known_peers.delete_peer_with_mac(&dst_mac); result = eee.config.super_nodes [eee.config.super_node_index.load(Ordering::Relaxed) as usize] .deepcopy(); @@ -674,7 +744,7 @@ async fn find_peer_destination(eee: &Node, dst_ip: u32) -> (SdlanSock, bool) { // println!("find peer_destination: {}", is_p2p); if !is_p2p { debug!("check_query_peer_info"); - super::packet::check_query_peer_info(eee, dst_ip).await; + super::packet::check_query_peer_info(eee, dst_mac).await; } return (result, is_p2p); } diff --git a/src/network/device.rs b/src/network/device.rs index 2b95b2a..e7b4eb5 100644 --- a/src/network/device.rs +++ b/src/network/device.rs @@ -1,12 +1,16 @@ -use sdlan_sn_rs::peer::IpSubnet; +use std::sync::RwLock; + +use sdlan_sn_rs::{peer::IpSubnet, utils::Mac}; pub struct DeviceConfig { + pub mac: RwLock, pub ip: IpSubnet, } impl DeviceConfig { pub fn new() -> Self { DeviceConfig { + mac: RwLock::new([0; 6]), ip: IpSubnet::new(0, 0), } } @@ -28,6 +32,10 @@ impl DeviceConfig { pub fn get_net_bit(&self) -> u8 { self.ip.net_bit_len() } + + pub fn get_mac(&self) -> Mac { + *self.mac.read().unwrap() + } } /// The mode in which open the virtual network adapter. diff --git a/src/network/mod.rs b/src/network/mod.rs index 8162463..639801b 100644 --- a/src/network/mod.rs +++ b/src/network/mod.rs @@ -9,10 +9,15 @@ mod ipv6; mod packet; pub use packet::*; +mod arp; +pub use arp::*; + +mod route; +pub use route::*; + #[cfg_attr(target_os = "linux", path = "tun_linux.rs")] #[cfg_attr(target_os = "windows", path = "tun_win.rs")] mod tun; pub use tun::get_install_channel; mod device; - diff --git a/src/network/node.rs b/src/network/node.rs index 1e8c866..5bffb76 100644 --- a/src/network/node.rs +++ b/src/network/node.rs @@ -25,7 +25,7 @@ use super::device::{DeviceConfig, Mode}; use super::tun::{new_iface, Iface}; use tokio::fs::File; -use sdlan_sn_rs::utils::{gen_rsa_keys, load_private_key_file}; +use sdlan_sn_rs::utils::{gen_rsa_keys, load_private_key_file, Mac}; use sdlan_sn_rs::utils::{Result, SDLanError}; static EDGE: OnceCell = OnceCell::new(); @@ -473,7 +473,7 @@ impl Node { } pub struct PeerMap { - pub peers: DashMap>, + pub peers: DashMap>, } #[allow(unused)] @@ -484,7 +484,7 @@ impl PeerMap { } } - pub fn get_peer(&self, ip: &u32) -> Option> { + pub fn get_peer(&self, ip: &Mac) -> Option> { if let Some(v) = self.peers.get(ip) { Some(v.clone()) } else { @@ -506,15 +506,12 @@ impl PeerMap { None } - pub fn delete_peer_with_ip(&self, ip: &u32) { - self.peers.remove(ip); + pub fn delete_peer_with_mac(&self, mac: &Mac) { + self.peers.remove(mac); } - pub fn insert_peer(&self, p: Arc) { - let net_addr = p.dev_addr.net_addr(); - if net_addr != 0 { - self.peers.insert(net_addr, p); - } + pub fn insert_peer(&self, mac: Mac, p: Arc) { + self.peers.insert(mac, p); } } @@ -588,6 +585,7 @@ pub struct NodeConfig { #[derive(Debug)] pub struct EdgePeer { + // pub mac: Mac, pub dev_addr: IpSubnet, // 对端对外开放的ip和端口信息 @@ -613,6 +611,7 @@ pub struct EdgePeer { impl EdgePeer { pub fn new( + // mac: Mac, net_addr: u32, net_bit_len: u8, sock: &SdlanSock, @@ -629,6 +628,7 @@ impl EdgePeer { }) } Self { + // mac, dev_addr: IpSubnet::new(net_addr, net_bit_len), sock: RwLock::new(sock.deepcopy()), _v6_info: RwLock::new(v6_info), diff --git a/src/network/packet.rs b/src/network/packet.rs index 41de93b..1640a3d 100644 --- a/src/network/packet.rs +++ b/src/network/packet.rs @@ -4,8 +4,12 @@ use std::{ time::Duration, }; +use crate::utils::mac_to_string; + use crate::{ - config::REGISTER_INTERVAL, + config::{NULL_MAC, REGISTER_INTERVAL}, + get_edge, + network::{send_arp_request, ArpHdr, ArpRequestInfo, ARP_REPLY, ARP_REQUEST}, pb::{ encode_to_tcp_message, encode_to_udp_message, SdlData, SdlEmpty, SdlPeerInfo, SdlQueryInfo, SdlRegister, SdlRegisterAck, SdlStunProbeReply, @@ -13,14 +17,14 @@ use crate::{ tcp::{get_tcp_conn, PacketType}, utils::{send_to_sock, Socket}, }; -use etherparse::IpHeaders; +use etherparse::{ether_type::ARP, Ethernet2Header, IpHeaders}; use prost::Message; use sdlan_sn_rs::{ config::{AF_INET, AF_INET6}, peer::{is_sdlan_sock_equal, SdlanSock, V6Info}, utils::{ aes_decrypt, get_current_timestamp, get_sdlan_sock_from_socketaddr, ip_to_string, - is_multi_broadcast, Result, SDLanError, + is_multi_broadcast, Mac, Result, SDLanError, BROADCAST_MAC, }, }; use std::sync::Arc; @@ -107,21 +111,24 @@ pub async fn handle_packet(eee: &Node, addr: SocketAddr, buf: &[u8]) -> Result<( error!("failed to decode to SDLData"); return Err(SDLanError::NormalError("failed to decode to SDLData")); }; + let Ok(src_mac) = data.src_mac.clone().try_into() else { + error!("failed to convert src mac"); + return Err(SDLanError::NormalError("failed to convert vec to Mac")); + }; // let from_sock = get_sdlan_sock_from_socketaddr(addr).unwrap(); if data.is_p2p { debug!("[P2P] Rx data from {}", from_sock.to_string()); } else { debug!( "[PsP] Rx data from {} via {}", - ip_to_string(&data.src_ip), + mac_to_string(&src_mac), from_sock.to_string() ); } if data.is_p2p { - check_peer_registration_needed(eee, !data.is_p2p, data.src_ip, &None, &from_sock) - .await; + check_peer_registration_needed(eee, !data.is_p2p, src_mac, &None, &from_sock).await; } - handle_tun_packet(eee, !data.is_p2p, data).await; + handle_tun_packet(eee, &from_sock, !data.is_p2p, data).await; } PacketType::StunProbeReply => { let Ok(reply) = SdlStunProbeReply::decode(&buf[1..]) else { @@ -232,6 +239,10 @@ pub async fn handle_packet_peer_info( }; debug!("got peer info: {:?}", pi); + let Ok(dst_mac) = pi.dst_mac.try_into() else { + error!("mac is null"); + return Ok(()); + }; if pi.v4_info.is_none() { error!("PEER's v4_info is none"); @@ -254,10 +265,10 @@ pub async fn handle_packet_peer_info( } // let src_ip = u32::from_be_bytes(v4_u32); - if pi.dst_ip == 0 { + if dst_mac == NULL_MAC { // pong from sn } else { - match eee.pending_peers.get_peer(&pi.dst_ip) { + match eee.pending_peers.get_peer(&dst_mac) { Some(edgeinfo) => { let mut sock = SdlanSock { family: AF_INET, @@ -268,19 +279,19 @@ pub async fn handle_packet_peer_info( *(edgeinfo.sock.write().unwrap()) = sock.deepcopy(); info!( "Rx PEERINFO for {}: is at {}", - ip_to_string(&pi.dst_ip), + mac_to_string(&dst_mac), sock.to_string() ); let mut v6_info = None; if v6_port != 0 { v6_info = Some(V6Info { port: v6_port, v6 }) } - send_register(eee, &sock, &v6_info).await; + send_register(eee, &sock, dst_mac, &v6_info).await; // register_with_local_peers(eee).await; } None => { - debug!("Rx PEERINFO unknown peer: {}", ip_to_string(&pi.dst_ip)); + debug!("Rx PEERINFO unknown peer: {}", mac_to_string(&dst_mac)); } } } @@ -372,15 +383,23 @@ async fn handle_packet_register_ack( }; let origin_sender = sender_sock; + let Ok(src_mac) = ack.src_mac.try_into() else { + error!("failed to get src_mac"); + return Ok(()); + }; + let Ok(dst_mac) = ack.dst_mac.try_into() else { + error!("failed to get dst_mac"); + return Ok(()); + }; debug!( "Rx REGISTER ACK from {} [{}] to {} via {}", - ip_to_string(&ack.src_ip), + mac_to_string(&src_mac), origin_sender.to_string(), - ip_to_string(&ack.dst_ip), + mac_to_string(&dst_mac), sender_sock.to_string(), ); - peer_set_p2p_confirmed(eee, ack.src_ip, sender_sock); + peer_set_p2p_confirmed(eee, src_mac, sender_sock); Ok(()) } @@ -404,27 +423,36 @@ async fn handle_packet_register( let origin_sender = sender_sock; - let via_multicast = is_multi_broadcast(reg.dst_ip); - if via_multicast && reg.src_ip == eee.device_config.get_ip() { + let Ok(src_mac) = reg.src_mac.clone().try_into() else { + error!("[REGISTER] failed to get src_mac"); + return Ok(()); + }; + let Ok(dst_mac) = reg.dst_mac.clone().try_into() else { + error!("[REGISTER] failed to get dst_mac"); + return Ok(()); + }; + + let via_multicast = is_multi_broadcast(&dst_mac); + if via_multicast && src_mac == eee.device_config.get_mac() { debug!("skipping register from self"); return Ok(()); } if !from_sn { info!("[P2P] Rx REGISTER from {}", sender_sock.to_string()); - eee.pending_peers.delete_peer_with_ip(®.src_ip); + eee.pending_peers.delete_peer_with_mac(&src_mac); send_register_ack(eee, origin_sender, ®).await; } else { info!( "[PsP] Rx REGISTER from {} [{}] to {} via {}", - ip_to_string(®.src_ip), - ip_to_string(®.dst_ip), + mac_to_string(&src_mac), + mac_to_string(&dst_mac), sender_sock.to_string(), origin_sender.to_string(), ); } // check_peer_registration_needed(eee, from_sn, reg.src_ip, &None, origin_sender).await; - check_peer_registration_needed(eee, from_sn, reg.src_ip, &None, origin_sender).await; + check_peer_registration_needed(eee, from_sn, src_mac, &None, origin_sender).await; Ok(()) } @@ -481,20 +509,20 @@ async fn handle_packet_packet( pub async fn check_peer_registration_needed( eee: &Node, from_sn: bool, - src_ip: u32, + src_mac: Mac, _v6_info: &Option, peer_sock: &SdlanSock, ) { - let mut p = eee.known_peers.get_peer(&src_ip); + let mut p = eee.known_peers.get_peer(&src_mac); if let None = p { p = eee.known_peers.get_peer_by_sock(peer_sock); if let Some(ref k) = p { - eee.known_peers.insert_peer(k.clone()); + eee.known_peers.insert_peer(src_mac, k.clone()); } } match p { None => { - let _ = register_with_new_peer(eee, from_sn, src_ip, _v6_info, peer_sock).await; + let _ = register_with_new_peer(eee, from_sn, src_mac, _v6_info, peer_sock).await; // unimplemented!(); } Some(k) => { @@ -513,7 +541,7 @@ pub async fn check_peer_registration_needed( let last_seen = k.last_seen.load(Ordering::Relaxed); // more than 3 seconds if now - last_seen > 1 { - check_known_peer_sock_change(eee, from_sn, src_ip, peer_sock, now, ipv4_to_ipv6) + check_known_peer_sock_change(eee, from_sn, src_mac, peer_sock, now, ipv4_to_ipv6) .await; } } @@ -523,28 +551,28 @@ pub async fn check_peer_registration_needed( async fn check_known_peer_sock_change( eee: &Node, from_sn: bool, - ip: u32, + mac: Mac, // v6_info: &Option, // dev_addr: &IpSubnet, peersock: &SdlanSock, when: u64, ipv4_to_ipv6: bool, ) { - if is_multi_broadcast(ip) { + if is_multi_broadcast(&mac) { return; } - match eee.known_peers.get_peer(&ip) { + match eee.known_peers.get_peer(&mac) { Some(p) => { if !ipv4_to_ipv6 && !is_sdlan_sock_equal(&p.sock.read().unwrap(), peersock) { if !from_sn { info!( "peer changed: {}: {} -> {}", - ip_to_string(&ip), + mac_to_string(&mac), &p.sock.read().unwrap().to_string(), peersock.to_string() ); - eee.known_peers.delete_peer_with_ip(&ip); - register_with_new_peer(eee, from_sn, ip, &None, peersock).await; + eee.known_peers.delete_peer_with_mac(&mac); + register_with_new_peer(eee, from_sn, mac, &None, peersock).await; } else { // from sn, sn could see a different sock with us, just ignore it } @@ -560,17 +588,18 @@ async fn check_known_peer_sock_change( async fn register_with_new_peer( eee: &Node, from_sn: bool, - ip: u32, + mac: Mac, v6_info: &Option, // dev_addr: &IpSubnet, peersock: &SdlanSock, ) { let now = get_current_timestamp(); - let mut scan = eee.pending_peers.get_peer(&ip); + let mut scan = eee.pending_peers.get_peer(&mac); if let None = scan { // such ip not found in pending let temp = Arc::new(EdgePeer::new( - ip, + // mac, + 0, eee.device_config.get_net_bit(), peersock, &None, @@ -578,10 +607,10 @@ async fn register_with_new_peer( )); debug!( "===> new pending {} => {}", - ip_to_string(&ip), + mac_to_string(&mac), peersock.to_string(), ); - eee.pending_peers.insert_peer(temp.clone()); + eee.pending_peers.insert_peer(mac, temp.clone()); scan = Some(temp); debug!("Pending size: {}", eee.pending_peers.peers.len()); @@ -593,31 +622,32 @@ async fn register_with_new_peer( let mut alter = 16; if let Ok(ttl) = eee.udp_sock_v4.ttl() { let mut temp = peersock.deepcopy(); - send_register(eee, &temp, v6_info).await; + send_register(eee, &temp, mac, v6_info).await; let _ = eee.udp_sock_v4.set_ttl(eee.config.register_ttl as u32); while alter > 0 { temp.port += 1; - send_register(eee, &temp, v6_info).await; + send_register(eee, &temp, mac, v6_info).await; alter -= 1; } let _ = eee.udp_sock_v4.set_ttl(ttl); } } else { // Normal STUN - send_register(eee, peersock, v6_info).await; + send_register(eee, peersock, mac, v6_info).await; } // 发送给sn send_register( eee, &eee.config.super_nodes [eee.config.super_node_index.load(Ordering::Relaxed) as usize], + mac, v6_info, ) .await; } else { // P2P register, send directly - send_register(eee, peersock, v6_info).await; + send_register(eee, peersock, mac, v6_info).await; } register_with_local_peers(eee).await; } else { @@ -634,11 +664,11 @@ async fn register_with_new_peer( async fn register_with_local_peers(eee: &Node) { if eee.config.allow_p2p { debug!("send register to multicast sock"); - send_register(eee, &eee.multicast_sock, &None).await; + send_register(eee, &eee.multicast_sock, NULL_MAC, &None).await; } } -async fn send_register(eee: &Node, sock: &SdlanSock, _v6_info: &Option) { +async fn send_register(eee: &Node, sock: &SdlanSock, mac: Mac, _v6_info: &Option) { if !eee.config.allow_p2p { debug!("skipping register as p2p is disabled"); return; @@ -651,8 +681,10 @@ async fn send_register(eee: &Node, sock: &SdlanSock, _v6_info: &Option) let register = SdlRegister { network_id: network_id, - src_ip: eee.device_config.get_ip(), - dst_ip: u32::from_be_bytes(sock.v4), + src_mac: Vec::from(eee.device_config.get_mac()), + // src_ip: eee.device_config.get_ip(), + dst_mac: Vec::from(mac), + // dst_ip: u32::from_be_bytes(sock.v4), }; let msg = encode_to_udp_message(Some(register), PacketType::Register as u8).unwrap(); @@ -685,6 +717,7 @@ async fn send_register(eee: &Node, sock: &SdlanSock, _v6_info: &Option) async fn handle_tun_packet( eee: &Node, + from_sock: &SdlanSock, from_sn: bool, pkt: SdlData, //orig_sender: &SdlanSock ) { @@ -706,8 +739,13 @@ async fn handle_tun_packet( let data = origin.unwrap(); let msg_size = data.len() as u64; + let Ok(dst_mac) = pkt.dst_mac.try_into() else { + error!("[PACKET] failed to decode dst_mac"); + return; + }; + if from_sn { - if is_multi_broadcast(pkt.dst_ip) { + if is_multi_broadcast(&dst_mac) { eee.stats .rx_broadcast .fetch_add(msg_size, Ordering::Relaxed); @@ -719,25 +757,94 @@ async fn handle_tun_packet( eee.stats.last_p2p.store(now, Ordering::Relaxed); } + // TODO: parse the mac debug!("got packet from sock, will send to tun"); - match IpHeaders::from_slice(&data) { - Ok((iphdr, _)) => { - if let Some(ipv4hdr) = iphdr.ipv4() { - let dstip = u32::from_be_bytes(ipv4hdr.0.destination); - if !is_multi_broadcast(dstip) && dstip != eee.device_config.get_ip() { - // should not routed to me - error!("should not routed to me"); - return; - } - // packet should be sent to dev - debug!("writing {} bytes to tun: {:?}", data.len(), data); - if let Err(e) = eee.device.send(&data) { - error!("failed to write to tun: {}", e.to_string()); + match Ethernet2Header::from_slice(&data) { + Ok((hdr, rest)) => { + let edge = get_edge(); + let self_mac = edge.device_config.get_mac(); + if hdr.destination != self_mac && hdr.destination != BROADCAST_MAC { + error!("packet not direct to us"); + return; + } + + if hdr.ether_type == ARP { + let mut arp = ArpHdr::from_slice(&data); + let self_ip = edge.device_config.get_ip(); + + println!("self_ip: {:?}", self_ip.to_be_bytes()); + let from_ip = ((arp.sipaddr[0] as u32) << 16) + arp.sipaddr[1] as u32; + println!("from_ip: {:?}", from_ip.to_be_bytes()); + let dest_ip = ((arp.dipaddr[0] as u32) << 16) + arp.dipaddr[1] as u32; + println!("dest_ip: {:?}", dest_ip.to_be_bytes()); + + match arp.opcode { + ARP_REQUEST => { + // handle ARP REQUEST + if arp.ethhdr.dest != [0xff; 6] { + println!("ARP REQUEST not broadcast"); + return; + } + if dest_ip == self_ip { + send_arp_request(ArpRequestInfo::Set { + ip: from_ip, + mac: arp.shwaddr, + }) + .await; + // target to us + arp.opcode = ARP_REPLY; + arp.dhwaddr = arp.shwaddr; + arp.shwaddr = self_mac; + arp.ethhdr.src = self_mac; + arp.ethhdr.dest = arp.dhwaddr; + + arp.dipaddr = arp.sipaddr; + + arp.sipaddr = + [((self_ip >> 16) & 0xffff) as u16, (self_ip & 0xffff) as u16]; + + let data = SdlData { + is_p2p: true, + ttl: 2, + network_id: edge.network_id.load(Ordering::Relaxed), + src_mac: Vec::from(self_mac), + dst_mac: Vec::from(arp.dhwaddr), + data: arp.marshal_to_bytes(), + }; + + let v = + encode_to_udp_message(Some(data), PacketType::Data as u8).unwrap(); + println!("xxxx send arp reply"); + send_to_sock(edge, &v, from_sock); + // edge.sock.send(v).await; + } + } + ARP_REPLY => { + println!("got arp reply"); + + println!("mac {:?} is at {:?}", arp.shwaddr, from_ip.to_be_bytes()); + if dest_ip == self_ip { + send_arp_request(ArpRequestInfo::Set { + ip: from_ip, + mac: arp.shwaddr, + }) + .await; + } + } + other => { + println!("unknown arp type info"); + } } + } else { + println!("got ip packet"); + println!("got data: {:?}", rest); + edge.device.send(rest); + // edge.tun.send_data_to_tun(Vec::from(hdr.1)).await; } } Err(e) => { - error!("failed to parse ip packet: {}", e.to_string()); + error!("failed to parse tap packet: {}", e); + return; } } } @@ -752,10 +859,11 @@ async fn send_register_ack(eee: &Node, orig_sender: &SdlanSock, reg: &SdlRegiste error!("not authed"); return; } + let src_mac = reg.src_mac.clone(); let ack = SdlRegisterAck { network_id, - src_ip: eee.device_config.get_ip(), - dst_ip: reg.src_ip, + src_mac: Vec::from(eee.device_config.get_mac()), + dst_mac: src_mac, }; let Ok(ack) = encode_to_udp_message(Some(ack), PacketType::RegisterACK as u8) else { error!("failed to encode to udp message"); @@ -764,8 +872,8 @@ async fn send_register_ack(eee: &Node, orig_sender: &SdlanSock, reg: &SdlRegiste let _ = send_to_sock(eee, &ack, orig_sender).await; } -fn peer_set_p2p_confirmed(eee: &Node, src_ip: u32, sender_sock: &SdlanSock) { - let mut scan = eee.pending_peers.get_peer(&src_ip); +fn peer_set_p2p_confirmed(eee: &Node, src_mac: Mac, sender_sock: &SdlanSock) { + let mut scan = eee.pending_peers.get_peer(&src_mac); if let None = scan { scan = eee.pending_peers.get_peer_by_sock(sender_sock); } @@ -778,17 +886,20 @@ fn peer_set_p2p_confirmed(eee: &Node, src_ip: u32, sender_sock: &SdlanSock) { } let mut scan = scan.unwrap(); - eee.pending_peers.delete_peer_with_ip(&src_ip); - match eee.known_peers.get_peer(&src_ip) { + eee.pending_peers.delete_peer_with_mac(&src_mac); + match eee.known_peers.get_peer(&src_mac) { Some(scantmp) => { - eee.known_peers.delete_peer_with_ip(&src_ip); + eee.known_peers.delete_peer_with_mac(&src_mac); scan = scantmp; // set the remote peer sock *scan.sock.write().unwrap() = sender_sock.deepcopy(); - scan.dev_addr.net_addr.store(src_ip, Ordering::Relaxed); + // scan.mac = src_mac; + /* + scan.dev_addr.net_addr.store(&src_mac, Ordering::Relaxed); scan.dev_addr .net_bit_len .store(eee.device_config.get_net_bit(), Ordering::Relaxed); + */ } None => { *(scan.sock.write().unwrap()) = sender_sock.deepcopy(); @@ -798,20 +909,20 @@ fn peer_set_p2p_confirmed(eee: &Node, src_ip: u32, sender_sock: &SdlanSock) { scan.last_p2p.store(now, Ordering::Relaxed); scan.last_seen.store(now, Ordering::Relaxed); - let ip_string = ip_to_string(&src_ip); + let mac_string = mac_to_string(&src_mac); let sock_string = sender_sock.to_string(); info!( "P2P connection established: {} [{}]", - &ip_string, &sock_string, + &mac_string, &sock_string, ); - debug!("==> new peer: {} -> {}", &ip_string, &sock_string,); - eee.known_peers.insert_peer(scan); + debug!("==> new peer: {} -> {}", &mac_string, &sock_string,); + eee.known_peers.insert_peer(src_mac, scan); } -pub async fn check_query_peer_info(eee: &Node, dst_ip: u32) { +pub async fn check_query_peer_info(eee: &Node, mac: Mac) { let scan: Arc; let now = get_current_timestamp(); - match eee.pending_peers.get_peer(&dst_ip) { + match eee.pending_peers.get_peer(&mac) { None => { let sock = SdlanSock { family: AF_INET, @@ -820,14 +931,15 @@ pub async fn check_query_peer_info(eee: &Node, dst_ip: u32) { v6: [0; 16], }; let peer = Arc::new(EdgePeer::new( - dst_ip, + // mac, + 0, eee.device_config.get_net_bit(), &sock, &None, now, )); - debug!("insert peer {} to pending", ip_to_string(&dst_ip)); - eee.pending_peers.insert_peer(peer.clone()); + debug!("insert peer {} to pending", mac_to_string(&mac)); + eee.pending_peers.insert_peer(mac, peer.clone()); scan = peer; } Some(s) => { @@ -850,22 +962,24 @@ pub async fn check_query_peer_info(eee: &Node, dst_ip: u32) { ) .await; */ - debug!("sending query for {}", ip_to_string(&dst_ip)); + debug!("sending query for {}", mac_to_string(&mac)); register_with_local_peers(eee).await; - if let Ok(()) = send_query_peer(eee, dst_ip).await { + if let Ok(()) = send_query_peer(eee, mac).await { scan.last_sent_query.store(now, Ordering::Relaxed); } } } -async fn send_query_peer(eee: &Node, dst_ip: u32) -> Result<()> { +async fn send_query_peer(eee: &Node, dst_mac: Mac) -> Result<()> { let network_id = eee.network_id.load(Ordering::Relaxed); if network_id == 0 { error!("not authed"); return Err(SDLanError::NormalError("not connected")); } - let query = SdlQueryInfo { dst_ip }; + let query = SdlQueryInfo { + dst_mac: Vec::from(dst_mac), + }; let Ok(content) = encode_to_tcp_message( Some(query), diff --git a/src/network/route.rs b/src/network/route.rs new file mode 100644 index 0000000..9225ea0 --- /dev/null +++ b/src/network/route.rs @@ -0,0 +1,124 @@ +use std::{net::Ipv4Addr, sync::RwLock}; + +use once_cell::sync::OnceCell; +use sdlan_sn_rs::utils::net_bit_len_to_mask; + +#[derive(Debug)] +pub struct RouteTable { + content: RwLock>, +} + +static ROUTETABLE: OnceCell = OnceCell::new(); + +pub fn init_route() { + let rt = RouteTable::new(); + ROUTETABLE.set(rt).unwrap(); +} + +pub fn get_route_table() -> &'static RouteTable { + ROUTETABLE.get().unwrap() +} + +impl RouteTable { + pub fn new() -> Self { + Self { + content: RwLock::new(Vec::new()), + } + } + + pub fn get_gateway_ip(&self, net_ip: u32) -> Option { + let routes = self.content.read().unwrap(); + for route in &*routes { + println!("route: {:?}", route.to_string()); + if (route.net_ip & route.net_mask) == (net_ip & route.net_mask) { + // found + return Some(route.gateway_ip); + } + } + None + } + + pub fn del_route(&self, net_ip: u32, net_mask: u32) { + let mut routes = self.content.write().unwrap(); + let mut remove_idx = routes.len(); + for i in 0..routes.len() { + let route = &routes[i]; + if route.net_ip == net_ip && route.net_mask == net_mask { + remove_idx = i; + break; + } + } + if remove_idx < routes.len() { + routes.remove(remove_idx); + } + } + + pub fn add_route(&self, net_ip: u32, net_mask: u32, gateway_ip: u32) -> Result<(), String> { + { + let cnt = self.content.read().unwrap(); + let net = net_ip & net_mask; + for route in &*cnt { + if (route.net_ip & route.net_mask) == net { + return Err("route exists".to_owned()); + } + } + } + { + let mut routes = self.content.write().unwrap(); + routes.push(RouteInfo { + net_ip, + net_mask, + gateway_ip, + }) + } + + Ok(()) + } +} + +#[derive(Debug)] +pub struct RouteInfo { + pub net_ip: u32, + pub net_mask: u32, + pub gateway_ip: u32, +} + +impl RouteInfo { + pub fn to_string(&self) -> String { + format!( + "{:?} mask={:?}, gateway={:?}", + self.net_ip.to_be_bytes(), + self.net_mask.to_be_bytes(), + self.gateway_ip.to_be_bytes() + ) + } +} + +// ip, mask, gateway +pub fn parse_route(route: String) -> Vec<(u32, u32, u32)> { + let mut result = Vec::new(); + let routes: Vec<_> = route.split(",").collect(); + for route in routes { + let route_info: Vec<_> = route.split(";").collect(); + println!("got route info: {:?}", route_info); + if route_info.len() != 2 { + println!("route info format error"); + continue; + } + let cidr = route_info[0]; + let gateway = route_info[1].parse::().unwrap(); + let ip_and_mask: Vec<_> = cidr.split("/").collect(); + if ip_and_mask.len() != 2 { + println!("route info ip/bit error"); + continue; + } + let ip = ip_and_mask[0].parse::().unwrap(); + let maskbit = ip_and_mask[1].parse::().unwrap(); + result.push(( + u32::from_be_bytes(ip.octets()), + net_bit_len_to_mask(maskbit), + u32::from_be_bytes(gateway.octets()), + )); + } + result +} diff --git a/src/pb/message.rs b/src/pb/message.rs index 500e8e7..66f6a05 100644 --- a/src/pb/message.rs +++ b/src/pb/message.rs @@ -23,9 +23,11 @@ pub struct Sdlv6Info { pub struct SdlDevAddr { #[prost(uint32, tag = "1")] pub network_id: u32, - #[prost(uint32, tag = "2")] - pub net_addr: u32, + #[prost(bytes = "vec", tag = "2")] + pub mac: ::prost::alloc::vec::Vec, #[prost(uint32, tag = "3")] + pub net_addr: u32, + #[prost(uint32, tag = "4")] pub net_bit_len: u32, } /// tcp通讯消息 @@ -55,8 +57,8 @@ pub struct SdlRegisterSuperAck { pub dev_addr: ::core::option::Option, #[prost(bytes = "vec", tag = "2")] pub aes_key: ::prost::alloc::vec::Vec, - #[prost(bytes = "vec", tag = "3")] - pub known_ips: ::prost::alloc::vec::Vec, + #[prost(map = "uint32, bytes", tag = "3")] + pub known_macs: ::std::collections::HashMap>, #[prost(uint32, tag = "4")] pub upgrade_type: u32, #[prost(string, optional, tag = "5")] @@ -75,14 +77,14 @@ pub struct SdlRegisterSuperNak { #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SdlQueryInfo { - #[prost(uint32, tag = "1")] - pub dst_ip: u32, + #[prost(bytes = "vec", tag = "1")] + pub dst_mac: ::prost::alloc::vec::Vec, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SdlPeerInfo { - #[prost(uint32, tag = "1")] - pub dst_ip: u32, + #[prost(bytes = "vec", tag = "1")] + pub dst_mac: ::prost::alloc::vec::Vec, #[prost(message, optional, tag = "2")] pub v4_info: ::core::option::Option, #[prost(message, optional, tag = "3")] @@ -90,27 +92,33 @@ pub struct SdlPeerInfo { } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] -pub struct SdlKnownIpEvent { - #[prost(uint32, tag = "1")] +pub struct SdlKnownMacEvent { + #[prost(bytes = "vec", tag = "1")] + pub mac: ::prost::alloc::vec::Vec, + #[prost(uint32, tag = "2")] pub ip: u32, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] -pub struct SdlDropIpEvent { - #[prost(uint32, tag = "1")] +pub struct SdlDropMacEvent { + #[prost(bytes = "vec", tag = "1")] + pub mac: ::prost::alloc::vec::Vec, + #[prost(uint32, tag = "2")] pub ip: u32, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SdlNatChangedEvent { - #[prost(uint32, tag = "1")] + #[prost(bytes = "vec", tag = "1")] + pub mac: ::prost::alloc::vec::Vec, + #[prost(uint32, tag = "2")] pub ip: u32, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SdlSendRegisterEvent { - #[prost(uint32, tag = "1")] - pub dst_ip: u32, + #[prost(bytes = "vec", tag = "1")] + pub dst_mac: ::prost::alloc::vec::Vec, #[prost(uint32, tag = "2")] pub nat_ip: u32, #[prost(uint32, tag = "3")] @@ -131,8 +139,8 @@ pub struct SdlChangeNetworkCommand { pub dev_addr: ::core::option::Option, #[prost(bytes = "vec", tag = "2")] pub aes_key: ::prost::alloc::vec::Vec, - #[prost(bytes = "vec", tag = "3")] - pub known_ips: ::prost::alloc::vec::Vec, + #[prost(map = "uint32, bytes", tag = "3")] + pub known_macs: ::std::collections::HashMap>, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -165,11 +173,13 @@ pub struct SdlStunRequest { pub client_id: ::prost::alloc::string::String, #[prost(uint32, tag = "3")] pub network_id: u32, - #[prost(uint32, tag = "4")] - pub ip: u32, + #[prost(bytes = "vec", tag = "4")] + pub mac: ::prost::alloc::vec::Vec, #[prost(uint32, tag = "5")] + pub ip: u32, + #[prost(uint32, tag = "6")] pub nat_type: u32, - #[prost(message, optional, tag = "6")] + #[prost(message, optional, tag = "7")] pub v6_info: ::core::option::Option, } #[allow(clippy::derive_partial_eq_without_eq)] @@ -183,10 +193,10 @@ pub struct SdlStunReply { pub struct SdlData { #[prost(uint32, tag = "1")] pub network_id: u32, - #[prost(uint32, tag = "2")] - pub src_ip: u32, - #[prost(uint32, tag = "3")] - pub dst_ip: u32, + #[prost(bytes = "vec", tag = "2")] + pub src_mac: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "3")] + pub dst_mac: ::prost::alloc::vec::Vec, #[prost(bool, tag = "4")] pub is_p2p: bool, #[prost(uint32, tag = "5")] @@ -199,20 +209,20 @@ pub struct SdlData { pub struct SdlRegister { #[prost(uint32, tag = "1")] pub network_id: u32, - #[prost(uint32, tag = "2")] - pub src_ip: u32, - #[prost(uint32, tag = "3")] - pub dst_ip: u32, + #[prost(bytes = "vec", tag = "2")] + pub src_mac: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "3")] + pub dst_mac: ::prost::alloc::vec::Vec, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SdlRegisterAck { #[prost(uint32, tag = "1")] pub network_id: u32, - #[prost(uint32, tag = "2")] - pub src_ip: u32, - #[prost(uint32, tag = "3")] - pub dst_ip: u32, + #[prost(bytes = "vec", tag = "2")] + pub src_mac: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "3")] + pub dst_mac: ::prost::alloc::vec::Vec, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] diff --git a/src/utils/mod.rs b/src/utils/mod.rs index b1e5a83..5057254 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -2,7 +2,15 @@ mod command; pub use command::*; mod socks; +use sdlan_sn_rs::utils::Mac; pub use socks::*; mod pid_recorder; pub use pid_recorder::PidRecorder; + +pub fn mac_to_string(mac: &Mac) -> String { + format!( + "[{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}]", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] + ) +}