github.com/rafaeltorres324/go/src@v0.0.0-20210519164414-9fdf653a9838/net/sock_linux.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package net 6 7 import "syscall" 8 9 func kernelVersion() (major int, minor int) { 10 var uname syscall.Utsname 11 if err := syscall.Uname(&uname); err != nil { 12 return 13 } 14 15 rl := uname.Release 16 var values [2]int 17 vi := 0 18 value := 0 19 for _, c := range rl { 20 if c >= '0' && c <= '9' { 21 value = (value * 10) + int(c-'0') 22 } else { 23 // Note that we're assuming N.N.N here. If we see anything else we are likely to 24 // mis-parse it. 25 values[vi] = value 26 vi++ 27 if vi >= len(values) { 28 break 29 } 30 value = 0 31 } 32 } 33 switch vi { 34 case 0: 35 return 0, 0 36 case 1: 37 return values[0], 0 38 case 2: 39 return values[0], values[1] 40 } 41 return 42 } 43 44 // Linux stores the backlog as: 45 // 46 // - uint16 in kernel version < 4.1, 47 // - uint32 in kernel version >= 4.1 48 // 49 // Truncate number to avoid wrapping. 50 // 51 // See issue 5030 and 41470. 52 func maxAckBacklog(n int) int { 53 major, minor := kernelVersion() 54 size := 16 55 if major > 4 || (major == 4 && minor >= 1) { 56 size = 32 57 } 58 59 var max uint = 1<<size - 1 60 if uint(n) > max { 61 n = int(max) 62 } 63 return n 64 } 65 66 func maxListenerBacklog() int { 67 fd, err := open("/proc/sys/net/core/somaxconn") 68 if err != nil { 69 return syscall.SOMAXCONN 70 } 71 defer fd.close() 72 l, ok := fd.readLine() 73 if !ok { 74 return syscall.SOMAXCONN 75 } 76 f := getFields(l) 77 n, _, ok := dtoi(f[0]) 78 if n == 0 || !ok { 79 return syscall.SOMAXCONN 80 } 81 82 if n > 1<<16-1 { 83 return maxAckBacklog(n) 84 } 85 return n 86 }