|
1 | 1 | use crate::common::{Profile, RunCommon, RunTarget}; |
2 | 2 | use anyhow::{anyhow, bail, Result}; |
3 | 3 | use clap::Parser; |
| 4 | +use std::net::SocketAddr; |
4 | 5 | use std::{ |
5 | 6 | path::PathBuf, |
6 | 7 | sync::{ |
@@ -64,7 +65,7 @@ pub struct ServeCommand { |
64 | 65 |
|
65 | 66 | /// Socket address for the web server to bind to. |
66 | 67 | #[arg(long = "addr", value_name = "SOCKADDR", default_value_t = DEFAULT_ADDR )] |
67 | | - addr: std::net::SocketAddr, |
| 68 | + addr: SocketAddr, |
68 | 69 |
|
69 | 70 | /// The WebAssembly component to run. |
70 | 71 | #[arg(value_name = "WASM", required = true)] |
@@ -262,7 +263,17 @@ impl ServeCommand { |
262 | 263 |
|
263 | 264 | let instance = linker.instantiate_pre(&component)?; |
264 | 265 |
|
265 | | - let listener = tokio::net::TcpListener::bind(self.addr).await?; |
| 266 | + // Tokio by default sets `SO_REUSEADDR` for listeners but that makes it |
| 267 | + // a bit confusing if you run Wasmtime but forget to close a previous |
| 268 | + // `serve` session. To avoid that we explicitly disable `SO_REUSEADDR` |
| 269 | + // here. |
| 270 | + let socket = match &self.addr { |
| 271 | + SocketAddr::V4(_) => tokio::net::TcpSocket::new_v4()?, |
| 272 | + SocketAddr::V6(_) => tokio::net::TcpSocket::new_v6()?, |
| 273 | + }; |
| 274 | + socket.set_reuseaddr(false)?; |
| 275 | + socket.bind(self.addr)?; |
| 276 | + let listener = socket.listen(100)?; |
266 | 277 |
|
267 | 278 | eprintln!("Serving HTTP on http://{}/", listener.local_addr()?); |
268 | 279 |
|
|
0 commit comments