listen on multiple addresses concurrently
This commit is contained in:
parent
f31b973435
commit
7a26b7c011
10
README.md
10
README.md
|
@ -27,13 +27,18 @@ Usage
|
|||
Use `opal -h` to get a list of options. There is no config file, every setting
|
||||
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.
|
||||
- `-k, --key <key>`: server private key path.
|
||||
- `-r, --root-path <root_path>`: path to CGI scripts root.
|
||||
- `-e, --env <key=value>`: additional environment variables for CGI scripts;
|
||||
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
|
||||
|
@ -103,9 +108,8 @@ Roadmap
|
|||
|
||||
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.
|
||||
- Chroot; quite cheap and can bring a bit of peace of mind.
|
||||
|
||||
Things that probably won't be considered:
|
||||
|
||||
|
|
49
src/main.rs
49
src/main.rs
|
@ -41,7 +41,8 @@ fn run() -> Result<(), i32> {
|
|||
.short("a")
|
||||
.long("address")
|
||||
.help("Address to listen to")
|
||||
.takes_value(true),
|
||||
.takes_value(true)
|
||||
.multiple(true),
|
||||
)
|
||||
.arg(
|
||||
clap::Arg::with_name("cert")
|
||||
|
@ -110,24 +111,38 @@ fn run() -> Result<(), i32> {
|
|||
)
|
||||
.map_err(|err| run_failure("Can't create TLS acceptor", &err))?;
|
||||
|
||||
let address = matches.value_of("address").unwrap();
|
||||
let listener = net::TcpListener::bind(address)
|
||||
.map_err(|err| run_failure("Can't create TCP listener", &err))?;
|
||||
|
||||
for stream in listener.incoming() {
|
||||
match stream {
|
||||
Ok(stream) => {
|
||||
let acceptor = acceptor.clone();
|
||||
let cgi_config = cgi_config.clone();
|
||||
thread::spawn(move || match acceptor.accept(stream) {
|
||||
Ok(mut tls_stream) => handle_client(&mut tls_stream, &cgi_config),
|
||||
Err(err) => error!("Can't initiate TLS stream: {}", err),
|
||||
});
|
||||
}
|
||||
let mut threads = vec![];
|
||||
for address in matches.values_of("address").unwrap() {
|
||||
let listener = match net::TcpListener::bind(address) {
|
||||
Ok(l) => l,
|
||||
Err(err) => {
|
||||
error!("Can't accept connection: {}", 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() {
|
||||
match stream {
|
||||
Ok(stream) => {
|
||||
let acceptor = acceptor.clone();
|
||||
let cgi_config = cgi_config.clone();
|
||||
thread::spawn(move || match acceptor.accept(stream) {
|
||||
Ok(mut tls_stream) => handle_client(&mut tls_stream, &cgi_config),
|
||||
Err(err) => error!("Can't initiate TLS stream: {}", err),
|
||||
});
|
||||
}
|
||||
Err(err) => {
|
||||
error!("Can't accept connection: {}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
for t in threads.into_iter() {
|
||||
t.join().unwrap();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
Reference in a new issue