X-Git-Url: http://git.datanom.net/pve-dhcp-server.git/blobdiff_plain/245c6d23660f28a41254df73bd2b9769b512dd60..HEAD:/DHCPServer.pm diff --git a/DHCPServer.pm b/DHCPServer.pm index 5569e96..8084c3f 100644 --- a/DHCPServer.pm +++ b/DHCPServer.pm @@ -432,6 +432,42 @@ my $read_config = sub { } }; +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 ######################################################################### @@ -914,20 +950,21 @@ my $request_ip4 = sub { }; my $release_ip4 = sub { - my ($self, $dhcpreq) = @_; + my ($self, $req) = @_; my ($ip, $mac); - $self->$logger($dhcpreq->toString()); - $ip = $dhcpreq->ciaddr(); - $mac = $self->$get_mac_ip4($dhcpreq); + $self->$logger($req->toString()); + $ip = $req->ciaddr(); + $mac = $self->$get_mac_ip4($req); $self->$logger("Release request for IP: $ip MAC: $mac", INFO); if ($self->{_leases}->{$ip}) { my $lease = $self->{_leases}->{$ip}; if ($lease->{'hardware ethernet'} eq $mac) { + $self->$logger("Set binding state free IP: $ip MAC: $mac", INFO); $lease->{'binding state'} = 'free'; + $self->$write_lease_file(); } - $self->$write_lease_file(); } $self->$logger("Transaction:\n".Dumper($self->{_transaction}), INFO); }; @@ -940,7 +977,7 @@ my $excuse_me_ip6 = sub { my ($self, $addr, $req) = @_; $self->$logger("IPv6 request from [$addr]: $req", INFO); - $self->{_sock_out_ip6} = IO::Socket::IP->new( + my $sock = IO::Socket::IP->new( Domain => PF_INET6, V6Only => 1, Broadcast => 1, @@ -953,7 +990,8 @@ my $excuse_me_ip6 = sub { die "[excuse_me_ip6] Socket creation error: $err\n"; }; $self->$logger("$addr: Not implemented here", INFO); - $self->{_sock_out_ip6}->send("Not implemented here") || die "Error sending excuse: $!\n"; + $sock->send("Not implemented here") || die "Error sending excuse: $!\n"; + $sock->close; }; ######################################################################### @@ -1002,6 +1040,7 @@ sub new { $self->{timeout} ||= 10; $self->{lease_file} ||= '/tmp/dhcpd.leases'; $self->{conf_file} ||= '/tmp/dhcpd.cfg'; + $self->{INTERVAL} ||= 5; return $self; } @@ -1076,6 +1115,8 @@ sub run { $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; @@ -1084,10 +1125,11 @@ sub run { 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 - $fromaddr = $self->{_sock_in_ip4}->recv($buf, 4096) + $fromaddr = $socket->recv($buf, 4096) || $self->$logger("recv: $!", ERROR); next if ($!); # continue loop if an error occured @@ -1118,9 +1160,9 @@ sub run { } } else { # Receive ipv6 packet - my $myaddr = $self->{_sock_in_ip6}->sockhost; + my $myaddr = $socket->sockhost; - $fromaddr = $self->{_sock_in_ip6}->recv($buf, 4096) + $fromaddr = $socket->recv($buf, 4096) || $self->$logger("recv: $!", ERROR); next if ($!); # continue loop if an error occured $self->$logger("recv: $buf", INFO);