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 stun client datarace #1237

Merged
merged 2 commits into from
May 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
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
3 changes: 2 additions & 1 deletion pkg/visor/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ func (v *Visor) Overview() (*Overview, error) {
newTransportSummary(v.tpM, tp, true, v.router.SetupIsTrusted(tp.Remote())))
return true
})
if v.stunClient != nil {

if v.isStunReady() {
switch v.stunClient.NATType {
case stun.NATNone, stun.NATFull, stun.NATRestricted, stun.NATPortRestricted:
publicIP = v.stunClient.PublicIP.IP()
Expand Down
6 changes: 3 additions & 3 deletions pkg/visor/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,12 +279,12 @@ func initDiscovery(ctx context.Context, v *Visor, log *logging.Logger) error {
}

func initStunClient(ctx context.Context, v *Visor, log *logging.Logger) error {
defer v.wgStunClient.Done()

sc := network.GetStunDetails(v.conf.StunServers, log)
v.initLock.Lock()
v.stunClient = sc
v.initLock.Unlock()
v.stunReadyOnce.Do(func() { close(v.stunReady) })
return nil
}

Expand Down Expand Up @@ -517,7 +517,7 @@ func getRouteSetupHooks(ctx context.Context, v *Visor, log *logging.Logger) []ro
ntype := network.Type(trans)

// Wait until stun client is ready
v.wgStunClient.Wait()
<-v.stunReady

// skip if SUDPH is under symmetric NAT / under UDP firewall.
if ntype == network.SUDPH && (v.stunClient.NATType == stun.NATSymmetric ||
Expand Down Expand Up @@ -1157,7 +1157,7 @@ func getPublicIP(v *Visor, service string) (pIP string, err error) {
}

// Wait until stun client is ready
v.wgStunClient.Wait()
<-v.stunReady

pIP = v.stunClient.PublicIP.IP()
return pIP, nil
Expand Down
26 changes: 18 additions & 8 deletions pkg/visor/visor.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,14 @@ type Visor struct {
trackers *dmsgtracker.Manager
trackersReady bool

stunClient *network.StunDetails
wgStunClient *sync.WaitGroup
tpM *transport.Manager
arClient addrresolver.APIClient
router router.Router
rfClient rfclient.Client
stunClient *network.StunDetails
stunReady chan struct{}
stunReadyOnce sync.Once

tpM *transport.Manager
arClient addrresolver.APIClient
router router.Router
rfClient rfclient.Client

procM appserver.ProcManager // proc manager
appL *launcher.Launcher // app launcher
Expand Down Expand Up @@ -118,10 +120,9 @@ func NewVisor(ctx context.Context, conf *visorconfig.V1, restartCtx *restart.Con
restartCtx: restartCtx,
initLock: new(sync.RWMutex),
isServicesHealthy: newInternalHealthInfo(),
wgStunClient: new(sync.WaitGroup),
stunReady: make(chan struct{}),
trackersReady: false,
}
v.wgStunClient.Add(1)
v.isServicesHealthy.init()

if logLvl, err := logging.LevelFromString(conf.LogLevel); err != nil {
Expand Down Expand Up @@ -196,6 +197,15 @@ func (v *Visor) processRuntimeErrs() bool {
}
}

func (v *Visor) isStunReady() bool {
select {
case <-v.stunReady:
return true
default:
return false
}
}

// Close safely stops spawned Apps and Visor.
func (v *Visor) Close() error {
if v == nil {
Expand Down