Moved source code into a separate repo.

See: https://github.com/BOINC/boinc-bittorrent
This commit is contained in:
Rom Walton 2015-11-14 22:49:04 -05:00
parent ac7ac7986d
commit 49b671f523
20 changed files with 0 additions and 889 deletions

View File

@ -1,25 +0,0 @@
-----------------
Setting it all up
-----------------
The .torrent cache will need to know where to look for the files that are going
to be sent to the clients. Usually this will be the project download directory.
<insert more settings here>
Also, you need to run the database scripts in the /database/-directory in order
to set up your database for bittorrent tracking.
------------------
How to enable this
------------------
By default Bittorrent support is turned off on both server and client. You must
enable bittorrent in your server configuration files by doing this:
<insert useful guide here>
You must also convince your users that enabling Bittorrent support on their clients
is a useful way to help the project. It is a good idea to let them know that
setting the "Maximum upload rate" under general preferences enables them to
control just how much of their outgoing bandwidth is ever used. A setting of 70%
or less of their actual bandwidth is recommended to avoid creating latency issues
on their connection.

View File

@ -1,47 +0,0 @@
NOTE: THE CODE IN THIS DIRECTORY DOESN'T CURRENTLY WORK,
AND IS NOT BEING MAINTAINED.
IT'S HERE IN CASE SOMEONE WANTS TO REVIVE IT.
-----------------------------------
Bittorrent file distribution system
-----------------------------------
When several workunits require the same file (for instance any particularly big
application file) it is really a waste to use a central server to distribute this
file. First of all a central server requires lots of bandwidth - which may be
quite expensive. Secondly getting 10'000 requests for the same multi-megabyte
file may be too much for even the largest of servers.
The solution is to harness the power of peer-to-peer computing in the domain of
volunteer and desktop grid computing by allowing the clients to share pieces of the
files they are downloading.
How it works
------------
Since noone can be trusted, "Bob" (a client) will need some way of knowing if "Eve"
(another client) sent him a valid piece of the original file. To enable him to do
so Bob has downloaded a .torrent from the project servers. The .torrent describes
the file he is downloading; it contains hash values for each piece so that he can
check whether "Eve" is trying to cheat him.
If "Alice" also wants to download the same file as "Bob" they can each fetch a
different piece from the project servers and then share the pieces. Seen from
"Bob" and "Alice"'s perspective this potentially doubles the download rate (if you
see it from the project perspective it cuts the required network bandwidth in half).
As more people join the synergetic effect increases dramatically.
Isn't Bittorrent illegal?
-------------------------
Bittorrent is a protocol for sharing files across the internet. As such it cannot
be illegal in itself - it is what you do with it that matters.
If you take a look at all the filesharing protocols out there Bittorrent seems to
be the one that has been taken into widespread use in the whitehat part of the
internet. Several major companies, including the movie industry, have adopted the
technology because of its unique ability to distribute load. To name a few uses:
- Bittorrent.com (Works with the movie industry, sells movies and shows)
- Blizzard Entertainment (Uses BT to distribute data patches for their World of
Warcraft game)
- EletricSheep screensaver (Uses BT to distribute computed "dreams")
How do I enable this?
---------------------
Have a look at the INSTALL file located in the same directory as this file.

View File

