diff --git a/cmd/dhcp4d/dhcp4d.go b/cmd/dhcp4d/dhcp4d.go index 7d4b79d..6babb70 100644 --- a/cmd/dhcp4d/dhcp4d.go +++ b/cmd/dhcp4d/dhcp4d.go @@ -389,7 +389,7 @@ func newSrv(permDir string) (*srv, error) { if err := json.Indent(&out, b, "", "\t"); err == nil { b = out.Bytes() } - if err := renameio.WriteFile(filepath.Join(permDir, "dhcp4d/leases.json"), out.Bytes(), 0644); err != nil { + if err := renameio.WriteFile(filepath.Join(permDir, "dhcp4d/leases.json"), b, 0644); err != nil { errs <- err } updateNonExpired(leases) diff --git a/integration/radvd/radvd_test.go b/integration/radvd/radvd_test.go index bf23f5d..82c2e46 100644 --- a/integration/radvd/radvd_test.go +++ b/integration/radvd/radvd_test.go @@ -15,6 +15,7 @@ package integration_test import ( + "fmt" "io/ioutil" "net" "os" @@ -80,7 +81,7 @@ func TestRouterAdvertisement(t *testing.T) { } go func() { if err := srv.Serve("veth2a", conn); err != nil { - t.Fatal(err) + panic(fmt.Sprintf("failed to serve router advertisements: %v", err)) } }() //time.Sleep(5 * time.Second) diff --git a/internal/dhcp4/dhcp4.go b/internal/dhcp4/dhcp4.go index 25796e7..5c99b80 100644 --- a/internal/dhcp4/dhcp4.go +++ b/internal/dhcp4/dhcp4.go @@ -100,7 +100,7 @@ func (c *Client) ObtainOrRenew() bool { c.connection = conn } if c.connection == nil && c.Interface == nil { - onceErr = fmt.Errorf("Interface is nil") + onceErr = fmt.Errorf("c.Interface is nil") return } if c.hardwareAddr == nil && c.HWAddr != nil { diff --git a/internal/dhcp4d/dhcp4d_test.go b/internal/dhcp4d/dhcp4d_test.go index 95cfd0f..522f2dd 100644 --- a/internal/dhcp4d/dhcp4d_test.go +++ b/internal/dhcp4d/dhcp4d_test.go @@ -15,7 +15,6 @@ package dhcp4d import ( - "bytes" "io/ioutil" "net" "os" @@ -112,7 +111,7 @@ func TestLease(t *testing.T) { t.Fatalf("unexpected number of leases: got %d, want %d", got, want) } l := leases[0] - if got, want := l.Addr, addr; !bytes.Equal(got, want) { + if got, want := l.Addr, addr; !got.Equal(want) { t.Fatalf("unexpected lease.Addr: got %v, want %v", got, want) } if got, want := l.HardwareAddr, hardwareAddr.String(); got != want { @@ -155,7 +154,7 @@ func TestPreferredAddress(t *testing.T) { t.Run("no requested IP", func(t *testing.T) { p := request(net.IPv4zero, hardwareAddr) resp := handler.serveDHCP(p, dhcp4.Discover, p.ParseOptions()) - if got, want := resp.YIAddr().To4(), addr.To4(); bytes.Equal(got, want) { + if got, want := resp.YIAddr().To4(), addr.To4(); got.Equal(want) { t.Errorf("DHCPOFFER for wrong IP: got %v, want anything else", got) } }) @@ -163,7 +162,7 @@ func TestPreferredAddress(t *testing.T) { t.Run("requested CIAddr", func(t *testing.T) { p := request(addr, hardwareAddr) resp := handler.serveDHCP(p, dhcp4.Discover, p.ParseOptions()) - if got, want := resp.YIAddr().To4(), addr.To4(); !bytes.Equal(got, want) { + if got, want := resp.YIAddr().To4(), addr.To4(); !got.Equal(want) { t.Errorf("DHCPOFFER for wrong IP: got %v, want %v", got, want) } }) @@ -188,7 +187,7 @@ func TestPreferredAddress(t *testing.T) { }, ) resp := handler.serveDHCP(p, dhcp4.Discover, p.ParseOptions()) - if got, want := resp.YIAddr().To4(), addr.To4(); !bytes.Equal(got, want) { + if got, want := resp.YIAddr().To4(), addr.To4(); !got.Equal(want) { t.Errorf("DHCPOFFER for wrong IP: got %v, want %v", got, want) } }) @@ -227,7 +226,7 @@ func TestPreviousLease(t *testing.T) { p := request(addr1, hardwareAddr1) resp := handler.serveDHCP(p, dhcp4.Request, p.ParseOptions()) - if got, want := resp.YIAddr().To4(), addr1.To4(); !bytes.Equal(got, want) { + if got, want := resp.YIAddr().To4(), addr1.To4(); !got.Equal(want) { t.Errorf("DHCPREQUEST resulted in wrong IP: got %v, want %v", got, want) } @@ -239,21 +238,21 @@ func TestPreviousLease(t *testing.T) { p = discover(net.IPv4zero, hardwareAddr1) resp = handler.serveDHCP(p, dhcp4.Discover, p.ParseOptions()) - if got, want := resp.YIAddr().To4(), addr1.To4(); !bytes.Equal(got, want) { + if got, want := resp.YIAddr().To4(), addr1.To4(); !got.Equal(want) { t.Errorf("DHCPOFFER for wrong IP: got %v, want %v", got, want) } // Free addr1 by requesting addr2 p = request(addr2, hardwareAddr1) resp = handler.serveDHCP(p, dhcp4.Request, p.ParseOptions()) - if got, want := resp.YIAddr().To4(), addr2.To4(); !bytes.Equal(got, want) { + if got, want := resp.YIAddr().To4(), addr2.To4(); !got.Equal(want) { t.Errorf("DHCPREQUEST resulted in wrong IP: got %v, want %v", got, want) } // Verify addr1 is now available to other clients p = request(addr1, hardwareAddr2) resp = handler.serveDHCP(p, dhcp4.Request, p.ParseOptions()) - if got, want := resp.YIAddr().To4(), addr1.To4(); !bytes.Equal(got, want) { + if got, want := resp.YIAddr().To4(), addr1.To4(); !got.Equal(want) { t.Errorf("DHCPREQUEST resulted in wrong IP: got %v, want %v", got, want) } } @@ -279,7 +278,7 @@ func TestPermanentLease(t *testing.T) { p := request(addr, hardwareAddr) resp := handler.serveDHCP(p, dhcp4.Request, p.ParseOptions()) - if got, want := resp.YIAddr().To4(), addr.To4(); !bytes.Equal(got, want) { + if got, want := resp.YIAddr().To4(), addr.To4(); !got.Equal(want) { t.Errorf("DHCPREQUEST resulted in wrong IP: got %v, want %v", got, want) } @@ -312,7 +311,7 @@ func TestExpiration(t *testing.T) { hardwareAddr[len(hardwareAddr)-1] = addr[len(addr)-1] p := request(addr, hardwareAddr) resp := handler.serveDHCP(p, dhcp4.Request, p.ParseOptions()) - if got, want := resp.YIAddr().To4(), addr.To4(); !bytes.Equal(got, want) { + if got, want := resp.YIAddr().To4(), addr.To4(); !got.Equal(want) { t.Errorf("DHCPREQUEST resulted in wrong IP: got %v, want %v", got, want) } } @@ -325,7 +324,7 @@ func TestExpiration(t *testing.T) { hardwareAddr[len(hardwareAddr)-1] = addr[len(addr)-1] p := request(addr, hardwareAddr) resp := handler.serveDHCP(p, dhcp4.Request, p.ParseOptions()) - if got, want := resp.YIAddr().To4(), addr.To4(); !bytes.Equal(got, want) { + if got, want := resp.YIAddr().To4(), addr.To4(); !got.Equal(want) { t.Errorf("DHCPREQUEST resulted in wrong IP: got %v, want %v", got, want) } } @@ -359,7 +358,7 @@ func TestExpiration(t *testing.T) { addr[len(addr)-1] = byte(1 + (i % 254)) // avoid .0 (net) and .255 (broadcast) p := request(addr, hardwareAddr) resp := handler.serveDHCP(p, dhcp4.Request, p.ParseOptions()) - if got, want := resp.YIAddr().To4(), addr.To4(); !bytes.Equal(got, want) { + if got, want := resp.YIAddr().To4(), addr.To4(); !got.Equal(want) { t.Errorf("DHCPREQUEST resulted in wrong IP: got %v, want %v", got, want) } } @@ -408,7 +407,7 @@ func TestRequestExpired(t *testing.T) { t.Run("mbp requests any", func(t *testing.T) { p := request(addr, hardwareAddr["mbp"]) resp := handler.serveDHCP(p, dhcp4.Discover, p.ParseOptions()) - if got, want := resp.YIAddr().To4(), addr.To4(); bytes.Equal(got, want) { + if got, want := resp.YIAddr().To4(), addr.To4(); got.Equal(want) { t.Errorf("DHCPOFFER for wrong IP: got offered %v (in use!)", got) } }) @@ -452,7 +451,7 @@ func TestPersistentStorage(t *testing.T) { p := request(net.IPv4zero, hardwareAddr) resp := handler.serveDHCP(p, dhcp4.Discover, p.ParseOptions()) - if got, want := resp.YIAddr().To4(), addr.To4(); !bytes.Equal(got, want) { + if got, want := resp.YIAddr().To4(), addr.To4(); !got.Equal(want) { t.Errorf("DHCPOFFER for wrong IP: got %v, want %v", got, want) } } diff --git a/internal/dhcp6/dhcp6.go b/internal/dhcp6/dhcp6.go index 7048b2c..739e73a 100644 --- a/internal/dhcp6/dhcp6.go +++ b/internal/dhcp6/dhcp6.go @@ -168,7 +168,7 @@ const maxUDPReceivedPacketSize = 8192 // arbitrary size. Theoretically could be func (c *Client) sendReceive(packet *dhcpv6.Message, expectedType dhcpv6.MessageType) (*dhcpv6.Message, error) { if packet == nil { - return nil, fmt.Errorf("Packet to send cannot be nil") + return nil, fmt.Errorf("packet to send cannot be nil") } if expectedType == dhcpv6.MessageTypeNone { // infer the expected type from the packet being sent diff --git a/internal/dns/dns.go b/internal/dns/dns.go index b48fbac..dc7d83d 100644 --- a/internal/dns/dns.go +++ b/internal/dns/dns.go @@ -327,7 +327,7 @@ func isLocalInAddrArpa(q string) bool { return local } -var sentinelEmpty = errors.New("no answers") +var errEmpty = errors.New("no answers") func (s *Server) resolve(q dns.Question) (rr dns.RR, err error) { if q.Qclass != dns.ClassINET { @@ -350,7 +350,7 @@ func (s *Server) resolve(q dns.Question) (rr dns.RR, err error) { if q.Qtype == dns.TypeA { return dns.NewRR(q.Name + " 3600 IN A " + host) } - return nil, sentinelEmpty + return nil, errEmpty } } if q.Qtype == dns.TypePTR { @@ -373,7 +373,7 @@ func (s *Server) handleInternal(w dns.ResponseWriter, r *dns.Msg) { } rr, err := s.resolve(r.Question[0]) if err != nil { - if err == sentinelEmpty { + if err == errEmpty { m := new(dns.Msg) m.SetReply(r) w.WriteMsg(m) @@ -457,7 +457,7 @@ func (s *Server) resolveSubname(hostname string, q dns.Question) (dns.RR, error) if q.Qtype == dns.TypeA { return dns.NewRR(q.Name + " 3600 IN A " + host) } - return nil, sentinelEmpty + return nil, errEmpty } if ip, ok := s.subname(hostname, name); ok { @@ -467,7 +467,7 @@ func (s *Server) resolveSubname(hostname string, q dns.Question) (dns.RR, error) if q.Qtype == dns.TypeAAAA && ip.To4() == nil { return dns.NewRR(q.Name + " 3600 IN AAAA " + ip.String()) } - return nil, sentinelEmpty + return nil, errEmpty } } return nil, nil @@ -481,7 +481,7 @@ func (s *Server) subnameHandler(hostname string) func(w dns.ResponseWriter, r *d rr, err := s.resolveSubname(hostname, r.Question[0]) if err != nil { - if err == sentinelEmpty { + if err == errEmpty { m := new(dns.Msg) m.SetReply(r) w.WriteMsg(m) diff --git a/internal/dns/dns_test.go b/internal/dns/dns_test.go index c278cab..7700716 100644 --- a/internal/dns/dns_test.go +++ b/internal/dns/dns_test.go @@ -15,7 +15,6 @@ package dns import ( - "bytes" "fmt" "io/ioutil" "net" @@ -412,7 +411,7 @@ func TestLocalhost(t *testing.T) { if _, ok := a.(*dns.AAAA); !ok { t.Fatalf("unexpected response type: got %T, want dns.A", a) } - if got, want := a.(*dns.AAAA).AAAA, (net.ParseIP("::1")); !bytes.Equal(got, want) { + if got, want := a.(*dns.AAAA).AAAA, (net.ParseIP("::1")); !got.Equal(want) { t.Fatalf("unexpected response IP: got %v, want %v", got, want) } }) diff --git a/internal/netconfig/netconfig.go b/internal/netconfig/netconfig.go index 77ad720..53637d2 100644 --- a/internal/netconfig/netconfig.go +++ b/internal/netconfig/netconfig.go @@ -238,6 +238,9 @@ func applyInterfaces(dir, root string) error { byName[details.Name] = details } links, err := netlink.LinkList() + if err != nil { + return err + } for _, l := range links { attr := l.Attrs() // TODO: prefix log line with details about the interface. diff --git a/internal/radvd/radvd.go b/internal/radvd/radvd.go index 07966cb..742c06d 100644 --- a/internal/radvd/radvd.go +++ b/internal/radvd/radvd.go @@ -16,13 +16,11 @@ package radvd import ( - "encoding/binary" "log" "net" "sync" "time" - "github.com/google/gopacket/layers" "github.com/mdlayher/ndp" "golang.org/x/net/ipv6" @@ -118,69 +116,6 @@ func (s *Server) ListenAndServe(ifname string) error { return s.Serve(ifname, conn) } -type sourceLinkLayerAddress struct { - address net.HardwareAddr -} - -func (o sourceLinkLayerAddress) Marshal() layers.ICMPv6Option { - return layers.ICMPv6Option{ - Type: layers.ICMPv6OptSourceAddress, - Data: o.address, - } -} - -type mtu struct { - mtu uint32 -} - -func (o mtu) Marshal() layers.ICMPv6Option { - buf := make([]byte, 6) - // First 2 bytes are reserved - binary.BigEndian.PutUint32(buf[2:], o.mtu) - return layers.ICMPv6Option{ - Type: layers.ICMPv6OptMTU, - Data: buf, - } -} - -type prefixInfo struct { - prefixLength byte - flags byte // TODO: enum for values - validLifetime uint32 // seconds - preferredLifetime uint32 // seconds - prefix [16]byte -} - -func (o prefixInfo) Marshal() layers.ICMPv6Option { - buf := make([]byte, 30) - buf[0] = o.prefixLength - buf[1] = o.flags - binary.BigEndian.PutUint32(buf[2:], o.validLifetime) - binary.BigEndian.PutUint32(buf[6:], o.preferredLifetime) - // 4 bytes reserved - copy(buf[14:], o.prefix[:]) - return layers.ICMPv6Option{ - Type: layers.ICMPv6OptPrefixInfo, - Data: buf, - } -} - -type rdnss struct { - lifetime uint32 // seconds - server []byte -} - -func (o rdnss) Marshal() layers.ICMPv6Option { - buf := make([]byte, 22) - // 2 bytes reserved - binary.BigEndian.PutUint32(buf[2:], o.lifetime) - copy(buf[6:], o.server[:]) - return layers.ICMPv6Option{ - Type: 25, // TODO: Recursive DNS Server - Data: buf, - } -} - var ipv6LinkLocal = func(cidr string) *net.IPNet { _, net, err := net.ParseCIDR(cidr) if err != nil { diff --git a/internal/testing/dnsmasq/dnsmasq.go b/internal/testing/dnsmasq/dnsmasq.go index f3217c1..ba696ba 100644 --- a/internal/testing/dnsmasq/dnsmasq.go +++ b/internal/testing/dnsmasq/dnsmasq.go @@ -116,7 +116,7 @@ func Run(t *testing.T, iface, ns string) *Process { case <-p.done: return // test done, any errors are from our Kill() default: - t.Fatalf("dnsmasq exited prematurely: %v", err) + panic(fmt.Sprintf("dnsmasq exited prematurely: %v", err)) } }()