mirror of
https://github.com/cirruslabs/softnet.git
synced 2026-09-30 20:11:16 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dfc04a49e4 | ||
|
|
7dc5992b55 | ||
|
|
58d4b32258 |
@@ -15,9 +15,6 @@ task:
|
||||
task:
|
||||
alias: Test
|
||||
matrix:
|
||||
- name: Test on macOS Sonoma
|
||||
macos_instance:
|
||||
image: ghcr.io/cirruslabs/macos-runner:sonoma
|
||||
- name: Test on macOS Sequoia
|
||||
macos_instance:
|
||||
image: ghcr.io/cirruslabs/macos-runner:sequoia
|
||||
|
||||
@@ -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
+33
-20
@@ -363,9 +363,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.49"
|
||||
version = "4.5.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4512b90fa68d3a9932cea5184017c5d200f5921df706d45e853537dea51508f"
|
||||
checksum = "0c2cfd7bf8a6017ddaa4e32ffe7403d547790db06bd171c1c53926faab501623"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
@@ -373,9 +373,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.49"
|
||||
version = "4.5.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0025e98baa12e766c67ba13ff4695a887a1eba19569aad00a472546795bd6730"
|
||||
checksum = "0a4c05b9e80c5ccd3a7ef080ad7b6ba7d6fc00a985b8b157197075677c82c7a0"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
@@ -602,21 +602,19 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "dhcproto"
|
||||
version = "0.14.0"
|
||||
source = "git+https://github.com/bluecatengineering/dhcproto.git?branch=master#96a6845f7154a54e9c18d3595807c62e7994d5fe"
|
||||
source = "git+https://github.com/bluecatengineering/dhcproto.git?branch=master#b4ea30defc01e7ae66e7075d6a0533d9bb9503dc"
|
||||
dependencies = [
|
||||
"dhcproto-macros",
|
||||
"hex",
|
||||
"hickory-proto",
|
||||
"ipnet",
|
||||
"rand",
|
||||
"thiserror 2.0.12",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dhcproto-macros"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/bluecatengineering/dhcproto.git?branch=master#96a6845f7154a54e9c18d3595807c62e7994d5fe"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/bluecatengineering/dhcproto.git?branch=master#b4ea30defc01e7ae66e7075d6a0533d9bb9503dc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -1956,6 +1954,15 @@ version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
|
||||
|
||||
[[package]]
|
||||
name = "scc"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46e6f046b7fef48e2660c57ed794263155d713de679057f2d0c169bfc6e756cc"
|
||||
dependencies = [
|
||||
"sdd",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "schannel"
|
||||
version = "0.1.24"
|
||||
@@ -1971,6 +1978,12 @@ 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"
|
||||
@@ -2178,27 +2191,27 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serial_test"
|
||||
version = "0.10.0"
|
||||
version = "3.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c789ec87f4687d022a2405cf46e0cd6284889f1839de292cadeb6c6019506f2"
|
||||
checksum = "1b258109f244e1d6891bf1053a55d63a5cd4f8f4c30cf9a1280989f80e7a1fa9"
|
||||
dependencies = [
|
||||
"dashmap",
|
||||
"futures",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"once_cell",
|
||||
"parking_lot",
|
||||
"scc",
|
||||
"serial_test_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serial_test_derive"
|
||||
version = "0.10.0"
|
||||
version = "3.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b64f9e531ce97c88b4778aad0ceee079216071cffec6ac9b904277f8f92e7fe3"
|
||||
checksum = "5d69265a08751de7844521fd15003ae0a888e035773ba05695c5c759a6f89eef"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
"syn 2.0.101",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2740,9 +2753,9 @@ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
|
||||
[[package]]
|
||||
name = "vmnet"
|
||||
version = "0.4.2"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c96eae216a9fa27c8e458ee5ef56dfc92d43fc8c25d67ade4a7fa83f0cb8b21b"
|
||||
checksum = "4d88878a5583a43715c9f6de9b4cf94bc1af1dfec2a6abd75fd821de623f693b"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"block",
|
||||
@@ -2758,9 +2771,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "vmnet-derive"
|
||||
version = "0.4.2"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa20b8d2b5b0504355848b99b54fda9411f8201f44c1a9ee5a2d3c3134d31297"
|
||||
checksum = "9ee4569490df90dfa2cfeda38230905b2331e72a16fa62a8f5d31069ea024db2"
|
||||
dependencies = [
|
||||
"darling",
|
||||
"proc-macro2",
|
||||
|
||||
+2
-2
@@ -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"
|
||||
@@ -32,7 +32,7 @@ prefix-trie = "0"
|
||||
ipnet = "2"
|
||||
oslog = "0.2.0"
|
||||
log = "0.4.28"
|
||||
serial_test = "0"
|
||||
serial_test = "3"
|
||||
|
||||
[profile.release]
|
||||
debug = true
|
||||
|
||||
+14
-3
@@ -9,7 +9,7 @@ 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,
|
||||
})
|
||||
}
|
||||
@@ -133,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
|
||||
|
||||
+17
-6
@@ -18,6 +18,7 @@ use prefix_trie::{Prefix, PrefixMap, PrefixSet};
|
||||
use smoltcp::wire::EthernetFrame;
|
||||
use std::io::ErrorKind;
|
||||
use std::os::unix::io::{AsRawFd, RawFd};
|
||||
use vmnet::Batch;
|
||||
|
||||
pub struct Proxy<'proxy> {
|
||||
vm: VM,
|
||||
@@ -76,8 +77,16 @@ impl Proxy<'_> {
|
||||
}
|
||||
|
||||
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 {
|
||||
@@ -88,7 +97,7 @@ impl Proxy<'_> {
|
||||
}
|
||||
|
||||
if host_readable {
|
||||
self.read_from_host(buf.as_mut_slice())?;
|
||||
self.read_from_host(&mut batch, &mut bufs)?;
|
||||
}
|
||||
|
||||
// Graceful termination
|
||||
@@ -125,12 +134,14 @@ impl Proxy<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
fn read_from_host(&mut self, buf: &mut [u8]) -> Result<()> {
|
||||
fn read_from_host(&mut self, batch: &mut Batch, bufs: &mut [Vec<u8>]) -> Result<()> {
|
||||
loop {
|
||||
match self.host.read(buf) {
|
||||
Ok(n) => {
|
||||
if let Ok(pkt) = EthernetFrame::new_checked(&buf[..n]) {
|
||||
self.process_frame_from_host(&pkt)?;
|
||||
match self.host.read(batch, bufs) {
|
||||
Ok(pktcnt) => {
|
||||
for buf in batch.packet_sized_bufs(bufs).take(pktcnt) {
|
||||
if let Ok(pkt) = EthernetFrame::new_checked(buf) {
|
||||
self.process_frame_from_host(&pkt)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
|
||||
Reference in New Issue
Block a user