From e695d1ac3fabdc00836b83af2e65617946c954ed Mon Sep 17 00:00:00 2001 From: David Zhao Date: Sun, 9 Nov 2025 14:53:18 -0800 Subject: [PATCH 1/3] add option to force webhooks to be made over IPv4 --- webhook/notifier.go | 1 + webhook/resource_url_notifier.go | 14 ++++++++++++++ webhook/url_notifier.go | 14 ++++++++++++++ 3 files changed, 29 insertions(+) diff --git a/webhook/notifier.go b/webhook/notifier.go index b14ab6ff7..c5bb366d2 100644 --- a/webhook/notifier.go +++ b/webhook/notifier.go @@ -185,6 +185,7 @@ type HTTPClientParams struct { RetryWaitMax time.Duration MaxRetries int ClientTimeout time.Duration + ForceIPv4 bool } type FilterParams struct { diff --git a/webhook/resource_url_notifier.go b/webhook/resource_url_notifier.go index 2dccbede0..8b88b38fc 100644 --- a/webhook/resource_url_notifier.go +++ b/webhook/resource_url_notifier.go @@ -21,6 +21,8 @@ import ( "encoding/base64" "errors" "fmt" + "net" + "net/http" "sync" "time" @@ -130,6 +132,18 @@ func NewResourceURLNotifier(params ResourceURLNotifierParams) *ResourceURLNotifi rhc.HTTPClient.Timeout = params.ClientTimeout } rhc.Logger = &logAdapter{} + if params.ForceIPv4 { + var tr *http.Transport + if existing, ok := rhc.HTTPClient.Transport.(*http.Transport); ok && existing != nil { + tr = existing.Clone() + } else { + tr = http.DefaultTransport.(*http.Transport).Clone() + } + tr.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) { + return (&net.Dialer{}).DialContext(ctx, "tcp4", addr) + } + rhc.HTTPClient.Transport = tr + } r := &ResourceURLNotifier{ params: params, client: rhc, diff --git a/webhook/url_notifier.go b/webhook/url_notifier.go index 26456cd01..9317878e1 100644 --- a/webhook/url_notifier.go +++ b/webhook/url_notifier.go @@ -20,6 +20,8 @@ import ( "crypto/sha256" "encoding/base64" "fmt" + "net" + "net/http" "sync" "time" @@ -91,6 +93,18 @@ func NewURLNotifier(params URLNotifierParams) *URLNotifier { if params.ClientTimeout > 0 { rhc.HTTPClient.Timeout = params.ClientTimeout } + if params.ForceIPv4 { + var tr *http.Transport + if existing, ok := rhc.HTTPClient.Transport.(*http.Transport); ok && existing != nil { + tr = existing.Clone() + } else { + tr = http.DefaultTransport.(*http.Transport).Clone() + } + tr.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) { + return (&net.Dialer{}).DialContext(ctx, "tcp4", addr) + } + rhc.HTTPClient.Transport = tr + } n := &URLNotifier{ params: params, client: rhc, From 2bac037734e863ee76ccbb7bd3785690cdde6e23 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Sun, 9 Nov 2025 14:57:03 -0800 Subject: [PATCH 2/3] include in test --- webhook/webhook_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/webhook/webhook_test.go b/webhook/webhook_test.go index 6c56cae35..bfa90478e 100644 --- a/webhook/webhook_test.go +++ b/webhook/webhook_test.go @@ -229,6 +229,9 @@ func TestURLNotifierFilter(t *testing.T) { Config: URLNotifierConfig{ QueueSize: 20, }, + HTTPClientParams: HTTPClientParams{ + ForceIPv4: true, + }, }) defer urlNotifier.Stop(false) From cf263227b41ae89c89406f065b5c2bd6d66c1418 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Sun, 9 Nov 2025 14:58:26 -0800 Subject: [PATCH 3/3] changeset --- .changeset/eager-foxes-allow.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/eager-foxes-allow.md diff --git a/.changeset/eager-foxes-allow.md b/.changeset/eager-foxes-allow.md new file mode 100644 index 000000000..7c2324637 --- /dev/null +++ b/.changeset/eager-foxes-allow.md @@ -0,0 +1,5 @@ +--- +"github.com/livekit/protocol": patch +--- + +add option to only use IPv4 for webhooks