From 09d8cb9b65a548e0ea3adf88c6009d5e62a112f4 Mon Sep 17 00:00:00 2001 From: Riobard Date: Thu, 13 Aug 2020 02:22:52 +0800 Subject: [PATCH] Drain net.Conn to avoid leaking behavioral feature --- tcp.go | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/tcp.go b/tcp.go index c4779369..1fb48b78 100644 --- a/tcp.go +++ b/tcp.go @@ -2,6 +2,7 @@ package main import ( "io" + "io/ioutil" "net" "sync" "time" @@ -111,11 +112,17 @@ func tcpRemote(addr string, shadow func(net.Conn) net.Conn) { go func() { defer c.Close() - c = shadow(c) + sc := shadow(c) - tgt, err := socks.ReadAddr(c) + tgt, err := socks.ReadAddr(sc) if err != nil { logf("failed to get target address: %v", err) + // drain c to avoid leaking server behavioral features + // see https://www.ndss-symposium.org/ndss-paper/detecting-probe-resistant-proxies/ + _, err = io.Copy(ioutil.Discard, c) + if err != nil { + logf("discard error: %v", err) + } return } @@ -127,7 +134,7 @@ func tcpRemote(addr string, shadow func(net.Conn) net.Conn) { defer rc.Close() logf("proxy %s <-> %s", c.RemoteAddr(), tgt) - err = relay(c, rc) + err = relay(sc, rc) if err != nil { if err, ok := err.(net.Error); ok && err.Timeout() { return // ignore i/o timeout