Skip to content

Commit

Permalink
Merge pull request #47 from getlantern/myles/visibility
Browse files Browse the repository at this point in the history
Use the newer eventual and tighten up public visibility of members
  • Loading branch information
myleshorton authored Nov 19, 2024
2 parents ddfdb52 + 9dc10f7 commit e357a92
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 41 deletions.
51 changes: 29 additions & 22 deletions context.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
package fronted

import (
"context"
"crypto/x509"
"fmt"
"net/http"
"time"

tls "github.com/refraction-networking/utls"

"github.com/getlantern/eventual"
"github.com/getlantern/eventual/v2"
)

var (
DefaultContext = NewFrontingContext("default")
)
var defaultContext = newFrontingContext("default")

// Configure sets the masquerades to use, the trusted root CAs, and the
// cache file for caching masquerades to set up direct domain fronting
Expand All @@ -22,31 +21,31 @@ var (
// defaultProviderID is used when a masquerade without a provider is
// encountered (eg in a cache file)
func Configure(pool *x509.CertPool, providers map[string]*Provider, defaultProviderID string, cacheFile string) {
if err := DefaultContext.Configure(pool, providers, defaultProviderID, cacheFile); err != nil {
log.Errorf("Error configuring fronting %s context: %s!!", DefaultContext.name, err)
if err := defaultContext.Configure(pool, providers, defaultProviderID, cacheFile); err != nil {
log.Errorf("Error configuring fronting %s context: %s!!", defaultContext.name, err)
}
}

// NewFronted creates a new http.RoundTripper that does direct domain fronting
// using the default context. If the default context isn't configured within
// the given timeout, this method returns nil, false.
func NewFronted(timeout time.Duration) (http.RoundTripper, bool) {
return DefaultContext.NewFronted(timeout)
return defaultContext.NewFronted(timeout)
}

// Close closes any existing cache file in the default context
func Close() {
DefaultContext.Close()
defaultContext.Close()
}

func NewFrontingContext(name string) *FrontingContext {
return &FrontingContext{
func newFrontingContext(name string) *frontingContext {
return &frontingContext{
name: name,
instance: eventual.NewValue(),
}
}

type FrontingContext struct {
type frontingContext struct {
name string
instance eventual.Value
}
Expand All @@ -55,25 +54,27 @@ type FrontingContext struct {
// cache file for caching masquerades to set up direct domain fronting.
// defaultProviderID is used when a masquerade without a provider is
// encountered (eg in a cache file)
func (fctx *FrontingContext) Configure(pool *x509.CertPool, providers map[string]*Provider, defaultProviderID string, cacheFile string) error {
func (fctx *frontingContext) Configure(pool *x509.CertPool, providers map[string]*Provider, defaultProviderID string, cacheFile string) error {
return fctx.ConfigureWithHello(pool, providers, defaultProviderID, cacheFile, tls.ClientHelloID{})
}

func (fctx *FrontingContext) ConfigureWithHello(pool *x509.CertPool, providers map[string]*Provider, defaultProviderID string, cacheFile string, clientHelloID tls.ClientHelloID) error {
func (fctx *frontingContext) ConfigureWithHello(pool *x509.CertPool, providers map[string]*Provider, defaultProviderID string, cacheFile string, clientHelloID tls.ClientHelloID) error {
log.Debugf("Configuring fronted %s context", fctx.name)

if len(providers) == 0 {
return fmt.Errorf("no fronted providers for %s context", fctx.name)
}

_existing, ok := fctx.instance.Get(0)
if ok && _existing != nil {
if _existing, err := fctx.instance.Get(eventual.DontWait); err != nil {
log.Errorf("Error getting existing instance for %s context: %s", fctx.name, err)
} else if _existing != nil {
existing := _existing.(*fronted)
log.Debugf("Closing cache from existing instance for %s context", fctx.name)
existing.closeCache()
}

_, err := newFronted(pool, providers, defaultProviderID, cacheFile, clientHelloID, func(f *fronted) {
log.Debug("Setting fronted instance")
fctx.instance.Set(f)
})
if err != nil {
Expand All @@ -85,22 +86,28 @@ func (fctx *FrontingContext) ConfigureWithHello(pool *x509.CertPool, providers m
// NewFronted creates a new http.RoundTripper that does direct domain fronting.
// If the context isn't configured within the given timeout, this method
// returns nil, false.
func (fctx *FrontingContext) NewFronted(timeout time.Duration) (http.RoundTripper, bool) {
func (fctx *frontingContext) NewFronted(timeout time.Duration) (http.RoundTripper, bool) {
start := time.Now()
instance, ok := fctx.instance.Get(timeout)
if !ok {
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
instance, err := fctx.instance.Get(ctx)
if err != nil {
log.Errorf("No DirectHttpClient available within %v for context %s", timeout, fctx.name)
return nil, false
} else {
log.Debugf("DirectHttpClient available for context %s after %v", fctx.name, time.Since(start))
log.Debugf("DirectHttpClient available for context %s after %v with duration %v", fctx.name, time.Since(start), timeout)
}
return instance.(http.RoundTripper), true
}

// Close closes any existing cache file in the default contexxt.
func (fctx *FrontingContext) Close() {
_existing, ok := fctx.instance.Get(0)
if ok && _existing != nil {
func (fctx *frontingContext) Close() {
_existing, err := fctx.instance.Get(eventual.DontWait)
if err != nil {
log.Errorf("Error getting existing instance for %s context: %s", fctx.name, err)
return
}
if _existing != nil {
existing := _existing.(*fronted)
log.Debugf("Closing cache from existing instance in %s context", fctx.name)
existing.closeCache()
Expand Down
19 changes: 10 additions & 9 deletions fronted_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"testing"
"time"

"github.com/getlantern/eventual/v2"
. "github.com/getlantern/waitforserver"
tls "github.com/refraction-networking/utls"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -55,7 +56,7 @@ func TestDirectDomainFrontingWithSNIConfig(t *testing.T) {
UseArbitrarySNIs: true,
ArbitrarySNIs: []string{"mercadopago.com", "amazon.com.br", "facebook.com", "google.com", "twitter.com", "youtube.com", "instagram.com", "linkedin.com", "whatsapp.com", "netflix.com", "microsoft.com", "yahoo.com", "bing.com", "wikipedia.org", "github.com"},
})
testContext := NewFrontingContext("TestDirectDomainFrontingWithSNIConfig")
testContext := newFrontingContext("TestDirectDomainFrontingWithSNIConfig")
testContext.Configure(certs, p, "akamai", cacheFile)

transport, ok := testContext.NewFronted(30 * time.Second)
Expand Down Expand Up @@ -84,7 +85,7 @@ func doTestDomainFronting(t *testing.T, cacheFile string, expectedMasqueradesAtE
}
certs := trustedCACerts(t)
p := testProvidersWithHosts(hosts)
testContext := NewFrontingContext("doTestDomainFronting")
testContext := newFrontingContext("doTestDomainFronting")
testContext.Configure(certs, p, testProviderID, cacheFile)

transport, ok := testContext.NewFronted(30 * time.Second)
Expand All @@ -103,8 +104,8 @@ func doTestDomainFronting(t *testing.T, cacheFile string, expectedMasqueradesAtE
}
require.True(t, doCheck(client, http.MethodGet, http.StatusOK, getURL))

instance, ok := testContext.instance.Get(0)
require.True(t, ok)
instance, err := testContext.instance.Get(eventual.DontWait)
require.NoError(t, err)
d := instance.(*fronted)

// Check the number of masquerades at the end, waiting until we get the right number
Expand Down Expand Up @@ -239,7 +240,7 @@ func TestHostAliasesBasic(t *testing.T) {
certs := x509.NewCertPool()
certs.AddCert(cloudSack.Certificate())

testContext := NewFrontingContext("TestHostAliasesBasic")
testContext := newFrontingContext("TestHostAliasesBasic")
testContext.Configure(certs, map[string]*Provider{"cloudsack": p}, "cloudsack", "")

rt, ok := testContext.NewFronted(30 * time.Second)
Expand Down Expand Up @@ -352,7 +353,7 @@ func TestHostAliasesMulti(t *testing.T) {
"sadcloud": p2,
}

testContext := NewFrontingContext("TestHostAliasesMulti")
testContext := newFrontingContext("TestHostAliasesMulti")
testContext.Configure(certs, providers, "cloudsack", "")
rt, ok := testContext.NewFronted(30 * time.Second)
if !assert.True(t, ok, "failed to obtain direct roundtripper") {
Expand Down Expand Up @@ -479,7 +480,7 @@ func TestPassthrough(t *testing.T) {
certs := x509.NewCertPool()
certs.AddCert(cloudSack.Certificate())

testContext := NewFrontingContext("TestPassthrough")
testContext := newFrontingContext("TestPassthrough")
testContext.Configure(certs, map[string]*Provider{"cloudsack": p}, "cloudsack", "")

rt, ok := testContext.NewFronted(30 * time.Second)
Expand Down Expand Up @@ -538,7 +539,7 @@ func TestCustomValidators(t *testing.T) {
sadCloudValidator := NewStatusCodeValidator(sadCloudCodes)
testURL := "https://abc.forbidden.com/quux"

setup := func(ctx *FrontingContext, validator ResponseValidator) {
setup := func(ctx *frontingContext, validator ResponseValidator) {
masq := []*Masquerade{{Domain: "example.com", IpAddress: sadCloudAddr}}
alias := map[string]string{
"abc.forbidden.com": "abc.sadcloud.io",
Expand Down Expand Up @@ -633,7 +634,7 @@ func TestCustomValidators(t *testing.T) {

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
testContext := NewFrontingContext(test.name)
testContext := newFrontingContext(test.name)
setup(testContext, test.validator)
direct, ok := testContext.NewFronted(30 * time.Second)
require.True(t, ok)
Expand Down
3 changes: 1 addition & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ module github.com/getlantern/fronted
go 1.22.3

require (
github.com/getlantern/eventual v1.0.0
github.com/getlantern/eventual/v2 v2.0.2
github.com/getlantern/golog v0.0.0-20190830074920-4ef2e798c2d7
github.com/getlantern/idletiming v0.0.0-20201229174729-33d04d220c4e
github.com/getlantern/keyman v0.0.0-20180207174507-f55e7280e93a
github.com/getlantern/netx v0.0.0-20210806160745-b824e2cad607
github.com/getlantern/ops v0.0.0-20230424193308-26325dfed3cf
Expand Down
10 changes: 2 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -33,30 +33,24 @@ github.com/getlantern/errors v0.0.0-20190325191628-abdb3e3e36f7/go.mod h1:l+xpFB
github.com/getlantern/errors v1.0.1/go.mod h1:l+xpFBrCtDLpK9qNjxs+cHU6+BAdlBaxHqikB6Lku3A=
github.com/getlantern/errors v1.0.3 h1:Ne4Ycj7NI1BtSyAfVeAT/DNoxz7/S2BUc3L2Ht1YSHE=
github.com/getlantern/errors v1.0.3/go.mod h1:m8C7H1qmouvsGpwQqk/6NUpIVMpfzUPn608aBZDYV04=
github.com/getlantern/eventual v1.0.0 h1:q56jlZhiDeWvdrc0QJ12AaWqcu/Z67wDDjdAUKGnYqc=
github.com/getlantern/eventual v1.0.0/go.mod h1:xL9T/pQI7i44INFSsKf4zDNz5bXA7P18j1cNd5qy/yI=
github.com/getlantern/eventual/v2 v2.0.2 h1:7b3N2oQBVqSHwm/8u7C8b6W+OkkjgZSmwUc1AdIkrHc=
github.com/getlantern/eventual/v2 v2.0.2/go.mod h1:o1VZHRk8UArBra+pwPSi23WrahBG4qgg4/ew6Mmlq84=
github.com/getlantern/fdcount v0.0.0-20190912142506-f89afd7367c4 h1:JdD4XSaT6/j6InM7MT1E4WRvzR8gurxfq53A3ML3B/Q=
github.com/getlantern/fdcount v0.0.0-20190912142506-f89afd7367c4/go.mod h1:XZwE+iIlAgr64OFbXKFNCllBwV4wEipPx8Hlo2gZdbM=
github.com/getlantern/filepersist v0.0.0-20160317154340-c5f0cd24e799 h1:FhkPUYCQYmoxS02r2GRrIV7dahUIncRl36xzs3/mnjA=
github.com/getlantern/filepersist v0.0.0-20160317154340-c5f0cd24e799/go.mod h1:8DGAx0LNUfXNnEH+fXI0s3OCBA/351kZCiz/8YSK3i8=
github.com/getlantern/golog v0.0.0-20190830074920-4ef2e798c2d7 h1:guBYzEaLz0Vfc/jv0czrr2z7qyzTOGC9hiQ0VC+hKjk=
github.com/getlantern/golog v0.0.0-20190830074920-4ef2e798c2d7/go.mod h1:zx/1xUUeYPy3Pcmet8OSXLbF47l+3y6hIPpyLWoR9oc=
github.com/getlantern/grtrack v0.0.0-20160824195228-cbf67d3fa0fd h1:GPrx88jy222gMuRHXxBSViT/3zdNO210nRAaXn+lL6s=
github.com/getlantern/grtrack v0.0.0-20160824195228-cbf67d3fa0fd/go.mod h1:RkQEgBdrJCH5tYJP2D+a/aJ216V3c9q8w/tCJtEiDoY=
github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7 h1:micT5vkcr9tOVk1FiH8SWKID8ultN44Z+yzd2y/Vyb0=
github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7/go.mod h1:dD3CgOrwlzca8ed61CsZouQS5h5jIzkK9ZWrTcf0s+o=
github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55 h1:XYzSdCbkzOC0FDNrgJqGRo8PCMFOBFL9py72DRs7bmc=
github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55/go.mod h1:6mmzY2kW1TOOrVy+r41Za2MxXM+hhqTtY3oBKd2AgFA=
github.com/getlantern/idletiming v0.0.0-20201229174729-33d04d220c4e h1:b0VWlP1TB369RANq5GnV76sGDm98eQwVJaaoH8OXOmw=
github.com/getlantern/idletiming v0.0.0-20201229174729-33d04d220c4e/go.mod h1:McaLC6faRlxJ9QjjqSjpEeYIjKnKA8+dzjoR+eYXCio=
github.com/getlantern/keyman v0.0.0-20180207174507-f55e7280e93a h1:SBw2c296eaLrrnydtLhcjgvNB1mDaXF1SSfW4DGt0kk=
github.com/getlantern/keyman v0.0.0-20180207174507-f55e7280e93a/go.mod h1:FMf0g72BHs14jVcD8i8ubEk4sMB6JdidBn67d44i3ws=
github.com/getlantern/mockconn v0.0.0-20190708122800-637bd46d8034/go.mod h1:+F5GJ7qGpQ03DBtcOEyQpM30ix4BLswdaojecFtsdy8=
github.com/getlantern/mockconn v0.0.0-20191023022503-481dbcceeb58/go.mod h1:+F5GJ7qGpQ03DBtcOEyQpM30ix4BLswdaojecFtsdy8=
github.com/getlantern/mockconn v0.0.0-20200818071412-cb30d065a848 h1:2MhMMVBTnaHrst6HyWFDhwQCaJ05PZuOv1bE2gN8WFY=
github.com/getlantern/mockconn v0.0.0-20200818071412-cb30d065a848/go.mod h1:+F5GJ7qGpQ03DBtcOEyQpM30ix4BLswdaojecFtsdy8=
github.com/getlantern/mtime v0.0.0-20170117193331-ba114e4a82b0/go.mod h1:u537FS7ld4Whf7h7/0ql/myAudWWBNgeRhgE9XXH4Pk=
github.com/getlantern/mtime v0.0.0-20200228202836-084e1d8282b0/go.mod h1:GfzwugvtH7YcmNIrHHizeyImsgEdyL88YkdnK28B14c=
github.com/getlantern/mtime v0.0.0-20200417132445-23682092d1f7 h1:03J6Cb42EG06lHgpOFGm5BOax4qFqlSbSeKO2RGrj2g=
github.com/getlantern/mtime v0.0.0-20200417132445-23682092d1f7/go.mod h1:GfzwugvtH7YcmNIrHHizeyImsgEdyL88YkdnK28B14c=
github.com/getlantern/netx v0.0.0-20190110220209-9912de6f94fd/go.mod h1:wKdY0ikOgzrWSeB9UyBVKPRhjXQ+vTb+BPeJuypUuNE=
Expand Down

0 comments on commit e357a92

Please sign in to comment.