Commit 50b0111f authored by nanamicat's avatar nanamicat

rust-next

parent f5ffc9fe
Pipeline #41893 failed with stages
in 46 seconds
......@@ -35,12 +35,6 @@ version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
[[package]]
name = "autocfg"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "base64"
version = "0.22.1"
......@@ -49,9 +43,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "bitflags"
version = "2.6.0"
version = "2.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
[[package]]
name = "blocking"
......@@ -68,24 +62,24 @@ dependencies = [
[[package]]
name = "bytes"
version = "1.9.0"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b"
checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3"
[[package]]
name = "c2rust-bitfields"
version = "0.19.0"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "367e5d1b30f28be590b6b3868da1578361d29d9bfac516d22f497d28ed7c9055"
checksum = "46dc7d2bffa0d0b3d47eb2dc69973466858281446c2ac9f6d8a10e92ab1017df"
dependencies = [
"c2rust-bitfields-derive",
]
[[package]]
name = "c2rust-bitfields-derive"
version = "0.19.0"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a279db9c50c4024eeca1a763b6e0f033848ce74e83e47454bcf8a8a98f7b0b56"
checksum = "ebe1117afa5937ce280034e31fa1e84ed1824a252f75380327eed438535333f8"
dependencies = [
"proc-macro2",
"quote",
......@@ -94,9 +88,9 @@ dependencies = [
[[package]]
name = "cfg-if"
version = "1.0.0"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "cfg_aliases"
......@@ -165,9 +159,9 @@ dependencies = [
[[package]]
name = "crossbeam-utils"
version = "0.8.20"
version = "0.8.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
[[package]]
name = "event-listener"
......@@ -262,7 +256,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.90",
"syn 2.0.111",
]
[[package]]
......@@ -301,17 +295,11 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2"
[[package]]
name = "grouping_by"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ad3dbb820113291dd2f6aea7fb4fa6594d80381b287d4ec03ee56bb692870a9"
[[package]]
name = "ipnet"
version = "2.10.1"
version = "2.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708"
checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
[[package]]
name = "ipnetwork"
......@@ -330,9 +318,9 @@ checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
[[package]]
name = "libc"
version = "0.2.167"
version = "0.2.178"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc"
checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091"
[[package]]
name = "libloading"
......@@ -341,26 +329,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34"
dependencies = [
"cfg-if",
"windows-targets",
"windows-targets 0.52.6",
]
[[package]]
name = "log"
version = "0.4.22"
version = "0.4.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
[[package]]
name = "memchr"
version = "2.7.4"
version = "2.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
[[package]]
name = "nix"
version = "0.29.0"
version = "0.30.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6"
dependencies = [
"bitflags",
"cfg-if",
......@@ -382,9 +370,9 @@ checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
[[package]]
name = "pin-project-lite"
version = "0.2.15"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff"
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
[[package]]
name = "pin-utils"
......@@ -448,7 +436,7 @@ dependencies = [
"proc-macro2",
"quote",
"regex",
"syn 2.0.90",
"syn 2.0.111",
]
[[package]]
......@@ -496,18 +484,18 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.92"
version = "1.0.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.37"
version = "1.0.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f"
dependencies = [
"proc-macro2",
]
......@@ -549,22 +537,32 @@ checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd"
[[package]]
name = "serde"
version = "1.0.217"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
"serde_derive",
]
[[package]]
name = "serde_core"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.217"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.90",
"syn 2.0.111",
]
[[package]]
......@@ -581,21 +579,18 @@ dependencies = [
[[package]]
name = "slab"
version = "0.4.9"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
dependencies = [
"autocfg",
]
checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589"
[[package]]
name = "socket2"
version = "0.5.8"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8"
checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881"
dependencies = [
"libc",
"windows-sys 0.52.0",
"windows-sys 0.60.2",
]
[[package]]
......@@ -611,9 +606,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.90"
version = "2.0.111"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31"
checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87"
dependencies = [
"proc-macro2",
"quote",
......@@ -622,29 +617,29 @@ dependencies = [
[[package]]
name = "thiserror"
version = "2.0.3"
version = "2.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c006c85c7651b3cf2ada4584faa36773bd07bac24acfb39f3c431b36d7e667aa"
checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "2.0.3"
version = "2.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568"
checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.90",
"syn 2.0.111",
]
[[package]]
name = "tun"
version = "0.7.5"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3c3f82bccbec181c56278683da7d915cf875a6cf8a450b3bcf1367de222775e"
checksum = "3a1527bfc1f78acb1287bbd132ee44bdbf9d064c9f3ca176cb2635253f891f76"
dependencies = [
"bytes",
"cfg-if",
......@@ -653,7 +648,7 @@ dependencies = [
"log",
"nix",
"thiserror",
"windows-sys 0.59.0",
"windows-sys 0.60.2",
"wintun-bindings",
]
......@@ -664,7 +659,7 @@ dependencies = [
"base64",
"crossbeam",
"crossbeam-utils",
"grouping_by",
"libc",
"pnet",
"serde",
"serde_json",
......@@ -674,9 +669,9 @@ dependencies = [
[[package]]
name = "unicode-ident"
version = "1.0.14"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
[[package]]
name = "winapi"
......@@ -700,22 +695,28 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-link"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]]
name = "windows-sys"
version = "0.52.0"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
"windows-targets",
"windows-targets 0.52.6",
]
[[package]]
name = "windows-sys"
version = "0.59.0"
version = "0.60.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
dependencies = [
"windows-targets",
"windows-targets 0.53.5",
]
[[package]]
......@@ -724,14 +725,31 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
"windows_aarch64_gnullvm 0.52.6",
"windows_aarch64_msvc 0.52.6",
"windows_i686_gnu 0.52.6",
"windows_i686_gnullvm 0.52.6",
"windows_i686_msvc 0.52.6",
"windows_x86_64_gnu 0.52.6",
"windows_x86_64_gnullvm 0.52.6",
"windows_x86_64_msvc 0.52.6",
]
[[package]]
name = "windows-targets"
version = "0.53.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3"
dependencies = [
"windows-link",
"windows_aarch64_gnullvm 0.53.1",
"windows_aarch64_msvc 0.53.1",
"windows_i686_gnu 0.53.1",
"windows_i686_gnullvm 0.53.1",
"windows_i686_msvc 0.53.1",
"windows_x86_64_gnu 0.53.1",
"windows_x86_64_gnullvm 0.53.1",
"windows_x86_64_msvc 0.53.1",
]
[[package]]
......@@ -740,53 +758,111 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_aarch64_msvc"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnu"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_gnullvm"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_i686_msvc"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnu"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "windows_x86_64_msvc"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
[[package]]
name = "winreg"
version = "0.55.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb5a765337c50e9ec252c2069be9bf91c7df47afb103b642ba3a53bf8101be97"
dependencies = [
"cfg-if",
"windows-sys 0.59.0",
]
[[package]]
name = "wintun-bindings"
version = "0.7.17"
version = "0.7.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8aed5bc5516ca7a52018b0a198911566edfa07584bdbfd71ea39161aa13806e"
checksum = "b88303b411e20a1319b368dcd04db1480003ed46ac35193e139f542720b15fbf"
dependencies = [
"blocking",
"c2rust-bitfields",
......@@ -794,5 +870,6 @@ dependencies = [
"libloading",
"log",
"thiserror",
"windows-sys 0.59.0",
"windows-sys 0.60.2",
"winreg",
]
......@@ -4,12 +4,12 @@ version = "0.1.0"
edition = "2021"
[dependencies]
tun = "0.7"
socket2 = { version = "0.5.8", features = ["all"] }
tun = "0.8"
socket2 = { version = "0.6.1", features = ["all"] }
pnet = "0.35.0"
serde = { version = "1.0.217", features = ["derive"] }
serde = { version = "1.0.228", features = ["derive"] }
serde_json = "1.0"
base64 = "0.22.1"
crossbeam = "0.8.4"
crossbeam-utils = "0.8.20"
grouping_by = "0.2.2"
crossbeam-utils = "0.8.21"
libc = "0.2.178"
mod router;
use crate::router::{Router, RouterReader, RouterWriter, SECRET_LENGTH};
use std::collections::HashMap;
use crate::router::{Router, SECRET_LENGTH};
use std::env;
use std::error::Error;
use std::intrinsics::transmute;
use std::io::{Read, Write};
use std::mem::MaybeUninit;
use std::sync::Arc;
use std::mem::size_of;
use std::mem::{transmute, MaybeUninit};
use std::sync::atomic::Ordering;
#[repr(C)]
pub struct Meta {
......@@ -18,10 +16,16 @@ pub struct Meta {
use serde::Deserialize;
#[derive(Deserialize)]
pub struct Config {
pub local_id: u8,
pub local_secret: String,
pub routers: Vec<ConfigRouter>,
}
#[derive(Deserialize)]
pub struct ConfigRouter {
pub remote_id: u8,
pub proto: i32,
pub proto: u8,
pub family: u8,
pub mark: u32,
pub endpoint: String,
......@@ -30,85 +34,55 @@ pub struct ConfigRouter {
pub up: String,
}
#[derive(Deserialize)]
pub struct Config {
pub local_id: u8,
pub local_secret: String,
pub routers: Vec<ConfigRouter>,
}
use crossbeam_utils::thread;
use grouping_by::GroupingBy;
use pnet::packet::ipv4::Ipv4Packet;
use socket2::Socket;
fn main() -> Result<(), Box<dyn Error>> {
let config: Config = serde_json::from_str(env::args().nth(1).ok_or("need param")?.as_str())?;
let local_secret: [u8; SECRET_LENGTH] = Router::create_secret(config.local_secret.as_str())?;
let mut sockets: HashMap<u16, Arc<Socket>> = HashMap::new();
let routers: HashMap<u8, Router> = config
let routers: Vec<Router> = config
.routers
.iter()
.map(|c| Router::new(c, &mut sockets).map(|router| (c.remote_id, router)))
.collect::<Result<_, _>>()?;
let (mut router_readers, router_writers): (
HashMap<u8, RouterReader>,
HashMap<u8, RouterWriter>,
) = routers
.into_iter()
.map(|(id, router)| {
let (reader, writer) = router.split();
((id, reader), (id, writer))
})
.unzip();
let router_writers3: Vec<(Arc<Socket>, HashMap<u8, RouterWriter>)> = router_writers
.into_iter()
.grouping_by(|(_, v)| v.key())
.into_iter()
.map(|(k, v)| {
(
Arc::clone(sockets.get_mut(&k).unwrap()),
v.into_iter().collect(),
)
})
.collect();
.map(|c| Router::new(c, config.local_id))
.collect::<Result<Vec<_>, _>>()?;
println!("created tuns");
thread::scope(|s| {
for router in router_readers.values_mut() {
s.spawn(|_| {
let mut buffer = [0u8; 1500 - 20]; // minus typical IP header space
let meta_size = size_of::<Meta>();
for router in routers {
let (mut reader, mut writer) = router.split();
s.spawn(move |_| {
let mut buffer = [0u8; 1500 - 20]; // minus typical IP header space
const META_SIZE: usize = size_of::<Meta>();
// Pre-initialize with our Meta header (local -> remote)
let meta = Meta {
src_id: config.local_id,
dst_id: router.config.remote_id,
dst_id: reader.config.remote_id,
reversed: 0,
};
// Turn the Meta struct into bytes
let meta_bytes = unsafe {
std::slice::from_raw_parts(&meta as *const Meta as *const u8, meta_size)
};
buffer[..meta_size].copy_from_slice(meta_bytes);
let meta_bytes: &[u8; META_SIZE] =
unsafe { &*(&meta as *const Meta as *const [u8; META_SIZE]) };
buffer[..META_SIZE].copy_from_slice(meta_bytes);
loop {
let n = router.tun_reader.read(&mut buffer[meta_size..]).unwrap();
if let Some(ref addr) = *router.endpoint.read().unwrap() {
router.encrypt(&mut buffer[meta_size..meta_size + n]);
#[cfg(target_os = "linux")]
let _ = router.socket.set_mark(router.config.mark);
let _ = router.socket.send_to(&buffer[..meta_size + n], addr);
let n = reader.tun_reader.read(&mut buffer[META_SIZE..]).unwrap();
let guard = crossbeam::epoch::pin();
let shared = reader.endpoint.load(Ordering::Acquire, &guard);
if let Some(addr) = unsafe { shared.as_ref() } {
reader.encrypt(&mut buffer[META_SIZE..META_SIZE + n]);
let _ = reader.socket.send_to(&buffer[..META_SIZE + n], addr);
}
}
});
}
for (socket, mut router_writers) in router_writers3 {
s.spawn(move |_| {
let mut recv_buf = [MaybeUninit::uninit(); 1500];
loop {
let _ = (|| {
let (len, addr) = socket.recv_from(&mut recv_buf).unwrap();
let (len, addr) = writer.socket.recv_from(&mut recv_buf).unwrap();
let data: &mut [u8] = unsafe { transmute(&mut recv_buf[..len]) };
let packet = Ipv4Packet::new(data).ok_or("malformed packet")?;
......@@ -119,16 +93,24 @@ fn main() -> Result<(), Box<dyn Error>> {
let (meta_bytes, payload) = rest
.split_at_mut_checked(size_of::<Meta>())
.ok_or("malformed packet")?;
let meta: &Meta = unsafe { transmute(meta_bytes.as_ptr()) };
if meta.dst_id == config.local_id && meta.reversed == 0 {
let router = router_writers
.get_mut(&meta.src_id)
.ok_or("missing router")?;
*router.endpoint.write().unwrap() = Some(addr);
router.decrypt(payload, &local_secret);
router.tun_writer.write_all(payload)?;
let guard = crossbeam::epoch::pin();
let current_shared = writer.endpoint.load(Ordering::SeqCst, &guard);
let is_same = unsafe { current_shared.as_ref() }
.map(|c| *c == addr)
.unwrap_or(false);
if !is_same {
let new_shared = crossbeam::epoch::Owned::new(addr).into_shared(&guard);
let old_shared =
writer.endpoint.swap(new_shared, Ordering::SeqCst, &guard);
unsafe {
guard.defer_destroy(old_shared);
}
}
writer.decrypt(payload, &local_secret);
writer.tun_writer.write_all(payload)?;
Ok::<(), Box<dyn Error>>(())
})();
}
......
use socket2::{Domain, Protocol, SockAddr, Socket, Type};
use std::collections::hash_map::Entry;
use std::collections::HashMap;
use base64::prelude::BASE64_STANDARD;
use base64::Engine;
use socket2::{Domain, Protocol, SockAddr, SockFilter, Socket, Type};
use std::net::ToSocketAddrs;
use std::process::{Command, ExitStatus};
use std::sync::{Arc, RwLock};
use std::sync::Arc;
use tun::{Reader, Writer};
pub const SECRET_LENGTH: usize = 32;
use crate::ConfigRouter;
use base64::prelude::*;
use crate::{ConfigRouter, Meta};
use crossbeam::epoch::Atomic;
// tun -> raw
pub struct RouterReader<'a> {
pub config: &'a ConfigRouter,
pub struct RouterReader {
pub config: ConfigRouter,
pub secret: [u8; SECRET_LENGTH],
pub tun_reader: Reader,
pub socket: Arc<Socket>,
pub endpoint: Arc<RwLock<Option<SockAddr>>>,
pub endpoint: Arc<Atomic<SockAddr>>,
}
impl<'a> RouterReader<'a> {
impl RouterReader {
pub(crate) fn encrypt(&self, data: &mut [u8]) {
for (i, b) in data.iter_mut().enumerate() {
*b ^= self.secret[i % SECRET_LENGTH];
......@@ -27,34 +27,30 @@ impl<'a> RouterReader<'a> {
}
// raw -> tun
pub struct RouterWriter<'a> {
pub config: &'a ConfigRouter,
pub struct RouterWriter {
pub tun_writer: Writer,
pub endpoint: Arc<RwLock<Option<SockAddr>>>,
pub socket: Arc<Socket>,
pub endpoint: Arc<Atomic<SockAddr>>,
}
impl<'a> RouterWriter<'a> {
impl RouterWriter {
pub(crate) fn decrypt(&self, data: &mut [u8], secret: &[u8; SECRET_LENGTH]) {
for (i, b) in data.iter_mut().enumerate() {
*b ^= secret[i % SECRET_LENGTH];
}
}
pub(crate) fn key(&self) -> u16 {
Router::key(self.config)
}
}
pub struct Router<'a> {
pub config: &'a ConfigRouter,
pub struct Router {
pub config: ConfigRouter,
pub secret: [u8; SECRET_LENGTH],
pub tun_reader: Reader,
pub tun_writer: Writer,
pub socket: Arc<Socket>,
pub endpoint: Arc<RwLock<Option<SockAddr>>>,
pub endpoint: Arc<Atomic<SockAddr>>,
}
impl<'a> Router<'a> {
impl Router {
pub(crate) fn create_secret(
config: &str,
) -> Result<[u8; SECRET_LENGTH], Box<dyn std::error::Error>> {
......@@ -65,30 +61,78 @@ impl<'a> Router<'a> {
Ok(secret)
}
fn key(config: &ConfigRouter) -> u16 {
(config.family as u16) << 8 | config.proto as u16
}
fn create_raw_socket(
config: &ConfigRouter,
sockets: &mut HashMap<u16, Arc<Socket>>,
) -> Result<Arc<Socket>, Box<dyn std::error::Error>> {
let key = Router::key(config);
let result = match sockets.entry(key) {
Entry::Occupied(entry) => entry.get().clone(),
Entry::Vacant(entry) => entry
.insert(Arc::new(Socket::new(
local_id: u8,
) -> Result<Arc<Socket>, std::io::Error> {
let result = Socket::new(
if config.family == 6 {
Domain::IPV6
} else {
Domain::IPV4
},
Type::RAW,
Some(Protocol::from(config.proto)),
)?))
.clone(),
Some(Protocol::from(config.proto as i32)),
)?;
#[cfg(target_os = "linux")]
result.set_mark(config.mark)?;
Self::attach_readable_filter(config, local_id, &result)?;
Ok(Arc::new(result))
}
fn attach_readable_filter(
config: &ConfigRouter,
local_id: u8,
socket: &Socket,
) -> std::io::Result<()> {
// 由于多个对端可能会使用相同的 ipprpto 号,这里确保每个 socket 上只会收到自己对应的对端发来的消息
const META_SIZE: usize = size_of::<Meta>();
let meta = Meta {
src_id: config.remote_id,
dst_id: local_id,
reversed: 0,
};
Ok(result)
let meta_bytes: [u8; META_SIZE] =
unsafe { *(&meta as *const Meta as *const [u8; META_SIZE]) };
let target_val = u32::from_be_bytes(meta_bytes);
// 如果你的协议是 UDP,这里必须是 8 (跳过 UDP 头: SrcPort(2)+DstPort(2)+Len(2)+Sum(2))
// 如果是纯自定义 IP 协议,这里是 0
let payload_offset = 0;
socket.attach_filter(&[
// 1. 【加载 IP 头长度到寄存器 X】
// BPF_LDX (Load X) | BPF_B (Byte) | BPF_MSH (Magic Shift)
// 这是一个特殊的 BPF 指令,专门用于计算 IPv4 头长度:X = 4 * (IP[0] & 0xf)
bpf_stmt(libc::BPF_LDX | libc::BPF_B | libc::BPF_MSH, 0),
// 2. 【读取 Payload 数据到累加器 A】
// BPF_LD (Load) | BPF_W (Word, 4 bytes) | BPF_IND (Indirect, relative to X)
// 逻辑:A = Packet[X + k]
bpf_stmt(libc::BPF_LD | libc::BPF_W | libc::BPF_IND, payload_offset),
// 3. 【比较并跳转】
// BPF_JMP (Jump) | BPF_JEQ (Jump if Equal) | BPF_K (Const)
// 逻辑:if (A == target_val) goto True(0); else goto False(1);
// jt=0: 继续执行下一条
// jf=1: 跳过下一条 (直接跳到 Reject)
bpf_jump(
libc::BPF_JMP | libc::BPF_JEQ | libc::BPF_K,
target_val,
0,
1,
),
// 4. 【接受 (True 路径)】
// BPF_RET (Return) | BPF_K (Constant)
// 返回 -1 (0xFFFFFFFF) 表示截取整个包的最大长度(即接收包)
bpf_stmt(libc::BPF_RET | libc::BPF_K, u32::MAX),
// 5. 【拒绝 (False 路径)】
// BPF_RET (Return) | BPF_K (Constant)
// 返回 0 表示截取 0 字节(即丢弃包)
bpf_stmt(libc::BPF_RET | libc::BPF_K, 0),
])?;
Ok(())
}
fn create_tun_device(
config: &ConfigRouter,
) -> Result<(Reader, Writer), Box<dyn std::error::Error>> {
......@@ -104,21 +148,18 @@ impl<'a> Router<'a> {
fn create_endpoint(
config: &ConfigRouter,
) -> Result<Arc<RwLock<Option<SockAddr>>>, Box<dyn std::error::Error>> {
) -> Result<Arc<Atomic<SockAddr>>, Box<dyn std::error::Error>> {
let parsed = (config.endpoint.clone(), 0u16)
.to_socket_addrs()?
.next()
.ok_or(config.endpoint.clone())?;
Ok(Arc::new(RwLock::new(Some(parsed.into()))))
Ok(Arc::new(Atomic::new(parsed.into())))
}
pub fn new(
config: &'a ConfigRouter,
sockets: &mut HashMap<u16, Arc<Socket>>,
) -> Result<Router<'a>, Box<dyn std::error::Error>> {
pub fn new(config: ConfigRouter, local_id: u8) -> Result<Router, Box<dyn std::error::Error>> {
let secret = Self::create_secret(config.remote_secret.as_str())?;
let endpoint = Self::create_endpoint(&config)?;
let socket = Self::create_raw_socket(&config, sockets)?;
let socket = Self::create_raw_socket(&config, local_id)?;
let (tun_reader, tun_writer) = Self::create_tun_device(&config)?;
Self::run_up_script(&config)?;
......@@ -134,11 +175,11 @@ impl<'a> Router<'a> {
Ok(router)
}
pub fn split(self) -> (RouterReader<'a>, RouterWriter<'a>) {
pub fn split(self) -> (RouterReader, RouterWriter) {
let writer = RouterWriter {
config: self.config,
endpoint: Arc::clone(&self.endpoint),
endpoint: self.endpoint.clone(),
tun_writer: self.tun_writer,
socket: self.socket.clone(),
};
let reader = RouterReader {
......@@ -152,3 +193,11 @@ impl<'a> Router<'a> {
(reader, writer)
}
}
fn bpf_stmt(code: u32, k: u32) -> SockFilter {
SockFilter::new(code as u16, 0, 0, k)
}
fn bpf_jump(code: u32, k: u32, jt: u8, jf: u8) -> SockFilter {
SockFilter::new(code as u16, jt, jf, k)
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment