Skip to content

[✨ Triage] dotnet/runtime#120168 by billpg - [API Proposal]: Allow a custom IP lookup function for HttpClient. #1542

@MihuBot

Description

@MihuBot

Triage for dotnet/runtime#120168.
Repo filter: All networking issues.
MihuBot version: 554101.
Ping MihaZupan for any issues.

This is a test triage report generated by AI, aimed at helping the triage team quickly identify past issues/PRs that may be related.
Take any conclusions with a large grain of salt.

Tool logs
dotnet/runtime#120168: [API Proposal]: Allow a custom IP lookup function for `HttpClient`. by billpg
[Tool] Searching for custom DNS resolution HttpClient, SocketsHttpHandler DNS delegate, HttpClient custom IP lookup, HttpClient DNS policy, SocketsHttpHandler IP address resolution (IncludeOpen=True, IncludeClosed=True, IncludeIssues=True, IncludePullRequests=True, Repository=dotnet/runtime)
[Tool] Found 33 issues, 411 comments, 30 returned results (7836 ms)

Here are the most relevant related issues and discussions for issue #120168, "[API Proposal]: Allow a custom IP lookup function for HttpClient":


1. Issue #25401 (March 2018) - "Option to have more control when resolving endpoint IP address in SocketsHttpHandler"

Summary:
This issue proposed adding a delegate to SocketsHttpHandler to allow custom endpoint resolution, very similar to the current proposal. The discussion covers:

  • API shape (initially proposed as Func<HttpRequestMessage, string, int, CancellationToken, ValueTask<IPEndPoint>> ResolveEndpointAsync)
  • Use cases: custom DNS, round-robin, IPv4/IPv6 control, test overrides.
  • Concerns about whether the delegate should be per-request or per-connection (due to pooling).
  • The conclusion was that returning an array of IPAddress (like Dns.GetHostAddressesAsync) is preferable for flexibility.
  • The issue was ultimately closed as resolved by the addition of ConnectCallback in .NET 5 (see #41949).

Key comments:

  • The .NET team suggested that a delegate for custom DNS resolution is reasonable, but that it should be similar to Dns.GetHostAddressesAsync.
  • There was debate about whether the callback should be per-request or per-connection.
  • The final resolution pointed to ConnectCallback as the extensibility point for custom connection logic, including DNS.

2. Issue #41949 (September 2020) - "Add SocketsHttpHandler.ConnectCallback"

Summary:
This is the official API that enables custom connection logic, including DNS resolution, in SocketsHttpHandler. The API is:

public Func<SocketsHttpConnectionContext, CancellationToken, ValueTask<Stream>>? ConnectCallback { get; set; }

Key points:

  • Allows full control over how connections are established, including custom DNS resolution, socket creation, and stream wrapping.
  • The .NET team considers this the supported way to inject custom DNS logic.
  • The callback is not used for HTTP/3 (QUIC), but only for TCP-based protocols.

3. Issue #18348 (August 2016) - "Singleton HttpClient doesn't respect DNS changes"

Summary:
A very long-running and widely referenced issue about DNS caching and connection pooling in HttpClient. While not directly about custom DNS, it is highly relevant for understanding the motivation for custom DNS hooks.

Key points:

  • The main workaround for DNS changes is to use SocketsHttpHandler.PooledConnectionLifetime to force periodic connection refreshes.
  • There is no built-in way to inject custom DNS logic except by replacing the handler or using ConnectCallback.
  • The issue is now considered resolved for most scenarios with the current APIs.

4. Issue #102105 (May 2024) - "[API Proposal]: Should we design a DnsClient abstract class?"

Summary:
A recent proposal to introduce a pluggable DNS client abstraction for all network components, including SocketsHttpHandler. The discussion notes:

  • ConnectCallback is currently the only way to customize DNS in SocketsHttpHandler.
  • There is interest in a higher-level, easier-to-use DNS customization API.
  • The team acknowledges that ConnectCallback is powerful but not always ergonomic, especially for advanced scenarios (e.g., proxies, HTTP/3).

5. Issue #19443 (November 2016) - "Proposal for DNS client and custom DNS queries"

Summary:
A long-standing proposal for a first-class DNS client API in .NET, which would enable custom DNS queries, including SRV, TXT, and custom servers. This is a broader ask than just HttpClient, but is highly relevant to the motivation for custom DNS hooks.


6. Issue #60390 (October 2021) - "Improve handling of DNS changes by revalidating pooled SocketsHttpHandler connections periodically"

Summary:
Discusses the limitations of the current DNS handling in SocketsHttpHandler and the trade-offs of various approaches (e.g., using TTL, revalidation). It is relevant for understanding the boundaries of what can be achieved with custom DNS logic.


7. Issue #45144 (November 2020) - "[Question] Custom the server name of SocketsHttpHandler"

Summary:
While focused on customizing SNI/Host headers, this issue includes discussion of the limitations of current extensibility points in SocketsHttpHandler and the use of ConnectCallback for advanced scenarios.


8. Issue #53371 (May 2021) - "Better HttpClient"

Summary:
A user proposal for a new, more flexible HttpClient with pluggable DNS and connection pools. The .NET team responded that ConnectCallback and SocketsHttpHandler are the current extensibility points for custom DNS and connection logic.


9. Issue #92314 (September 2023) - "Httpclient dns translation should be configurable"

Summary:
A user asks for a way to disable DNS resolution in HttpClient and let the proxy handle it. The discussion clarifies that, with a proxy configured, the hostname should be preserved, but there is no direct API to control DNS resolution order.


10. Comments in Issue #120168 itself

Summary:

  • The .NET team (stephentoub) points out that SocketsHttpHandler.ConnectCallback allows replacing the DNS resolution logic.
  • The original poster (billpg) expresses concern that ConnectCallback replaces both DNS and TCP logic, and asks about HTTP/3/QUIC.
  • The .NET team clarifies that ConnectCallback is not used for HTTP/3, and that a similar callback for QUIC is under consideration.

Conclusions

  • The most direct way to inject custom DNS logic into HttpClient is via SocketsHttpHandler.ConnectCallback, available since .NET 5.
  • There have been multiple proposals for higher-level or more ergonomic DNS customization APIs, but none have been accepted yet; the team is open to future improvements.
  • For HTTP/3/QUIC, there is currently no equivalent to ConnectCallback, but it is under consideration (see #64449).
  • The .NET team is aware of the need for better DNS extensibility, but currently considers ConnectCallback sufficient for most scenarios.
  • There is ongoing discussion about a pluggable DNS client abstraction (#102105, #19443), but no concrete API yet.

Highly Relevant Issues

  • #25401 (2018): Early proposal for custom DNS resolution in SocketsHttpHandler.
  • #41949 (2020): Introduction of ConnectCallback for custom connection/DNS logic.
  • #102105 (2024): Recent proposal for a pluggable DNS client abstraction.
  • #19443 (2016): Long-standing proposal for a DNS client API.
  • #60390 (2021): Discussion of DNS revalidation and connection pooling.

Recommendation

If you are triaging #120168, you should:

  • Reference #41949 as the canonical way to achieve custom DNS resolution in HttpClient today.
  • Note that the .NET team considers ConnectCallback the supported extensibility point, but that there is interest in higher-level DNS customization APIs (see #102105, #19443).
  • Mention that for HTTP/3/QUIC, there is currently no equivalent, but it is being tracked (see #64449).
  • Suggest that the proposal in #120168 is a duplicate of the functionality provided by ConnectCallback, but that the ergonomic concerns and desire for a more focused DNS hook are valid and under discussion.

Let me know if you need a more detailed summary of any specific issue or further cross-references.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions