Skip to content

Commit

Permalink
reverse-merging from master
Browse files Browse the repository at this point in the history
  • Loading branch information
myleshorton committed Aug 3, 2016
2 parents 49ef327 + 6905970 commit cb9e104
Show file tree
Hide file tree
Showing 15 changed files with 260 additions and 154 deletions.
9 changes: 8 additions & 1 deletion src/github.com/getlantern/balancer/balancer.go
Expand Up @@ -30,11 +30,12 @@ var (

// Balancer balances connections among multiple Dialers.
type Balancer struct {
// make sure to align on 64bit boundary
lastDialTime int64 // Time.UnixNano()
st Strategy
mu sync.RWMutex
dialers dialerHeap
trusted dialerHeap
lastDialTime int64 // Time.UnixNano()
}

// New creates a new Balancer using the supplied Strategy and Dialers.
Expand Down Expand Up @@ -101,11 +102,17 @@ func (b *Balancer) Dial(network, addr string) (net.Conn, error) {
trustedOnly = true
}

var lastDialer *dialer
for i := 0; i < dialAttempts; i++ {
d, pickErr := b.pickDialer(trustedOnly)
if pickErr != nil {
return nil, pickErr
}
if d == lastDialer {
log.Debugf("Skip dialing %s://%s with same dailer %s", network, addr, d.Label)
continue
}
lastDialer = d
log.Tracef("Dialing %s://%s with %s", network, addr, d.Label)
conn, err := d.dial(network, addr)
if err != nil {
Expand Down
21 changes: 21 additions & 0 deletions src/github.com/getlantern/balancer/balancer_test.go
Expand Up @@ -57,6 +57,27 @@ func TestSingleDialer(t *testing.T) {
}
}

func TestRetryOnBadDialer(t *testing.T) {
addr, l := echoServer()
defer func() { _ = l.Close() }()

d1Attempts := int32(0)
dialer1 := newCondDialer(1, func() bool { atomic.AddInt32(&d1Attempts, 1); return true })
d2Attempts := int32(0)
dialer2 := newCondDialer(2, func() bool { atomic.AddInt32(&d2Attempts, 1); return true })

b := New(Sticky, dialer1)
_, err := b.Dial("tcp", addr)
if assert.Error(t, err, "Dialing bad dialer should fail") {
assert.EqualValues(t, 1, atomic.LoadInt32(&d1Attempts), "should try same dialer only once")
}
b.Reset(dialer1, dialer2)
_, err = b.Dial("tcp", addr)
if assert.Error(t, err, "Dialing bad dialer should fail") {
assert.EqualValues(t, dialAttempts, atomic.LoadInt32(&d1Attempts)+atomic.LoadInt32(&d2Attempts), "should try enough times when there are more then 1 dialer")
}
}

func TestRandomDialer(t *testing.T) {
addr, l := echoServer()
defer func() { _ = l.Close() }()
Expand Down
2 changes: 1 addition & 1 deletion src/github.com/getlantern/chained/dialer.go
Expand Up @@ -49,7 +49,7 @@ func (d *dialer) Dial(network, addr string) (net.Conn, error) {
// that we should send a CONNECT request and tunnel all traffic through
// that.
if network == "connect" {
log.Debugf("Sending CONNECT REQUEST")
log.Tracef("Sending CONNECT REQUEST")
if err := d.sendCONNECT("tcp", addr, conn); err != nil {
// We discard this error, since we are only interested in sendCONNECT
_ = conn.Close()
Expand Down
34 changes: 29 additions & 5 deletions src/github.com/getlantern/errors/errors.go
Expand Up @@ -93,6 +93,18 @@ type Error interface {
error
context.Contextual

// ErrorClean returns a non-parameterized version of the error whenever
// possible. For example, if the error text is:
//
// unable to dial www.google.com caused by: i/o timeout
//
// ErrorClean might return:
//
// unable to dial %v caused by: %v
//
// This can be useful when performing analytics on the error.
ErrorClean() string

// MultiLinePrinter implements the interface golog.MultiLine
MultiLinePrinter() func(buf *bytes.Buffer) bool

Expand Down Expand Up @@ -138,7 +150,7 @@ func NewOffset(offset int, desc string, args ...interface{}) Error {
break
}
}
e := buildError(fmt.Sprintf(desc, args...), nil, Wrap(cause))
e := buildError(desc, fmt.Sprintf(desc, args...), nil, Wrap(cause))
e.attachStack(2 + offset)
return e
}
Expand Down Expand Up @@ -202,9 +214,13 @@ func (e *structured) RootCause() error {
return e.cause.RootCause()
}

func (e *structured) ErrorClean() string {
return e.data["error"].(string)
}

// Error satisfies the error interface
func (e *structured) Error() string {
return e.data["error"].(string) + e.hiddenID
return e.data["error_text"].(string) + e.hiddenID
}

func (e *structured) MultiLinePrinter() func(buf *bytes.Buffer) bool {
Expand Down Expand Up @@ -276,15 +292,16 @@ func wrapSkipFrames(err error, skip int) Error {
}

// Create a new *structured
return buildError(err.Error(), err, cause)
return buildError("", "", err, cause)
}

func (e *structured) attachStack(skip int) {
call := stack.Caller(skip)
e.callStack = stack.Trace().TrimBelow(call)
e.data["error_location"] = fmt.Sprintf("%+n (%s:%d)", call, call, call)
}

func buildError(desc string, wrapped error, cause Error) *structured {
func buildError(desc string, fullText string, wrapped error, cause Error) *structured {
e := &structured{
data: make(context.Map),
// We capture the current context to allow it to propagate to higher layers.
Expand All @@ -308,7 +325,14 @@ func buildError(desc string, wrapped error, cause Error) *structured {
}
}
}
e.data["error"] = hidden.Clean(desc)

cleanedDesc := hidden.Clean(desc)
e.data["error"] = cleanedDesc
if fullText != "" {
e.data["error_text"] = hidden.Clean(fullText)
} else {
e.data["error_text"] = cleanedDesc
}
e.data["error_type"] = errorType

return e
Expand Down
4 changes: 4 additions & 0 deletions src/github.com/getlantern/errors/errors_test.go
Expand Up @@ -54,6 +54,10 @@ func TestNewWithCause(t *testing.T) {
cause := buildCause()
outer := New("Hello %v", cause)
assert.Equal(t, "Hello World", hidden.Clean(outer.Error()))
assert.Equal(t, "Hello %v", outer.(*structured).ErrorClean())
assert.Equal(t,
"github.com/getlantern/errors.TestNewWithCause (errors_test.go:999)",
replaceNumbers.ReplaceAllString(outer.(*structured).data["error_location"].(string), "999"))
assert.Equal(t, cause, outer.(*structured).cause)

// Make sure that stacktrace prints out okay
Expand Down
2 changes: 1 addition & 1 deletion src/github.com/getlantern/flashlight/app/app.go
Expand Up @@ -57,7 +57,7 @@ func (app *App) LogPanicAndExit(msg string) {
panic("Error initializing logging")
}

<-logging.Configure("", "dummy-device-id-for-panic", flashlight.Version, flashlight.RevisionDate, 0, 0)
<-logging.Configure("", "dummy-device-id-for-panic", flashlight.Version, flashlight.RevisionDate, 0, 0, 0)

log.Error(msg)

Expand Down
2 changes: 2 additions & 0 deletions src/github.com/getlantern/flashlight/client/client.go
Expand Up @@ -202,7 +202,9 @@ func (client *Client) proxiedDialer(orig func(network, addr string) (net.Conn, e
log.Tracef("Rewriting %v to %v", addr, rewritten)
return net.Dial(network, rewritten)
}
start := time.Now()
conn, err := proxied(network, addr)
log.Debugf("Dialing proxy takes %v for %s", time.Since(start), addr)
return conn, op.FailIf(err)
}
}
Expand Down
3 changes: 1 addition & 2 deletions src/github.com/getlantern/flashlight/client/handler.go
Expand Up @@ -138,16 +138,15 @@ func pipeData(clientConn net.Conn, connOut net.Conn, op *ops.Op, closeFunc func(
}

func respondOK(writer io.Writer, req *http.Request) error {
log.Debugf("Responding OK to %v", req.URL)
return respondHijacked(writer, req, http.StatusOK)
}

func respondBadGatewayHijacked(writer io.Writer, req *http.Request) error {
log.Debugf("Responding %v", http.StatusBadGateway)
return respondHijacked(writer, req, http.StatusBadGateway)
}

func respondHijacked(writer io.Writer, req *http.Request, statusCode int) error {
log.Debugf("Responding %v to %v", statusCode, req.URL)
defer func() {
if err := req.Body.Close(); err != nil {
log.Debugf("Error closing body of OK response: %s", err)
Expand Down
11 changes: 6 additions & 5 deletions src/github.com/getlantern/flashlight/config/global.go
Expand Up @@ -16,11 +16,12 @@ type Global struct {
CloudConfigCA string

// AutoUpdateCA is the CA key to pin for auto-updates.
AutoUpdateCA string
UpdateServerURL string
BordaReportInterval time.Duration
BordaSamplePercentage float64
Client *client.ClientConfig
AutoUpdateCA string
UpdateServerURL string
BordaReportInterval time.Duration
BordaSamplePercentage float64
LogglySamplePercentage float64
Client *client.ClientConfig

// ProxiedSites are domains that get routed through Lantern rather than accessed directly.
ProxiedSites *proxiedsites.Config
Expand Down
7 changes: 5 additions & 2 deletions src/github.com/getlantern/flashlight/flashlight.go
Expand Up @@ -45,7 +45,8 @@ var (
// BuildDate is the date the code was actually built.
BuildDate string // The actual date and time the binary was built.

cfgMutex sync.Mutex
cfgMutex sync.Mutex
configureLoggingOnce sync.Once
)

func bestPackageVersion() string {
Expand Down Expand Up @@ -141,7 +142,9 @@ func applyClientConfig(client *client.Client, cfg *config.Global, deviceID strin
} else if cfg.Client != nil {
fronted.Configure(certs, cfg.Client.MasqueradeSets, filepath.Join(appdir.General("Lantern"), "masquerade_cache"))
}
logging.Configure(cfg.CloudConfigCA, deviceID, Version, RevisionDate, cfg.BordaReportInterval, cfg.BordaSamplePercentage)
configureLoggingOnce.Do(func() {
logging.Configure(cfg.CloudConfigCA, deviceID, Version, RevisionDate, cfg.BordaReportInterval, cfg.BordaSamplePercentage, cfg.LogglySamplePercentage)
})
}

func getTrustedCACerts(cfg *config.Global) (pool *x509.CertPool, err error) {
Expand Down

0 comments on commit cb9e104

Please sign in to comment.