listen on multiple addresses concurrently

This commit is contained in:
dece 2021-12-17 19:54:54 +01:00
parent f31b973435
commit 7a26b7c011
2 changed files with 39 additions and 20 deletions

View file

@ -27,13 +27,18 @@ Usage
Use `opal -h` to get a list of options. There is no config file, every setting Use `opal -h` to get a list of options. There is no config file, every setting
can be configured from the command line. can be configured from the command line.
- `-a, --address <address>`: specify the address to listen to. - `-a, --address <address>`: specify the address(es) to listen to.
- `-c, --cert <cert>`: server certificate path. - `-c, --cert <cert>`: server certificate path.
- `-k, --key <key>`: server private key path. - `-k, --key <key>`: server private key path.
- `-r, --root-path <root_path>`: path to CGI scripts root. - `-r, --root-path <root_path>`: path to CGI scripts root.
- `-e, --env <key=value>`: additional environment variables for CGI scripts; - `-e, --env <key=value>`: additional environment variables for CGI scripts;
this option can be used multiple times. this option can be used multiple times.
You can specify multiple addresses to listen to by using several `-a` options.
Note that if you just want to listen to both IPv4 and IPv6 on any interface,
listening only on `[::]:1965` should suffice for systems with dual-stack
enabled (default on many Linux systems, maybe not BSD).
CGI support CGI support
@ -103,9 +108,8 @@ Roadmap
Things to consider: Things to consider:
- Multiple listening addresses, at least so we can easily listen on both IPv4
and IPv6.
- Support SCGI; a bit more complex but should save resources on smol hardware. - Support SCGI; a bit more complex but should save resources on smol hardware.
- Chroot; quite cheap and can bring a bit of peace of mind.
Things that probably won't be considered: Things that probably won't be considered:

View file

@ -41,7 +41,8 @@ fn run() -> Result<(), i32> {
.short("a") .short("a")
.long("address") .long("address")
.help("Address to listen to") .help("Address to listen to")
.takes_value(true), .takes_value(true)
.multiple(true),
) )
.arg( .arg(
clap::Arg::with_name("cert") clap::Arg::with_name("cert")
@ -110,10 +111,19 @@ fn run() -> Result<(), i32> {
) )
.map_err(|err| run_failure("Can't create TLS acceptor", &err))?; .map_err(|err| run_failure("Can't create TLS acceptor", &err))?;
let address = matches.value_of("address").unwrap(); let mut threads = vec![];
let listener = net::TcpListener::bind(address) for address in matches.values_of("address").unwrap() {
.map_err(|err| run_failure("Can't create TCP listener", &err))?; let listener = match net::TcpListener::bind(address) {
Ok(l) => l,
Err(err) => {
error!("Can't create TCP listener: {}", &err);
continue
}
};
info!("Listening on {}", address);
let acceptor = acceptor.clone();
let cgi_config = cgi_config.clone();
threads.push(thread::spawn(move || {
for stream in listener.incoming() { for stream in listener.incoming() {
match stream { match stream {
Ok(stream) => { Ok(stream) => {
@ -129,6 +139,11 @@ fn run() -> Result<(), i32> {
} }
} }
} }
}));
}
for t in threads.into_iter() {
t.join().unwrap();
}
Ok(()) Ok(())
} }