]> Cypherpunks repositories - gostls13.git/commitdiff
net: make use of the kernel state to listen on TCP, Unix
authorMikio Hara <mikioh.mikioh@gmail.com>
Sat, 14 Jan 2012 04:42:18 +0000 (13:42 +0900)
committerMikio Hara <mikioh.mikioh@gmail.com>
Sat, 14 Jan 2012 04:42:18 +0000 (13:42 +0900)
R=golang-dev, dave, minux.ma
CC=golang-dev
https://golang.org/cl/5545044

src/pkg/net/Makefile
src/pkg/net/ipsock_posix.go
src/pkg/net/sock.go
src/pkg/net/sock_bsd.go [new file with mode: 0644]
src/pkg/net/sock_linux.go [new file with mode: 0644]
src/pkg/net/sock_windows.go [new file with mode: 0644]
src/pkg/net/tcpsock_posix.go
src/pkg/net/unixsock_posix.go

index f3d77c744fce18675c11c0a368c8f9e8634d9f25..81df2a266c355a0de0447ad91fa87cf12aac7a0d 100644 (file)
@@ -36,6 +36,7 @@ GOFILES_darwin=\
        port.go\
        sendfile_stub.go\
        sock.go\
+       sock_bsd.go\
        sockopt.go\
        sockopt_bsd.go\
        sockoptip.go\
@@ -68,6 +69,7 @@ GOFILES_freebsd=\
        port.go\
        sendfile_stub.go\
        sock.go\
+       sock_bsd.go\
        sockopt.go\
        sockopt_bsd.go\
        sockoptip.go\
@@ -99,6 +101,7 @@ GOFILES_linux=\
        port.go\
        sendfile_linux.go\
        sock.go\
+       sock_linux.go\
        sockopt.go\
        sockopt_linux.go\
        sockoptip.go\
@@ -130,6 +133,7 @@ GOFILES_netbsd=\
        port.go\
        sendfile_stub.go\
        sock.go\
+       sock_bsd.go\
        sockopt.go\
        sockopt_bsd.go\
        sockoptip.go\
@@ -155,6 +159,7 @@ GOFILES_openbsd=\
        port.go\
        sendfile_stub.go\
        sock.go\
+       sock_bsd.go\
        sockopt.go\
        sockopt_bsd.go\
        sockoptip.go\
@@ -184,6 +189,7 @@ GOFILES_windows=\
        lookup_windows.go\
        sendfile_windows.go\
        sock.go\
+       sock_windows.go\
        sockopt.go\
        sockopt_windows.go\
        sockoptip.go\
index d141c050b23042b4e8ae5611401966fd3e6636a7..45fe0d9640b224b749c56af091ce0068911b0732 100644 (file)
@@ -91,11 +91,6 @@ func favoriteAddrFamily(net string, raddr, laddr sockaddr, mode string) int {
        return syscall.AF_INET6
 }
 
-// TODO(rsc): if syscall.OS == "linux", we're supposed to read
-// /proc/sys/net/core/somaxconn,
-// to take advantage of kernels that have raised the limit.
-func listenBacklog() int { return syscall.SOMAXCONN }
-
 // Internet sockets (TCP, UDP)
 
 // A sockaddr represents a TCP or UDP network address that can
index 3ed072047792487d3ad5ea12719b73ca2b20dd9d..7732d2e06301456f8d6ff0981254dddc3fd70448 100644 (file)
@@ -14,6 +14,8 @@ import (
        "syscall"
 )
 
