From f18ba64dd93bbf7c47e6b5143bfc99af817888e8 Mon Sep 17 00:00:00 2001 From: Dirk Koopman Date: Tue, 28 Apr 2020 00:38:11 +0100 Subject: [PATCH] new version of ip address storage --- Changes | 5 ++++ perl/DXProtHandle.pm | 19 +++++++----- perl/DXUser.pm | 17 ++++++++++- perl/DXUtil.pm | 71 +++++++++++++++++++++++++++++++++++++++++--- perl/Route.pm | 17 ++++++++++- 5 files changed, 115 insertions(+), 14 deletions(-) diff --git a/Changes b/Changes index bf420e82..974eadca 100644 --- 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. + + 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. +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. diff --git a/perl/DXProtHandle.pm b/perl/DXProtHandle.pm index 0c71e590..6dc13795 100644 --- a/perl/DXProtHandle.pm +++ b/perl/DXProtHandle.pm @@ -232,16 +232,18 @@ sub handle_11 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 { - $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')) { - 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); @@ -1521,10 +1523,11 @@ sub _add_thingy $user->sort('U') unless $user->sort; } } - $ip ||= $user->ip; + $ip ||= $user->ip($ncall); 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'); diff --git a/perl/DXUser.pm b/perl/DXUser.pm index 3497fa8a..a2617a31 100644 --- a/perl/DXUser.pm +++ b/perl/DXUser.pm @@ -92,7 +92,7 @@ $noips = 4; 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; @@ -189,6 +189,21 @@ sub del_file 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 # diff --git a/perl/DXUtil.pm b/perl/DXUtil.pm index 8bb9b956..baa041d4 100644 --- a/perl/DXUtil.pm +++ b/perl/DXUtil.pm @@ -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 - diffms _diffms + diffms _diffms ahour piplist mindate adate ); @@ -54,6 +54,24 @@ sub atime 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 { @@ -193,7 +211,7 @@ sub ptimelist 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 @@ -220,13 +238,58 @@ sub phash 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; } +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; diff --git a/perl/Route.pm b/perl/Route.pm index 81452dec..ef76c9e8 100644 --- a/perl/Route.pm +++ b/perl/Route.pm @@ -32,7 +32,7 @@ use vars qw(%list %valid $filterdef $maxlevel); cq => '0,CQ Zone', state => '0,State', city => '0,City', - ip => '0,IP Address', + ip => '0,IP Address,piplist', ); $filterdef = bless ([ @@ -375,6 +375,21 @@ sub dxchan 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 { -- 2.43.0