From d24d3fa047c0115fd56a98b076c0b13dc6b47e87 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sat, 24 Sep 2022 16:51:31 +0100 Subject: [PATCH] Use deadline for link handshake (#949) This uses a 6 second deadline for timeouts instead of using `util.FuncTimeout` at 30 seconds for the read and then again for the write. If the handshake doesn't complete within 6 seconds then it's going to probably collapse when we give the connection to Ironwood and it tries to do a keepalive anyway. --- src/core/link.go | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/src/core/link.go b/src/core/link.go index 4d5cff5..939bb25 100644 --- a/src/core/link.go +++ b/src/core/link.go @@ -17,7 +17,6 @@ import ( "github.com/Arceliar/phony" "github.com/yggdrasil-network/yggdrasil-go/src/address" - "github.com/yggdrasil-network/yggdrasil-go/src/util" //"github.com/Arceliar/phony" // TODO? use instead of mutexes ) @@ -234,36 +233,25 @@ func (intf *link) handler() error { delete(intf.links._links, intf.info) }) - // TODO split some of this into shorter functions, so it's easier to read, and for the FIXME duplicate peer issue mentioned later meta := version_getBaseMetadata() meta.key = intf.links.core.public metaBytes := meta.encode() - // TODO timeouts on send/recv (goroutine for send/recv, channel select w/ timer) - var err error - if !util.FuncTimeout(30*time.Second, func() { - var n int - n, err = intf.conn.Write(metaBytes) - if err == nil && n != len(metaBytes) { - err = errors.New("incomplete metadata send") - } - }) { - return errors.New("timeout on metadata send") + if err := intf.conn.SetDeadline(time.Now().Add(time.Second * 6)); err != nil { + return fmt.Errorf("failed to set handshake deadline: %w", err) } - if err != nil { + n, err := intf.conn.Write(metaBytes) + switch { + case err != nil: return fmt.Errorf("write handshake: %w", err) + case err == nil && n != len(metaBytes): + return fmt.Errorf("incomplete handshake send") } - if !util.FuncTimeout(30*time.Second, func() { - var n int - n, err = io.ReadFull(intf.conn, metaBytes) - if err == nil && n != len(metaBytes) { - err = errors.New("incomplete metadata recv") - } - }) { - return errors.New("timeout on metadata recv") - } - if err != nil { + if _, err = io.ReadFull(intf.conn, metaBytes); err != nil { return fmt.Errorf("read handshake: %w", err) } + if err := intf.conn.SetDeadline(time.Time{}); err != nil { + return fmt.Errorf("failed to clear handshake deadline: %w", err) + } meta = version_metadata{} base := version_getBaseMetadata() if !meta.decode(metaBytes) {