aboutsummaryrefslogtreecommitdiff
path: root/src/device.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/device.go')
-rw-r--r--src/device.go221
1 files changed, 0 insertions, 221 deletions
diff --git a/src/device.go b/src/device.go
deleted file mode 100644
index a3461ad..0000000
--- a/src/device.go
+++ /dev/null
@@ -1,221 +0,0 @@
-package main
-
-import (
- "runtime"
- "sync"
- "sync/atomic"
- "time"
-)
-
-type Device struct {
- closed AtomicBool // device is closed? (acting as guard)
- log *Logger // collection of loggers for levels
- idCounter uint // for assigning debug ids to peers
- fwMark uint32
- tun struct {
- device TUNDevice
- isUp AtomicBool
- mtu int32
- }
- pool struct {
- messageBuffers sync.Pool
- }
- net struct {
- mutex sync.RWMutex
- bind Bind // bind interface
- port uint16 // listening port
- fwmark uint32 // mark value (0 = disabled)
- }
- mutex sync.RWMutex
- privateKey NoisePrivateKey
- publicKey NoisePublicKey
- routingTable RoutingTable
- indices IndexTable
- queue struct {
- encryption chan *QueueOutboundElement
- decryption chan *QueueInboundElement
- handshake chan QueueHandshakeElement
- }
- signal struct {
- stop Signal
- }
- underLoadUntil atomic.Value
- ratelimiter Ratelimiter
- peers map[NoisePublicKey]*Peer
- mac CookieChecker
-}
-
-/* Warning:
- * The caller must hold the device mutex (write lock)
- */
-func removePeerUnsafe(device *Device, key NoisePublicKey) {
- peer, ok := device.peers[key]
- if !ok {
- return
- }
- peer.mutex.Lock()
- device.routingTable.RemovePeer(peer)
- delete(device.peers, key)
- peer.Close()
-}
-
-func (device *Device) IsUnderLoad() bool {
-
- // check if currently under load
-
- now := time.Now()
- underLoad := len(device.queue.handshake) >= UnderLoadQueueSize
- if underLoad {
- device.underLoadUntil.Store(now.Add(time.Second))
- return true
- }
-
- // check if recently under load
-
- until := device.underLoadUntil.Load().(time.Time)
- return until.After(now)
-}
-
-func (device *Device) SetPrivateKey(sk NoisePrivateKey) error {
- device.mutex.Lock()
- defer device.mutex.Unlock()
-
- // remove peers with matching public keys
-
- publicKey := sk.publicKey()
- for key, peer := range device.peers {
- h := &peer.handshake
- h.mutex.RLock()
- if h.remoteStatic.Equals(publicKey) {
- removePeerUnsafe(device, key)
- }
- h.mutex.RUnlock()
- }
-
- // update key material
-
- device.privateKey = sk
- device.publicKey = publicKey
- device.mac.Init(publicKey)
-
- // do DH precomputations
-
- rmKey := device.privateKey.IsZero()
-
- for key, peer := range device.peers {
- h := &peer.handshake
- h.mutex.Lock()
- if rmKey {
- h.precomputedStaticStatic = [NoisePublicKeySize]byte{}
- } else {
- h.precomputedStaticStatic = device.privateKey.sharedSecret(h.remoteStatic)
- if isZero(h.precomputedStaticStatic[:]) {
- removePeerUnsafe(device, key)
- }
- }
- h.mutex.Unlock()
- }
-
- return nil
-}
-
-func (device *Device) GetMessageBuffer() *[MaxMessageSize]byte {
- return device.pool.messageBuffers.Get().(*[MaxMessageSize]byte)
-}
-
-func (device *Device) PutMessageBuffer(msg *[MaxMessageSize]byte) {
- device.pool.messageBuffers.Put(msg)
-}
-
-func NewDevice(tun TUNDevice, logger *Logger) *Device {
- device := new(Device)
- device.mutex.Lock()
- defer device.mutex.Unlock()
-
- device.log = logger
- device.peers = make(map[NoisePublicKey]*Peer)
- device.tun.device = tun
- device.tun.isUp.Set(false)
-
- device.indices.Init()
- device.ratelimiter.Init()
-
- device.routingTable.Reset()
- device.underLoadUntil.Store(time.Time{})
-
- // setup buffer pool
-
- device.pool.messageBuffers = sync.Pool{
- New: func() interface{} {
- return new([MaxMessageSize]byte)
- },
- }
-
- // create queues
-
- device.queue.handshake = make(chan QueueHandshakeElement, QueueHandshakeSize)
- device.queue.encryption = make(chan *QueueOutboundElement, QueueOutboundSize)
- device.queue.decryption = make(chan *QueueInboundElement, QueueInboundSize)
-
- // prepare signals
-
- device.signal.stop = NewSignal()
-
- // prepare net
-
- device.net.port = 0
- device.net.bind = nil
-
- // start workers
-
- for i := 0; i < runtime.NumCPU(); i += 1 {
- go device.RoutineEncryption()
- go device.RoutineDecryption()
- go device.RoutineHandshake()
- }
-
- go device.RoutineReadFromTUN()
- go device.RoutineTUNEventReader()
- go device.ratelimiter.RoutineGarbageCollector(device.signal.stop)
-
- return device
-}
-
-func (device *Device) LookupPeer(pk NoisePublicKey) *Peer {
- device.mutex.RLock()
- defer device.mutex.RUnlock()
- return device.peers[pk]
-}
-
-func (device *Device) RemovePeer(key NoisePublicKey) {
- device.mutex.Lock()
- defer device.mutex.Unlock()
- removePeerUnsafe(device, key)
-}
-
-func (device *Device) RemoveAllPeers() {
- device.mutex.Lock()
- defer device.mutex.Unlock()
-
- for key, peer := range device.peers {
- peer.mutex.Lock()
- delete(device.peers, key)
- peer.Close()
- peer.mutex.Unlock()
- }
-}
-
-func (device *Device) Close() {
- if device.closed.Swap(true) {
- return
- }
- device.log.Info.Println("Closing device")
- device.RemoveAllPeers()
- device.signal.stop.Broadcast()
- device.tun.device.Close()
- closeBind(device)
-}
-
-func (device *Device) Wait() chan struct{} {
- return device.signal.stop.Wait()
-}