Skip to content

Commit 1b28cbd

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 b69cdbf commit 1b28cbd

1 file changed

Lines changed: 37 additions & 3 deletions

File tree

host/src/lib.rs

Lines changed: 37 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
@@ -1187,6 +1190,8 @@ fn handle_net_socket(
11871190
Some(Protocol::from(protocol))
11881191
};
11891192
let sock = Socket::new(domain, stype, proto)?;
1193+
sock.set_read_timeout(Some(SOCKET_TIMEOUT))?;
1194+
sock.set_write_timeout(Some(SOCKET_TIMEOUT))?;
11901195
let fd = table.lock().unwrap().insert(HostSocket {
11911196
socket: sock,
11921197
sock_type,
@@ -1205,9 +1210,11 @@ fn handle_net_connect(
12051210
let addr = parse_sockaddr(args)?;
12061211
policy.check(&addr)?;
12071212
let sa: SockAddr = addr.into();
1208-
let tbl = table.lock().unwrap();
1209-
let sock = tbl.get_socket(fd)?;
1210-
sock.connect(&sa)?;
1213+
let sock = {
1214+
let tbl = table.lock().unwrap();
1215+
tbl.get_socket(fd)?.try_clone()?
1216+
};
1217+
sock.connect_timeout(&sa, SOCKET_TIMEOUT)?;
12111218
Ok(json!({}))
12121219
}
12131220

@@ -3369,4 +3376,31 @@ mod tests {
33693376
"expected 'too large' error for net_sendto, got: {resp}"
33703377
);
33713378
}
3379+
3380+
#[test]
3381+
fn net_socket_has_default_timeout() {
3382+
let mut tools = ToolRegistry::new();
3383+
let exit_code = Arc::new(AtomicI32::new(0));
3384+
let table = register_internal_tools(
3385+
&mut tools,
3386+
&exit_code,
3387+
Some(&NetworkPolicy::AllowAll),
3388+
None,
3389+
)
3390+
.expect("network tools should be registered");
3391+
3392+
let req = br#"{"name":"net_socket","args":{"family":2,"type":1}}"#;
3393+
let resp = tools.dispatch(req);
3394+
let s = std::str::from_utf8(&resp).unwrap();
3395+
assert!(!s.contains("error"), "socket creation should succeed: {s}");
3396+
3397+
let v: serde_json::Value = serde_json::from_str(s).unwrap();
3398+
let fd = v["result"]["fd"].as_u64().unwrap();
3399+
assert!(fd > 0);
3400+
3401+
let tbl = table.lock().unwrap();
3402+
let sock = tbl.get_socket(fd).unwrap();
3403+
assert_eq!(sock.read_timeout().unwrap(), Some(SOCKET_TIMEOUT));
3404+
assert_eq!(sock.write_timeout().unwrap(), Some(SOCKET_TIMEOUT));
3405+
}
33723406
}

0 commit comments

Comments
 (0)