#!perl package Apache2::ModBT::LeechNuker; =pod =head1 NAME Apache2::ModBT::LeechNuker - mod_perl handler to shun leeches on a mod_bt BitTorrent Tracker =head1 SYNOPSIS PerlModule Apache2::ModBT::LeechNuker PerlFixupHandler Apache::ModBT::LeechNuker PerlSetVar MinLeechTime 3600 =head1 DESCRIPTION The Apache::ModBT::LeechNuker module is a basic example on how to manipulate the operations of a mod_bt BitTorrent tracker from mod_perl. When run on an "/announce" request, this module will look up the peer making the request in the tracker's database. If the peer has not uploaded anything, and has been connected to the tracker for a certain amount of time (the default is 3600 seconds or 1 hour), has been downloading, and there are other peers that need his or her help, the peer's "Shunned" flag is set in the database. A "Shunned" peer is never given any other peers when it makes /announce requests, and is never served to other peers, effectively blocking the peer from the network =head1 SEE ALSO L, L, L, L =cut use strict; use warnings; use Apache2::Const qw(DECLINED); use Apache2::RequestRec; use Apache2::RequestIO; use URI; use Apache2::ModBT; use Net::BitTorrent::LibBTT; use URI::Escape; our $Shunned; my(%flags)=(reverse(Net::BitTorrent::LibBTT::Peer::Flags())); if(!$flags{Shunned}) { die "This tracker does not have a \"Shunned\" flag!"; } $Shunned = $flags{Shunned}; our $shunstr = "Shunning peer \"%s\" from hash \"%s\" (No up, %u down, %u left, %u online, %u/%u downloaders)\n"; return 1; sub handler { my $r = shift; my $uri = URI->new(); my $leechtime = $r->dir_config("MinLeechTime") || 3600; $uri->query($r->args); my(%args)=($uri->query_form()); my $tracker; unless($tracker = $r->server->ModBT_Tracker()) { # tracker is not enabled return DECLINED; } if($args{"info_hash"} && $args{"peer_id"}) { if(my $hash = $tracker->Infohash(uri_unescape($args{"info_hash"}))) { if(my $peer = $hash->Peer(uri_unescape($args{"peer_id"}))) { if( (!$peer->uploaded) && ($peer->downloaded) && ($peer->left) && ($hash->seeds) && ($hash->peers > ($hash->seeds + 1)) && ((time() - $peer->first_t) > $leechtime) && (!($peer->flags & $Shunned)) ) { warn sprintf ( $shunstr, uri_escape($peer->peerid), uri_escape($peer->infohash), $peer->downloaded, $peer->left, time() - $peer->first_t, $hash->peers, $hash->seeds ); $peer->flags($peer->flags | $Shunned); $peer->save(); } } } } return DECLINED; }