f-46: dhcpd: add the decision engine and the persisted state #46
Store porte la configuration du subnet et les réservations par MAC, et les persiste dans un .state écrit de façon atomique (temp + chmod 0600 + rename). Chaque écriture remplace le fichier, donc un chmod externe est effacé. Les snapshots sont à la fois la forme sérialisée et la forme d'entrée des ordres : validation au moment où l'agent pousse, pas quand un guest demande une adresse. Les hôtes sont triés par MAC, base du digest de L3. Handle rend (nil, nil) — le silence est un retour normal — pour un type de message non traité, un subnet non configuré ou une MAC inconnue. La MAC est normalisée à l'écriture comme au chargement. 58 tests, -race propre, dix mutations toutes détectées. Signed-off-by: GnomeZworc <nicolas.boufidjeline@g3e.fr>
This commit is contained in:
parent
8658acfe08
commit
e44f3aca96
4 changed files with 901 additions and 0 deletions
66
internal/dhcpd/engine.go
Normal file
66
internal/dhcpd/engine.go
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
package dhcpd
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
"github.com/insomniacslk/dhcp/dhcpv4"
|
||||
)
|
||||
|
||||
func answerable(req *dhcpv4.DHCPv4) bool {
|
||||
switch req.MessageType() {
|
||||
case dhcpv4.MessageTypeDiscover, dhcpv4.MessageTypeRequest:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Store) Handle(req *dhcpv4.DHCPv4) (*dhcpv4.DHCPv4, error) {
|
||||
if req == nil {
|
||||
return nil, ErrNoRequest
|
||||
}
|
||||
if !answerable(req) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
subnet, configured := s.Subnet()
|
||||
if !configured {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
host, known := s.Lookup(req.ClientHWAddr)
|
||||
if !known {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return BuildReply(subnet, host, req)
|
||||
}
|
||||
|
||||
func (s *Store) Probe(mac string) (*dhcpv4.DHCPv4, error) {
|
||||
key, err := normalizeMAC(mac)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
subnet, configured := s.Subnet()
|
||||
if !configured {
|
||||
return nil, ErrNotConfigured
|
||||
}
|
||||
|
||||
parsed, err := net.ParseMAC(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
host, known := s.Lookup(parsed)
|
||||
if !known {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
req, err := dhcpv4.New(dhcpv4.WithMessageType(dhcpv4.MessageTypeRequest), dhcpv4.WithHwAddr(parsed))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return BuildReply(subnet, host, req)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue