From df9a40557c42dd5fb916943e438363cb809d48fa Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Wed, 21 Nov 2018 08:41:24 +0100 Subject: [PATCH] dhcp4: correctly check errors from c.once --- integration/dhcpv4/dhcpv4_test.go | 12 ++++++++++++ internal/dhcp4/dhcp4.go | 14 +++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/integration/dhcpv4/dhcpv4_test.go b/integration/dhcpv4/dhcpv4_test.go index 3305e32..43b86e5 100644 --- a/integration/dhcpv4/dhcpv4_test.go +++ b/integration/dhcpv4/dhcpv4_test.go @@ -173,3 +173,15 @@ func TestDHCPv4(t *testing.T) { strings.Join(diff.TrimLines(want), "\n"))) } } + +func TestError(t *testing.T) { + c := dhcp4.Client{ + Interface: nil, + } + if c.ObtainOrRenew() { + t.Fatalf("ObtainOrRenew unexpectedly succeeded") + } + if err := c.Err(); err == nil { + t.Fatalf("Err unexpectedly nil") + } +} diff --git a/internal/dhcp4/dhcp4.go b/internal/dhcp4/dhcp4.go index 7d92d50..6aec109 100644 --- a/internal/dhcp4/dhcp4.go +++ b/internal/dhcp4/dhcp4.go @@ -18,7 +18,6 @@ package dhcp4 import ( "bytes" "fmt" - "log" "net" "sync" "syscall" @@ -81,6 +80,7 @@ func (c *Client) packet(xid uint32, opts []layers.DHCPOption) *layers.DHCPv4 { // ObtainOrRenew returns false when encountering a permanent error. func (c *Client) ObtainOrRenew() bool { + var onceErr error c.once.Do(func() { if c.timeNow == nil { c.timeNow = time.Now @@ -90,13 +90,13 @@ func (c *Client) ObtainOrRenew() bool { LinuxSockDGRAM: true, }) if err != nil { - c.err = err + onceErr = err return } c.connection = conn } if c.connection == nil && c.Interface == nil { - c.err = fmt.Errorf("Interface is nil") + onceErr = fmt.Errorf("Interface is nil") return } if c.hardwareAddr == nil { @@ -108,12 +108,16 @@ func (c *Client) ObtainOrRenew() bool { if c.hostname == "" { var utsname unix.Utsname if err := unix.Uname(&utsname); err != nil { - log.Fatal(err) + onceErr = err + return } c.hostname = string(utsname.Nodename[:bytes.IndexByte(utsname.Nodename[:], 0)]) } }) - // TODO: handle c.err from c.once + if onceErr != nil { + c.err = onceErr + return false // permanent error + } c.err = nil // clear previous error ack, err := c.dhcpRequest() if err != nil {