new version of ip address storage
authorDirk Koopman <djk@tobit.co.uk>
Mon, 27 Apr 2020 23:38:11 +0000 (00:38 +0100)
committerDirk Koopman <djk@tobit.co.uk>
Mon, 27 Apr 2020 23:38:11 +0000 (00:38 +0100)
Changes
perl/DXProtHandle.pm
perl/DXUser.pm
perl/DXUtil.pm
perl/Route.pm

diff --git a/Changes b/Changes
index bf420e828ddcf647ccbb2957a0678b97eb4ed874..974eadca46151652e011559472d75a136f9de0fd 100644 (file)
--- a/Changes
+++ b/Changes
@@ -5,9 +5,14 @@
 2. Use this information to work backwards to, for instance, put an IP address
    on a spot that came in on a PC11 before any PC61 or PC62 A arrived. That 
    IP address may be on a PC61 for a different spot that had come previously.
 2. Use this information to work backwards to, for instance, put an IP address
    on a spot that came in on a PC11 before any PC61 or PC62 A arrived. That 
    IP address may be on a PC61 for a different spot that had come previously.
+   
+   An IP address that has not come in on that PC61, but is deduced from route
+   or user login information is mark in the debug with a '*'
 3. Show which debugging category triggered any debug output. Debug output
    that was not trigger, but just output (e.g. the startup stuff) has no
    category.
 3. Show which debugging category triggered any debug output. Debug output
    that was not trigger, but just output (e.g. the startup stuff) has no
    category.
+4. IP addresses are stored in hash tables in the user record permanently as an
+   IP address + time tuple. A pruning mechanism will appear when need arises.
 25Apr20=======================================================================
 1. Add maximum no of users on node to show/cluster.
 2. Add ability to show last n lines of debugging ring buffer.
 25Apr20=======================================================================
 1. Add maximum no of users on node to show/cluster.
 2. Add ability to show last n lines of debugging ring buffer.
index 0c71e5900d96d3fb5ebd3a01360993d92be8ba05..6dc13795deccd8ff99c2c8530e961536155baec9 100644 (file)
@@ -232,16 +232,18 @@ sub handle_11
        my $ip = $spot[14] if exists $spot[14];
        my $implied = '';
        if ($ip) {
        my $ip = $spot[14] if exists $spot[14];
        my $implied = '';
        if ($ip) {
-               $user->ip($ip), $user->put if !$user->ip || $user->ip ne $ip;
-               $r->ip($ip) if $r && !$r->ip;
+               $ip =~ s/[\(\)\*]+//g;  # strip these off :-)
+               $user->ip($spot[7], $ip);
+               $user->put;
+               $r->ip($spot[7], $ip) if $r;
        } else {
        } else {
-               $ip ||= $r->ip if $r;
-               $ip ||= $user->ip;
+               $ip ||= $r->ip($spot[7]) if $r;
+               $ip ||= $user->ip($spot[7]);
                $implied = '*' if $ip;
        }
        
        if (isdbg('progress')) {
                $implied = '*' if $ip;
        }
        
        if (isdbg('progress')) {
-               my $sip = $ip ? sprintf "($ip$implied)" : '' unless $ip =~ m|[\(\)\*]|;
+               my $sip = $ip ? sprintf "($ip$implied)" : '';
                my $s = sprintf "SPOT: $spot[1] on $spot[0] \@ %s by $spot[4]$sip\@$spot[7]", cldatetime($spot[2]);
                $s .= " '$spot[3]'" if $spot[3];
                dbg($s);
                my $s = sprintf "SPOT: $spot[1] on $spot[0] \@ %s by $spot[4]$sip\@$spot[7]", cldatetime($spot[2]);
                $s .= " '$spot[3]'" if $spot[3];
                dbg($s);
@@ -1521,10 +1523,11 @@ sub _add_thingy
                                $user->sort('U') unless $user->sort;
                        }
                }
                                $user->sort('U') unless $user->sort;
                        }
                }
-               $ip ||= $user->ip;
+               $ip ||= $user->ip($ncall);
                if ($ip) {
                if ($ip) {
-                       $user->ip($ip);
-                       $r->ip($ip);
+                       $ip =~ s/^::ffff://; #  remove ipv6 stuff from the front of an ipv4 address
+                       $user->ip($ncall, $ip);
+                       $r->ip($ncall, $ip);
                        my $s = "PC92A $call -> $ip on $ncall";
                        Log('DXProt', $s);
                        dbg($s) if isdbg('routelow');
                        my $s = "PC92A $call -> $ip on $ncall";
                        Log('DXProt', $s);
                        dbg($s) if isdbg('routelow');
index 3497fa8af71e4eb41b3d8bba230dc26e5449ff86..a2617a31884d80dd632c4193dba45928e9a8d4ee 100644 (file)
@@ -92,7 +92,7 @@ $noips = 4;
                  believe => '1,Believable nodes,parray',
                  lastping => '1,Last Ping at,ptimelist',
                  maxconnect => '1,Max Connections',
                  believe => '1,Believable nodes,parray',
                  lastping => '1,Last Ping at,ptimelist',
                  maxconnect => '1,Max Connections',
-                 ip => '1,IP address',
+                 ip => '1,IP addresses,piplist',
                 );
 
 #no strict;
                 );
 
 #no strict;
@@ -189,6 +189,21 @@ sub del_file
        unlink "$main::local_data/users.v3";
 }
 
        unlink "$main::local_data/users.v3";
 }
 
