aboutsummaryrefslogtreecommitdiff
path: root/util/tools/r_functions.pl
diff options
context:
space:
mode:
authorDarkelarious <darkelarious@333networks.com>2016-11-19 20:56:04 +0100
committerDarkelarious <darkelarious@333networks.com>2016-11-19 20:56:04 +0100
commitc3f8d65a4fb1f5674557ee67cf7f74369df86ad1 (patch)
tree92aab2a394bda28da0ed7c7c75e633fdf386fc71 /util/tools/r_functions.pl
parent1de3da4b8027508a91144639455c934fd6ccb9b7 (diff)
downloadMasterServer-Perl-c3f8d65a4fb1f5674557ee67cf7f74369df86ad1.tar.gz
MasterServer-Perl-c3f8d65a4fb1f5674557ee67cf7f74369df86ad1.zip
Massive improvements on efficiency, robustness, security, reliability and more
Diffstat (limited to 'util/tools/r_functions.pl')
-rwxr-xr-xutil/tools/r_functions.pl111
1 files changed, 111 insertions, 0 deletions
diff --git a/util/tools/r_functions.pl b/util/tools/r_functions.pl
new file mode 100755
index 0000000..f4834c6
--- /dev/null
+++ b/util/tools/r_functions.pl
@@ -0,0 +1,111 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use Encode;
+use AnyEvent;
+use AnyEvent::Handle;
+
+our %S;
+
+################################################################################
+# Verify whether a given domain name or IP address and port are valid.
+# returns the valid ip-address + port, or 0 when not.
+################################################################################
+sub valid_address {
+ my $h = shift;
+
+ # split up address and port
+ my ($a, $p) = ($h =~ m/:/) ? $h =~ /(.*):(.*)/ : ($h,0);
+ return (undef,undef) unless ($a && $p);
+
+ # resolve hostname when needed -- shouldn't even be in the list! FIXME
+ #if($a =~ /[a-zA-Z]/g) {
+ # my $raw_addr = (gethostbyname($a))[4];
+ # my @octets = unpack("C4", $raw_addr);
+ # $a = join(".", @octets);
+ #}
+
+ # check if IP and port are in valid range
+ $a = ($a =~ '\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b') ? $a : 0;
+ $p = (0 < $p && $p <= 65535) ? $p : 0;
+
+ # exclude addresses where we don't want people sniffing
+ for (qw|192.168.(.\d*).(.\d*) 127.0.(.\d*).(.\d*) 10.0.(.\d*).(.\d*)|){$a = 0 if ($a =~ m/$_/)}
+
+ return ($a, $p);
+}
+
+sub query_master {
+ my $ms = shift;
+
+ for my $g (@{$ms->{games}}) {
+
+ my $cv = AnyEvent->condvar;
+ my $master_list = "";
+ my $handle; $handle = new AnyEvent::Handle(
+ connect => [$ms->{ip} => $ms->{port}],
+ timeout => 15,
+ poll => 'r',
+ on_error => sub {
+ print "($ms->{ip}, $g) $!\n";
+ $handle->destroy;
+ $cv->send;
+ },
+ on_eof => sub {
+ process_received_data($master_list, $g, $ms);
+ $handle->destroy;
+ $cv->send;
+ },
+ on_read => sub {
+ my $m = $_[0]->rbuf;
+ $_[0]->rbuf = "";
+
+ # part 1: receive \basic\\secure\$key
+ if ($m =~ m/\\basic\\\\secure\\/) {
+
+ # received data
+ my %r;
+ $m =~ s/\\([^\\]+)\\([^\\]+)/$r{$1}=$2/eg;
+
+ # respond to challenge
+ my $validate = get_validate_string($S{game}->{$g}->{key}, $r{secure}, $r{enctype}||0);
+
+ # print and send response
+ $handle->push_write("\\gamename\\$g\\location\\0\\validate\\$validate\\final\\");
+
+ #part 3: also request the list \list\gamename\ut -- skipped in UCC applets
+ $handle->push_write("\\list\\\\gamename\\$g\\final\\");
+ }
+
+ # part 3b: receive the entire list in multiple steps.
+ if ($m =~ m/\\ip\\/) { $master_list .= $m; }
+ }
+ );
+ $cv->recv;
+ }
+}
+
+sub process_received_data {
+ my ($buf, $g, $ms) = @_;
+ $buf = encode('UTF-8', $buf);
+
+ #counter
+ my $c = 0;
+
+ # parse $buf into an array of [ip, port]
+ foreach my $l (split(/\\/, $buf)) {
+
+ # search for \ip\255.255.255.255:7778\, contains ':'
+ if ($l =~ /:/) {
+ my ($a,$p) = valid_address($l);
+ next unless ($a && $p);
+ db_add_server(ip => $a, port => $p);
+ $c++;
+ }
+ }
+
+ print "found $c \t$g \taddresses at $ms->{ip}.\n" if ($c > 0 );
+}
+
+1;