+ remove, list static leases

This commit is contained in:
Simon Zolin 2020-04-28 17:47:58 +03:00
parent a5727f8dcb
commit 9fa72cb7c0
3 changed files with 115 additions and 25 deletions

View file

@ -300,7 +300,28 @@ func (s *Server) handleDHCPRemoveStaticLease(w http.ResponseWriter, r *http.Requ
return
}
ip, _ := parseIPv4(lj.IP)
ip := net.ParseIP(lj.IP)
if ip != nil && ip.To16() != nil {
mac, err := net.ParseMAC(lj.HWAddr)
if err != nil {
httpError(r, w, http.StatusBadRequest, "invalid MAC")
return
}
lease := Lease{
IP: ip,
HWAddr: mac,
}
err = s.v6RemoveStaticLease(lease)
if err != nil {
httpError(r, w, http.StatusBadRequest, "%s", err)
return
}
return
}
ip, _ = parseIPv4(lj.IP)
if ip == nil {
httpError(r, w, http.StatusBadRequest, "invalid IP")
return

View file

@ -239,29 +239,31 @@ func (s *Server) Start() error {
return wrapErrPrint(err, "Couldn't find interface by name %s", s.conf.InterfaceName)
}
c, err := newFilterConn(*iface, ":67") // it has to be bound to 0.0.0.0:67, otherwise it won't see DHCP discover/request packets
if err != nil {
return wrapErrPrint(err, "Couldn't start listening socket on 0.0.0.0:67")
}
log.Info("DHCP: listening on 0.0.0.0:67")
s.conn = c
s.cond = sync.NewCond(&s.mutex)
s.running = true
go func() {
// operate on c instead of c.conn because c.conn can change over time
err := dhcp4.Serve(c, s)
if err != nil && !s.stopping {
log.Printf("dhcp4.Serve() returned with error: %s", err)
if false {
c, err := newFilterConn(*iface, ":67") // it has to be bound to 0.0.0.0:67, otherwise it won't see DHCP discover/request packets
if err != nil {
return wrapErrPrint(err, "Couldn't start listening socket on 0.0.0.0:67")
}
_ = c.Close() // in case Serve() exits for other reason than listening socket closure
s.running = false
s.cond.Signal()
}()
log.Info("DHCP: listening on 0.0.0.0:67")
s.conn = c
s.cond = sync.NewCond(&s.mutex)
s.running = true
go func() {
// operate on c instead of c.conn because c.conn can change over time
err := dhcp4.Serve(c, s)
if err != nil && !s.stopping {
log.Printf("dhcp4.Serve() returned with error: %s", err)
}
_ = c.Close() // in case Serve() exits for other reason than listening socket closure
s.running = false
s.cond.Signal()
}()
}
if s.conf.EnableV6 {
err := s.v6Start()
err := s.v6Start(*iface)
if err != nil {
return err
}
@ -749,6 +751,9 @@ func (s *Server) Leases(flags int) []Lease {
}
s.leasesLock.RUnlock()
v6leases := s.v6GetLeases(flags)
result = append(result, v6leases...)
return result
}

View file

@ -13,7 +13,26 @@ import (
const valIAID = "ADGH"
func (s *Server) v6GetLeases(flags int) []Lease {
var result []Lease
s.v6LeasesLock.Lock()
for _, lease := range s.v6Leases {
if (flags&LeasesStatic) != 0 && lease.Expiry.Unix() == leaseExpireStatic {
result = append(result, *lease)
}
}
s.v6LeasesLock.Unlock()
return result
}
func (s *Server) v6AddStaticLease(l Lease) error {
if len(l.IP) != 16 {
return fmt.Errorf("invalid IP")
}
if len(l.HWAddr) != 6 {
return fmt.Errorf("invalid MAC")
}
l.Expiry = time.Unix(leaseExpireStatic, 0)
s.v6LeasesLock.Lock()
@ -24,6 +43,47 @@ func (s *Server) v6AddStaticLease(l Lease) error {
return nil
}
// Remove a lease
func (s *Server) v6RmLease(l Lease) error {
var newLeases []*Lease
for _, lease := range s.v6Leases {
if net.IP.Equal(lease.IP, l.IP) {
if !bytes.Equal(lease.HWAddr, l.HWAddr) {
return fmt.Errorf("Lease not found")
}
continue
}
newLeases = append(newLeases, lease)
}
if len(newLeases) == len(s.v6Leases) {
return fmt.Errorf("Lease not found")
}
s.v6Leases = newLeases
return nil
}
func (s *Server) v6RemoveStaticLease(l Lease) error {
if len(l.IP) != 16 {
return fmt.Errorf("invalid IP")
}
if len(l.HWAddr) != 6 {
return fmt.Errorf("invalid MAC")
}
s.v6LeasesLock.Lock()
err := s.v6RmLease(l)
if err != nil {
s.v6LeasesLock.Unlock()
return err
}
s.dbStore()
s.v6LeasesLock.Unlock()
// s.notify(LeaseChangedRemovedStatic)
return nil
}
func (s *Server) v6FindLease(mac net.HardwareAddr) *Lease {
s.v6LeasesLock.Lock()
defer s.v6LeasesLock.Unlock()
@ -104,15 +164,19 @@ func (s *Server) v6PacketHandler(conn net.PacketConn, peer net.Addr, req dhcpv6.
}
}
func (s *Server) v6Start() error {
func (s *Server) v6Start(iface net.Interface) error {
laddr := &net.UDPAddr{
IP: net.ParseIP("::1"),
IP: net.ParseIP("::"),
Port: dhcpv6.DefaultServerPort,
}
server, err := server6.NewServer("", laddr, s.v6PacketHandler, server6.WithDebugLogger())
if err != nil {
log.Fatal(err)
return err
}
return server.Serve()
go func() {
err = server.Serve()
log.Error("DHCPv6: %s", err)
}()
return nil
}