Compare commits

..
Author SHA1 Message Date
Nikolay Edigaryev df84a30016 --allow: support "@host" syntax (#160)
* --allow: support "@host" syntax

To make communication with the guest VM possible
when using --block=0.0.0.0/0.

* Use "@-alias" wording instead of "@host"
2026-05-15 16:06:03 +02:00
dependabot[bot] bbff9996ab Bump rustls-webpki from 0.103.9 to 0.103.13 (#154)
Bumps [rustls-webpki](https://github.com/rustls/webpki) from 0.103.9 to 0.103.13.
- [Release notes](https://github.com/rustls/webpki/releases)
- [Commits](https://github.com/rustls/webpki/compare/v/0.103.9...v/0.103.13)

---
updated-dependencies:
- dependency-name: rustls-webpki
  dependency-version: 0.103.13
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-12 22:24:05 +02:00
dependabot[bot] dd55a20de0 Bump openssl from 0.10.72 to 0.10.79 (#158)
Bumps [openssl](https://github.com/rust-openssl/rust-openssl) from 0.10.72 to 0.10.79.
- [Release notes](https://github.com/rust-openssl/rust-openssl/releases)
- [Commits](https://github.com/rust-openssl/rust-openssl/compare/openssl-v0.10.72...openssl-v0.10.79)

---
updated-dependencies:
- dependency-name: openssl
  dependency-version: 0.10.79
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-12 22:23:56 +02:00
dependabot[bot] 012a93834a Bump the all-updates group across 1 directory with 7 updates (#159)
Bumps the all-updates group with 7 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [smoltcp](https://github.com/smoltcp-rs/smoltcp) | `0.13.0` | `0.13.1` |
| [libc](https://github.com/rust-lang/libc) | `0.2.183` | `0.2.186` |
| [dhcproto](https://github.com/bluecatengineering/dhcproto) | ``b4ea30d`` | ``eece41c`` |
| [clap](https://github.com/clap-rs/clap) | `4.6.0` | `4.6.1` |
| [sentry](https://github.com/getsentry/sentry-rust) | `0.47.0` | `0.48.1` |
| [sentry-anyhow](https://github.com/getsentry/sentry-rust) | `0.47.0` | `0.48.1` |
| [prefix-trie](https://github.com/tiborschneider/prefix-trie) | `0.8.2` | `0.8.3` |



Updates `smoltcp` from 0.13.0 to 0.13.1
- [Release notes](https://github.com/smoltcp-rs/smoltcp/releases)
- [Changelog](https://github.com/smoltcp-rs/smoltcp/blob/main/CHANGELOG.md)
- [Commits](https://github.com/smoltcp-rs/smoltcp/compare/v0.13.0...v0.13.1)

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

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

Updates `clap` from 4.6.0 to 4.6.1
- [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.6.0...clap_complete-v4.6.1)

Updates `sentry` from 0.47.0 to 0.48.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.47.0...0.48.1)

Updates `sentry-anyhow` from 0.47.0 to 0.48.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.47.0...0.48.1)

Updates `prefix-trie` from 0.8.2 to 0.8.3
- [Release notes](https://github.com/tiborschneider/prefix-trie/releases)
- [Commits](https://github.com/tiborschneider/prefix-trie/compare/v0.8.2...v0.8.3)

---
updated-dependencies:
- dependency-name: smoltcp
  dependency-version: 0.13.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
- dependency-name: libc
  dependency-version: 0.2.186
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
- dependency-name: dhcproto
  dependency-version: eece41c9a13b0e4912fb9a8f08401ab01b4123d4
  dependency-type: direct:production
  dependency-group: all-updates
- dependency-name: clap
  dependency-version: 4.6.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
- dependency-name: sentry
  dependency-version: 0.48.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
- dependency-name: sentry-anyhow
  dependency-version: 0.48.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
- dependency-name: prefix-trie
  dependency-version: 0.8.3
  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-05-12 22:23:19 +02:00
dependabot[bot] d806af1f9d Bump the all-updates group with 2 updates (#149)
Bumps the all-updates group with 2 updates: [smoltcp](https://github.com/smoltcp-rs/smoltcp) and [prefix-trie](https://github.com/tiborschneider/prefix-trie).


Updates `smoltcp` from 0.12.0 to 0.13.0
- [Release notes](https://github.com/smoltcp-rs/smoltcp/releases)
- [Changelog](https://github.com/smoltcp-rs/smoltcp/blob/main/CHANGELOG.md)
- [Commits](https://github.com/smoltcp-rs/smoltcp/compare/v0.12.0...v0.13.0)

Updates `prefix-trie` from 0.8.1 to 0.8.2
- [Release notes](https://github.com/tiborschneider/prefix-trie/releases)
- [Commits](https://github.com/tiborschneider/prefix-trie/compare/v0.8.1...v0.8.2)

---
updated-dependencies:
- dependency-name: smoltcp
  dependency-version: 0.13.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
- dependency-name: prefix-trie
  dependency-version: 0.8.2
  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-03-23 16:54:31 +01:00
dependabot[bot] d992da7023 Bump the all-updates group with 4 updates (#147)
Bumps the all-updates group with 4 updates: [clap](https://github.com/clap-rs/clap), [num_enum](https://github.com/illicitonion/num_enum), [sentry](https://github.com/getsentry/sentry-rust) and [sentry-anyhow](https://github.com/getsentry/sentry-rust).


Updates `clap` from 4.5.60 to 4.6.0
- [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.60...clap_complete-v4.6.0)

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

Updates `sentry` from 0.46.2 to 0.47.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.46.2...0.47.0)

Updates `sentry-anyhow` from 0.46.2 to 0.47.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.46.2...0.47.0)

---
updated-dependencies:
- dependency-name: clap
  dependency-version: 4.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
- dependency-name: num_enum
  dependency-version: 0.7.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
- dependency-name: sentry
  dependency-version: 0.47.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
- dependency-name: sentry-anyhow
  dependency-version: 0.47.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>
2026-03-16 12:40:06 +01:00
dependabot[bot] 2e74102ee4 Bump the all-updates group with 2 updates (#146)
Bumps the all-updates group with 2 updates: [libc](https://github.com/rust-lang/libc) and [ipnet](https://github.com/krisprice/ipnet).


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

Updates `ipnet` from 2.11.0 to 2.12.0
- [Release notes](https://github.com/krisprice/ipnet/releases)
- [Changelog](https://github.com/krisprice/ipnet/blob/master/RELEASES.md)
- [Commits](https://github.com/krisprice/ipnet/compare/2.11.0...2.12.0)

---
updated-dependencies:
- dependency-name: libc
  dependency-version: 0.2.183
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
- dependency-name: ipnet
  dependency-version: 2.12.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>
2026-03-09 10:58:27 +01:00
dependabot[bot] 35ae0608db Bump nix from 0.31.1 to 0.31.2 in the all-updates group (#145)
Bumps the all-updates group with 1 update: [nix](https://github.com/nix-rust/nix).


Updates `nix` from 0.31.1 to 0.31.2
- [Changelog](https://github.com/nix-rust/nix/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nix-rust/nix/compare/v0.31.1...v0.31.2)

---
updated-dependencies:
- dependency-name: nix
  dependency-version: 0.31.2
  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-03-02 11:01:12 +01:00
dependabot[bot] 54f40f914b Bump the all-updates group with 3 updates (#144)
Bumps the all-updates group with 3 updates: [clap](https://github.com/clap-rs/clap), [anyhow](https://github.com/dtolnay/anyhow) and [serial_test](https://github.com/palfrey/serial_test).


Updates `clap` from 4.5.58 to 4.5.60
- [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.58...clap_complete-v4.5.60)

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

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

---
updated-dependencies:
- dependency-name: clap
  dependency-version: 4.5.60
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
- dependency-name: anyhow
  dependency-version: 1.0.102
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
- dependency-name: serial_test
  dependency-version: 3.4.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>
2026-02-23 02:12:09 +01:00
dependabot[bot] 088011e714 Bump clap from 4.5.57 to 4.5.58 in the all-updates group (#143)
Bumps the all-updates group with 1 update: [clap](https://github.com/clap-rs/clap).


Updates `clap` from 4.5.57 to 4.5.58
- [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.57...clap_complete-v4.5.58)

---
updated-dependencies:
- dependency-name: clap
  dependency-version: 4.5.58
  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-02-17 14:14:33 +01:00
dependabot[bot] 3cd8732f1c Bump the all-updates group with 4 updates (#142)
Bumps the all-updates group with 4 updates: [clap](https://github.com/clap-rs/clap), [anyhow](https://github.com/dtolnay/anyhow), [sentry](https://github.com/getsentry/sentry-rust) and [sentry-anyhow](https://github.com/getsentry/sentry-rust).


Updates `clap` from 4.5.54 to 4.5.57
- [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.54...clap_complete-v4.5.57)

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

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

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

---
updated-dependencies:
- dependency-name: clap
  dependency-version: 4.5.57
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
- dependency-name: anyhow
  dependency-version: 1.0.101
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
- dependency-name: sentry
  dependency-version: 0.46.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
- dependency-name: sentry-anyhow
  dependency-version: 0.46.2
  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-02-11 13:56:41 +01:00
dependabot[bot] ca15d50f8d Bump time from 0.3.36 to 0.3.44 (#141)
Bumps [time](https://github.com/time-rs/time) from 0.3.36 to 0.3.44.
- [Release notes](https://github.com/time-rs/time/releases)
- [Changelog](https://github.com/time-rs/time/blob/main/CHANGELOG.md)
- [Commits](https://github.com/time-rs/time/compare/v0.3.36...v0.3.44)

---
updated-dependencies:
- dependency-name: time
  dependency-version: 0.3.44
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-05 22:18:49 +01:00
dependabot[bot] 928dc3c333 Bump nix from 0.30.1 to 0.31.1 in the all-updates group (#139)
Bumps the all-updates group with 1 update: [nix](https://github.com/nix-rust/nix).


Updates `nix` from 0.30.1 to 0.31.1
- [Changelog](https://github.com/nix-rust/nix/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nix-rust/nix/compare/v0.30.1...v0.31.1)

---
updated-dependencies:
- dependency-name: nix
  dependency-version: 0.31.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-27 22:39:35 +01:00
dependabot[bot] 62d9326d26 Bump vmnet from 0.5.0 to 0.5.1 in the all-updates group (#138)
Bumps the all-updates group with 1 update: [vmnet](https://github.com/edigaryev/vmnet).


Updates `vmnet` from 0.5.0 to 0.5.1
- [Release notes](https://github.com/edigaryev/vmnet/releases)
- [Commits](https://github.com/edigaryev/vmnet/compare/0.5.0...0.5.1)

---
updated-dependencies:
- dependency-name: vmnet
  dependency-version: 0.5.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-19 14:29:58 +01:00
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
6 changed files with 973 additions and 435 deletions
Generated
+843 -296
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -16,7 +16,7 @@ smoltcp = "0"
libc = "0"
polling = "3"
dhcproto = { git = "https://github.com/bluecatengineering/dhcproto.git", branch = "master" }
vmnet = "0.5.0"
vmnet = "0.5.1"
clap = { version = "4", features = ["derive"] }
mac_address = "1"
privdrop = "0"
@@ -33,6 +33,7 @@ ipnet = "2"
oslog = "0.2.0"
log = "0.4.29"
serial_test = "3"
coarsetime = "0.1.37"
[profile.release]
debug = true
+18 -9
View File
@@ -2,14 +2,22 @@ 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;
@@ -66,7 +75,7 @@ impl DhcpSnooper {
#[derive(Debug)]
pub struct Lease {
address: Ipv4Address,
valid_until: Instant,
valid_until: coarsetime::Instant,
dns_ips: HashSet<Ipv4Address>,
}
@@ -74,7 +83,7 @@ impl 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,
}
}
@@ -84,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 {
+8 -3
View File
@@ -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
+83 -21
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, PrefixMap, PrefixSet};
use prefix_trie::{Prefix, PrefixMap};
use smoltcp::wire::EthernetFrame;
use std::io::ErrorKind;
use std::os::unix::io::{AsRawFd, RawFd};
use std::str::FromStr;
use std::time::Duration;
use vmnet::Batch;
pub struct Proxy<'proxy> {
@@ -31,6 +33,24 @@ pub struct Proxy<'proxy> {
port_forwarder: PortForwarder,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Target {
Prefix(Ipv4Net),
Host,
}
impl FromStr for Target {
type Err = ipnet::AddrParseError;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
if s == "@host" {
return Ok(Target::Host);
}
Ipv4Net::from_str(s).map(Target::Prefix)
}
}
#[derive(Debug, Clone, PartialEq)]
pub(crate) enum Action {
Block,
@@ -42,13 +62,17 @@ impl Proxy<'_> {
vm_fd: RawFd,
vm_mac_address: MacAddress,
vm_net_type: NetType,
allow: PrefixSet<Ipv4Net>,
block: PrefixSet<Ipv4Net>,
allow: Vec<Target>,
block: Vec<Target>,
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 host = Host::new(
vm_net_type,
!allow.contains(&Target::Prefix(Ipv4Net::zero())),
)?;
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
//
@@ -56,12 +80,22 @@ impl Proxy<'_> {
// over allowing rules when prefixes are identical.
let mut rules = PrefixMap::new();
for allow_net in allow {
rules.insert(allow_net, Action::Allow);
for allow_target in allow {
let allow_prefix = match allow_target {
Target::Prefix(prefix) => prefix,
Target::Host => host.gateway_ip.into(),
};
rules.insert(allow_prefix, Action::Allow);
}
for block_net in block {
rules.insert(block_net, Action::Block);
for block_target in block {
let block_prefix = match block_target {
Target::Prefix(prefix) => prefix,
Target::Host => host.gateway_ip.into(),
};
rules.insert(block_prefix, Action::Block);
}
Ok(Proxy {
@@ -69,7 +103,7 @@ impl Proxy<'_> {
host,
poller,
vm_mac_address: smoltcp::wire::EthernetAddress(vm_mac_address.bytes()),
dhcp_snooper: Default::default(),
dhcp_snooper: DhcpSnooper::new(poller_timeout),
rules,
enobufs_encountered: false,
port_forwarder: PortForwarder::new(exposed_ports),
@@ -92,6 +126,9 @@ impl Proxy<'_> {
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())?;
}
@@ -119,6 +156,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)?;
}
@@ -138,6 +178,9 @@ impl Proxy<'_> {
loop {
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)?;
@@ -164,7 +207,7 @@ mod tests {
use ipnet::Ipv4Net;
use mac_address::MacAddress;
use nix::sys::socket::{AddressFamily, SockFlag, SockType, socketpair};
use prefix_trie::{PrefixMap, PrefixSet};
use prefix_trie::PrefixMap;
use serial_test::serial;
use smoltcp::wire::{Ipv4Address, Ipv4Packet};
use std::collections::HashSet;
@@ -208,6 +251,27 @@ mod tests {
assert!(allowed_from_vm_ipv4(&proxy, vm_ip, "33.33.33.34").is_none());
}
#[test]
#[serial]
fn test_allow_host() {
let vm_ip = Ipv4Address::from_str("192.168.0.2").unwrap();
let proxy = create_proxy(vm_ip, vec!["@host"], vec!["0.0.0.0/0"]);
assert_eq!(
proxy.rules,
PrefixMap::from_iter(vec![
(proxy.host.gateway_ip.into(), Action::Allow),
(Ipv4Net::from_str("0.0.0.0/0").unwrap(), Action::Block),
])
);
// Access to global IPs should be disallowed because of --block=0.0.0.0/0
assert!(allowed_from_vm_ipv4(&proxy, vm_ip, "8.8.8.8").is_none());
// Despite the above, access to host IP address should be possible because of --allow=@host
assert!(allowed_from_vm_ipv4(&proxy, vm_ip, &proxy.host.gateway_ip.to_string()).is_some());
}
fn create_proxy<'test>(vm_ip: Ipv4Address, allow: Vec<&str>, block: Vec<&str>) -> Proxy<'test> {
let (vm_fd, _) = socketpair(
AddressFamily::Unix,
@@ -222,16 +286,14 @@ mod tests {
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()),
),
allow
.into_iter()
.map(|cidr| cidr.parse().unwrap())
.collect(),
block
.into_iter()
.map(|cidr| cidr.parse().unwrap())
.collect(),
Vec::default(),
)
.unwrap();
+19 -105
View File
@@ -1,22 +1,19 @@
use anyhow::{Context, Error, anyhow};
use anyhow::{Context, anyhow};
use clap::Parser;
use ipnet::Ipv4Net;
use log::LevelFilter;
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::proxy::Target;
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;
@@ -25,67 +22,6 @@ 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(
@@ -115,32 +51,34 @@ struct Args {
#[clap(
long,
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. \
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), \
plus supported @-aliases. Currently the only supported @-alias is @host, \
which matches the vmnet bridge gateway IP. \
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",
value_name = "comma-separated CIDRs or @-alias",
use_value_delimiter = true,
action = clap::ArgAction::Set
)]
allow: Vec<AllowBlockEntry>,
allow: Vec<Target>,
#[clap(
long,
help = "Comma-separated list of CIDRs, IPs, or domains to block the traffic to \
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). 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",
that is further relaxed with --allow), plus supported @-aliases. \
Currently the only supported @-alias is @host, which matches the vmnet bridge gateway IP. \
When used with --allow, the longest prefix match always wins. \
In case an identical prefix is both --allow'ed and --block'ed, \
blocking will take precedence.",
value_name = "comma-separated CIDRs or @-alias",
use_value_delimiter = true,
action = clap::ArgAction::Set
)]
block: Vec<AllowBlockEntry>,
block: Vec<Target>,
#[clap(
long,
@@ -210,7 +148,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 mut args: Args = Args::parse();
let args: Args = Args::parse();
// No need to run anything, just return
// so that the invoker process knows we
@@ -253,9 +191,6 @@ 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);
@@ -264,8 +199,8 @@ fn try_main() -> anyhow::Result<()> {
args.vm_fd as RawFd,
args.vm_mac_address,
args.vm_net_type,
PrefixSet::from_iter(allow),
PrefixSet::from_iter(block),
args.allow,
args.block,
args.expose,
)
.context("failed to initialize proxy")?;
@@ -317,24 +252,3 @@ 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)))
);
}
}