Pull request: 3443 dhcp broadcast
Merge in DNS/adguard-home from 3443-fix-wired-dhcp to master Updates #3443. Squashed commit of the following: commit ec7c3b73e274ba7c05c5856cb2f4ea218ad46870 Author: Eugene Burkov <E.Burkov@AdGuard.COM> Date: Tue Sep 7 18:21:07 2021 +0300 dhcpd: imp docs & naming commit d87c646af44d837c81aa032e82aad846bde97bc8 Author: Eugene Burkov <E.Burkov@AdGuard.COM> Date: Tue Sep 7 16:56:36 2021 +0300 dhcpd: fix build tags & log changes commit cbd0b3c1aa0efb32aeaa9130111719ab3861e817 Author: Eugene Burkov <E.Burkov@AdGuard.COM> Date: Tue Sep 7 16:26:50 2021 +0300 dhcpd: revert 3443 & imp broadcasting
This commit is contained in:
@@ -928,28 +928,50 @@ func (s *v4Server) packetHandler(conn net.PacketConn, peer net.Addr, req *dhcpv4
|
||||
resp.Options.Update(dhcpv4.OptMessageType(dhcpv4.MessageTypeNak))
|
||||
}
|
||||
|
||||
// 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)
|
||||
s.send(peer, conn, req, resp)
|
||||
}
|
||||
|
||||
// send writes resp for peer to conn considering the req's fields and options
|
||||
// according to RFC-2131.
|
||||
//
|
||||
// See https://datatracker.ietf.org/doc/html/rfc2131#section-4.1.
|
||||
func (s *v4Server) send(peer net.Addr, conn net.PacketConn, req, resp *dhcpv4.DHCPv4) {
|
||||
var unicast bool
|
||||
if giaddr, unspec := req.GatewayIPAddr, netutil.IPv4Zero(); !giaddr.Equal(unspec) {
|
||||
// Send any return messages to the server port on the BOOTP
|
||||
// relay agent whose address appears in giaddr.
|
||||
peer = &net.UDPAddr{
|
||||
IP: giaddr,
|
||||
Port: dhcpv4.ServerPort,
|
||||
}
|
||||
unicast = true
|
||||
} else if mtype := resp.MessageType(); mtype == dhcpv4.MessageTypeNak {
|
||||
// Broadcast any DHCPNAK messages to 0xffffffff.
|
||||
} else if ciaddr := req.ClientIPAddr; !ciaddr.Equal(unspec) {
|
||||
// Unicast DHCPOFFER and DHCPACK messages to the address in
|
||||
// ciaddr.
|
||||
peer = &net.UDPAddr{
|
||||
IP: ciaddr,
|
||||
Port: dhcpv4.ClientPort,
|
||||
}
|
||||
unicast = true
|
||||
}
|
||||
|
||||
// TODO(e.burkov): Unicast the message to the actual link-layer address
|
||||
// of the client if broadcast bit is not set. Perhaps, use custom
|
||||
// connection when creating the server.
|
||||
//
|
||||
// See https://github.com/AdguardTeam/AdGuardHome/issues/3443.
|
||||
|
||||
if !unicast {
|
||||
s.broadcast(peer, conn, resp)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Despite the fact that server4.NewIPv4UDPConn explicitly sets socket
|
||||
// options to allow broadcasting, it also binds the connection to a
|
||||
// specific 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
|
||||
// server4.Server.Serve sets it to net.IPv4Bcast.
|
||||
if udpPeer.IP.Equal(net.IPv4bcast) {
|
||||
udpPeer.IP = s.conf.broadcastIP
|
||||
}
|
||||
log.Debug("dhcpv4: sending to %s: %s", peer, resp.Summary())
|
||||
|
||||
log.Debug("dhcpv4: sending: %s", resp.Summary())
|
||||
|
||||
_, err = conn.WriteTo(resp.ToBytes(), peer)
|
||||
_, err := conn.WriteTo(resp.ToBytes(), peer)
|
||||
if err != nil {
|
||||
log.Error("dhcpv4: conn.Write to %s failed: %s", peer, err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user