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
|
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:
|
||||||
|
|
||||||
|
|
49
src/main.rs
49
src/main.rs
|
@ -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,24 +111,38 @@ 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,
|
||||||
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) => {
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue