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

Please add option to force resolve DNS address by using IPv4 or IPv6 #22089

Closed
vdjuric opened this issue Jun 1, 2017 · 16 comments
Closed

Please add option to force resolve DNS address by using IPv4 or IPv6 #22089

vdjuric opened this issue Jun 1, 2017 · 16 comments
Labels
api-needs-work API needs work before it is approved, it is NOT ready for implementation area-System.Net.Http
Milestone

Comments

@vdjuric
Copy link
Contributor

vdjuric commented Jun 1, 2017

For example, this is supported by CURL with command line parameters -4, --ipv4 and -6, --ipv6 (https://curl.haxx.se/docs/manpage.html#-6)
This parameter would probably be in HttpClientHandler class with default value set to IPv4.

One could resolve IP address manually by calling System.Net.Dns.GetHostAddressesAsync and use this in Uri.Host, but there can be issues when connecting to servers with HTTPS protocol.

@PeterSmithRedmond
Copy link

Can you speak to why you would find this useful? Most of the IPv4/IPv6 kinks have been worked out, and tons of people can connect without specifying IPv4 versus IPv6. in this case, the OS should automatically get both the IPv4 and IPv6 addresses for the host and then pick the "best" one. In some cases, that will be the IPv4 address, and in some case (like the newer Cell networks) it will be the IPv6 address.

What kind of network are your customers on such that the wrong IP address is being picked?

@vdjuric
Copy link
Contributor Author

vdjuric commented Jun 2, 2017

This is just an idea to make API more powerful (maybe this could be long-term plan). Similar like user can choose HTTP Version (1.0, 1.1, 2.0), it would be also nice if IP version could be explicitly set.

And default value should be probably "Auto" and not "IPv4". Auto setting would behave like current version (probably takes first record from DNS server regardless if it IPv4 or IPv6).

On .NET Core for Unix which uses CURL, I think this change would be easy because CURL already supports this.

Another (even more poweful) idea for hostname resolving would be as following:

  • user could optionally set non-static property httpClientHandlerInstance.ResolveHostAddressAsync
  • ResolveHostAddressAsync would accept delegate with signature similar to System.Net.Dns.GetHostAddressesAsync but instead of array of addresses it would return single address: System.Threading.Tasks.Task<System.Net.IPAddress>
  • this IP address would then be used when establishing connection with server
  • by default this ResolveHostAddressAsync property would be null (current behaviour)
  • user could then easily setup custom resolving logic which would be very powerful feature
    • for example, one could use for integration testing production URLs on HttpClient, but ResolveHostAddressAsync would resolve it to test IP (instead of production)

What do you think?

@vdjuric
Copy link
Contributor Author

vdjuric commented Jun 2, 2017

Update:

Good thing about second idea is that:

  • it automatically solves initial problem (no need to set IPv4 or IPv6)
  • if this feature is used, IP resolution is then completely on user of the HttpClient library (they can't "blame" you for any issues)

@vdjuric
Copy link
Contributor Author

vdjuric commented Jun 2, 2017

Bonus: with this user could also achieve 100% same IP resolution regardless of underlying operating system

@svick
Copy link
Contributor

svick commented Jun 2, 2017

This is just an idea to make API more powerful

That doesn't sound like a good enough reason to me. Can you describe a situation when someone would actually use this?

@vdjuric
Copy link
Contributor Author

vdjuric commented Jun 2, 2017

  • unit/integration testing (production URLs resolve to test IPs)
  • IP would always be resolved same regardless of operating system (consistency)
  • possible to choose between IPv4 / IPv6 addresses by querying DNS server directly
  • possible to implement custom caching of resolved IP addresses, not relying on operating system DNS caching
  • one could easily create programmatic round-robin strategy built into their client library to access web services by using different IP address each time
  • more robust client libraries: if server resources are accessible on multiple IP addresses, you could quickly ping each server before resolving IP address, making sure it is healthy. This way you would always return only working IP address
  • ...

Again, this is just an idea. You would have to explicitly "turn on" this feature to use it, so backward compatibility would not be an issue.

Please close this if you think it is not relevant :)

@wernerb90
Copy link

Did anything come of this suggestion?

I would +1 to the feature of adding something similar to curl's --resolve, to manually put an IP address behind a hostname.

@geoffkizer
Copy link
Contributor

Adding something like a ResolveHostAddress hook does seem interesting. At this point I don't think it's a priority, but it's something to consider for the future.

Note we would probably only support this in the managed handler, since for winhttp and curl the DNS lookup is handled by the underlying library.

@vdjuric
Copy link
Contributor Author

vdjuric commented Jan 16, 2018

Sounds good! I will look into managed implementation of HttpClient and try to prepare prototype.

@vdjuric
Copy link
Contributor Author

vdjuric commented Jan 20, 2018

I am currently playing with HttpRequestMessage class. Just for test I added new property:

  • AddressFamily? DnsResolveAddressFamily {get;set;}

(AddressFamily? = null would mean current default behaviour) and updated System.Net.Http.ConnectHelper to pass this parameter.

Now I need to test this but I am having DLL conflicts with official .NET Core System.Net.Http library :)
Will spend some more time :)

@vdjuric
Copy link
Contributor Author

vdjuric commented Jan 20, 2018

Supported values for DnsResolveAddressFamily would be:

  • AddressFamily.InterNetwork (IPv4)
  • AddressFamily.InterNetworkV6 (IPv6)
  • null (default behaviour)

@vdjuric
Copy link
Contributor Author

vdjuric commented Jan 20, 2018

Possible alternative for null: AddressFamily.Unspecified

@PaulDotNet
Copy link

This is badly needed. IPv4 vs IPv6 kinks are not worked out at least when it comes to VPN clients.

Git credential manager is failing because standard IP address resolution does not always work right.

@karelz
Copy link
Member

karelz commented Oct 10, 2019

Triage: We believe this should be addressed by dotnet/corefx#35404.

@karelz karelz closed this as completed Oct 10, 2019
@karelz
Copy link
Member

karelz commented Oct 10, 2019

Duplicate of dotnet/corefx#35404

@msftgits msftgits transferred this issue from dotnet/corefx Jan 31, 2020
@msftgits msftgits added this to the 5.0 milestone Jan 31, 2020
@scalablecory
Copy link
Contributor

This has been resolved via the API added here in .NET 5: #41949

@ghost ghost locked as resolved and limited conversation to collaborators Dec 22, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api-needs-work API needs work before it is approved, it is NOT ready for implementation area-System.Net.Http
Projects
None yet
Development

No branches or pull requests

9 participants