package main
import (
- "github.com/sasha-s/go-deadlock"
"runtime"
"sync"
"sync/atomic"
// synchronized resources (locks acquired in order)
state struct {
- mutex deadlock.Mutex
+ mutex sync.Mutex
changing AtomicBool
current bool
}
net struct {
- mutex deadlock.RWMutex
+ mutex sync.RWMutex
bind Bind // bind interface
port uint16 // listening port
fwmark uint32 // mark value (0 = disabled)
}
noise struct {
- mutex deadlock.RWMutex
+ mutex sync.RWMutex
privateKey NoisePrivateKey
publicKey NoisePublicKey
}
routing struct {
- mutex deadlock.RWMutex
+ mutex sync.RWMutex
table RoutingTable
}
peers struct {
- mutex deadlock.RWMutex
+ mutex sync.RWMutex
keyMap map[NoisePublicKey]*Peer
}
return
}
- func() {
+ // compare to current state of device
- // compare to current state of device
-
- device.state.mutex.Lock()
- defer device.state.mutex.Unlock()
-
- newIsUp := device.isUp.Get()
-
- if newIsUp == device.state.current {
- device.state.changing.Set(false)
- return
- }
-
- // change state of device
-
- switch newIsUp {
- case true:
- if err := device.BindUpdate(); err != nil {
- device.isUp.Set(false)
- break
- }
+ device.state.mutex.Lock()
- device.peers.mutex.Lock()
- defer device.peers.mutex.Unlock()
+ newIsUp := device.isUp.Get()
- for _, peer := range device.peers.keyMap {
- peer.Start()
- }
+ if newIsUp == device.state.current {
+ device.state.changing.Set(false)
+ device.state.mutex.Unlock()
+ return
+ }
- case false:
- device.BindClose()
+ // change state of device
- device.peers.mutex.Lock()
- defer device.peers.mutex.Unlock()
+ switch newIsUp {
+ case true:
+ if err := device.BindUpdate(); err != nil {
+ device.isUp.Set(false)
+ break
+ }
+ device.peers.mutex.Lock()
+ for _, peer := range device.peers.keyMap {
+ peer.Start()
+ }
+ device.peers.mutex.Unlock()
- for _, peer := range device.peers.keyMap {
- println("stopping peer")
- peer.Stop()
- }
+ case false:
+ device.BindClose()
+ device.peers.mutex.Lock()
+ for _, peer := range device.peers.keyMap {
+ peer.Stop()
}
+ device.peers.mutex.Unlock()
+ }
- // update state variables
+ // update state variables
- device.state.current = newIsUp
- device.state.changing.Set(false)
- }()
+ device.state.current = newIsUp
+ device.state.changing.Set(false)
+ device.state.mutex.Unlock()
// check for state change in the mean time
"encoding/base64"
"errors"
"fmt"
- "github.com/sasha-s/go-deadlock"
"sync"
"time"
)
type Peer struct {
isRunning AtomicBool
- mutex deadlock.RWMutex
+ mutex sync.RWMutex
persistentKeepaliveInterval uint64
keyPairs KeyPairs
handshake Handshake
}
time struct {
- mutex deadlock.RWMutex
+ mutex sync.RWMutex
lastSend time.Time // last send message
lastHandshake time.Time // last completed handshake
nextKeepalive time.Time
}
routines struct {
- mutex deadlock.Mutex // held when stopping / starting routines
+ mutex sync.Mutex // held when stopping / starting routines
starting sync.WaitGroup // routines pending start
stopping sync.WaitGroup // routines pending stop
stop Signal // size 0, stop all go-routines in peer