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

net: default dialer should accept list of IPs with fallback included #20782

Open
AlmogBaku opened this Issue Jun 24, 2017 · 11 comments

Comments

Projects
None yet
5 participants
@AlmogBaku

AlmogBaku commented Jun 24, 2017

Please answer these questions before submitting your issue. Thanks!

What version of Go are you using (go version)?

master

What did you do?

  1. In case you want to implement/extend your own dialer you might want to use the original dialer to handle all the TCP/UDP connection, but to still resolve the DNS.. in this scenario you can't wrap it and just send list of IPs because it won't use fallbacks
  2. In case you want to dial IP with fallbacks you can't do that.

What did you expect to see?

func (d *Dialer) DialContext(ctx context.Context, network string, addresses []string) (Conn, error) will accept list of addresses

Or at least

func (d *Dialer) DialContextWithFallbacks(ctx context.Context, network string, addresses []string) (Conn, error)

@bradfitz

This comment has been minimized.

Member

bradfitz commented Jun 24, 2017

I'm not sure I understand your problem enough yet to start discussion solutions yet.

Can you elaborate?

/cc @mikioh

@bradfitz bradfitz added this to the Unplanned milestone Jun 24, 2017

@AlmogBaku

This comment has been minimized.

AlmogBaku commented Jun 24, 2017

This feature enables few scenarios:

  1. My current issue - I want to create a custom dialer, that resolves the hostname, filter it results, and then dial to it. If i'll just use any other dialer i'll lose the option to have fallback IPs, or I'll have to implement it myself.
func DialContext(ctx context.Context, network, address string) (net.Conn, error) {
	ips, err := net.LookupIP(address)
	if err != nil {
		panic(err)
	}
	
	// Now we want to dial at least one of these IPs
}
  1. Allowing dialing list of IPs without hostname (this will call the primary IPs, and will try to reach at least one connection.. otherwise it'll fall to the fallback IPs)
@AlmogBaku

This comment has been minimized.

AlmogBaku commented Jun 24, 2017

If you'll take a look at the Default Dialer, you can see that after it resolves the IPs it dial them and try to reach at least one of them:
https://github.com/golang/go/blob/master/src/net/dial.go#L394

In case you want to do the same with IPs, you can't do that without implementing the whole dialer by yourself (or at least copying it)

@as

This comment has been minimized.

Contributor

as commented Jun 24, 2017

Based on context, it seems the proposal is to expose the behavior of concurrent name resolution and subsequent connection attempts by allowing a list of addresses to be passed in to DialContext instead of just one address (please correct me if I'm wrong). This change implies that addresses in this list are all IP addresses that do not require name resolution. One concern I have is what happens when []address contains names that need to be resolved too?

@AlmogBaku

This comment has been minimized.

AlmogBaku commented Jun 24, 2017

@as we can either expose the dialer of the steps other the resolution(then DialerContext() will call DialerContextWithFallbacks()) or to flatten the list of hosts.

Obviously the second one will introduce breaking news, so the first option is just easier to implement

@mikioh

This comment has been minimized.

Contributor

mikioh commented Aug 2, 2017

@AlmogBaku,

I'm still not sure what is you really want but it looks like you want to use some internal functionality of the net package; it's probably part of TCP connection setup methods for RFC 3493-style (iterating each IP address) and RFC 6555-style (Happy Eyeballs).

FWIW, the Happy Eyeballs method will be updated to version 2 not far in future: https://tools.ietf.org/html/draft-ietf-v6ops-rfc6555bis.

As the I-D (6555bis) section 2 "Overview" describes, the connection setup methods comprise of distinct phases. I don't understand whether you want to make some tailor-made connection setup API just for your use case, or you want to make a bit flexible API that allows you to compose the distinct phases with concurrency support under your control. I personally much prefer the latter rather than the former.

@jfesler

This comment has been minimized.

jfesler commented Jun 21, 2018

This issue interests me as well. I'd like to do DNS caching before dialing; and I'll lose all the wonderful happy eyeballs behavior if I can only send a single (resolved and cached) IP address. I'd rather pass the full list.

My alternative is to duplicate dial.go (and then track changes over go releases), with some kind of wrapper around resolveAddrList.

@AlmogBaku

This comment has been minimized.

AlmogBaku commented Jun 22, 2018

@bradfitz how can i help fill the gaps?

@bradfitz

This comment has been minimized.

Member

bradfitz commented Jun 22, 2018

In Go 1.9 we added https://golang.org/pkg/net/#Resolver.Dial to control how a DNS connection is created. You can use that to create a fake in-memory DNS connection that returns any A and/or AAAA records you want, and then use that Resolver with your *net.Dialer.

You can use the https://godoc.org/golang.org/x/net/dns/dnsmessage package to serialize the records in your net.Conn implementation.

@bradfitz

This comment has been minimized.

Member

bradfitz commented Jun 22, 2018

Actually, #12503 and https://golang.org/cl/115855 will make this even easier. So maybe you just wait for that.

@AlmogBaku

This comment has been minimized.

AlmogBaku commented Jun 25, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment