Compare commits

...
16 Commits
Author SHA1 Message Date
Nikolay Edigaryev 173f7832b3 DHCP snooper: use coarse time to avoid clock_gettime() overhead (#137)
* DHCP snooper: use coarse time to avoid clock_gettime() overhead

* Introduce uncertainty duration and subtract it from total lease time

* Update coarse time after we've performed the waiting

* Use coarsetime::Updater to update time even when deep inside event loop

* No need for manual coarsetime::Instant::update() anymore

* Ensure that coarsetime::Updater is stopped on Proxy::shutdown()

* Revert "Ensure that coarsetime::Updater is stopped on Proxy::shutdown()"

This reverts commit de255f4240.

* Revert "Use coarsetime::Updater to update time even when deep inside event loop"

This reverts commit 6a95272dcf.

* Revert "No need for manual coarsetime::Instant::update() anymore"

This reverts commit 9ffa829add.

* Update coarse time for the DHCP snooper after reading packet(s)
2026-01-14 21:16:19 +01:00
dependabot[bot] be2c706b00 Bump the all-updates group with 3 updates (#136)
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.179 to 0.2.180
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Changelog](https://github.com/rust-lang/libc/blob/0.2.180/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.179...0.2.180)

Updates `sentry` from 0.46.0 to 0.46.1
- [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.46.0...0.46.1)

Updates `sentry-anyhow` from 0.46.0 to 0.46.1
- [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.46.0...0.46.1)

---
updated-dependencies:
- dependency-name: libc
  dependency-version: 0.2.180
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
- dependency-name: sentry
  dependency-version: 0.46.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
- dependency-name: sentry-anyhow
  dependency-version: 0.46.1
  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>
2026-01-12 11:03:21 +01:00
dependabot[bot] b1f5678f18 Bump the all-updates group across 1 directory with 4 updates (#135)
Bumps the all-updates group with 4 updates in the / directory: [libc](https://github.com/rust-lang/libc), [clap](https://github.com/clap-rs/clap), [uzers](https://github.com/rustadopt/uzers-rs) and [serial_test](https://github.com/palfrey/serial_test).


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

Updates `clap` from 4.5.53 to 4.5.54
- [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.53...clap_complete-v4.5.54)

Updates `uzers` from 0.12.1 to 0.12.2
- [Release notes](https://github.com/rustadopt/uzers-rs/releases)
- [Changelog](https://github.com/rustadopt/uzers-rs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rustadopt/uzers-rs/compare/v0.12.1...v0.12.2)

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

---
updated-dependencies:
- dependency-name: libc
  dependency-version: 0.2.179
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
- dependency-name: clap
  dependency-version: 4.5.54
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
- dependency-name: uzers
  dependency-version: 0.12.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
- dependency-name: serial_test
  dependency-version: 3.3.1
  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>
2026-01-05 12:53:19 +01: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 590 additions and 237 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
+276 -164
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",
@@ -90,7 +90,7 @@ dependencies = [
"futures-core",
"futures-util",
"mio",
"socket2",
"socket2 0.5.7",
"tokio",
"tracing",
]
@@ -148,7 +148,7 @@ dependencies = [
"serde_json",
"serde_urlencoded",
"smallvec",
"socket2",
"socket2 0.5.7",
"time",
"tracing",
"url",
@@ -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",
]
@@ -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.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7eac00902d9d136acd712710d71823fb8ac8004ca445a89e73a41d45aa712931"
checksum = "c6e6ff9dcd79cff5cd969a17a545d79e84ab086e444102a591e288a8aa3ce394"
dependencies = [
"clap_builder",
"clap_derive",
@@ -373,9 +373,9 @@ dependencies = [
[[package]]
name = "clap_builder"
version = "4.5.47"
version = "4.5.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ad9bbf750e73b5884fb8a211a9424a1906c1e156724260fdae972f31d70e1d6"
checksum = "fa42cf4d2b7a41bc8f663a7cab4031ebafa1bf3875705bfaf8466dc60ab52c00"
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",
@@ -401,6 +401,17 @@ version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
[[package]]
name = "coarsetime"
version = "0.1.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e58eb270476aa4fc7843849f8a35063e8743b4dbcdf6dd0f8ea0886980c204c2"
dependencies = [
"libc",
"wasix",
"wasm-bindgen",
]
[[package]]
name = "colorchoice"
version = "1.0.2"
@@ -602,21 +613,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",
@@ -777,6 +786,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"
@@ -1006,9 +1026,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
[[package]]
name = "hyper"
version = "1.4.1"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05"
checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80"
dependencies = [
"bytes",
"futures-channel",
@@ -1041,18 +1061,23 @@ dependencies = [
[[package]]
name = "hyper-util"
version = "0.1.9"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b"
checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8"
dependencies = [
"base64",
"bytes",
"futures-channel",
"futures-core",
"futures-util",
"http 1.1.0",
"http-body",
"hyper",
"ipnet",
"libc",
"percent-encoding",
"pin-project-lite",
"socket2",
"socket2 0.6.1",
"tokio",
"tower-service",
"tracing",
@@ -1231,6 +1256,16 @@ version = "2.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
[[package]]
name = "iri-string"
version = "0.7.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a"
dependencies = [
"memchr",
"serde",
]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
@@ -1245,10 +1280,11 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
[[package]]
name = "js-sys"
version = "0.3.70"
version = "0.3.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a"
checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8"
dependencies = [
"once_cell",
"wasm-bindgen",
]
@@ -1266,9 +1302,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
version = "0.2.175"
version = "0.2.180"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543"
checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc"
[[package]]
name = "linux-raw-sys"
@@ -1317,9 +1353,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 +1439,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 +1452,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 +1485,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 +1507,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 +1542,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",
@@ -1623,16 +1660,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 +1816,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]]
@@ -1819,9 +1856,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "reqwest"
version = "0.12.8"
version = "0.12.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f713147fbe92361e52392c73b8c9e48c04c6625bce969ef54dc901e58e042a7b"
checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147"
dependencies = [
"base64",
"bytes",
@@ -1834,27 +1871,25 @@ dependencies = [
"hyper",
"hyper-tls",
"hyper-util",
"ipnet",
"js-sys",
"log",
"mime",
"native-tls",
"once_cell",
"percent-encoding",
"pin-project-lite",
"rustls-pemfile",
"rustls-pki-types",
"serde",
"serde_json",
"serde_urlencoded",
"sync_wrapper",
"tokio",
"tokio-native-tls",
"tower",
"tower-http",
"tower-service",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"windows-registry",
]
[[package]]
@@ -1878,7 +1913,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 +1926,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 +1963,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 +1987,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 +2024,9 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
[[package]]
name = "sentry"
version = "0.42.0"
version = "0.46.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "989425268ab5c011e06400187eed6c298272f8ef913e49fcadc3fda788b45030"
checksum = "2f925d575b468e88b079faf590a8dd0c9c99e2ec29e9bab663ceb8b45056312f"
dependencies = [
"httpdate",
"native-tls",
@@ -1994,9 +2044,9 @@ dependencies = [
[[package]]
name = "sentry-actix"
version = "0.42.0"
version = "0.46.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5c675bdf6118764a8e265c3395c311b4d905d12866c92df52870c0223d2ffc1"
checksum = "18bac0f6b8621fa0f85e298901e51161205788322e1a995e3764329020368058"
dependencies = [
"actix-http",
"actix-web",
@@ -2007,9 +2057,9 @@ dependencies = [
[[package]]
name = "sentry-anyhow"
version = "0.42.0"
version = "0.46.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1b4523c2595d6730bfbe401e95a6423fe9cb16dc3b6046f340551591cffe723"
checksum = "c8e45993dc8981e7fb5d9b7f701f65ca5c9fb0390263e47f612f30bea3d35fac"
dependencies = [
"anyhow",
"sentry-backtrace",
@@ -2018,9 +2068,9 @@ dependencies = [
[[package]]
name = "sentry-backtrace"
version = "0.42.0"
version = "0.46.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68e299dd3f7bcf676875eee852c9941e1d08278a743c32ca528e2debf846a653"
checksum = "6cb1ef7534f583af20452b1b1bf610a60ed9c8dd2d8485e7bd064efc556a78fb"
dependencies = [
"backtrace",
"regex",
@@ -2029,9 +2079,9 @@ dependencies = [
[[package]]
name = "sentry-contexts"
version = "0.42.0"
version = "0.46.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fac0c5d6892cd4c414492fc957477b620026fb3411fca9fa12774831da561c88"
checksum = "ebd6be899d9938390b6d1ec71e2f53bd9e57b6a9d8b1d5b049e5c364e7da9078"
dependencies = [
"hostname",
"libc",
@@ -2043,9 +2093,9 @@ dependencies = [
[[package]]
name = "sentry-core"
version = "0.42.0"
version = "0.46.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "deaa38b94e70820ff3f1f9db3c8b0aef053b667be130f618e615e0ff2492cbcc"
checksum = "26ab054c34b87f96c3e4701bea1888317cde30cc7e4a6136d2c48454ab96661c"
dependencies = [
"rand",
"sentry-types",
@@ -2056,9 +2106,9 @@ dependencies = [
[[package]]
name = "sentry-debug-images"
version = "0.42.0"
version = "0.46.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00950648aa0d371c7f57057434ad5671bd4c106390df7e7284739330786a01b6"
checksum = "5637ec550dc6f8c49a711537950722d3fc4baa6fd433c371912104eaff31e2a5"
dependencies = [
"findshlibs",
"sentry-core",
@@ -2066,9 +2116,9 @@ dependencies = [
[[package]]
name = "sentry-panic"
version = "0.42.0"
version = "0.46.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b7a23b13c004873de3ce7db86eb0f59fe4adfc655a31f7bbc17fd10bacc9bfe"
checksum = "3f02c7162f7b69b8de872b439d4696dc1d65f80b13ddd3c3831723def4756b63"
dependencies = [
"sentry-backtrace",
"sentry-core",
@@ -2076,11 +2126,11 @@ dependencies = [
[[package]]
name = "sentry-tracing"
version = "0.42.0"
version = "0.46.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fac841c7050aa73fc2bec8f7d8e9cb1159af0b3095757b99820823f3e54e5080"
checksum = "e1dd47df349a80025819f3d25c3d2f751df705d49c65a4cdc0f130f700972a48"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.4",
"sentry-backtrace",
"sentry-core",
"tracing-core",
@@ -2089,9 +2139,9 @@ dependencies = [
[[package]]
name = "sentry-types"
version = "0.42.0"
version = "0.46.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e477f4d4db08ddb4ab553717a8d3a511bc9e81dde0c808c680feacbb8105c412"
checksum = "eecbd63e9d15a26a40675ed180d376fcb434635d2e33de1c24003f61e3e2230d"
dependencies = [
"debugid",
"hex",
@@ -2148,6 +2198,32 @@ dependencies = [
"serde",
]
[[package]]
name = "serial_test"
version = "3.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d0b343e184fc3b7bb44dff0705fffcf4b3756ba6aff420dddd8b24ca145e555"
dependencies = [
"futures-executor",
"futures-util",
"log",
"once_cell",
"parking_lot",
"scc",
"serial_test_derive",
]
[[package]]
name = "serial_test_derive"
version = "3.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f50427f258fb77356e4cd4aa0e87e2bd2c66dbcee41dc405282cae2bfc26c83"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.101",
]
[[package]]
name = "sha1"
version = "0.10.6"
@@ -2215,12 +2291,23 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "socket2"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881"
dependencies = [
"libc",
"windows-sys 0.60.2",
]
[[package]]
name = "softnet"
version = "0.1.0"
dependencies = [
"anyhow",
"clap",
"coarsetime",
"dhcproto",
"ip_network",
"ipnet",
@@ -2228,13 +2315,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 +2391,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",
]
@@ -2444,7 +2532,7 @@ dependencies = [
"parking_lot",
"pin-project-lite",
"signal-hook-registry",
"socket2",
"socket2 0.5.7",
"windows-sys 0.52.0",
]
@@ -2499,6 +2587,45 @@ dependencies = [
"winnow 0.6.20",
]
[[package]]
name = "tower"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9"
dependencies = [
"futures-core",
"futures-util",
"pin-project-lite",
"sync_wrapper",
"tokio",
"tower-layer",
"tower-service",
]
[[package]]
name = "tower-http"
version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8"
dependencies = [
"bitflags 2.9.4",
"bytes",
"futures-util",
"http 1.1.0",
"http-body",
"iri-string",
"pin-project-lite",
"tower",
"tower-layer",
"tower-service",
]
[[package]]
name = "tower-layer"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e"
[[package]]
name = "tower-service"
version = "0.3.3"
@@ -2530,9 +2657,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 +2667,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",
]
@@ -2658,9 +2785,9 @@ dependencies = [
[[package]]
name = "uzers"
version = "0.12.1"
version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4df81ff504e7d82ad53e95ed1ad5b72103c11253f39238bcc0235b90768a97dd"
checksum = "0b8275fb1afee25b4111d2dc8b5c505dbbc4afd0b990cb96deb2d88bff8be18d"
dependencies = [
"libc",
"log",
@@ -2686,9 +2813,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 +2831,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",
@@ -2739,28 +2866,24 @@ dependencies = [
]
[[package]]
name = "wasm-bindgen"
version = "0.2.93"
name = "wasix"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5"
checksum = "1757e0d1f8456693c7e5c6c629bdb54884e032aa0bb53c155f6a39f94440d332"
dependencies = [
"cfg-if",
"once_cell",
"wasm-bindgen-macro",
"wasi 0.11.0+wasi-snapshot-preview1",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.93"
name = "wasm-bindgen"
version = "0.2.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b"
checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd"
dependencies = [
"bumpalo",
"log",
"cfg-if",
"once_cell",
"proc-macro2",
"quote",
"syn 2.0.101",
"rustversion",
"wasm-bindgen-macro",
"wasm-bindgen-shared",
]
@@ -2778,9 +2901,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.93"
version = "0.2.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf"
checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@@ -2788,22 +2911,25 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.93"
version = "0.2.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836"
checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40"
dependencies = [
"bumpalo",
"proc-macro2",
"quote",
"syn 2.0.101",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.93"
version = "0.2.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484"
checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4"
dependencies = [
"unicode-ident",
]
[[package]]
name = "web-sys"
@@ -2875,34 +3001,10 @@ dependencies = [
]
[[package]]
name = "windows-registry"
version = "0.2.0"
name = "windows-link"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0"
dependencies = [
"windows-result",
"windows-strings",
"windows-targets 0.52.6",
]
[[package]]
name = "windows-result"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e"
dependencies = [
"windows-targets 0.52.6",
]
[[package]]
name = "windows-strings"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10"
dependencies = [
"windows-result",
"windows-targets 0.52.6",
]
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]]
name = "windows-sys"
@@ -2928,7 +3030,16 @@ version = "0.60.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
dependencies = [
"windows-targets 0.53.2",
"windows-targets 0.53.5",
]
[[package]]
name = "windows-sys"
version = "0.61.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e201184e40b2ede64bc2ea34968b28e33622acdbbf37104f0e4a33f7abe657aa"
dependencies = [
"windows-link",
]
[[package]]
@@ -2949,18 +3060,19 @@ dependencies = [
[[package]]
name = "windows-targets"
version = "0.53.2"
version = "0.53.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef"
checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3"
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-link",
"windows_aarch64_gnullvm 0.53.1",
"windows_aarch64_msvc 0.53.1",
"windows_i686_gnu 0.53.1",
"windows_i686_gnullvm 0.53.1",
"windows_i686_msvc 0.53.1",
"windows_x86_64_gnu 0.53.1",
"windows_x86_64_gnullvm 0.53.1",
"windows_x86_64_msvc 0.53.1",
]
[[package]]
@@ -2971,9 +3083,9 @@ checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.53.0"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53"
[[package]]
name = "windows_aarch64_msvc"
@@ -2983,9 +3095,9 @@ checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_aarch64_msvc"
version = "0.53.0"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006"
[[package]]
name = "windows_i686_gnu"
@@ -2995,9 +3107,9 @@ checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnu"
version = "0.53.0"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"
checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3"
[[package]]
name = "windows_i686_gnullvm"
@@ -3007,9 +3119,9 @@ checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_gnullvm"
version = "0.53.0"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c"
[[package]]
name = "windows_i686_msvc"
@@ -3019,9 +3131,9 @@ checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_i686_msvc"
version = "0.53.0"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2"
[[package]]
name = "windows_x86_64_gnu"
@@ -3031,9 +3143,9 @@ checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnu"
version = "0.53.0"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499"
[[package]]
name = "windows_x86_64_gnullvm"
@@ -3043,9 +3155,9 @@ checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.53.0"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1"
[[package]]
name = "windows_x86_64_msvc"
@@ -3055,9 +3167,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "windows_x86_64_msvc"
version = "0.53.0"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
[[package]]
name = "winnow"
@@ -3083,7 +3195,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]]
+6 -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,13 @@ 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"
coarsetime = "0.1.37"
[profile.release]
debug = true
+26 -11
View File
@@ -1,15 +1,23 @@
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};
use std::time::Duration;
#[derive(Default)]
pub struct DhcpSnooper {
vm_lease: Option<Lease>,
uncertainty_duration: Duration,
}
impl DhcpSnooper {
pub fn new(uncertainty_duration: Duration) -> Self {
DhcpSnooper {
uncertainty_duration,
..Default::default()
}
}
pub fn register_dhcp_reply(&mut self, dhcp_packet: &[u8]) {
let mut decoder = dhcproto::v4::Decoder::new(dhcp_packet);
@@ -32,11 +40,12 @@ impl DhcpSnooper {
_ => HashSet::new(),
};
self.vm_lease = Some(Lease::new(
message.yiaddr(),
Duration::from_secs(*lease_time as u64),
dns_ips,
))
let mut lease_duration = Duration::from_secs(*lease_time as u64);
// Adjust for uncertainty caused by using a coarse clock
lease_duration = lease_duration.saturating_sub(self.uncertainty_duration);
self.vm_lease = Some(Lease::new(message.yiaddr(), lease_duration, dns_ips))
}
Some(MessageType::Nak) => {
self.vm_lease = None;
@@ -45,6 +54,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,17 +72,18 @@ impl DhcpSnooper {
}
}
#[derive(Debug)]
pub struct Lease {
address: Ipv4Address,
valid_until: Instant,
valid_until: coarsetime::Instant,
dns_ips: HashSet<Ipv4Address>,
}
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,
valid_until: coarsetime::Instant::recent() + lease_time.into(),
dns_ips,
}
}
@@ -78,7 +93,7 @@ impl Lease {
}
pub fn valid(&self) -> bool {
Instant::now() < self.valid_until
coarsetime::Instant::recent() < self.valid_until
}
pub fn valid_ip_source(&self, address: Ipv4Address) -> bool {
+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
+9 -4
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;
@@ -9,6 +9,7 @@ use std::time::Duration;
pub struct Poller<'poller> {
poller: polling::Poller,
events: polling::Events,
timeout: Duration,
vm_fd: BorrowedFd<'poller>,
host_fd: BorrowedFd<'poller>,
}
@@ -22,12 +23,17 @@ enum EventKey {
}
impl Poller<'_> {
pub fn new<'poller>(vm_fd: RawFd, host_fd: RawFd) -> Result<Poller<'poller>> {
pub fn new<'poller>(
vm_fd: RawFd,
host_fd: RawFd,
timeout: Duration,
) -> Result<Poller<'poller>> {
let poller = polling::Poller::new()?;
Ok(Poller {
poller,
events: polling::Events::new(),
timeout,
vm_fd: unsafe { BorrowedFd::borrow_raw(vm_fd) },
host_fd: unsafe { BorrowedFd::borrow_raw(host_fd) },
})
@@ -59,8 +65,7 @@ impl Poller<'_> {
}
pub fn wait(&mut self) -> Result<(bool, bool, bool)> {
self.poller
.wait(&mut self.events, Some(Duration::from_millis(100)))?;
self.poller.wait(&mut self.events, Some(self.timeout))?;
let vm_readable = self
.events
+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};
+156 -11
View File
@@ -14,10 +14,12 @@ 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 std::time::Duration;
use vmnet::Batch;
pub struct Proxy<'proxy> {
vm: VM,
@@ -25,49 +27,82 @@ 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())?;
let poller_timeout = Duration::from_millis(100);
let poller = Poller::new(vm.as_raw_fd(), host.as_raw_fd(), poller_timeout)?;
// 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,
dhcp_snooper: DhcpSnooper::new(poller_timeout),
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 {
let (vm_readable, host_readable, interrupt) = self.poller.wait()?;
// Update coarse time for the DHCP snooper
coarsetime::Instant::update();
if vm_readable {
self.read_from_vm(buf.as_mut_slice())?;
}
if host_readable {
self.read_from_host(buf.as_mut_slice())?;
self.read_from_host(&mut batch, &mut bufs)?;
}
// Graceful termination
@@ -89,6 +124,9 @@ impl Proxy<'_> {
loop {
match self.vm.read(buf) {
Ok(n) => {
// Update coarse time for the DHCP snooper
coarsetime::Instant::update();
if let Ok(frame) = EthernetFrame::new_checked(&buf[..n]) {
self.process_frame_from_vm(frame)?;
}
@@ -104,12 +142,17 @@ 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) => {
// Update coarse time for the DHCP snooper
coarsetime::Instant::update();
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 +166,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(());
+26 -5
View File
@@ -1,14 +1,14 @@
use anyhow::{anyhow, Context};
use anyhow::{Context, 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::os::raw::c_int;
@@ -52,13 +52,31 @@ struct Args {
#[clap(
long,
help = "comma-separated list of CIDRs to allow the traffic to (e.g. --allow=192.168.0.0/24)",
help = "Comma-separated list of CIDRs to allow the traffic to \
(e.g. --allow=192.168.0.0/24 may be used to allow a LAN access for a VM). \
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",
use_value_delimiter = true,
action = clap::ArgAction::Set
)]
allow: Vec<Ipv4Net>,
#[clap(
long,
help = "Comma-separated list of CIDRs 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). 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",
use_value_delimiter = true,
action = clap::ArgAction::Set
)]
block: Vec<Ipv4Net>,
#[clap(
long,
help = "comma-separated list of TCP ports to expose (e.g. --expose 2222:22,8080:80)",
@@ -78,7 +96,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
@@ -177,6 +197,7 @@ fn try_main() -> anyhow::Result<()> {
args.vm_mac_address,
args.vm_net_type,
PrefixSet::from_iter(args.allow),
PrefixSet::from_iter(args.block),
args.expose,
)
.context("failed to initialize proxy")?;