Fixed tabs

This commit is contained in:
Mathias Hall-Andersen 2018-02-11 19:02:50 +01:00
parent 73cb1a1155
commit 743364f647
4 changed files with 392 additions and 392 deletions

View file

@ -1,34 +1,34 @@
package main package main
import ( import (
"os" "os"
) )
/* Daemonizes the process on windows /* Daemonizes the process on windows
* *
* This is done by spawning and releasing a copy with the --foreground flag * This is done by spawning and releasing a copy with the --foreground flag
*/ */
func Daemonize() error { func Daemonize() error {
argv := []string{os.Args[0], "--foreground"} argv := []string{os.Args[0], "--foreground"}
argv = append(argv, os.Args[1:]...) argv = append(argv, os.Args[1:]...)
attr := &os.ProcAttr{ attr := &os.ProcAttr{
Dir: ".", Dir: ".",
Env: os.Environ(), Env: os.Environ(),
Files: []*os.File{ Files: []*os.File{
os.Stdin, os.Stdin,
nil, nil,
nil, nil,
}, },
} }
process, err := os.StartProcess( process, err := os.StartProcess(
argv[0], argv[0],
argv, argv,
attr, attr,
) )
if err != nil { if err != nil {
return err return err
} }
process.Release() process.Release()
return nil return nil
} }

696
timers.go
View file

