Sockets: running actors get TCP, UDP, and DNS through wasi:sockets; candidates get no network

This commit is contained in:
2026-10-15 19:27:45 +01:00
parent c636eb0803
commit 285f77a9e2
7 changed files with 62 additions and 11 deletions
+13
View File
@@ -16,6 +16,15 @@ fn reply(out: &mut impl Write, message: &Value, body: Value) {
);
}
/// Connect to `address`, send one line, and return the line that comes back.
fn tcp_line(address: &str, line: &str) -> io::Result<String> {
let mut stream = std::net::TcpStream::connect(address)?;
writeln!(stream, "{line}")?;
let mut answer = String::new();
io::BufReader::new(stream).read_line(&mut answer)?;
Ok(answer.trim_end().to_string())
}
fn io_error(error: io::Error) -> Value {
json!({"type": "error", "error": error.to_string()})
}
@@ -131,6 +140,10 @@ fn main() {
json!({"type": "armed"})
}
Some("ignore-stdin") => json!({"type": "ignoring"}),
Some("tcp") => match tcp_line(body["address"].as_str().unwrap_or_default(), text) {
Ok(line) => json!({"type": "tcp", "line": line}),
Err(error) => io_error(error),
},
Some("read") => match std::fs::read_to_string(&path) {
Ok(text) => json!({"type": "content", "text": text}),
Err(error) => io_error(error),
+31
View File
@@ -831,3 +831,34 @@ async fn candidates_receive_version_and_preexisting_spawn_state() {
assert_eq!(successful, 2);
host.stop().await;
}
#[tokio::test]
async fn running_actors_have_sockets_and_candidates_do_not() {
// A TCP server on the host that answers each line with "echo: <line>".
let listener = tokio::net::TcpListener::bind("127.0.0.1:0").await.unwrap();
let address = listener.local_addr().unwrap().to_string();
tokio::spawn(async move {
while let Ok((stream, _)) = listener.accept().await {
tokio::spawn(async move {
use tokio::io::{AsyncBufReadExt, AsyncWriteExt};
let (read, mut write) = stream.into_split();
let mut lines = tokio::io::BufReader::new(read).lines();
while let Ok(Some(line)) = lines.next_line().await {
let _ = write.write_all(format!("echo: {line}\n").as_bytes()).await;
}
});
}
});
let world = create_world("sockets");
let wasm = toolbox_wasm().clone();
let (host, mut mailbox) = start(&world).await;
let tcp = json!({"type": "tcp", "address": address, "text": "hi"});
// The candidate test expects the connection to fail.
let offline = source_with_test(&world, "offline", json!({"steps": [{"send": tcp, "expect": {"type": "error"}}]}));
assert_eq!(spawn_actor(&host, &mut mailbox, "net", &wasm, &offline).await.body["type"], "spawned");
let answer = ask(&host, &mut mailbox, "net", tcp).await;
assert_eq!(answer.body, json!({"type": "tcp", "line": "echo: hi"}));
host.stop().await;
}