Skip to content

Commit

Permalink
Merge: * clients: update runtime clients of type DHCP by event from D…
Browse files Browse the repository at this point in the history
…HCP module

Close #1378

Squashed commit of the following:

commit e45e2d0
Merge: bea8f79 5e9c21b
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Wed Jan 29 20:08:20 2020 +0300

    Merge remote-tracking branch 'origin/master' into 1378-dhcp-clients

commit bea8f79
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Wed Jan 29 20:08:06 2020 +0300

    minor

commit 6f1da9c
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Wed Jan 29 19:31:08 2020 +0300

    fix

commit a88b46c
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Wed Jan 29 12:53:22 2020 +0300

    minor

commit d2897fe
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Tue Jan 28 19:55:10 2020 +0300

    * clients: update runtime clients of type DHCP by event from DHCP module

commit 3aa352e
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Tue Jan 28 19:52:08 2020 +0300

    * minor

commit f5c2291
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Tue Jan 28 19:08:23 2020 +0300

    * clients: remove old entries of source type /etc/hosts or ARP
  • Loading branch information
szolin committed Jan 30, 2020
1 parent 5e9c21b commit dcc5754
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 37 deletions.
9 changes: 9 additions & 0 deletions dhcpd/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ type leaseJSON struct {
Expiry int64 `json:"exp"`
}

func normalizeIP(ip net.IP) net.IP {
ip4 := ip.To4()
if ip4 != nil {
return ip4
}
return ip
}

