Source file src/net/sock_linux.go

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

View as plain text