// 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. package net import "syscall" func kernelVersion() (major int, minor int) { var uname syscall.Utsname if err := syscall.Uname(&uname); err != nil { return } rl := uname.Release var values [2]int vi := 0 value := 0 for _, c := range rl { if c >= '0' && c <= '9' { value = (value * 10) + int(c-'0') } else { // Note that we're assuming N.N.N here. If we see anything else we are likely to // mis-parse it. values[vi] = value vi++ if vi >= len(values) { break } value = 0 } } switch vi { case 0: return 0, 0 case 1: return values[0], 0 case 2: return values[0], values[1] } return } // Linux stores the backlog as: // // - uint16 in kernel version < 4.1, // - uint32 in kernel version >= 4.1 // // Truncate number to avoid wrapping. // // See issue 5030 and 41470. func maxAckBacklog(n int) int { major, minor := kernelVersion() size := 16 if major > 4 || (major == 4 && minor >= 1) { size = 32 } var max uint = 1< max { n = int(max) } return n } 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]) if n == 0 || !ok { return syscall.SOMAXCONN } if n > 1<<16-1 { return maxAckBacklog(n) } return n }