#!/usr/bin/perl use strict; use warnings; use threads; use IO::Socket::IP; my $host = '127.0.0.1'; my $port = '1337'; my $proto = 'tcp'; my $debug = 1; my $output = 'report.txt'; my @allowed_ips = ('127.0.0.1'); sub Main { # flush after every write $| = 1; my ($socket, $client_socket); # Bind to listening address and port $socket = new IO::Socket::INET( LocalHost => $host, LocalPort => $port, Proto => $proto, Listen => 5, Reuse => 1 ) or die "ERROR > Could not open socket: ".$!."\n"; print "INFO > Waiting for client connections on tcp:[$host]:$port...\n"; my @clients = (); while(1){ # Waiting for new client connection $client_socket = $socket->accept(); # Push new client connection to it's own thread push (@clients, threads->create(\&clientHandler, $client_socket)); foreach(@clients){ if($_->is_joinable()) { $_->join(); } } } $socket->close(); return 1; } sub clientHandler { # Socket is passed to thread as first (and only) argument. my ($client_socket) = @_; # Create hash for user connection/session information and set initial connection information. my %user = (); $user{peer_address} = $client_socket->peerhost(); $user{peer_port} = $client_socket->peerport(); unless (client_allowed($user{peer_address})){ print $client_socket "Server > Connection denied.\n"; print "WARN > Connection from $user{peer_address}:$user{peer_port} denied by IP policy.\n"; $client_socket->shutdown(2); $client_socket->close(); threads->exit(); } print "INFO > Client ".$user{peer_address}.":".$user{peer_port}." has been conected.\n"; # Let client know that server is ready for commands. print $client_socket "Server > Welcome to raClus-Server $user{peer_address}\n$user{peer_address}> "; # Listen for commands while client socket remains open while(my $buffer = <$client_socket>){ # Accept the command `PING` from client with optional arguments if($buffer =~ /^PING(\s|$)/i) { print $client_socket "Server > Pong!\n"; } # Accept the command `HELLO` from client with optional arguments if($buffer =~ /^HELLO(\s|$)/i){ print $client_socket "Server > Hello!\n"; print $client_socket "Server > Your IP:\t".$user{peer_address}."\n"; print $client_socket "Server > Your Port:\t".$user{peer_port}."\n"; } # This will terminate the client connection to the server if($buffer =~ /^QUIT(\s|$)/i){ # Print to client, and print to STDOUT then exit client connection & thread print $client_socket "Server > GOODBYE\n"; print "INFO > Client ".$user{peer_address}.":".$user{peer_port}." has been disconnected.\n"; $client_socket->shutdown(2); threads->exit(); } print "DEBUG > $buffer" if $debug; print $client_socket "$user{peer_address} > "; } print "INFO > Client ".$user{peer_address}.":".$user{peer_port}." has been disconnected.\n"; # Client has exited so thread should exit too threads->exit(); } sub client_allowed { my $client_ip = shift; return grep { $_ eq $client_ip || $_ eq '0/0' || $_ eq '0.0.0.0/0' } @allowed_ips; } # Start the Main loop Main();