summaryrefslogtreecommitdiffhomepage
path: root/server/sockopt_linux_test.go
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2017-08-12 23:46:45 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2017-08-13 00:22:10 +0900
commitf615fa49a768bb358e6318e64dc42e9a6af10681 (patch)
treee196b3c3c2a88ef4bbf6e7c5c0dda176792e5482 /server/sockopt_linux_test.go
parent534531b1b1887ac7146adcbbbef906f440abec37 (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.go40
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)
+ }
+}