diff options
| author | Darkelarious <darkelarious@333networks.com> | 2017-08-22 11:00:13 +0200 |
|---|---|---|
| committer | Darkelarious <darkelarious@333networks.com> | 2017-08-22 11:00:13 +0200 |
| commit | c06322da38b4cb76b2036af1a5448083adb8ff20 (patch) | |
| tree | 189c9f0fec3325be927f763aba23cf18aa68cfe4 /lib/MasterServer/UDP/UDPTicker.pm | |
| parent | e0d727670cbeda0db0812c5c9efc503d75f8d0a4 (diff) | |
| download | MasterServer-Perl-2.4.0.tar.gz MasterServer-Perl-2.4.0.zip | |
new server checking mechanism, complete recode of major functionsv2.4.0
Diffstat (limited to 'lib/MasterServer/UDP/UDPTicker.pm')
| -rwxr-xr-x | lib/MasterServer/UDP/UDPTicker.pm | 272 |
1 files changed, 56 insertions, 216 deletions
diff --git a/lib/MasterServer/UDP/UDPTicker.pm b/lib/MasterServer/UDP/UDPTicker.pm index 6b3a681..0566449 100755 --- a/lib/MasterServer/UDP/UDPTicker.pm +++ b/lib/MasterServer/UDP/UDPTicker.pm @@ -4,253 +4,93 @@ use strict; use warnings; use AnyEvent::Handle::UDP; use Exporter 'import'; -use Data::Dumper 'Dumper'; - our @EXPORT = qw| udp_ticker |; ################################################################################ -## When addresses are stored in the 'pending' list, they are supposed to be -## queried immediately with the secure/validate challenge to testify that -## the server is genuine and alive. -## -## Some servers do not support the secure-challenge on the Uplink port. These -## servers are verified with a secure-challenge on their heartbeat ports, -## which are designed to respond to secure queries, as well as status queries. -## -## Addresses collected by other scripts, whether from the UCC applet or manual -## input via the website, are added to the pending list. It is more -## important to verify pending beacons and new server addresses, than to -## update the status of existing addresses. Therefore, pending addresses are -## prioritized. +## When addresses are provided from secondary sources (master applets, +## synchronization or manual addition, they are queried by this udp_ticker. +## When they validate (which also implies correct router settings) they are +## added to the masterserver list. ## -## Another function required for 333networks is the "server info" part of the -## site. UT servers are queried and stored in the database. This is the lowest -## priority for the masterserver and is therefore performed last. +## Some servers do not support the secure-challenge or do not respond to +## queries directly. By retrieving the server information we are able to +## make exceptions on a case to case basis. ## +## Other than previous MS-Perl versions, unresponsive servers are no longer +## checked. When servers become fail to report in after 2 hours, they remain +## are considered offline and will remain archived. This server can become +## active again by uplinking to one of the affiliated masterservers. ################################################################################ sub udp_ticker { my $self = shift; - # inform that we are running - $self->log("info", "UDP Ticker is loaded."); + # queue: start time, server id, counter, time limit + my %p = (start => time, id => 0, c => 0, limit => 900); # pending: 15m + my %u = (start => time, id => 0, c => 0, limit => 300); # updater: 5m - # queue -- which address is next in line? - my %reset = (start => time, id => 0); - my %pending = (%reset, c => 0, limit => 900); # 900s ~ 15m - my %updater = (%reset, c => 0, limit => 1800); # 1800s ~ 30m - my %ut_serv = (%reset, c => 0, limit => 300); # 300s ~ 5m - my %oldserv = (%reset, c => 0, limit => 86400); # 86400s ~ 24h - - my $debug_counter = 0; - - # go through all servers that need querying + # tick through pending list and server list my $server_info = AnyEvent->timer ( - after => 120, # first give beacons a chance to uplink - interval => 0.2, # 5 addresses per second is fast enough + after => 120, # grace time receiving beacons + interval => 0.2, # ~5 servers/s cb => sub { - - # after the first full run was completed, reset the counters when loop time expires - if (defined $self->{firstrun}) { - # reset timer - %reset = (start => time, id => 0, c => 0); - - # - # it can happen that a run takes more than the allowed time - # in that case, allow more time - # - - # pending - if (time - $pending{start} > $pending{limit}) { - if ($pending{c} > 0) { - # done within defined time, reset - %pending = (%pending, %reset); - } - } - - # ut servers - if (time - $ut_serv{start} > $ut_serv{limit}) { - if ($ut_serv{c} > 0) { - # done within defined time, reset - %ut_serv = (%ut_serv, %reset); - } - } - - # updater - if (time - $updater{start} > $updater{limit}) { - if ($updater{c} > 0) { - # done within defined time, reset - %updater = (%updater, %reset); - } - } - - # old servers - if (time - $oldserv{start} > $oldserv{limit}) { - if ($oldserv{c} > 0) { - %oldserv = (%oldserv, %reset); - } - } - } - - # - # Check pending beacons - # - - # pending beacons/servers (15 seconds grace time) - my $n = $self->get_pending( - next_id => $pending{id}, - added => 15, - sort => "id", - limit => 1 - )->[0] if $self->{beacon_checker_enabled}; - - # if next pending server/address exists: - if ( $n ) { - # next pending id will be > $n - $pending{id} = $n->{id}; - - # query the server using the heartbeat port provided in the beacon/manual add - $self->query_udp_server( - $n->{id}, - $n->{ip}, - $n->{heartbeat}, - $n->{secure}, # secure string necessary! - 1, # request secure challenge - ); - - # our work is done for this cycle. - return; + # reset counters if minimum time before reset passed + list processed + if ($self->{firstrun}) { + if ($p{c} && time - $p{start} > $p{limit}) { # pending reset + %p = (%p, start => time, id => 0, c => 0); } + if ($u{c} && time - $u{start} > $u{limit}) { # updater reset + %u = (%u, start => time, id => 0, c => 0); } } - # pending are done and is allowed to reset at a later stadium - $pending{c}++; - - - # - # Query Unreal Tournament 99 (demo) servers for serverstats - # - - # next server in line - $n = $self->get_server( - next_id => $ut_serv{id}, - updated => 3600, - gamename => "ut", - sort => "id", - limit => 1, - )->[0] if $self->{utserver_query_enabled}; - - # if next server/address exists: - if ( $n ) { - #next pending id will be > $n - $ut_serv{id} = $n->{id}; + # Check pending addresses + if ( my $n = $self->get_pending(next_id => $p{id}, limit => 1)->[0] ) { + $p{id} = $n->{id}; # next id will be >$n - # query the server (no secure string) + # assign BeaconChecker to query the server for validate, status $self->query_udp_server( - $n->{id}, - $n->{ip}, - $n->{port}, - "", # no secure string necessary - 2, # request full status info + ip => $n->{ip}, + port => $n->{heartbeat}, + need_validate => 1, ); - - # our work is done for this cycle. return; } + $p{c}++; # all pending addresses were processed - # ut servers are done and is allowed to reset at a later stadium - $ut_serv{c}++; - - # - # update existing servers (both ut/non-ut) - # - - # next server in line - $n = $self->get_server( - next_id => $updater{id}, - updated => 7200, - sort => "id", - limit => 1, - )->[0] if $self->{beacon_checker_enabled}; - - # if next server/address exists: - if ( $n ) { - #next pending id will be > $n - $updater{id} = $n->{id}; + # Update server status + if ( my $n = $self->get_server( + next_id => $u{id}, + updated => 7200, # count >2h as unresponsive + limit => 1 + )->[0] ) { + $u{id} = $n->{id}; # next id will be >$n - # query the server (no secure string) + # assign BeaconChecker to query the server for status (no validate) $self->query_udp_server( - $n->{id}, - $n->{ip}, - $n->{port}, - "", # no secure string necessary - 0, # request info + ip => $n->{ip}, + port => $n->{port}, ); - - # our work is done for this cycle. return; - } - - # updating servers is done and is allowed to reset at a later stadium - $updater{c}++; - - # - # Query servers older than 2 hours - # + } + $u{c}++; # all servers were processed - # next server in line - $n = $self->get_server( - next_id => $oldserv{id}, - before => 7200, - (defined $self->{firstrun}) ? () : (updated => 86400), # FIXME long firstrun time fixed now? - sort => "id", - limit => 1, - )->[0] if $self->{beacon_checker_enabled}; - - # if next server/address exists: - if ( $n ) { - #next old server id will be > $n - $oldserv{id} = $n->{id}; - - # query the server (no secure string) - $self->query_udp_server( - $n->{id}, - $n->{ip}, - $n->{port}, - "", # no secure string necessary - 0, # request info - ); - - # our work is done for this cycle. + # first run complete? + if ($self->{firstrun}) { + # done. no other actions required return; - } - - # old servers are done and is allowed to reset at a later stadium - $oldserv{c}++; - - # and notify about first run being completed - if (!defined $self->{firstrun}) { - # inform that first run is completed + } else { + # notify about first run being completed and reset my $t = time-$self->{firstruntime}; my $t_readable = ($t > 60) ? (int($t/60). " minutes ". ($t%60). " seconds") : ($t. " seconds"); - - $self->log("info", "First run completed after $t_readable."); - $self->{firstrun} = 0; - - # reset all counters and follow procedure - %reset = (start => time, id => 0, c => 0); - %pending = (%pending, %reset); - %updater = (%updater, %reset); - %ut_serv = (%ut_serv, %reset); - %oldserv = (%oldserv, %reset); - } - - # At this point, we are out of server entries. From here on, just count - # down until the cycle is complete and handle new entries while they are - # added to the list. + $self->log("info", "first run completed after $t_readable"); + delete $self->{firstruntime}; + $self->{firstrun} = 1; + } + # Run complete. Count down until the minimum time has elapsed and handle + # new server entries as they are added to the list. } ); - - # return the timer object to keep it alive outside of this scope + # allow object to exist beyond this scope. Objects have ambitions too. + $self->log("info", "UDP ticker is loaded"); return $server_info; } |
