udp_darwin.go 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. //go:build !e2e_testing
  2. // +build !e2e_testing
  3. package udp
  4. // Darwin support is primarily implemented in udp_generic, besides NewListenConfig
  5. import (
  6. "fmt"
  7. "net"
  8. "syscall"
  9. "github.com/sirupsen/logrus"
  10. "golang.org/x/sys/unix"
  11. )
  12. func NewListener(l *logrus.Logger, ip net.IP, port int, multi bool, batch int) (Conn, error) {
  13. return NewGenericListener(l, ip, port, multi, batch)
  14. }
  15. func NewListenConfig(multi bool) net.ListenConfig {
  16. return net.ListenConfig{
  17. Control: func(network, address string, c syscall.RawConn) error {
  18. if multi {
  19. var controlErr error
  20. err := c.Control(func(fd uintptr) {
  21. if err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, unix.SO_REUSEPORT, 1); err != nil {
  22. controlErr = fmt.Errorf("SO_REUSEPORT failed: %v", err)
  23. return
  24. }
  25. })
  26. if err != nil {
  27. return err
  28. }
  29. if controlErr != nil {
  30. return controlErr
  31. }
  32. }
  33. return nil
  34. },
  35. }
  36. }
  37. func (u *GenericConn) Rebind() error {
  38. rc, err := u.UDPConn.SyscallConn()
  39. if err != nil {
  40. return err
  41. }
  42. return rc.Control(func(fd uintptr) {
  43. err := syscall.SetsockoptInt(int(fd), unix.IPPROTO_IPV6, unix.IPV6_BOUND_IF, 0)
  44. if err != nil {
  45. u.l.WithError(err).Error("Failed to rebind udp socket")
  46. }
  47. })
  48. }