@ -1,100 +0,0 @@
<?php
/**
* This file contains the main portion of the tracker.
* The tracker is the central part of any Bittorrent system. The tracker coordinates the downloads
* between peers and ensures that only valid files are tracked. It is queried multiple times during
* any Bittorrent-enabled download - usually whenever a peer wants to expand its list of other peers.
*
* The tracker also keeps track of how the downloads are progressing.
*/
$cvs_version_tracker[]="\$Id$"; //Generated automatically - do not edit
require_once("config.php");
function trackerError($error){
echo BDictionary::toEncoded(array("failure_reason"=>$error));
exit;
}
$info_hash = rawurldecode($_GET["info_hash"]);
if (strlen($info_hash)!=20) throw new IllegalArgumentException("Malformed infohash key (length ".strlen($info_hash).")");
$peer_id = $_GET["peer_id"];
if (strlen($peer_id)!=20) throw new IllegalArgumentException("Malformed peer ID (".strlen($peer_id).")");
$port = $_GET["port"];
if (!is_numeric($port)) throw new IllegalArgumentException("Non-numeric port supplied");
$event = $_GET["event"];
$ip = $_GET["ip"];
$uploaded = $_GET["uploaded"];
if (!$uploaded) $uploaded = 0;
if (!is_numeric($uploaded)) throw new IllegalArgumentException("Non-numeric upload amount specified");
$downloaded = $_GET["downloaded"]; if (!$downloaded) $downloaded = 0;
if (!is_numeric($downloaded)) throw new IllegalArgumentException("Non-numeric download amount specified");
if (!$ip){
$ip = $_SERVER["REMOTE_ADDR"];
}
// Is the IP banned?
db_init();
if (isIPBanned($ip)){
trackerError("Banned IP: ".$ip);
}
// Check that the info_hash is one that we allow:
$queryHandle = mysql_query("SELECT * from bittorrent_files where info_hash=\"".process_user_text($info_hash)."\""); echo mysql_error();
if (!mysql_num_rows($queryHandle)){
trackerError("The tracker does not allow tracking of this file:".$info_hash . " [] ".$_GET["info_hash"]);
}
$infoHashObject = mysql_fetch_object($queryHandle);
// If the peer is actively doing something let's update the DB
if ($event=="started" || $event=="stopped" || $event=="completed"){
mysql_query("REPLACE into bittorrent_peers SET fileid=".$infoHashObject->id.", peerid=\"".process_user_text($peer_id)."\", ip=\"".process_user_text($ip)."\", port=\"".process_user_text($port)."\", status=\"".$event."\", uploaded=".process_user_text($uploaded).", downloaded=".process_user_text($downloaded).", timestamp=".time());
echo mysql_error();
} else {
mysql_query("REPLACE delayed into bittorrent_peers SET fileid=".$infoHashObject->id.", peerid=\"".process_user_text($peer_id)."\", ip=\"".process_user_text($ip)."\", port=\"".process_user_text($port)."\", uploaded=".process_user_text($uploaded).", downloaded=".process_user_text($downloaded).", timestamp=".time());
echo mysql_error();
}
// Always send back a random selection of peers who are downloading a file with the same info_hash
$queryHandle = mysql_query("SELECT * from bittorrent_peers WHERE fileid = ".$infoHashObject->id." order by RAND() limit ".MAX_INFO_HASH_PEERS); echo mysql_error();
$peerList = array();
while ($dbPeer = mysql_fetch_object($queryHandle)){
$peer = array("peer id"=>$dbPeer->peerid, "ip"=>$dbPeer->ip, "port"=>intval($dbPeer->port));
$peerList[] = new BElement(BDictionary::toEncoded($peer));
}
// Get some statistical counts
$queryHandle = mysql_query("SELECT count(fileid) as complete from bittorrent_peers where fileid = '".$infoHashObject->id."' and status='completed'");
$data = mysql_fetch_object($queryHandle);
$complete = intval($data->complete);
$queryHandle = mysql_query("SELECT count(fileid) as incomplete from bittorrent_peers where fileid = '".$infoHashObject->id."' and status!='completed'");
$data = mysql_fetch_object($queryHandle);
$incomplete = intval($data->incomplete);
$peersElement = new BElement(BList::toEncoded($peerList));
$out = BDictionary::toEncoded(array("interval"=>DEFAULT_CONNECTION_INTERVAL, "complete"=>$complete, "incomplete"=>$incomplete, "peers"=>$peersElement));
// Echo the answer to stdout
echo $out;
$fh = fopen(TRACKER_LOGFILE, "a");
fputs($fh, date(DATE_ATOM, time())." ".$_SERVER["REMOTE_ADDR"]." - ".$event."\n");
fclose($fh);
// ------------------------------------------------------
// Check if the database needs cleaning
$cache_args = "tracker_timer";
$cacheddata=get_cached_data(DB_CLEAN_TTL,$cache_args);
if ($cacheddata){ //If we have got the timer in cache
// Do nothing
} else { //if not do queries etc to clean DB
// TODO: update the bittorrent_statistics table here before deleting entries
mysql_query("DELETE from bittorrent_files where timestamp<".(time()-TORRENT_TTL)); echo mysql_error();
mysql_query("DELETE from bittorrent_peers where timestamp<".(time()-PEER_TTL)); echo mysql_error();
mysql_query("DELETE from bittorrent_ipbans where timestamp<".time()); echo mysql_error();
// And reset the timer in the cache
set_cache_data(serialize(time()),$cache_args); //save data in cache
};
?>

View File

