public
Description: Tiny PHP+mySQL BitTorrent tracker
Homepage: http://soultcer.net/wiki/Code/nanotrack
Clone URL: git://github.com/soult/nanotrack.git
nanotrack / announce.php
100644 85 lines (74 sloc) 3.815 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
<?php
 
// Some starting stuff
header('Content-type: text/plain');
require('config.inc.php');
 
// In case of an error
function send_error($error = 'Fatal tracker error') {
die('d14:failure reason' . strlen($error) . ':' . $error . 'e');
}
 
// Validate input data
if(empty($_GET['port']) || (int) $_GET['port'] < 0 || (int) $_GET['port'] > 65535) {
send_error('Invalid client port');
}
if(!array_key_exists('no_peer_id', $_GET) && !array_key_exists('compact', $_GET)) {
send_error('Please use a client that uses no_peer_id or compact requests');
}
if(empty($_GET['info_hash']) || strlen($_GET['info_hash']) != 20) {
  send_error('Invalid info hash');
}
if(array_key_exists('event', $_GET) && $_GET['event'] == 'stopped') {
$_GET['numwant'] = 0;
} else {
unset($_GET['event']); // So we only need to check if $_GET['event'] is set
}
if(!array_key_exists('numwant', $_GET)) {
$_GET['numwant'] = 50;
} elseif($_GET['numwant'] > $config['max_peers']) {
$_GET['numwant'] = $config['max_peers'];
}
 
// Connect to mysql
$mysql_connection = mysql_connect($config['mysql']['host'], $config['mysql']['user'], $config['mysql']['password']) or send_error('Fatal tracker error: DB connection failed');
unset($config['mysql']['password']);
mysql_select_db($config['mysql']['database'], $mysql_connection) or send_error('Fatal tracker error: DB connection failed');
 
// Set own entry
$_GET['info_hash'] = mysql_real_escape_string($_GET['info_hash'], $mysql_connection);
if(!array_key_exists('event', $_GET)) { // event is not stopped
mysql_query('INSERT INTO ' . $config['mysql']['table'] . ' ( info_hash, ip, port ) VALUES ( \'' . $_GET['info_hash'] . '\', ' . sprintf('%u', ip2long($_SERVER['REMOTE_ADDR'])) . ', ' . (int) $_GET['port'] . ' ) ON DUPLICATE KEY UPDATE port=VALUES(port)', $mysql_connection) or send_error('Fatal tracker error: DB insert failed');
} else {
mysql_query('DELETE FROM ' . $config['mysql']['table'] . ' WHERE info_hash = \'' . $_GET['info_hash'] . '\' AND ip = ' . sprintf('%u', ip2long($_SERVER['REMOTE_ADDR'])), $mysql_connection) or send_error('Fatal tracker error: DB delete failed');
}
 
// Get some other peers
if($_GET['numwant'] > 0) {
$result = mysql_query('SELECT SQL_CALC_FOUND_ROWS ip, port FROM ' . $config['mysql']['table'] . ' WHERE info_hash = \'' . $_GET['info_hash'] . '\' ORDER BY RAND() LIMIT ' . (int) $_GET['numwant'], $mysql_connection) or send_error('Fatal tracker error: DB select failed');
echo 'd'; // <--- here the output starts
echo '5:peers';
if(array_key_exists('compact', $_GET)) {
echo mysql_num_rows($result) * 6 . ':';
while($row = mysql_fetch_row($result)) {
echo pack('Nn', $row[0], $row[1]);
}
} else {
echo 'l';
while($row = mysql_fetch_row($result)) {
$ip = long2ip($row[0]);
echo 'd2:ip' . strlen($ip) . ':' . $ip . '4:porti' . $row[1] . 'e';
}
echo 'e';
}
mysql_free_result($result);
 
// Send some torrent statistics
$result = mysql_query('SELECT FOUND_ROWS()', $mysql_connection) or send_error('Fatal tracker error: DB select failed');
} else {
// The client wants no peers but still should get stats
$result = mysql_query('SELECT COUNT(*) FROM ' . $config['mysql']['table'] . ' WHERE info_hash = \'' . $_GET['info_hash'] . '\'', $mysql_connection) or send_error('Fatal tracker error: DB select failed');
}
$row = mysql_fetch_row($result);
mysql_free_result($result);
 
// Close mysql connection (it's about time)
mysql_close($mysql_connection);
 
// Estimate number of seeders and leechers and send some other stuff
$row[0] = floor($row[0] / 2); // We assume half of all peers are seeders
echo '8:completei' . $row[0] . 'e10:incompletei' . $row[0] . 'e';
echo '8:intervali' . ($config['interval'] + mt_rand(-120, 120)) . 'e';
echo '12:min intervali' . $config['min_interval'] . 'e';
die('e'); // <--- output ends here