Pull request: 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 <E.Burkov@AdGuard.COM>
Date:   Tue Mar 29 15:57:06 2022 +0300

    aghnet: fix catching timeout errors
This commit is contained in:
Eugene Burkov 2022-03-29 16:21:22 +03:00
parent 0d562a7b1f
commit f31ffcc5d1
2 changed files with 18 additions and 25 deletions

View file

@ -81,6 +81,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. - 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 ### Removed
- Go 1.16 support. - Go 1.16 support.

View file

@ -156,7 +156,7 @@ func tryConn4(req *dhcpv4.DHCPv4, c net.PacketConn, iface *net.Interface) (ok, n
b := make([]byte, 1500) b := make([]byte, 1500)
n, _, err := c.ReadFrom(b) n, _, err := c.ReadFrom(b)
if err != nil { if err != nil {
if isTimeout(err) { if errors.Is(err, os.ErrDeadlineExceeded) {
log.Debug("dhcpv4: didn't receive dhcp response") log.Debug("dhcpv4: didn't receive dhcp response")
return false, false, nil 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()) log.Debug("dhcpv4: received message from server: %s", response.Summary())
if !(response.OpCode == dhcpv4.OpcodeBootReply && switch {
response.HWType == iana.HWTypeEthernet && case
bytes.Equal(response.ClientHWAddr, iface.HardwareAddr) && response.OpCode != dhcpv4.OpcodeBootReply,
bytes.Equal(response.TransactionID[:], req.TransactionID[:]) && response.HWType != iana.HWTypeEthernet,
response.Options.Has(dhcpv4.OptionDHCPMessageType)) { !bytes.Equal(response.ClientHWAddr, iface.HardwareAddr),
response.TransactionID != req.TransactionID,
log.Debug("dhcpv4: received message from server doesn't match our request") !response.Options.Has(dhcpv4.OptionDHCPMessageType):
log.Debug("dhcpv4: received response doesn't match the request")
return false, true, nil 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 // 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) n, _, err := c.ReadFrom(b)
if err != nil { if err != nil {
if isTimeout(err) { if errors.Is(err, os.ErrDeadlineExceeded) {
log.Debug("dhcpv6: didn't receive dhcp response") log.Debug("dhcpv6: didn't receive dhcp response")
return false, false, nil 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 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
}