@ -1,81 +0,0 @@
<?php
// Includes from BOINC
require_once("../inc/cache.inc");
require_once("../inc/util.inc");
// Includes from BT
require_once("./inc/illegalargumentexception.php");
require_once("./inc/torrent.php");
require_once("./inc/belement.php");
require_once("./inc/blist.php");
require_once("./inc/bstring.php");
require_once("./inc/bdictionary.php");
require_once("./inc/binteger.php");
require_once("./inc/checks.php");
// Includes for filtering
require_once("./filters/filefilter.php");
$cvs_version_tracker[]="\$Id$"; //Generated automatically - do not edit
/**
* Usually it should be enough to edit the lines below this comment to fit your usage scenario -
* ie. if you have a lot of users and the files you have change a lot you may wish to cut down on
* the torrent_ttl (since this determines the final size of the database).
* The remaining part of this configuation file is split into 2 subparts: One for configuration
* of the tracker and one for configuration of the .torrent-generator.
*/
// Tracker --------------------------------------------------------------------------------------------------------
define (TORRENT_TTL, 3600*24*15); // How long any torrent will remain in the database if it hasn't been accessed
define (PEER_TTL, 3600*24); // How long any peer will remain in the database if it hasn't talked to us
define (DB_CLEAN_TTL, 3600*24); // How often the DB will be cleaned
define (DEFAULT_CONNECTION_INTERVAL, 3600); // How often we would like clients to talk to the tracker
define (MAX_INFO_HASH_PEERS, 30); // How many peers to send back for each tracker request
define (TRACKER_LOGFILE, "../../logs/bittorrent.log");
// Tracker end ----------------------------------------------------------------------------------------------------
// Generator ------------------------------------------------------------------------------------------------------
define (TORRENT_CACHE_TTL, 3600*24); // How long before regenerating any torrent information (if your files are immutable simply set this to TORRENT_TTL).
/**
* The file filter determines which files to use bittorrent for and which not to track through bittorrent.
* Setting the file filter requires that you include whatever filter you decide to use first. For a list
* of available filters please have a look in the ./filters/-folder.
* A good default behaviour is to either track anything or only track files greater than some set size.
*/
require_once("./filters/allfilesfilefilter.php"); // Include happens with the FILEname of the chosen FileFilter class
$fileFilter = new AllFilesFileFilter(); // Instantiation happens with the CLASSname of the class.
/**
* FileDirectory: The base directory to serve files from. All file references will be relative to this.
* Symlinks outside the $fileDirectory are not allowed. Either do hardlinking or make the
* entire $fileDirectory a symlink somewhere.
*/
$fileDirectory="../../download";
$trackerURL = "http://bittorrent.burp.boinc.dk/announce.php"; // The externally accessible URL to use for tracking purposes (should point to announce.php)
/**
* Webseeds: This optional array lists any project HTTP webservers capable of handing out the files.
* Note that the servers must have a very strict hierarchy for the files:
* The optional webseeds must be HTTP servers with a similar structure to $fileDirectory
* For instance if you have a webseed called "http://burp.boinc.dk/download/" and a file
* $fileDirectory/dir/file
* then the webseed musst respond to queries on http://burp.boinc.dk/download/dir/file.
*/
$webseeds = array(
"http://burp.boinc.dk/mirror/mirror_download.php?fetch=true&mirsug=0&getfile=",
"http://burp.boinc.dk/mirror/mirror_download.php?fetch=true&mirsug=1&getfile=",
"http://burp.boinc.dk/mirror/mirror_download.php?fetch=true&mirsug=2&getfile=",
"http://burp.boinc.dk/mirror/mirror_download.php?fetch=true&mirsug=3&getfile=",
"http://burp.boinc.dk/mirror/mirror_download.php?fetch=true&mirsug=4&getfile=",
"http://burp.boinc.dk/mirror/mirror_download.php?fetch=true&mirsug=5&getfile=",
"http://burp.boinc.dk/mirror/mirror_download.php?fetch=true&mirsug=6&getfile=",
"http://burp.boinc.dk/mirror/mirror_download.php?fetch=true&mirsug=7&getfile=",
"http://burp.boinc.dk/mirror/mirror_download.php?fetch=true&mirsug=8&getfile=",
"http://burp.boinc.dk/mirror/mirror_download.php?fetch=true&mirsug=9&getfile=");
// Generator end --------------------------------------------------------------------------------------------------
?>

View File

@ -1,9 +0,0 @@
CREATE TABLE `bittorrent_files` (
`id` int(11) NOT NULL auto_increment,
`filename` varchar(256) default NULL,
`info_hash` varbinary(22) default NULL,
`timestamp` int(14) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `filename` (`filename`),
KEY `info_hash` (`info_hash`)
) ENGINE=MEMORY;

