Compare commits

..
Author SHA1 Message Date
Fedor Korotkov c377206064 chore: remove unused skill file for PR fixes 2026-01-08 15:27:44 +01:00
Fedor Korotkov 7623d698ce revert: restore args parsing style
- switch back to let mut args: Args = Args::parse()
2026-01-08 15:08:47 +01:00
Fedor KorotkovandClaude Opus 4.5 1ccb0ee4b4 fix: address PR review feedback
- simplify allow/block resolution without mem::take (refs #2661210452)
- use dns.google test domain with stable A records (refs #2661236654)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 12:34:46 +01:00
Fedor Korotkov 50b5e2af2d Add domain resolution for allow/block entries
- Updated `--allow` and `--block` flags to accept domains, alongside CIDRs and IPs.
- Implemented A-record resolution for domain entries during startup.
- Added tests for domain resolution functionality.
2025-12-20 06:44:51 -05:00
dependabot[bot] c1ddb2afc6 Bump the all-updates group with 3 updates (#132)
Bumps the all-updates group with 3 updates: [libc](https://github.com/rust-lang/libc), [system-configuration](https://github.com/mullvad/system-configuration-rs) and [log](https://github.com/rust-lang/log).


Updates `libc` from 0.2.177 to 0.2.178
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Changelog](https://github.com/rust-lang/libc/blob/0.2.178/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.177...0.2.178)

Updates `system-configuration` from 0.6.1 to 0.7.0
- [Changelog](https://github.com/mullvad/system-configuration-rs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/mullvad/system-configuration-rs/compare/v0.6.1...v0.7.0)

Updates `log` from 0.4.28 to 0.4.29
- [Release notes](https://github.com/rust-lang/log/releases)
- [Changelog](https://github.com/rust-lang/log/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/log/compare/0.4.28...0.4.29)

---
updated-dependencies:
- dependency-name: libc
  dependency-version: 0.2.178
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
- dependency-name: system-configuration
  dependency-version: 0.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
- dependency-name: log
  dependency-version: 0.4.29
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-08 11:55:22 +01:00
dependabot[bot] 401dea6612 Bump the all-updates group with 2 updates (#131)
Bumps the all-updates group with 2 updates: [sentry](https://github.com/getsentry/sentry-rust) and [sentry-anyhow](https://github.com/getsentry/sentry-rust).


Updates `sentry` from 0.45.0 to 0.46.0
- [Release notes](https://github.com/getsentry/sentry-rust/releases)
- [Changelog](https://github.com/getsentry/sentry-rust/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-rust/compare/0.45.0...0.46.0)

Updates `sentry-anyhow` from 0.45.0 to 0.46.0
- [Release notes](https://github.com/getsentry/sentry-rust/releases)
- [Changelog](https://github.com/getsentry/sentry-rust/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-rust/compare/0.45.0...0.46.0)

---
updated-dependencies:
- dependency-name: sentry
  dependency-version: 0.46.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
- dependency-name: sentry-anyhow
  dependency-version: 0.46.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-01 13:37:30 +04:00
dependabot[bot] 1dcb0755df Bump clap from 4.5.51 to 4.5.53 in the all-updates group (#130)
Bumps the all-updates group with 1 update: [clap](https://github.com/clap-rs/clap).


Updates `clap` from 4.5.51 to 4.5.53
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.51...clap_complete-v4.5.53)

---
updated-dependencies:
- dependency-name: clap
  dependency-version: 4.5.53
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-24 14:53:18 +04:00
dependabot[bot] 1706062004 Bump clap from 4.5.50 to 4.5.51 in the all-updates group (#129)
Bumps the all-updates group with 1 update: [clap](https://github.com/clap-rs/clap).


Updates `clap` from 4.5.50 to 4.5.51
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.50...clap_complete-v4.5.51)

---
updated-dependencies:
- dependency-name: clap
  dependency-version: 4.5.51
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-03 14:17:54 +04:00
Nikolay Edigaryev dfc04a49e4 .goreleaser.yml: require macOS Sequoia (see #128) 2025-10-28 13:49:09 +01:00
Nikolay Edigaryev 7dc5992b55 Perform batched reads from host to improve efficiency (#128)
* Perform batched reads from host to improve efficiency

* CI: don't test on macOS Sonoma
2025-10-28 16:48:05 +04:00
dependabot[bot] 58d4b32258 Bump the all-updates group with 3 updates (#127)
Bumps the all-updates group with 3 updates: [dhcproto](https://github.com/bluecatengineering/dhcproto), [clap](https://github.com/clap-rs/clap) and [serial_test](https://github.com/palfrey/serial_test).


Updates `dhcproto` from `96a6845` to `b4ea30d`
- [Release notes](https://github.com/bluecatengineering/dhcproto/releases)
- [Commits](https://github.com/bluecatengineering/dhcproto/compare/96a6845f7154a54e9c18d3595807c62e7994d5fe...b4ea30defc01e7ae66e7075d6a0533d9bb9503dc)

Updates `clap` from 4.5.49 to 4.5.50
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.49...clap_complete-v4.5.50)

Updates `serial_test` from 0.10.0 to 3.2.0
- [Release notes](https://github.com/palfrey/serial_test/releases)
- [Commits](https://github.com/palfrey/serial_test/compare/v0.10.0...v3.2.0)

---
updated-dependencies:
- dependency-name: dhcproto
  dependency-version: b4ea30defc01e7ae66e7075d6a0533d9bb9503dc
  dependency-type: direct:production
  dependency-group: all-updates
- dependency-name: clap
  dependency-version: 4.5.50
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
- dependency-name: serial_test
  dependency-version: 3.2.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: all-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-27 16:10:36 +04:00
Nikolay Edigaryev 431ae9bbc9 Introduce --block in addition to --allow (#126) 2025-10-21 17:14:28 +04:00
dependabot[bot] 98988e5c73 Bump the all-updates group with 2 updates (#125)
Bumps the all-updates group with 2 updates: [clap](https://github.com/clap-rs/clap) and [num_enum](https://github.com/illicitonion/num_enum).


Updates `clap` from 4.5.48 to 4.5.49
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.48...clap_complete-v4.5.49)

Updates `num_enum` from 0.7.4 to 0.7.5
- [Commits](https://github.com/illicitonion/num_enum/compare/0.7.4...0.7.5)

---
updated-dependencies:
- dependency-name: clap
  dependency-version: 4.5.49
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
- dependency-name: num_enum
  dependency-version: 0.7.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-20 11:11:33 +04:00
dependabot[bot] b122b49b3c Bump the all-updates group with 3 updates (#123)
Bumps the all-updates group with 3 updates: [libc](https://github.com/rust-lang/libc), [sentry](https://github.com/getsentry/sentry-rust) and [sentry-anyhow](https://github.com/getsentry/sentry-rust).


Updates `libc` from 0.2.176 to 0.2.177
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Changelog](https://github.com/rust-lang/libc/blob/0.2.177/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.176...0.2.177)

Updates `sentry` from 0.43.0 to 0.45.0
- [Release notes](https://github.com/getsentry/sentry-rust/releases)
- [Changelog](https://github.com/getsentry/sentry-rust/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-rust/compare/0.43.0...0.45.0)

Updates `sentry-anyhow` from 0.43.0 to 0.45.0
- [Release notes](https://github.com/getsentry/sentry-rust/releases)
- [Changelog](https://github.com/getsentry/sentry-rust/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-rust/compare/0.43.0...0.45.0)

---
updated-dependencies:
- dependency-name: libc
  dependency-version: 0.2.177
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
- dependency-name: sentry
  dependency-version: 0.45.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
- dependency-name: sentry-anyhow
  dependency-version: 0.45.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-13 13:22:56 +04:00
dependabot[bot] 2650e78eb0 Bump the all-updates group with 3 updates (#122)
Bumps the all-updates group with 3 updates: [libc](https://github.com/rust-lang/libc), [sentry](https://github.com/getsentry/sentry-rust) and [sentry-anyhow](https://github.com/getsentry/sentry-rust).


Updates `libc` from 0.2.175 to 0.2.176
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Changelog](https://github.com/rust-lang/libc/blob/0.2.176/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.175...0.2.176)

Updates `sentry` from 0.42.0 to 0.43.0
- [Release notes](https://github.com/getsentry/sentry-rust/releases)
- [Changelog](https://github.com/getsentry/sentry-rust/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-rust/compare/0.42.0...0.43.0)

Updates `sentry-anyhow` from 0.42.0 to 0.43.0
- [Release notes](https://github.com/getsentry/sentry-rust/releases)
- [Changelog](https://github.com/getsentry/sentry-rust/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-rust/compare/0.42.0...0.43.0)

---
updated-dependencies:
- dependency-name: libc
  dependency-version: 0.2.176
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
- dependency-name: sentry
  dependency-version: 0.43.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
- dependency-name: sentry-anyhow
  dependency-version: 0.43.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-07 00:45:39 +04:00
dependabot[bot] 0c59910018 Bump the all-updates group with 2 updates (#121)
Bumps the all-updates group with 2 updates: [clap](https://github.com/clap-rs/clap) and [anyhow](https://github.com/dtolnay/anyhow).


Updates `clap` from 4.5.47 to 4.5.48
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.47...clap_complete-v4.5.48)

Updates `anyhow` from 1.0.99 to 1.0.100
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.99...1.0.100)

---
updated-dependencies:
- dependency-name: clap
  dependency-version: 4.5.48
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
- dependency-name: anyhow
  dependency-version: 1.0.100
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-22 12:52:22 +04:00
dependabot[bot] 7e622716f7 Bump polling from 3.10.0 to 3.11.0 in the all-updates group (#120)
Bumps the all-updates group with 1 update: [polling](https://github.com/smol-rs/polling).


Updates `polling` from 3.10.0 to 3.11.0
- [Release notes](https://github.com/smol-rs/polling/releases)
- [Changelog](https://github.com/smol-rs/polling/blob/master/CHANGELOG.md)
- [Commits](https://github.com/smol-rs/polling/compare/v3.10.0...v3.11.0)

---
updated-dependencies:
- dependency-name: polling
  dependency-version: 3.11.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-15 12:43:22 +04:00
13 changed files with 530 additions and 217 deletions
+2
View File
@@ -0,0 +1,2 @@
[target.aarch64-apple-darwin]
runner = 'sudo -E'
+29 -4
View File
@@ -1,11 +1,35 @@
use_compute_credits: true
macos_instance:
image: ghcr.io/cirruslabs/macos-runner:tahoe
env:
PATH: "$PATH:$HOME/.cargo/bin"
task:
name: Lint
install_rust_script: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
rustfmt_script: cargo fmt --check
clippy_script: cargo clippy --all-targets --all-features -- -D warnings
task:
alias: Test
matrix:
- name: Test on macOS Sequoia
macos_instance:
image: ghcr.io/cirruslabs/macos-runner:sequoia
- name: Test on macOS Tahoe
macos_instance:
image: ghcr.io/cirruslabs/macos-runner:tahoe
install_rust_script: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
test_script: cargo test
task:
name: Release (Dry Run)
only_if: $CIRRUS_TAG == ''
macos_instance:
image: ghcr.io/cirruslabs/macos-sequoia-xcode:latest
depends_on:
- Lint
- Test
install_rust_script: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
install_script: brew install go
install_goreleaser_script: brew install --cask goreleaser/tap/goreleaser-pro
@@ -16,8 +40,9 @@ task:
task:
name: Release
only_if: $CIRRUS_TAG != ''
macos_instance:
image: ghcr.io/cirruslabs/macos-sequoia-xcode:latest
depends_on:
- Lint
- Test
env:
GITHUB_TOKEN: ENCRYPTED[!98ace8259c6024da912c14d5a3c5c6aac186890a8d4819fad78f3e0c41a4e0cd3a2537dd6e91493952fb056fa434be7c!]
GORELEASER_KEY: ENCRYPTED[!9b80b6ef684ceaf40edd4c7af93014ee156c8aba7e6e5795f41c482729887b5c31f36b651491d790f1f668670888d9fd!]
+2
View File
@@ -29,3 +29,5 @@ brews:
homepage: https://github.com/cirruslabs/softnet
description: Software networking with isolation for Tart
skip_upload: auto
custom_block: |
depends_on :macos => :sequoia
Generated
+163 -154
View File
@@ -8,7 +8,7 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f7b0a21988c1bf877cf4759ef5ddaac04c1c9fe808c9142ecb78ba97d97a28a"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.4",
"bytes",
"futures-core",
"futures-sink",
@@ -30,7 +30,7 @@ dependencies = [
"actix-service",
"actix-utils",
"base64",
"bitflags 2.6.0",
"bitflags 2.9.4",
"bytes",
"bytestring",
"derive_more",
@@ -229,9 +229,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.99"
version = "1.0.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100"
checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
dependencies = [
"backtrace",
]
@@ -271,7 +271,7 @@ dependencies = [
"miniz_oxide",
"object",
"rustc-demangle",
"windows-targets 0.52.6",
"windows-targets",
]
[[package]]
@@ -294,9 +294,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.6.0"
version = "2.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394"
[[package]]
name = "block"
@@ -363,9 +363,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
[[package]]
name = "clap"
version = "4.5.47"
version = "4.5.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7eac00902d9d136acd712710d71823fb8ac8004ca445a89e73a41d45aa712931"
checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8"
dependencies = [
"clap_builder",
"clap_derive",
@@ -373,9 +373,9 @@ dependencies = [
[[package]]
name = "clap_builder"
version = "4.5.47"
version = "4.5.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ad9bbf750e73b5884fb8a211a9424a1906c1e156724260fdae972f31d70e1d6"
checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00"
dependencies = [
"anstream",
"anstyle",
@@ -385,9 +385,9 @@ dependencies = [
[[package]]
name = "clap_derive"
version = "4.5.47"
version = "4.5.49"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c"
checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671"
dependencies = [
"heck",
"proc-macro2",
@@ -602,21 +602,19 @@ dependencies = [
[[package]]
name = "dhcproto"
version = "0.14.0"
source = "git+https://github.com/bluecatengineering/dhcproto.git?branch=master#96a6845f7154a54e9c18d3595807c62e7994d5fe"
source = "git+https://github.com/bluecatengineering/dhcproto.git?branch=master#b4ea30defc01e7ae66e7075d6a0533d9bb9503dc"
dependencies = [
"dhcproto-macros",
"hex",
"hickory-proto",
"ipnet",
"rand",
"thiserror 2.0.12",
"url",
]
[[package]]
name = "dhcproto-macros"
version = "0.1.0"
source = "git+https://github.com/bluecatengineering/dhcproto.git?branch=master#96a6845f7154a54e9c18d3595807c62e7994d5fe"
version = "0.2.0"
source = "git+https://github.com/bluecatengineering/dhcproto.git?branch=master#b4ea30defc01e7ae66e7075d6a0533d9bb9503dc"
dependencies = [
"proc-macro2",
"quote",
@@ -761,6 +759,21 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "futures"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0"
dependencies = [
"futures-channel",
"futures-core",
"futures-executor",
"futures-io",
"futures-sink",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-channel"
version = "0.3.30"
@@ -777,6 +790,17 @@ version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
[[package]]
name = "futures-executor"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
dependencies = [
"futures-core",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-io"
version = "0.3.30"
@@ -801,6 +825,7 @@ version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
dependencies = [
"futures-channel",
"futures-core",
"futures-io",
"futures-sink",
@@ -1266,9 +1291,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
version = "0.2.175"
version = "0.2.178"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543"
checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091"
[[package]]
name = "linux-raw-sys"
@@ -1317,9 +1342,9 @@ dependencies = [
[[package]]
name = "log"
version = "0.4.28"
version = "0.4.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
[[package]]
name = "mac_address"
@@ -1403,7 +1428,7 @@ version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.4",
"cfg-if",
"cfg_aliases",
"libc",
@@ -1416,10 +1441,11 @@ version = "0.30.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.4",
"cfg-if",
"cfg_aliases",
"libc",
"memoffset",
]
[[package]]
@@ -1448,11 +1474,11 @@ dependencies = [
[[package]]
name = "num_enum"
version = "0.7.4"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a973b4e44ce6cad84ce69d797acf9a044532e4184c4f267913d1b546a0727b7a"
checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c"
dependencies = [
"num_enum_derive 0.7.4",
"num_enum_derive 0.7.5",
"rustversion",
]
@@ -1470,9 +1496,9 @@ dependencies = [
[[package]]
name = "num_enum_derive"
version = "0.7.4"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d"
checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7"
dependencies = [
"proc-macro-crate 3.2.0",
"proc-macro2",
@@ -1505,7 +1531,7 @@ version = "0.10.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fedfea7d58a1f73118430a55da6a286e7b044961736ce96a16a17068ea25e5da"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.4",
"cfg-if",
"foreign-types",
"libc",
@@ -1585,7 +1611,7 @@ dependencies = [
"libc",
"redox_syscall",
"smallvec",
"windows-targets 0.52.6",
"windows-targets",
]
[[package]]
@@ -1623,16 +1649,16 @@ checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
[[package]]
name = "polling"
version = "3.10.0"
version = "3.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5bd19146350fe804f7cb2669c851c03d69da628803dab0d98018142aaa5d829"
checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218"
dependencies = [
"cfg-if",
"concurrent-queue",
"hermit-abi 0.5.1",
"pin-project-lite",
"rustix 1.0.7",
"windows-sys 0.60.2",
"windows-sys 0.61.0",
]
[[package]]
@@ -1779,7 +1805,7 @@ version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.4",
]
[[package]]
@@ -1878,7 +1904,7 @@ version = "0.38.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.4",
"errno",
"libc",
"linux-raw-sys 0.4.14",
@@ -1891,7 +1917,7 @@ version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.4",
"errno",
"libc",
"linux-raw-sys 0.9.4",
@@ -1928,6 +1954,15 @@ version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
[[package]]
name = "scc"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46e6f046b7fef48e2660c57ed794263155d713de679057f2d0c169bfc6e756cc"
dependencies = [
"sdd",
]
[[package]]
name = "schannel"
version = "0.1.24"
@@ -1943,13 +1978,19 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "sdd"
version = "3.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "490dcfcbfef26be6800d11870ff2df8774fa6e86d047e3e8c8a76b25655e41ca"
[[package]]
name = "security-framework"
version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.4",
"core-foundation",
"core-foundation-sys",
"libc",
@@ -1974,9 +2015,9 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
[[package]]
name = "sentry"
version = "0.42.0"
version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "989425268ab5c011e06400187eed6c298272f8ef913e49fcadc3fda788b45030"
checksum = "d9794f69ad475e76c057e326175d3088509649e3aed98473106b9fe94ba59424"
dependencies = [
"httpdate",
"native-tls",
@@ -1994,9 +2035,9 @@ dependencies = [
[[package]]
name = "sentry-actix"
version = "0.42.0"
version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5c675bdf6118764a8e265c3395c311b4d905d12866c92df52870c0223d2ffc1"
checksum = "e0fee202934063ace4f1d1d063113b8982293762628e563a2d2fba08fb20b110"
dependencies = [
"actix-http",
"actix-web",
@@ -2007,9 +2048,9 @@ dependencies = [
[[package]]
name = "sentry-anyhow"
version = "0.42.0"
version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1b4523c2595d6730bfbe401e95a6423fe9cb16dc3b6046f340551591cffe723"
checksum = "d1832cd051f3198af8ebc5222da5fd213e49976d758b7defa7accbff3aed1909"
dependencies = [
"anyhow",
"sentry-backtrace",
@@ -2018,9 +2059,9 @@ dependencies = [
[[package]]
name = "sentry-backtrace"
version = "0.42.0"
version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68e299dd3f7bcf676875eee852c9941e1d08278a743c32ca528e2debf846a653"
checksum = "e81137ad53b8592bd0935459ad74c0376053c40084aa170451e74eeea8dbc6c3"
dependencies = [
"backtrace",
"regex",
@@ -2029,9 +2070,9 @@ dependencies = [
[[package]]
name = "sentry-contexts"
version = "0.42.0"
version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fac0c5d6892cd4c414492fc957477b620026fb3411fca9fa12774831da561c88"
checksum = "cfb403c66cc2651a01b9bacda2e7c22cd51f7e8f56f206aa4310147eb3259282"
dependencies = [
"hostname",
"libc",
@@ -2043,9 +2084,9 @@ dependencies = [
[[package]]
name = "sentry-core"
version = "0.42.0"
version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "deaa38b94e70820ff3f1f9db3c8b0aef053b667be130f618e615e0ff2492cbcc"
checksum = "cfc409727ae90765ca8ea76fe6c949d6f159a11d02e130b357fa652ee9efcada"
dependencies = [
"rand",
"sentry-types",
@@ -2056,9 +2097,9 @@ dependencies = [
[[package]]
name = "sentry-debug-images"
version = "0.42.0"
version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00950648aa0d371c7f57057434ad5671bd4c106390df7e7284739330786a01b6"
checksum = "06a2778a222fd90ebb01027c341a72f8e24b0c604c6126504a4fe34e5500e646"
dependencies = [
"findshlibs",
"sentry-core",
@@ -2066,9 +2107,9 @@ dependencies = [
[[package]]
name = "sentry-panic"
version = "0.42.0"
version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b7a23b13c004873de3ce7db86eb0f59fe4adfc655a31f7bbc17fd10bacc9bfe"
checksum = "3df79f4e1e72b2a8b75a0ebf49e78709ceb9b3f0b451f13adc92a0361b0aaabe"
dependencies = [
"sentry-backtrace",
"sentry-core",
@@ -2076,11 +2117,11 @@ dependencies = [
[[package]]
name = "sentry-tracing"
version = "0.42.0"
version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fac841c7050aa73fc2bec8f7d8e9cb1159af0b3095757b99820823f3e54e5080"
checksum = "ff2046f527fd4b75e0b6ab3bd656c67dce42072f828dc4d03c206d15dca74a93"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.4",
"sentry-backtrace",
"sentry-core",
"tracing-core",
@@ -2089,9 +2130,9 @@ dependencies = [
[[package]]
name = "sentry-types"
version = "0.42.0"
version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e477f4d4db08ddb4ab553717a8d3a511bc9e81dde0c808c680feacbb8105c412"
checksum = "c7b9b4e4c03a4d3643c18c78b8aa91d2cbee5da047d2fa0ca4bb29bc67e6c55c"
dependencies = [
"debugid",
"hex",
@@ -2148,6 +2189,31 @@ dependencies = [
"serde",
]
[[package]]
name = "serial_test"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b258109f244e1d6891bf1053a55d63a5cd4f8f4c30cf9a1280989f80e7a1fa9"
dependencies = [
"futures",
"log",
"once_cell",
"parking_lot",
"scc",
"serial_test_derive",
]
[[package]]
name = "serial_test_derive"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d69265a08751de7844521fd15003ae0a888e035773ba05695c5c759a6f89eef"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.101",
]
[[package]]
name = "sha1"
version = "0.10.6"
@@ -2228,13 +2294,14 @@ dependencies = [
"log",
"mac_address",
"nix 0.30.1",
"num_enum 0.7.4",
"num_enum 0.7.5",
"oslog",
"polling",
"prefix-trie",
"privdrop",
"sentry",
"sentry-anyhow",
"serial_test",
"smoltcp",
"system-configuration",
"uzers",
@@ -2303,11 +2370,11 @@ dependencies = [
[[package]]
name = "system-configuration"
version = "0.6.1"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b"
checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.4",
"core-foundation",
"system-configuration-sys",
]
@@ -2530,9 +2597,9 @@ dependencies = [
[[package]]
name = "tracing-core"
version = "0.1.32"
version = "0.1.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678"
dependencies = [
"once_cell",
"valuable",
@@ -2540,9 +2607,9 @@ dependencies = [
[[package]]
name = "tracing-subscriber"
version = "0.3.19"
version = "0.3.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008"
checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5"
dependencies = [
"tracing-core",
]
@@ -2686,9 +2753,9 @@ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "vmnet"
version = "0.4.2"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c96eae216a9fa27c8e458ee5ef56dfc92d43fc8c25d67ade4a7fa83f0cb8b21b"
checksum = "4d88878a5583a43715c9f6de9b4cf94bc1af1dfec2a6abd75fd821de623f693b"
dependencies = [
"bitflags 1.3.2",
"block",
@@ -2704,9 +2771,9 @@ dependencies = [
[[package]]
name = "vmnet-derive"
version = "0.4.2"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa20b8d2b5b0504355848b99b54fda9411f8201f44c1a9ee5a2d3c3134d31297"
checksum = "9ee4569490df90dfa2cfeda38230905b2331e72a16fa62a8f5d31069ea024db2"
dependencies = [
"darling",
"proc-macro2",
@@ -2862,7 +2929,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be"
dependencies = [
"windows-core",
"windows-targets 0.52.6",
"windows-targets",
]
[[package]]
@@ -2871,9 +2938,15 @@ version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
dependencies = [
"windows-targets 0.52.6",
"windows-targets",
]
[[package]]
name = "windows-link"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65"
[[package]]
name = "windows-registry"
version = "0.2.0"
@@ -2882,7 +2955,7 @@ checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0"
dependencies = [
"windows-result",
"windows-strings",
"windows-targets 0.52.6",
"windows-targets",
]
[[package]]
@@ -2891,7 +2964,7 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e"
dependencies = [
"windows-targets 0.52.6",
"windows-targets",
]
[[package]]
@@ -2901,7 +2974,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10"
dependencies = [
"windows-result",
"windows-targets 0.52.6",
"windows-targets",
]
[[package]]
@@ -2910,7 +2983,7 @@ version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets 0.52.6",
"windows-targets",
]
[[package]]
@@ -2919,16 +2992,16 @@ version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
"windows-targets 0.52.6",
"windows-targets",
]
[[package]]
name = "windows-sys"
version = "0.60.2"
version = "0.61.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
checksum = "e201184e40b2ede64bc2ea34968b28e33622acdbbf37104f0e4a33f7abe657aa"
dependencies = [
"windows-targets 0.53.2",
"windows-link",
]
[[package]]
@@ -2937,30 +3010,14 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm 0.52.6",
"windows_aarch64_msvc 0.52.6",
"windows_i686_gnu 0.52.6",
"windows_i686_gnullvm 0.52.6",
"windows_i686_msvc 0.52.6",
"windows_x86_64_gnu 0.52.6",
"windows_x86_64_gnullvm 0.52.6",
"windows_x86_64_msvc 0.52.6",
]
[[package]]
name = "windows-targets"
version = "0.53.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef"
dependencies = [
"windows_aarch64_gnullvm 0.53.0",
"windows_aarch64_msvc 0.53.0",
"windows_i686_gnu 0.53.0",
"windows_i686_gnullvm 0.53.0",
"windows_i686_msvc 0.53.0",
"windows_x86_64_gnu 0.53.0",
"windows_x86_64_gnullvm 0.53.0",
"windows_x86_64_msvc 0.53.0",
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
@@ -2969,96 +3026,48 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_aarch64_msvc"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnu"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_gnullvm"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_i686_msvc"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnu"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "windows_x86_64_msvc"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
[[package]]
name = "winnow"
version = "0.5.40"
@@ -3083,7 +3092,7 @@ version = "0.39.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.4",
]
[[package]]
+5 -4
View File
@@ -2,7 +2,7 @@
name = "softnet"
version = "0.1.0"
publish = false
edition = "2021"
edition = "2024"
[lib]
path = "lib/mod.rs"
@@ -16,7 +16,7 @@ smoltcp = "0"
libc = "0"
polling = "3"
dhcproto = { git = "https://github.com/bluecatengineering/dhcproto.git", branch = "master" }
vmnet = "0"
vmnet = "0.5.0"
clap = { version = "4", features = ["derive"] }
mac_address = "1"
privdrop = "0"
@@ -27,11 +27,12 @@ system-configuration = "0"
num_enum = "0"
sentry = { version = "0", features = ["debug-images"] }
sentry-anyhow = { version = "0", features = ["backtrace"] }
nix = { version = "0", features = ["signal"] }
nix = { version = "0", features = ["signal", "socket"] }
prefix-trie = "0"
ipnet = "2"
oslog = "0.2.0"
log = "0.4.28"
log = "0.4.29"
serial_test = "3"
[profile.release]
debug = true
+8 -2
View File
@@ -1,5 +1,5 @@
use dhcproto::v4::{DhcpOption, MessageType, OptionCode};
use dhcproto::Decodable;
use dhcproto::v4::{DhcpOption, MessageType, OptionCode};
use smoltcp::wire::Ipv4Address;
use std::collections::HashSet;
use std::time::{Duration, Instant};
@@ -45,6 +45,11 @@ impl DhcpSnooper {
};
}
#[cfg(test)]
pub(crate) fn set_lease(&mut self, vm_lease: Option<Lease>) {
self.vm_lease = vm_lease
}
pub fn lease(&self) -> &Option<Lease> {
&self.vm_lease
}
@@ -58,6 +63,7 @@ impl DhcpSnooper {
}
}
#[derive(Debug)]
pub struct Lease {
address: Ipv4Address,
valid_until: Instant,
@@ -65,7 +71,7 @@ pub struct Lease {
}
impl Lease {
fn new(address: Ipv4Address, lease_time: Duration, dns_ips: HashSet<Ipv4Address>) -> Lease {
pub fn new(address: Ipv4Address, lease_time: Duration, dns_ips: HashSet<Ipv4Address>) -> Lease {
Lease {
address,
valid_until: Instant::now() + lease_time,
+19 -6
View File
@@ -1,15 +1,15 @@
use anyhow::{anyhow, Context, Result};
use anyhow::{Context, Result, anyhow};
use clap::ValueEnum;
use log::info;
use std::net::Ipv4Addr;
use std::os::unix::io::{AsRawFd, RawFd};
use std::os::unix::net::UnixDatagram;
use std::str::FromStr;
use std::sync::mpsc::{sync_channel, SyncSender};
use std::sync::mpsc::{SyncSender, sync_channel};
use vmnet::mode::Mode;
use vmnet::parameters::{Parameter, ParameterKind};
use vmnet::port_forwarding::{AddressFamily, Protocol};
use vmnet::{Events, Options};
use vmnet::{Batch, Events, Options};
#[derive(ValueEnum, Clone, Debug)]
pub enum NetType {
@@ -29,6 +29,7 @@ pub struct Host {
callback_can_continue_tx: SyncSender<()>,
pub gateway_ip: smoltcp::wire::Ipv4Address,
pub max_packet_size: u64,
pub read_max_packets: u64,
finalized: bool,
}
@@ -67,6 +68,15 @@ impl Host {
));
};
// Retrieve read max packets for this interface
let Some(Parameter::ReadMaxPackets(read_max_packets)) =
interface.parameters().get(ParameterKind::ReadMaxPackets)
else {
return Err(anyhow!(
"failed to retrieve vmnet's interface read max packets"
));
};
// Set up a socketpair() to emulate polling of the vmnet interface
let (new_packets_tx, new_packets_rx) = UnixDatagram::pair()?;
new_packets_rx.set_nonblocking(true)?;
@@ -96,6 +106,7 @@ impl Host {
callback_can_continue_tx,
gateway_ip,
max_packet_size,
read_max_packets,
finalized: false,
})
}
@@ -108,7 +119,9 @@ impl Host {
internal_addr: Ipv4Addr,
internal_port: u16,
) -> Result<()> {
let details = format!("external_port={external_port}, internal_addr={internal_addr}, internal_port={internal_port}");
let details = format!(
"external_port={external_port}, internal_addr={internal_addr}, internal_port={internal_port}"
);
self.interface
.port_forwarding_rule_add(
@@ -131,14 +144,14 @@ impl Host {
.map_err(|err| anyhow!("failed to remove port forwarding rule {details}: {err}"))
}
pub fn read(&mut self, buf: &mut [u8]) -> vmnet::Result<usize> {
pub fn read(&mut self, batch: &mut Batch, bufs: &mut [Vec<u8>]) -> vmnet::Result<usize> {
// Dequeue dummy datagram from the socket (if any)
// to free up buffer space and reduce false-positives
// when polling
let mut buf_to_be_discarded: [u8; 1] = [0; 1];
let _ = self.new_packets_rx.recv(&mut buf_to_be_discarded);
let result = self.interface.read(buf);
let result = self.interface.read_batch(batch, bufs);
if let Err(vmnet::Error::VmnetReadNothing) = result {
// We've emptied everything, unlock the callback
+1 -1
View File
@@ -1,7 +1,7 @@
use anyhow::Result;
use num_enum::IntoPrimitive;
use polling::os::kqueue::PollerKqueueExt;
use polling::PollMode;
use polling::os::kqueue::PollerKqueueExt;
use std::os::fd::{AsRawFd, BorrowedFd};
use std::os::unix::io::RawFd;
use std::time::Duration;
+1 -1
View File
@@ -1,4 +1,4 @@
use anyhow::{anyhow, Context, Error};
use anyhow::{Context, Error, anyhow};
use std::str::FromStr;
#[derive(Debug, Clone, Copy, Default, PartialEq)]
+1 -1
View File
@@ -1,5 +1,5 @@
use crate::proxy::udp_packet_helper::UdpPacketHelper;
use crate::proxy::Proxy;
use crate::proxy::udp_packet_helper::UdpPacketHelper;
use anyhow::{Context, Result};
use smoltcp::wire::{EthernetFrame, EthernetProtocol, Ipv4Packet, UdpPacket};
+143 -9
View File
@@ -14,10 +14,11 @@ pub use exposed_port::ExposedPort;
use ipnet::Ipv4Net;
use mac_address::MacAddress;
use port_forwarder::PortForwarder;
use prefix_trie::{Prefix, PrefixSet};
use prefix_trie::{Prefix, PrefixMap, PrefixSet};
use smoltcp::wire::EthernetFrame;
use std::io::ErrorKind;
use std::os::unix::io::{AsRawFd, RawFd};
use vmnet::Batch;
pub struct Proxy<'proxy> {
vm: VM,
@@ -25,38 +26,67 @@ pub struct Proxy<'proxy> {
poller: Poller<'proxy>,
vm_mac_address: smoltcp::wire::EthernetAddress,
dhcp_snooper: DhcpSnooper,
allow: PrefixSet<Ipv4Net>,
rules: PrefixMap<Ipv4Net, Action>,
enobufs_encountered: bool,
port_forwarder: PortForwarder,
}
#[derive(Debug, Clone, PartialEq)]
pub(crate) enum Action {
Block,
Allow,
}
impl Proxy<'_> {
pub fn new<'proxy>(
vm_fd: RawFd,
vm_mac_address: MacAddress,
vm_net_type: NetType,
allow: PrefixSet<Ipv4Net>,
block: PrefixSet<Ipv4Net>,
exposed_ports: Vec<ExposedPort>,
) -> Result<Proxy<'proxy>> {
let vm = VM::new(vm_fd)?;
let host = Host::new(vm_net_type, !allow.contains(&Ipv4Net::zero()))?;
let poller = Poller::new(vm.as_raw_fd(), host.as_raw_fd())?;
// Craft packet filter rules
//
// SECURITY: blocking rules must always take precedence
// over allowing rules when prefixes are identical.
let mut rules = PrefixMap::new();
for allow_net in allow {
rules.insert(allow_net, Action::Allow);
}
for block_net in block {
rules.insert(block_net, Action::Block);
}
Ok(Proxy {
vm,
host,
poller,
vm_mac_address: smoltcp::wire::EthernetAddress(vm_mac_address.bytes()),
dhcp_snooper: Default::default(),
allow,
rules,
enobufs_encountered: false,
port_forwarder: PortForwarder::new(exposed_ports),
})
}
pub fn run(&mut self) -> Result<()> {
// Create a single buffer from reading from the VM
let mut buf: Vec<u8> = vec![0; self.host.max_packet_size as usize];
// Create multiple buffers and a batch for reading from the host
let mut bufs = vec![
vec![0u8; self.host.max_packet_size as usize];
self.host.read_max_packets as usize
];
let mut batch = Batch::preallocate(bufs.len());
self.poller.arm()?;
loop {
@@ -67,7 +97,7 @@ impl Proxy<'_> {
}
if host_readable {
self.read_from_host(buf.as_mut_slice())?;
self.read_from_host(&mut batch, &mut bufs)?;
}
// Graceful termination
@@ -104,12 +134,14 @@ impl Proxy<'_> {
}
}
fn read_from_host(&mut self, buf: &mut [u8]) -> Result<()> {
fn read_from_host(&mut self, batch: &mut Batch, bufs: &mut [Vec<u8>]) -> Result<()> {
loop {
match self.host.read(buf) {
Ok(n) => {
if let Ok(pkt) = EthernetFrame::new_checked(&buf[..n]) {
self.process_frame_from_host(&pkt)?;
match self.host.read(batch, bufs) {
Ok(pktcnt) => {
for buf in batch.packet_sized_bufs(bufs).take(pktcnt) {
if let Ok(pkt) = EthernetFrame::new_checked(buf) {
self.process_frame_from_host(&pkt)?;
}
}
}
Err(err) => {
@@ -123,3 +155,105 @@ impl Proxy<'_> {
}
}
}
#[cfg(test)]
mod tests {
use crate::NetType;
use crate::dhcp_snooper::Lease;
use crate::proxy::{Action, Proxy};
use ipnet::Ipv4Net;
use mac_address::MacAddress;
use nix::sys::socket::{AddressFamily, SockFlag, SockType, socketpair};
use prefix_trie::{PrefixMap, PrefixSet};
use serial_test::serial;
use smoltcp::wire::{Ipv4Address, Ipv4Packet};
use std::collections::HashSet;
use std::os::fd::AsRawFd;
use std::str::FromStr;
use std::time::Duration;
#[test]
#[serial]
fn test_blocking_takes_precedence() {
let vm_ip = Ipv4Address::from_str("192.168.0.2").unwrap();
let proxy = create_proxy(vm_ip, vec!["66.66.0.0/16"], vec!["66.66.0.0/16"]);
assert_eq!(
proxy.rules,
PrefixMap::<Ipv4Net, Action>::from_iter(vec![(
Ipv4Net::from_str("66.66.0.0/16").unwrap(),
Action::Block
),])
);
assert!(allowed_from_vm_ipv4(&proxy, vm_ip, "66.66.66.66").is_none());
}
#[test]
#[serial]
fn test_longest_prefix_match_wins() {
let vm_ip = Ipv4Address::from_str("192.168.0.2").unwrap();
let proxy = create_proxy(vm_ip, vec!["33.33.33.33/32"], vec!["33.33.33.0/24"]);
assert_eq!(
proxy.rules,
PrefixMap::<Ipv4Net, Action>::from_iter(vec![
(Ipv4Net::from_str("33.33.33.33/32").unwrap(), Action::Allow),
(Ipv4Net::from_str("33.33.33.0/24").unwrap(), Action::Block),
])
);
assert!(allowed_from_vm_ipv4(&proxy, vm_ip, "33.33.33.32").is_none());
assert!(allowed_from_vm_ipv4(&proxy, vm_ip, "33.33.33.33").is_some());
assert!(allowed_from_vm_ipv4(&proxy, vm_ip, "33.33.33.34").is_none());
}
fn create_proxy<'test>(vm_ip: Ipv4Address, allow: Vec<&str>, block: Vec<&str>) -> Proxy<'test> {
let (vm_fd, _) = socketpair(
AddressFamily::Unix,
SockType::Datagram,
None,
SockFlag::empty(),
)
.unwrap();
let vm_fd = Box::leak(Box::new(vm_fd));
let mut proxy = Proxy::new(
vm_fd.as_raw_fd(),
MacAddress::from_str("02:00:00:00:00:01").unwrap(),
NetType::Nat,
PrefixSet::from_iter(
allow
.into_iter()
.map(|cidr| Ipv4Net::from_str(cidr).unwrap()),
),
PrefixSet::from_iter(
block
.into_iter()
.map(|cidr| Ipv4Net::from_str(cidr).unwrap()),
),
Vec::default(),
)
.unwrap();
proxy.dhcp_snooper.set_lease(Some(Lease::new(
vm_ip,
Duration::from_secs(600),
HashSet::new(),
)));
proxy
}
fn allowed_from_vm_ipv4(proxy: &Proxy, src: Ipv4Address, dst: &str) -> Option<()> {
let mut buf = vec![0; 1500];
let mut ipv4_pkt_mut = Ipv4Packet::new_unchecked(&mut buf[..]);
ipv4_pkt_mut.set_src_addr(src);
ipv4_pkt_mut.set_dst_addr(Ipv4Address::from_str(dst).unwrap());
let ipv4_pkt = Ipv4Packet::new_unchecked(buf.as_slice());
proxy.allowed_from_vm_ipv4(ipv4_pkt)
}
}
+37 -26
View File
@@ -1,5 +1,5 @@
use crate::proxy::udp_packet_helper::UdpPacketHelper;
use crate::proxy::Proxy;
use crate::proxy::{Action, Proxy};
use anyhow::Context;
use anyhow::Result;
use ipnet::Ipv4Net;
@@ -58,43 +58,54 @@ impl Proxy<'_> {
None
}
fn allowed_from_vm_ipv4(&self, ipv4_pkt: Ipv4Packet<&[u8]>) -> Option<()> {
// Have we learned the VM's IP from the DHCP snooping?
if let Some(lease) = &self.dhcp_snooper.lease() {
// If so, allow all global traffic
pub(crate) fn allowed_from_vm_ipv4(&self, ipv4_pkt: Ipv4Packet<&[u8]>) -> Option<()> {
// Is this packet coming from VM's IP address that we've learned from DHCP snooping?
if let Some(lease) = &self.dhcp_snooper.lease()
&& lease.valid_ip_source(ipv4_pkt.src_addr())
{
let dst_addr = ipv4_pkt.dst_addr();
let dst_is_global = ip_network::IpNetwork::from(dst_addr).is_global();
if lease.valid_ip_source(ipv4_pkt.src_addr()) && dst_is_global {
// Filter traffic based on user-specified rules first
if !self.rules.is_empty() {
let dst_net = Ipv4Net::from(dst_addr);
if let Some((_, action)) = self.rules.get_lpm(&dst_net) {
return match action {
Action::Allow => Some(()),
Action::Block => None,
};
}
}
// When no user-specified rules matched, simply allow all global traffic
if ip_network::IpNetwork::from(dst_addr).is_global() {
return Some(());
}
// Also allow all traffic to the user-specified CIDRs
let dst_net = Ipv4Net::from(dst_addr);
// Use get_lpm() instead of get_spm() to work around prefix-trie
// not handling prefixes like 0.0.0.0/0 correctly[1]
//
// [1]: https://github.com/tiborschneider/prefix-trie/issues/8
if self.allow.get_lpm(&dst_net).is_some() {
// Additionally, allow communication with the host,
// otherwise things like SSH to a VM won't work
if ipv4_pkt.dst_addr() == self.host.gateway_ip {
return Some(());
}
// Additionally, allow DNS requests to DNS-servers
// provided to a VM by the host's DHCP server
if ipv4_pkt.next_header() == IpProtocol::Udp {
let udp_pkt = UdpPacket::new_checked(ipv4_pkt.payload()).ok()?;
if udp_pkt.is_dns_request()
&& self.dhcp_snooper.valid_dns_target(&ipv4_pkt.dst_addr())
{
return Some(());
}
}
}
// Allow communication with host
if ipv4_pkt.dst_addr() == self.host.gateway_ip {
return Some(());
}
// Allow outgoing DHCP requests to broadcast addresses,
// otherwise DHCP snooper will never be populated
if ipv4_pkt.next_header() == IpProtocol::Udp {
let udp_pkt = UdpPacket::new_checked(ipv4_pkt.payload()).ok()?;
// Allow DNS communication with the DNS-servers provided by DHCP
if udp_pkt.is_dns_request() && self.dhcp_snooper.valid_dns_target(&ipv4_pkt.dst_addr())
{
return Some(());
}
// Allow DHCP communication with the bootpd(8) on host via broadcast address
if udp_pkt.is_dhcp_request() && ipv4_pkt.dst_addr().is_broadcast() {
return Some(());
+119 -9
View File
@@ -1,20 +1,22 @@
use anyhow::{anyhow, Context};
use anyhow::{Context, Error, anyhow};
use clap::Parser;
use ipnet::Ipv4Net;
use log::LevelFilter;
use nix::sys::signal::{signal, SigHandler, Signal};
use nix::sys::signal::{SigHandler, Signal, signal};
use oslog::OsLogger;
use prefix_trie::PrefixSet;
use privdrop::PrivDrop;
use softnet::NetType;
use softnet::proxy::ExposedPort;
use softnet::proxy::Proxy;
use softnet::NetType;
use std::borrow::Cow;
use std::env;
use std::net::{Ipv4Addr, SocketAddr, ToSocketAddrs};
use std::os::raw::c_int;
use std::os::unix::io::RawFd;
use std::os::unix::process::CommandExt;
use std::process::{Command, ExitCode};
use std::str::FromStr;
use system_configuration::core_foundation::base::TCFType;
use system_configuration::core_foundation::dictionary::CFDictionary;
use system_configuration::core_foundation::number::CFNumber;
@@ -23,6 +25,67 @@ use system_configuration::preferences::SCPreferences;
use system_configuration::sys::preferences::{SCPreferencesCommitChanges, SCPreferencesSetValue};
use uzers::{get_current_groupname, get_current_username, get_effective_uid};
#[derive(Debug, Clone)]
enum AllowBlockEntry {
Net(Ipv4Net),
Domain(String),
}
impl FromStr for AllowBlockEntry {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let trimmed = s.trim();
if trimmed.is_empty() {
return Err(anyhow!("empty allow/block entry"));
}
if let Ok(net) = trimmed.parse::<Ipv4Net>() {
return Ok(AllowBlockEntry::Net(net));
}
if let Ok(addr) = trimmed.parse::<Ipv4Addr>() {
return Ok(AllowBlockEntry::Net(Ipv4Net::from(addr)));
}
Ok(AllowBlockEntry::Domain(trimmed.to_string()))
}
}
fn resolve_allow_block_entries(
kind: &str,
entries: Vec<AllowBlockEntry>,
) -> anyhow::Result<Vec<Ipv4Net>> {
let mut nets = Vec::new();
for entry in entries {
match entry {
AllowBlockEntry::Net(net) => nets.push(net),
AllowBlockEntry::Domain(domain) => {
// A-record resolution happens here via ToSocketAddrs, then we keep only IPv4s.
let resolved: Vec<Ipv4Net> = (domain.as_str(), 0)
.to_socket_addrs()
.with_context(|| format!("failed to resolve {kind} entry {domain}"))?
.filter_map(|addr| match addr {
SocketAddr::V4(v4) => Some(Ipv4Net::from(*v4.ip())),
SocketAddr::V6(_) => None,
})
.collect();
if resolved.is_empty() {
return Err(anyhow!(
"no IPv4 addresses found for {kind} entry {domain}"
));
}
nets.extend(resolved);
}
}
}
Ok(nets)
}
#[derive(Parser, Debug)]
struct Args {
#[clap(
@@ -52,12 +115,32 @@ struct Args {
#[clap(
long,
help = "comma-separated list of CIDRs to allow the traffic to (e.g. --allow=192.168.0.0/24)",
value_name = "comma-separated CIDRs",
help = "Comma-separated list of CIDRs, IPs, or domains to allow the traffic to \
(e.g. --allow=192.168.0.0/24 or --allow=example.com). Domains are resolved to A records \
at startup. \
When used with --block, the longest prefix match always wins. \
In case an identical prefix is both --allow'ed and --block'ed, \
blocking will take precedence. --allow=0.0.0.0/0 is a special case, \
it additionally disables bridge isolation (even when --block=0.0.0.0/0 is specified).",
value_name = "comma-separated CIDRs/IPs/domains",
use_value_delimiter = true,
action = clap::ArgAction::Set
)]
allow: Vec<Ipv4Net>,
allow: Vec<AllowBlockEntry>,
#[clap(
long,
help = "Comma-separated list of CIDRs, IPs, or domains to block the traffic to \
(e.g. --block=0.0.0.0/0 may be used to establish a default deny policy \
that is further relaxed with --allow). Domains are resolved to A records at startup. \
When used with --allow, \
the longest prefix match always wins. In case the same prefix is both \
--allow'ed and --block'ed, blocking takes precedence.",
value_name = "comma-separated CIDRs/IPs/domains",
use_value_delimiter = true,
action = clap::ArgAction::Set
)]
block: Vec<AllowBlockEntry>,
#[clap(
long,
@@ -78,7 +161,9 @@ struct Args {
fn main() -> ExitCode {
// Enable backtraces by default
if env::var("RUST_BACKTRACE").is_err() {
env::set_var("RUST_BACKTRACE", "full");
unsafe {
env::set_var("RUST_BACKTRACE", "full");
}
}
// Initialize Sentry
@@ -125,7 +210,7 @@ fn try_main() -> anyhow::Result<()> {
// [2]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/kqueue.2.html
unsafe { signal(Signal::SIGINT, SigHandler::SigIgn) }?;
let args: Args = Args::parse();
let mut args: Args = Args::parse();
// No need to run anything, just return
// so that the invoker process knows we
@@ -168,6 +253,9 @@ fn try_main() -> anyhow::Result<()> {
));
}
let allow = resolve_allow_block_entries("allow", std::mem::take(&mut args.allow))?;
let block = resolve_allow_block_entries("block", std::mem::take(&mut args.block))?;
// Set bootpd(8) min/max lease time while still having the root privileges
set_bootpd_lease_time(args.bootpd_lease_time);
@@ -176,7 +264,8 @@ fn try_main() -> anyhow::Result<()> {
args.vm_fd as RawFd,
args.vm_mac_address,
args.vm_net_type,
PrefixSet::from_iter(args.allow),
PrefixSet::from_iter(allow),
PrefixSet::from_iter(block),
args.expose,
)
.context("failed to initialize proxy")?;
@@ -228,3 +317,24 @@ fn set_bootpd_lease_time(lease_time: u32) {
SCPreferencesCommitChanges(prefs.as_concrete_TypeRef());
}
}
#[cfg(test)]
mod tests {
use super::{AllowBlockEntry, resolve_allow_block_entries};
use ipnet::Ipv4Net;
use std::net::Ipv4Addr;
#[test]
fn resolve_domain_to_ipv4_nets_dns_google() {
let nets = resolve_allow_block_entries(
"allow",
vec![AllowBlockEntry::Domain("dns.google".to_string())],
)
.unwrap();
assert!(
nets.contains(&Ipv4Net::from(Ipv4Addr::new(8, 8, 8, 8)))
|| nets.contains(&Ipv4Net::from(Ipv4Addr::new(8, 8, 4, 4)))
);
}
}