v4
This commit is contained in:
parent
c22d64fb50
commit
e975ec2460
96
xtr.pl
96
xtr.pl
@ -12,24 +12,66 @@ use File::Fetch;
|
|||||||
use PerlIO::gzip;
|
use PerlIO::gzip;
|
||||||
use LWP::UserAgent;
|
use LWP::UserAgent;
|
||||||
use HTTP::Request;
|
use HTTP::Request;
|
||||||
|
use Data::Validate::IP qw(is_ipv4);
|
||||||
use Data::Dumper;
|
use Data::Dumper;
|
||||||
|
|
||||||
### README
|
|
||||||
# to install needed modules on debian:
|
|
||||||
# * apt-get install libnet-whois-ip-perl libperlio-gzip-perl libdancer2-perl libnet-dns-perl libnet-traceroute-perl libdbi-perl libdbd-sqlite3-perl
|
|
||||||
|
|
||||||
### vars
|
|
||||||
my $dbfile = "ip2asn.db";
|
### README #########################################################################################################################################
|
||||||
|
# This is the client for the XTR (XiCoN Trace Route). It opens a port and listening to HTTP requests. It answers with a traceroute
|
||||||
|
# in a json hash. The hash contains for each hop the IP, the PTR, the request time and the AS (Autonomous System).
|
||||||
|
#
|
||||||
|
# This client also tries to connect to a "master server" which helps keeping track of all the traceroute clients and their availability.
|
||||||
|
#
|
||||||
|
# This software uses the iptoasn database (https://iptoasn.com/) to determine the AS for each hop. To keep track of all ip to asn relations,
|
||||||
|
# this software creates a local database file "ip2asn.db", which is a simple SQLite3 database with an index for faster searches.
|
||||||
|
#
|
||||||
|
# For now, the traceroutes are only IPv4. This will change in the future.
|
||||||
|
######################################################################################################################################################
|
||||||
|
|
||||||
|
|
||||||
|
### INSTALL ########################################################################################################################################
|
||||||
|
# This is a standalone software which usually runs in the "foreground". Starting it in a screen session or via init.d/systemd/rc.d is
|
||||||
|
# highly recommended. For testing, starting this script in a screen session is also fine.
|
||||||
|
#
|
||||||
|
# Either install all listed modules with "cpan -i <module>" or use your system's package manager (apt, yum, yast).
|
||||||
|
#
|
||||||
|
# On Debian just install there packages:
|
||||||
|
# libnet-whois-ip-perl
|
||||||
|
# libperlio-gzip-perl
|
||||||
|
# libdancer2-perl
|
||||||
|
# libnet-dns-perl
|
||||||
|
# libnet-traceroute-perl
|
||||||
|
# libdbi-perl
|
||||||
|
# libdbd-sqlite3-perl
|
||||||
|
# libdata-validate-ip-perl
|
||||||
|
#
|
||||||
|
######################################################################################################################################################
|
||||||
|
|
||||||
|
|
||||||
|
### VARS ###########################################################################################################################################
|
||||||
|
my $VERSION = "0.4";
|
||||||
|
my $dbfile = 'ip2asn.db';
|
||||||
my $ip2asn_csv_url = 'http://iptoasn.com/data/ip2asn-v4-u32.tsv.gz';
|
my $ip2asn_csv_url = 'http://iptoasn.com/data/ip2asn-v4-u32.tsv.gz';
|
||||||
my $master_server = "xtr-master.xicon.eu";
|
my $master_server = 'xtr-master.xicon.eu';
|
||||||
my $my_ip = get_my_ipv4();
|
my $get_my_ip_service = 'http://ipv4.xicon.eu/'; # some service, which returns just the ip of the requesting host (in this case, us.)
|
||||||
|
my $client_protocol_version = 3;
|
||||||
|
my $my_ip = get_my_ipv4($get_my_ip_service);
|
||||||
my $my_ext_ip = ""; # set different ip, if access differs from default public ip
|
my $my_ext_ip = ""; # set different ip, if access differs from default public ip
|
||||||
my $my_port = 3000;
|
my $my_port = 12111;
|
||||||
my $my_ext_port = 0; # set different port, if public access port differs from app port
|
my $my_ext_port = 0; # set different port, if public access port differs from app port
|
||||||
|
######################################################################################################################################################
|
||||||
|
|
||||||
|
|
||||||
|
######################################################################################################################################################
|
||||||
|
### NOTHING TO CHANGE BELOW HERE ###################################################################################################################
|
||||||
|
######################################################################################################################################################
|
||||||
|
|
||||||
|
|
||||||
### set vars
|
### set vars
|
||||||
set port => $my_port;
|
set port => $my_port;
|
||||||
if($my_ext_ip eq "") { $my_ext_ip = $my_ip; }
|
if($my_ext_ip eq "") { $my_ext_ip = $my_ip; }
|
||||||
|
if($my_ext_ip eq "0.0.0.0") { die "Couldn't determine my own IP"; }
|
||||||
if($my_ext_port eq 0 || $my_ext_port eq "") { $my_ext_port = $my_port; }
|
if($my_ext_port eq 0 || $my_ext_port eq "") { $my_ext_port = $my_port; }
|
||||||
|
|
||||||
### connect to database
|
### connect to database
|
||||||
@ -45,12 +87,18 @@ hook 'before' => sub {
|
|||||||
};
|
};
|
||||||
|
|
||||||
### main get route
|
### main get route
|
||||||
get '/:ip' => sub {
|
get '/v3/client/request/:ip' => sub {
|
||||||
my $ip = route_parameters->get('ip') || 8.8.8.8;
|
my $ip = route_parameters->get('ip') || 8.8.8.8;
|
||||||
|
if(!is_ipv4($ip)) { status('bad_request'); return "invalid IP address" }
|
||||||
my $trace = traceit($dbh,$ip);
|
my $trace = traceit($dbh,$ip);
|
||||||
return encode_json $trace;
|
return encode_json $trace;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
### return client protocol verison
|
||||||
|
get '/v3/client/info/version' => sub {
|
||||||
|
return $client_protocol_version;
|
||||||
|
};
|
||||||
|
|
||||||
### give the master server the info, that we are available
|
### give the master server the info, that we are available
|
||||||
if(send_server_status($master_server,$my_ext_ip,$my_ext_port,"1"))
|
if(send_server_status($master_server,$my_ext_ip,$my_ext_port,"1"))
|
||||||
{
|
{
|
||||||
@ -64,17 +112,19 @@ else
|
|||||||
### catch "INT" signal to send the status to the master server
|
### catch "INT" signal to send the status to the master server
|
||||||
$SIG{'INT'} = sub { send_server_status($master_server,$my_ext_ip,$my_ext_port,"0"); exit; };
|
$SIG{'INT'} = sub { send_server_status($master_server,$my_ext_ip,$my_ext_port,"0"); exit; };
|
||||||
|
|
||||||
### start the loop
|
### start the main loop
|
||||||
start;
|
start;
|
||||||
|
|
||||||
### if you reach this, you're done
|
### if you reach this, you're done
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
sub send_server_status
|
sub send_server_status
|
||||||
{
|
{
|
||||||
my ($master_server,$hostname,$port,$status) = @_;
|
my ($master_server,$hostname,$port,$status) = @_;
|
||||||
my $url = "http://".$master_server."/v2/server/".$hostname."/".$port."/".$status;
|
my $url = "http://".$master_server."/v3/server/add/".$hostname."/".$port."/".$status;
|
||||||
my $ua = LWP::UserAgent->new(timeout => 10);
|
my $ua = LWP::UserAgent->new(timeout => 2);
|
||||||
my $req = HTTP::Request->new("PUT", $url);
|
my $req = HTTP::Request->new("PUT", $url);
|
||||||
my $response = $ua->request($req);
|
my $response = $ua->request($req);
|
||||||
return $response->is_success;
|
return $response->is_success;
|
||||||
@ -82,10 +132,19 @@ sub send_server_status
|
|||||||
|
|
||||||
sub get_my_ipv4
|
sub get_my_ipv4
|
||||||
{
|
{
|
||||||
|
my ($ip_service) = @_;
|
||||||
my $ua = LWP::UserAgent->new(timeout => 10);
|
my $ua = LWP::UserAgent->new(timeout => 10);
|
||||||
my $response = $ua->get("http://ipv4.xicon.eu/");
|
my $response = $ua->get($ip_service);
|
||||||
|
if(is_ipv4($response->decoded_content))
|
||||||
|
{
|
||||||
return $response->decoded_content;
|
return $response->decoded_content;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
# no valid ip returned from ip service
|
||||||
|
return "0.0.0.0";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sub traceit
|
sub traceit
|
||||||
{
|
{
|
||||||
@ -200,15 +259,18 @@ sub create_db_table
|
|||||||
my $check_table_cmd = "SELECT name FROM sqlite_master WHERE type='table' AND name='ip2asn';";
|
my $check_table_cmd = "SELECT name FROM sqlite_master WHERE type='table' AND name='ip2asn';";
|
||||||
my $check_table_sth = $dbh->prepare($check_table_cmd);
|
my $check_table_sth = $dbh->prepare($check_table_cmd);
|
||||||
$check_table_sth->execute();
|
$check_table_sth->execute();
|
||||||
|
|
||||||
if(!$check_table_sth->fetch)
|
if(!$check_table_sth->fetch)
|
||||||
{
|
{
|
||||||
print "creating table...\n";
|
print "creating main table...\n";
|
||||||
my $create_table_cmd = "CREATE TABLE ip2asn( ip_from INTEGER, ip_to INTEGER, ip_as INTEGER)";
|
my $create_table_cmd = "CREATE TABLE ip2asn( ip_from INTEGER, ip_to INTEGER, ip_as INTEGER)";
|
||||||
my $create_table_sth = $dbh->prepare($create_table_cmd);
|
my $create_table_sth = $dbh->prepare($create_table_cmd);
|
||||||
$create_table_sth->execute();
|
$create_table_sth->execute();
|
||||||
#my $create_index_cmd = "CREATE INDEX ip2asnIndex ON ip2asn(ip_from,ip_to);";
|
|
||||||
#my $create_index_sth = $dbh->prepare($create_index_cmd);
|
print "creating index table...\n";
|
||||||
#$create_index_sth->execute();
|
my $create_index_cmd = "CREATE INDEX ip2asnIndex ON ip2asn(ip_from,ip_to);";
|
||||||
|
my $create_index_sth = $dbh->prepare($create_index_cmd);
|
||||||
|
$create_index_sth->execute();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
Loading…
Reference in New Issue
Block a user