diff options
author | Aziz Rmadi <[email protected]> | 2024-07-09 02:06:30 -0500 |
---|---|---|
committer | GitHub <[email protected]> | 2024-07-09 03:06:30 -0400 |
commit | 630c62b3137abf688aa1a698a614fa28c08e43dd (patch) | |
tree | ad0f014660b790bc2ed38811460bc250d9d456ce | |
parent | 9338741ca79a74247ced86bc26e4994138470852 (diff) | |
download | caddy-630c62b3137abf688aa1a698a614fa28c08e43dd.tar.gz caddy-630c62b3137abf688aa1a698a614fa28c08e43dd.zip |
fixed bug in resolving ip version in dynamic upstreams (#6448)
-rw-r--r-- | modules/caddyhttp/reverseproxy/upstreams.go | 26 | ||||
-rw-r--r-- | modules/caddyhttp/reverseproxy/upstreams_test.go | 56 |
2 files changed, 70 insertions, 12 deletions
diff --git a/modules/caddyhttp/reverseproxy/upstreams.go b/modules/caddyhttp/reverseproxy/upstreams.go index 46e45c646..c8ba930d2 100644 --- a/modules/caddyhttp/reverseproxy/upstreams.go +++ b/modules/caddyhttp/reverseproxy/upstreams.go @@ -231,6 +231,19 @@ type IPVersions struct { IPv6 *bool `json:"ipv6,omitempty"` } +func resolveIpVersion(versions *IPVersions) string { + resolveIpv4 := versions == nil || (versions.IPv4 == nil && versions.IPv6 == nil) || (versions.IPv4 != nil && *versions.IPv4) + resolveIpv6 := versions == nil || (versions.IPv6 == nil && versions.IPv4 == nil) || (versions.IPv6 != nil && *versions.IPv6) + switch { + case resolveIpv4 && !resolveIpv6: + return "ip4" + case !resolveIpv4 && resolveIpv6: + return "ip6" + default: + return "ip" + } +} + // AUpstreams provides upstreams from A/AAAA lookups. // Results are cached and refreshed at the configured // refresh interval. @@ -313,9 +326,6 @@ func (au *AUpstreams) Provision(ctx caddy.Context) error { func (au AUpstreams) GetUpstreams(r *http.Request) ([]*Upstream, error) { repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer) - resolveIpv4 := au.Versions == nil || au.Versions.IPv4 == nil || *au.Versions.IPv4 - resolveIpv6 := au.Versions == nil || au.Versions.IPv6 == nil || *au.Versions.IPv6 - // Map ipVersion early, so we can use it as part of the cache-key. // This should be fairly inexpensive and comes and the upside of // allowing the same dynamic upstream (name + port combination) @@ -324,15 +334,7 @@ func (au AUpstreams) GetUpstreams(r *http.Request) ([]*Upstream, error) { // It also forced a cache-miss if a previously cached dynamic // upstream changes its ip version, e.g. after a config reload, // while keeping the cache-invalidation as simple as it currently is. - var ipVersion string - switch { - case resolveIpv4 && !resolveIpv6: - ipVersion = "ip4" - case !resolveIpv4 && resolveIpv6: - ipVersion = "ip6" - default: - ipVersion = "ip" - } + ipVersion := resolveIpVersion(au.Versions) auStr := repl.ReplaceAll(au.String()+ipVersion, "") diff --git a/modules/caddyhttp/reverseproxy/upstreams_test.go b/modules/caddyhttp/reverseproxy/upstreams_test.go new file mode 100644 index 000000000..48e2d2a63 --- /dev/null +++ b/modules/caddyhttp/reverseproxy/upstreams_test.go @@ -0,0 +1,56 @@ +package reverseproxy + +import "testing" + +func TestResolveIpVersion(t *testing.T) { + falseBool := false + trueBool := true + tests := []struct { + Versions *IPVersions + expectedIpVersion string + }{ + { + Versions: &IPVersions{IPv4: &trueBool}, + expectedIpVersion: "ip4", + }, + { + Versions: &IPVersions{IPv4: &falseBool}, + expectedIpVersion: "ip", + }, + { + Versions: &IPVersions{IPv4: &trueBool, IPv6: &falseBool}, + expectedIpVersion: "ip4", + }, + { + Versions: &IPVersions{IPv6: &trueBool}, + expectedIpVersion: "ip6", + }, + { + Versions: &IPVersions{IPv6: &falseBool}, + expectedIpVersion: "ip", + }, + { + Versions: &IPVersions{IPv6: &trueBool, IPv4: &falseBool}, + expectedIpVersion: "ip6", + }, + { + Versions: &IPVersions{}, + expectedIpVersion: "ip", + }, + { + Versions: &IPVersions{IPv4: &trueBool, IPv6: &trueBool}, + expectedIpVersion: "ip", + }, + { + Versions: &IPVersions{IPv4: &falseBool, IPv6: &falseBool}, + expectedIpVersion: "ip", + }, + } + for _, test := range tests { + ipVersion := resolveIpVersion(test.Versions) + if ipVersion != test.expectedIpVersion { + t.Errorf("resolveIpVersion(): Expected %s got %s", test.expectedIpVersion, ipVersion) + } + } + +} |