Skip to content

Commit 4c053f6

Browse files
authored
Merge pull request #65 from hyperlight-dev/fix/socket-timeouts
fix: set default 30s timeout on guest-created sockets
2 parents f096ea1 + 5af8e1f commit 4c053f6

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
@@ -108,6 +108,9 @@ const MAX_DISPATCH_PAYLOAD: usize = 64 * 1024 * 1024;
108108
/// Cap for `__hl_sleep` duration to prevent unbounded host-thread blocking (60 s).
109109
const MAX_SLEEP_NS: u64 = 60_000_000_000;
110110

111+
/// Default socket timeout for read/write/connect operations (30 s).
112+
const SOCKET_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(30);
113+
111114
/// A preopened host directory exposed to the guest.
112115
///
113116
/// Semantics mirror Wasmtime's `preopened_dir`: `host_dir` is canonicalised
@@ -1211,6 +1214,8 @@ fn handle_net_socket(
12111214
Some(Protocol::from(protocol))
12121215
};
12131216
let sock = Socket::new(domain, stype, proto)?;
1217+
sock.set_read_timeout(Some(SOCKET_TIMEOUT))?;
1218+
sock.set_write_timeout(Some(SOCKET_TIMEOUT))?;
12141219
let fd = table.lock().unwrap().insert(HostSocket {
12151220
socket: sock,
12161221
sock_type,
@@ -1229,9 +1234,11 @@ fn handle_net_connect(
12291234
let addr = parse_sockaddr(args)?;
12301235
policy.check(&addr)?;
12311236
let sa: SockAddr = addr.into();
1232-
let tbl = table.lock().unwrap();
1233-
let sock = tbl.get_socket(fd)?;
1234-
sock.connect(&sa)?;
1237+
let sock = {
1238+
let tbl = table.lock().unwrap();
1239+
tbl.get_socket(fd)?.try_clone()?
1240+
};
1241+
sock.connect_timeout(&sa, SOCKET_TIMEOUT)?;
12351242
Ok(json!({}))
12361243
}
12371244

@@ -3435,4 +3442,27 @@ mod tests {
34353442
al.learn_ip(IpAddr::V4(Ipv4Addr::new(10, 1, 0, 1)));
34363443
assert_eq!(al.learned_ips.lock().unwrap().len(), MAX_LEARNED_IPS);
34373444
}
3445+
3446+
#[test]
3447+
fn net_socket_has_default_timeout() {
3448+
let mut tools = ToolRegistry::new();
3449+
let exit_code = Arc::new(AtomicI32::new(0));
3450+
let table =
3451+
register_internal_tools(&mut tools, &exit_code, Some(&NetworkPolicy::AllowAll), None)
3452+
.expect("network tools should be registered");
3453+
3454+
let req = br#"{"name":"net_socket","args":{"family":2,"type":1}}"#;
3455+
let resp = tools.dispatch(req);
3456+
let s = std::str::from_utf8(&resp).unwrap();
3457+
assert!(!s.contains("error"), "socket creation should succeed: {s}");
3458+
3459+
let v: serde_json::Value = serde_json::from_str(s).unwrap();
3460+
let fd = v["result"]["fd"].as_u64().unwrap();
3461+
assert!(fd > 0);
3462+
3463+
let tbl = table.lock().unwrap();
3464+
let sock = tbl.get_socket(fd).unwrap();
3465+
assert_eq!(sock.read_timeout().unwrap(), Some(SOCKET_TIMEOUT));
3466+
assert_eq!(sock.write_timeout().unwrap(), Some(SOCKET_TIMEOUT));
3467+
}
34383468
}

0 commit comments

Comments
 (0)