View File

@ -1,5 +0,0 @@
CREATE TABLE `bittorrent_ipbans` (
`ip` varbinary(256) NOT NULL default '',
`timestamp` int(14) NOT NULL,
PRIMARY KEY (`ip`)
) ENGINE=MEMORY COMMENT='Banned IPs and when they can be unbanned (reset when SQL-server restarts)';

View File

@ -1,13 +0,0 @@
CREATE TABLE `bittorrent_peers` (
`fileid` int(11) NOT NULL default '0',
`peerid` varbinary(20) NOT NULL,
`ip` varbinary(50) default NULL,
`port` int(11) NOT NULL,
`status` enum('started','stopped','completed') NOT NULL,
`uploaded` int(11) NOT NULL,
`downloaded` int(11) NOT NULL,
`timestamp` int(14) NOT NULL,
PRIMARY KEY (`fileid`,`peerid`),
KEY `timestamp` (`timestamp`)
) ENGINE=MEMORY;

View File

@ -1,16 +0,0 @@
<?php
/**
* A file filter that simply accepts any file whatsoever
*/
$cvs_version_tracker[]="\$Id: checks.php 12885 2007-06-11 18:27:24Z jbk $"; //Generated automatically - do not edit
class AllFilesFileFilter extends FileFilter {
function isValid($file){
return true;
}
}
?>

View File

@ -1,13 +0,0 @@
<?php
/**
* Any file filter must implement the following interface
*/
$cvs_version_tracker[]="\$Id: checks.php 12885 2007-06-11 18:27:24Z jbk $"; //Generated automatically - do not edit
abstract class FileFilter {
abstract function isValid($file);
}
?>

View File

@ -1,53 +0,0 @@
<?php
/**
* A dictionary is a mapping from strings to elements. When BEncoded a dictionary is
* two lists interleaved. In PHP dictionaries are represented as arrays with the
* string as index and value as entry at that index.
* In BEncoded form a dictionary starts with "d" and is followed directly by the
* contents of the interleaved data list and ends with "e".
*
* d3:cow3:moo4:spam4:eggse represents the dictionary { "cow" => "moo", "spam" => "eggs" }
*/
$cvs_version_tracker[]="\$Id$"; //Generated automatically - do not edit
class BDictionary {
private function __construct(){
}
/**
* Returns the decoded array from $str
* @throws an IllegalArgumentException in the case
* that the string is malformed.
*/
public static function toArray($str){
if (substr($str, 0, 1)!="d" || substr($str, -1, 1)!="e") throw new IllegalArgumentException("BEncoded dictionary does not start with d or end with e.");
// An array is simply two lists encoded in an alternating list
$arrays = BList::toList("l".substr($str, 1));
$i=0;
for ($i=0;$i<sizeof($arrays); $i+=2){
$array[$arrays[$i]] = $arrays[$i+1];
}
return $array;
}
/**
* Returns a BEncoded dictonary
*/
public static function toEncoded($array){
ksort($array);
// An array is simply two lists encoded as an alternating list
$list = array();
foreach ($array as $key => $value){
$list[] = $key;
$list[] = $value;
}
return "d".substr(BList::toEncoded($list), 1);
}
}
?>

View File

@ -1,29 +0,0 @@
<?php
/**
* This class is used as part of the Bittorrent .torrent creator and tracker system.
* A BElement is used to contain BEncoded elements inside other BEncodings (like lists or dictonaries)
*/
$cvs_version_tracker[]="\$Id: belement.inc 12611 2007-05-08 08:25:13Z jbk $"; //Generated automatically - do not edit
class BElement {
private $encodedText;
/**
* Constructs a new BElement with the $bEncoding as BEncoded
* value to be used
*/
public function __construct($bEncoding){
$this->encodedText = $bEncoding;
}
/**
* Returns a BEncoded value
*/
public function toEncoded(){
return $this->encodedText;
}
}
?>

View File

