From 26724df27e92d457c39c8bf0fb78179a874e3fb2 Mon Sep 17 00:00:00 2001 From: Eugene Burkov Date: Fri, 30 Jul 2021 14:52:58 +0300 Subject: [PATCH] all: imp code & docs --- internal/aghnet/net_freebsd.go | 7 +++---- internal/aghnet/net_freebsd_test.go | 4 ++-- internal/dhcpd/server.go | 4 ++-- internal/dhcpd/v4.go | 14 +++++++++++--- 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/internal/aghnet/net_freebsd.go b/internal/aghnet/net_freebsd.go index d9c68bd0ed1..df6e8970481 100644 --- a/internal/aghnet/net_freebsd.go +++ b/internal/aghnet/net_freebsd.go @@ -31,7 +31,6 @@ func ifaceHasStaticIP(ifaceName string) (ok bool, err error) { if err != nil { return false, err } - defer func() { err = errors.WithDeferred(err, f.Close()) }() var r io.Reader @@ -40,12 +39,12 @@ func ifaceHasStaticIP(ifaceName string) (ok bool, err error) { return false, err } - return rcconfStaticConfig(r, ifaceName) + return rcConfStaticConfig(r, ifaceName) } -// rcconfStaticConfig checks if the interface is configured by /etc/rc.conf to +// rcConfStaticConfig checks if the interface is configured by /etc/rc.conf to // have a static IP. -func rcconfStaticConfig(r io.Reader, ifaceName string) (has bool, err error) { +func rcConfStaticConfig(r io.Reader, ifaceName string) (has bool, err error) { s := bufio.NewScanner(r) for ifaceLinePref := fmt.Sprintf("ifconfig_%s", ifaceName); s.Scan(); { line := strings.TrimSpace(s.Text()) diff --git a/internal/aghnet/net_freebsd_test.go b/internal/aghnet/net_freebsd_test.go index cc3f959ea5a..bf8c7ec384a 100644 --- a/internal/aghnet/net_freebsd_test.go +++ b/internal/aghnet/net_freebsd_test.go @@ -11,7 +11,7 @@ import ( "github.com/stretchr/testify/require" ) -func TestRcconfStaticConfig(t *testing.T) { +func TestRcConfStaticConfig(t *testing.T) { const ifaceName = `em0` const nl = "\n" @@ -51,7 +51,7 @@ func TestRcconfStaticConfig(t *testing.T) { for _, tc := range testCases { r := strings.NewReader(tc.rcconfData) t.Run(tc.name, func(t *testing.T) { - has, err := rcconfStaticConfig(r, ifaceName) + has, err := rcConfStaticConfig(r, ifaceName) require.NoError(t, err) assert.Equal(t, tc.wantHas, has) diff --git a/internal/dhcpd/server.go b/internal/dhcpd/server.go index 3acd61725a0..d326e812c8e 100644 --- a/internal/dhcpd/server.go +++ b/internal/dhcpd/server.go @@ -38,8 +38,8 @@ type V4ServerConf struct { GatewayIP net.IP `yaml:"gateway_ip" json:"gateway_ip"` SubnetMask net.IP `yaml:"subnet_mask" json:"subnet_mask"` - // broadcastIP is the broadcasting address specific for the configured - // interface. + // broadcastIP is the broadcasting address pre-calculated from the + // configured gateway IP and subnet mask. broadcastIP net.IP // The first & the last IP address for dynamic leases diff --git a/internal/dhcpd/v4.go b/internal/dhcpd/v4.go index bb702fafe32..f04767e8bd1 100644 --- a/internal/dhcpd/v4.go +++ b/internal/dhcpd/v4.go @@ -927,15 +927,23 @@ func (s *v4Server) packetHandler(conn net.PacketConn, peer net.Addr, req *dhcpv4 resp.Options.Update(dhcpv4.OptMessageType(dhcpv4.MessageTypeNak)) } - upeer, ok := peer.(*net.UDPAddr) + // peer is expected to be of type *net.UDPConn as the server4.NewServer + // initializes it. + udpPeer, ok := peer.(*net.UDPAddr) if !ok { log.Error("dhcpv4: peer is of unexpected type %T", peer) return } - if upeer.IP.Equal(net.IPv4bcast) { - upeer.IP = s.conf.broadcastIP + // Despite the fact that server4.NewIPv4UDPConn explicitly sets socket + // options to allow broadcasting, it's also binds the connection to the + // specified interface. On FreeBSD conn.WriteTo causes errors while + // writing to the addresses that belong to another interface. So use + // the broadcast address specific for the binded interface in case the + // server4.Serve method sets it to net.IPv4Bcast. + if udpPeer.IP.Equal(net.IPv4bcast) { + udpPeer.IP = s.conf.broadcastIP } log.Debug("dhcpv4: sending: %s", resp.Summary())