From 91a374d69889dd40fb7954de21917157a80fff78 Mon Sep 17 00:00:00 2001 From: cathugger Date: Thu, 19 Jul 2018 21:58:53 +0000 Subject: [PATCH] rearrange tcp reading loop according to documentation of io.Reader interface, "Callers should always process the n > 0 bytes returned before considering the error err. Doing so correctly handles I/O errors that happen after reading some bytes and also both of the allowed EOF behaviors." --- src/yggdrasil/tcp.go | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/yggdrasil/tcp.go b/src/yggdrasil/tcp.go index 831cd741..3372fe64 100644 --- a/src/yggdrasil/tcp.go +++ b/src/yggdrasil/tcp.go @@ -324,26 +324,29 @@ func (iface *tcpInterface) reader(sock net.Conn, in func([]byte)) error { timeout := time.Now().Add(tcp_timeout) sock.SetReadDeadline(timeout) n, err := sock.Read(bs[len(frag):]) + if n > 0 { + frag = bs[:len(frag)+n] + for { + msg, ok, err2 := tcp_chop_msg(&frag) + if err2 != nil { + return fmt.Errorf("Message error: %v", err2) + } + if !ok { + // We didn't get the whole message yet + break + } + newMsg := append(util_getBytes(), msg...) + in(newMsg) + util_yield() + } + frag = append(bs[:0], frag...) + } if err != nil || n == 0 { if err != io.EOF { return err } return nil } - frag = bs[:len(frag)+n] - for { - msg, ok, err := tcp_chop_msg(&frag) - if err != nil { - return fmt.Errorf("Message error: %v", err) - } - if !ok { - break - } // We didn't get the whole message yet - newMsg := append(util_getBytes(), msg...) - in(newMsg) - util_yield() - } - frag = append(bs[:0], frag...) } }