@ -1,35 +0,0 @@
<?php
/**
* A BInteger takes care of the BEncoding and BDecoding of integers for the
* Bittorrent features.
* An integer starts with "i", has the value and then ends with "e".
*/
$cvs_version_tracker[]="\$Id$"; //Generated automatically - do not edit
class BInteger {
private function __construct(){
}
/**
* Returns the ordinary value decoded from $str
* @throws an IllegalArgumentException in the case
* that the string is malformed.
*/
public static function toInteger($str){
if (substr($str, 0, 1)!="i" || substr($str, -1, 1)!="e") throw new IllegalArgumentException("BEncoded integer value does not start with i or end with e.");
$value = substr($str, 1,-1);
if (!is_numeric($value)) throw new IllegalArgumentException("BEncoded string has non-numeric length specification.");
return $value;
}
/**
* Returns a BEncoded integer value
*/
public static function toEncoded($value){
return "i".$value."e";
}
}
?>

View File

@ -1,102 +0,0 @@
<?php
/**
* The BList class is part of the Bittorrent serverside utility classes
* It implements a BEncoded list - which always starts with l and ends with e.
* In PHP lists are simply non-keyed (ie. standard keyed) arrays.
*/
$cvs_version_tracker[]="\$Id$"; //Generated automatically - do not edit
class BList {
private function __construct(){
}
/**
* Returns the decoded array from $str
* @throws an IllegalArgumentException in the case
* that the string is malformed.
*/
public static function toList($str){
if (substr($str, 0, 1)!="l" || substr($str, -1, 1)!="e") throw new IllegalArgumentException("BEncoded list does not start with l or end with e.");
$value = substr($str, 1,-1);
// Scan through encoded list and decode everything
$list = array();
$i=0; $lastI = 0;
while ($i<strlen($value)){
$curChar = substr($value, $i,1);
if ($curChar == "i"){ // We just saw an Integer
$endPos = strpos($value, "e", $i); // Search for the end of it
if ($endPos===false) throw new IllegalArgumentException("BEncoded list contains non-terminated integer");
$list[] = BInteger::toInteger(substr($value, $i, $endPos-$i+1));
$i=$endPos+1;
} elseif (is_numeric($curChar)){ // A number means we just saw a string starting
$seperatorPos = strpos($value, ":", $i); // Search for the seperator
if ($seperatorPos===false) throw new IllegalArgumentException("BEncoded list contains malformed string with no length specified");
$totalLength = substr($value, $i, $seperatorPos-$i);
$list[] = BString::toString(substr($value, $i, $seperatorPos-$i+$totalLength+1));
$i=$seperatorPos+$totalLength+1;
} elseif ($curChar == "d" || $curChar == "l"){ // Found a dictionary or list
// Scan for end of it
$listLength = BList::getListLength(substr($value, $i));
if ($curChar == "d"){
$list[] = BDictionary::toArray(substr($value, $i, $listLength));
} else {
$list[] = BList::toList(substr($value, $i, $listLength));
}
$i+=$listLength;
}
if ($i==$lastI) throw new IllegalArgumentException("BEncoded list contains malfomed or unrecognized content");
$lastI = $i;
}
return $list;
}
private static function getListLength($text){
$i = 1; $lastI = 0; $foundEnd = false;
while ($i<strlen($text)){
$curChar = substr($text, $i, 1);
if ($curChar == "i"){
$i = strpos($text, "e", $i);
if ($i===false) throw new IllegalArgumentException("BEncoded sublist/dictionary integer has no end");
$i++;
} elseif (is_numeric($curChar)){
$seperatorPos = strpos($text, ":", $i); // Search for the seperator
if ($seperatorPos===false) throw new IllegalArgumentException("BEncoded sublist/dictionary contains a string with no length specified");
$totalLength = substr($text, $i, $seperatorPos-$i);
$i=$seperatorPos+$totalLength+1;
} elseif ($curChar == "d" || $curChar == "l"){
$i+=BList::getListLength(substr($text, $i));
} elseif ($curChar == "e"){
$foundEnd = true;
break;
}
if ($i==$lastI) throw new IllegalArgumentException("BEncoded sublist/dictionary contains malfomed or unrecognized content");
$lastI = $i;
}
if (!$foundEnd) throw new IllegalArgumentException("BEncoded sublist/dictionary had no end");
return $i+1;
}
/**
* Returns a BEncoded list
*/
public static function toEncoded($list){
$values = array_values($list);
$text = "l";
foreach ($values as $value){
if (is_integer($value)){
$text.=BInteger::toEncoded($value);
} elseif (is_string($value)){
$text.=BString::toEncoded($value);
} elseif ($value instanceof BElement){
$text.=$value->toEncoded();
}
}
$text.= "e";
return $text;
}
}
?>

View File

