sockopt_posix.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. // Copyright 2009 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. //go:build aix || darwin || dragonfly || freebsd || hurd || linux || netbsd || openbsd || solaris || windows
  5. package net
  6. import (
  7. "internal/bytealg"
  8. "runtime"
  9. "syscall"
  10. )
  11. // Boolean to int.
  12. func boolint(b bool) int {
  13. if b {
  14. return 1
  15. }
  16. return 0
  17. }
  18. func ipv4AddrToInterface(ip IP) (*Interface, error) {
  19. ift, err := Interfaces()
  20. if err != nil {
  21. return nil, err
  22. }
  23. for _, ifi := range ift {
  24. ifat, err := ifi.Addrs()
  25. if err != nil {
  26. return nil, err
  27. }
  28. for _, ifa := range ifat {
  29. switch v := ifa.(type) {
  30. case *IPAddr:
  31. if ip.Equal(v.IP) {
  32. return &ifi, nil
  33. }
  34. case *IPNet:
  35. if ip.Equal(v.IP) {
  36. return &ifi, nil
  37. }
  38. }
  39. }
  40. }
  41. if ip.Equal(IPv4zero) {
  42. return nil, nil
  43. }
  44. return nil, errNoSuchInterface
  45. }
  46. func interfaceToIPv4Addr(ifi *Interface) (IP, error) {
  47. if ifi == nil {
  48. return IPv4zero, nil
  49. }
  50. ifat, err := ifi.Addrs()
  51. if err != nil {
  52. return nil, err
  53. }
  54. for _, ifa := range ifat {
  55. switch v := ifa.(type) {
  56. case *IPAddr:
  57. if v.IP.To4() != nil {
  58. return v.IP, nil
  59. }
  60. case *IPNet:
  61. if v.IP.To4() != nil {
  62. return v.IP, nil
  63. }
  64. }
  65. }
  66. return nil, errNoSuchInterface
  67. }
  68. func setIPv4MreqToInterface(mreq *syscall.IPMreq, ifi *Interface) error {
  69. if ifi == nil {
  70. return nil
  71. }
  72. ifat, err := ifi.Addrs()
  73. if err != nil {
  74. return err
  75. }
  76. for _, ifa := range ifat {
  77. switch v := ifa.(type) {
  78. case *IPAddr:
  79. if a := v.IP.To4(); a != nil {
  80. copy(mreq.Interface[:], a)
  81. goto done
  82. }
  83. case *IPNet:
  84. if a := v.IP.To4(); a != nil {
  85. copy(mreq.Interface[:], a)
  86. goto done
  87. }
  88. }
  89. }
  90. done:
  91. if bytealg.Equal(mreq.Multiaddr[:], IPv4zero.To4()) {
  92. return errNoSuchMulticastInterface
  93. }
  94. return nil
  95. }
  96. func setReadBuffer(fd *netFD, bytes int) error {
  97. err := fd.pfd.SetsockoptInt(syscall.SOL_SOCKET, syscall.SO_RCVBUF, bytes)
  98. runtime.KeepAlive(fd)
  99. return wrapSyscallError("setsockopt", err)
  100. }
  101. func setWriteBuffer(fd *netFD, bytes int) error {
  102. err := fd.pfd.SetsockoptInt(syscall.SOL_SOCKET, syscall.SO_SNDBUF, bytes)
  103. runtime.KeepAlive(fd)
  104. return wrapSyscallError("setsockopt", err)
  105. }
  106. func setKeepAlive(fd *netFD, keepalive bool) error {
  107. err := fd.pfd.SetsockoptInt(syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, boolint(keepalive))
  108. runtime.KeepAlive(fd)
  109. return wrapSyscallError("setsockopt", err)
  110. }
  111. func setLinger(fd *netFD, sec int) error {
  112. var l syscall.Linger
  113. if sec >= 0 {
  114. l.Onoff = 1
  115. l.Linger = int32(sec)
  116. } else {
  117. l.Onoff = 0
  118. l.Linger = 0
  119. }
  120. err := fd.pfd.SetsockoptLinger(syscall.SOL_SOCKET, syscall.SO_LINGER, &l)
  121. runtime.KeepAlive(fd)
  122. return wrapSyscallError("setsockopt", err)
  123. }