Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I've added ipfilter.dat support to Bitflu::Network #15

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions bitflu.config.example
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,10 @@ webgui_port = 4081
# Bitflus 'root directory'
workdir = ./workdir

# Support for ipfilter.dat files - needs Net::IPAddress::Filter::IPFilterDat
# Filepath of filter list file.
# ipfilter_dat_file = ./ipfilter.dat
ipfilter_dat_file =

# Change uid/gid after startup (if started as root, needed for chroot)
# runas_uid =
Expand Down
54 changes: 52 additions & 2 deletions bitflu.pl
Original file line number Diff line number Diff line change
Expand Up @@ -1791,7 +1791,7 @@ package Bitflu::Network;
use constant MAGIC_DSNUM => 1024*0.75; # Don't ask me why, but 0.75 makes our downspeed guess much better
use constant KILL_IPV4 => 0; # 'simulate' non-working ipv4 stack

use fields qw( super NOWTIME avfds bpx_dn bpx_up _HANDLES _SOCKETS stagger up_q stats resolver_fail have_ipv6);
use fields qw( super NOWTIME avfds bpx_dn bpx_up _HANDLES _SOCKETS stagger up_q stats resolver_fail have_ipv6 ip_filter);

##########################################################################
# Creates a new Networking Object
Expand Down Expand Up @@ -1835,6 +1835,20 @@ package Bitflu::Network;
}
}

# Check whether to use an ipfilter.dat IP address filter.
if($self->{super}->Configuration->GetValue('ipfilter_dat_file')) {
my $ipfilter_dat_file = $self->{super}->Configuration->GetValue('ipfilter_dat_file');
eval {
require Net::IPAddress::Filter::IPFilterDat;
};
if ($@) {
$self->stop("Net::IPAddress::Filter::IPFilterDat is required for ipfilter.dat support.");
}
if ( ! -f $ipfilter_dat_file ) {
$self->stop("Unable to find ipfilter.dat file at '$ipfilter_dat_file'");
}
}

if(KILL_IPV4) {
$self->warn("IPv4 support is *DISABLED*");
}
Expand All @@ -1843,7 +1857,7 @@ package Bitflu::Network;
}

##########################################################################
# Register Admin commands
# Register Admin commands. Load any IP filter file.
sub init {
my($self) = @_;
$self->info("IPv6 support is ".($self->HaveIPv6 ? 'enabled' : 'not active'));
Expand All @@ -1853,6 +1867,16 @@ package Bitflu::Network;
$self->{super}->Admin->RegisterCommand('netstat', $self, '_Command_Netstat', 'Display networking statistics');
$self->{super}->Admin->RegisterCommand('dig', $self, '_Command_Dig', 'Resolve a hostname');
$self->{super}->CreateSxTask(Superclass=>$self,Callback=>'_UpdateNetstats', Interval=>NETSTATS, Args=>[]);

# Check whether to use an ipfilter.dat IP address filter.
if($self->{super}->Configuration->GetValue('ipfilter_dat_file')) {
my $ipfilter_dat_file = $self->{super}->Configuration->GetValue('ipfilter_dat_file');
$self->info("Loading ipfilter.dat file '$ipfilter_dat_file'");
$self->{ip_filter} = Net::IPAddress::Filter::IPFilterDat->new();
$self->{ip_filter}->load_file($ipfilter_dat_file);
$self->info("IP address filter initialized");
}

return 1;
}

Expand Down Expand Up @@ -2421,6 +2445,10 @@ package Bitflu::Network;
$self->debug("Won't connect to blacklisted IP $remote_ip");
return undef;
}
elsif($self->IpIsFiltered($remote_ip)) {
$self->debug("Won't connect to filtered IP $remote_ip");
return undef;
}
if(KILL_IPV4 && $self->IsNativeIPv4($remote_ip)) {
$self->debug("Will not connect to IPv4 addr $remote_ip");
return undef;
Expand Down Expand Up @@ -2482,6 +2510,10 @@ package Bitflu::Network;
$self->debug("Refusing incoming connection from blacklisted ip $new_ip");
$new_sock->close;
}
elsif($self->IpIsFiltered($new_ip)) {
$self->debug("Refusing incoming connection from filtered ip $new_ip");
$new_sock->close;
}
elsif(KILL_IPV4 && $self->IsNativeIPv4($new_ip)) {
$self->debug("Dropping new IPv4 connection from $new_ip");
$new_sock->close;
Expand Down Expand Up @@ -2657,6 +2689,24 @@ package Bitflu::Network;
}
}

sub IpIsFiltered {
my($self, $this_ip) = @_;

return 0 unless $self->{ip_filter};

# Filter only supports IPv4
return 0 if $self->IsNativeIPv6($this_ip);

if ( !$self->IsNativeIPv4($this_ip) ) {
$this_ip = $self->SixToFour($this_ip);
}
my $is_filtered = $self->{ip_filter}->in_filter($this_ip);

$self->debug("Filtering $this_ip") if $is_filtered;

return $is_filtered;
}


sub debug { my($self, $msg) = @_; $self->{super}->debug("Network : ".$msg); }
sub info { my($self, $msg) = @_; $self->{super}->info("Network : ".$msg); }
Expand Down