aboutsummaryrefslogtreecommitdiff
path: root/lib/MasterServer/Util/UDPBrowser.pm
diff options
context:
space:
mode:
authorDarkelarious <darkelarious@333networks.com>2017-08-22 11:00:13 +0200
committerDarkelarious <darkelarious@333networks.com>2017-08-22 11:00:13 +0200
commitc06322da38b4cb76b2036af1a5448083adb8ff20 (patch)
tree189c9f0fec3325be927f763aba23cf18aa68cfe4 /lib/MasterServer/Util/UDPBrowser.pm
parente0d727670cbeda0db0812c5c9efc503d75f8d0a4 (diff)
downloadMasterServer-Perl-c06322da38b4cb76b2036af1a5448083adb8ff20.tar.gz
MasterServer-Perl-c06322da38b4cb76b2036af1a5448083adb8ff20.zip
new server checking mechanism, complete recode of major functionsv2.4.0
Diffstat (limited to 'lib/MasterServer/Util/UDPBrowser.pm')
-rwxr-xr-xlib/MasterServer/Util/UDPBrowser.pm54
1 files changed, 54 insertions, 0 deletions
diff --git a/lib/MasterServer/Util/UDPBrowser.pm b/lib/MasterServer/Util/UDPBrowser.pm
new file mode 100755
index 0000000..045a7a8
--- /dev/null
+++ b/lib/MasterServer/Util/UDPBrowser.pm
@@ -0,0 +1,54 @@
+package MasterServer::Util::UDPBrowser;
+
+use strict;
+use warnings;
+use AnyEvent::Handle::UDP;
+use Socket qw(sockaddr_in inet_ntoa);
+use Exporter 'import';
+our @EXPORT = qw| udpbrowser_host |;
+
+################################################################################
+## Wait for incoming UDP messages from game clients and other masterservers.
+## In contrary to the compliant TCP browser host, this function handles the
+## request in a single query and responds with a single udp list.
+## This read-only method is slightly unsafe as it bypasses the secure/validate
+## challenge; however, this list is freely available over the JSON api, so not
+## worth protecting against exploits.
+## Request format: \echo\request\gamename\postal2\list\\final\
+################################################################################
+sub udpbrowser_host {
+ # self, handle, packed address, buffer
+ my ($self, $udp, $paddress, $buffer) = @_;
+ my $rx = $self->data2hashref($buffer);
+ my $response = "";
+
+ # unpack ip from packed client address
+ my ($port, $iaddr) = sockaddr_in($paddress);
+ my $addr = inet_ntoa($iaddr);
+
+ # list request with valid gamename and list request
+ if ($rx->{gamename} && exists $rx->{list}) {
+ # get list and log
+ $response = $self->generate_list($rx->{gamename}, $rx->{list});
+ $self->log("list","$addr:$port retrieved the list for $rx->{gamename} over UDP");
+ }
+ else {
+ # log error
+ $response = "\\echo\\incorrect request format";
+ $self->log("warning","$addr:$port failed to retrieve the list over UDP for ".
+ ($rx->{gamename} || "empty_gamename"));
+ }
+
+ # close query with final tag
+ $response .= "\\final\\";
+
+ # split the response in chunks of 512 bytes and send (for large lists)
+ while (length $response > 512) {
+ my $chunk = substr $response, 0, 512, '';
+ $udp->push_send($chunk, $paddress);
+ }
+ # last <512 chunk
+ $udp->push_send($response, $paddress);
+}
+
+1;