Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connect to multiple addresses #7

Open
stepancheg opened this issue May 17, 2017 · 7 comments
Open

Connect to multiple addresses #7

stepancheg opened this issue May 17, 2017 · 7 comments

Comments

@stepancheg
Copy link
Owner

stepancheg commented May 17, 2017

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.

@FauxFaux
Copy link

FauxFaux commented Sep 13, 2017

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:
b7e1e4a#diff-31bbf71c54bca98a0ae3d40a327af940L70

@stepancheg
Copy link
Owner Author

@FauxFaux I believe, it does not panic, it returns Err.

@sphw
Copy link

sphw commented Jun 9, 2018

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.

@stepancheg
Copy link
Owner Author

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.

@sphw
Copy link

sphw commented Jun 9, 2018

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?

@stepancheg
Copy link
Owner Author

stepancheg commented Jun 9, 2018

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.

@qwandor
Copy link

qwandor commented Oct 26, 2018

Any update on this? Not being able to connect to hosts with multiple addresses (without manually resolving first) is a pain for many services.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants