rust-http2
                                
                                 rust-http2 copied to clipboard
                                
                                    rust-http2 copied to clipboard
                            
                            
                            
                        Connect to multiple addresses
Currently Client connects to single address, first address name resolved to.
Instead, client should attempt to connect to several addresses: both IPv4 and IPv6, and to multiple addresses resolved by DNS.
As of today's HEAD, it seems to panic instead, which is much worse:
% cargo run --example client https://fau.xxx/
    Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
     Running `target/debug/examples/client 'https://fau.xxx/'`
thread 'main' panicked at 'client: Other("addr is resolved to more than one addr")', /checkout/src/libcore/result.rs:860:4
note: Run with `RUST_BACKTRACE=1` for a backtrace.
Seems to have been intentionally broken here: https://github.com/stepancheg/rust-http2/commit/b7e1e4ad77aec26972df0e72f9ea6f4f43f12b29#diff-31bbf71c54bca98a0ae3d40a327af940L70
@FauxFaux I believe, it does not panic, it returns Err.
What would be the best way to solve this problem? It seems like the simplest solution would be to choose a random address from the list. Could it also be added as an option to have it just choose the first address that it resolves to?
Currently this is a blocking issue for one of my projects, and I would be interested in contributing a solution.
First, as a workaround, you can resolve addr yourself, and call set_addr with the resolved address (IP address instead of hostname).
About proper solution.
As I said, "client should attempt to connect to several addresses".
ClientBuilder.addr field should be changed to Vec<AnySocketAddr>, and this line in client_conn.rs
        let connect = addr.connect(&lh).map_err(Into::into);
should be changed to connect concurrently to multiple addresses instead of one.
Alternatively, a single-connection client (ClientConn) can be exposed as public API so a user could connect to proper address themselves and create a client with an already configured socket.
My worry with that workaround is that I need the Authority header to be set properly. If I manually resolve it will just be set to the ip right?
Is it generally the correct behavior to connect to all of the IPs resolved by the DNS query? RFC8305 seems to indicate that some sort of sorting algorithm should be used then they should connected to in order.
I thought (and might be wrong) that when a DNS record resolved to multiple IPs it was to provide round robin load balancing and graceful failover, wouldn't simultaneously connecting break that down? Or would the goal be to race the connection futures and pick whichever resolves first?
My worry with that workaround is that I need the Authority header to be set properly. If I manually resolve it will just be set to the ip right?
Authority is passed explicitly to each client call, e. g.
impl Client { ... 
    pub fn start_get(
        &self,
        path: &str,
        authority: &str)
            -> Response { ... }
}
Is it generally the correct behavior to connect to all of the IPs resolved by the DNS query? RFC8305 seems to indicate that some sort of sorting algorithm should be used then they should connected to in order.
Yep, using the algorithm like that or having a configuration option specifying connect strategy should be the right thing, but for the starters connecting to multiple addresses concurrently is acceptable I think.
I thought (and might be wrong) that when a DNS record resolved to multiple IPs it was to provide round robin load balancing and graceful failover, wouldn't simultaneously connecting break that down? Or would the goal be to race the connection futures and pick whichever resolves first?
I think that multiple IP addresses could be used for failover. So as before I think the proper strategy is to connect to the first address, and after a failure or after small timeout connect to second address etc.
But I'm not an expert, I can be wrong.
Any update on this? Not being able to connect to hosts with multiple addresses (without manually resolving first) is a pain for many services.