* dhcpd: refactor: use separate objects for ServerConfig and RWMutex
This commit is contained in:
parent
763b986955
commit
fa47fa3f9c
4
dhcp.go
4
dhcp.go
@ -451,10 +451,6 @@ func stopDHCPServer() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if !dhcpServer.Enabled {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
err := dhcpServer.Stop()
|
err := dhcpServer.Stop()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errorx.Decorate(err, "Couldn't stop DHCP server")
|
return errorx.Decorate(err, "Couldn't stop DHCP server")
|
||||||
|
@ -57,6 +57,7 @@ type Server struct {
|
|||||||
|
|
||||||
// leases
|
// leases
|
||||||
leases []*Lease
|
leases []*Lease
|
||||||
|
leasesLock sync.RWMutex
|
||||||
leaseStart net.IP // parsed from config RangeStart
|
leaseStart net.IP // parsed from config RangeStart
|
||||||
leaseStop net.IP // parsed from config RangeEnd
|
leaseStop net.IP // parsed from config RangeEnd
|
||||||
leaseTime time.Duration // parsed from config LeaseDuration
|
leaseTime time.Duration // parsed from config LeaseDuration
|
||||||
@ -65,8 +66,7 @@ type Server struct {
|
|||||||
// IP address pool -- if entry is in the pool, then it's attached to a lease
|
// IP address pool -- if entry is in the pool, then it's attached to a lease
|
||||||
IPpool map[[4]byte]net.HardwareAddr
|
IPpool map[[4]byte]net.HardwareAddr
|
||||||
|
|
||||||
ServerConfig
|
conf ServerConfig
|
||||||
sync.RWMutex
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print information about the available network interfaces
|
// Print information about the available network interfaces
|
||||||
@ -96,49 +96,48 @@ func (s *Server) Init(config ServerConfig) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) setConfig(config ServerConfig) error {
|
func (s *Server) setConfig(config ServerConfig) error {
|
||||||
s.ServerConfig = config
|
s.conf = config
|
||||||
|
|
||||||
iface, err := net.InterfaceByName(s.InterfaceName)
|
iface, err := net.InterfaceByName(config.InterfaceName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
printInterfaces()
|
printInterfaces()
|
||||||
return wrapErrPrint(err, "Couldn't find interface by name %s", s.InterfaceName)
|
return wrapErrPrint(err, "Couldn't find interface by name %s", config.InterfaceName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// get ipv4 address of an interface
|
// get ipv4 address of an interface
|
||||||
s.ipnet = getIfaceIPv4(iface)
|
s.ipnet = getIfaceIPv4(iface)
|
||||||
if s.ipnet == nil {
|
if s.ipnet == nil {
|
||||||
return wrapErrPrint(err, "Couldn't find IPv4 address of interface %s %+v", s.InterfaceName, iface)
|
return wrapErrPrint(err, "Couldn't find IPv4 address of interface %s %+v", config.InterfaceName, iface)
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.LeaseDuration == 0 {
|
if config.LeaseDuration == 0 {
|
||||||
s.leaseTime = time.Hour * 2
|
s.leaseTime = time.Hour * 2
|
||||||
s.LeaseDuration = uint(s.leaseTime.Seconds())
|
|
||||||
} else {
|
} else {
|
||||||
s.leaseTime = time.Second * time.Duration(s.LeaseDuration)
|
s.leaseTime = time.Second * time.Duration(config.LeaseDuration)
|
||||||
}
|
}
|
||||||
|
|
||||||
s.leaseStart, err = parseIPv4(s.RangeStart)
|
s.leaseStart, err = parseIPv4(config.RangeStart)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return wrapErrPrint(err, "Failed to parse range start address %s", s.RangeStart)
|
return wrapErrPrint(err, "Failed to parse range start address %s", config.RangeStart)
|
||||||
}
|
}
|
||||||
|
|
||||||
s.leaseStop, err = parseIPv4(s.RangeEnd)
|
s.leaseStop, err = parseIPv4(config.RangeEnd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return wrapErrPrint(err, "Failed to parse range end address %s", s.RangeEnd)
|
return wrapErrPrint(err, "Failed to parse range end address %s", config.RangeEnd)
|
||||||
}
|
}
|
||||||
|
|
||||||
subnet, err := parseIPv4(s.SubnetMask)
|
subnet, err := parseIPv4(config.SubnetMask)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return wrapErrPrint(err, "Failed to parse subnet mask %s", s.SubnetMask)
|
return wrapErrPrint(err, "Failed to parse subnet mask %s", config.SubnetMask)
|
||||||
}
|
}
|
||||||
|
|
||||||
// if !bytes.Equal(subnet, s.ipnet.Mask) {
|
// if !bytes.Equal(subnet, s.ipnet.Mask) {
|
||||||
// return wrapErrPrint(err, "specified subnet mask %s does not meatch interface %s subnet mask %s", s.SubnetMask, s.InterfaceName, s.ipnet.Mask)
|
// return wrapErrPrint(err, "specified subnet mask %s does not meatch interface %s subnet mask %s", s.SubnetMask, s.InterfaceName, s.ipnet.Mask)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
router, err := parseIPv4(s.GatewayIP)
|
router, err := parseIPv4(config.GatewayIP)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return wrapErrPrint(err, "Failed to parse gateway IP %s", s.GatewayIP)
|
return wrapErrPrint(err, "Failed to parse gateway IP %s", config.GatewayIP)
|
||||||
}
|
}
|
||||||
|
|
||||||
s.leaseOptions = dhcp4.Options{
|
s.leaseOptions = dhcp4.Options{
|
||||||
@ -158,9 +157,9 @@ func (s *Server) Start() error {
|
|||||||
s.closeConn()
|
s.closeConn()
|
||||||
}
|
}
|
||||||
|
|
||||||
iface, err := net.InterfaceByName(s.InterfaceName)
|
iface, err := net.InterfaceByName(s.conf.InterfaceName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return wrapErrPrint(err, "Couldn't find interface by name %s", s.InterfaceName)
|
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
|
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
|
||||||
@ -246,9 +245,9 @@ func (s *Server) reserveLease(p dhcp4.Packet) (*Lease, error) {
|
|||||||
log.Tracef("Assigning IP address %s to %s (lease for %s expired at %s)",
|
log.Tracef("Assigning IP address %s to %s (lease for %s expired at %s)",
|
||||||
s.leases[i].IP, hwaddr, s.leases[i].HWAddr, s.leases[i].Expiry)
|
s.leases[i].IP, hwaddr, s.leases[i].HWAddr, s.leases[i].Expiry)
|
||||||
lease.IP = s.leases[i].IP
|
lease.IP = s.leases[i].IP
|
||||||
s.Lock()
|
s.leasesLock.Lock()
|
||||||
s.leases[i] = lease
|
s.leases[i] = lease
|
||||||
s.Unlock()
|
s.leasesLock.Unlock()
|
||||||
|
|
||||||
s.reserveIP(lease.IP, hwaddr)
|
s.reserveIP(lease.IP, hwaddr)
|
||||||
return lease, nil
|
return lease, nil
|
||||||
@ -256,9 +255,9 @@ func (s *Server) reserveLease(p dhcp4.Packet) (*Lease, error) {
|
|||||||
|
|
||||||
log.Tracef("Assigning to %s IP address %s", hwaddr, ip.String())
|
log.Tracef("Assigning to %s IP address %s", hwaddr, ip.String())
|
||||||
lease.IP = ip
|
lease.IP = ip
|
||||||
s.Lock()
|
s.leasesLock.Lock()
|
||||||
s.leases = append(s.leases, lease)
|
s.leases = append(s.leases, lease)
|
||||||
s.Unlock()
|
s.leasesLock.Unlock()
|
||||||
return lease, nil
|
return lease, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,7 +372,7 @@ func (s *Server) ServeDHCP(p dhcp4.Packet, msgType dhcp4.MessageType, options dh
|
|||||||
// Return TRUE if it doesn't reply, which probably means that the IP is available
|
// Return TRUE if it doesn't reply, which probably means that the IP is available
|
||||||
func (s *Server) addrAvailable(target net.IP) bool {
|
func (s *Server) addrAvailable(target net.IP) bool {
|
||||||
|
|
||||||
if s.ICMPTimeout == 0 {
|
if s.conf.ICMPTimeout == 0 {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,7 +383,7 @@ func (s *Server) addrAvailable(target net.IP) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pinger.SetPrivileged(true)
|
pinger.SetPrivileged(true)
|
||||||
pinger.Timeout = time.Duration(s.ICMPTimeout) * time.Millisecond
|
pinger.Timeout = time.Duration(s.conf.ICMPTimeout) * time.Millisecond
|
||||||
pinger.Count = 1
|
pinger.Count = 1
|
||||||
reply := false
|
reply := false
|
||||||
pinger.OnRecv = func(pkt *ping.Packet) {
|
pinger.OnRecv = func(pkt *ping.Packet) {
|
||||||
@ -407,11 +406,11 @@ func (s *Server) addrAvailable(target net.IP) bool {
|
|||||||
func (s *Server) blacklistLease(lease *Lease) {
|
func (s *Server) blacklistLease(lease *Lease) {
|
||||||
hw := make(net.HardwareAddr, 6)
|
hw := make(net.HardwareAddr, 6)
|
||||||
s.reserveIP(lease.IP, hw)
|
s.reserveIP(lease.IP, hw)
|
||||||
s.Lock()
|
s.leasesLock.Lock()
|
||||||
lease.HWAddr = hw
|
lease.HWAddr = hw
|
||||||
lease.Hostname = ""
|
lease.Hostname = ""
|
||||||
lease.Expiry = time.Now().Add(s.leaseTime)
|
lease.Expiry = time.Now().Add(s.leaseTime)
|
||||||
s.Unlock()
|
s.leasesLock.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return TRUE if DHCP packet is correct
|
// Return TRUE if DHCP packet is correct
|
||||||
@ -595,33 +594,33 @@ func (s *Server) RemoveStaticLease(l Lease) error {
|
|||||||
func (s *Server) Leases() []Lease {
|
func (s *Server) Leases() []Lease {
|
||||||
var result []Lease
|
var result []Lease
|
||||||
now := time.Now().Unix()
|
now := time.Now().Unix()
|
||||||
s.RLock()
|
s.leasesLock.RLock()
|
||||||
for _, lease := range s.leases {
|
for _, lease := range s.leases {
|
||||||
if lease.Expiry.Unix() > now {
|
if lease.Expiry.Unix() > now {
|
||||||
result = append(result, *lease)
|
result = append(result, *lease)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.RUnlock()
|
s.leasesLock.RUnlock()
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// StaticLeases returns the list of statically-configured DHCP leases (thread-safe)
|
// StaticLeases returns the list of statically-configured DHCP leases (thread-safe)
|
||||||
func (s *Server) StaticLeases() []Lease {
|
func (s *Server) StaticLeases() []Lease {
|
||||||
s.Lock()
|
s.leasesLock.Lock()
|
||||||
if s.IPpool == nil {
|
if s.IPpool == nil {
|
||||||
s.dbLoad()
|
s.dbLoad()
|
||||||
}
|
}
|
||||||
s.Unlock()
|
s.leasesLock.Unlock()
|
||||||
|
|
||||||
var result []Lease
|
var result []Lease
|
||||||
s.RLock()
|
s.leasesLock.RLock()
|
||||||
for _, lease := range s.leases {
|
for _, lease := range s.leases {
|
||||||
if lease.Expiry.Unix() == 1 {
|
if lease.Expiry.Unix() == 1 {
|
||||||
result = append(result, *lease)
|
result = append(result, *lease)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.RUnlock()
|
s.leasesLock.RUnlock()
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -637,8 +636,8 @@ func (s *Server) printLeases() {
|
|||||||
// FindIPbyMAC finds an IP address by MAC address in the currently active DHCP leases
|
// FindIPbyMAC finds an IP address by MAC address in the currently active DHCP leases
|
||||||
func (s *Server) FindIPbyMAC(mac net.HardwareAddr) net.IP {
|
func (s *Server) FindIPbyMAC(mac net.HardwareAddr) net.IP {
|
||||||
now := time.Now().Unix()
|
now := time.Now().Unix()
|
||||||
s.RLock()
|
s.leasesLock.RLock()
|
||||||
defer s.RUnlock()
|
defer s.leasesLock.RUnlock()
|
||||||
for _, l := range s.leases {
|
for _, l := range s.leases {
|
||||||
if l.Expiry.Unix() > now && bytes.Equal(mac, l.HWAddr) {
|
if l.Expiry.Unix() > now && bytes.Equal(mac, l.HWAddr) {
|
||||||
return l.IP
|
return l.IP
|
||||||
@ -649,8 +648,8 @@ func (s *Server) FindIPbyMAC(mac net.HardwareAddr) net.IP {
|
|||||||
|
|
||||||
// Reset internal state
|
// Reset internal state
|
||||||
func (s *Server) reset() {
|
func (s *Server) reset() {
|
||||||
s.Lock()
|
s.leasesLock.Lock()
|
||||||
s.leases = nil
|
s.leases = nil
|
||||||
s.Unlock()
|
s.leasesLock.Unlock()
|
||||||
s.IPpool = make(map[[4]byte]net.HardwareAddr)
|
s.IPpool = make(map[[4]byte]net.HardwareAddr)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user