}
};
+my $cleanup_leases = sub {
+ my ($self, $last_run) = @_;
+ my ($current, $last, $lease, $dirty);
+
+ $self->{INTERVAL} = 5 if $self->{INTERVAL} <= 0;
+ $current = time;
+ $last = $last_run + ($self->{INTERVAL} * 60);
+
+ $self->$logger("Run 'cleanup_leases' $last < $current", INFO);
+
+ if ($last < $current) {
+ $last_run = $current;
+ my $leases = $self->{_leases};
+ $dirty = 0;
+ while ((my $lease, my $elems) = each (%$leases)) {
+ $self->$logger("Clean up lease: $lease\n". Dumper($elems));
+ if ($elems->{ends} < $last_run) {
+ $self->$logger("Considering $lease for clean up: $elems->{ends} < $last_run\n". Dumper($elems));
+ if ($elems->{'binding state'} eq 'active') {
+ $self->$logger("Setting $lease 'binding state' to free", INFO);
+ $elems->{'binding state'} = 'free';
+ $dirty = 1;
+ }
+ }
+ }
+ if ($dirty) {
+ my $res = $self->$write_lease_file();
+ if ($res) {
+ $self->$logger("Updated lease file", INFO);
+ }
+ }
+ }
+
+ return $last_run;
+};
+
#########################################################################
# Private methods which handle DHCP4 requests
#########################################################################
$self->{timeout} ||= 10;
$self->{lease_file} ||= '/tmp/dhcpd.leases';
$self->{conf_file} ||= '/tmp/dhcpd.cfg';
+ $self->{INTERVAL} ||= 5;
return $self;
}
$sel = IO::Select->new($self->{_sock_in_ip4});
$sel->add($self->{_sock_in_ip6});
+ my $last_run = time;
+
until ($time_to_die) {
my $buf = undef;
my $fromaddr;
eval { # catch fatal errors
while (@ready = $sel->can_read) {
$self->$logger("Waiting for incoming packet", INFO);
+ $last_run = $self->$cleanup_leases($last_run);
foreach $socket (@ready) {
if ($socket == $self->{_sock_in_ip4}) {
# receive ipv4 packet