From 25692420501e7252c2615382b8115d7119008eb2 Mon Sep 17 00:00:00 2001 From: Arceliar Date: Tue, 26 Feb 2019 21:07:56 -0600 Subject: [PATCH] fixes to linkInterface.handler() --- src/util/util.go | 20 ++++++++++++++++++++ src/yggdrasil/link.go | 11 ++++++++--- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/util/util.go b/src/util/util.go index 45be3b19..df15ff2c 100644 --- a/src/util/util.go +++ b/src/util/util.go @@ -56,3 +56,23 @@ func TimerStop(t *time.Timer) bool { } return true } + +// Run a blocking function with a timeout. +// Returns true if the function returns. +// Returns false if the timer fires. +// The blocked function remains blocked--the caller is responsible for somehow killing it. +func FuncTimeout(f func(), timeout time.Duration) bool { + success := make(chan struct{}) + go func() { + defer close(success) + f() + }() + timer := time.NewTimer(timeout) + defer TimerStop(timer) + select { + case <-success: + return true + case <-timer.C: + return false + } +} diff --git a/src/yggdrasil/link.go b/src/yggdrasil/link.go index 443b5943..06020cd7 100644 --- a/src/yggdrasil/link.go +++ b/src/yggdrasil/link.go @@ -92,11 +92,16 @@ func (intf *linkInterface) handler() error { meta.link = *myLinkPub metaBytes := meta.encode() // TODO timeouts on send/recv (goroutine for send/recv, channel select w/ timer) - err := intf.msgIO._sendMetaBytes(metaBytes) + var err error + if !util.FuncTimeout(func() { err = intf.msgIO._sendMetaBytes(metaBytes) }, 30*time.Second) { + return errors.New("timeout on metadata send") + } if err != nil { return err } - metaBytes, err = intf.msgIO._recvMetaBytes() + if !util.FuncTimeout(func() { metaBytes, err = intf.msgIO._recvMetaBytes() }, 30*time.Second) { + return errors.New("timeout on metadata recv") + } if err != nil { return err } @@ -110,7 +115,7 @@ func (intf *linkInterface) handler() error { return errors.New("failed to connect: wrong version") } // Check if we're authorized to connect to this key / IP - if !intf.force && !intf.link.core.peers.isAllowedEncryptionPublicKey(&meta.box) { + if !intf.incoming && !intf.force && !intf.link.core.peers.isAllowedEncryptionPublicKey(&meta.box) { intf.link.core.log.Debugf("%s connection to %s forbidden: AllowedEncryptionPublicKeys does not contain key %s", strings.ToUpper(intf.info.linkType), intf.info.remote, hex.EncodeToString(meta.box[:])) intf.msgIO.close()