]> git.datanom.net - pve-dhcp-server.git/blobdiff - DHCPServer.pm
Added lease maintainance monitor
[pve-dhcp-server.git] / DHCPServer.pm
index 5569e96994a42787c9691c445b05a253ce368113..8084c3f98670de6b0cb555c20f9d5e176ed2cc93 100644 (file)
@@ -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);
This page took 0.0355 seconds and 5 git commands to generate.