+# IP address handling
+# this allows one to ask whether an IP address has been used with this node or let's one set an IP address for this node.
+sub ip
+{
+       my $self = shift;
+       my $node = shift;
+       my $ipin = shift;
+
+       $self->{ip} = {} unless ref $self->{ip};
+       my $ref = $self->{ip};
+       delete $ref->{''};
+       $ref->{$node} = [$ipin, $main::systime] if $ipin;
+       return $ref->{$node}->[0];
+}
+
 #
 # periodic processing
 #
 #
 # periodic processing
 #
index 8bb9b956c59d306b8aab36b6cab0807bca10c5bd..baa041d42bce04d1c232d2e4edf7cfb79ec2e8d0 100644 (file)
@@ -27,7 +27,7 @@ require Exporter;
              print_all_fields cltounix unpad is_callsign is_latlong
                         is_qra is_freq is_digits is_pctext is_pcflag insertitem deleteitem
                         is_prefix dd is_ipaddr $pi $d2r $r2d localdata localdata_mv
              print_all_fields cltounix unpad is_callsign is_latlong
                         is_qra is_freq is_digits is_pctext is_pcflag insertitem deleteitem
                         is_prefix dd is_ipaddr $pi $d2r $r2d localdata localdata_mv
-                        diffms _diffms
+                        diffms _diffms ahour piplist mindate adate
             );
 
 
             );
 
 
@@ -54,6 +54,24 @@ sub atime
        return $buf;
 }
 
        return $buf;
 }
 
+# just the hour
+sub ahour
+{
+       my $t = shift;
+       my ($sec,$min,$hour,$mday,$mon,$year) = gmtime((defined $t) ? $t : time);
+       my $buf = sprintf "%02d:%02d:%02d", $hour, $min, $sec;
+       return $buf;
+}
+
+sub adate
+{
+       my $t = shift;
+       my ($sec,$min,$hour,$mday,$mon,$year) = gmtime((defined $t) ? $t : time);
+       $year += 1900;
+       my $buf = sprintf "%02d%s%04d", $mday, $month[$mon], $year;
+       return $buf;
+}
+
 # get a zulu time in cluster format (2300Z)
 sub ztime
 {
 # get a zulu time in cluster format (2300Z)
 sub ztime
 {
@@ -193,7 +211,7 @@ sub ptimelist
 sub parray
 {
        my $ref = shift;
 sub parray
 {
        my $ref = shift;
-       return ref $ref ? join(', ', @{$ref}) : $ref;
+       return ref $ref ? join(',', @{$ref}) : $ref;
 }
 
 # take the arg as an array reference and print as a list of pairs
 }
 
 # take the arg as an array reference and print as a list of pairs
@@ -220,13 +238,58 @@ sub phash
        my $out;
 
        while (my ($k,$v) = each %$ref) {
        my $out;
 
        while (my ($k,$v) = each %$ref) {
-               $out .= "${k}=>$v, ";
+               if (ref $v eq 'ARRAY') {
+                       $out = "${k}=>[" . parray($v) . "],";
+               } elsif (ref $v eq 'HASH') {
+                       $out = "${k}=>{" . phash($v) . "},";
+               } else {
+                       $out .= "${k}=>$v,";
+               }
        }
        }
-       chop $out;                                      # remove last space
        chop $out;                                      # remove last comma
        return $out;
 }
 
        chop $out;                                      # remove last comma
        return $out;
 }
 
+sub mindate
+{
+       my $t = shift;
+       my $out;
+
+       if ($main::system-$t < 86400 ) {
+               $out = ahour($t);
+       } elsif ($main::system-$t < 365*86400) {
+               $out = adate($t);
+               chop $out for (1..4);
+               $out .= ' ' . atime($t);
+               chop $out for (1..3);
+       } else {
+               $out = atime($t);
+               $out =~ s/\@/ /;
+       }
+       return $out;
+}
+
+# like phash but prints dates and times
+sub piplist
+{
+       my $ref = shift;
+       my $out;
+
+       return $ref unless ref $ref;
+       
+       while (my ($k,$v) = each %$ref) {
+               if (ref $v eq 'HASH') {
+                       $out .= piplist($v);
+               } elsif (ref $v eq 'ARRAY') {
+                       $out .= join(',', map { sprintf "$_->[0]@%s", mindate($_->[1]) }  ref $v->[0] eq 'ARRAY' ? @$v : $v);
+               } else {
+                       $out .= $v;
+               }
+       }
+       $out =~ s/,+$//;                                        # remove last comma
+       return $out;
+}
+
 sub _sort_fields
 {
        my $ref = shift;
 sub _sort_fields
 {
        my $ref = shift;
index 81452decdb0f720b034acc9edd288f5125fe2958..ef76c9e8b5a793201e871b28a776ee2277c42f82 100644 (file)
@@ -32,7 +32,7 @@ use vars qw(%list %valid $filterdef $maxlevel);
                  cq => '0,CQ Zone',
                  state => '0,State',
                  city => '0,City',
                  cq => '0,CQ Zone',
                  state => '0,State',
                  city => '0,City',
-                 ip => '0,IP Address',
+                 ip => '0,IP Address,piplist',
                 );
 
 $filterdef = bless ([
                 );
 
 $filterdef = bless ([
@@ -375,6 +375,21 @@ sub dxchan
        return $dxchan[0];
 }
 
        return $dxchan[0];
 }
 
+# IP address handling
+# this allows one to ask whether an IP address has been used with this node or let's one set an IP address for this node.
+sub ip
+{
+       my $self = shift;
+       my $node = shift;
+       my $ipin = shift;
+
+       $self->{ip} = {} unless ref $self->{ip};
+       my $ref = $self->{ip};
+       my $ip = $ref->{$node}->[0];
+       $ip = $ref->{$node} = [$ipin, $main::systime] if $ipin;
+       return $ip;
+}
+
 sub delete_interface
 {
 
 sub delete_interface
 {