// Safe version of dhcp4.IPInRange()
func ipInRange(start, stop, ip net.IP) bool {
if len(start) != len(stop) ||
Expand Down Expand Up @@ -56,6 +64,7 @@ func (s *Server) dbLoad() {

numLeases := len(obj)
for i := range obj {
obj[i].IP = normalizeIP(obj[i].IP)

if obj[i].Expiry != leaseExpireStatic &&
!ipInRange(s.leaseStart, s.leaseStop, obj[i].IP) {
Expand Down
4 changes: 2 additions & 2 deletions dhcpd/dhcp_http.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ func convertLeases(inputLeases []Lease, includeExpires bool) []map[string]string
}

func (s *Server) handleDHCPStatus(w http.ResponseWriter, r *http.Request) {
leases := convertLeases(s.Leases(), true)
staticLeases := convertLeases(s.StaticLeases(), false)
leases := convertLeases(s.Leases(LeasesDynamic), true)
staticLeases := convertLeases(s.Leases(LeasesStatic), false)
status := map[string]interface{}{
"config": s.conf,
"leases": leases,
Expand Down
74 changes: 54 additions & 20 deletions dhcpd/dhcpd.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,16 @@ type ServerConfig struct {
HTTPRegister func(string, string, func(http.ResponseWriter, *http.Request)) `json:"-" yaml:"-"`
}

type onLeaseChangedT func(flags int)

// flags for onLeaseChanged()
const (
LeaseChangedAdded = iota
LeaseChangedAddedStatic
LeaseChangedRemovedStatic
LeaseChangedBlacklisted
)

// Server - the current state of the DHCP server
type Server struct {
conn *filterConn // listening UDP socket
Expand All @@ -78,6 +88,9 @@ type Server struct {
IPpool map[[4]byte]net.HardwareAddr

conf ServerConfig

// Called when the leases DB is modified
onLeaseChanged onLeaseChangedT
}

// Print information about the available network interfaces
Expand All @@ -101,6 +114,13 @@ func Create(config ServerConfig) *Server {
s := Server{}
s.conf = config
s.conf.DBFilePath = filepath.Join(config.WorkDir, dbFilename)
if s.conf.Enabled {
err := s.setConfig(config)
if err != nil {
log.Error("DHCP: %s", err)
return nil
}
}
if s.conf.HTTPRegister != nil {
s.registerHandlers()
}
Expand All @@ -120,6 +140,18 @@ func (s *Server) Init(config ServerConfig) error {
return nil
}

// SetOnLeaseChanged - set callback
func (s *Server) SetOnLeaseChanged(onLeaseChanged onLeaseChangedT) {
s.onLeaseChanged = onLeaseChanged
}

func (s *Server) notify(flags int) {
if s.onLeaseChanged == nil {
return
}
s.onLeaseChanged(flags)
}

// WriteDiskConfig - write configuration
func (s *Server) WriteDiskConfig(c *ServerConfig) {
*c = s.conf
Expand Down Expand Up @@ -285,7 +317,6 @@ func (s *Server) reserveLease(p dhcp4.Packet) (*Lease, error) {
s.leases[i].IP, hwaddr, s.leases[i].HWAddr, s.leases[i].Expiry)
lease.IP = s.leases[i].IP
s.leases[i] = lease
s.dbStore()

s.reserveIP(lease.IP, hwaddr)
return lease, nil
Expand All @@ -294,7 +325,6 @@ func (s *Server) reserveLease(p dhcp4.Packet) (*Lease, error) {
log.Tracef("Assigning to %s IP address %s", hwaddr, ip.String())
lease.IP = ip
s.leases = append(s.leases, lease)
s.dbStore()
return lease, nil
}

Expand Down Expand Up @@ -449,6 +479,7 @@ func (s *Server) blacklistLease(lease *Lease) {
lease.Expiry = time.Now().Add(s.leaseTime)
s.dbStore()
s.leasesLock.Unlock()
s.notify(LeaseChangedBlacklisted)
}

// Return TRUE if DHCP packet is correct
Expand Down Expand Up @@ -538,6 +569,10 @@ func (s *Server) handleDHCP4Request(p dhcp4.Packet, options dhcp4.Options) dhcp4

if lease.Expiry.Unix() != leaseExpireStatic {
lease.Expiry = time.Now().Add(s.leaseTime)
s.leasesLock.Lock()
s.dbStore()
s.leasesLock.Unlock()
s.notify(LeaseChangedAdded) // Note: maybe we shouldn't call this function if only expiration time is updated
}
log.Tracef("Replying with ACK. IP: %s HW: %s Expire: %s",
lease.IP, lease.HWAddr, lease.Expiry)
Expand Down Expand Up @@ -578,17 +613,19 @@ func (s *Server) AddStaticLease(l Lease) error {
l.Expiry = time.Unix(leaseExpireStatic, 0)

s.leasesLock.Lock()
defer s.leasesLock.Unlock()

if s.findReservedHWaddr(l.IP) != nil {
err := s.rmDynamicLeaseWithIP(l.IP)
if err != nil {
s.leasesLock.Unlock()
return err
}
}
s.leases = append(s.leases, &l)
s.reserveIP(l.IP, l.HWAddr)
s.dbStore()
s.leasesLock.Unlock()
s.notify(LeaseChangedAddedStatic)
return nil
}

Expand Down Expand Up @@ -637,27 +674,38 @@ func (s *Server) RemoveStaticLease(l Lease) error {
}

s.leasesLock.Lock()
defer s.leasesLock.Unlock()

if s.findReservedHWaddr(l.IP) == nil {
s.leasesLock.Unlock()
return fmt.Errorf("Lease not found")
}

err := s.rmLease(l)
if err != nil {
s.leasesLock.Unlock()
return err
}
s.dbStore()
s.leasesLock.Unlock()
s.notify(LeaseChangedRemovedStatic)
return nil
}

// flags for Leases() function
const (
LeasesDynamic = 1
LeasesStatic = 2
LeasesAll = LeasesDynamic | LeasesStatic
)

// Leases returns the list of current DHCP leases (thread-safe)
func (s *Server) Leases() []Lease {
func (s *Server) Leases(flags int) []Lease {
var result []Lease
now := time.Now().Unix()
s.leasesLock.RLock()
for _, lease := range s.leases {
if lease.Expiry.Unix() > now {
if ((flags&LeasesDynamic) != 0 && lease.Expiry.Unix() > now) ||
((flags&LeasesStatic) != 0 && lease.Expiry.Unix() == leaseExpireStatic) {
result = append(result, *lease)
}
}
Expand All @@ -666,20 +714,6 @@ func (s *Server) Leases() []Lease {
return result
}

// StaticLeases returns the list of statically-configured DHCP leases (thread-safe)
func (s *Server) StaticLeases() []Lease {
s.leasesLock.Lock()
defer s.leasesLock.Unlock()

var result []Lease
for _, lease := range s.leases {
if lease.Expiry.Unix() == 1 {
result = append(result, *lease)
}
}
return result
}

// Print information about the current leases
func (s *Server) printLeases() {
log.Tracef("Leases:")
Expand Down
2 changes: 1 addition & 1 deletion dhcpd/dhcpd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ func testStaticLeases(t *testing.T, s *Server) {
err = s.AddStaticLease(l)
check(t, err == nil, "AddStaticLease")

ll := s.StaticLeases()
ll := s.Leases(LeasesStatic)
check(t, len(ll) != 0 && bytes.Equal(ll[0].IP, []byte{1, 1, 1, 1}), "StaticLeases")

err = s.RemoveStaticLease(l)
Expand Down
3 changes: 1 addition & 2 deletions dnsforward/dnsforward.go
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 +685,7 @@ func (s *Server) handleDNSRequest(p *proxy.Proxy, d *proxy.DNSContext) error {
processFilteringBeforeRequest,
processUpstream,
processFilteringAfterResponse,
processQueryLogsAndStats,
}
for _, process := range mods {
r := process(ctx)
Expand All @@ -699,8 +700,6 @@ func (s *Server) handleDNSRequest(p *proxy.Proxy, d *proxy.DNSContext) error {
if d.Res != nil {
d.Res.Compress = true // some devices require DNS message compression
}

_ = processQueryLogsAndStats(ctx)
return nil
}

Expand Down
Loading

0 comments on commit dcc5754

Please sign in to comment.