mirror of
https://github.com/netbirdio/netbird.git
synced 2024-12-11 17:31:12 +01:00
2dec016201
In case of 'always-on' feature has switched on, after the reboot the service do not start properly in all cases. If the device is in offline state (no internet connection) the auth login steps will fail and the service will stop. For the auth steps make no sense in this case because if the OS start the service we do not have option for the user interaction.
146 lines
2.9 KiB
Go
146 lines
2.9 KiB
Go
package peer
|
|
|
|
import (
|
|
"sync"
|
|
)
|
|
|
|
const (
|
|
stateDisconnected = iota
|
|
stateConnected
|
|
stateConnecting
|
|
stateDisconnecting
|
|
)
|
|
|
|
type notifier struct {
|
|
serverStateLock sync.Mutex
|
|
listenersLock sync.Mutex
|
|
listener Listener
|
|
currentClientState bool
|
|
lastNotification int
|
|
lastNumberOfPeers int
|
|
}
|
|
|
|
func newNotifier() *notifier {
|
|
return ¬ifier{}
|
|
}
|
|
|
|
func (n *notifier) setListener(listener Listener) {
|
|
n.listenersLock.Lock()
|
|
defer n.listenersLock.Unlock()
|
|
|
|
n.serverStateLock.Lock()
|
|
n.notifyListener(listener, n.lastNotification)
|
|
listener.OnPeersListChanged(n.lastNumberOfPeers)
|
|
n.serverStateLock.Unlock()
|
|
|
|
n.listener = listener
|
|
}
|
|
|
|
func (n *notifier) removeListener() {
|
|
n.listenersLock.Lock()
|
|
defer n.listenersLock.Unlock()
|
|
n.listener = nil
|
|
}
|
|
|
|
func (n *notifier) updateServerStates(mgmState bool, signalState bool) {
|
|
n.serverStateLock.Lock()
|
|
defer n.serverStateLock.Unlock()
|
|
|
|
calculatedState := n.calculateState(mgmState, signalState)
|
|
|
|
if !n.isServerStateChanged(calculatedState) {
|
|
return
|
|
}
|
|
|
|
n.lastNotification = calculatedState
|
|
|
|
n.notify(n.lastNotification)
|
|
}
|
|
|
|
func (n *notifier) clientStart() {
|
|
n.serverStateLock.Lock()
|
|
defer n.serverStateLock.Unlock()
|
|
n.currentClientState = true
|
|
n.lastNotification = stateConnecting
|
|
n.notify(n.lastNotification)
|
|
}
|
|
|
|
func (n *notifier) clientStop() {
|
|
n.serverStateLock.Lock()
|
|
defer n.serverStateLock.Unlock()
|
|
n.currentClientState = false
|
|
n.lastNotification = stateDisconnected
|
|
n.notify(n.lastNotification)
|
|
}
|
|
|
|
func (n *notifier) clientTearDown() {
|
|
n.serverStateLock.Lock()
|
|
defer n.serverStateLock.Unlock()
|
|
n.currentClientState = false
|
|
n.lastNotification = stateDisconnecting
|
|
n.notify(n.lastNotification)
|
|
}
|
|
|
|
func (n *notifier) isServerStateChanged(newState int) bool {
|
|
return n.lastNotification != newState
|
|
}
|
|
|
|
func (n *notifier) notify(state int) {
|
|
n.listenersLock.Lock()
|
|
defer n.listenersLock.Unlock()
|
|
if n.listener == nil {
|
|
return
|
|
}
|
|
n.notifyListener(n.listener, state)
|
|
}
|
|
|
|
func (n *notifier) notifyListener(l Listener, state int) {
|
|
go func() {
|
|
switch state {
|
|
case stateDisconnected:
|
|
l.OnDisconnected()
|
|
case stateConnected:
|
|
l.OnConnected()
|
|
case stateConnecting:
|
|
l.OnConnecting()
|
|
case stateDisconnecting:
|
|
l.OnDisconnecting()
|
|
}
|
|
}()
|
|
}
|
|
|
|
func (n *notifier) calculateState(managementConn, signalConn bool) int {
|
|
if managementConn && signalConn {
|
|
return stateConnected
|
|
}
|
|
|
|
if !managementConn && !signalConn && !n.currentClientState {
|
|
return stateDisconnected
|
|
}
|
|
|
|
if n.lastNotification == stateDisconnecting {
|
|
return stateDisconnecting
|
|
}
|
|
|
|
return stateConnecting
|
|
}
|
|
|
|
func (n *notifier) peerListChanged(numOfPeers int) {
|
|
n.lastNumberOfPeers = numOfPeers
|
|
n.listenersLock.Lock()
|
|
defer n.listenersLock.Unlock()
|
|
if n.listener == nil {
|
|
return
|
|
}
|
|
n.listener.OnPeersListChanged(numOfPeers)
|
|
}
|
|
|
|
func (n *notifier) localAddressChanged(fqdn, address string) {
|
|
n.listenersLock.Lock()
|
|
defer n.listenersLock.Unlock()
|
|
if n.listener == nil {
|
|
return
|
|
}
|
|
n.listener.OnAddressChanged(fqdn, address)
|
|
}
|