1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- // 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<<size - 1
- if uint(n) > 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
- }
|