|  | // 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 | 
|  | } |