mirror of https://github.com/grpc/grpc-go.git
resolver: delete Target.Scheme and Target.Authority (#6363)
* Delete resolver.Target.Scheme and resolver.Target.Authority * cleanup - wrap block comments @ 80 columns
This commit is contained in:
parent
df3e021458
commit
11feb0a9af
|
@ -1807,19 +1807,15 @@ func (cc *ClientConn) parseTargetAndFindResolver() error {
|
|||
}
|
||||
|
||||
// parseTarget uses RFC 3986 semantics to parse the given target into a
|
||||
// resolver.Target struct containing scheme, authority and url. Query
|
||||
// params are stripped from the endpoint.
|
||||
// resolver.Target struct containing url. Query params are stripped from the
|
||||
// endpoint.
|
||||
func parseTarget(target string) (resolver.Target, error) {
|
||||
u, err := url.Parse(target)
|
||||
if err != nil {
|
||||
return resolver.Target{}, err
|
||||
}
|
||||
|
||||
return resolver.Target{
|
||||
Scheme: u.Scheme,
|
||||
Authority: u.Host,
|
||||
URL: *u,
|
||||
}, nil
|
||||
return resolver.Target{URL: *u}, nil
|
||||
}
|
||||
|
||||
// Determine channel authority. The order of precedence is as follows:
|
||||
|
|
|
@ -23,7 +23,6 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/url"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
@ -38,64 +37,29 @@ func (s) TestParsedTarget_Success_WithoutCustomDialer(t *testing.T) {
|
|||
defScheme := resolver.GetDefaultScheme()
|
||||
tests := []struct {
|
||||
target string
|
||||
badScheme bool
|
||||
wantParsed resolver.Target
|
||||
}{
|
||||
// No scheme is specified.
|
||||
{target: "://", badScheme: true, wantParsed: resolver.Target{Scheme: defScheme, Authority: "", URL: *testutils.MustParseURL(fmt.Sprintf("%s:///%s", defScheme, "://"))}},
|
||||
{target: ":///", badScheme: true, wantParsed: resolver.Target{Scheme: defScheme, Authority: "", URL: *testutils.MustParseURL(fmt.Sprintf("%s:///%s", defScheme, ":///"))}},
|
||||
{target: "://a/", badScheme: true, wantParsed: resolver.Target{Scheme: defScheme, Authority: "", URL: *testutils.MustParseURL(fmt.Sprintf("%s:///%s", defScheme, "://a/"))}},
|
||||
{target: ":///a", badScheme: true, wantParsed: resolver.Target{Scheme: defScheme, Authority: "", URL: *testutils.MustParseURL(fmt.Sprintf("%s:///%s", defScheme, ":///a"))}},
|
||||
{target: "://a/b", badScheme: true, wantParsed: resolver.Target{Scheme: defScheme, Authority: "", URL: *testutils.MustParseURL(fmt.Sprintf("%s:///%s", defScheme, "://a/b"))}},
|
||||
{target: "/", badScheme: true, wantParsed: resolver.Target{Scheme: defScheme, Authority: "", URL: *testutils.MustParseURL(fmt.Sprintf("%s:///%s", defScheme, "/"))}},
|
||||
{target: "a/b", badScheme: true, wantParsed: resolver.Target{Scheme: defScheme, Authority: "", URL: *testutils.MustParseURL(fmt.Sprintf("%s:///%s", defScheme, "a/b"))}},
|
||||
{target: "a//b", badScheme: true, wantParsed: resolver.Target{Scheme: defScheme, Authority: "", URL: *testutils.MustParseURL(fmt.Sprintf("%s:///%s", defScheme, "a//b"))}},
|
||||
{target: "google.com", badScheme: true, wantParsed: resolver.Target{Scheme: defScheme, Authority: "", URL: *testutils.MustParseURL(fmt.Sprintf("%s:///%s", defScheme, "google.com"))}},
|
||||
{target: "google.com/?a=b", badScheme: true, wantParsed: resolver.Target{Scheme: defScheme, Authority: "", URL: *testutils.MustParseURL(fmt.Sprintf("%s:///%s", defScheme, "google.com/?a=b"))}},
|
||||
{target: "/unix/socket/address", badScheme: true, wantParsed: resolver.Target{Scheme: defScheme, Authority: "", URL: *testutils.MustParseURL(fmt.Sprintf("%s:///%s", defScheme, "/unix/socket/address"))}},
|
||||
{target: "://a/b", wantParsed: resolver.Target{URL: *testutils.MustParseURL(fmt.Sprintf("%s:///%s", defScheme, "://a/b"))}},
|
||||
{target: "a//b", wantParsed: resolver.Target{URL: *testutils.MustParseURL(fmt.Sprintf("%s:///%s", defScheme, "a//b"))}},
|
||||
|
||||
// An unregistered scheme is specified.
|
||||
{target: "a:///", badScheme: true, wantParsed: resolver.Target{Scheme: defScheme, Authority: "", URL: *testutils.MustParseURL(fmt.Sprintf("%s:///%s", defScheme, "a:///"))}},
|
||||
{target: "a://b/", badScheme: true, wantParsed: resolver.Target{Scheme: defScheme, Authority: "", URL: *testutils.MustParseURL(fmt.Sprintf("%s:///%s", defScheme, "a://b/"))}},
|
||||
{target: "a:///b", badScheme: true, wantParsed: resolver.Target{Scheme: defScheme, Authority: "", URL: *testutils.MustParseURL(fmt.Sprintf("%s:///%s", defScheme, "a:///b"))}},
|
||||
{target: "a://b/c", badScheme: true, wantParsed: resolver.Target{Scheme: defScheme, Authority: "", URL: *testutils.MustParseURL(fmt.Sprintf("%s:///%s", defScheme, "a://b/c"))}},
|
||||
{target: "a:b", badScheme: true, wantParsed: resolver.Target{Scheme: defScheme, Authority: "", URL: *testutils.MustParseURL(fmt.Sprintf("%s:///%s", defScheme, "a:b"))}},
|
||||
{target: "a:/b", badScheme: true, wantParsed: resolver.Target{Scheme: defScheme, Authority: "", URL: *testutils.MustParseURL(fmt.Sprintf("%s:///%s", defScheme, "a:/b"))}},
|
||||
{target: "a://b", badScheme: true, wantParsed: resolver.Target{Scheme: defScheme, Authority: "", URL: *testutils.MustParseURL(fmt.Sprintf("%s:///%s", defScheme, "a://b"))}},
|
||||
{target: "a:///", wantParsed: resolver.Target{URL: *testutils.MustParseURL(fmt.Sprintf("%s:///%s", defScheme, "a:///"))}},
|
||||
{target: "a:b", wantParsed: resolver.Target{URL: *testutils.MustParseURL(fmt.Sprintf("%s:///%s", defScheme, "a:b"))}},
|
||||
|
||||
// A registered scheme is specified.
|
||||
{target: "dns:///google.com", wantParsed: resolver.Target{Scheme: "dns", Authority: "", URL: *testutils.MustParseURL("dns:///google.com")}},
|
||||
{target: "dns://a.server.com/google.com", wantParsed: resolver.Target{Scheme: "dns", Authority: "a.server.com", URL: *testutils.MustParseURL("dns://a.server.com/google.com")}},
|
||||
{target: "dns://a.server.com/google.com/?a=b", wantParsed: resolver.Target{Scheme: "dns", Authority: "a.server.com", URL: *testutils.MustParseURL("dns://a.server.com/google.com/?a=b")}},
|
||||
{target: "unix:///a/b/c", wantParsed: resolver.Target{Scheme: "unix", Authority: "", URL: *testutils.MustParseURL("unix:///a/b/c")}},
|
||||
{target: "unix-abstract:a/b/c", wantParsed: resolver.Target{Scheme: "unix-abstract", Authority: "", URL: *testutils.MustParseURL("unix-abstract:a/b/c")}},
|
||||
{target: "unix-abstract:a b", wantParsed: resolver.Target{Scheme: "unix-abstract", Authority: "", URL: *testutils.MustParseURL("unix-abstract:a b")}},
|
||||
{target: "unix-abstract:a:b", wantParsed: resolver.Target{Scheme: "unix-abstract", Authority: "", URL: *testutils.MustParseURL("unix-abstract:a:b")}},
|
||||
{target: "unix-abstract:a-b", wantParsed: resolver.Target{Scheme: "unix-abstract", Authority: "", URL: *testutils.MustParseURL("unix-abstract:a-b")}},
|
||||
{target: "unix-abstract:/ a///://::!@#$%25^&*()b", wantParsed: resolver.Target{Scheme: "unix-abstract", Authority: "", URL: *testutils.MustParseURL("unix-abstract:/ a///://::!@#$%25^&*()b")}},
|
||||
{target: "unix-abstract:passthrough:abc", wantParsed: resolver.Target{Scheme: "unix-abstract", Authority: "", URL: *testutils.MustParseURL("unix-abstract:passthrough:abc")}},
|
||||
{target: "unix-abstract:unix:///abc", wantParsed: resolver.Target{Scheme: "unix-abstract", Authority: "", URL: *testutils.MustParseURL("unix-abstract:unix:///abc")}},
|
||||
{target: "unix-abstract:///a/b/c", wantParsed: resolver.Target{Scheme: "unix-abstract", Authority: "", URL: *testutils.MustParseURL("unix-abstract:///a/b/c")}},
|
||||
{target: "unix-abstract:///", wantParsed: resolver.Target{Scheme: "unix-abstract", Authority: "", URL: *testutils.MustParseURL("unix-abstract:///")}},
|
||||
{target: "passthrough:///unix:///a/b/c", wantParsed: resolver.Target{Scheme: "passthrough", Authority: "", URL: *testutils.MustParseURL("passthrough:///unix:///a/b/c")}},
|
||||
{target: "dns://a.server.com/google.com", wantParsed: resolver.Target{URL: *testutils.MustParseURL("dns://a.server.com/google.com")}},
|
||||
{target: "unix-abstract:/ a///://::!@#$%25^&*()b", wantParsed: resolver.Target{URL: *testutils.MustParseURL("unix-abstract:/ a///://::!@#$%25^&*()b")}},
|
||||
{target: "unix-abstract:passthrough:abc", wantParsed: resolver.Target{URL: *testutils.MustParseURL("unix-abstract:passthrough:abc")}},
|
||||
{target: "passthrough:///unix:///a/b/c", wantParsed: resolver.Target{URL: *testutils.MustParseURL("passthrough:///unix:///a/b/c")}},
|
||||
|
||||
// Cases for `scheme:absolute-path`.
|
||||
{target: "dns:/a/b/c", wantParsed: resolver.Target{Scheme: "dns", Authority: "", URL: *testutils.MustParseURL("dns:/a/b/c")}},
|
||||
{target: "unregistered:/a/b/c", badScheme: true, wantParsed: resolver.Target{Scheme: defScheme, Authority: "", URL: *testutils.MustParseURL("unregistered:/a/b/c")}},
|
||||
{target: "dns:/a/b/c", wantParsed: resolver.Target{URL: *testutils.MustParseURL("dns:/a/b/c")}},
|
||||
{target: "unregistered:/a/b/c", wantParsed: resolver.Target{URL: *testutils.MustParseURL(fmt.Sprintf("%s:///%s", defScheme, "unregistered:/a/b/c"))}},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.target, func(t *testing.T) {
|
||||
target := test.target
|
||||
if test.badScheme {
|
||||
target = defScheme + ":///" + target
|
||||
}
|
||||
url, err := url.Parse(target)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error parsing URL: %v", err)
|
||||
}
|
||||
test.wantParsed.URL = *url
|
||||
|
||||
cc, err := Dial(test.target, WithTransportCredentials(insecure.NewCredentials()))
|
||||
if err != nil {
|
||||
t.Fatalf("Dial(%q) failed: %v", test.target, err)
|
||||
|
@ -132,7 +96,6 @@ func (s) TestParsedTarget_WithCustomDialer(t *testing.T) {
|
|||
defScheme := resolver.GetDefaultScheme()
|
||||
tests := []struct {
|
||||
target string
|
||||
badScheme bool
|
||||
wantParsed resolver.Target
|
||||
wantDialerAddress string
|
||||
}{
|
||||
|
@ -140,72 +103,58 @@ func (s) TestParsedTarget_WithCustomDialer(t *testing.T) {
|
|||
// different behaviors with a custom dialer.
|
||||
{
|
||||
target: "unix:a/b/c",
|
||||
wantParsed: resolver.Target{Scheme: "unix", Authority: "", URL: *testutils.MustParseURL("unix:a/b/c")},
|
||||
wantParsed: resolver.Target{URL: *testutils.MustParseURL("unix:a/b/c")},
|
||||
wantDialerAddress: "unix:a/b/c",
|
||||
},
|
||||
{
|
||||
target: "unix:/a/b/c",
|
||||
wantParsed: resolver.Target{Scheme: "unix", Authority: "", URL: *testutils.MustParseURL("unix:/a/b/c")},
|
||||
wantParsed: resolver.Target{URL: *testutils.MustParseURL("unix:/a/b/c")},
|
||||
wantDialerAddress: "unix:///a/b/c",
|
||||
},
|
||||
{
|
||||
target: "unix:///a/b/c",
|
||||
wantParsed: resolver.Target{Scheme: "unix", Authority: "", URL: *testutils.MustParseURL("unix:///a/b/c")},
|
||||
wantParsed: resolver.Target{URL: *testutils.MustParseURL("unix:///a/b/c")},
|
||||
wantDialerAddress: "unix:///a/b/c",
|
||||
},
|
||||
{
|
||||
target: "dns:///127.0.0.1:50051",
|
||||
wantParsed: resolver.Target{Scheme: "dns", Authority: "", URL: *testutils.MustParseURL("dns:///127.0.0.1:50051")},
|
||||
wantParsed: resolver.Target{URL: *testutils.MustParseURL("dns:///127.0.0.1:50051")},
|
||||
wantDialerAddress: "127.0.0.1:50051",
|
||||
},
|
||||
{
|
||||
target: ":///127.0.0.1:50051",
|
||||
badScheme: true,
|
||||
wantParsed: resolver.Target{Scheme: defScheme, Authority: "", URL: *testutils.MustParseURL(fmt.Sprintf("%s:///%s", defScheme, ":///127.0.0.1:50051"))},
|
||||
wantParsed: resolver.Target{URL: *testutils.MustParseURL(fmt.Sprintf("%s:///%s", defScheme, ":///127.0.0.1:50051"))},
|
||||
wantDialerAddress: ":///127.0.0.1:50051",
|
||||
},
|
||||
{
|
||||
target: "dns://authority/127.0.0.1:50051",
|
||||
wantParsed: resolver.Target{Scheme: "dns", Authority: "authority", URL: *testutils.MustParseURL("dns://authority/127.0.0.1:50051")},
|
||||
wantParsed: resolver.Target{URL: *testutils.MustParseURL("dns://authority/127.0.0.1:50051")},
|
||||
wantDialerAddress: "127.0.0.1:50051",
|
||||
},
|
||||
{
|
||||
target: "://authority/127.0.0.1:50051",
|
||||
badScheme: true,
|
||||
wantParsed: resolver.Target{Scheme: defScheme, Authority: "", URL: *testutils.MustParseURL(fmt.Sprintf("%s:///%s", defScheme, "://authority/127.0.0.1:50051"))},
|
||||
wantParsed: resolver.Target{URL: *testutils.MustParseURL(fmt.Sprintf("%s:///%s", defScheme, "://authority/127.0.0.1:50051"))},
|
||||
wantDialerAddress: "://authority/127.0.0.1:50051",
|
||||
},
|
||||
{
|
||||
target: "/unix/socket/address",
|
||||
badScheme: true,
|
||||
wantParsed: resolver.Target{Scheme: defScheme, Authority: "", URL: *testutils.MustParseURL(fmt.Sprintf("%s:///%s", defScheme, "/unix/socket/address"))},
|
||||
wantParsed: resolver.Target{URL: *testutils.MustParseURL(fmt.Sprintf("%s:///%s", defScheme, "/unix/socket/address"))},
|
||||
wantDialerAddress: "/unix/socket/address",
|
||||
},
|
||||
{
|
||||
target: "",
|
||||
badScheme: true,
|
||||
wantParsed: resolver.Target{Scheme: defScheme, Authority: "", URL: *testutils.MustParseURL(fmt.Sprintf("%s:///%s", defScheme, ""))},
|
||||
wantParsed: resolver.Target{URL: *testutils.MustParseURL(fmt.Sprintf("%s:///%s", defScheme, ""))},
|
||||
wantDialerAddress: "",
|
||||
},
|
||||
{
|
||||
target: "passthrough://a.server.com/google.com",
|
||||
wantParsed: resolver.Target{Scheme: "passthrough", Authority: "a.server.com", URL: *testutils.MustParseURL("passthrough://a.server.com/google.com")},
|
||||
wantParsed: resolver.Target{URL: *testutils.MustParseURL("passthrough://a.server.com/google.com")},
|
||||
wantDialerAddress: "google.com",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.target, func(t *testing.T) {
|
||||
target := test.target
|
||||
if test.badScheme {
|
||||
target = defScheme + ":///" + target
|
||||
}
|
||||
url, err := url.Parse(target)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error parsing URL: %v", err)
|
||||
}
|
||||
test.wantParsed.URL = *url
|
||||
|
||||
addrCh := make(chan string, 1)
|
||||
dialer := func(ctx context.Context, address string) (net.Conn, error) {
|
||||
addrCh <- address
|
||||
|
|
|
@ -62,7 +62,8 @@ const (
|
|||
defaultPort = "443"
|
||||
defaultDNSSvrPort = "53"
|
||||
golang = "GO"
|
||||
// txtPrefix is the prefix string to be prepended to the host name for txt record lookup.
|
||||
// txtPrefix is the prefix string to be prepended to the host name for txt
|
||||
// record lookup.
|
||||
txtPrefix = "_grpc_config."
|
||||
// In DNS, service config is encoded in a TXT record via the mechanism
|
||||
// described in RFC-1464 using the attribute name grpc_config.
|
||||
|
@ -86,14 +87,14 @@ var (
|
|||
minDNSResRate = 30 * time.Second
|
||||
)
|
||||
|
||||
var customAuthorityDialler = func(authority string) func(ctx context.Context, network, address string) (net.Conn, error) {
|
||||
return func(ctx context.Context, network, address string) (net.Conn, error) {
|
||||
var addressDialer = func(address string) func(context.Context, string, string) (net.Conn, error) {
|
||||
return func(ctx context.Context, network, _ string) (net.Conn, error) {
|
||||
var dialer net.Dialer
|
||||
return dialer.DialContext(ctx, network, authority)
|
||||
return dialer.DialContext(ctx, network, address)
|
||||
}
|
||||
}
|
||||
|
||||
var customAuthorityResolver = func(authority string) (netResolver, error) {
|
||||
var newNetResolver = func(authority string) (netResolver, error) {
|
||||
host, port, err := parseTarget(authority, defaultDNSSvrPort)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -103,7 +104,7 @@ var customAuthorityResolver = func(authority string) (netResolver, error) {
|
|||
|
||||
return &net.Resolver{
|
||||
PreferGo: true,
|
||||
Dial: customAuthorityDialler(authorityWithPort),
|
||||
Dial: addressDialer(authorityWithPort),
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -114,7 +115,8 @@ func NewBuilder() resolver.Builder {
|
|||
|
||||
type dnsBuilder struct{}
|
||||
|
||||
// Build creates and starts a DNS resolver that watches the name resolution of the target.
|
||||
// Build creates and starts a DNS resolver that watches the name resolution of
|
||||
// the target.
|
||||
func (b *dnsBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (resolver.Resolver, error) {
|
||||
host, port, err := parseTarget(target.Endpoint(), defaultPort)
|
||||
if err != nil {
|
||||
|
@ -143,7 +145,7 @@ func (b *dnsBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts
|
|||
if target.URL.Host == "" {
|
||||
d.resolver = defaultResolver
|
||||
} else {
|
||||
d.resolver, err = customAuthorityResolver(target.URL.Host)
|
||||
d.resolver, err = newNetResolver(target.URL.Host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -180,19 +182,22 @@ type dnsResolver struct {
|
|||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
cc resolver.ClientConn
|
||||
// rn channel is used by ResolveNow() to force an immediate resolution of the target.
|
||||
// rn channel is used by ResolveNow() to force an immediate resolution of the
|
||||
// target.
|
||||
rn chan struct{}
|
||||
// wg is used to enforce Close() to return after the watcher() goroutine has finished.
|
||||
// Otherwise, data race will be possible. [Race Example] in dns_resolver_test we
|
||||
// replace the real lookup functions with mocked ones to facilitate testing.
|
||||
// If Close() doesn't wait for watcher() goroutine finishes, race detector sometimes
|
||||
// will warns lookup (READ the lookup function pointers) inside watcher() goroutine
|
||||
// has data race with replaceNetFunc (WRITE the lookup function pointers).
|
||||
// wg is used to enforce Close() to return after the watcher() goroutine has
|
||||
// finished. Otherwise, data race will be possible. [Race Example] in
|
||||
// dns_resolver_test we replace the real lookup functions with mocked ones to
|
||||
// facilitate testing. If Close() doesn't wait for watcher() goroutine
|
||||
// finishes, race detector sometimes will warns lookup (READ the lookup
|
||||
// function pointers) inside watcher() goroutine has data race with
|
||||
// replaceNetFunc (WRITE the lookup function pointers).
|
||||
wg sync.WaitGroup
|
||||
disableServiceConfig bool
|
||||
}
|
||||
|
||||
// ResolveNow invoke an immediate resolution of the target that this dnsResolver watches.
|
||||
// ResolveNow invoke an immediate resolution of the target that this
|
||||
// dnsResolver watches.
|
||||
func (d *dnsResolver) ResolveNow(resolver.ResolveNowOptions) {
|
||||
select {
|
||||
case d.rn <- struct{}{}:
|
||||
|
@ -220,8 +225,8 @@ func (d *dnsResolver) watcher() {
|
|||
|
||||
var timer *time.Timer
|
||||
if err == nil {
|
||||
// Success resolving, wait for the next ResolveNow. However, also wait 30 seconds at the very least
|
||||
// to prevent constantly re-resolving.
|
||||
// Success resolving, wait for the next ResolveNow. However, also wait 30
|
||||
// seconds at the very least to prevent constantly re-resolving.
|
||||
backoffIndex = 1
|
||||
timer = newTimerDNSResRate(minDNSResRate)
|
||||
select {
|
||||
|
@ -231,7 +236,8 @@ func (d *dnsResolver) watcher() {
|
|||
case <-d.rn:
|
||||
}
|
||||
} else {
|
||||
// Poll on an error found in DNS Resolver or an error received from ClientConn.
|
||||
// Poll on an error found in DNS Resolver or an error received from
|
||||
// ClientConn.
|
||||
timer = newTimer(backoff.DefaultExponential.Backoff(backoffIndex))
|
||||
backoffIndex++
|
||||
}
|
||||
|
@ -278,7 +284,8 @@ func (d *dnsResolver) lookupSRV() ([]resolver.Address, error) {
|
|||
}
|
||||
|
||||
func handleDNSError(err error, lookupType string) error {
|
||||
if dnsErr, ok := err.(*net.DNSError); ok && !dnsErr.IsTimeout && !dnsErr.IsTemporary {
|
||||
dnsErr, ok := err.(*net.DNSError)
|
||||
if ok && !dnsErr.IsTimeout && !dnsErr.IsTemporary {
|
||||
// Timeouts and temporary errors should be communicated to gRPC to
|
||||
// attempt another DNS query (with backoff). Other errors should be
|
||||
// suppressed (they may represent the absence of a TXT record).
|
||||
|
@ -307,10 +314,12 @@ func (d *dnsResolver) lookupTXT() *serviceconfig.ParseResult {
|
|||
res += s
|
||||
}
|
||||
|
||||
// TXT record must have "grpc_config=" attribute in order to be used as service config.
|
||||
// TXT record must have "grpc_config=" attribute in order to be used as
|
||||
// service config.
|
||||
if !strings.HasPrefix(res, txtAttribute) {
|
||||
logger.Warningf("dns: TXT record %v missing %v attribute", res, txtAttribute)
|
||||
// This is not an error; it is the equivalent of not having a service config.
|
||||
// This is not an error; it is the equivalent of not having a service
|
||||
// config.
|
||||
return nil
|
||||
}
|
||||
sc := canaryingSC(strings.TrimPrefix(res, txtAttribute))
|
||||
|
@ -352,9 +361,10 @@ func (d *dnsResolver) lookup() (*resolver.State, error) {
|
|||
return &state, nil
|
||||
}
|
||||
|
||||
// formatIP returns ok = false if addr is not a valid textual representation of an IP address.
|
||||
// If addr is an IPv4 address, return the addr and ok = true.
|
||||
// If addr is an IPv6 address, return the addr enclosed in square brackets and ok = true.
|
||||
// formatIP returns ok = false if addr is not a valid textual representation of
|
||||
// an IP address. If addr is an IPv4 address, return the addr and ok = true.
|
||||
// If addr is an IPv6 address, return the addr enclosed in square brackets and
|
||||
// ok = true.
|
||||
func formatIP(addr string) (addrIP string, ok bool) {
|
||||
ip := net.ParseIP(addr)
|
||||
if ip == nil {
|
||||
|
@ -366,10 +376,10 @@ func formatIP(addr string) (addrIP string, ok bool) {
|
|||
return "[" + addr + "]", true
|
||||
}
|
||||
|
||||
// parseTarget takes the user input target string and default port, returns formatted host and port info.
|
||||
// If target doesn't specify a port, set the port to be the defaultPort.
|
||||
// If target is in IPv6 format and host-name is enclosed in square brackets, brackets
|
||||
// are stripped when setting the host.
|
||||
// parseTarget takes the user input target string and default port, returns
|
||||
// formatted host and port info. If target doesn't specify a port, set the port
|
||||
// to be the defaultPort. If target is in IPv6 format and host-name is enclosed
|
||||
// in square brackets, brackets are stripped when setting the host.
|
||||
// examples:
|
||||
// target: "www.google.com" defaultPort: "443" returns host: "www.google.com", port: "443"
|
||||
// target: "ipv4-host:80" defaultPort: "443" returns host: "ipv4-host", port: "80"
|
||||
|
@ -385,12 +395,14 @@ func parseTarget(target, defaultPort string) (host, port string, err error) {
|
|||
}
|
||||
if host, port, err = net.SplitHostPort(target); err == nil {
|
||||
if port == "" {
|
||||
// If the port field is empty (target ends with colon), e.g. "[::1]:", this is an error.
|
||||
// If the port field is empty (target ends with colon), e.g. "[::1]:",
|
||||
// this is an error.
|
||||
return "", "", errEndsWithColon
|
||||
}
|
||||
// target has port, i.e ipv4-host:port, [ipv6-host]:port, host-name:port
|
||||
if host == "" {
|
||||
// Keep consistent with net.Dial(): If the host is empty, as in ":80", the local system is assumed.
|
||||
// Keep consistent with net.Dial(): If the host is empty, as in ":80",
|
||||
// the local system is assumed.
|
||||
host = "localhost"
|
||||
}
|
||||
return host, port, nil
|
||||
|
|
|
@ -1419,14 +1419,14 @@ func TestCustomAuthority(t *testing.T) {
|
|||
true,
|
||||
},
|
||||
}
|
||||
oldCustomAuthorityDialler := customAuthorityDialler
|
||||
oldAddressDialer := addressDialer
|
||||
defer func() {
|
||||
customAuthorityDialler = oldCustomAuthorityDialler
|
||||
addressDialer = oldAddressDialer
|
||||
}()
|
||||
|
||||
for _, a := range tests {
|
||||
errChan := make(chan error, 1)
|
||||
customAuthorityDialler = func(authority string) func(ctx context.Context, network, address string) (net.Conn, error) {
|
||||
addressDialer = func(authority string) func(ctx context.Context, network, address string) (net.Conn, error) {
|
||||
if authority != a.authorityWant {
|
||||
errChan <- fmt.Errorf("wrong custom authority passed to resolver. input: %s expected: %s actual: %s", a.authority, a.authorityWant, authority)
|
||||
} else {
|
||||
|
@ -1441,8 +1441,7 @@ func TestCustomAuthority(t *testing.T) {
|
|||
b := NewBuilder()
|
||||
cc := &testClientConn{target: mockEndpointTarget, errChan: make(chan error, 1)}
|
||||
target := resolver.Target{
|
||||
Authority: a.authority,
|
||||
URL: *testutils.MustParseURL(fmt.Sprintf("scheme://%s/%s", a.authority, mockEndpointTarget)),
|
||||
URL: *testutils.MustParseURL(fmt.Sprintf("scheme://%s/%s", a.authority, mockEndpointTarget)),
|
||||
}
|
||||
r, err := b.Build(target, cc, resolver.BuildOptions{})
|
||||
|
||||
|
|
|
@ -264,10 +264,6 @@ type ClientConn interface {
|
|||
// - "unknown_scheme://authority/endpoint"
|
||||
// Target{Scheme: resolver.GetDefaultScheme(), Endpoint: "unknown_scheme://authority/endpoint"}
|
||||
type Target struct {
|
||||
// Deprecated: use URL.Scheme instead.
|
||||
Scheme string
|
||||
// Deprecated: use URL.Host instead.
|
||||
Authority string
|
||||
// URL contains the parsed dial target with an optional default scheme added
|
||||
// to it if the original dial target contained no scheme or contained an
|
||||
// unregistered scheme. Any query params specified in the original dial
|
||||
|
|
|
@ -97,7 +97,6 @@ func (c2pResolverBuilder) Build(t resolver.Target, cc resolver.ClientConn, opts
|
|||
|
||||
if !runDirectPath() {
|
||||
// If not xDS, fallback to DNS.
|
||||
t.Scheme = dnsName
|
||||
t.URL.Scheme = dnsName
|
||||
return resolver.Get(dnsName).Build(t, cc, opts)
|
||||
}
|
||||
|
@ -144,7 +143,6 @@ func (c2pResolverBuilder) Build(t resolver.Target, cc resolver.ClientConn, opts
|
|||
}
|
||||
|
||||
// Create and return an xDS resolver.
|
||||
t.Scheme = xdsName
|
||||
t.URL.Scheme = xdsName
|
||||
if envconfig.XDSFederation {
|
||||
t = resolver.Target{
|
||||
|
|
|
@ -75,7 +75,7 @@ func newDNSResolver(target string, topLevelResolver topLevelResolver) *dnsDiscov
|
|||
return ret
|
||||
}
|
||||
|
||||
r, err := newDNS(resolver.Target{Scheme: "dns", URL: *u}, ret, resolver.BuildOptions{})
|
||||
r, err := newDNS(resolver.Target{URL: *u}, ret, resolver.BuildOptions{})
|
||||
if err != nil {
|
||||
topLevelResolver.onError(fmt.Errorf("failed to build DNS resolver for target %q: %v", target, err))
|
||||
return ret
|
||||
|
|
Loading…
Reference in New Issue