Skip to content

Commit

Permalink
Merge pull request #4325 from getlantern/issue-4319
Browse files Browse the repository at this point in the history
Move the device ID to settings and linter cleanups closes #4319
  • Loading branch information
xiam committed May 18, 2016
2 parents 63086bc + a994246 commit 5218d29
Show file tree
Hide file tree
Showing 12 changed files with 88 additions and 83 deletions.
19 changes: 6 additions & 13 deletions src/github.com/getlantern/flashlight/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ import (
)

var (
log = golog.LoggerFor("flashlight")
log = golog.LoggerFor("flashlight")
settings *Settings
)

func init() {
Expand Down Expand Up @@ -52,20 +53,11 @@ func (app *App) Init() {

// LogPanicAndExit logs a panic and then exits the application.
func (app *App) LogPanicAndExit(msg string) {
cfg, err := config.Init(settings,
flashlight.PackageVersion,
app.Flags["configdir"].(string),
app.Flags["stickyconfig"].(bool),
app.Flags,
)
if err != nil {
panic("Error initializing config")
}
if err := logging.EnableFileLogging(); err != nil {
panic("Error initializing logging")
}

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

log.Error(msg)

Expand Down Expand Up @@ -102,7 +94,8 @@ func (app *App) Run() error {
app.afterStart,
app.onConfigUpdate,
settings,
app.Exit)
app.Exit,
settings.GetDeviceID())
if err != nil {
app.Exit(err)
return
Expand Down Expand Up @@ -164,7 +157,7 @@ func (app *App) beforeStart(cfg *config.Config) bool {

// Only run analytics once on startup.
if settings.IsAutoReport() {
stopAnalytics := analytics.Start(cfg.Client.DeviceID, flashlight.Version)
stopAnalytics := analytics.Start(settings.GetDeviceID(), flashlight.Version)
app.AddExitFunc(stopAnalytics)
}
watchDirectAddrs()
Expand Down
36 changes: 24 additions & 12 deletions src/github.com/getlantern/flashlight/app/settings.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package app

import (
"encoding/base64"
"io/ioutil"
"net/http"
"path/filepath"
"sync"

"code.google.com/p/go-uuid/uuid"

"github.com/getlantern/appdir"
"github.com/getlantern/launcher"
"github.com/getlantern/yaml"
Expand All @@ -19,7 +22,6 @@ const (

var (
service *ui.Service
settings *Settings
httpClient *http.Client
path = filepath.Join(appdir.General("Lantern"), "settings.yaml")
once = &sync.Once{}
Expand Down Expand Up @@ -49,11 +51,10 @@ func loadSettings(version, revisionDate, buildDate string) *Settings {

// loadSettings loads the initial settings at startup, either from disk or using defaults.
func loadSettingsFrom(version, revisionDate, buildDate, path string) *Settings {

log.Debug("Loading settings")
// Create default settings that may or may not be overridden from an existing file
// on disk.
settings = &Settings{
set := &Settings{
AutoReport: true,
AutoLaunch: true,
ProxyAll: false,
Expand All @@ -63,33 +64,37 @@ func loadSettingsFrom(version, revisionDate, buildDate, path string) *Settings {
// Use settings from disk if they're available.
if bytes, err := ioutil.ReadFile(path); err != nil {
log.Debugf("Could not read file %v", err)
} else if err := yaml.Unmarshal(bytes, settings); err != nil {
} else if err := yaml.Unmarshal(bytes, set); err != nil {
log.Errorf("Could not load yaml %v", err)
// Just keep going with the original settings not from disk.
} else {
log.Debugf("Loaded settings from %v", path)
}

if settings.AutoLaunch {
launcher.CreateLaunchFile(settings.AutoLaunch)
// We always just set the device ID to the MAC address on the system. Note
// this ignores what's on disk, if anything.
set.DeviceID = base64.StdEncoding.EncodeToString(uuid.NodeID())

if set.AutoLaunch {
launcher.CreateLaunchFile(set.AutoLaunch)
}
// always override below 3 attributes as they are not meant to be persisted across versions
settings.Version = version
settings.BuildDate = buildDate
settings.RevisionDate = revisionDate
set.Version = version
set.BuildDate = buildDate
set.RevisionDate = revisionDate

// Only configure the UI once. This will typically be the case in the normal
// application flow, but tests might call Load twice, for example, which we
// want to allow.
once.Do(func() {
err := settings.start()
err := set.start()
if err != nil {
log.Errorf("Unable to register settings service: %q", err)
return
}
go settings.read(service.In, service.Out)
go set.read(service.In, service.Out)
})
return settings
return set
}

// start the settings service that synchronizes Lantern's configuration with every UI client
Expand Down Expand Up @@ -214,6 +219,13 @@ func (s *Settings) SetDeviceID(deviceID string) {
s.DeviceID = deviceID
}

// GetDeviceID returns the unique ID of this device.
func (s *Settings) GetDeviceID() string {
s.RLock()
defer s.RUnlock()
return s.DeviceID
}

// SetToken sets the user token
func (s *Settings) SetToken(token string) {
s.Lock()
Expand Down
4 changes: 2 additions & 2 deletions src/github.com/getlantern/flashlight/app/settings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,6 @@ func TestNotPersistVersion(t *testing.T) {
version := "version-not-on-disk"
revisionDate := "1970-1-1"
buildDate := "1970-1-1"
loadSettings(version, revisionDate, buildDate)
assert.Equal(t, settings.Version, version, "Should be set to version")
set := loadSettings(version, revisionDate, buildDate)
assert.Equal(t, version, set.Version, "Should be set to version")
}
4 changes: 2 additions & 2 deletions src/github.com/getlantern/flashlight/client/balancer.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func (client *Client) getBalancer() *balancer.Balancer {

// initBalancer takes hosts from cfg.ChainedServers and it uses them to create a
// balancer.
func (client *Client) initBalancer(cfg *ClientConfig) (*balancer.Balancer, error) {
func (client *Client) initBalancer(cfg *ClientConfig, deviceID string) (*balancer.Balancer, error) {
if len(cfg.ChainedServers) == 0 {
return nil, fmt.Errorf("No chained servers configured, not initializing balancer")
}
Expand All @@ -32,7 +32,7 @@ func (client *Client) initBalancer(cfg *ClientConfig) (*balancer.Balancer, error
// Add chained (CONNECT proxy) servers.
log.Debugf("Adding %d chained servers", len(cfg.ChainedServers))
for _, s := range cfg.ChainedServers {
dialer, err := s.Dialer(cfg.DeviceID)
dialer, err := s.Dialer(deviceID)
if err == nil {
log.Debugf("Adding chained server: %v", s.Addr)
dialers = append(dialers, dialer)
Expand Down
2 changes: 2 additions & 0 deletions src/github.com/getlantern/flashlight/client/chained.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ var ForceChainedProxyAddr string
// ForceAuthToken - If specified, auth token will be forced to this
var ForceAuthToken string

// ChainedServerInfo contains all the data for connecting to a given chained
// server.
type ChainedServerInfo struct {
// Addr: the host:port of the upstream proxy server
Addr string
Expand Down
38 changes: 22 additions & 16 deletions src/github.com/getlantern/flashlight/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const (
// LanternSpecialDomain is a special domain for use by lantern that gets
// resolved to localhost by the proxy
LanternSpecialDomain = "ui.lantern.io"
LanternSpecialDomainWithColon = "ui.lantern.io:"
lanternSpecialDomainWithColon = "ui.lantern.io:"
)

var (
Expand All @@ -30,7 +30,8 @@ var (
// UIAddr is the address at which UI is to be found
UIAddr string

addr = eventual.NewValue()
addr = eventual.NewValue()

socksAddr = eventual.NewValue()
)

Expand All @@ -43,7 +44,6 @@ type Client struct {
// WriteTimeout: (optional) timeout for write ops
WriteTimeout time.Duration

proxyAll atomic.Value
cfgHolder atomic.Value
priorCfg *ClientConfig
cfgMutex sync.RWMutex
Expand All @@ -55,12 +55,18 @@ type Client struct {
rp eventual.Value

l net.Listener

proxyAll func() bool
}

func NewClient() *Client {
// NewClient creates a new client that does things like starts the HTTP and
// SOCKS proxies. It take a function for determing whether or not to proxy
// all traffic.
func NewClient(proxyAll func() bool) *Client {
return &Client{
bal: eventual.NewValue(),
rp: eventual.NewValue(),
bal: eventual.NewValue(),
rp: eventual.NewValue(),
proxyAll: proxyAll,
}
}

Expand All @@ -70,6 +76,8 @@ func Addr(timeout time.Duration) (interface{}, bool) {
return addr.Get(timeout)
}

// Addr returns the address at which the client is listening with HTTP, blocking
// until the given timeout for an address to become available.
func (client *Client) Addr(timeout time.Duration) (interface{}, bool) {
return Addr(timeout)
}
Expand All @@ -80,6 +88,8 @@ func Socks5Addr(timeout time.Duration) (interface{}, bool) {
return socksAddr.Get(timeout)
}

// Socks5Addr returns the address at which the client is listening with SOCKS5,
// blocking until the given timeout for an address to become available.
func (client *Client) Socks5Addr(timeout time.Duration) (interface{}, bool) {
return Socks5Addr(timeout)
}
Expand Down Expand Up @@ -116,6 +126,8 @@ func (client *Client) ListenAndServeHTTP(requestedAddr string, onListeningFn fun
return httpServer.Serve(l)
}

// ListenAndServeSOCKS5 starts the SOCKS server listening at the specified
// address.
func (client *Client) ListenAndServeSOCKS5(requestedAddr string) error {
var err error
var l net.Listener
Expand Down Expand Up @@ -148,7 +160,7 @@ func (client *Client) ListenAndServeSOCKS5(requestedAddr string) error {

// Configure updates the client's configuration. Configure can be called
// before or after ListenAndServe, and can be called multiple times.
func (client *Client) Configure(cfg *ClientConfig, proxyAll func() bool) {
func (client *Client) Configure(cfg *ClientConfig, deviceID string) {
client.cfgMutex.Lock()
defer client.cfgMutex.Unlock()

Expand All @@ -166,10 +178,8 @@ func (client *Client) Configure(cfg *ClientConfig, proxyAll func() bool) {

log.Debugf("Requiring minimum QOS of %d", cfg.MinQOS)
client.cfgHolder.Store(cfg)
log.Debugf("Proxy all traffic or not: %v", proxyAll())
client.proxyAll.Store(proxyAll)

bal, err := client.initBalancer(cfg)
bal, err := client.initBalancer(cfg, deviceID)
if err != nil {
log.Error(err)
} else if bal != nil {
Expand All @@ -185,10 +195,6 @@ func (client *Client) Stop() error {
return client.l.Close()
}

func (client *Client) ProxyAll() bool {
return client.proxyAll.Load().(func() bool)()
}

func (client *Client) cfg() *ClientConfig {
return client.cfgHolder.Load().(*ClientConfig)
}
Expand All @@ -198,7 +204,7 @@ func (client *Client) proxiedDialer(orig func(network, addr string) (net.Conn, e

return func(network, addr string) (net.Conn, error) {
var proxied func(network, addr string) (net.Conn, error)
if client.ProxyAll() {
if client.proxyAll() {
proxied = orig
} else {
proxied = detourDialer
Expand All @@ -214,7 +220,7 @@ func (client *Client) proxiedDialer(orig func(network, addr string) (net.Conn, e
}

func isLanternSpecialDomain(addr string) bool {
return strings.Index(addr, LanternSpecialDomainWithColon) == 0
return strings.Index(addr, lanternSpecialDomainWithColon) == 0
}

func rewriteLanternSpecialDomain(addr string) string {
Expand Down
3 changes: 0 additions & 3 deletions src/github.com/getlantern/flashlight/client/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@ type ClientConfig struct {
// MinQOS: (optional) the minimum QOS to require from proxies.
MinQOS int

// Unique identifier for this device
DeviceID string

// List of CONNECT ports that are proxied via the remote proxy. Other ports
// will be handled with direct connections.
ProxiedCONNECTPorts []int
Expand Down
8 changes: 4 additions & 4 deletions src/github.com/getlantern/flashlight/client/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,13 @@ func (client *Client) intercept(resp http.ResponseWriter, req *http.Request) {
// after completed send / receive so that won't cause problem.
closeConns := func() {
if clientConn != nil {
if err := clientConn.Close(); err != nil {
log.Debugf("Error closing the out connection: %s", err)
if closeErr := clientConn.Close(); closeErr != nil {
log.Debugf("Error closing the out connection: %s", closeErr)
}
}
if connOut != nil {
if err := connOut.Close(); err != nil {
log.Debugf("Error closing the client connection: %s", err)
if closeErr := connOut.Close(); closeErr != nil {
log.Debugf("Error closing the client connection: %s", closeErr)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ func defaultDialFactory(s *ChainedServerInfo, deviceID string) (dialFN, error) {
return nil, err
}
if !forceProxy && !conn.ConnectionState().PeerCertificates[0].Equal(x509cert) {
if err := conn.Close(); err != nil {
log.Debugf("Error closing chained server connection: %s", err)
if closeErr := conn.Close(); closeErr != nil {
log.Debugf("Error closing chained server connection: %s", closeErr)
}
return nil, fmt.Errorf("Server's certificate didn't match expected!")
}
Expand Down

0 comments on commit 5218d29

Please sign in to comment.