@ -1,348 +1,348 @@
package main package main
import ( import (
"bytes" "bytes"
"encoding/binary" "encoding/binary"
"math/rand" "math/rand"
"sync/atomic" "sync/atomic"
"time" "time"
) )
/* NOTE: /* NOTE:
* Notion of validity * Notion of validity
* *
* *
*/ */
/* Called when a new authenticated message has been send /* Called when a new authenticated message has been send
* *
*/ */
func (peer *Peer) KeepKeyFreshSending() { func (peer *Peer) KeepKeyFreshSending() {
kp := peer.keyPairs.Current() kp := peer.keyPairs.Current()
if kp == nil { if kp == nil {
return return
} }
nonce := atomic.LoadUint64(&kp.sendNonce) nonce := atomic.LoadUint64(&kp.sendNonce)
if nonce > RekeyAfterMessages { if nonce > RekeyAfterMessages {
peer.signal.handshakeBegin.Send() peer.signal.handshakeBegin.Send()
} }
if kp.isInitiator && time.Now().Sub(kp.created) > RekeyAfterTime { if kp.isInitiator && time.Now().Sub(kp.created) > RekeyAfterTime {
peer.signal.handshakeBegin.Send() peer.signal.handshakeBegin.Send()
} }
} }
/* Called when a new authenticated message has been received /* Called when a new authenticated message has been received
* *
* NOTE: Not thread safe, but called by sequential receiver! * NOTE: Not thread safe, but called by sequential receiver!
*/ */
func (peer *Peer) KeepKeyFreshReceiving() { func (peer *Peer) KeepKeyFreshReceiving() {
if peer.timer.sendLastMinuteHandshake { if peer.timer.sendLastMinuteHandshake {
return return
} }
kp := peer.keyPairs.Current() kp := peer.keyPairs.Current()
if kp == nil { if kp == nil {
return return
} }
if !kp.isInitiator { if !kp.isInitiator {
return return
} }
nonce := atomic.LoadUint64(&kp.sendNonce) nonce := atomic.LoadUint64(&kp.sendNonce)
send := nonce > RekeyAfterMessages || time.Now().Sub(kp.created) > RekeyAfterTimeReceiving send := nonce > RekeyAfterMessages || time.Now().Sub(kp.created) > RekeyAfterTimeReceiving
if send { if send {
// do a last minute attempt at initiating a new handshake // do a last minute attempt at initiating a new handshake
peer.timer.sendLastMinuteHandshake = true peer.timer.sendLastMinuteHandshake = true
peer.signal.handshakeBegin.Send() peer.signal.handshakeBegin.Send()
} }
} }
/* Queues a keep-alive if no packets are queued for peer /* Queues a keep-alive if no packets are queued for peer
*/ */
func (peer *Peer) SendKeepAlive() bool { func (peer *Peer) SendKeepAlive() bool {
if len(peer.queue.nonce) != 0 { if len(peer.queue.nonce) != 0 {
return false return false
} }
elem := peer.device.NewOutboundElement() elem := peer.device.NewOutboundElement()
elem.packet = nil elem.packet = nil
select { select {
case peer.queue.nonce <- elem: case peer.queue.nonce <- elem:
return true return true
default: default:
return false return false
} }
} }
/* Event: /* Event:
* Sent non-empty (authenticated) transport message * Sent non-empty (authenticated) transport message
*/ */
func (peer *Peer) TimerDataSent() { func (peer *Peer) TimerDataSent() {
peer.timer.keepalivePassive.Stop() peer.timer.keepalivePassive.Stop()
peer.timer.handshakeNew.Start(NewHandshakeTime) peer.timer.handshakeNew.Start(NewHandshakeTime)
} }
/* Event: /* Event:
* Received non-empty (authenticated) transport message * Received non-empty (authenticated) transport message
* *
* Action: * Action:
* Set a timer to confirm the message using a keep-alive (if not already set) * Set a timer to confirm the message using a keep-alive (if not already set)
*/ */
func (peer *Peer) TimerDataReceived() { func (peer *Peer) TimerDataReceived() {
if !peer.timer.keepalivePassive.Start(KeepaliveTimeout) { if !peer.timer.keepalivePassive.Start(KeepaliveTimeout) {
peer.timer.needAnotherKeepalive = true peer.timer.needAnotherKeepalive = true
} }
} }
/* Event: /* Event:
* Any (authenticated) packet received * Any (authenticated) packet received
*/ */
func (peer *Peer) TimerAnyAuthenticatedPacketReceived() { func (peer *Peer) TimerAnyAuthenticatedPacketReceived() {
peer.timer.handshakeNew.Stop() peer.timer.handshakeNew.Stop()
} }
/* Event: /* Event:
* Any authenticated packet send / received. * Any authenticated packet send / received.
* *
* Action: * Action:
* Push persistent keep-alive into the future * Push persistent keep-alive into the future
*/ */
func (peer *Peer) TimerAnyAuthenticatedPacketTraversal() { func (peer *Peer) TimerAnyAuthenticatedPacketTraversal() {
interval := atomic.LoadUint64(&peer.persistentKeepaliveInterval) interval := atomic.LoadUint64(&peer.persistentKeepaliveInterval)
if interval > 0 { if interval > 0 {
duration := time.Duration(interval) * time.Second duration := time.Duration(interval) * time.Second
peer.timer.keepalivePersistent.Reset(duration) peer.timer.keepalivePersistent.Reset(duration)
} }
} }
/* Called after successfully completing a handshake. /* Called after successfully completing a handshake.
* i.e. after: * i.e. after:
* *
* - Valid handshake response * - Valid handshake response
* - First transport message under the "next" key * - First transport message under the "next" key
*/ */
func (peer *Peer) TimerHandshakeComplete() { func (peer *Peer) TimerHandshakeComplete() {
peer.signal.handshakeCompleted.Send() peer.signal.handshakeCompleted.Send()
peer.device.log.Info.Println("Negotiated new handshake for", peer.String()) peer.device.log.Info.Println("Negotiated new handshake for", peer.String())
} }
/* Event: /* Event:
* An ephemeral key is generated * An ephemeral key is generated
* *
* i.e. after: * i.e. after:
* *
* CreateMessageInitiation * CreateMessageInitiation
* CreateMessageResponse * CreateMessageResponse
* *
* Action: * Action:
* Schedule the deletion of all key material * Schedule the deletion of all key material
* upon failure to complete a handshake * upon failure to complete a handshake
*/ */
func (peer *Peer) TimerEphemeralKeyCreated() { func (peer *Peer) TimerEphemeralKeyCreated() {
peer.timer.zeroAllKeys.Reset(RejectAfterTime * 3) peer.timer.zeroAllKeys.Reset(RejectAfterTime * 3)
} }
/* Sends a new handshake initiation message to the peer (endpoint) /* Sends a new handshake initiation message to the peer (endpoint)
*/ */
func (peer *Peer) sendNewHandshake() error { func (peer *Peer) sendNewHandshake() error {
// temporarily disable the handshake complete signal // temporarily disable the handshake complete signal
peer.signal.handshakeCompleted.Disable() peer.signal.handshakeCompleted.Disable()
// create initiation message // create initiation message
msg, err := peer.device.CreateMessageInitiation(peer) msg, err := peer.device.CreateMessageInitiation(peer)
if err != nil { if err != nil {
return err return err
} }
// marshal handshake message // marshal handshake message
var buff [MessageInitiationSize]byte var buff [MessageInitiationSize]byte
writer := bytes.NewBuffer(buff[:0]) writer := bytes.NewBuffer(buff[:0])
binary.Write(writer, binary.LittleEndian, msg) binary.Write(writer, binary.LittleEndian, msg)
packet := writer.Bytes() packet := writer.Bytes()
peer.mac.AddMacs(packet) peer.mac.AddMacs(packet)
// send to endpoint // send to endpoint
peer.TimerAnyAuthenticatedPacketTraversal() peer.TimerAnyAuthenticatedPacketTraversal()
err = peer.SendBuffer(packet) err = peer.SendBuffer(packet)
if err == nil { if err == nil {
peer.signal.handshakeCompleted.Enable() peer.signal.handshakeCompleted.Enable()
} }
// set timeout // set timeout
jitter := time.Millisecond * time.Duration(rand.Uint32()%334) jitter := time.Millisecond * time.Duration(rand.Uint32()%334)
peer.timer.keepalivePassive.Stop() peer.timer.keepalivePassive.Stop()
peer.timer.handshakeTimeout.Reset(RekeyTimeout + jitter) peer.timer.handshakeTimeout.Reset(RekeyTimeout + jitter)
return err return err
} }
func (peer *Peer) RoutineTimerHandler() { func (peer *Peer) RoutineTimerHandler() {
defer peer.routines.stopping.Done() defer peer.routines.stopping.Done()
device := peer.device device := peer.device
logInfo := device.log.Info logInfo := device.log.Info
logDebug := device.log.Debug logDebug := device.log.Debug
logDebug.Println("Routine, timer handler, started for peer", peer.String()) logDebug.Println("Routine, timer handler, started for peer", peer.String())
// reset all timers // reset all timers
peer.timer.keepalivePassive.Stop() peer.timer.keepalivePassive.Stop()
peer.timer.handshakeDeadline.Stop() peer.timer.handshakeDeadline.Stop()
peer.timer.handshakeTimeout.Stop() peer.timer.handshakeTimeout.Stop()
peer.timer.handshakeNew.Stop() peer.timer.handshakeNew.Stop()
peer.timer.zeroAllKeys.Stop() peer.timer.zeroAllKeys.Stop()
interval := atomic.LoadUint64(&peer.persistentKeepaliveInterval) interval := atomic.LoadUint64(&peer.persistentKeepaliveInterval)
if interval > 0 { if interval > 0 {
duration := time.Duration(interval) * time.Second duration := time.Duration(interval) * time.Second
peer.timer.keepalivePersistent.Reset(duration) peer.timer.keepalivePersistent.Reset(duration)
} }
// signal synchronised setup complete // signal synchronised setup complete
peer.routines.starting.Done() peer.routines.starting.Done()
// handle timer events // handle timer events
for { for {
select { select {
/* stopping */ /* stopping */
case <-peer.routines.stop.Wait(): case <-peer.routines.stop.Wait():
return return
/* timers */ /* timers */
// keep-alive // keep-alive
case <-peer.timer.keepalivePersistent.Wait(): case <-peer.timer.keepalivePersistent.Wait():
interval := atomic.LoadUint64(&peer.persistentKeepaliveInterval) interval := atomic.LoadUint64(&peer.persistentKeepaliveInterval)
if interval > 0 { if interval > 0 {
logDebug.Println(peer.String(), ": Send keep-alive (persistent)") logDebug.Println(peer.String(), ": Send keep-alive (persistent)")
peer.timer.keepalivePassive.Stop() peer.timer.keepalivePassive.Stop()
peer.SendKeepAlive() peer.SendKeepAlive()
} }
case <-peer.timer.keepalivePassive.Wait(): case <-peer.timer.keepalivePassive.Wait():
logDebug.Println(peer.String(), ": Send keep-alive (passive)") logDebug.Println(peer.String(), ": Send keep-alive (passive)")
peer.SendKeepAlive() peer.SendKeepAlive()
if peer.timer.needAnotherKeepalive { if peer.timer.needAnotherKeepalive {
peer.timer.needAnotherKeepalive = false peer.timer.needAnotherKeepalive = false
peer.timer.keepalivePassive.Reset(KeepaliveTimeout) peer.timer.keepalivePassive.Reset(KeepaliveTimeout)
} }
// clear key material timer // clear key material timer
case <-peer.timer.zeroAllKeys.Wait(): case <-peer.timer.zeroAllKeys.Wait():
logDebug.Println(peer.String(), ": Clear all key-material (timer event)") logDebug.Println(peer.String(), ": Clear all key-material (timer event)")
hs := &peer.handshake hs := &peer.handshake
hs.mutex.Lock() hs.mutex.Lock()
kp := &peer.keyPairs kp := &peer.keyPairs
kp.mutex.Lock() kp.mutex.Lock()
// remove key-pairs // remove key-pairs
if kp.previous != nil { if kp.previous != nil {
device.DeleteKeyPair(kp.previous) device.DeleteKeyPair(kp.previous)
kp.previous = nil kp.previous = nil
} }
if kp.current != nil { if kp.current != nil {
device.DeleteKeyPair(kp.current) device.DeleteKeyPair(kp.current)
kp.current = nil kp.current = nil
} }
if kp.next != nil { if kp.next != nil {
device.DeleteKeyPair(kp.next) device.DeleteKeyPair(kp.next)
kp.next = nil kp.next = nil
} }
kp.mutex.Unlock() kp.mutex.Unlock()
// zero out handshake // zero out handshake
device.indices.Delete(hs.localIndex) device.indices.Delete(hs.localIndex)
hs.Clear() hs.Clear()
hs.mutex.Unlock() hs.mutex.Unlock()
// handshake timers // handshake timers
case <-peer.timer.handshakeNew.Wait(): case <-peer.timer.handshakeNew.Wait():
logInfo.Println(peer.String(), ": Retrying handshake (timer event)") logInfo.Println(peer.String(), ": Retrying handshake (timer event)")
peer.signal.handshakeBegin.Send() peer.signal.handshakeBegin.Send()
case <-peer.timer.handshakeTimeout.Wait(): case <-peer.timer.handshakeTimeout.Wait():
// clear source (in case this is causing problems) // clear source (in case this is causing problems)
peer.mutex.Lock() peer.mutex.Lock()
if peer.endpoint != nil { if peer.endpoint != nil {
peer.endpoint.ClearSrc() peer.endpoint.ClearSrc()
} }
peer.mutex.Unlock() peer.mutex.Unlock()
// send new handshake // send new handshake
err := peer.sendNewHandshake() err := peer.sendNewHandshake()
if err != nil { if err != nil {
logInfo.Println(peer.String(), ": Failed to send handshake initiation", err) logInfo.Println(peer.String(), ": Failed to send handshake initiation", err)
} else { } else {
logDebug.Println(peer.String(), ": Send handshake initiation (subsequent)") logDebug.Println(peer.String(), ": Send handshake initiation (subsequent)")
} }
case <-peer.timer.handshakeDeadline.Wait(): case <-peer.timer.handshakeDeadline.Wait():
// clear all queued packets and stop keep-alive // clear all queued packets and stop keep-alive
logInfo.Println(peer.String(), ": Handshake negotiation timed-out") logInfo.Println(peer.String(), ": Handshake negotiation timed-out")
peer.signal.flushNonceQueue.Send() peer.signal.flushNonceQueue.Send()
peer.timer.keepalivePersistent.Stop() peer.timer.keepalivePersistent.Stop()
peer.signal.handshakeBegin.Enable() peer.signal.handshakeBegin.Enable()
/* signals */ /* signals */
case <-peer.signal.handshakeBegin.Wait(): case <-peer.signal.handshakeBegin.Wait():
peer.signal.handshakeBegin.Disable() peer.signal.handshakeBegin.Disable()
err := peer.sendNewHandshake() err := peer.sendNewHandshake()
if err != nil { if err != nil {
logInfo.Println(peer.String(), ": Failed to send handshake initiation", err) logInfo.Println(peer.String(), ": Failed to send handshake initiation", err)
} else { } else {
logDebug.Println(peer.String(), ": Send handshake initiation (initial)") logDebug.Println(peer.String(), ": Send handshake initiation (initial)")
} }
peer.timer.handshakeDeadline.Reset(RekeyAttemptTime) peer.timer.handshakeDeadline.Reset(RekeyAttemptTime)
case <-peer.signal.handshakeCompleted.Wait(): case <-peer.signal.handshakeCompleted.Wait():
logInfo.Println(peer.String(), ": Handshake completed") logInfo.Println(peer.String(), ": Handshake completed")
atomic.StoreInt64( atomic.StoreInt64(
&peer.stats.lastHandshakeNano, &peer.stats.lastHandshakeNano,
time.Now().UnixNano(), time.Now().UnixNano(),
) )
peer.timer.handshakeTimeout.Stop() peer.timer.handshakeTimeout.Stop()
peer.timer.handshakeDeadline.Stop() peer.timer.handshakeDeadline.Stop()
peer.signal.handshakeBegin.Enable() peer.signal.handshakeBegin.Enable()
peer.timer.sendLastMinuteHandshake = false peer.timer.sendLastMinuteHandshake = false
} }
} }
} }

