mirror of
https://github.com/soypat/lneto.git
synced 2026-09-06 06:49:06 +00:00
fix: two fixes for dhcp/ap (#136)
* feature: ipv4 broadcast support * stackip4 method receiver varname * Incorporate strict test timing for TestStackGoTCPDialRetriesPendingControl (#135) * rewrite tinygo failing test to be more real-time * use channels to scheduler stack * fix flakiness by increasing timeout and move implementation to top of file * fix(dhcp): use chaddr as lookup key and patch Ethernet dst on Offer/Ack - Client lookup in Demux() now keys on chaddr when no OptClientIdentifier is present. It previously used ciaddr which is 0.0.0.0 during initial lease acquisition, causing MsgRequest to fail to match any client (RFC 2131 §4.3.1) - In Encapsulate(), overwrite Ethernet dst with client.hwaddr when packet is embedded in an IP frame (offsetToIP >= 14), per RFC 2131 §4.1. It previously sent to gwmac which clients without an ARP entry could not receive Signed-off-by: deadprogram <ron@hybridgroup.com> * fix: accept 255.255.255.255 aka bradcast dst in demux4 This fixes a problem with accept 255.255.255.255 dst in demux4 which previously dropped when stack had a static IP. Signed-off-by: deadprogram <ron@hybridgroup.com> --------- Signed-off-by: deadprogram <ron@hybridgroup.com> Co-authored-by: Patricio Whittingslow <graded.sp@gmail.com>
This commit is contained in:
+22
-1
@@ -152,7 +152,20 @@ func (sv *Server) Demux(carrierData []byte, frameOffset int) error {
|
||||
var client serverEntry
|
||||
var clientExists bool
|
||||
if len(clientID) == 0 {
|
||||
client, clientIDRaw, clientExists = sv.getClientByIP(*dfrm.CIAddr())
|
||||
// No explicit client identifier: use chaddr as the stable lookup key.
|
||||
// This lets the server correlate Discover→Offer→Request even when
|
||||
// ciaddr=0.0.0.0 (client has no IP yet), which is the normal case
|
||||
// for first-time lease acquisition (RFC 2131 §4.3.1).
|
||||
chaddr := *dfrm.CHAddrAs6()
|
||||
copy(clientIDRaw[:], chaddr[:])
|
||||
client, clientExists = sv.getClient(clientIDRaw)
|
||||
if !clientExists {
|
||||
// Fallback: look up by ciaddr for clients that did send ciaddr.
|
||||
ciaddr := *dfrm.CIAddr()
|
||||
if ciaddr != ([4]byte{}) {
|
||||
client, clientIDRaw, clientExists = sv.getClientByIP(ciaddr)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
copy(clientIDRaw[:], clientID)
|
||||
client, clientExists = sv.getClient(clientIDRaw)
|
||||
@@ -301,6 +314,14 @@ func (sv *Server) Encapsulate(carrierData []byte, offsetToIP, offsetToFrame int)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
// Per RFC 2131 §4.1: unicast Offer/Ack to chaddr because the client
|
||||
// does not yet have the offered IP, so no ARP entry exists.
|
||||
// The Ethernet layer sets dst=gwmac before calling us; overwrite it
|
||||
// here so the frame reaches the client via its hardware address.
|
||||
// offsetToIP==14 means the Ethernet header is at carrierData[0:14].
|
||||
if offsetToIP >= 14 {
|
||||
copy(carrierData[offsetToIP-14:offsetToIP-8], client.hwaddr[:])
|
||||
}
|
||||
}
|
||||
|
||||
client.state = futureState
|
||||
|
||||
Reference in New Issue
Block a user