controlfns_linux.go 2.0 KB

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