+var listenerBacklog = maxListenerBacklog()
+
 // Generic socket creation.
 func socket(net string, f, p, t int, la, ra syscall.Sockaddr, toAddr func(syscall.Sockaddr) Addr) (fd *netFD, err error) {
        // See ../syscall/exec.go for description of ForkLock.
diff --git a/src/pkg/net/sock_bsd.go b/src/pkg/net/sock_bsd.go
new file mode 100644 (file)
index 0000000..630a91e
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin freebsd netbsd openbsd
+
+// Sockets for BSD variants
+
+package net
+
+import (
+       "runtime"
+       "syscall"
+)
+
+func maxListenerBacklog() int {
+       var (
+               n   uint32
+               err error
+       )
+       switch runtime.GOOS {
+       case "darwin", "freebsd":
+               n, err = syscall.SysctlUint32("kern.ipc.somaxconn")
+       case "netbsd":
+               // NOTE: NetBSD has no somaxconn-like kernel state so far
+       case "openbsd":
+               n, err = syscall.SysctlUint32("kern.somaxconn")
+       }
+       if n == 0 || err != nil {
+               return syscall.SOMAXCONN
+       }
+       return int(n)
+}
diff --git a/src/pkg/net/sock_linux.go b/src/pkg/net/sock_linux.go
new file mode 100644 (file)
index 0000000..2cbc34f
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Sockets for Linux
+
+package net
+
+import "syscall"
+
+func maxListenerBacklog() int {
+       fd, err := open("/proc/sys/net/core/somaxconn")
+       if err != nil {
+               return syscall.SOMAXCONN
+       }
+       defer fd.close()
+       l, ok := fd.readLine()
+       if !ok {
+               return syscall.SOMAXCONN
+       }
+       f := getFields(l)
+       n, _, ok := dtoi(f[0], 0)
+       if n == 0 || !ok {
+               return syscall.SOMAXCONN
+       }
+       return n
+}
diff --git a/src/pkg/net/sock_windows.go b/src/pkg/net/sock_windows.go
new file mode 100644 (file)
index 0000000..2d803de
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Sockets for Windows
+
+package net
+
+import "syscall"
+
+func maxListenerBacklog() int {
+       // TODO: Implement this
+       return syscall.SOMAXCONN
+}
index a7c09c73ed5bd89ac7f49160a4f9a3834dfd545e..a492e614e35419ba95aca0e1cec32e2f8b876481 100644 (file)
@@ -249,10 +249,10 @@ func ListenTCP(net string, laddr *TCPAddr) (l *TCPListener, err error) {
        if err != nil {
                return nil, err
        }
-       errno := syscall.Listen(fd.sysfd, listenBacklog())
-       if errno != nil {
+       err = syscall.Listen(fd.sysfd, listenerBacklog)
+       if err != nil {
                closesocket(fd.sysfd)
-               return nil, &OpError{"listen", "tcp", laddr, errno}
+               return nil, &OpError{"listen", "tcp", laddr, err}
        }
        l = new(TCPListener)
        l.fd = fd
index 10632c1412e16558bebd92fad91b2580a307e06e..00ee0164f2e64ad14511b258fcddd124f226db2b 100644 (file)
@@ -315,7 +315,7 @@ type UnixListener struct {
 
 // ListenUnix announces on the Unix domain socket laddr and returns a Unix listener.
 // Net must be "unix" (stream sockets).
-func ListenUnix(net string, laddr *UnixAddr) (l *UnixListener, err error) {
+func ListenUnix(net string, laddr *UnixAddr) (*UnixListener, error) {
        if net != "unix" && net != "unixgram" && net != "unixpacket" {
                return nil, UnknownNetworkError(net)
        }
@@ -326,10 +326,10 @@ func ListenUnix(net string, laddr *UnixAddr) (l *UnixListener, err error) {
        if err != nil {
                return nil, err
        }
-       e1 := syscall.Listen(fd.sysfd, 8) // listenBacklog());
-       if e1 != nil {
+       err = syscall.Listen(fd.sysfd, listenerBacklog)
+       if err != nil {
                closesocket(fd.sysfd)
-               return nil, &OpError{Op: "listen", Net: "unix", Addr: laddr, Err: e1}
+               return nil, &OpError{Op: "listen", Net: "unix", Addr: laddr, Err: err}
        }
        return &UnixListener{fd, laddr.Name}, nil
 }