controlfns_linux.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  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. _ = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEPORT, 1) //todo!!!
  27. _ = unix.SetsockoptInt(int(fd), unix.IPPROTO_UDP, unix.UDP_GRO, 1) //todo!!!
  28. _ = unix.SetsockoptInt(int(fd), unix.SOL_UDP, unix.UDP_SEGMENT, 0xffff) //todo!!!
  29. //print(err.Error())
  30. })
  31. },
  32. // Enable receiving of the packet information (IP_PKTINFO for IPv4,
  33. // IPV6_PKTINFO for IPv6) that is used to implement sticky socket support.
  34. func(network, address string, c syscall.RawConn) error {
  35. var err error
  36. switch network {
  37. case "udp4":
  38. if runtime.GOOS != "android" {
  39. c.Control(func(fd uintptr) {
  40. err = unix.SetsockoptInt(int(fd), unix.IPPROTO_IP, unix.IP_PKTINFO, 1)
  41. })
  42. }
  43. case "udp6":
  44. c.Control(func(fd uintptr) {
  45. if runtime.GOOS != "android" {
  46. err = unix.SetsockoptInt(int(fd), unix.IPPROTO_IPV6, unix.IPV6_RECVPKTINFO, 1)
  47. if err != nil {
  48. return
  49. }
  50. }
  51. err = unix.SetsockoptInt(int(fd), unix.IPPROTO_IPV6, unix.IPV6_V6ONLY, 1)
  52. })
  53. default:
  54. err = fmt.Errorf("unhandled network: %s: %w", network, unix.EINVAL)
  55. }
  56. return err
  57. },
  58. )
  59. }