controlfns_linux.go 1.8 KB

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