Skip to content

Comments

Add WithDialer option for custom TCP dialer injection#67

Merged
myleshorton merged 2 commits intomainfrom
add-with-dialer
Feb 22, 2026
Merged

Add WithDialer option for custom TCP dialer injection#67
myleshorton merged 2 commits intomainfrom
add-with-dialer

Conversation

@myleshorton
Copy link
Contributor

Summary

  • Adds a WithDialer(func(ctx context.Context, network, addr string) (net.Conn, error)) option to fronted
  • Threads the custom dialer through loadFrontsnewFrontfront.dial(), adapting it to tlsdialer.Dialer.DoDial via context.WithTimeout
  • Falls back to (&net.Dialer{}).DialContext when no custom dialer is provided (preserving existing behavior)

Test plan

  • go build ./... compiles cleanly
  • go vet ./... passes
  • Existing tests pass (go test ./...)
  • Verify domain fronting still works end-to-end with default dialer
  • Verify custom dialer is called when injected via WithDialer

🤖 Generated with Claude Code

Allow callers to inject a custom dialer function via WithDialer() that
flows through to the tlsdialer used by each front. This enables kindling
to set a single dialer that automatically applies to all fronted connections.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@myleshorton myleshorton requested a review from Copilot February 22, 2026 12:57
myleshorton added a commit to getlantern/kindling that referenced this pull request Feb 22, 2026
Introduce a single WithDialer option at the kindling level that
automatically flows to all transports (fronted, dnstt, amp, smart).

Key changes:
- Add exported DialContextFunc type and WithDialer option
- Add Close() to Kindling interface for resource cleanup
- Rewrite WithDomainFronting to accept fronted.Option params
- Rewrite WithDNSTunnel to accept dnstt.Option params
- Rewrite WithAMPCache to accept amp.Config + amp.Option params
- Update smart dialer to use injected dialer via FuncStreamDialer
- Add streamConnAdapter and closerFunc helper types
- Update tests for new API signatures

The With* functions now construct transport instances internally and
prepend the dialer option, so callers no longer need to create
transport instances themselves.

Requires getlantern/fronted#67 and getlantern/dnstt#12.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds support for injecting a custom TCP dialing function into the fronted client so callers can control how underlying network connections are established (e.g., for custom transports, proxies, or instrumentation), while preserving default behavior when not provided.

Changes:

  • Introduces WithDialer(func(ctx context.Context, network, addr string) (net.Conn, error)) option and stores it on fronted.
  • Threads the dial function through loadFrontsnewFrontfront.dial() and adapts it to tlsdialer.Dialer.DoDial using context.WithTimeout.
  • Updates TestLoadFronts to match the new loadFronts signature.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
fronted.go Adds dialFunc to fronted, a WithDialer option, and threads dialer injection through onNewFronts/loadFronts.
front.go Stores dialer on front and uses it in front.dial() by adapting to tlsdialer.Dialer.DoDial.
fronted_test.go Updates loadFronts callsite for the new parameter.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 185 to 191
// WithDialer sets a custom dialer function for the fronted instance. This allows callers to
// inject their own dialer for making TCP connections to fronting domains.
func WithDialer(dial func(ctx context.Context, network, addr string) (net.Conn, error)) Option {
return func(f *fronted) {
f.dialFunc = dial
}
}
Copy link

Copilot AI Feb 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New public option WithDialer adds behavior that isn’t covered by tests yet. Please add a unit test that injects a dialer via WithDialer, triggers a dial (e.g., by calling fr.dial(...) or f.doDial(...) with a dialer that records invocation and returns a sentinel error), and asserts the injected dialer is called and its error is propagated.

Copilot uses AI. Check for mistakes.
fronted.go Outdated
Comment on lines 48 to 51
// fronted identifies working IP address/domain pairings for domain fronting and is
// an implementation of http.RoundTripper for the convenience of callers.
type fronted struct {
dialFunc func(ctx context.Context, network, addr string) (net.Conn, error)
Copy link

Copilot AI Feb 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dialer function type is repeated in several places (fronted.dialFunc, WithDialer, loadFronts, front.dialFunc, newFront). Consider introducing a named type (e.g., type DialFunc func(context.Context, string, string) (net.Conn, error)) to reduce duplication and make future signature changes safer.

Suggested change
// fronted identifies working IP address/domain pairings for domain fronting and is
// an implementation of http.RoundTripper for the convenience of callers.
type fronted struct {
dialFunc func(ctx context.Context, network, addr string) (net.Conn, error)
// DialFunc is the function type used for dialing network connections.
type DialFunc func(ctx context.Context, network, addr string) (net.Conn, error)
// fronted identifies working IP address/domain pairings for domain fronting and is
// an implementation of http.RoundTripper for the convenience of callers.
type fronted struct {
dialFunc DialFunc

Copilot uses AI. Check for mistakes.
fronted.go Outdated
}

// WithDialer sets a custom dialer function for the fronted instance. This allows callers to
// inject their own dialer for making TCP connections to fronting domains.
Copy link

Copilot AI Feb 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The WithDialer docstring says it’s for “making TCP connections to fronting domains”, but the dialer is ultimately invoked with the addr passed to tlsdialer.Dialer.Dial("tcp", addr), which (in front.dial) is built from fr.IpAddress (plus default port). Consider clarifying in the comment that the injected dialer will typically receive an IP:port target, while SNI/ServerName is handled separately via TLS config.

Suggested change
// inject their own dialer for making TCP connections to fronting domains.
// inject their own dialer for making the underlying TCP connections. The dialer will typically
// be invoked with an IP:port destination (derived from the configured fronting infrastructure),
// while the fronting domain name (SNI/ServerName) is configured separately via the TLS settings.

Copilot uses AI. Check for mistakes.
myleshorton added a commit to getlantern/kindling that referenced this pull request Feb 22, 2026
Introduce a single WithDialer option at the kindling level that
automatically flows to all transports (fronted, dnstt, amp, smart).

Key changes:
- Add exported DialContextFunc type and WithDialer option
- Add Close() to Kindling interface for resource cleanup
- Rewrite WithDomainFronting to accept fronted.Option params
- Rewrite WithDNSTunnel to accept dnstt.Option params
- Rewrite WithAMPCache to accept amp.Config + amp.Option params
- Update smart dialer to use injected dialer via FuncStreamDialer
- Add streamConnAdapter and closerFunc helper types
- Update tests for new API signatures

The With* functions now construct transport instances internally and
prepend the dialer option, so callers no longer need to create
transport instances themselves.

Requires getlantern/fronted#67 and getlantern/dnstt#12.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Introduce named DialFunc type for the dialer function signature
- Improve WithDialer docstring with more context about how the dialer is used
- Add tests: TestWithDialer, TestWithDialerDefault, TestWithDialerFlowsToFronts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@myleshorton myleshorton merged commit 4bfa74d into main Feb 22, 2026
1 check failed
@myleshorton myleshorton deleted the add-with-dialer branch February 22, 2026 15:04
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

Successfully merging this pull request may close these issues.

1 participant