Skip to content

Commit 2eb4c8b

Browse files
committed
fix: set default 30s timeout on guest-created sockets
Adds SOCKET_TIMEOUT (30s) applied to all sockets at creation time via set_read_timeout/set_write_timeout. Also uses connect_timeout in handle_net_connect, releasing the SocketTable lock before the blocking connect call to avoid stalling concurrent socket operations. Includes a unit test that verifies the timeout is actually set. Signed-off-by: danbugs <danilochiarlone@gmail.com>
1 parent 659686a commit 2eb4c8b

1 file changed

Lines changed: 33 additions & 3 deletions

File tree

host/src/lib.rs

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ const MAX_NET_SEND: usize = 1024 * 1024;
9999
/// Cap for `__hl_sleep` duration to prevent unbounded host-thread blocking (60 s).
100100
const MAX_SLEEP_NS: u64 = 60_000_000_000;
101101

102+
/// Default socket timeout for read/write/connect operations (30 s).
103+
const SOCKET_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(30);
104+
102105
/// A preopened host directory exposed to the guest.
103106
///
104107
/// Semantics mirror Wasmtime's `preopened_dir`: `host_dir` is canonicalised
@@ -1192,6 +1195,8 @@ fn handle_net_socket(
11921195
Some(Protocol::from(protocol))
11931196
};
11941197
let sock = Socket::new(domain, stype, proto)?;
1198+
sock.set_read_timeout(Some(SOCKET_TIMEOUT))?;
1199+
sock.set_write_timeout(Some(SOCKET_TIMEOUT))?;
11951200
let fd = table.lock().unwrap().insert(HostSocket {
11961201
socket: sock,
11971202
sock_type,
@@ -1210,9 +1215,11 @@ fn handle_net_connect(
12101215
let addr = parse_sockaddr(args)?;
12111216
policy.check(&addr)?;
12121217
let sa: SockAddr = addr.into();
1213-
let tbl = table.lock().unwrap();
1214-
let sock = tbl.get_socket(fd)?;
1215-
sock.connect(&sa)?;
1218+
let sock = {
1219+
let tbl = table.lock().unwrap();
1220+
tbl.get_socket(fd)?.try_clone()?
1221+
};
1222+
sock.connect_timeout(&sa, SOCKET_TIMEOUT)?;
12161223
Ok(json!({}))
12171224
}
12181225

@@ -3389,4 +3396,27 @@ mod tests {
33893396
al.learn_ip(IpAddr::V4(Ipv4Addr::new(10, 1, 0, 1)));
33903397
assert_eq!(al.learned_ips.lock().unwrap().len(), MAX_LEARNED_IPS);
33913398
}
3399+
3400+
#[test]
3401+
fn net_socket_has_default_timeout() {
3402+
let mut tools = ToolRegistry::new();
3403+
let exit_code = Arc::new(AtomicI32::new(0));
3404+
let table =
3405+
register_internal_tools(&mut tools, &exit_code, Some(&NetworkPolicy::AllowAll), None)
3406+
.expect("network tools should be registered");
3407+
3408+
let req = br#"{"name":"net_socket","args":{"family":2,"type":1}}"#;
3409+
let resp = tools.dispatch(req);
3410+
let s = std::str::from_utf8(&resp).unwrap();
3411+
assert!(!s.contains("error"), "socket creation should succeed: {s}");
3412+
3413+
let v: serde_json::Value = serde_json::from_str(s).unwrap();
3414+
let fd = v["result"]["fd"].as_u64().unwrap();
3415+
assert!(fd > 0);
3416+
3417+
let tbl = table.lock().unwrap();
3418+
let sock = tbl.get_socket(fd).unwrap();
3419+
assert_eq!(sock.read_timeout().unwrap(), Some(SOCKET_TIMEOUT));
3420+
assert_eq!(sock.write_timeout().unwrap(), Some(SOCKET_TIMEOUT));
3421+
}
33923422
}

0 commit comments

Comments
 (0)