From e9a98c3aefac5baebd974e8427e484e9c74bb280 Mon Sep 17 00:00:00 2001 From: David Fifield Date: Sun, 19 Apr 2020 02:13:48 -0600 Subject: [PATCH] Avoid logging EOF and ErrClosedPipe errors. smux Stream.WriteTo may return io.EOF, which breaks the contract of io.Copy that says it should not return io.EOF. smux.Stream doesn't have a unidirectional shutdown, so we always end up slamming it shut in both directions and leave the other direction with a broken pipe. --- dnstt-client/main.go | 9 +++++++-- dnstt-server/main.go | 9 +++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/dnstt-client/main.go b/dnstt-client/main.go index 9754cae..87dc302 100644 --- a/dnstt-client/main.go +++ b/dnstt-client/main.go @@ -110,16 +110,21 @@ func handle(local *net.TCPConn, sess *smux.Session, conv uint32) error { if err != nil { log.Printf("stream %08x:%d copy stream←local: %v\n", conv, stream.ID(), err) } + local.CloseRead() stream.Close() }() wg.Add(1) go func() { defer wg.Done() _, err := io.Copy(local, stream) - if err != nil { + if err == io.EOF { + // smux Stream.WriteTo may return io.EOF. + err = nil + } + if err != nil && err != io.ErrClosedPipe { log.Printf("stream %08x:%d copy local←stream: %v\n", conv, stream.ID(), err) } - local.Close() + local.CloseWrite() }() wg.Wait() diff --git a/dnstt-server/main.go b/dnstt-server/main.go index 0cf1e38..bd7a4fe 100644 --- a/dnstt-server/main.go +++ b/dnstt-server/main.go @@ -83,16 +83,21 @@ func handleStream(stream *smux.Stream, upstream *net.TCPAddr, conv uint32) error if err != nil { log.Printf("stream %08x:%d copy stream←upstream: %v\n", conv, stream.ID(), err) } + conn.CloseRead() stream.Close() }() wg.Add(1) go func() { defer wg.Done() _, err := io.Copy(conn, stream) - if err != nil { + if err == io.EOF { + // smux Stream.WriteTo may return io.EOF. + err = nil + } + if err != nil && err != io.ErrClosedPipe { log.Printf("stream %08x:%d copy upstream←stream: %v\n", conv, stream.ID(), err) } - conn.Close() + conn.CloseWrite() }() wg.Wait()