From cddcf852c2102fb622206c63027b8348245b42b0 Mon Sep 17 00:00:00 2001 From: Eugene Burkov Date: Tue, 29 Mar 2022 16:21:22 +0300 Subject: [PATCH] cherry-pick: aghnet: fix catching timeout errors Merge in DNS/adguard-home from fix-is-timeout to master Squashed commit of the following: commit b0fefd01f27a835a34e44beb2eb2c34027960a51 Author: Eugene Burkov Date: Tue Mar 29 15:57:06 2022 +0300 aghnet: fix catching timeout errors --- CHANGELOG.md | 4 ++++ internal/aghnet/dhcp_unix.go | 39 +++++++++++++----------------------- 2 files changed, 18 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b89c6b3..6c09d44e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -74,6 +74,10 @@ In this release, the schema version has changed from 12 to 13. - Go 1.17 support. v0.109.0 will require at least Go 1.18 to build. +### Fixed + +- I/O timeout errors on checking another DHCP server. + ### Removed - Go 1.16 support. diff --git a/internal/aghnet/dhcp_unix.go b/internal/aghnet/dhcp_unix.go index fd2b9b93..4791d0e5 100644 --- a/internal/aghnet/dhcp_unix.go +++ b/internal/aghnet/dhcp_unix.go @@ -156,7 +156,7 @@ func tryConn4(req *dhcpv4.DHCPv4, c net.PacketConn, iface *net.Interface) (ok, n b := make([]byte, 1500) n, _, err := c.ReadFrom(b) if err != nil { - if isTimeout(err) { + if errors.Is(err, os.ErrDeadlineExceeded) { log.Debug("dhcpv4: didn't receive dhcp response") return false, false, nil @@ -176,20 +176,21 @@ func tryConn4(req *dhcpv4.DHCPv4, c net.PacketConn, iface *net.Interface) (ok, n log.Debug("dhcpv4: received message from server: %s", response.Summary()) - if !(response.OpCode == dhcpv4.OpcodeBootReply && - response.HWType == iana.HWTypeEthernet && - bytes.Equal(response.ClientHWAddr, iface.HardwareAddr) && - bytes.Equal(response.TransactionID[:], req.TransactionID[:]) && - response.Options.Has(dhcpv4.OptionDHCPMessageType)) { - - log.Debug("dhcpv4: received message from server doesn't match our request") + switch { + case + response.OpCode != dhcpv4.OpcodeBootReply, + response.HWType != iana.HWTypeEthernet, + !bytes.Equal(response.ClientHWAddr, iface.HardwareAddr), + response.TransactionID != req.TransactionID, + !response.Options.Has(dhcpv4.OptionDHCPMessageType): + log.Debug("dhcpv4: received response doesn't match the request") return false, true, nil + default: + log.Tracef("dhcpv4: the packet is from an active dhcp server") + + return true, false, nil } - - log.Tracef("dhcpv4: the packet is from an active dhcp server") - - return true, false, nil } // checkOtherDHCPv6 sends a DHCP request to the specified network interface, and @@ -275,7 +276,7 @@ func tryConn6(req *dhcpv6.Message, c net.PacketConn) (ok, next bool, err error) n, _, err := c.ReadFrom(b) if err != nil { - if isTimeout(err) { + if errors.Is(err, os.ErrDeadlineExceeded) { log.Debug("dhcpv6: didn't receive dhcp response") return false, false, nil @@ -318,15 +319,3 @@ func tryConn6(req *dhcpv6.Message, c net.PacketConn) (ok, next bool, err error) return true, false, nil } - -// isTimeout returns true if err is an operation timeout error from net package. -// -// TODO(e.burkov): Consider moving into netutil. -func isTimeout(err error) (ok bool) { - var operr *net.OpError - if errors.As(err, &operr) { - return operr.Timeout() - } - - return false -}