github.com/forest33/wtun@v0.3.1/conn/controlfns_linux.go (about)

     1  /* SPDX-License-Identifier: MIT
     2   *
     3   * Copyright (C) 2017-2023 WireGuard LLC. All Rights Reserved.
     4   */
     5  
     6  package conn
     7  
     8  import (
     9  	"fmt"
    10  	"runtime"
    11  	"syscall"
    12  
    13  	"golang.org/x/sys/unix"
    14  )
    15  
    16  func init() {
    17  	controlFns = append(controlFns,
    18  
    19  		// Attempt to set the socket buffer size beyond net.core.{r,w}mem_max by
    20  		// using SO_*BUFFORCE. This requires CAP_NET_ADMIN, and is allowed here to
    21  		// fail silently - the result of failure is lower performance on very fast
    22  		// links or high latency links.
    23  		func(network, address string, c syscall.RawConn) error {
    24  			return c.Control(func(fd uintptr) {
    25  				// Set up to *mem_max
    26  				_ = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_RCVBUF, socketBufferSize)
    27  				_ = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_SNDBUF, socketBufferSize)
    28  				// Set beyond *mem_max if CAP_NET_ADMIN
    29  				_ = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_RCVBUFFORCE, socketBufferSize)
    30  				_ = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_SNDBUFFORCE, socketBufferSize)
    31  			})
    32  		},
    33  
    34  		// Enable receiving of the packet information (IP_PKTINFO for IPv4,
    35  		// IPV6_PKTINFO for IPv6) that is used to implement sticky socket support.
    36  		func(network, address string, c syscall.RawConn) error {
    37  			var err error
    38  			switch network {
    39  			case "udp4":
    40  				if runtime.GOOS != "android" {
    41  					c.Control(func(fd uintptr) {
    42  						err = unix.SetsockoptInt(int(fd), unix.IPPROTO_IP, unix.IP_PKTINFO, 1)
    43  					})
    44  				}
    45  			case "udp6":
    46  				c.Control(func(fd uintptr) {
    47  					if runtime.GOOS != "android" {
    48  						err = unix.SetsockoptInt(int(fd), unix.IPPROTO_IPV6, unix.IPV6_RECVPKTINFO, 1)
    49  						if err != nil {
    50  							return
    51  						}
    52  					}
    53  					err = unix.SetsockoptInt(int(fd), unix.IPPROTO_IPV6, unix.IPV6_V6ONLY, 1)
    54  				})
    55  			default:
    56  				err = fmt.Errorf("unhandled network: %s: %w", network, unix.EINVAL)
    57  			}
    58  			return err
    59  		},
    60  	)
    61  }