@ -1,36 +0,0 @@
<?php
/**
* The BString class represents BEncoded strings for the serverside Bittorrent system.
* A BEncoded string always starts with the length, then a ":" and then the actual data.
* Strings are native in PHP.
*/
$cvs_version_tracker[]="\$Id$"; //Generated automatically - do not edit
class BString {
private function __construct(){
}
/**
* Returns the ordinary string decoded from $str
* @throws an IllegalArgumentException in the case
* that the string is malformed (ie. has more/less chars than specified
* or does not correctly define a BEncoded string)
*/
public static function toString($str){
list($length, $data) = explode(":", $str);
if (!is_numeric($length)) throw new IllegalArgumentException("BEncoded string has non-numeric length specification.");
if ($length != strlen($data)) throw new IllegalArgumentException("BEncoded string length does not match actual length of string.");
return $data;
}
/**
* Returns a BEncoded string
*/
public static function toEncoded($str){
return strlen($str).":".$str;
}
}
?>

View File

@ -1,31 +0,0 @@
<?php
/**
* Checks common to both the tracker and the scraping mechanism.
*/
$cvs_version_tracker[]="\$Id$"; //Generated automatically - do not edit
function isIPBanned($ip){
$queryHandle = mysql_query("SELECT * from bittorrent_ipbans where ip=\"".process_user_text($ip)."\" and timestamp > ".time()); echo mysql_error();
if (mysql_num_rows($queryHandle)){
return true;
} else {
return false;
}
}
if (get_magic_quotes_gpc()) {
function stripslashes_deep($value) {
$value = is_array($value) ?
array_map('stripslashes_deep', $value) :
stripslashes($value);
return $value;
}
$_POST = array_map('stripslashes_deep', $_POST);
$_GET = array_map('stripslashes_deep', $_GET);
$_COOKIE = array_map('stripslashes_deep', $_COOKIE);
$_REQUEST = array_map('stripslashes_deep', $_REQUEST);
}
?>

View File

@ -1,9 +0,0 @@
<?php
$cvs_version_tracker[]="\$Id$"; //Generated automatically - do not edit
class IllegalArgumentException extends Exception {
}
?>

View File

@ -1,89 +0,0 @@
<?php
/**
* A .torrent is a metafile containing info about a P2P file
* This class encapsulates all related .torrent information
* for a single file.
* We don't seem to need multifile support since the clients can
* simply download a .torrent for each file they want to fetch.
*/
$cvs_version_tracker[]="\$Id$"; //Generated automatically - do not edit
class Torrent {
private $trackerURL; // String
private $name; // String
private $pieceLength = 524288; // (512KB)
private $filename; // String
private $webseeds; // URL String Array
private $concattedSHA1; // Imploded string of SHA1 hashes
private $generatedPieceLength;
private $infoHash;
/**
* Filename is the full path to the file to be encapsulated.
*/
function __construct($filename, $trackerURL, $webseeds=array()){
if (!file_exists($filename)) throw new IllegalArgumentException("No such file found");
$this->filename = $filename;
$this->trackerURL = $trackerURL;
$this->webseeds = $webseeds;
$this->name = basename($filename);
}
/**
* Scans the entire file generating SHA1 hashes for each piece
*/
public function ensureSHA1Loaded(){
if (!$this->concattedSHA1 || ($this->pieceLength!=$this->generatedPieceLength)){
$fh = fopen($this->filename, "rb");
if (!$fh) throw new Exception("No filehandle");
$fsize = filesize($this->filename);
$this->concattedSHA1 = "";
for ($i = 0; $i<ceil($fsize/$this->pieceLength); $i++){
fseek($fh, $i*$this->pieceLength);
$this->concattedSHA1 .= sha1(fread($fh,$this->pieceLength), true);
}
$this->generatedPieceLength = $this->pieceLength;
fclose($fh);
if (!$this->concattedSHA1) throw new Exception("No SHA gotten");
}
}
/**
* Fetches all relevant information from the file and generates a
* .torrent
*/
public function toEncoded(){
$infoArray["name"] = $this->name;
$infoArray["piece length"] = $this->pieceLength;
$infoArray["length"] = filesize($this->filename);
$this->ensureSHA1Loaded();
$infoArray["pieces"] = $this->concattedSHA1;
$infoDictionary = new BElement(BDictionary::toEncoded($infoArray));
$this->infoHash = sha1($infoDictionary->toEncoded(), true);
$metainfoArray = array("announce"=>$this->trackerURL, "info"=>$infoDictionary);
$metainfoArray["url-list"] = new BElement(BList::toEncoded($this->webseeds));
$metainfoDictionary = BDictionary::toEncoded($metainfoArray);
return $metainfoDictionary;
}
/**
* Registers this torrent in the database
*/
public function register(){
$this->toEncoded();
// Check if exists:
$queryHandle = mysql_query("SELECT id from bittorrent_files where filename=\"".process_user_text($this->filename)."\"");
if ($queryHandle && $data = mysql_fetch_object($queryHandle)){
$extra = "id=".$data->id.", ";
} else {
$extra = "";
}
mysql_query("REPLACE into bittorrent_files set ".$extra."filename=\"".process_user_text($this->filename)."\", info_hash=\"".process_user_text($this->infoHash)."\", timestamp=".time());
}
}

