diff --git a/event.go b/event.go index ccf57c2..6235ba4 100644 --- a/event.go +++ b/event.go @@ -29,7 +29,7 @@ func (e *Event) Clear() { } func (e *Event) Fire() { - if atomic.SwapInt32(&e.guard, 1) != 0 { + if e == nil || atomic.SwapInt32(&e.guard, 1) != 0 { return } if now := time.Now(); now.After(e.next) { diff --git a/main.go b/main.go index 5001bc4..ecfbc50 100644 --- a/main.go +++ b/main.go @@ -30,8 +30,6 @@ func printUsage() { } func warning() { - shouldQuit := false - fmt.Fprintln(os.Stderr, "WARNING WARNING WARNING WARNING WARNING WARNING WARNING") fmt.Fprintln(os.Stderr, "W G") fmt.Fprintln(os.Stderr, "W This is alpha software. It will very likely not G") @@ -39,8 +37,6 @@ func warning() { fmt.Fprintln(os.Stderr, "W horribly wrong. You have been warned. Proceed G") fmt.Fprintln(os.Stderr, "W at your own risk. G") if runtime.GOOS == "linux" { - shouldQuit = os.Getenv("WG_I_PREFER_BUGGY_USERSPACE_TO_POLISHED_KMOD") != "1" - fmt.Fprintln(os.Stderr, "W G") fmt.Fprintln(os.Stderr, "W Furthermore, you are running this software on a G") fmt.Fprintln(os.Stderr, "W Linux kernel, which is probably unnecessary and G") @@ -50,20 +46,9 @@ func warning() { fmt.Fprintln(os.Stderr, "W program. For more information on installing the G") fmt.Fprintln(os.Stderr, "W kernel module, please visit: G") fmt.Fprintln(os.Stderr, "W https://www.wireguard.com/install G") - if shouldQuit { - fmt.Fprintln(os.Stderr, "W G") - fmt.Fprintln(os.Stderr, "W If you still want to use this program, against G") - fmt.Fprintln(os.Stderr, "W the sage advice here, please first export this G") - fmt.Fprintln(os.Stderr, "W environment variable: G") - fmt.Fprintln(os.Stderr, "W WG_I_PREFER_BUGGY_USERSPACE_TO_POLISHED_KMOD=1 G") - } } fmt.Fprintln(os.Stderr, "W G") fmt.Fprintln(os.Stderr, "WARNING WARNING WARNING WARNING WARNING WARNING WARNING") - - if shouldQuit { - os.Exit(1) - } } func main() { diff --git a/peer.go b/peer.go index 0b947fd..739c8fb 100644 --- a/peer.go +++ b/peer.go @@ -51,15 +51,11 @@ type Peer struct { handshakeBegin *Event ephemeralKeyCreated *Event newKeyPair *Event - } - - signal struct { - flushNonceQueue chan struct{} // size 0, empty queued packets + flushNonceQueue *Event } timer struct { sendLastMinuteHandshake AtomicBool - needAnotherKeepalive AtomicBool } queue struct { @@ -72,7 +68,7 @@ type Peer struct { 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 + stop chan struct{} // size 0, stop all go-routines in peer } mac CookieGenerator @@ -111,18 +107,6 @@ func (device *Device) NewPeer(pk NoisePublicKey) (*Peer, error) { peer.device = device peer.isRunning.Set(false) - // events - - peer.event.dataSent = newEvent(EventInterval) - peer.event.dataReceived = newEvent(EventInterval) - peer.event.anyAuthenticatedPacketReceived = newEvent(EventInterval) - peer.event.anyAuthenticatedPacketTraversal = newEvent(EventInterval) - peer.event.handshakeCompleted = newEvent(EventInterval) - peer.event.handshakePushDeadline = newEvent(EventInterval) - peer.event.handshakeBegin = newEvent(EventInterval) - peer.event.ephemeralKeyCreated = newEvent(EventInterval) - peer.event.newKeyPair = newEvent(EventInterval) - // map public key _, ok := device.peers.keyMap[pk] @@ -143,12 +127,6 @@ func (device *Device) NewPeer(pk NoisePublicKey) (*Peer, error) { peer.endpoint = nil - // prepare signaling & routines - - peer.routines.mutex.Lock() - peer.routines.stop = NewSignal() - peer.routines.mutex.Unlock() - // start peer if peer.device.isUp.Get() { @@ -205,20 +183,31 @@ func (peer *Peer) Start() { device := peer.device device.log.Debug.Println(peer, ": Starting...") - // sanity check : these should be 0 + // reset routine state peer.routines.starting.Wait() peer.routines.stopping.Wait() + peer.routines.stop = make(chan struct{}) - // prepare queues and signals - - peer.signal.flushNonceQueue = make(chan struct{}) + // prepare queues peer.queue.nonce = make(chan *QueueOutboundElement, QueueOutboundSize) peer.queue.outbound = make(chan *QueueOutboundElement, QueueOutboundSize) peer.queue.inbound = make(chan *QueueInboundElement, QueueInboundSize) - peer.routines.stop = NewSignal() + // events + + peer.event.dataSent = newEvent(EventInterval) + peer.event.dataReceived = newEvent(EventInterval) + peer.event.anyAuthenticatedPacketReceived = newEvent(EventInterval) + peer.event.anyAuthenticatedPacketTraversal = newEvent(EventInterval) + peer.event.handshakeCompleted = newEvent(EventInterval) + peer.event.handshakePushDeadline = newEvent(EventInterval) + peer.event.handshakeBegin = newEvent(EventInterval) + peer.event.ephemeralKeyCreated = newEvent(EventInterval) + peer.event.newKeyPair = newEvent(EventInterval) + peer.event.flushNonceQueue = newEvent(EventInterval) + peer.isRunning.Set(true) // wait for routines to start @@ -252,7 +241,7 @@ func (peer *Peer) Stop() { // stop & wait for ongoing peer routines peer.routines.starting.Wait() - peer.routines.stop.Broadcast() + close(peer.routines.stop) peer.routines.stopping.Wait() // close queues @@ -261,11 +250,6 @@ func (peer *Peer) Stop() { close(peer.queue.outbound) close(peer.queue.inbound) - // close signals - - close(peer.signal.flushNonceQueue) - peer.signal.flushNonceQueue = nil - // clear key pairs kp := &peer.keyPairs diff --git a/receive.go b/receive.go index 1d8b718..b6261b2 100644 --- a/receive.go +++ b/receive.go @@ -561,7 +561,7 @@ func (peer *Peer) RoutineSequentialReceiver() { select { - case <-peer.routines.stop.Wait(): + case <-peer.routines.stop: return case elem, ok := <-peer.queue.inbound: diff --git a/send.go b/send.go index 7423e3b..a7c68be 100644 --- a/send.go +++ b/send.go @@ -209,8 +209,11 @@ func (peer *Peer) RoutineNonce() { for { NextPacket: + + peer.event.flushNonceQueue.Clear() + select { - case <-peer.routines.stop.Wait(): + case <-peer.routines.stop: return case elem, ok := <-peer.queue.nonce: @@ -239,9 +242,9 @@ func (peer *Peer) RoutineNonce() { select { case <-peer.event.newKeyPair.C: logDebug.Println(peer, ": Obtained awaited key-pair") - case <-peer.signal.flushNonceQueue: + case <-peer.event.flushNonceQueue.C: goto NextPacket - case <-peer.routines.stop.Wait(): + case <-peer.routines.stop: return } } @@ -368,7 +371,7 @@ func (peer *Peer) RoutineSequentialSender() { for { select { - case <-peer.routines.stop.Wait(): + case <-peer.routines.stop: return case elem, ok := <-peer.queue.outbound: diff --git a/timers.go b/timers.go index ce90685..38c9b46 100644 --- a/timers.go +++ b/timers.go @@ -148,9 +148,9 @@ func (peer *Peer) RoutineTimerHandler() { // reset all timers enableHandshake := true - pendingHandshakeNew := false pendingKeepalivePassive := false + needAnotherKeepalive := false timerKeepalivePassive := newTimer() timerHandshakeDeadline := newTimer() @@ -176,7 +176,7 @@ func (peer *Peer) RoutineTimerHandler() { /* stopping */ - case <-peer.routines.stop.Wait(): + case <-peer.routines.stop: return /* events */ @@ -189,7 +189,7 @@ func (peer *Peer) RoutineTimerHandler() { case <-peer.event.dataReceived.C: if pendingKeepalivePassive { - peer.timer.needAnotherKeepalive.Set(true) // TODO: make local + needAnotherKeepalive = true } else { timerKeepalivePassive.Reset(KeepaliveTimeout) } @@ -250,8 +250,6 @@ func (peer *Peer) RoutineTimerHandler() { /* timers */ - // keep-alive - case <-timerKeepalivePersistent.C: interval := peer.persistentKeepaliveInterval @@ -267,12 +265,11 @@ func (peer *Peer) RoutineTimerHandler() { peer.SendKeepAlive() - if peer.timer.needAnotherKeepalive.Swap(false) { + if needAnotherKeepalive { timerKeepalivePassive.Reset(KeepaliveTimeout) + needAnotherKeepalive = false } - // clear key material timer - case <-timerZeroAllKeys.C: logDebug.Println(peer, ": Clear all key-material (timer event)") @@ -305,8 +302,6 @@ func (peer *Peer) RoutineTimerHandler() { hs.Clear() hs.mutex.Unlock() - // handshake timers - case <-timerHandshakeTimeout.C: // allow new handshake to be send @@ -349,14 +344,12 @@ func (peer *Peer) RoutineTimerHandler() { logInfo.Println(peer, ": Handshake negotiation timed-out") peer.flushNonceQueue() - signalSend(peer.signal.flushNonceQueue) - timerKeepalivePersistent.Stop() + peer.event.flushNonceQueue.Fire() - // disable further handshakes + // renable further handshakes peer.event.handshakeBegin.Clear() enableHandshake = true - } } } diff --git a/uapi.go b/uapi.go index c87a536..54d9bae 100644 --- a/uapi.go +++ b/uapi.go @@ -288,6 +288,8 @@ func ipcSetOperation(device *Device, socket *bufio.ReadWriter) *IPCError { return &IPCError{Code: ipcErrorInvalid} } + peer.event.handshakePushDeadline.Fire() + case "endpoint": // set endpoint destination