diff options
Diffstat (limited to 'lib/MasterServer/UDP/UpLink.pm')
| -rwxr-xr-x | lib/MasterServer/UDP/UpLink.pm | 93 |
1 files changed, 33 insertions, 60 deletions
diff --git a/lib/MasterServer/UDP/UpLink.pm b/lib/MasterServer/UDP/UpLink.pm index e5c703b..63cbefb 100755 --- a/lib/MasterServer/UDP/UpLink.pm +++ b/lib/MasterServer/UDP/UpLink.pm @@ -10,8 +10,7 @@ use Exporter 'import'; our @EXPORT = qw| send_heartbeats do_uplink process_uplink_response - process_udp_secure - process_udp_basic |; + process_udp_secure |; ################################################################################ ## Broadcast heartbeats to other masterservers @@ -23,16 +22,21 @@ sub send_heartbeats { # in order to be permitted to sync, you need to share your address too so # others can sync from you too. if ($self->{sync_enabled}) { - - # uplink to every entry of the masterserver brotherhood list - foreach my $uplink (values %{$self->masterserver_list()}) { + + # get serverlist + my $masterserverlist = $self->get_server( + updated => 3600, + gamename => "333networks", + ); + + # uplink to every 333networks-based masterserver + foreach my $ms (@{$masterserverlist}) { # send uplink - $self->do_uplink($uplink->{ip}, $uplink->{udp}); + $self->do_uplink($ms->{ip}, $ms->{port}); } - } + } } - ################################################################################ ## Do an uplink to other 333networks-based masterservers so we can be shared ## along the 333networks synchronization protocol. Other 333networks-based @@ -44,16 +48,15 @@ sub do_uplink { # do not proceed if not all information is available return unless (defined $ip && defined $port && $port > 0); - # debug spamming + # report uplinks to log $self->log("uplink", "Uplink to Masterserver $ip:$port"); # connect with UDP server my $udp_client; $udp_client = AnyEvent::Handle::UDP->new( - # Bind to this host and port connect => [$ip, $port], - timeout => 5, - on_timeout => sub {$udp_client->destroy();}, # don't bother reporting timeouts - on_error => sub {$udp_client->destroy();}, # or errors + timeout => $self->{timeout_time}, + on_timeout => sub {$udp_client->destroy()}, + on_error => sub {$udp_client->destroy()}, on_recv => sub {$self->process_uplink_response(@_)}, ); @@ -73,8 +76,7 @@ sub process_uplink_response { my ($port, $iaddr) = sockaddr_in($pa); my $peer_addr = inet_ntoa($iaddr); - # if the beacon has a length longer than a certain amount, assume it is - # a fraud or crash attempt + # assume fraud/crash attempt if response too long if (length $b > 64) { # log $self->log("attack","length exceeded in uplink response: $peer_addr:$port sent $b"); @@ -91,27 +93,28 @@ sub process_uplink_response { ################################################################################ ## Process the received secure query and respond with the correct response -## +## TODO: expand queries with support for info, rules, players, status, etc ################################################################################ sub process_udp_secure { # $self, handle, packed address, udp data, peer ip address, $port my ($self, $udp, $pa, $buf, $peer_addr) = @_; - - # received secure in $buf: \basic\secure\l8jfVy + + # received secure in $buf: \basic\\secure\wookie my %r; - my $raw = $buf; # raw buffer for logging if necessary + $buf = encode('UTF-8', $buf); $buf =~ s/\\\\/\\undef\\/; $buf =~ s/\n//; $buf =~ s/\\([^\\]+)\\([^\\]+)/$r{$1}=$2/eg; - # scope + # response string my $response = ""; - # provide basic information if asked for (not uncommon) - if (defined $r{basic}) { - # compile basic string (identical to process_udp_basic) - + # compile basic string + + # provide basic information if asked for + if (defined $r{basic} || defined $r{status} || defined $r{info}) { + # format: \gamename\ut\gamever\348\minnetver\348\location\0\final\\queryid\16.1 $response .= "\\gamename\\333networks" . "\\gamever\\$self->{short_version}" @@ -119,51 +122,21 @@ sub process_udp_secure { . "\\hostname\\$self->{masterserver_hostname}" . "\\hostport\\$self->{listen_port}"; } + + # TODO: add queryid -- not because it's useful, but because protocol compliant - # we only respond with gamename = 333networks + # support for secure/validate if (defined $r{secure}) { - # get response + # generate response + $response .= "\\validate\\" . $self->validate_string(gamename => "333networks", enctype => 0, secure => $r{secure}); } - # send the response to the \basic\\secure\wookie query + # send the response $udp->push_send("$response\\final\\", $pa); } -################################################################################ -## Respond to basic or status queries -## TODO: abstract function for this -- otherwise these functions pile up. -################################################################################ -sub process_udp_basic { - # $self, handle, packed address, udp data, peer ip address, $port - my ($self, $udp, $pa, $buf, $peer_addr) = @_; - - # received basic or status in $buf: \basic\ or \status\ - my %r; - $buf = encode('UTF-8', $buf); - $buf =~ s/\\\\/\\undef\\/; - $buf =~ s/\n//; - $buf =~ s/\\([^\\]+)\\([^\\]+)/$r{$1}=$2/eg; - - # scope - my $basic = ""; - # provide basic information - - if (defined $r{basic} || defined $r{status} || defined $r{info}) { - # compile basic string (identical to process_udp_basic) - - # format: \gamename\ut\gamever\348\minnetver\348\location\0\final\\queryid\16.1 - $basic = "\\gamename\\333networks" - . "\\gamever\\$self->{short_version}" - . "\\location\\0" - . "\\hostname\\$self->{masterserver_hostname}" - . "\\hostport\\$self->{listen_port}"; - } - - # send the response to the \basic\ or \status\ - $udp->push_send("$basic\\final\\", $pa); -} 1; |