View File

@ -1,78 +0,0 @@
<?php
/**
* This index-file helps setup and debug any Bittorrent tracker and generator installation through
* the use of some built-in checks in the code.
* It is advised that you leave the index file in place even after succesful installation so that any
* later debugging can easily be done.
*
* Also, at some point, this file will display some statistical information about the data distributed
* through the use of the tracker.
*/
$cvs_version_tracker[]="\$Id$"; //Generated automatically - do not edit
?>
<html>
<head>
<title>BOINC Bittorrent</title>
</head
<body>
<h1>BOINC Bittorrent</h1>
<p>
This page helps you identify whether the BOINC Bittorrent system has succesfully been installed
on the server. If all of the bellow checks are green and all of the settings seem to match your
setup then everything should be perfectly fine.<br />
If, for some reason, the entire page (including the text at the bottom, bellow the table of checks)
isn't displayed, you should have a look at the error-log for your server. Similarly, if one of the
checks fail you may find additional information on the page or in your server logs.
</p>
<table>
<tr>
<th>Check</th><th>Status</th>
</tr>
<?php
function showCheck($check, $status, $comment){
echo "<tr><td>".$check."</td><td>";
if ($status){
echo "<font color='green'>OK";
} else {
echo "<font color='yellow'>Hm...";
}
echo "</td><td>";
if (!$status) echo $comment;
echo "</td></tr>";
}
showCheck("Linking to config.php", file_exists("./config.php"), "config.php is missing - did you remember to copy from the sample?");
require_once("./config.php");
showCheck("Linking to BOINC serverside framework", file_exists("../inc/util.inc"), "Cannot find the BOINC framework - did you install the BT system in the html/-directory of your BOINC installation?");
require_once("../inc/util.inc");
showCheck("Database link", (db_init()||true), "");
showCheck("bittorrent_files table", mysql_query("select * from bittorrent_files"), "Table inaccessible");
showCheck("bittorrent_ipbans table", mysql_query("select * from bittorrent_ipbans"), "Table inaccessible");
showCheck("bittorrent_peers table", mysql_query("select * from bittorrent_peers"), "Table inaccessible");
showCheck("bittorrent_statistics table", mysql_query("select * from bittorrent_statistics"), "Table inaccessible");
showCheck("Linking to download dir (".$fileDirectory.")", file_exists($fileDirectory), "Directory not accessible or present");
showCheck("Tracker present (".$trackerURL.")", fopen($trackerURL, "r"), "Either this webserver doesn't support URL-fopen-wrappers or the tracker is not available. In the first case you may safely ignore this warning.");
showCheck("Webseeds defined", (sizeof($webseeds)>0), "No webseeds defined");
foreach ($webseeds as $webseed){
showCheck("Seed present (".$webseed.")", fopen($webseed, "r"), "Either this webserver doesn't support URL-fopen-wrappers or the webseed is not present. If the first is the case this warning may safely be ignored.");
}
showCheck("Linking to logfile (".TRACKER_LOGFILE.")", file_exists(TRACKER_LOGFILE), "The logfile doesn't exist - this may be because the system hasn't been run yet or because the file couldn't be created.");
?>
</table>
<p>
Files used in this distribution:
<ul>
<?php
for ($i=0;$i<sizeof($cvs_version_tracker);$i++) {
echo "<li>".$cvs_version_tracker[$i]."\n";
}
?>
</ul>
</p>
<p>
For more information check the documentation delivered within the bt directory.
</p>
</body>
</html>

View File

