Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(transport): enforce 1s timeout on requests to MDS universe_domain #2393

Merged
Merged
39 changes: 39 additions & 0 deletions internal/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"net/http"
"os"
"strconv"
"time"

"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
Expand Down Expand Up @@ -187,3 +188,41 @@ func (ds *DialSettings) GetUniverseDomain() string {
func (ds *DialSettings) IsUniverseDomainGDU() bool {
return ds.GetUniverseDomain() == ds.GetDefaultUniverseDomain()
}

// GetUniverseDomain returns the default service domain for a given Cloud
// universe, from google.Credentials, for comparison with the value returned by
// (*DialSettings).GetUniverseDomain. This wrapper function should be removed
// to close [TODO(chrisdsmith): issue link here]. See details below.
func GetUniverseDomain(creds *google.Credentials) (string, error) {
timer := time.NewTimer(time.Second)
codyoss marked this conversation as resolved.
Show resolved Hide resolved
defer timer.Stop()
errors := make(chan error)
results := make(chan string)

go func() {
result, err := creds.GetUniverseDomain()
if err != nil {
errors <- err
return
}
results <- result
}()

select {
case err := <-errors:
// An error that is returned before the timer expires is legitimate.
return "", err
case res := <-results:
return res, nil
case <-timer.C: // Timer is expired.
// If err or res was not returned, it means that creds.GetUniverseDomain()
// did not complete in 1s. Assume that MDS is likely never responding to
// the endpoint and will timeout. This is the source of issues such as
// https://github.com/googleapis/google-cloud-go/issues/9350.
// Temporarily (2024-02-02) return the GDU domain. Restore the original
// calls to creds.GetUniverseDomain() in grpc/dial.go and http/dial.go
// and remove this method to close
// https://github.com/googleapis/google-api-go-client/issues/2399.
return universeDomainDefault, nil
}
}
2 changes: 1 addition & 1 deletion transport/grpc/dial.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ func dial(ctx context.Context, insecure bool, o *internal.DialSettings) (*grpc.C
if err != nil {
return nil, err
}
credsUniverseDomain, err := creds.GetUniverseDomain()
credsUniverseDomain, err := internal.GetUniverseDomain(creds)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion transport/http/dial.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func newTransport(ctx context.Context, base http.RoundTripper, settings *interna
if err != nil {
return nil, err
}
credsUniverseDomain, err := creds.GetUniverseDomain()
credsUniverseDomain, err := internal.GetUniverseDomain(creds)
if err != nil {
return nil, err
}
Expand Down