sockopt_linux.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. package internet
  2. import (
  3. "syscall"
  4. "v2ray.com/core/common/net"
  5. )
  6. const (
  7. // For incoming connections.
  8. TCP_FASTOPEN = 23
  9. // For out-going connections.
  10. TCP_FASTOPEN_CONNECT = 30
  11. )
  12. func bindAddr(fd uintptr, address net.Address, port net.Port) error {
  13. err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1)
  14. if err != nil {
  15. return newError("failed to set resuse_addr").Base(err).AtWarning()
  16. }
  17. var sockaddr syscall.Sockaddr
  18. switch address.Family() {
  19. case net.AddressFamilyIPv4:
  20. a4 := &syscall.SockaddrInet4{
  21. Port: int(port),
  22. }
  23. copy(a4.Addr[:], address.IP())
  24. sockaddr = a4
  25. case net.AddressFamilyIPv6:
  26. a6 := &syscall.SockaddrInet6{
  27. Port: int(port),
  28. }
  29. copy(a6.Addr[:], address.IP())
  30. sockaddr = a6
  31. default:
  32. return newError("unsupported address family: ", address.Family())
  33. }
  34. return syscall.Bind(int(fd), sockaddr)
  35. }
  36. func applyOutboundSocketOptions(network string, address string, fd uintptr, config *SocketConfig) error {
  37. if config.Mark != 0 {
  38. if err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_MARK, int(config.Mark)); err != nil {
  39. return newError("failed to set SO_MARK").Base(err)
  40. }
  41. }
  42. if isTCPSocket(network) {
  43. switch config.Tfo {
  44. case SocketConfig_Enable:
  45. if err := syscall.SetsockoptInt(int(fd), syscall.SOL_TCP, TCP_FASTOPEN_CONNECT, 1); err != nil {
  46. return newError("failed to set TCP_FASTOPEN_CONNECT=1").Base(err)
  47. }
  48. case SocketConfig_Disable:
  49. if err := syscall.SetsockoptInt(int(fd), syscall.SOL_TCP, TCP_FASTOPEN_CONNECT, 0); err != nil {
  50. return newError("failed to set TCP_FASTOPEN_CONNECT=0").Base(err)
  51. }
  52. }
  53. }
  54. if config.Tproxy.IsEnabled() {
  55. if err := syscall.SetsockoptInt(int(fd), syscall.SOL_IP, syscall.IP_TRANSPARENT, 1); err != nil {
  56. return newError("failed to set IP_TRANSPARENT").Base(err)
  57. }
  58. }
  59. return nil
  60. }
  61. func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig) error {
  62. if isTCPSocket(network) {
  63. switch config.Tfo {
  64. case SocketConfig_Enable:
  65. if err := syscall.SetsockoptInt(int(fd), syscall.SOL_TCP, TCP_FASTOPEN, 1); err != nil {
  66. return newError("failed to set TCP_FASTOPEN=1").Base(err)
  67. }
  68. case SocketConfig_Disable:
  69. if err := syscall.SetsockoptInt(int(fd), syscall.SOL_TCP, TCP_FASTOPEN, 0); err != nil {
  70. return newError("failed to set TCP_FASTOPEN=0").Base(err)
  71. }
  72. }
  73. }
  74. if config.Tproxy.IsEnabled() {
  75. if err := syscall.SetsockoptInt(int(fd), syscall.SOL_IP, syscall.IP_TRANSPARENT, 1); err != nil {
  76. return newError("failed to set IP_TRANSPARENT").Base(err)
  77. }
  78. }
  79. if config.ReceiveOriginalDestAddress && isUDPSocket(network) {
  80. if err := syscall.SetsockoptInt(int(fd), syscall.SOL_IP, syscall.IP_RECVORIGDSTADDR, 1); err != nil {
  81. return err
  82. }
  83. }
  84. return nil
  85. }