├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── LightningRouter.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcuserdata │ └── jacksoncoxson.xcuserdatad │ └── xcschemes │ └── xcschememanagement.plist ├── LightningRouter ├── Assets.xcassets │ ├── AccentColor.colorset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json ├── ContentView.swift ├── Info.plist ├── LightningRouter.entitlements ├── LightningRouterApp.swift └── silence.mp3 ├── Makefile ├── README.md ├── build.rs ├── module.modulemap ├── relay ├── Cargo.lock ├── Cargo.toml └── src │ └── main.rs └── src ├── lib.rs └── tcp ├── mod.rs └── packets.rs /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /build 3 | /relay/target 4 | 5 | *.xcframework 6 | lightning_router_rs.h 7 | bundle.zip 8 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "addr2line" 7 | version = "0.24.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler2" 16 | version = "2.0.1" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" 19 | 20 | [[package]] 21 | name = "anstream" 22 | version = "0.6.20" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192" 25 | dependencies = [ 26 | "anstyle", 27 | "anstyle-parse", 28 | "anstyle-query", 29 | "anstyle-wincon", 30 | "colorchoice", 31 | "is_terminal_polyfill", 32 | "utf8parse", 33 | ] 34 | 35 | [[package]] 36 | name = "anstyle" 37 | version = "1.0.11" 38 | source = "registry+https://github.com/rust-lang/crates.io-index" 39 | checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" 40 | 41 | [[package]] 42 | name = "anstyle-parse" 43 | version = "0.2.7" 44 | source = "registry+https://github.com/rust-lang/crates.io-index" 45 | checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" 46 | dependencies = [ 47 | "utf8parse", 48 | ] 49 | 50 | [[package]] 51 | name = "anstyle-query" 52 | version = "1.1.4" 53 | source = "registry+https://github.com/rust-lang/crates.io-index" 54 | checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" 55 | dependencies = [ 56 | "windows-sys 0.60.2", 57 | ] 58 | 59 | [[package]] 60 | name = "anstyle-wincon" 61 | version = "3.0.10" 62 | source = "registry+https://github.com/rust-lang/crates.io-index" 63 | checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" 64 | dependencies = [ 65 | "anstyle", 66 | "once_cell_polyfill", 67 | "windows-sys 0.60.2", 68 | ] 69 | 70 | [[package]] 71 | name = "autocfg" 72 | version = "1.5.0" 73 | source = "registry+https://github.com/rust-lang/crates.io-index" 74 | checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" 75 | 76 | [[package]] 77 | name = "backtrace" 78 | version = "0.3.75" 79 | source = "registry+https://github.com/rust-lang/crates.io-index" 80 | checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" 81 | dependencies = [ 82 | "addr2line", 83 | "cfg-if", 84 | "libc", 85 | "miniz_oxide", 86 | "object", 87 | "rustc-demangle", 88 | "windows-targets 0.52.6", 89 | ] 90 | 91 | [[package]] 92 | name = "bitflags" 93 | version = "2.9.1" 94 | source = "registry+https://github.com/rust-lang/crates.io-index" 95 | checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" 96 | 97 | [[package]] 98 | name = "bytes" 99 | version = "1.10.1" 100 | source = "registry+https://github.com/rust-lang/crates.io-index" 101 | checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" 102 | 103 | [[package]] 104 | name = "cbindgen" 105 | version = "0.29.0" 106 | source = "registry+https://github.com/rust-lang/crates.io-index" 107 | checksum = "975982cdb7ad6a142be15bdf84aea7ec6a9e5d4d797c004d43185b24cfe4e684" 108 | dependencies = [ 109 | "clap", 110 | "heck", 111 | "indexmap", 112 | "log", 113 | "proc-macro2", 114 | "quote", 115 | "serde", 116 | "serde_json", 117 | "syn", 118 | "tempfile", 119 | "toml", 120 | ] 121 | 122 | [[package]] 123 | name = "cfg-if" 124 | version = "1.0.1" 125 | source = "registry+https://github.com/rust-lang/crates.io-index" 126 | checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" 127 | 128 | [[package]] 129 | name = "clap" 130 | version = "4.5.42" 131 | source = "registry+https://github.com/rust-lang/crates.io-index" 132 | checksum = "ed87a9d530bb41a67537289bafcac159cb3ee28460e0a4571123d2a778a6a882" 133 | dependencies = [ 134 | "clap_builder", 135 | ] 136 | 137 | [[package]] 138 | name = "clap_builder" 139 | version = "4.5.42" 140 | source = "registry+https://github.com/rust-lang/crates.io-index" 141 | checksum = "64f4f3f3c77c94aff3c7e9aac9a2ca1974a5adf392a8bb751e827d6d127ab966" 142 | dependencies = [ 143 | "anstream", 144 | "anstyle", 145 | "clap_lex", 146 | "strsim", 147 | ] 148 | 149 | [[package]] 150 | name = "clap_lex" 151 | version = "0.7.5" 152 | source = "registry+https://github.com/rust-lang/crates.io-index" 153 | checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" 154 | 155 | [[package]] 156 | name = "colorchoice" 157 | version = "1.0.4" 158 | source = "registry+https://github.com/rust-lang/crates.io-index" 159 | checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" 160 | 161 | [[package]] 162 | name = "equivalent" 163 | version = "1.0.2" 164 | source = "registry+https://github.com/rust-lang/crates.io-index" 165 | checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" 166 | 167 | [[package]] 168 | name = "errno" 169 | version = "0.3.13" 170 | source = "registry+https://github.com/rust-lang/crates.io-index" 171 | checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" 172 | dependencies = [ 173 | "libc", 174 | "windows-sys 0.60.2", 175 | ] 176 | 177 | [[package]] 178 | name = "fastrand" 179 | version = "2.3.0" 180 | source = "registry+https://github.com/rust-lang/crates.io-index" 181 | checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" 182 | 183 | [[package]] 184 | name = "getrandom" 185 | version = "0.3.3" 186 | source = "registry+https://github.com/rust-lang/crates.io-index" 187 | checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" 188 | dependencies = [ 189 | "cfg-if", 190 | "libc", 191 | "r-efi", 192 | "wasi 0.14.2+wasi-0.2.4", 193 | ] 194 | 195 | [[package]] 196 | name = "gimli" 197 | version = "0.31.1" 198 | source = "registry+https://github.com/rust-lang/crates.io-index" 199 | checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" 200 | 201 | [[package]] 202 | name = "hashbrown" 203 | version = "0.15.4" 204 | source = "registry+https://github.com/rust-lang/crates.io-index" 205 | checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" 206 | 207 | [[package]] 208 | name = "heck" 209 | version = "0.5.0" 210 | source = "registry+https://github.com/rust-lang/crates.io-index" 211 | checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 212 | 213 | [[package]] 214 | name = "indexmap" 215 | version = "2.10.0" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" 218 | dependencies = [ 219 | "equivalent", 220 | "hashbrown", 221 | ] 222 | 223 | [[package]] 224 | name = "io-uring" 225 | version = "0.7.9" 226 | source = "registry+https://github.com/rust-lang/crates.io-index" 227 | checksum = "d93587f37623a1a17d94ef2bc9ada592f5465fe7732084ab7beefabe5c77c0c4" 228 | dependencies = [ 229 | "bitflags", 230 | "cfg-if", 231 | "libc", 232 | ] 233 | 234 | [[package]] 235 | name = "is_terminal_polyfill" 236 | version = "1.70.1" 237 | source = "registry+https://github.com/rust-lang/crates.io-index" 238 | checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" 239 | 240 | [[package]] 241 | name = "itoa" 242 | version = "1.0.15" 243 | source = "registry+https://github.com/rust-lang/crates.io-index" 244 | checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" 245 | 246 | [[package]] 247 | name = "libc" 248 | version = "0.2.174" 249 | source = "registry+https://github.com/rust-lang/crates.io-index" 250 | checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" 251 | 252 | [[package]] 253 | name = "lightning-router" 254 | version = "0.1.0" 255 | dependencies = [ 256 | "cbindgen", 257 | "once_cell", 258 | "tokio", 259 | ] 260 | 261 | [[package]] 262 | name = "linux-raw-sys" 263 | version = "0.9.4" 264 | source = "registry+https://github.com/rust-lang/crates.io-index" 265 | checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" 266 | 267 | [[package]] 268 | name = "lock_api" 269 | version = "0.4.13" 270 | source = "registry+https://github.com/rust-lang/crates.io-index" 271 | checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" 272 | dependencies = [ 273 | "autocfg", 274 | "scopeguard", 275 | ] 276 | 277 | [[package]] 278 | name = "log" 279 | version = "0.4.27" 280 | source = "registry+https://github.com/rust-lang/crates.io-index" 281 | checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" 282 | 283 | [[package]] 284 | name = "memchr" 285 | version = "2.7.5" 286 | source = "registry+https://github.com/rust-lang/crates.io-index" 287 | checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" 288 | 289 | [[package]] 290 | name = "miniz_oxide" 291 | version = "0.8.9" 292 | source = "registry+https://github.com/rust-lang/crates.io-index" 293 | checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" 294 | dependencies = [ 295 | "adler2", 296 | ] 297 | 298 | [[package]] 299 | name = "mio" 300 | version = "1.0.4" 301 | source = "registry+https://github.com/rust-lang/crates.io-index" 302 | checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" 303 | dependencies = [ 304 | "libc", 305 | "wasi 0.11.1+wasi-snapshot-preview1", 306 | "windows-sys 0.59.0", 307 | ] 308 | 309 | [[package]] 310 | name = "object" 311 | version = "0.36.7" 312 | source = "registry+https://github.com/rust-lang/crates.io-index" 313 | checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" 314 | dependencies = [ 315 | "memchr", 316 | ] 317 | 318 | [[package]] 319 | name = "once_cell" 320 | version = "1.21.3" 321 | source = "registry+https://github.com/rust-lang/crates.io-index" 322 | checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" 323 | 324 | [[package]] 325 | name = "once_cell_polyfill" 326 | version = "1.70.1" 327 | source = "registry+https://github.com/rust-lang/crates.io-index" 328 | checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" 329 | 330 | [[package]] 331 | name = "parking_lot" 332 | version = "0.12.4" 333 | source = "registry+https://github.com/rust-lang/crates.io-index" 334 | checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" 335 | dependencies = [ 336 | "lock_api", 337 | "parking_lot_core", 338 | ] 339 | 340 | [[package]] 341 | name = "parking_lot_core" 342 | version = "0.9.11" 343 | source = "registry+https://github.com/rust-lang/crates.io-index" 344 | checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" 345 | dependencies = [ 346 | "cfg-if", 347 | "libc", 348 | "redox_syscall", 349 | "smallvec", 350 | "windows-targets 0.52.6", 351 | ] 352 | 353 | [[package]] 354 | name = "pin-project-lite" 355 | version = "0.2.16" 356 | source = "registry+https://github.com/rust-lang/crates.io-index" 357 | checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" 358 | 359 | [[package]] 360 | name = "proc-macro2" 361 | version = "1.0.95" 362 | source = "registry+https://github.com/rust-lang/crates.io-index" 363 | checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" 364 | dependencies = [ 365 | "unicode-ident", 366 | ] 367 | 368 | [[package]] 369 | name = "quote" 370 | version = "1.0.40" 371 | source = "registry+https://github.com/rust-lang/crates.io-index" 372 | checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" 373 | dependencies = [ 374 | "proc-macro2", 375 | ] 376 | 377 | [[package]] 378 | name = "r-efi" 379 | version = "5.3.0" 380 | source = "registry+https://github.com/rust-lang/crates.io-index" 381 | checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" 382 | 383 | [[package]] 384 | name = "redox_syscall" 385 | version = "0.5.17" 386 | source = "registry+https://github.com/rust-lang/crates.io-index" 387 | checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" 388 | dependencies = [ 389 | "bitflags", 390 | ] 391 | 392 | [[package]] 393 | name = "rustc-demangle" 394 | version = "0.1.26" 395 | source = "registry+https://github.com/rust-lang/crates.io-index" 396 | checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" 397 | 398 | [[package]] 399 | name = "rustix" 400 | version = "1.0.8" 401 | source = "registry+https://github.com/rust-lang/crates.io-index" 402 | checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" 403 | dependencies = [ 404 | "bitflags", 405 | "errno", 406 | "libc", 407 | "linux-raw-sys", 408 | "windows-sys 0.60.2", 409 | ] 410 | 411 | [[package]] 412 | name = "ryu" 413 | version = "1.0.20" 414 | source = "registry+https://github.com/rust-lang/crates.io-index" 415 | checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" 416 | 417 | [[package]] 418 | name = "scopeguard" 419 | version = "1.2.0" 420 | source = "registry+https://github.com/rust-lang/crates.io-index" 421 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 422 | 423 | [[package]] 424 | name = "serde" 425 | version = "1.0.219" 426 | source = "registry+https://github.com/rust-lang/crates.io-index" 427 | checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" 428 | dependencies = [ 429 | "serde_derive", 430 | ] 431 | 432 | [[package]] 433 | name = "serde_derive" 434 | version = "1.0.219" 435 | source = "registry+https://github.com/rust-lang/crates.io-index" 436 | checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" 437 | dependencies = [ 438 | "proc-macro2", 439 | "quote", 440 | "syn", 441 | ] 442 | 443 | [[package]] 444 | name = "serde_json" 445 | version = "1.0.142" 446 | source = "registry+https://github.com/rust-lang/crates.io-index" 447 | checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7" 448 | dependencies = [ 449 | "itoa", 450 | "memchr", 451 | "ryu", 452 | "serde", 453 | ] 454 | 455 | [[package]] 456 | name = "serde_spanned" 457 | version = "0.6.9" 458 | source = "registry+https://github.com/rust-lang/crates.io-index" 459 | checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" 460 | dependencies = [ 461 | "serde", 462 | ] 463 | 464 | [[package]] 465 | name = "signal-hook-registry" 466 | version = "1.4.6" 467 | source = "registry+https://github.com/rust-lang/crates.io-index" 468 | checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" 469 | dependencies = [ 470 | "libc", 471 | ] 472 | 473 | [[package]] 474 | name = "slab" 475 | version = "0.4.10" 476 | source = "registry+https://github.com/rust-lang/crates.io-index" 477 | checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" 478 | 479 | [[package]] 480 | name = "smallvec" 481 | version = "1.15.1" 482 | source = "registry+https://github.com/rust-lang/crates.io-index" 483 | checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" 484 | 485 | [[package]] 486 | name = "socket2" 487 | version = "0.6.0" 488 | source = "registry+https://github.com/rust-lang/crates.io-index" 489 | checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" 490 | dependencies = [ 491 | "libc", 492 | "windows-sys 0.59.0", 493 | ] 494 | 495 | [[package]] 496 | name = "strsim" 497 | version = "0.11.1" 498 | source = "registry+https://github.com/rust-lang/crates.io-index" 499 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 500 | 501 | [[package]] 502 | name = "syn" 503 | version = "2.0.104" 504 | source = "registry+https://github.com/rust-lang/crates.io-index" 505 | checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" 506 | dependencies = [ 507 | "proc-macro2", 508 | "quote", 509 | "unicode-ident", 510 | ] 511 | 512 | [[package]] 513 | name = "tempfile" 514 | version = "3.20.0" 515 | source = "registry+https://github.com/rust-lang/crates.io-index" 516 | checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" 517 | dependencies = [ 518 | "fastrand", 519 | "getrandom", 520 | "once_cell", 521 | "rustix", 522 | "windows-sys 0.59.0", 523 | ] 524 | 525 | [[package]] 526 | name = "tokio" 527 | version = "1.47.1" 528 | source = "registry+https://github.com/rust-lang/crates.io-index" 529 | checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" 530 | dependencies = [ 531 | "backtrace", 532 | "bytes", 533 | "io-uring", 534 | "libc", 535 | "mio", 536 | "parking_lot", 537 | "pin-project-lite", 538 | "signal-hook-registry", 539 | "slab", 540 | "socket2", 541 | "tokio-macros", 542 | "windows-sys 0.59.0", 543 | ] 544 | 545 | [[package]] 546 | name = "tokio-macros" 547 | version = "2.5.0" 548 | source = "registry+https://github.com/rust-lang/crates.io-index" 549 | checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" 550 | dependencies = [ 551 | "proc-macro2", 552 | "quote", 553 | "syn", 554 | ] 555 | 556 | [[package]] 557 | name = "toml" 558 | version = "0.8.23" 559 | source = "registry+https://github.com/rust-lang/crates.io-index" 560 | checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" 561 | dependencies = [ 562 | "serde", 563 | "serde_spanned", 564 | "toml_datetime", 565 | "toml_edit", 566 | ] 567 | 568 | [[package]] 569 | name = "toml_datetime" 570 | version = "0.6.11" 571 | source = "registry+https://github.com/rust-lang/crates.io-index" 572 | checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" 573 | dependencies = [ 574 | "serde", 575 | ] 576 | 577 | [[package]] 578 | name = "toml_edit" 579 | version = "0.22.27" 580 | source = "registry+https://github.com/rust-lang/crates.io-index" 581 | checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" 582 | dependencies = [ 583 | "indexmap", 584 | "serde", 585 | "serde_spanned", 586 | "toml_datetime", 587 | "toml_write", 588 | "winnow", 589 | ] 590 | 591 | [[package]] 592 | name = "toml_write" 593 | version = "0.1.2" 594 | source = "registry+https://github.com/rust-lang/crates.io-index" 595 | checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" 596 | 597 | [[package]] 598 | name = "unicode-ident" 599 | version = "1.0.18" 600 | source = "registry+https://github.com/rust-lang/crates.io-index" 601 | checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" 602 | 603 | [[package]] 604 | name = "utf8parse" 605 | version = "0.2.2" 606 | source = "registry+https://github.com/rust-lang/crates.io-index" 607 | checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" 608 | 609 | [[package]] 610 | name = "wasi" 611 | version = "0.11.1+wasi-snapshot-preview1" 612 | source = "registry+https://github.com/rust-lang/crates.io-index" 613 | checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" 614 | 615 | [[package]] 616 | name = "wasi" 617 | version = "0.14.2+wasi-0.2.4" 618 | source = "registry+https://github.com/rust-lang/crates.io-index" 619 | checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" 620 | dependencies = [ 621 | "wit-bindgen-rt", 622 | ] 623 | 624 | [[package]] 625 | name = "windows-link" 626 | version = "0.1.3" 627 | source = "registry+https://github.com/rust-lang/crates.io-index" 628 | checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" 629 | 630 | [[package]] 631 | name = "windows-sys" 632 | version = "0.59.0" 633 | source = "registry+https://github.com/rust-lang/crates.io-index" 634 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 635 | dependencies = [ 636 | "windows-targets 0.52.6", 637 | ] 638 | 639 | [[package]] 640 | name = "windows-sys" 641 | version = "0.60.2" 642 | source = "registry+https://github.com/rust-lang/crates.io-index" 643 | checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" 644 | dependencies = [ 645 | "windows-targets 0.53.3", 646 | ] 647 | 648 | [[package]] 649 | name = "windows-targets" 650 | version = "0.52.6" 651 | source = "registry+https://github.com/rust-lang/crates.io-index" 652 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 653 | dependencies = [ 654 | "windows_aarch64_gnullvm 0.52.6", 655 | "windows_aarch64_msvc 0.52.6", 656 | "windows_i686_gnu 0.52.6", 657 | "windows_i686_gnullvm 0.52.6", 658 | "windows_i686_msvc 0.52.6", 659 | "windows_x86_64_gnu 0.52.6", 660 | "windows_x86_64_gnullvm 0.52.6", 661 | "windows_x86_64_msvc 0.52.6", 662 | ] 663 | 664 | [[package]] 665 | name = "windows-targets" 666 | version = "0.53.3" 667 | source = "registry+https://github.com/rust-lang/crates.io-index" 668 | checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" 669 | dependencies = [ 670 | "windows-link", 671 | "windows_aarch64_gnullvm 0.53.0", 672 | "windows_aarch64_msvc 0.53.0", 673 | "windows_i686_gnu 0.53.0", 674 | "windows_i686_gnullvm 0.53.0", 675 | "windows_i686_msvc 0.53.0", 676 | "windows_x86_64_gnu 0.53.0", 677 | "windows_x86_64_gnullvm 0.53.0", 678 | "windows_x86_64_msvc 0.53.0", 679 | ] 680 | 681 | [[package]] 682 | name = "windows_aarch64_gnullvm" 683 | version = "0.52.6" 684 | source = "registry+https://github.com/rust-lang/crates.io-index" 685 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 686 | 687 | [[package]] 688 | name = "windows_aarch64_gnullvm" 689 | version = "0.53.0" 690 | source = "registry+https://github.com/rust-lang/crates.io-index" 691 | checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" 692 | 693 | [[package]] 694 | name = "windows_aarch64_msvc" 695 | version = "0.52.6" 696 | source = "registry+https://github.com/rust-lang/crates.io-index" 697 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 698 | 699 | [[package]] 700 | name = "windows_aarch64_msvc" 701 | version = "0.53.0" 702 | source = "registry+https://github.com/rust-lang/crates.io-index" 703 | checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" 704 | 705 | [[package]] 706 | name = "windows_i686_gnu" 707 | version = "0.52.6" 708 | source = "registry+https://github.com/rust-lang/crates.io-index" 709 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 710 | 711 | [[package]] 712 | name = "windows_i686_gnu" 713 | version = "0.53.0" 714 | source = "registry+https://github.com/rust-lang/crates.io-index" 715 | checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" 716 | 717 | [[package]] 718 | name = "windows_i686_gnullvm" 719 | version = "0.52.6" 720 | source = "registry+https://github.com/rust-lang/crates.io-index" 721 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 722 | 723 | [[package]] 724 | name = "windows_i686_gnullvm" 725 | version = "0.53.0" 726 | source = "registry+https://github.com/rust-lang/crates.io-index" 727 | checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" 728 | 729 | [[package]] 730 | name = "windows_i686_msvc" 731 | version = "0.52.6" 732 | source = "registry+https://github.com/rust-lang/crates.io-index" 733 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 734 | 735 | [[package]] 736 | name = "windows_i686_msvc" 737 | version = "0.53.0" 738 | source = "registry+https://github.com/rust-lang/crates.io-index" 739 | checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" 740 | 741 | [[package]] 742 | name = "windows_x86_64_gnu" 743 | version = "0.52.6" 744 | source = "registry+https://github.com/rust-lang/crates.io-index" 745 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 746 | 747 | [[package]] 748 | name = "windows_x86_64_gnu" 749 | version = "0.53.0" 750 | source = "registry+https://github.com/rust-lang/crates.io-index" 751 | checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" 752 | 753 | [[package]] 754 | name = "windows_x86_64_gnullvm" 755 | version = "0.52.6" 756 | source = "registry+https://github.com/rust-lang/crates.io-index" 757 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 758 | 759 | [[package]] 760 | name = "windows_x86_64_gnullvm" 761 | version = "0.53.0" 762 | source = "registry+https://github.com/rust-lang/crates.io-index" 763 | checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" 764 | 765 | [[package]] 766 | name = "windows_x86_64_msvc" 767 | version = "0.52.6" 768 | source = "registry+https://github.com/rust-lang/crates.io-index" 769 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 770 | 771 | [[package]] 772 | name = "windows_x86_64_msvc" 773 | version = "0.53.0" 774 | source = "registry+https://github.com/rust-lang/crates.io-index" 775 | checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" 776 | 777 | [[package]] 778 | name = "winnow" 779 | version = "0.7.12" 780 | source = "registry+https://github.com/rust-lang/crates.io-index" 781 | checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95" 782 | dependencies = [ 783 | "memchr", 784 | ] 785 | 786 | [[package]] 787 | name = "wit-bindgen-rt" 788 | version = "0.39.0" 789 | source = "registry+https://github.com/rust-lang/crates.io-index" 790 | checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" 791 | dependencies = [ 792 | "bitflags", 793 | ] 794 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "lightning-router" 3 | version = "0.1.0" 4 | edition = "2024" 5 | 6 | [dependencies] 7 | tokio = { version = "1.47", features = ["full"] } 8 | once_cell = "1.21" 9 | 10 | [build-dependencies] 11 | cbindgen = "0.29" 12 | 13 | [lib] 14 | crate-type = ["staticlib"] 15 | -------------------------------------------------------------------------------- /LightningRouter.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 77; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 19785ED12E42E7B700C6C1F9 /* LightningRouterRS.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 19785ED02E42E7B700C6C1F9 /* LightningRouterRS.xcframework */; }; 11 | /* End PBXBuildFile section */ 12 | 13 | /* Begin PBXFileReference section */ 14 | 19785E662E4292E400C6C1F9 /* LightningRouter.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LightningRouter.app; sourceTree = BUILT_PRODUCTS_DIR; }; 15 | 19785ED02E42E7B700C6C1F9 /* LightningRouterRS.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = LightningRouterRS.xcframework; sourceTree = ""; }; 16 | /* End PBXFileReference section */ 17 | 18 | /* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ 19 | 19C804FB2E43F472009A3853 /* Exceptions for "LightningRouter" folder in "LightningRouter" target */ = { 20 | isa = PBXFileSystemSynchronizedBuildFileExceptionSet; 21 | membershipExceptions = ( 22 | Info.plist, 23 | ); 24 | target = 19785E652E4292E400C6C1F9 /* LightningRouter */; 25 | }; 26 | /* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ 27 | 28 | /* Begin PBXFileSystemSynchronizedRootGroup section */ 29 | 19785E682E4292E400C6C1F9 /* LightningRouter */ = { 30 | isa = PBXFileSystemSynchronizedRootGroup; 31 | exceptions = ( 32 | 19C804FB2E43F472009A3853 /* Exceptions for "LightningRouter" folder in "LightningRouter" target */, 33 | ); 34 | path = LightningRouter; 35 | sourceTree = ""; 36 | }; 37 | /* End PBXFileSystemSynchronizedRootGroup section */ 38 | 39 | /* Begin PBXFrameworksBuildPhase section */ 40 | 19785E632E4292E400C6C1F9 /* Frameworks */ = { 41 | isa = PBXFrameworksBuildPhase; 42 | buildActionMask = 2147483647; 43 | files = ( 44 | 19785ED12E42E7B700C6C1F9 /* LightningRouterRS.xcframework in Frameworks */, 45 | ); 46 | runOnlyForDeploymentPostprocessing = 0; 47 | }; 48 | /* End PBXFrameworksBuildPhase section */ 49 | 50 | /* Begin PBXGroup section */ 51 | 19785E5D2E4292E400C6C1F9 = { 52 | isa = PBXGroup; 53 | children = ( 54 | 19785E682E4292E400C6C1F9 /* LightningRouter */, 55 | 19785E672E4292E400C6C1F9 /* Products */, 56 | 19785ED02E42E7B700C6C1F9 /* LightningRouterRS.xcframework */, 57 | ); 58 | sourceTree = ""; 59 | }; 60 | 19785E672E4292E400C6C1F9 /* Products */ = { 61 | isa = PBXGroup; 62 | children = ( 63 | 19785E662E4292E400C6C1F9 /* LightningRouter.app */, 64 | ); 65 | name = Products; 66 | sourceTree = ""; 67 | }; 68 | /* End PBXGroup section */ 69 | 70 | /* Begin PBXNativeTarget section */ 71 | 19785E652E4292E400C6C1F9 /* LightningRouter */ = { 72 | isa = PBXNativeTarget; 73 | buildConfigurationList = 19785E882E4292E500C6C1F9 /* Build configuration list for PBXNativeTarget "LightningRouter" */; 74 | buildPhases = ( 75 | 19785E622E4292E400C6C1F9 /* Sources */, 76 | 19785E632E4292E400C6C1F9 /* Frameworks */, 77 | 19785E642E4292E400C6C1F9 /* Resources */, 78 | ); 79 | buildRules = ( 80 | ); 81 | dependencies = ( 82 | ); 83 | fileSystemSynchronizedGroups = ( 84 | 19785E682E4292E400C6C1F9 /* LightningRouter */, 85 | ); 86 | name = LightningRouter; 87 | packageProductDependencies = ( 88 | ); 89 | productName = LightningRouter; 90 | productReference = 19785E662E4292E400C6C1F9 /* LightningRouter.app */; 91 | productType = "com.apple.product-type.application"; 92 | }; 93 | /* End PBXNativeTarget section */ 94 | 95 | /* Begin PBXProject section */ 96 | 19785E5E2E4292E400C6C1F9 /* Project object */ = { 97 | isa = PBXProject; 98 | attributes = { 99 | BuildIndependentTargetsInParallel = 1; 100 | LastSwiftUpdateCheck = 1640; 101 | LastUpgradeCheck = 1640; 102 | TargetAttributes = { 103 | 19785E652E4292E400C6C1F9 = { 104 | CreatedOnToolsVersion = 16.4; 105 | }; 106 | }; 107 | }; 108 | buildConfigurationList = 19785E612E4292E400C6C1F9 /* Build configuration list for PBXProject "LightningRouter" */; 109 | developmentRegion = en; 110 | hasScannedForEncodings = 0; 111 | knownRegions = ( 112 | en, 113 | Base, 114 | ); 115 | mainGroup = 19785E5D2E4292E400C6C1F9; 116 | minimizedProjectReferenceProxies = 1; 117 | preferredProjectObjectVersion = 77; 118 | productRefGroup = 19785E672E4292E400C6C1F9 /* Products */; 119 | projectDirPath = ""; 120 | projectRoot = ""; 121 | targets = ( 122 | 19785E652E4292E400C6C1F9 /* LightningRouter */, 123 | ); 124 | }; 125 | /* End PBXProject section */ 126 | 127 | /* Begin PBXResourcesBuildPhase section */ 128 | 19785E642E4292E400C6C1F9 /* Resources */ = { 129 | isa = PBXResourcesBuildPhase; 130 | buildActionMask = 2147483647; 131 | files = ( 132 | ); 133 | runOnlyForDeploymentPostprocessing = 0; 134 | }; 135 | /* End PBXResourcesBuildPhase section */ 136 | 137 | /* Begin PBXSourcesBuildPhase section */ 138 | 19785E622E4292E400C6C1F9 /* Sources */ = { 139 | isa = PBXSourcesBuildPhase; 140 | buildActionMask = 2147483647; 141 | files = ( 142 | ); 143 | runOnlyForDeploymentPostprocessing = 0; 144 | }; 145 | /* End PBXSourcesBuildPhase section */ 146 | 147 | /* Begin XCBuildConfiguration section */ 148 | 19785E862E4292E500C6C1F9 /* Debug */ = { 149 | isa = XCBuildConfiguration; 150 | buildSettings = { 151 | ALWAYS_SEARCH_USER_PATHS = NO; 152 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 153 | CLANG_ANALYZER_NONNULL = YES; 154 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 155 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 156 | CLANG_ENABLE_MODULES = YES; 157 | CLANG_ENABLE_OBJC_ARC = YES; 158 | CLANG_ENABLE_OBJC_WEAK = YES; 159 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 160 | CLANG_WARN_BOOL_CONVERSION = YES; 161 | CLANG_WARN_COMMA = YES; 162 | CLANG_WARN_CONSTANT_CONVERSION = YES; 163 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 164 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 165 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 166 | CLANG_WARN_EMPTY_BODY = YES; 167 | CLANG_WARN_ENUM_CONVERSION = YES; 168 | CLANG_WARN_INFINITE_RECURSION = YES; 169 | CLANG_WARN_INT_CONVERSION = YES; 170 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 171 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 172 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 173 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 174 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 175 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 176 | CLANG_WARN_STRICT_PROTOTYPES = YES; 177 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 178 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 179 | CLANG_WARN_UNREACHABLE_CODE = YES; 180 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 181 | COPY_PHASE_STRIP = NO; 182 | DEBUG_INFORMATION_FORMAT = dwarf; 183 | DEVELOPMENT_TEAM = 4FW3Q8784L; 184 | ENABLE_STRICT_OBJC_MSGSEND = YES; 185 | ENABLE_TESTABILITY = YES; 186 | ENABLE_USER_SCRIPT_SANDBOXING = YES; 187 | GCC_C_LANGUAGE_STANDARD = gnu17; 188 | GCC_DYNAMIC_NO_PIC = NO; 189 | GCC_NO_COMMON_BLOCKS = YES; 190 | GCC_OPTIMIZATION_LEVEL = 0; 191 | GCC_PREPROCESSOR_DEFINITIONS = ( 192 | "DEBUG=1", 193 | "$(inherited)", 194 | ); 195 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 196 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 197 | GCC_WARN_UNDECLARED_SELECTOR = YES; 198 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 199 | GCC_WARN_UNUSED_FUNCTION = YES; 200 | GCC_WARN_UNUSED_VARIABLE = YES; 201 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES; 202 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 203 | MTL_FAST_MATH = YES; 204 | ONLY_ACTIVE_ARCH = YES; 205 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; 206 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 207 | }; 208 | name = Debug; 209 | }; 210 | 19785E872E4292E500C6C1F9 /* Release */ = { 211 | isa = XCBuildConfiguration; 212 | buildSettings = { 213 | ALWAYS_SEARCH_USER_PATHS = NO; 214 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 215 | CLANG_ANALYZER_NONNULL = YES; 216 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 217 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 218 | CLANG_ENABLE_MODULES = YES; 219 | CLANG_ENABLE_OBJC_ARC = YES; 220 | CLANG_ENABLE_OBJC_WEAK = YES; 221 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 222 | CLANG_WARN_BOOL_CONVERSION = YES; 223 | CLANG_WARN_COMMA = YES; 224 | CLANG_WARN_CONSTANT_CONVERSION = YES; 225 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 226 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 227 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 228 | CLANG_WARN_EMPTY_BODY = YES; 229 | CLANG_WARN_ENUM_CONVERSION = YES; 230 | CLANG_WARN_INFINITE_RECURSION = YES; 231 | CLANG_WARN_INT_CONVERSION = YES; 232 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 233 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 234 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 235 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 236 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 237 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 238 | CLANG_WARN_STRICT_PROTOTYPES = YES; 239 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 240 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 241 | CLANG_WARN_UNREACHABLE_CODE = YES; 242 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 243 | COPY_PHASE_STRIP = NO; 244 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 245 | DEVELOPMENT_TEAM = 4FW3Q8784L; 246 | ENABLE_NS_ASSERTIONS = NO; 247 | ENABLE_STRICT_OBJC_MSGSEND = YES; 248 | ENABLE_USER_SCRIPT_SANDBOXING = YES; 249 | GCC_C_LANGUAGE_STANDARD = gnu17; 250 | GCC_NO_COMMON_BLOCKS = YES; 251 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 252 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 253 | GCC_WARN_UNDECLARED_SELECTOR = YES; 254 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 255 | GCC_WARN_UNUSED_FUNCTION = YES; 256 | GCC_WARN_UNUSED_VARIABLE = YES; 257 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES; 258 | MTL_ENABLE_DEBUG_INFO = NO; 259 | MTL_FAST_MATH = YES; 260 | SWIFT_COMPILATION_MODE = wholemodule; 261 | }; 262 | name = Release; 263 | }; 264 | 19785E892E4292E500C6C1F9 /* Debug */ = { 265 | isa = XCBuildConfiguration; 266 | buildSettings = { 267 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 268 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 269 | CODE_SIGN_ENTITLEMENTS = LightningRouter/LightningRouter.entitlements; 270 | CODE_SIGN_STYLE = Automatic; 271 | CURRENT_PROJECT_VERSION = 1; 272 | DEVELOPMENT_TEAM = 4FW3Q8784L; 273 | ENABLE_HARDENED_RUNTIME = YES; 274 | ENABLE_PREVIEWS = YES; 275 | GENERATE_INFOPLIST_FILE = YES; 276 | INFOPLIST_FILE = LightningRouter/Info.plist; 277 | "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES; 278 | "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES; 279 | "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES; 280 | "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphonesimulator*]" = YES; 281 | "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphoneos*]" = YES; 282 | "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphonesimulator*]" = YES; 283 | "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphoneos*]" = UIStatusBarStyleDefault; 284 | "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault; 285 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 286 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 287 | IPHONEOS_DEPLOYMENT_TARGET = 18.5; 288 | LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks"; 289 | "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks"; 290 | MACOSX_DEPLOYMENT_TARGET = 15.5; 291 | MARKETING_VERSION = 1.0; 292 | PRODUCT_BUNDLE_IDENTIFIER = com.jkcoxson.LightningRouter; 293 | PRODUCT_NAME = "$(TARGET_NAME)"; 294 | REGISTER_APP_GROUPS = YES; 295 | SDKROOT = auto; 296 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx xros xrsimulator"; 297 | SWIFT_EMIT_LOC_STRINGS = YES; 298 | SWIFT_VERSION = 5.0; 299 | TARGETED_DEVICE_FAMILY = "1,2,7"; 300 | XROS_DEPLOYMENT_TARGET = 2.5; 301 | }; 302 | name = Debug; 303 | }; 304 | 19785E8A2E4292E500C6C1F9 /* Release */ = { 305 | isa = XCBuildConfiguration; 306 | buildSettings = { 307 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 308 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 309 | CODE_SIGN_ENTITLEMENTS = LightningRouter/LightningRouter.entitlements; 310 | CODE_SIGN_STYLE = Automatic; 311 | CURRENT_PROJECT_VERSION = 1; 312 | DEVELOPMENT_TEAM = 4FW3Q8784L; 313 | ENABLE_HARDENED_RUNTIME = YES; 314 | ENABLE_PREVIEWS = YES; 315 | GENERATE_INFOPLIST_FILE = YES; 316 | INFOPLIST_FILE = LightningRouter/Info.plist; 317 | "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES; 318 | "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES; 319 | "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES; 320 | "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphonesimulator*]" = YES; 321 | "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphoneos*]" = YES; 322 | "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphonesimulator*]" = YES; 323 | "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphoneos*]" = UIStatusBarStyleDefault; 324 | "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault; 325 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 326 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 327 | IPHONEOS_DEPLOYMENT_TARGET = 18.5; 328 | LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks"; 329 | "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks"; 330 | MACOSX_DEPLOYMENT_TARGET = 15.5; 331 | MARKETING_VERSION = 1.0; 332 | PRODUCT_BUNDLE_IDENTIFIER = com.jkcoxson.LightningRouter; 333 | PRODUCT_NAME = "$(TARGET_NAME)"; 334 | REGISTER_APP_GROUPS = YES; 335 | SDKROOT = auto; 336 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx xros xrsimulator"; 337 | SWIFT_EMIT_LOC_STRINGS = YES; 338 | SWIFT_VERSION = 5.0; 339 | TARGETED_DEVICE_FAMILY = "1,2,7"; 340 | XROS_DEPLOYMENT_TARGET = 2.5; 341 | }; 342 | name = Release; 343 | }; 344 | /* End XCBuildConfiguration section */ 345 | 346 | /* Begin XCConfigurationList section */ 347 | 19785E612E4292E400C6C1F9 /* Build configuration list for PBXProject "LightningRouter" */ = { 348 | isa = XCConfigurationList; 349 | buildConfigurations = ( 350 | 19785E862E4292E500C6C1F9 /* Debug */, 351 | 19785E872E4292E500C6C1F9 /* Release */, 352 | ); 353 | defaultConfigurationIsVisible = 0; 354 | defaultConfigurationName = Release; 355 | }; 356 | 19785E882E4292E500C6C1F9 /* Build configuration list for PBXNativeTarget "LightningRouter" */ = { 357 | isa = XCConfigurationList; 358 | buildConfigurations = ( 359 | 19785E892E4292E500C6C1F9 /* Debug */, 360 | 19785E8A2E4292E500C6C1F9 /* Release */, 361 | ); 362 | defaultConfigurationIsVisible = 0; 363 | defaultConfigurationName = Release; 364 | }; 365 | /* End XCConfigurationList section */ 366 | }; 367 | rootObject = 19785E5E2E4292E400C6C1F9 /* Project object */; 368 | } 369 | -------------------------------------------------------------------------------- /LightningRouter.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /LightningRouter.xcodeproj/xcuserdata/jacksoncoxson.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | LightningRouter-MacOS.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 1 11 | 12 | LightningRouter.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 0 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /LightningRouter/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /LightningRouter/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "platform" : "ios", 6 | "size" : "1024x1024" 7 | }, 8 | { 9 | "appearances" : [ 10 | { 11 | "appearance" : "luminosity", 12 | "value" : "dark" 13 | } 14 | ], 15 | "idiom" : "universal", 16 | "platform" : "ios", 17 | "size" : "1024x1024" 18 | }, 19 | { 20 | "appearances" : [ 21 | { 22 | "appearance" : "luminosity", 23 | "value" : "tinted" 24 | } 25 | ], 26 | "idiom" : "universal", 27 | "platform" : "ios", 28 | "size" : "1024x1024" 29 | }, 30 | { 31 | "idiom" : "mac", 32 | "scale" : "1x", 33 | "size" : "16x16" 34 | }, 35 | { 36 | "idiom" : "mac", 37 | "scale" : "2x", 38 | "size" : "16x16" 39 | }, 40 | { 41 | "idiom" : "mac", 42 | "scale" : "1x", 43 | "size" : "32x32" 44 | }, 45 | { 46 | "idiom" : "mac", 47 | "scale" : "2x", 48 | "size" : "32x32" 49 | }, 50 | { 51 | "idiom" : "mac", 52 | "scale" : "1x", 53 | "size" : "128x128" 54 | }, 55 | { 56 | "idiom" : "mac", 57 | "scale" : "2x", 58 | "size" : "128x128" 59 | }, 60 | { 61 | "idiom" : "mac", 62 | "scale" : "1x", 63 | "size" : "256x256" 64 | }, 65 | { 66 | "idiom" : "mac", 67 | "scale" : "2x", 68 | "size" : "256x256" 69 | }, 70 | { 71 | "idiom" : "mac", 72 | "scale" : "1x", 73 | "size" : "512x512" 74 | }, 75 | { 76 | "idiom" : "mac", 77 | "scale" : "2x", 78 | "size" : "512x512" 79 | } 80 | ], 81 | "info" : { 82 | "author" : "xcode", 83 | "version" : 1 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /LightningRouter/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /LightningRouter/ContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentView.swift 3 | // LightningRouter 4 | // 5 | // Created by Jackson Coxson on 8/5/25. 6 | // 7 | 8 | import SwiftUI 9 | import LightningRouterRS 10 | import AVFoundation 11 | 12 | struct ContentView: View { 13 | @State private var plsEnable = false 14 | @AppStorage("lastTargetIP") private var targetIP: String = "1.1.1.1" 15 | @State private var threadKiller: OpaquePointer? = nil 16 | @State private var connectionStatus: String = "Disconnected" 17 | 18 | var body: some View { 19 | VStack(spacing: 20) { 20 | Image(systemName: "globe") 21 | .imageScale(.large) 22 | .foregroundStyle(.tint) 23 | .font(.system(size: 40)) 24 | .padding(.top, 20) 25 | 26 | Text("LightningRouter") 27 | .font(.title2) 28 | .bold() 29 | 30 | TextField("Enter IP address", text: $targetIP) 31 | .textFieldStyle(RoundedBorderTextFieldStyle()) 32 | .padding(.horizontal) 33 | .disableAutocorrection(true) 34 | .autocapitalization(.none) 35 | 36 | Toggle(isOn: $plsEnable) { 37 | Text("Enable Tunnel") 38 | } 39 | .padding(.horizontal) 40 | 41 | Text("Status: \(connectionStatus)") 42 | .foregroundColor(plsEnable ? .green : .secondary) 43 | .font(.footnote) 44 | .padding(.top, 10) 45 | 46 | Spacer() 47 | } 48 | .padding() 49 | .onChange(of: plsEnable) { newValue in 50 | print("Tunnel changed: \(newValue), IP: \(targetIP)") 51 | 52 | if threadKiller != nil { 53 | thread_killer_kill(threadKiller) 54 | threadKiller = nil 55 | connectionStatus = "Disconnected" 56 | UIApplication.shared.isIdleTimerDisabled = false 57 | } 58 | 59 | if newValue { 60 | enableBackgroundAudioTrick() 61 | let cAddress = strdup(targetIP) 62 | let success = start_simple_udp_proxy(cAddress, 51820, &threadKiller) 63 | free(cAddress) 64 | 65 | if success { 66 | connectionStatus = "Connected" 67 | UIApplication.shared.isIdleTimerDisabled = true 68 | } else { 69 | connectionStatus = "Failed to connect" 70 | plsEnable = false 71 | } 72 | } 73 | } 74 | } 75 | } 76 | 77 | 78 | func enableBackgroundAudioTrick() { 79 | let session = AVAudioSession.sharedInstance() 80 | do { 81 | try session.setCategory(.playback, mode: .default) 82 | try session.setActive(true) 83 | 84 | let silent = Bundle.main.url(forResource: "silence", withExtension: "mp3")! 85 | let player = try AVAudioPlayer(contentsOf: silent) 86 | player.numberOfLoops = -1 87 | player.volume = 0 88 | player.play() 89 | } catch { 90 | print("Failed to enable background audio: \(error)") 91 | } 92 | } 93 | 94 | #Preview { 95 | ContentView() 96 | } 97 | -------------------------------------------------------------------------------- /LightningRouter/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIBackgroundModes 6 | 7 | audio 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /LightningRouter/LightningRouter.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | com.apple.security.network.client 10 | 11 | com.apple.security.network.server 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /LightningRouter/LightningRouterApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LightningRouterApp.swift 3 | // LightningRouter 4 | // 5 | // Created by Jackson Coxson on 8/5/25. 6 | // 7 | 8 | import SwiftUI 9 | 10 | @main 11 | struct LightningRouterApp: App { 12 | var body: some Scene { 13 | WindowGroup { 14 | ContentView() 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /LightningRouter/silence.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jkcoxson/LightningRouter/031eccdc01f54abfb3224116796cf4d790d04841/LightningRouter/silence.mp3 -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # intended to be run by Xcode during build 2 | 3 | CARGO := $(HOME)/.cargo/bin/cargo 4 | 5 | .PHONY: all debug clean build 6 | 7 | all: build 8 | 9 | build: 10 | # iOS device build 11 | BINDGEN_EXTRA_CLANG_ARGS="--sysroot=$(xcrun --sdk iphoneos --show-sdk-path)" \ 12 | $(CARGO) build --lib --release --target aarch64-apple-ios 13 | 14 | # iOS Simulator (arm64) 15 | BINDGEN_EXTRA_CLANG_ARGS="--sysroot=$(xcrun --sdk iphonesimulator --show-sdk-path)" \ 16 | $(CARGO) build --lib --release --target aarch64-apple-ios-sim 17 | 18 | # iOS Simulator (x86_64) 19 | BINDGEN_EXTRA_CLANG_ARGS="--sysroot=$(xcrun --sdk iphonesimulator --show-sdk-path)" \ 20 | $(CARGO) build --lib --release --target x86_64-apple-ios 21 | cargo build --lib --release --target aarch64-apple-darwin 22 | cargo build --lib --release --target x86_64-apple-darwin 23 | rm -rf LightningRouterRS.xcframework 24 | mkdir -p build/include 25 | cp lightning_router_rs.h build/include 26 | cp module.modulemap build/include 27 | lipo -create -output build/liblightning_router-ios-sim.a \ 28 | target/aarch64-apple-ios-sim/release/liblightning_router.a \ 29 | target/x86_64-apple-ios/release/liblightning_router.a 30 | lipo -create -output build/liblightning_router-macos.a \ 31 | target/aarch64-apple-darwin/release/liblightning_router.a \ 32 | target/x86_64-apple-darwin/release/liblightning_router.a 33 | 34 | xcodebuild -create-xcframework \ 35 | -library target/aarch64-apple-ios/release/liblightning_router.a -headers build/include \ 36 | -library build/liblightning_router-ios-sim.a -headers build/include \ 37 | -library build/liblightning_router-macos.a -headers build/include \ 38 | -output LightningRouterRS.xcframework 39 | 40 | zip -r bundle.zip LightningRouterRS.xcframework 41 | openssl dgst -sha256 bundle.zip 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Lightning Router 2 | 3 | Use your device as a router through USB 4 | 5 | ## Vision 6 | 7 | Your device has mobile data. Your Mac does not. 8 | Why not use your device's mobile data on your Mac? 9 | 10 | Right now, this program relays a Wireguard connection 11 | from your Mac to a Wireguard server. 12 | 13 | Eventually, this app will have a userspace TCP stack 14 | to proxy connections as a NAT. 15 | 16 | ## Building/Running 17 | 18 | Build the dependencies 19 | 20 | ```sh 21 | cd LightningRouter 22 | make 23 | ``` 24 | 25 | Build the app with Xcode and install on your device 26 | 27 | Build the Mac relay 28 | 29 | ```sh 30 | cd relay 31 | cargo run --release 32 | ``` 33 | 34 | In Wireguard, set the target address to ``127.0.0.1:3400`` 35 | (or the IP of your Mac from another device). 36 | 37 | In the iOS app, set the target IP to your Wireguard endpoint, and enable. 38 | 39 | Profit. 40 | 41 | ## Speed 42 | 43 | But is it fast? *Oh yeah* it's fast. I get roughly 200mbps, 44 | or about 2/3 of my internet connection speed. 45 | Not too bad for overhead. 46 | 47 | ## License 48 | 49 | Not sure yet 50 | -------------------------------------------------------------------------------- /build.rs: -------------------------------------------------------------------------------- 1 | // Jackson Coxson 2 | 3 | use std::env; 4 | 5 | fn main() { 6 | let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); 7 | 8 | cbindgen::Builder::new() 9 | .with_crate(crate_dir) 10 | .with_header( 11 | "// Jackson Coxson\n// Bindings to LightningRouter - https://github.com/jkcoxson/idevice", 12 | ) 13 | .with_language(cbindgen::Language::C) 14 | .generate() 15 | .expect("Unable to generate bindings") 16 | .write_to_file("lightning_router_rs.h"); 17 | } 18 | -------------------------------------------------------------------------------- /module.modulemap: -------------------------------------------------------------------------------- 1 | module LightningRouterRS { 2 | header "lightning_router_rs.h" 3 | export * 4 | } 5 | 6 | -------------------------------------------------------------------------------- /relay/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "addr2line" 7 | version = "0.24.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler2" 16 | version = "2.0.1" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" 19 | 20 | [[package]] 21 | name = "aho-corasick" 22 | version = "1.1.3" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 25 | dependencies = [ 26 | "memchr", 27 | ] 28 | 29 | [[package]] 30 | name = "anstream" 31 | version = "0.6.20" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192" 34 | dependencies = [ 35 | "anstyle", 36 | "anstyle-parse", 37 | "anstyle-query", 38 | "anstyle-wincon", 39 | "colorchoice", 40 | "is_terminal_polyfill", 41 | "utf8parse", 42 | ] 43 | 44 | [[package]] 45 | name = "anstyle" 46 | version = "1.0.11" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" 49 | 50 | [[package]] 51 | name = "anstyle-parse" 52 | version = "0.2.7" 53 | source = "registry+https://github.com/rust-lang/crates.io-index" 54 | checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" 55 | dependencies = [ 56 | "utf8parse", 57 | ] 58 | 59 | [[package]] 60 | name = "anstyle-query" 61 | version = "1.1.4" 62 | source = "registry+https://github.com/rust-lang/crates.io-index" 63 | checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" 64 | dependencies = [ 65 | "windows-sys 0.60.2", 66 | ] 67 | 68 | [[package]] 69 | name = "anstyle-wincon" 70 | version = "3.0.10" 71 | source = "registry+https://github.com/rust-lang/crates.io-index" 72 | checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" 73 | dependencies = [ 74 | "anstyle", 75 | "once_cell_polyfill", 76 | "windows-sys 0.60.2", 77 | ] 78 | 79 | [[package]] 80 | name = "autocfg" 81 | version = "1.5.0" 82 | source = "registry+https://github.com/rust-lang/crates.io-index" 83 | checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" 84 | 85 | [[package]] 86 | name = "aws-lc-rs" 87 | version = "1.13.3" 88 | source = "registry+https://github.com/rust-lang/crates.io-index" 89 | checksum = "5c953fe1ba023e6b7730c0d4b031d06f267f23a46167dcbd40316644b10a17ba" 90 | dependencies = [ 91 | "aws-lc-sys", 92 | "zeroize", 93 | ] 94 | 95 | [[package]] 96 | name = "aws-lc-sys" 97 | version = "0.30.0" 98 | source = "registry+https://github.com/rust-lang/crates.io-index" 99 | checksum = "dbfd150b5dbdb988bcc8fb1fe787eb6b7ee6180ca24da683b61ea5405f3d43ff" 100 | dependencies = [ 101 | "bindgen", 102 | "cc", 103 | "cmake", 104 | "dunce", 105 | "fs_extra", 106 | ] 107 | 108 | [[package]] 109 | name = "backtrace" 110 | version = "0.3.75" 111 | source = "registry+https://github.com/rust-lang/crates.io-index" 112 | checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" 113 | dependencies = [ 114 | "addr2line", 115 | "cfg-if", 116 | "libc", 117 | "miniz_oxide", 118 | "object", 119 | "rustc-demangle", 120 | "windows-targets 0.52.6", 121 | ] 122 | 123 | [[package]] 124 | name = "base64" 125 | version = "0.22.1" 126 | source = "registry+https://github.com/rust-lang/crates.io-index" 127 | checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" 128 | 129 | [[package]] 130 | name = "bindgen" 131 | version = "0.69.5" 132 | source = "registry+https://github.com/rust-lang/crates.io-index" 133 | checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" 134 | dependencies = [ 135 | "bitflags", 136 | "cexpr", 137 | "clang-sys", 138 | "itertools", 139 | "lazy_static", 140 | "lazycell", 141 | "log", 142 | "prettyplease", 143 | "proc-macro2", 144 | "quote", 145 | "regex", 146 | "rustc-hash", 147 | "shlex", 148 | "syn", 149 | "which", 150 | ] 151 | 152 | [[package]] 153 | name = "bitflags" 154 | version = "2.9.1" 155 | source = "registry+https://github.com/rust-lang/crates.io-index" 156 | checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" 157 | 158 | [[package]] 159 | name = "bytes" 160 | version = "1.10.1" 161 | source = "registry+https://github.com/rust-lang/crates.io-index" 162 | checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" 163 | 164 | [[package]] 165 | name = "cc" 166 | version = "1.2.31" 167 | source = "registry+https://github.com/rust-lang/crates.io-index" 168 | checksum = "c3a42d84bb6b69d3a8b3eaacf0d88f179e1929695e1ad012b6cf64d9caaa5fd2" 169 | dependencies = [ 170 | "jobserver", 171 | "libc", 172 | "shlex", 173 | ] 174 | 175 | [[package]] 176 | name = "cexpr" 177 | version = "0.6.0" 178 | source = "registry+https://github.com/rust-lang/crates.io-index" 179 | checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" 180 | dependencies = [ 181 | "nom", 182 | ] 183 | 184 | [[package]] 185 | name = "cfg-if" 186 | version = "1.0.1" 187 | source = "registry+https://github.com/rust-lang/crates.io-index" 188 | checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" 189 | 190 | [[package]] 191 | name = "clang-sys" 192 | version = "1.8.1" 193 | source = "registry+https://github.com/rust-lang/crates.io-index" 194 | checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" 195 | dependencies = [ 196 | "glob", 197 | "libc", 198 | "libloading", 199 | ] 200 | 201 | [[package]] 202 | name = "cmake" 203 | version = "0.1.54" 204 | source = "registry+https://github.com/rust-lang/crates.io-index" 205 | checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" 206 | dependencies = [ 207 | "cc", 208 | ] 209 | 210 | [[package]] 211 | name = "colorchoice" 212 | version = "1.0.4" 213 | source = "registry+https://github.com/rust-lang/crates.io-index" 214 | checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" 215 | 216 | [[package]] 217 | name = "deranged" 218 | version = "0.4.0" 219 | source = "registry+https://github.com/rust-lang/crates.io-index" 220 | checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" 221 | dependencies = [ 222 | "powerfmt", 223 | ] 224 | 225 | [[package]] 226 | name = "dunce" 227 | version = "1.0.5" 228 | source = "registry+https://github.com/rust-lang/crates.io-index" 229 | checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" 230 | 231 | [[package]] 232 | name = "either" 233 | version = "1.15.0" 234 | source = "registry+https://github.com/rust-lang/crates.io-index" 235 | checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" 236 | 237 | [[package]] 238 | name = "env_filter" 239 | version = "0.1.3" 240 | source = "registry+https://github.com/rust-lang/crates.io-index" 241 | checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" 242 | dependencies = [ 243 | "log", 244 | "regex", 245 | ] 246 | 247 | [[package]] 248 | name = "env_logger" 249 | version = "0.11.8" 250 | source = "registry+https://github.com/rust-lang/crates.io-index" 251 | checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" 252 | dependencies = [ 253 | "anstream", 254 | "anstyle", 255 | "env_filter", 256 | "jiff", 257 | "log", 258 | ] 259 | 260 | [[package]] 261 | name = "equivalent" 262 | version = "1.0.2" 263 | source = "registry+https://github.com/rust-lang/crates.io-index" 264 | checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" 265 | 266 | [[package]] 267 | name = "errno" 268 | version = "0.3.13" 269 | source = "registry+https://github.com/rust-lang/crates.io-index" 270 | checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" 271 | dependencies = [ 272 | "libc", 273 | "windows-sys 0.60.2", 274 | ] 275 | 276 | [[package]] 277 | name = "fs_extra" 278 | version = "1.3.0" 279 | source = "registry+https://github.com/rust-lang/crates.io-index" 280 | checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" 281 | 282 | [[package]] 283 | name = "getrandom" 284 | version = "0.2.16" 285 | source = "registry+https://github.com/rust-lang/crates.io-index" 286 | checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" 287 | dependencies = [ 288 | "cfg-if", 289 | "libc", 290 | "wasi 0.11.1+wasi-snapshot-preview1", 291 | ] 292 | 293 | [[package]] 294 | name = "getrandom" 295 | version = "0.3.3" 296 | source = "registry+https://github.com/rust-lang/crates.io-index" 297 | checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" 298 | dependencies = [ 299 | "cfg-if", 300 | "libc", 301 | "r-efi", 302 | "wasi 0.14.2+wasi-0.2.4", 303 | ] 304 | 305 | [[package]] 306 | name = "gimli" 307 | version = "0.31.1" 308 | source = "registry+https://github.com/rust-lang/crates.io-index" 309 | checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" 310 | 311 | [[package]] 312 | name = "glob" 313 | version = "0.3.2" 314 | source = "registry+https://github.com/rust-lang/crates.io-index" 315 | checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" 316 | 317 | [[package]] 318 | name = "hashbrown" 319 | version = "0.15.4" 320 | source = "registry+https://github.com/rust-lang/crates.io-index" 321 | checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" 322 | 323 | [[package]] 324 | name = "home" 325 | version = "0.5.11" 326 | source = "registry+https://github.com/rust-lang/crates.io-index" 327 | checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" 328 | dependencies = [ 329 | "windows-sys 0.59.0", 330 | ] 331 | 332 | [[package]] 333 | name = "idevice" 334 | version = "0.1.37" 335 | dependencies = [ 336 | "base64", 337 | "env_logger", 338 | "log", 339 | "plist", 340 | "rustls", 341 | "serde", 342 | "thiserror", 343 | "tokio", 344 | "tokio-rustls", 345 | ] 346 | 347 | [[package]] 348 | name = "indexmap" 349 | version = "2.10.0" 350 | source = "registry+https://github.com/rust-lang/crates.io-index" 351 | checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" 352 | dependencies = [ 353 | "equivalent", 354 | "hashbrown", 355 | ] 356 | 357 | [[package]] 358 | name = "io-uring" 359 | version = "0.7.9" 360 | source = "registry+https://github.com/rust-lang/crates.io-index" 361 | checksum = "d93587f37623a1a17d94ef2bc9ada592f5465fe7732084ab7beefabe5c77c0c4" 362 | dependencies = [ 363 | "bitflags", 364 | "cfg-if", 365 | "libc", 366 | ] 367 | 368 | [[package]] 369 | name = "is_terminal_polyfill" 370 | version = "1.70.1" 371 | source = "registry+https://github.com/rust-lang/crates.io-index" 372 | checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" 373 | 374 | [[package]] 375 | name = "itertools" 376 | version = "0.12.1" 377 | source = "registry+https://github.com/rust-lang/crates.io-index" 378 | checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" 379 | dependencies = [ 380 | "either", 381 | ] 382 | 383 | [[package]] 384 | name = "itoa" 385 | version = "1.0.15" 386 | source = "registry+https://github.com/rust-lang/crates.io-index" 387 | checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" 388 | 389 | [[package]] 390 | name = "jiff" 391 | version = "0.2.15" 392 | source = "registry+https://github.com/rust-lang/crates.io-index" 393 | checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49" 394 | dependencies = [ 395 | "jiff-static", 396 | "log", 397 | "portable-atomic", 398 | "portable-atomic-util", 399 | "serde", 400 | ] 401 | 402 | [[package]] 403 | name = "jiff-static" 404 | version = "0.2.15" 405 | source = "registry+https://github.com/rust-lang/crates.io-index" 406 | checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4" 407 | dependencies = [ 408 | "proc-macro2", 409 | "quote", 410 | "syn", 411 | ] 412 | 413 | [[package]] 414 | name = "jobserver" 415 | version = "0.1.33" 416 | source = "registry+https://github.com/rust-lang/crates.io-index" 417 | checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" 418 | dependencies = [ 419 | "getrandom 0.3.3", 420 | "libc", 421 | ] 422 | 423 | [[package]] 424 | name = "lazy_static" 425 | version = "1.5.0" 426 | source = "registry+https://github.com/rust-lang/crates.io-index" 427 | checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" 428 | 429 | [[package]] 430 | name = "lazycell" 431 | version = "1.3.0" 432 | source = "registry+https://github.com/rust-lang/crates.io-index" 433 | checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" 434 | 435 | [[package]] 436 | name = "libc" 437 | version = "0.2.174" 438 | source = "registry+https://github.com/rust-lang/crates.io-index" 439 | checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" 440 | 441 | [[package]] 442 | name = "libloading" 443 | version = "0.8.8" 444 | source = "registry+https://github.com/rust-lang/crates.io-index" 445 | checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" 446 | dependencies = [ 447 | "cfg-if", 448 | "windows-targets 0.53.3", 449 | ] 450 | 451 | [[package]] 452 | name = "lightning-router-relay" 453 | version = "0.1.0" 454 | dependencies = [ 455 | "env_logger", 456 | "idevice", 457 | "tokio", 458 | ] 459 | 460 | [[package]] 461 | name = "linux-raw-sys" 462 | version = "0.4.15" 463 | source = "registry+https://github.com/rust-lang/crates.io-index" 464 | checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" 465 | 466 | [[package]] 467 | name = "lock_api" 468 | version = "0.4.13" 469 | source = "registry+https://github.com/rust-lang/crates.io-index" 470 | checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" 471 | dependencies = [ 472 | "autocfg", 473 | "scopeguard", 474 | ] 475 | 476 | [[package]] 477 | name = "log" 478 | version = "0.4.27" 479 | source = "registry+https://github.com/rust-lang/crates.io-index" 480 | checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" 481 | 482 | [[package]] 483 | name = "memchr" 484 | version = "2.7.5" 485 | source = "registry+https://github.com/rust-lang/crates.io-index" 486 | checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" 487 | 488 | [[package]] 489 | name = "minimal-lexical" 490 | version = "0.2.1" 491 | source = "registry+https://github.com/rust-lang/crates.io-index" 492 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" 493 | 494 | [[package]] 495 | name = "miniz_oxide" 496 | version = "0.8.9" 497 | source = "registry+https://github.com/rust-lang/crates.io-index" 498 | checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" 499 | dependencies = [ 500 | "adler2", 501 | ] 502 | 503 | [[package]] 504 | name = "mio" 505 | version = "1.0.4" 506 | source = "registry+https://github.com/rust-lang/crates.io-index" 507 | checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" 508 | dependencies = [ 509 | "libc", 510 | "wasi 0.11.1+wasi-snapshot-preview1", 511 | "windows-sys 0.59.0", 512 | ] 513 | 514 | [[package]] 515 | name = "nom" 516 | version = "7.1.3" 517 | source = "registry+https://github.com/rust-lang/crates.io-index" 518 | checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" 519 | dependencies = [ 520 | "memchr", 521 | "minimal-lexical", 522 | ] 523 | 524 | [[package]] 525 | name = "num-conv" 526 | version = "0.1.0" 527 | source = "registry+https://github.com/rust-lang/crates.io-index" 528 | checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" 529 | 530 | [[package]] 531 | name = "object" 532 | version = "0.36.7" 533 | source = "registry+https://github.com/rust-lang/crates.io-index" 534 | checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" 535 | dependencies = [ 536 | "memchr", 537 | ] 538 | 539 | [[package]] 540 | name = "once_cell" 541 | version = "1.21.3" 542 | source = "registry+https://github.com/rust-lang/crates.io-index" 543 | checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" 544 | 545 | [[package]] 546 | name = "once_cell_polyfill" 547 | version = "1.70.1" 548 | source = "registry+https://github.com/rust-lang/crates.io-index" 549 | checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" 550 | 551 | [[package]] 552 | name = "parking_lot" 553 | version = "0.12.4" 554 | source = "registry+https://github.com/rust-lang/crates.io-index" 555 | checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" 556 | dependencies = [ 557 | "lock_api", 558 | "parking_lot_core", 559 | ] 560 | 561 | [[package]] 562 | name = "parking_lot_core" 563 | version = "0.9.11" 564 | source = "registry+https://github.com/rust-lang/crates.io-index" 565 | checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" 566 | dependencies = [ 567 | "cfg-if", 568 | "libc", 569 | "redox_syscall", 570 | "smallvec", 571 | "windows-targets 0.52.6", 572 | ] 573 | 574 | [[package]] 575 | name = "pin-project-lite" 576 | version = "0.2.16" 577 | source = "registry+https://github.com/rust-lang/crates.io-index" 578 | checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" 579 | 580 | [[package]] 581 | name = "plist" 582 | version = "1.7.4" 583 | source = "registry+https://github.com/rust-lang/crates.io-index" 584 | checksum = "3af6b589e163c5a788fab00ce0c0366f6efbb9959c2f9874b224936af7fce7e1" 585 | dependencies = [ 586 | "base64", 587 | "indexmap", 588 | "quick-xml", 589 | "serde", 590 | "time", 591 | ] 592 | 593 | [[package]] 594 | name = "portable-atomic" 595 | version = "1.11.1" 596 | source = "registry+https://github.com/rust-lang/crates.io-index" 597 | checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" 598 | 599 | [[package]] 600 | name = "portable-atomic-util" 601 | version = "0.2.4" 602 | source = "registry+https://github.com/rust-lang/crates.io-index" 603 | checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" 604 | dependencies = [ 605 | "portable-atomic", 606 | ] 607 | 608 | [[package]] 609 | name = "powerfmt" 610 | version = "0.2.0" 611 | source = "registry+https://github.com/rust-lang/crates.io-index" 612 | checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" 613 | 614 | [[package]] 615 | name = "prettyplease" 616 | version = "0.2.36" 617 | source = "registry+https://github.com/rust-lang/crates.io-index" 618 | checksum = "ff24dfcda44452b9816fff4cd4227e1bb73ff5a2f1bc1105aa92fb8565ce44d2" 619 | dependencies = [ 620 | "proc-macro2", 621 | "syn", 622 | ] 623 | 624 | [[package]] 625 | name = "proc-macro2" 626 | version = "1.0.95" 627 | source = "registry+https://github.com/rust-lang/crates.io-index" 628 | checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" 629 | dependencies = [ 630 | "unicode-ident", 631 | ] 632 | 633 | [[package]] 634 | name = "quick-xml" 635 | version = "0.38.1" 636 | source = "registry+https://github.com/rust-lang/crates.io-index" 637 | checksum = "9845d9dccf565065824e69f9f235fafba1587031eda353c1f1561cd6a6be78f4" 638 | dependencies = [ 639 | "memchr", 640 | ] 641 | 642 | [[package]] 643 | name = "quote" 644 | version = "1.0.40" 645 | source = "registry+https://github.com/rust-lang/crates.io-index" 646 | checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" 647 | dependencies = [ 648 | "proc-macro2", 649 | ] 650 | 651 | [[package]] 652 | name = "r-efi" 653 | version = "5.3.0" 654 | source = "registry+https://github.com/rust-lang/crates.io-index" 655 | checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" 656 | 657 | [[package]] 658 | name = "redox_syscall" 659 | version = "0.5.17" 660 | source = "registry+https://github.com/rust-lang/crates.io-index" 661 | checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" 662 | dependencies = [ 663 | "bitflags", 664 | ] 665 | 666 | [[package]] 667 | name = "regex" 668 | version = "1.11.1" 669 | source = "registry+https://github.com/rust-lang/crates.io-index" 670 | checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" 671 | dependencies = [ 672 | "aho-corasick", 673 | "memchr", 674 | "regex-automata", 675 | "regex-syntax", 676 | ] 677 | 678 | [[package]] 679 | name = "regex-automata" 680 | version = "0.4.9" 681 | source = "registry+https://github.com/rust-lang/crates.io-index" 682 | checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" 683 | dependencies = [ 684 | "aho-corasick", 685 | "memchr", 686 | "regex-syntax", 687 | ] 688 | 689 | [[package]] 690 | name = "regex-syntax" 691 | version = "0.8.5" 692 | source = "registry+https://github.com/rust-lang/crates.io-index" 693 | checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" 694 | 695 | [[package]] 696 | name = "ring" 697 | version = "0.17.14" 698 | source = "registry+https://github.com/rust-lang/crates.io-index" 699 | checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" 700 | dependencies = [ 701 | "cc", 702 | "cfg-if", 703 | "getrandom 0.2.16", 704 | "libc", 705 | "untrusted", 706 | "windows-sys 0.52.0", 707 | ] 708 | 709 | [[package]] 710 | name = "rustc-demangle" 711 | version = "0.1.26" 712 | source = "registry+https://github.com/rust-lang/crates.io-index" 713 | checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" 714 | 715 | [[package]] 716 | name = "rustc-hash" 717 | version = "1.1.0" 718 | source = "registry+https://github.com/rust-lang/crates.io-index" 719 | checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" 720 | 721 | [[package]] 722 | name = "rustix" 723 | version = "0.38.44" 724 | source = "registry+https://github.com/rust-lang/crates.io-index" 725 | checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" 726 | dependencies = [ 727 | "bitflags", 728 | "errno", 729 | "libc", 730 | "linux-raw-sys", 731 | "windows-sys 0.59.0", 732 | ] 733 | 734 | [[package]] 735 | name = "rustls" 736 | version = "0.23.31" 737 | source = "registry+https://github.com/rust-lang/crates.io-index" 738 | checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc" 739 | dependencies = [ 740 | "aws-lc-rs", 741 | "once_cell", 742 | "rustls-pki-types", 743 | "rustls-webpki", 744 | "subtle", 745 | "zeroize", 746 | ] 747 | 748 | [[package]] 749 | name = "rustls-pki-types" 750 | version = "1.12.0" 751 | source = "registry+https://github.com/rust-lang/crates.io-index" 752 | checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" 753 | dependencies = [ 754 | "zeroize", 755 | ] 756 | 757 | [[package]] 758 | name = "rustls-webpki" 759 | version = "0.103.4" 760 | source = "registry+https://github.com/rust-lang/crates.io-index" 761 | checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc" 762 | dependencies = [ 763 | "aws-lc-rs", 764 | "ring", 765 | "rustls-pki-types", 766 | "untrusted", 767 | ] 768 | 769 | [[package]] 770 | name = "scopeguard" 771 | version = "1.2.0" 772 | source = "registry+https://github.com/rust-lang/crates.io-index" 773 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 774 | 775 | [[package]] 776 | name = "serde" 777 | version = "1.0.219" 778 | source = "registry+https://github.com/rust-lang/crates.io-index" 779 | checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" 780 | dependencies = [ 781 | "serde_derive", 782 | ] 783 | 784 | [[package]] 785 | name = "serde_derive" 786 | version = "1.0.219" 787 | source = "registry+https://github.com/rust-lang/crates.io-index" 788 | checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" 789 | dependencies = [ 790 | "proc-macro2", 791 | "quote", 792 | "syn", 793 | ] 794 | 795 | [[package]] 796 | name = "shlex" 797 | version = "1.3.0" 798 | source = "registry+https://github.com/rust-lang/crates.io-index" 799 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 800 | 801 | [[package]] 802 | name = "signal-hook-registry" 803 | version = "1.4.6" 804 | source = "registry+https://github.com/rust-lang/crates.io-index" 805 | checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" 806 | dependencies = [ 807 | "libc", 808 | ] 809 | 810 | [[package]] 811 | name = "slab" 812 | version = "0.4.10" 813 | source = "registry+https://github.com/rust-lang/crates.io-index" 814 | checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" 815 | 816 | [[package]] 817 | name = "smallvec" 818 | version = "1.15.1" 819 | source = "registry+https://github.com/rust-lang/crates.io-index" 820 | checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" 821 | 822 | [[package]] 823 | name = "socket2" 824 | version = "0.6.0" 825 | source = "registry+https://github.com/rust-lang/crates.io-index" 826 | checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" 827 | dependencies = [ 828 | "libc", 829 | "windows-sys 0.59.0", 830 | ] 831 | 832 | [[package]] 833 | name = "subtle" 834 | version = "2.6.1" 835 | source = "registry+https://github.com/rust-lang/crates.io-index" 836 | checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" 837 | 838 | [[package]] 839 | name = "syn" 840 | version = "2.0.104" 841 | source = "registry+https://github.com/rust-lang/crates.io-index" 842 | checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" 843 | dependencies = [ 844 | "proc-macro2", 845 | "quote", 846 | "unicode-ident", 847 | ] 848 | 849 | [[package]] 850 | name = "thiserror" 851 | version = "2.0.12" 852 | source = "registry+https://github.com/rust-lang/crates.io-index" 853 | checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" 854 | dependencies = [ 855 | "thiserror-impl", 856 | ] 857 | 858 | [[package]] 859 | name = "thiserror-impl" 860 | version = "2.0.12" 861 | source = "registry+https://github.com/rust-lang/crates.io-index" 862 | checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" 863 | dependencies = [ 864 | "proc-macro2", 865 | "quote", 866 | "syn", 867 | ] 868 | 869 | [[package]] 870 | name = "time" 871 | version = "0.3.41" 872 | source = "registry+https://github.com/rust-lang/crates.io-index" 873 | checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" 874 | dependencies = [ 875 | "deranged", 876 | "itoa", 877 | "num-conv", 878 | "powerfmt", 879 | "serde", 880 | "time-core", 881 | "time-macros", 882 | ] 883 | 884 | [[package]] 885 | name = "time-core" 886 | version = "0.1.4" 887 | source = "registry+https://github.com/rust-lang/crates.io-index" 888 | checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" 889 | 890 | [[package]] 891 | name = "time-macros" 892 | version = "0.2.22" 893 | source = "registry+https://github.com/rust-lang/crates.io-index" 894 | checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" 895 | dependencies = [ 896 | "num-conv", 897 | "time-core", 898 | ] 899 | 900 | [[package]] 901 | name = "tokio" 902 | version = "1.47.1" 903 | source = "registry+https://github.com/rust-lang/crates.io-index" 904 | checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" 905 | dependencies = [ 906 | "backtrace", 907 | "bytes", 908 | "io-uring", 909 | "libc", 910 | "mio", 911 | "parking_lot", 912 | "pin-project-lite", 913 | "signal-hook-registry", 914 | "slab", 915 | "socket2", 916 | "tokio-macros", 917 | "windows-sys 0.59.0", 918 | ] 919 | 920 | [[package]] 921 | name = "tokio-macros" 922 | version = "2.5.0" 923 | source = "registry+https://github.com/rust-lang/crates.io-index" 924 | checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" 925 | dependencies = [ 926 | "proc-macro2", 927 | "quote", 928 | "syn", 929 | ] 930 | 931 | [[package]] 932 | name = "tokio-rustls" 933 | version = "0.26.2" 934 | source = "registry+https://github.com/rust-lang/crates.io-index" 935 | checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" 936 | dependencies = [ 937 | "rustls", 938 | "tokio", 939 | ] 940 | 941 | [[package]] 942 | name = "unicode-ident" 943 | version = "1.0.18" 944 | source = "registry+https://github.com/rust-lang/crates.io-index" 945 | checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" 946 | 947 | [[package]] 948 | name = "untrusted" 949 | version = "0.9.0" 950 | source = "registry+https://github.com/rust-lang/crates.io-index" 951 | checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" 952 | 953 | [[package]] 954 | name = "utf8parse" 955 | version = "0.2.2" 956 | source = "registry+https://github.com/rust-lang/crates.io-index" 957 | checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" 958 | 959 | [[package]] 960 | name = "wasi" 961 | version = "0.11.1+wasi-snapshot-preview1" 962 | source = "registry+https://github.com/rust-lang/crates.io-index" 963 | checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" 964 | 965 | [[package]] 966 | name = "wasi" 967 | version = "0.14.2+wasi-0.2.4" 968 | source = "registry+https://github.com/rust-lang/crates.io-index" 969 | checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" 970 | dependencies = [ 971 | "wit-bindgen-rt", 972 | ] 973 | 974 | [[package]] 975 | name = "which" 976 | version = "4.4.2" 977 | source = "registry+https://github.com/rust-lang/crates.io-index" 978 | checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" 979 | dependencies = [ 980 | "either", 981 | "home", 982 | "once_cell", 983 | "rustix", 984 | ] 985 | 986 | [[package]] 987 | name = "windows-link" 988 | version = "0.1.3" 989 | source = "registry+https://github.com/rust-lang/crates.io-index" 990 | checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" 991 | 992 | [[package]] 993 | name = "windows-sys" 994 | version = "0.52.0" 995 | source = "registry+https://github.com/rust-lang/crates.io-index" 996 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 997 | dependencies = [ 998 | "windows-targets 0.52.6", 999 | ] 1000 | 1001 | [[package]] 1002 | name = "windows-sys" 1003 | version = "0.59.0" 1004 | source = "registry+https://github.com/rust-lang/crates.io-index" 1005 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 1006 | dependencies = [ 1007 | "windows-targets 0.52.6", 1008 | ] 1009 | 1010 | [[package]] 1011 | name = "windows-sys" 1012 | version = "0.60.2" 1013 | source = "registry+https://github.com/rust-lang/crates.io-index" 1014 | checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" 1015 | dependencies = [ 1016 | "windows-targets 0.53.3", 1017 | ] 1018 | 1019 | [[package]] 1020 | name = "windows-targets" 1021 | version = "0.52.6" 1022 | source = "registry+https://github.com/rust-lang/crates.io-index" 1023 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 1024 | dependencies = [ 1025 | "windows_aarch64_gnullvm 0.52.6", 1026 | "windows_aarch64_msvc 0.52.6", 1027 | "windows_i686_gnu 0.52.6", 1028 | "windows_i686_gnullvm 0.52.6", 1029 | "windows_i686_msvc 0.52.6", 1030 | "windows_x86_64_gnu 0.52.6", 1031 | "windows_x86_64_gnullvm 0.52.6", 1032 | "windows_x86_64_msvc 0.52.6", 1033 | ] 1034 | 1035 | [[package]] 1036 | name = "windows-targets" 1037 | version = "0.53.3" 1038 | source = "registry+https://github.com/rust-lang/crates.io-index" 1039 | checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" 1040 | dependencies = [ 1041 | "windows-link", 1042 | "windows_aarch64_gnullvm 0.53.0", 1043 | "windows_aarch64_msvc 0.53.0", 1044 | "windows_i686_gnu 0.53.0", 1045 | "windows_i686_gnullvm 0.53.0", 1046 | "windows_i686_msvc 0.53.0", 1047 | "windows_x86_64_gnu 0.53.0", 1048 | "windows_x86_64_gnullvm 0.53.0", 1049 | "windows_x86_64_msvc 0.53.0", 1050 | ] 1051 | 1052 | [[package]] 1053 | name = "windows_aarch64_gnullvm" 1054 | version = "0.52.6" 1055 | source = "registry+https://github.com/rust-lang/crates.io-index" 1056 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 1057 | 1058 | [[package]] 1059 | name = "windows_aarch64_gnullvm" 1060 | version = "0.53.0" 1061 | source = "registry+https://github.com/rust-lang/crates.io-index" 1062 | checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" 1063 | 1064 | [[package]] 1065 | name = "windows_aarch64_msvc" 1066 | version = "0.52.6" 1067 | source = "registry+https://github.com/rust-lang/crates.io-index" 1068 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 1069 | 1070 | [[package]] 1071 | name = "windows_aarch64_msvc" 1072 | version = "0.53.0" 1073 | source = "registry+https://github.com/rust-lang/crates.io-index" 1074 | checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" 1075 | 1076 | [[package]] 1077 | name = "windows_i686_gnu" 1078 | version = "0.52.6" 1079 | source = "registry+https://github.com/rust-lang/crates.io-index" 1080 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 1081 | 1082 | [[package]] 1083 | name = "windows_i686_gnu" 1084 | version = "0.53.0" 1085 | source = "registry+https://github.com/rust-lang/crates.io-index" 1086 | checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" 1087 | 1088 | [[package]] 1089 | name = "windows_i686_gnullvm" 1090 | version = "0.52.6" 1091 | source = "registry+https://github.com/rust-lang/crates.io-index" 1092 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 1093 | 1094 | [[package]] 1095 | name = "windows_i686_gnullvm" 1096 | version = "0.53.0" 1097 | source = "registry+https://github.com/rust-lang/crates.io-index" 1098 | checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" 1099 | 1100 | [[package]] 1101 | name = "windows_i686_msvc" 1102 | version = "0.52.6" 1103 | source = "registry+https://github.com/rust-lang/crates.io-index" 1104 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 1105 | 1106 | [[package]] 1107 | name = "windows_i686_msvc" 1108 | version = "0.53.0" 1109 | source = "registry+https://github.com/rust-lang/crates.io-index" 1110 | checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" 1111 | 1112 | [[package]] 1113 | name = "windows_x86_64_gnu" 1114 | version = "0.52.6" 1115 | source = "registry+https://github.com/rust-lang/crates.io-index" 1116 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 1117 | 1118 | [[package]] 1119 | name = "windows_x86_64_gnu" 1120 | version = "0.53.0" 1121 | source = "registry+https://github.com/rust-lang/crates.io-index" 1122 | checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" 1123 | 1124 | [[package]] 1125 | name = "windows_x86_64_gnullvm" 1126 | version = "0.52.6" 1127 | source = "registry+https://github.com/rust-lang/crates.io-index" 1128 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 1129 | 1130 | [[package]] 1131 | name = "windows_x86_64_gnullvm" 1132 | version = "0.53.0" 1133 | source = "registry+https://github.com/rust-lang/crates.io-index" 1134 | checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" 1135 | 1136 | [[package]] 1137 | name = "windows_x86_64_msvc" 1138 | version = "0.52.6" 1139 | source = "registry+https://github.com/rust-lang/crates.io-index" 1140 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 1141 | 1142 | [[package]] 1143 | name = "windows_x86_64_msvc" 1144 | version = "0.53.0" 1145 | source = "registry+https://github.com/rust-lang/crates.io-index" 1146 | checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" 1147 | 1148 | [[package]] 1149 | name = "wit-bindgen-rt" 1150 | version = "0.39.0" 1151 | source = "registry+https://github.com/rust-lang/crates.io-index" 1152 | checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" 1153 | dependencies = [ 1154 | "bitflags", 1155 | ] 1156 | 1157 | [[package]] 1158 | name = "zeroize" 1159 | version = "1.8.1" 1160 | source = "registry+https://github.com/rust-lang/crates.io-index" 1161 | checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" 1162 | -------------------------------------------------------------------------------- /relay/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "lightning-router-relay" 3 | version = "0.1.0" 4 | edition = "2024" 5 | 6 | [dependencies] 7 | tokio = { version = "1.47", features = ["full"] } 8 | idevice = { path = "../../idevice/idevice", features = ["usbmuxd"] } 9 | env_logger = { version = "0.11" } 10 | -------------------------------------------------------------------------------- /relay/src/main.rs: -------------------------------------------------------------------------------- 1 | // Jackson Coxson 2 | 3 | use std::{net::SocketAddr, str::FromStr}; 4 | 5 | use idevice::usbmuxd::{Connection, UsbmuxdAddr, UsbmuxdDevice}; 6 | use tokio::{ 7 | io::{AsyncReadExt, AsyncWriteExt}, 8 | net::UdpSocket, 9 | }; 10 | 11 | #[tokio::main] 12 | pub async fn main() { 13 | env_logger::init(); 14 | 15 | let addr = UsbmuxdAddr::default(); 16 | let mut conn = addr 17 | .connect(69) 18 | .await 19 | .expect("Failed to connect to usbmuxd"); 20 | let devices = conn.get_devices().await.expect("Failed to get devices"); 21 | let devices: Vec = devices 22 | .into_iter() 23 | .filter(|x| x.connection_type == Connection::Usb) 24 | .collect(); 25 | let dev = devices.first().expect("No devices connected via USB"); 26 | println!("Using {} to connect to", dev.udid); 27 | let conn = conn 28 | .connect_to_device(dev.device_id, 51820, "lightning-router") 29 | .await 30 | .expect("Failed to connect to LightningRouter on device. Is the app running?"); 31 | println!("Connected!"); 32 | let mut conn = conn.get_socket().unwrap(); 33 | 34 | let input_socket = UdpSocket::bind("0.0.0.0:3400") 35 | .await 36 | .expect("Failed to bind to UDP port 3400"); 37 | 38 | let mut buf0 = [0u8; u16::MAX as usize]; 39 | let mut conn_buf = [0u8; 2]; 40 | let mut input_address = SocketAddr::from_str("127.0.0.1:1").unwrap(); 41 | loop { 42 | tokio::select! { 43 | res = input_socket.recv_from(&mut buf0) => { 44 | match res { 45 | Ok((size, addr)) => { 46 | input_address = addr; 47 | let buf0 = &buf0[..size]; 48 | let size = buf0.len() as u16; 49 | if let Err(e) = conn.write_all(&size.to_le_bytes()).await { 50 | eprintln!("Failed to send to device: {e:?}"); 51 | return; 52 | } 53 | if let Err(e) = conn.write_all(buf0).await { 54 | eprintln!("Failed to send to device: {e:?}"); 55 | return; 56 | } 57 | }, 58 | Err(e) => { 59 | eprintln!("Failed to read from input socket: {e:?}"); 60 | return; 61 | }, 62 | } 63 | } 64 | res = conn.read_exact(&mut conn_buf) => { 65 | match res { 66 | Ok(_) => { 67 | let size = u16::from_le_bytes(conn_buf); 68 | let mut buf1 = vec![0u8; size as usize]; 69 | conn.read_exact(&mut buf1).await.expect("Failed to read body"); 70 | if let Err(e) = input_socket.send_to(&buf1, input_address).await { 71 | eprintln!("Failed to send to input socket: {e:?}"); 72 | return; 73 | } 74 | } 75 | Err(e) => { 76 | eprintln!("Failed to read from device: {e:?}"); 77 | return; 78 | } 79 | } 80 | } 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | // Jackson Coxson 2 | 3 | use once_cell::sync::Lazy; 4 | use std::ffi::{CStr, c_char}; 5 | use tokio::{ 6 | io::{AsyncReadExt, AsyncWriteExt}, 7 | net::{TcpListener, UdpSocket}, 8 | runtime::{self, Runtime}, 9 | sync::oneshot::{self, error::TryRecvError}, 10 | }; 11 | 12 | mod tcp; 13 | 14 | static RUNTIME: Lazy = Lazy::new(|| { 15 | runtime::Builder::new_multi_thread() 16 | .enable_io() 17 | .enable_time() 18 | .build() 19 | .unwrap() 20 | }); 21 | 22 | pub struct ThreadKiller(oneshot::Sender<()>); 23 | 24 | /// # Safety 25 | /// Don't be dumb 26 | #[unsafe(no_mangle)] 27 | pub unsafe extern "C" fn start_simple_udp_proxy( 28 | address: *const c_char, 29 | port: u16, 30 | thread_killer: *mut *mut ThreadKiller, 31 | ) -> bool { 32 | if address.is_null() { 33 | return false; 34 | } 35 | let address = match unsafe { CStr::from_ptr(address) }.to_str() { 36 | Ok(a) => a, 37 | Err(_) => { 38 | return false; 39 | } 40 | } 41 | .to_string(); 42 | let (killer, mut killed) = oneshot::channel::<()>(); 43 | let input_listener = match std::net::TcpListener::bind("0.0.0.0:51820") { 44 | Ok(l) => l, 45 | Err(e) => { 46 | eprintln!("no input bind: {e:?}"); 47 | return false; 48 | } 49 | }; 50 | input_listener.set_nonblocking(true).unwrap(); 51 | 52 | RUNTIME.spawn(async move { 53 | let input_listener = TcpListener::from_std(input_listener).unwrap(); 54 | 55 | while let Err(TryRecvError::Empty) = killed.try_recv() { 56 | tokio::select! { 57 | Ok((mut input_socket, _addr)) = input_listener.accept() => { 58 | input_socket.set_nodelay(true).unwrap(); 59 | let target_address = format!("{address}:{port}"); 60 | RUNTIME.spawn(async move { 61 | let target_socket = match UdpSocket::bind("0.0.0.0:0").await { 62 | Ok(t) => t, 63 | Err(e) => { 64 | eprintln!("Failed to bind target socket: {e:?}"); 65 | return; 66 | } 67 | }; 68 | 69 | if let Err(e) = target_socket.connect(&target_address).await { 70 | eprintln!("Failed to connect to target socket {target_address}: {e:?}"); 71 | return; 72 | } 73 | 74 | let mut buf0 = [0u8; 2]; 75 | let mut buf1 = [0u8; u16::MAX as usize]; 76 | loop { 77 | tokio::select! { 78 | res = input_socket.read_exact(&mut buf0) => { 79 | match res { 80 | Ok(_) => { 81 | let size = u16::from_le_bytes(buf0); 82 | let mut buf0 = vec![0u8; size as usize]; 83 | if let Err(e) = input_socket.read_exact(&mut buf0).await { 84 | eprintln!("Failed to read {size} bytes from input socket: {e:?}"); 85 | return; 86 | } 87 | if size == 0 { 88 | println!("Input connection closed"); 89 | return; 90 | } 91 | if let Err(e) = target_socket.send(&buf0).await { 92 | eprintln!("Failed to send to target socket: {e:?}"); 93 | return; 94 | } 95 | }, 96 | Err(e) => { 97 | eprintln!("Failed to read from input socket: {e:?}"); 98 | return; 99 | }, 100 | } 101 | } 102 | res = target_socket.recv(&mut buf1) => { 103 | match res { 104 | Ok(size) => { 105 | if size == 0 { 106 | println!("Target connection closed"); 107 | return; 108 | } 109 | let buf1 = &buf1[..size]; 110 | let size = buf1.len() as u16; 111 | 112 | if let Err(e) = input_socket.write_all(&size.to_le_bytes()).await { 113 | eprintln!("Failed to send to input socket: {e:?}"); 114 | return; 115 | } 116 | if let Err(e) = input_socket.write_all(buf1).await { 117 | eprintln!("Failed to send to input socket: {e:?}"); 118 | return; 119 | } 120 | }, 121 | Err(e) => { 122 | eprintln!("Failed to read from target socket: {e:?}"); 123 | return; 124 | }, 125 | } 126 | } 127 | } 128 | } 129 | }); 130 | } 131 | _ = tokio::time::sleep(std::time::Duration::from_secs(5)) => { 132 | // re-run the loop to test for thread killer 133 | } 134 | } 135 | } 136 | }); 137 | 138 | unsafe { 139 | *thread_killer = Box::into_raw(Box::new(ThreadKiller(killer))); 140 | } 141 | true 142 | } 143 | 144 | /// # Safety 145 | /// Don't be dumb 146 | #[unsafe(no_mangle)] 147 | pub unsafe extern "C" fn thread_killer_kill(killer: *mut ThreadKiller) { 148 | if killer.is_null() { 149 | return; 150 | } 151 | 152 | let killer = unsafe { Box::from_raw(killer) }; 153 | (*killer).0.send(()).ok(); 154 | } 155 | -------------------------------------------------------------------------------- /src/tcp/mod.rs: -------------------------------------------------------------------------------- 1 | // Custom TCP stack copied from idevice 2 | // I really should just make it its own library at this point... 3 | mod packets; 4 | -------------------------------------------------------------------------------- /src/tcp/packets.rs: -------------------------------------------------------------------------------- 1 | // Jackson Coxson 2 | // I couldn't find a lib that parses IP/TCP, so I guess we'll write our own 3 | // 4 | // use std::{ 5 | // io::Read, 6 | // net::{IpAddr, Ipv4Addr, Ipv6Addr}, 7 | // sync::Arc, 8 | // }; 9 | // 10 | // pub enum ProtocolNumber { 11 | // Tcp = 6, 12 | // } 13 | // 14 | // #[derive(Debug)] 15 | // pub struct Ipv4Packet { 16 | // pub version: u8, // always 4 for IPv4 17 | // pub ihl: u8, // len of header / 4 18 | // pub tos: u8, // nobody can agree what this is for 19 | // pub total_length: u16, // length of packet in bytes 20 | // pub identification: u16, // ID from sender to help assemble datagram 21 | // pub flags: u8, // 3 bits; reserved: 0, may fragment: 0/1, last fragment 0 / more fragments 1 22 | // pub fragment_offset: u16, // where in the datagram this belongs 23 | // // If Google can ignore fragments, so can we 24 | // pub ttl: u8, // max amount of time this packet can live 25 | // pub protocol: u8, // protocol number, 6 for TCP 26 | // pub header_checksum: u16, // wrapping add all the u16 in header, then invert all bits 27 | // pub source: Ipv4Addr, 28 | // pub destination: Ipv4Addr, 29 | // pub options: Vec, 30 | // pub payload: Vec, // if smoltcp can ignore options, so can we 31 | // } 32 | // 33 | // impl Ipv4Packet { 34 | // pub fn parse(packet: &[u8]) -> Option { 35 | // if packet.len() < 20 { 36 | // return None; 37 | // } 38 | // 39 | // let version_ihl = packet[0]; 40 | // let version = version_ihl >> 4; 41 | // let ihl = (version_ihl & 0x0F) * 4; // send help I don't understand bitwise ops 42 | // 43 | // if version != 4 || packet.len() < ihl as usize { 44 | // return None; 45 | // } 46 | // 47 | // let tos = packet[1]; 48 | // let total_length = u16::from_be_bytes([packet[2], packet[3]]); 49 | // let identification = u16::from_be_bytes([packet[4], packet[5]]); 50 | // let flags_fragment = u16::from_be_bytes([packet[6], packet[7]]); 51 | // let flags = (flags_fragment >> 13) as u8; 52 | // let fragment_offset = flags_fragment & 0x1FFF; 53 | // let ttl = packet[8]; 54 | // let protocol = packet[9]; 55 | // let header_checksum = u16::from_be_bytes([packet[10], packet[11]]); 56 | // let source = Ipv4Addr::new(packet[12], packet[13], packet[14], packet[15]); 57 | // let destination = Ipv4Addr::new(packet[16], packet[17], packet[18], packet[19]); 58 | // 59 | // let options_end = ihl as usize; 60 | // let options = if options_end > 20 { 61 | // packet[20..options_end].to_vec() 62 | // } else { 63 | // Vec::new() 64 | // }; 65 | // 66 | // let payload = if total_length as usize > options_end { 67 | // packet[options_end..total_length as usize].to_vec() 68 | // } else { 69 | // Vec::new() 70 | // }; 71 | // 72 | // Some(Self { 73 | // version, 74 | // ihl, 75 | // tos, 76 | // total_length, 77 | // identification, 78 | // flags, 79 | // fragment_offset, 80 | // ttl, 81 | // protocol, 82 | // header_checksum, 83 | // source, 84 | // destination, 85 | // options, 86 | // payload, 87 | // }) 88 | // } 89 | // 90 | // /// Asynchronously read an IPv4 packet from a Tokio AsyncRead source. 91 | // pub fn from_reader( 92 | // reader: &mut R, 93 | // log: &Option>>, 94 | // ) -> Result { 95 | // let mut log_packet = Vec::new(); 96 | // 97 | // let mut header = [0u8; 20]; // Minimum IPv4 header size 98 | // reader.read_exact(&mut header).await?; 99 | // if log.is_some() { 100 | // log_packet.extend_from_slice(&header); 101 | // } 102 | // 103 | // let version_ihl = header[0]; 104 | // let version = version_ihl >> 4; 105 | // let ihl = (version_ihl & 0x0F) * 4; 106 | // 107 | // if version != 4 || ihl < 20 { 108 | // return Err(std::io::Error::new( 109 | // std::io::ErrorKind::InvalidData, 110 | // "Invalid IPv4 header", 111 | // )); 112 | // } 113 | // 114 | // let tos = header[1]; 115 | // let total_length = u16::from_be_bytes([header[2], header[3]]); 116 | // let identification = u16::from_be_bytes([header[4], header[5]]); 117 | // let flags_fragment = u16::from_be_bytes([header[6], header[7]]); 118 | // let flags = (flags_fragment >> 13) as u8; 119 | // let fragment_offset = flags_fragment & 0x1FFF; 120 | // let ttl = header[8]; 121 | // let protocol = header[9]; 122 | // let header_checksum = u16::from_be_bytes([header[10], header[11]]); 123 | // let source = Ipv4Addr::new(header[12], header[13], header[14], header[15]); 124 | // let destination = Ipv4Addr::new(header[16], header[17], header[18], header[19]); 125 | // 126 | // // Read options if the header is larger than 20 bytes 127 | // let options_len = ihl as usize - 20; 128 | // let mut options = vec![0u8; options_len]; 129 | // if options_len > 0 { 130 | // reader.read_exact(&mut options).await?; 131 | // if log.is_some() { 132 | // log_packet.extend_from_slice(&options); 133 | // } 134 | // } 135 | // 136 | // // Read the payload 137 | // let payload_len = total_length as usize - ihl as usize; 138 | // let mut payload = vec![0u8; payload_len]; 139 | // reader.read_exact(&mut payload).await?; 140 | // if let Some(log) = log { 141 | // log_packet.extend_from_slice(&payload); 142 | // super::log_packet(log, &log_packet); 143 | // } 144 | // 145 | // Ok(Self { 146 | // version, 147 | // ihl, 148 | // tos, 149 | // total_length, 150 | // identification, 151 | // flags, 152 | // fragment_offset, 153 | // ttl, 154 | // protocol, 155 | // header_checksum, 156 | // source, 157 | // destination, 158 | // options, 159 | // payload, 160 | // }) 161 | // } 162 | // 163 | // pub fn create( 164 | // source: Ipv4Addr, 165 | // destination: Ipv4Addr, 166 | // protocol: ProtocolNumber, 167 | // ttl: u8, 168 | // payload: &[u8], 169 | // ) -> Vec { 170 | // let ihl: u8 = 5; 171 | // let total_length = (ihl as usize * 4 + payload.len()) as u16; 172 | // let identification: u16 = 0; 173 | // let flags_fragment: u16 = 0; 174 | // let header_checksum: u16 = 0; 175 | // 176 | // let mut packet = vec![0; total_length as usize]; 177 | // packet[0] = (4 << 4) | (ihl & 0x0F); 178 | // packet[1] = 0; 179 | // packet[2..4].copy_from_slice(&total_length.to_be_bytes()); 180 | // packet[4..6].copy_from_slice(&identification.to_be_bytes()); 181 | // packet[6..8].copy_from_slice(&flags_fragment.to_be_bytes()); 182 | // packet[8] = ttl; 183 | // packet[9] = protocol as u8; 184 | // packet[10..12].copy_from_slice(&header_checksum.to_be_bytes()); 185 | // packet[12..16].copy_from_slice(&source.octets()); 186 | // packet[16..20].copy_from_slice(&destination.octets()); 187 | // packet[20..].copy_from_slice(payload); 188 | // 189 | // Self::apply_checksum(&mut packet); 190 | // packet 191 | // } 192 | // 193 | // fn apply_checksum(packet: &mut [u8]) { 194 | // packet[10] = 0; 195 | // packet[11] = 0; 196 | // let mut checksum: u16 = 0; 197 | // for i in 0..packet.len() / 2 { 198 | // let word = u16::from_be_bytes([packet[i * 2], packet[(i * 2) + 1]]); 199 | // checksum = checksum.wrapping_add(word); 200 | // } 201 | // let checksum = checksum.to_be_bytes(); 202 | // packet[10] = checksum[0]; 203 | // packet[11] = checksum[1]; 204 | // } 205 | // } 206 | // 207 | // pub struct Ipv6Packet { 208 | // pub version: u8, 209 | // pub traffic_class: u8, 210 | // pub flow_label: u32, 211 | // pub payload_length: u16, 212 | // pub next_header: u8, 213 | // pub hop_limit: u8, 214 | // pub source: Ipv6Addr, 215 | // pub destination: Ipv6Addr, 216 | // pub payload: Vec, 217 | // } 218 | // 219 | // impl Ipv6Packet { 220 | // pub fn parse(packet: &[u8]) -> Option { 221 | // if packet.len() < 40 { 222 | // return None; 223 | // } 224 | // 225 | // let version = packet[0] >> 4; 226 | // if version != 6 { 227 | // return None; 228 | // } 229 | // 230 | // let traffic_class = ((packet[0] & 0x0F) << 4) | (packet[1] >> 4); 231 | // let flow_label = 232 | // ((packet[1] as u32 & 0x0F) << 16) | ((packet[2] as u32) << 8) | packet[3] as u32; 233 | // let payload_length = u16::from_be_bytes([packet[4], packet[5]]); 234 | // let next_header = packet[6]; 235 | // let hop_limit = packet[7]; 236 | // let source = Ipv6Addr::new( 237 | // u16::from_be_bytes([packet[8], packet[9]]), 238 | // u16::from_be_bytes([packet[10], packet[11]]), 239 | // u16::from_be_bytes([packet[12], packet[13]]), 240 | // u16::from_be_bytes([packet[14], packet[15]]), 241 | // u16::from_be_bytes([packet[16], packet[17]]), 242 | // u16::from_be_bytes([packet[18], packet[19]]), 243 | // u16::from_be_bytes([packet[20], packet[21]]), 244 | // u16::from_be_bytes([packet[22], packet[23]]), 245 | // ); 246 | // 247 | // let destination = Ipv6Addr::new( 248 | // u16::from_be_bytes([packet[24], packet[25]]), 249 | // u16::from_be_bytes([packet[26], packet[27]]), 250 | // u16::from_be_bytes([packet[28], packet[29]]), 251 | // u16::from_be_bytes([packet[30], packet[31]]), 252 | // u16::from_be_bytes([packet[32], packet[33]]), 253 | // u16::from_be_bytes([packet[34], packet[35]]), 254 | // u16::from_be_bytes([packet[36], packet[37]]), 255 | // u16::from_be_bytes([packet[38], packet[39]]), 256 | // ); 257 | // let payload = packet[40..].to_vec(); 258 | // 259 | // Some(Self { 260 | // version, 261 | // traffic_class, 262 | // flow_label, 263 | // payload_length, 264 | // next_header, 265 | // hop_limit, 266 | // source, 267 | // destination, 268 | // payload, 269 | // }) 270 | // } 271 | // 272 | // pub async fn from_reader( 273 | // reader: &mut R, 274 | // log: &Option>>, 275 | // ) -> Result { 276 | // let mut log_packet = Vec::new(); 277 | // let mut header = [0u8; 40]; // IPv6 header size is fixed at 40 bytes 278 | // reader.read_exact(&mut header).await?; 279 | // if log.is_some() { 280 | // log_packet.extend_from_slice(&header); 281 | // } 282 | // 283 | // let version = header[0] >> 4; 284 | // if version != 6 { 285 | // return Err(std::io::Error::new( 286 | // std::io::ErrorKind::InvalidData, 287 | // "Invalid IPv6 header", 288 | // )); 289 | // } 290 | // 291 | // let traffic_class = ((header[0] & 0x0F) << 4) | ((header[1] & 0xF0) >> 4); 292 | // let flow_label = 293 | // ((header[1] as u32 & 0x0F) << 16) | ((header[2] as u32) << 8) | (header[3] as u32); 294 | // let payload_length = u16::from_be_bytes([header[4], header[5]]); 295 | // let next_header = header[6]; 296 | // let hop_limit = header[7]; 297 | // let source = Ipv6Addr::new( 298 | // u16::from_be_bytes([header[8], header[9]]), 299 | // u16::from_be_bytes([header[10], header[11]]), 300 | // u16::from_be_bytes([header[12], header[13]]), 301 | // u16::from_be_bytes([header[14], header[15]]), 302 | // u16::from_be_bytes([header[16], header[17]]), 303 | // u16::from_be_bytes([header[18], header[19]]), 304 | // u16::from_be_bytes([header[20], header[21]]), 305 | // u16::from_be_bytes([header[22], header[23]]), 306 | // ); 307 | // let destination = Ipv6Addr::new( 308 | // u16::from_be_bytes([header[24], header[25]]), 309 | // u16::from_be_bytes([header[26], header[27]]), 310 | // u16::from_be_bytes([header[28], header[29]]), 311 | // u16::from_be_bytes([header[30], header[31]]), 312 | // u16::from_be_bytes([header[32], header[33]]), 313 | // u16::from_be_bytes([header[34], header[35]]), 314 | // u16::from_be_bytes([header[36], header[37]]), 315 | // u16::from_be_bytes([header[38], header[39]]), 316 | // ); 317 | // 318 | // // Read the payload 319 | // let mut payload = vec![0u8; payload_length as usize]; 320 | // reader.read_exact(&mut payload).await?; 321 | // if let Some(log) = log { 322 | // log_packet.extend_from_slice(&payload); 323 | // super::log_packet(log, &log_packet); 324 | // } 325 | // 326 | // Ok(Self { 327 | // version, 328 | // traffic_class, 329 | // flow_label, 330 | // payload_length, 331 | // next_header, 332 | // hop_limit, 333 | // source, 334 | // destination, 335 | // payload, 336 | // }) 337 | // } 338 | // 339 | // pub fn create( 340 | // source: Ipv6Addr, 341 | // destination: Ipv6Addr, 342 | // next_header: ProtocolNumber, 343 | // hop_limit: u8, 344 | // payload: &[u8], 345 | // ) -> Vec { 346 | // let mut packet = Vec::with_capacity(40 + payload.len()); 347 | // 348 | // // Version (6) and Traffic Class (0) 349 | // let version_traffic_class = 6 << 4; 350 | // packet.push(version_traffic_class); 351 | // packet.push(0); // The rest of the Traffic Class and the start of the Flow Label 352 | // 353 | // // Flow Label (0) 354 | // let flow_label = 0u16; 355 | // packet.extend_from_slice(&flow_label.to_be_bytes()[..]); 356 | // 357 | // // Payload Length (length of the payload only) 358 | // packet.extend_from_slice(&(payload.len() as u16).to_be_bytes()); 359 | // 360 | // // Next Header and Hop Limit 361 | // packet.push(next_header as u8); 362 | // packet.push(hop_limit); 363 | // 364 | // // Source and Destination Addresses 365 | // packet.extend_from_slice(&source.octets()); 366 | // packet.extend_from_slice(&destination.octets()); 367 | // 368 | // // Payload 369 | // packet.extend_from_slice(payload); 370 | // 371 | // packet 372 | // } 373 | // } 374 | // 375 | // impl std::fmt::Debug for Ipv6Packet { 376 | // fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 377 | // f.debug_struct("Ipv6Packet") 378 | // .field("version", &self.version) 379 | // .field("traffic_class", &self.traffic_class) 380 | // .field("flow_label", &self.flow_label) 381 | // .field("payload_length", &self.payload_length) 382 | // .field("next_header", &self.next_header) 383 | // .field("hop_limit", &self.hop_limit) 384 | // .field("source", &self.source) 385 | // .field("destination", &self.destination) 386 | // .field("payload len", &self.payload.len()) 387 | // .finish() 388 | // } 389 | // } 390 | // 391 | // #[derive(Debug, Default, Clone, Copy)] 392 | // pub struct TcpFlags { 393 | // pub urg: bool, // Urgent pointer flag 394 | // pub ack: bool, // Acknowledgment flag 395 | // pub psh: bool, // Push flag 396 | // pub rst: bool, // Reset flag 397 | // pub syn: bool, // Synchronize flag 398 | // pub fin: bool, // Finish flag 399 | // } 400 | // 401 | // impl TcpFlags { 402 | // /// Create a new `TcpFlags` struct from a raw byte. 403 | // pub fn from_byte(flags: u8) -> Self { 404 | // Self { 405 | // urg: (flags & 0b0010_0000) != 0, // URG flag (bit 5) 406 | // ack: (flags & 0b0001_0000) != 0, // ACK flag (bit 4) 407 | // psh: (flags & 0b0000_1000) != 0, // PSH flag (bit 3) 408 | // rst: (flags & 0b0000_0100) != 0, // RST flag (bit 2) 409 | // syn: (flags & 0b0000_0010) != 0, // SYN flag (bit 1) 410 | // fin: (flags & 0b0000_0001) != 0, // FIN flag (bit 0) 411 | // } 412 | // } 413 | // 414 | // /// Convert the `TcpFlags` struct into a raw byte. 415 | // pub fn to_byte(&self) -> u8 { 416 | // let mut flags = 0u8; 417 | // if self.urg { 418 | // flags |= 0b0010_0000; 419 | // } 420 | // if self.ack { 421 | // flags |= 0b0001_0000; 422 | // } 423 | // if self.psh { 424 | // flags |= 0b0000_1000; 425 | // } 426 | // if self.rst { 427 | // flags |= 0b0000_0100; 428 | // } 429 | // if self.syn { 430 | // flags |= 0b0000_0010; 431 | // } 432 | // if self.fin { 433 | // flags |= 0b0000_0001; 434 | // } 435 | // flags 436 | // } 437 | // } 438 | // 439 | // pub struct TcpPacket { 440 | // pub source_port: u16, 441 | // pub destination_port: u16, 442 | // pub sequence_number: u32, 443 | // pub acknowledgment_number: u32, 444 | // pub data_offset: u8, // Header length in 32-bit words 445 | // pub flags: TcpFlags, // TCP flags 446 | // pub window_size: u16, 447 | // pub checksum: u16, 448 | // pub urgent_pointer: u16, 449 | // pub options: Vec, // Optional TCP options 450 | // pub payload: Vec, // TCP payload 451 | // } 452 | // 453 | // impl TcpPacket { 454 | // pub fn parse(packet: &[u8]) -> Result { 455 | // if packet.len() < 20 { 456 | // return Err(std::io::Error::new( 457 | // std::io::ErrorKind::InvalidData, 458 | // "Not enough bytes for TCP header", 459 | // )); 460 | // } 461 | // 462 | // let source_port = u16::from_be_bytes([packet[0], packet[1]]); 463 | // let destination_port = u16::from_be_bytes([packet[2], packet[3]]); 464 | // let sequence_number = u32::from_be_bytes([packet[4], packet[5], packet[6], packet[7]]); 465 | // let acknowledgment_number = 466 | // u32::from_be_bytes([packet[8], packet[9], packet[10], packet[11]]); 467 | // let data_offset = (packet[12] >> 4) * 4; // Convert from 32-bit words to bytes 468 | // let flags = TcpFlags::from_byte(packet[13]); // Parse flags 469 | // let window_size = u16::from_be_bytes([packet[14], packet[15]]); 470 | // let checksum = u16::from_be_bytes([packet[16], packet[17]]); 471 | // let urgent_pointer = u16::from_be_bytes([packet[18], packet[19]]); 472 | // 473 | // // Parse options if the header is longer than 20 bytes 474 | // let options_end = data_offset as usize; 475 | // let options = if options_end > 20 { 476 | // // packet[20..options_end].to_vec() 477 | // Vec::new() 478 | // } else { 479 | // Vec::new() 480 | // }; 481 | // 482 | // // Payload starts after the header 483 | // let payload = if packet.len() > options_end { 484 | // packet[options_end..].to_vec() 485 | // } else { 486 | // Vec::new() 487 | // }; 488 | // 489 | // Ok(Self { 490 | // source_port, 491 | // destination_port, 492 | // sequence_number, 493 | // acknowledgment_number, 494 | // data_offset, 495 | // flags, 496 | // window_size, 497 | // checksum, 498 | // urgent_pointer, 499 | // options, 500 | // payload, 501 | // }) 502 | // } 503 | // 504 | // #[allow(clippy::too_many_arguments)] 505 | // pub fn create( 506 | // source_ip: IpAddr, 507 | // destination_ip: IpAddr, 508 | // source_port: u16, 509 | // destination_port: u16, 510 | // sequence_number: u32, 511 | // acknowledgment_number: u32, 512 | // flags: TcpFlags, 513 | // window_size: u16, 514 | // payload: &[u8], 515 | // ) -> Vec { 516 | // let data_offset = 5_u8; // Header length in 32-bit words 517 | // let mut packet = Vec::with_capacity(20 + payload.len()); 518 | // 519 | // // Source and Destination Ports 520 | // packet.extend_from_slice(&source_port.to_be_bytes()); 521 | // packet.extend_from_slice(&destination_port.to_be_bytes()); 522 | // 523 | // // Sequence and Acknowledgment Numbers 524 | // packet.extend_from_slice(&sequence_number.to_be_bytes()); 525 | // packet.extend_from_slice(&acknowledgment_number.to_be_bytes()); 526 | // 527 | // // Data Offset and Flags 528 | // packet.push(data_offset << 4); // Data offset (4 bits) and reserved bits (4 bits) 529 | // packet.push(flags.to_byte()); // Flags byte 530 | // 531 | // // Window Size, Checksum (set to zero first), and Urgent Pointer 532 | // packet.extend_from_slice(&window_size.to_be_bytes()); 533 | // packet.extend_from_slice(&[0, 0]); // Checksum placeholder 534 | // packet.extend_from_slice(&[0, 0]); // Urgent pointer 535 | // 536 | // // No options, keeping it simple 537 | // packet.extend_from_slice(payload); 538 | // 539 | // // Compute checksum with the appropriate pseudo-header 540 | // let checksum = match (source_ip, destination_ip) { 541 | // (IpAddr::V4(src), IpAddr::V4(dest)) => { 542 | // let src_bytes = src.octets(); 543 | // let dest_bytes = dest.octets(); 544 | // Self::calculate_checksum(&packet, &src_bytes, &dest_bytes, false) 545 | // } 546 | // (IpAddr::V6(src), IpAddr::V6(dest)) => { 547 | // let src_bytes = src.octets(); 548 | // let dest_bytes = dest.octets(); 549 | // Self::calculate_checksum(&packet, &src_bytes, &dest_bytes, true) 550 | // } 551 | // _ => panic!("Source and destination IP versions must match"), 552 | // }; 553 | // 554 | // packet[16..18].copy_from_slice(&checksum.to_be_bytes()); 555 | // 556 | // packet 557 | // } 558 | // 559 | // fn calculate_checksum( 560 | // packet: &[u8], 561 | // source_ip: &[u8], 562 | // destination_ip: &[u8], 563 | // is_ipv6: bool, 564 | // ) -> u16 { 565 | // let mut sum = 0u32; 566 | // 567 | // if is_ipv6 { 568 | // // IPv6 pseudo-header 569 | // // Add source and destination addresses (128 bits each) 570 | // for chunk in source_ip.chunks(2) { 571 | // sum += u16::from_be_bytes([chunk[0], chunk[1]]) as u32; 572 | // } 573 | // for chunk in destination_ip.chunks(2) { 574 | // sum += u16::from_be_bytes([chunk[0], chunk[1]]) as u32; 575 | // } 576 | // 577 | // // Upper layer packet length (32 bits for IPv6) 578 | // let tcp_length = packet.len() as u32; 579 | // sum += (tcp_length >> 16) & 0xFFFF; 580 | // sum += tcp_length & 0xFFFF; 581 | // 582 | // // Next Header value (8 bits of zeros + 8 bits of protocol value) 583 | // sum += 6u32; // TCP protocol number 584 | // } else { 585 | // // IPv4 pseudo-header 586 | // // Add source and destination addresses (32 bits each) 587 | // for chunk in source_ip.chunks(2) { 588 | // sum += u16::from_be_bytes([chunk[0], chunk[1]]) as u32; 589 | // } 590 | // for chunk in destination_ip.chunks(2) { 591 | // sum += u16::from_be_bytes([chunk[0], chunk[1]]) as u32; 592 | // } 593 | // 594 | // // Zero byte + Protocol byte 595 | // sum += 6u32; // TCP protocol number 596 | // 597 | // // TCP segment length (16 bits) 598 | // sum += packet.len() as u32; 599 | // } 600 | // 601 | // // Create a copy of the packet with checksum field zeroed out 602 | // let mut packet_copy = packet.to_vec(); 603 | // if packet_copy.len() >= 18 { 604 | // packet_copy[16] = 0; 605 | // packet_copy[17] = 0; 606 | // } 607 | // 608 | // // Sum all 16-bit words in the packet 609 | // for chunk in packet_copy.chunks(2) { 610 | // let word = if chunk.len() == 2 { 611 | // u16::from_be_bytes([chunk[0], chunk[1]]) 612 | // } else { 613 | // u16::from_be_bytes([chunk[0], 0]) // Padding for odd-length packets 614 | // }; 615 | // sum += word as u32; 616 | // } 617 | // 618 | // // Fold sum to 16 bits 619 | // while sum >> 16 != 0 { 620 | // sum = (sum & 0xFFFF) + (sum >> 16); 621 | // } 622 | // 623 | // // One's complement 624 | // !(sum as u16) 625 | // } 626 | // } 627 | // 628 | // impl std::fmt::Debug for TcpPacket { 629 | // fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 630 | // f.debug_struct("TcpPacket") 631 | // .field("source_port", &self.source_port) 632 | // .field("destination_port", &self.destination_port) 633 | // .field("sequence_number", &self.sequence_number) 634 | // .field("acknowledgment_number", &self.acknowledgment_number) 635 | // .field("data_offset", &self.data_offset) 636 | // .field("flags", &self.flags) 637 | // .field("window_size", &self.window_size) 638 | // .field("checksum", &self.checksum) 639 | // .field("urgent_pointer", &self.urgent_pointer) 640 | // .field("options", &self.options) 641 | // .field("payload len", &self.payload.len()) 642 | // .finish() 643 | // } 644 | // } 645 | // 646 | // #[cfg(test)] 647 | // mod tests { 648 | // use super::*; 649 | // 650 | // #[test] 651 | // fn ipv4() { 652 | // let b1 = Ipv4Packet::create( 653 | // Ipv4Addr::new(127, 0, 0, 1), 654 | // Ipv4Addr::new(1, 1, 1, 1), 655 | // ProtocolNumber::Tcp, 656 | // 255, 657 | // &[1, 2, 3, 4, 5], 658 | // ); 659 | // println!("{b1:02X?}"); 660 | // 661 | // let ip1 = Ipv4Packet::parse(&b1); 662 | // println!("{ip1:#?}"); 663 | // } 664 | // 665 | // #[test] 666 | // fn ipv6() { 667 | // let b1 = Ipv6Packet::create( 668 | // Ipv6Addr::new(1, 2, 3, 4, 5, 6, 7, 8), 669 | // Ipv6Addr::new(9, 10, 11, 12, 13, 14, 15, 16), 670 | // ProtocolNumber::Tcp, 671 | // 255, 672 | // &[1, 2, 3, 4, 5], 673 | // ); 674 | // println!("{b1:02X?}"); 675 | // 676 | // let ip1 = Ipv6Packet::parse(&b1); 677 | // println!("{ip1:#?}"); 678 | // } 679 | // 680 | // #[test] 681 | // fn tcp() { 682 | // let b1 = TcpPacket::create( 683 | // IpAddr::V4(Ipv4Addr::new(1, 1, 1, 1)), 684 | // IpAddr::V4(Ipv4Addr::new(1, 1, 1, 1)), 685 | // 1234, 686 | // 5678, 687 | // 420, 688 | // 6969, 689 | // TcpFlags { 690 | // urg: false, 691 | // ack: false, 692 | // psh: true, 693 | // rst: false, 694 | // syn: false, 695 | // fin: false, 696 | // }, 697 | // 5555, 698 | // &[1, 2, 3, 4, 5], 699 | // ); 700 | // let i1 = Ipv6Packet::create( 701 | // Ipv6Addr::new(1, 2, 3, 4, 5, 6, 7, 8), 702 | // Ipv6Addr::new(9, 10, 11, 12, 13, 14, 15, 16), 703 | // ProtocolNumber::Tcp, 704 | // 255, 705 | // &b1, 706 | // ); 707 | // println!("{i1:02X?}"); 708 | // 709 | // let t1 = TcpPacket::parse(&b1); 710 | // println!("{t1:#?}"); 711 | // } 712 | // } 713 | --------------------------------------------------------------------------------