@ -1,47 +0,0 @@
<?php
/**
* For multiple purposes it may be interesting for clients to know a little about
* the network statistics for the entire Bittorrent swarm controlled by the tracker.
* Scraping allows clients to get this information easily and quickly.
*/
$cvs_version_tracker[]="\$Id$"; //Generated automatically - do not edit
require_once("config.php");
function trackerError($error){
echo BDictionary::toEncoded(array("failure_reason"=>$error));
exit;
}
$info_hash = rawurldecode($_GET["info_hash"]);
if (strlen($info_hash)!=20) throw new IllegalArgumentException("Malformed infohash key (length ".strlen($info_hash).")");
if (!$ip){
$ip = $_SERVER["REMOTE_ADDR"];
}
// Is the IP banned?
db_init();
if (isIPBanned($ip)){
trackerError("Banned IP: ".$ip);
}
// Check that the info_hash is one that we allow:
$queryHandle = mysql_query("SELECT * from bittorrent_files where info_hash=\"".process_user_text($info_hash)."\""); echo mysql_error();
if (!mysql_num_rows($queryHandle)){
trackerError("The tracker does not allow tracking of this file:".$info_hash);
}
$infoHashObject = mysql_fetch_object($queryHandle);
// Get some statistical counts
$queryHandle = mysql_query("SELECT count(fileid) as complete from bittorrent_peers where fileid = '".$infoHashObject->id."' and status='completed'");
$data = mysql_fetch_object($queryHandle);
$complete = intval($data->complete);
$queryHandle = mysql_query("SELECT count(fileid) as incomplete from bittorrent_peers where fileid = '".$infoHashObject->id."' and status!='completed'");
$data = mysql_fetch_object($queryHandle);
$incomplete = intval($data->incomplete);
$out = BDictionary::toEncoded(array("interval"=>DEFAULT_CONNECTION_INTERVAL, "downloaded"=>$complete, "complete"=>$complete, "incomplete"=>$incomplete));
?>

View File

@ -1,71 +0,0 @@
<?php
/**
* The torrent cache and generator script takes care of dynamically generating .torrents
* when they are requested by clients.
* To optimize performance .torrent-objects are cached in the cache directory so that
* on any second request they can be directly sent without re-calculating the SHA1 strings.
*
* A file is requested by torrent_cache.php?file=/some_file.filetype
*
* Symlinks outside the $fileDirectory are not allowed. Either do hardlinking or make the
* entire $fileDirectory a symlink somewhere.
*
* The optional webseeds must be HTTP servers with a similar structure to $fileDirectory
* For instance if you have a webseed called "http://burp.boinc.dk/download/" and a file
* $fileDirectory/dir/file
* then the webseed musst respond to queries on http://burp.boinc.dk/download/dir/file.
*
* Please see config.php for the setting of these variables.
*/
require_once("config.php");
function isSubDir($possibleSubDir, $parent){
$realPossible = realpath($possibleSubDir);
$realParent = realpath($parent);
return (substr($realPossible, 0, strlen($realParent)) == $realParent);
}
// Get the file request and do some checkups
$file = $_GET["file"];
if (!$file) throw new IllegalArgumentException("No file specified");
if (strpos(urldecode($file), "..")!==false) throw new IllegalArgumentException("Cannot use '..' in path");
// See if we've got the file
while (!$fileModTime){
if (($fileModTime = @filemtime($fileDirectory.$file)) === false){
$pos = strpos($file, "/", 1);
if ($pos === false){
throw new IllegalArgumentException("File does not exist");
} else {
$file = substr($file, $pos);
}
}
}
$file = $fileDirectory.$file;
if (!$fileFilter->isValid($file)) throw new IllegalArgumentException("File was not accepted by the server for tracking.");
// Everything's fine let's lookup the .torrent in the cache if needed:
$cache_args = "file=".$file."&modtime=".$fileModTime;
$cacheddata=get_cached_data(TORRENT_CACHE_TTL,$cache_args);
if ($cacheddata){ //If we have got the data in cache
$torrent = unserialize($cacheddata); // use the cached data
} else { //if not do queries etc to generate new data
for ($i=0; $i<sizeof($webseeds);$i++){
$realWebseeds[] = $webseeds[$i].substr($file, strlen($fileDirectory));
}
$torrent = new Torrent($file, $trackerURL, $realWebseeds);
$torrent->ensureSHA1Loaded();
db_init();
$torrent->register();
set_cache_data(serialize($torrent),$cache_args); //save data in cache
};
header("Content-type: application/x-bittorrent");
header("Content-Disposition: attachment; filename=\"".basename($file).".torrent\"");
echo $torrent->toEncoded();
?>