View file

@ -10,12 +10,12 @@ import (
) )
const ( const (
ipcErrorIO = -int64(unix.EIO) ipcErrorIO = -int64(unix.EIO)
ipcErrorProtocol = -int64(unix.EPROTO) ipcErrorProtocol = -int64(unix.EPROTO)
ipcErrorInvalid = -int64(unix.EINVAL) ipcErrorInvalid = -int64(unix.EINVAL)
ipcErrorPortInUse = -int64(unix.EADDRINUSE) ipcErrorPortInUse = -int64(unix.EADDRINUSE)
socketDirectory = "/var/run/wireguard" socketDirectory = "/var/run/wireguard"
socketName = "%s.sock" socketName = "%s.sock"
) )
type UAPIListener struct { type UAPIListener struct {

View file

@ -11,10 +11,10 @@ import (
) )
const ( const (
ipcErrorIO = -int64(windows.ERROR_BROKEN_PIPE) ipcErrorIO = -int64(windows.ERROR_BROKEN_PIPE)
ipcErrorProtocol = -int64(windows.ERROR_INVALID_NAME) ipcErrorProtocol = -int64(windows.ERROR_INVALID_NAME)
ipcErrorInvalid = -int64(windows.ERROR_INVALID_PARAMETER) ipcErrorInvalid = -int64(windows.ERROR_INVALID_PARAMETER)
ipcErrorPortInUse = -int64(windows.ERROR_ALREADY_EXISTS) ipcErrorPortInUse = -int64(windows.ERROR_ALREADY_EXISTS)
) )
const PipeNameFmt = "\\\\.\\pipe\\wireguard-ipc-%s" const PipeNameFmt = "\\\\.\\pipe\\wireguard-ipc-%s"