Pull request: 3443 dhcp broadcast vol.2
Merge in DNS/adguard-home from 3443-dhcp-broadcast-vol.2 to master
Closes #3443.
Squashed commit of the following:
commit a85af89cb43f2489126fe3c12366fc034e89f59d
Merge: 72eb3a88 a4e07827
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Thu Sep 30 18:08:19 2021 +0300
Merge branch 'master' into 3443-dhcp-broadcast-vol.2
commit 72eb3a8853540b06ee1096decf50e836b539fe45
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Thu Sep 30 18:03:19 2021 +0300
dhcpd: imp code readability
commit 2d1fbc40d04a4125855d6be9f02e09d15430150d
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Thu Sep 30 14:16:59 2021 +0300
dhcpd: imp tests
commit 889fad3084ad2b81edfc12100e2ce29d323227ba
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Wed Sep 29 20:09:25 2021 +0300
dhcpd: imp code, docs
commit 1fd6b2346ff66e033bceaa169aed751be5822ca8
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Thu Sep 23 16:08:18 2021 +0300
dhcpd: unicast to mac address
This commit is contained in:
@@ -19,6 +19,7 @@ import (
|
||||
"github.com/go-ping/ping"
|
||||
"github.com/insomniacslk/dhcp/dhcpv4"
|
||||
"github.com/insomniacslk/dhcp/dhcpv4/server4"
|
||||
"github.com/mdlayher/raw"
|
||||
)
|
||||
|
||||
// v4Server is a DHCPv4 server.
|
||||
@@ -955,43 +956,44 @@ func (s *v4Server) packetHandler(conn net.PacketConn, peer net.Addr, req *dhcpv4
|
||||
//
|
||||
// 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 := req.GatewayIPAddr; giaddr != nil && !giaddr.IsUnspecified() {
|
||||
switch giaddr, ciaddr, mtype := req.GatewayIPAddr, req.ClientIPAddr, resp.MessageType(); {
|
||||
case giaddr != nil && !giaddr.IsUnspecified():
|
||||
// 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 {
|
||||
if mtype == dhcpv4.MessageTypeNak {
|
||||
// Set the broadcast bit in the DHCPNAK, so that the
|
||||
// relay agent broadcasted it to the client, because the
|
||||
// client may not have a correct network address or
|
||||
// subnet mask, and the client may not be answering ARP
|
||||
// requests.
|
||||
resp.SetBroadcast()
|
||||
}
|
||||
case mtype == dhcpv4.MessageTypeNak:
|
||||
// Broadcast any DHCPNAK messages to 0xffffffff.
|
||||
} else if ciaddr := req.ClientIPAddr; ciaddr != nil && !ciaddr.IsUnspecified() {
|
||||
case ciaddr != nil && !ciaddr.IsUnspecified():
|
||||
// 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
|
||||
case !req.IsBroadcast() && req.ClientHWAddr != nil:
|
||||
// Unicast DHCPOFFER and DHCPACK messages to the client's
|
||||
// hardware address and yiaddr.
|
||||
peer = &dhcpUnicastAddr{
|
||||
Addr: raw.Addr{HardwareAddr: req.ClientHWAddr},
|
||||
yiaddr: resp.YourIPAddr,
|
||||
}
|
||||
default:
|
||||
// Go on since peer is already set to broadcast.
|
||||
}
|
||||
|
||||
log.Debug("dhcpv4: sending to %s: %s", peer, resp.Summary())
|
||||
|
||||
_, err := conn.WriteTo(resp.ToBytes(), peer)
|
||||
if err != nil {
|
||||
if _, err := conn.WriteTo(resp.ToBytes(), peer); err != nil {
|
||||
log.Error("dhcpv4: conn.Write to %s failed: %s", peer, err)
|
||||
}
|
||||
}
|
||||
@@ -1029,11 +1031,18 @@ func (s *v4Server) Start() (err error) {
|
||||
|
||||
s.conf.dnsIPAddrs = dnsIPAddrs
|
||||
|
||||
laddr := &net.UDPAddr{
|
||||
IP: net.IP{0, 0, 0, 0},
|
||||
Port: dhcpv4.ServerPort,
|
||||
var c net.PacketConn
|
||||
if c, err = s.newDHCPConn(iface); err != nil {
|
||||
return err
|
||||
}
|
||||
s.srv, err = server4.NewServer(iface.Name, laddr, s.packetHandler, server4.WithDebugLogger())
|
||||
|
||||
s.srv, err = server4.NewServer(
|
||||
iface.Name,
|
||||
nil,
|
||||
s.packetHandler,
|
||||
server4.WithConn(c),
|
||||
server4.WithDebugLogger(),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user