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

Add more granular otel instrumentation #48

Merged
merged 5 commits into from
Nov 20, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 55 additions & 41 deletions fronted.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,66 +257,78 @@ func (f *fronted) RoundTripHijack(req *http.Request) (*http.Response, net.Conn,
op.FailIf(err)
return nil, nil, err
}
provider := f.providerFor(m)
if provider == nil {
log.Debugf("Skipping masquerade with disabled/unknown provider '%s'", m.getProviderID())
masqueradeGood(false)
continue
}
frontedHost := provider.Lookup(originHost)
if frontedHost == "" {
// this error is not the masquerade's fault in particular
// so it is returned as good.
conn.Close()
masqueradeGood(true)
err := fmt.Errorf("no domain fronting mapping for '%s'. Please add it to provider_map.yaml or equivalent for %s",
m.getProviderID(), originHost)
op.FailIf(err)
return nil, nil, err
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was actually a bug where we'd return entirely instead of continuing to retry

}
log.Debugf("Translated origin %s -> %s for provider %s...", originHost, frontedHost, m.getProviderID())

reqi, err := cloneRequestWith(req, frontedHost, getBody())
if err != nil {
return nil, nil, op.FailIf(log.Errorf("Failed to copy http request with origin translated to %v?: %v", frontedHost, err))
}

// don't clobber/confuse Connection header on Upgrade requests.
disableKeepAlives := true
if strings.EqualFold(reqi.Header.Get("Connection"), "upgrade") {
disableKeepAlives = false
}

tr := frontedHTTPTransport(conn, disableKeepAlives)
resp, err := tr.RoundTrip(reqi)
if err != nil {
log.Debugf("Could not complete request: %v", err)
masqueradeGood(false)
continue
}

err = provider.ValidateResponse(resp)
resp, conn, err := f.requestWithConn(req, conn, m, originHost, getBody, masqueradeGood)
if err != nil {
log.Debugf("Could not complete request: %v", err)
resp.Body.Close()
masqueradeGood(false)
continue
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We now continue on all validation errors

}

masqueradeGood(true)
return resp, conn, nil
}

return nil, nil, op.FailIf(errors.New("could not complete request even with retries"))
}

func (f *fronted) requestWithConn(req *http.Request, conn net.Conn, m MasqueradeInterface, originHost string, getBody func() io.ReadCloser, masqueradeGood func(bool) bool) (*http.Response, net.Conn, error) {
op := ops.Begin("request_with_conn")
defer op.End()
provider := f.providerFor(m)
if provider == nil {
log.Debugf("Skipping masquerade with disabled/unknown provider '%s'", m.getProviderID())
masqueradeGood(false)
return nil, nil, op.FailIf(log.Errorf("Skipping masquerade with disabled/unknown provider '%s'", m.getProviderID()))
}
frontedHost := provider.Lookup(originHost)
if frontedHost == "" {
// this error is not the masquerade's fault in particular
// so it is returned as good.
conn.Close()
masqueradeGood(true)
err := fmt.Errorf("no domain fronting mapping for '%s'. Please add it to provider_map.yaml or equivalent for %s",
m.getProviderID(), originHost)
op.FailIf(err)
return nil, nil, err
}
log.Debugf("Translated origin %s -> %s for provider %s...", originHost, frontedHost, m.getProviderID())

reqi, err := cloneRequestWith(req, frontedHost, getBody())
if err != nil {
return nil, nil, op.FailIf(log.Errorf("Failed to copy http request with origin translated to %v?: %v", frontedHost, err))
}
disableKeepAlives := true
if strings.EqualFold(reqi.Header.Get("Connection"), "upgrade") {
disableKeepAlives = false
}

tr := frontedHTTPTransport(conn, disableKeepAlives)
resp, err := tr.RoundTrip(reqi)
if err != nil {
log.Debugf("Could not complete request: %v", err)
masqueradeGood(false)
return nil, nil, err
}

err = provider.ValidateResponse(resp)
if err != nil {
log.Debugf("Could not complete request: %v", err)
resp.Body.Close()
masqueradeGood(false)
return nil, nil, err
}

masqueradeGood(true)
return resp, conn, nil
}

// Dial dials out using all available masquerades until one succeeds.
func (f *fronted) dialAll(ctx context.Context) (net.Conn, MasqueradeInterface, func(bool) bool, error) {
conn, m, masqueradeGood, err := f.dialAllWith(ctx, f.masquerades)
return conn, m, masqueradeGood, err
}

func (f *fronted) dialAllWith(ctx context.Context, masquerades sortedMasquerades) (net.Conn, MasqueradeInterface, func(bool) bool, error) {
defer func(op ops.Op) { op.End() }(ops.Begin("dial_all_with"))
// never take more than a minute trying to find a dialer
ctx, cancel := context.WithTimeout(ctx, 1*time.Minute)
defer cancel()
Expand Down Expand Up @@ -491,6 +503,8 @@ type directTransport struct {
}

func (ddf *directTransport) RoundTrip(req *http.Request) (resp *http.Response, err error) {
defer func(op ops.Op) { op.End() }(ops.Begin("direct_transport_roundtrip"))

// The connection is already encrypted by domain fronting. We need to rewrite URLs starting
// with "https://" to "http://", lest we get an error for doubling up on TLS.

Expand Down
Loading