sock_linux.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  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. package net
  5. import "syscall"
  6. func kernelVersion() (major int, minor int) {
  7. var uname syscall.Utsname
  8. if err := syscall.Uname(&uname); err != nil {
  9. return
  10. }
  11. rl := uname.Release
  12. var values [2]int
  13. vi := 0
  14. value := 0
  15. for _, c := range rl {
  16. if c >= '0' && c <= '9' {
  17. value = (value * 10) + int(c-'0')
  18. } else {
  19. // Note that we're assuming N.N.N here. If we see anything else we are likely to
  20. // mis-parse it.
  21. values[vi] = value
  22. vi++
  23. if vi >= len(values) {
  24. break
  25. }
  26. value = 0
  27. }
  28. }
  29. switch vi {
  30. case 0:
  31. return 0, 0
  32. case 1:
  33. return values[0], 0
  34. case 2:
  35. return values[0], values[1]
  36. }
  37. return
  38. }
  39. // Linux stores the backlog as:
  40. //
  41. // - uint16 in kernel version < 4.1,
  42. // - uint32 in kernel version >= 4.1
  43. //
  44. // Truncate number to avoid wrapping.
  45. //
  46. // See issue 5030 and 41470.
  47. func maxAckBacklog(n int) int {
  48. major, minor := kernelVersion()
  49. size := 16
  50. if major > 4 || (major == 4 && minor >= 1) {
  51. size = 32
  52. }
  53. var max uint = 1<<size - 1
  54. if uint(n) > max {
  55. n = int(max)
  56. }
  57. return n
  58. }
  59. func maxListenerBacklog() int {
  60. fd, err := open("/proc/sys/net/core/somaxconn")
  61. if err != nil {
  62. return syscall.SOMAXCONN
  63. }
  64. defer fd.close()
  65. l, ok := fd.readLine()
  66. if !ok {
  67. return syscall.SOMAXCONN
  68. }
  69. f := getFields(l)
  70. n, _, ok := dtoi(f[0])
  71. if n == 0 || !ok {
  72. return syscall.SOMAXCONN
  73. }
  74. if n > 1<<16-1 {
  75. return maxAckBacklog(n)
  76. }
  77. return n
  78. }