diff options
author | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2017-08-12 23:46:45 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2017-08-13 00:22:10 +0900 |
commit | f615fa49a768bb358e6318e64dc42e9a6af10681 (patch) | |
tree | e196b3c3c2a88ef4bbf6e7c5c0dda176792e5482 /server/sockopt_linux_test.go | |
parent | 534531b1b1887ac7146adcbbbef906f440abec37 (diff) |
server: fix fd leak in DialTCP() on Linux
A new socket was created so we must close it before this function
returns _either_ on failure or success. On success, net.FileConn() in
newTCPConn() increases the refcount of the socket so this fi.Close()
doesn't destroy the socket; the caller can use it (and needs to close
it later).
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Diffstat (limited to 'server/sockopt_linux_test.go')
-rw-r--r-- | server/sockopt_linux_test.go | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/server/sockopt_linux_test.go b/server/sockopt_linux_test.go index f78431af..3730672c 100644 --- a/server/sockopt_linux_test.go +++ b/server/sockopt_linux_test.go @@ -18,8 +18,12 @@ package server import ( "bytes" + "fmt" + "net" + "os" "syscall" "testing" + "time" "unsafe" ) @@ -64,3 +68,39 @@ func Test_buildTcpMD5Sigv6(t *testing.T) { t.Error("Something wrong v6") } } + +func Test_DialTCP_FDleak(t *testing.T) { + openFds := func() int { + pid := os.Getpid() + f, err := os.OpenFile(fmt.Sprintf("/proc/%d/fdinfo", pid), os.O_RDONLY, 0) + if err != nil { + t.Fatal(err) + } + defer f.Close() + names, err := f.Readdirnames(0) + if err != nil { + t.Fatal(err) + } + return len(names) + } + + before := openFds() + + for i := 0; i < 10; i++ { + laddr, _ := net.ResolveTCPAddr("tcp", net.JoinHostPort("127.0.0.1", "0")) + d := TCPDialer{ + Dialer: net.Dialer{ + LocalAddr: laddr, + Timeout: 1 * time.Second, + }, + } + if _, err := d.DialTCP("127.0.0.1", 1); err == nil { + t.Fatalf("should not succeed") + } + + } + + if after := openFds(); before != after { + t.Fatalf("could be fd leak, %d %d", before, after) + } +} |