diff --git a/conn.go b/conn.go index cacae9d..a361a71 100644 --- a/conn.go +++ b/conn.go @@ -5,18 +5,14 @@ package resolve import ( - "context" "errors" "fmt" "net" - "runtime" "sync" - "syscall" "time" "github.com/caffix/queue" "github.com/miekg/dns" - "golang.org/x/sys/unix" ) const headerSize = 12 @@ -74,7 +70,7 @@ func (r *connections) Close() { } func (r *connections) rotations() { - t := time.NewTicker(time.Minute) + t := time.NewTicker(30 * time.Second) defer t.Stop() for { @@ -121,48 +117,19 @@ func (r *connections) Next() net.PacketConn { } func (r *connections) Add() error { - var err error - var conn net.PacketConn - - if runtime.GOOS == "linux" { - conn, err = r.linuxListenPacket() - } else { - conn, err = net.ListenPacket("udp", ":0") + conn, err := r.ListenPacket() + if err != nil { + return err } - if err == nil { - _ = conn.SetDeadline(time.Time{}) - c := &connection{ - conn: conn, - done: make(chan struct{}), - } - r.conns = append(r.conns, c) - go r.responses(c) + _ = conn.SetDeadline(time.Time{}) + c := &connection{ + conn: conn, + done: make(chan struct{}), } - return err -} - -func (r *connections) linuxListenPacket() (net.PacketConn, error) { - lc := net.ListenConfig{ - Control: func(network, address string, c syscall.RawConn) error { - var operr error - - if err := c.Control(func(fd uintptr) { - operr = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEPORT, 1) - }); err != nil { - return err - } - - return operr - }, - } - - laddr := ":0" - if len(r.conns) > 0 { - laddr = r.conns[0].conn.LocalAddr().String() - } - - return lc.ListenPacket(context.Background(), "udp", laddr) + r.conns = append(r.conns, c) + go r.responses(c) + return nil } func (r *connections) WriteMsg(msg *dns.Msg, addr net.Addr) error { diff --git a/linux_packet.go b/linux_packet.go new file mode 100644 index 0000000..b526a04 --- /dev/null +++ b/linux_packet.go @@ -0,0 +1,38 @@ +// Copyright © by Jeff Foley 2024. All rights reserved. +// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. +// SPDX-License-Identifier: Apache-2.0 + +//go:build linux + +package resolve + +import ( + "context" + "net" + "syscall" + + "golang.org/x/sys/unix" +) + +func (r *connections) ListenPacket() (net.PacketConn, error) { + lc := net.ListenConfig{ + Control: func(network, address string, c syscall.RawConn) error { + var operr error + + if err := c.Control(func(fd uintptr) { + operr = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEPORT, 1) + }); err != nil { + return err + } + + return operr + }, + } + + laddr := ":0" + if len(r.conns) > 0 { + laddr = r.conns[0].conn.LocalAddr().String() + } + + return lc.ListenPacket(context.Background(), "udp", laddr) +} diff --git a/listen_packet.go b/listen_packet.go new file mode 100644 index 0000000..88b8a52 --- /dev/null +++ b/listen_packet.go @@ -0,0 +1,15 @@ +// Copyright © by Jeff Foley 2024. All rights reserved. +// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. +// SPDX-License-Identifier: Apache-2.0 + +//go:build !linux + +package resolve + +import ( + "net" +) + +func (r *connections) ListenPacket() (net.PacketConn, error) { + return net.ListenPacket("udp", ":0") +}