From e64f3f211ac03f270a2db476e01b34fd1d1c5301 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Tue, 12 Mar 2013 01:48:48 -0400 Subject: [PATCH] net: never use backlog > 65535 The system call takes an int, but the kernel stores it in a uint16. At least one Linux system sets /proc/sys/net/core/somaxconn to 262144, which ends up being 0 in the uint16. Avoid being tricked. FreeBSD sources also store the backlog in a uint16. Assume the problem is systemic and fix it everywhere. Fixes #5030. R=golang-dev, bradfitz CC=golang-dev https://golang.org/cl/7480046 --- src/pkg/net/sock_bsd.go | 6 ++++++ src/pkg/net/sock_linux.go | 6 ++++++ src/pkg/net/sock_windows.go | 1 + 3 files changed, 13 insertions(+) diff --git a/src/pkg/net/sock_bsd.go b/src/pkg/net/sock_bsd.go index 3205f94047..d99349265e 100644 --- a/src/pkg/net/sock_bsd.go +++ b/src/pkg/net/sock_bsd.go @@ -27,5 +27,11 @@ func maxListenerBacklog() int { if n == 0 || err != nil { return syscall.SOMAXCONN } + // FreeBSD stores the backlog in a uint16, as does Linux. + // Assume the other BSDs do too. Truncate number to avoid wrapping. + // See issue 5030. + if n > 1<<16-1 { + n = 1<<16 - 1 + } return int(n) } diff --git a/src/pkg/net/sock_linux.go b/src/pkg/net/sock_linux.go index 8bbd74ddc9..cc5ce153b3 100644 --- a/src/pkg/net/sock_linux.go +++ b/src/pkg/net/sock_linux.go @@ -21,5 +21,11 @@ func maxListenerBacklog() int { if n == 0 || !ok { return syscall.SOMAXCONN } + // Linux stores the backlog in a uint16. + // Truncate number to avoid wrapping. + // See issue 5030. + if n > 1<<16-1 { + n = 1<<16 - 1 + } return n } diff --git a/src/pkg/net/sock_windows.go b/src/pkg/net/sock_windows.go index a77c48437f..41368d39e8 100644 --- a/src/pkg/net/sock_windows.go +++ b/src/pkg/net/sock_windows.go @@ -8,6 +8,7 @@ import "syscall" func maxListenerBacklog() int { // TODO: Implement this + // NOTE: Never return a number bigger than 1<<16 - 1. See issue 5030. return syscall.SOMAXCONN }