aboutsummaryrefslogtreecommitdiff
path: root/lib/MasterServer/UDP/UpLink.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/MasterServer/UDP/UpLink.pm')
-rwxr-xr-xlib/MasterServer/UDP/UpLink.pm93
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;