Bugfixes + optimisations
This commit is contained in:
parent
0fc658d5b2
commit
7246de7ff0
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
.idea
|
||||
.idea
|
||||
error.log
|
|
@ -7,7 +7,7 @@ https://gist.github.com/nsuan/1967006
|
|||
|
||||
## Pre-note
|
||||
|
||||
Trackers are putting on an extremely hard job in maintaining their trackers and dealing with their trackers being taken down or hosts forcing them to shut down,
|
||||
Owners of trackers are putting on an extremely hard task in maintaining their trackers and dealing with their trackers being taken down or hosts forcing them to shut down,
|
||||
even though the service is perfectly legal. And most of the people administering trackers don't make any money, as there's no way to advertise using a tracker.
|
||||
That's why we need to show them support and help them out by creating as many small trackers as possible.
|
||||
|
||||
|
|
169
announce.php
169
announce.php
|
@ -23,14 +23,15 @@
|
|||
|
||||
/*
|
||||
* Enable debugging?
|
||||
* This allows anyone to see the entire peer database by appending ?debug to the announce URL
|
||||
* This allows anyone to see the entire peer database by appending ?debug to the announce URL.
|
||||
* It will also create debugging file used to report php errors.
|
||||
*/
|
||||
define('__DEBUGGING_ENABLED', true);
|
||||
|
||||
/**
|
||||
* Version
|
||||
*/
|
||||
define('__VERSION', 1.4);
|
||||
define('__VERSION', 1.5);
|
||||
|
||||
/**
|
||||
* How often should clients pull server for new clients? (Seconds)
|
||||
|
@ -65,38 +66,61 @@ define('__NO_SEED_P2P', true);
|
|||
* On Linux, you should use /dev/shm as it is very fast.
|
||||
* On Windows, you will need to change this value to some other valid path such as C:/Peers.txt
|
||||
*/
|
||||
define('__LOCATION_PEERS', '');
|
||||
define('__LOCATION_PEERS', 'peers.txt');
|
||||
|
||||
/**
|
||||
* Should we enable short announces?
|
||||
* This allows NATed clients to get updates much faster, but it also
|
||||
* takes more load on the server. (This is just an experimental feature which may be turned off)
|
||||
*/
|
||||
define('__ENABLE_SHORT_ANNOUNCE', true);
|
||||
define('__ENABLE_SHORT_ANNOUNCE', false);
|
||||
|
||||
/**
|
||||
* In case someone tries to access the tracker using a browser, redirect to this URL or file
|
||||
*/
|
||||
define('__REDIR_BROWSER', '');
|
||||
|
||||
define('__LOG_FILE', __DIR__ . '/error.log');
|
||||
|
||||
/***********************
|
||||
** Configuration end **
|
||||
***********************/
|
||||
|
||||
if(__DEBUGGING_ENABLED === true) {
|
||||
|
||||
set_error_handler(function ($errno, $errstr, $errfile, $errline) {
|
||||
|
||||
if (file_exists(__LOG_FILE) === false) {
|
||||
$handle = fopen(__LOG_FILE, 'w+b');
|
||||
fclose($handle);
|
||||
}
|
||||
|
||||
file_put_contents(__LOG_FILE, sprintf('Line: %s - Error: %s', $errline, $errstr));
|
||||
|
||||
}, E_ALL);
|
||||
|
||||
}
|
||||
|
||||
//Send response as text
|
||||
header('Content-type: Text/Plain');
|
||||
header('X-Tracker-Version: Bitstorm '.__VERSION.' by ck3r.org'); //Please give me some credit
|
||||
//If you *really* dont want to, comment this line out
|
||||
//Bencoding function, returns a bencoded dictionary
|
||||
//You may go ahead and enter custom keys in the dictionary in
|
||||
//this function if you'd like.
|
||||
function track($list, $interval=60, $min_ival=0) {
|
||||
header('X-Tracker-Version: Bitstorm ' . __VERSION); //Please give me some credit
|
||||
|
||||
/**
|
||||
* If you *really* dont want to, comment this line out.
|
||||
* Bencoding function, returns a bencoded dictionary.
|
||||
* You may go ahead and enter custom keys in the dictionary in this function if you'd like.
|
||||
*/
|
||||
|
||||
function track($list, $interval = 60, $min_ival = 0)
|
||||
{
|
||||
if (is_string($list)) { //Did we get a string? Return an error to the client
|
||||
return 'd14:failure reason'.strlen($list).':'.$list.'e';
|
||||
return 'd14:failure reason' . strlen($list) . ':' . $list . 'e';
|
||||
}
|
||||
|
||||
$p = ''; //Peer directory
|
||||
$c = $i = 0; //Complete and Incomplete clients
|
||||
foreach($list as $d) { //Runs for each client
|
||||
|
||||
foreach ($list as $d) { //Runs for each client
|
||||
if ($d[7]) { //Are we seeding?
|
||||
$c++; //Seeding, add to complete list
|
||||
if (__NO_SEED_P2P && is_seed()) { //Seeds should not see each others
|
||||
|
@ -105,30 +129,27 @@ function track($list, $interval=60, $min_ival=0) {
|
|||
} else {
|
||||
$i++; //Not seeding, add to incomplete list
|
||||
}
|
||||
//Do some bencoding
|
||||
|
||||
//Do some bencoding
|
||||
$pid = '';
|
||||
|
||||
if (!isset($_GET['no_peer_id']) && __NO_PEER_ID) { //Shall we include the peer id
|
||||
$pid = '7:peer id'.strlen($d[1]).':'.$d[1];
|
||||
if (isset($_GET['no_peer_id']) === false && __NO_PEER_ID) { //Shall we include the peer id
|
||||
$pid = '7:peer id' . strlen($d[1]) . ':' . $d[1];
|
||||
}
|
||||
|
||||
$p .= 'd2:ip'.strlen($d[0]).':'.$d[0].$pid.'4:porti'.$d[2].'ee';
|
||||
$p .= 'd2:ip' . strlen($d[0]) . ':' . $d[0] . $pid . '4:porti' . $d[2] . 'ee';
|
||||
}
|
||||
|
||||
//Add some other paramters in the dictionary and merge with peer list
|
||||
$r = 'd8:intervali'.$interval.'e12:min intervali'.$min_ival.'e8:completei'.$c.'e10:incompletei'.$i.'e5:peersl'.$p.'ee';
|
||||
$r = 'd8:intervali' . $interval . 'e12:min intervali' . $min_ival . 'e8:completei' . $c . 'e10:incompletei' . $i . 'e5:peersl' . $p . 'ee';
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
//Find out if we are seeding or not. Assume not if unknown.
|
||||
function is_seed() {
|
||||
if (!isset($_GET['left'])) {
|
||||
return false;
|
||||
}
|
||||
if ($_GET['left'] == 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
function is_seed()
|
||||
{
|
||||
return (isset($_GET['left']) && (int)$_GET['left'] === 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -140,40 +161,58 @@ function is_seed() {
|
|||
*/
|
||||
|
||||
//Save database to file
|
||||
function db_save($data) {
|
||||
function db_save($data)
|
||||
{
|
||||
$b = serialize($data);
|
||||
$h = @fopen(__LOCATION_PEERS, 'w');
|
||||
if (!$h) { return false; }
|
||||
if (!@flock($h, LOCK_EX)) { return false; }
|
||||
@fwrite($h, $b);
|
||||
@fclose($h);
|
||||
$handle = fopen(__LOCATION_PEERS, 'wb');
|
||||
|
||||
if ($handle === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (flock($handle, LOCK_EX) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fwrite($handle, $b);
|
||||
fclose($handle);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//Load database from file
|
||||
function db_open() {
|
||||
function db_open()
|
||||
{
|
||||
$p = '';
|
||||
$h = @fopen(__LOCATION_PEERS, 'r');
|
||||
if (!$h) { return false; }
|
||||
if (!@flock($h, LOCK_EX)) { return false; }
|
||||
while (!@feof($h)) {
|
||||
$p .= @fread($h, 512);
|
||||
$handle = fopen(__LOCATION_PEERS, 'rb');
|
||||
if ($handle === false) {
|
||||
return false;
|
||||
}
|
||||
@fclose($h);
|
||||
return (strlen($p)) ? unserialize($p) : true;
|
||||
|
||||
if (flock($handle, LOCK_EX) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (feof($handle) === false) {
|
||||
$p .= fread($handle, 512);
|
||||
}
|
||||
|
||||
fclose($handle);
|
||||
|
||||
return ($p !== '') ? unserialize($p) : true;
|
||||
}
|
||||
|
||||
//Check if DB file exists, otherwise create it
|
||||
function db_exists($create_empty=false) {
|
||||
if (file_exists(__LOCATION_PEERS)) {
|
||||
function db_exists($createEmpty = false)
|
||||
{
|
||||
if (file_exists(__LOCATION_PEERS) === true) {
|
||||
return true;
|
||||
}
|
||||
if ($create_empty) {
|
||||
if (!db_save(array())) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
if ($createEmpty === true) {
|
||||
return db_save([]);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -199,7 +238,7 @@ if (isset($_GET['short']) && __ENABLE_SHORT_ANNOUNCE) {
|
|||
//Did we get any parameters at all?
|
||||
//Client is probably a web browser, do a redirect
|
||||
if (empty($_GET)) {
|
||||
header('Location: '.__REDIR_BROWSER);
|
||||
header('Location: ' . __REDIR_BROWSER);
|
||||
die();
|
||||
}
|
||||
|
||||
|
@ -209,7 +248,7 @@ $d = db_open();
|
|||
|
||||
//Do we want to debug? (Should not be used by default)
|
||||
if (isset($_GET['debug']) && __DEBUGGING_ENABLED) {
|
||||
echo 'Connected peers:'.count($d)."\n\n";
|
||||
echo 'Connected peers:' . count($d) . "\n\n";
|
||||
die();
|
||||
}
|
||||
|
||||
|
@ -219,7 +258,8 @@ if ($d === false) {
|
|||
}
|
||||
|
||||
//Do some input validation
|
||||
function valdata($g, $must_be_20_chars=false) {
|
||||
function valdata($g, $must_be_20_chars = false)
|
||||
{
|
||||
if (!isset($_GET[$g])) {
|
||||
die(track('Missing one or more arguments'));
|
||||
}
|
||||
|
@ -227,10 +267,10 @@ function valdata($g, $must_be_20_chars=false) {
|
|||
die(track('Invalid types on one or more arguments'));
|
||||
}
|
||||
if ($must_be_20_chars && strlen($_GET[$g]) != 20) {
|
||||
die(track('Invalid length on '.$g.' argument'));
|
||||
die(track('Invalid length on ' . $g . ' argument'));
|
||||
}
|
||||
if (strlen($_GET[$g]) > 128) { //128 chars should really be enough
|
||||
die(track('Argument '.$g.' is too large to handle'));
|
||||
die(track('Argument ' . $g . ' is too large to handle'));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -251,7 +291,7 @@ if (!ctype_digit($_GET['port']) || $_GET['port'] < 1 || $_GET['port'] > 65535) {
|
|||
}
|
||||
|
||||
//Array key, unique for each client and torrent
|
||||
$sum = sha1($_GET['peer_id'].$_GET['info_hash']);
|
||||
$sum = sha1($_GET['peer_id'] . $_GET['info_hash']);
|
||||
|
||||
//Make sure we've got a user agent to avoid errors
|
||||
//Used for debugging
|
||||
|
@ -260,18 +300,18 @@ if (!isset($_SERVER['HTTP_USER_AGENT'])) {
|
|||
}
|
||||
|
||||
//When should we remove the client?
|
||||
$expire = time()+$interval;
|
||||
$expire = time() + $interval;
|
||||
|
||||
//Have this client registered itself before? Check that it uses the same key
|
||||
if (isset($d[$sum])) {
|
||||
if ($d[$sum][6] !== $_GET['key']) {
|
||||
if ((string)$d[$sum][6] !== (string)$_GET['key']) {
|
||||
sleep(3); //Anti brute force
|
||||
die(track('Access denied, authentication failed'));
|
||||
}
|
||||
}
|
||||
|
||||
//Add/update the client in our global list of clients, with some information
|
||||
$d[$sum] = array($_SERVER['REMOTE_ADDR'], $_GET['peer_id'], $_GET['port'], $expire, $_GET['info_hash'], $_SERVER['HTTP_USER_AGENT'], $_GET['key'], is_seed());
|
||||
$d[$sum] = [$_SERVER['REMOTE_ADDR'], $_GET['peer_id'], $_GET['port'], $expire, $_GET['info_hash'], $_SERVER['HTTP_USER_AGENT'], $_GET['key'], is_seed()];
|
||||
|
||||
//No point in saving the user agent, unless we are debugging
|
||||
if (!__DEBUGGING_ENABLED) {
|
||||
|
@ -285,14 +325,14 @@ if (!__DEBUGGING_ENABLED) {
|
|||
if (isset($_GET['event']) && $_GET['event'] === 'stopped') {
|
||||
unset($d[$sum]);
|
||||
db_save($d);
|
||||
die(track(array())); //The RFC says its OK to return whatever we want when the client stops downloading,
|
||||
die(track([])); //The RFC says its OK to return whatever we want when the client stops downloading,
|
||||
//however, some clients will complain about the tracker not working, hence we return
|
||||
//an empty bencoded peer list
|
||||
}
|
||||
|
||||
//Check if any client timed out
|
||||
foreach($d as $k => $data) {
|
||||
if (time() > $data[3]+__CLIENT_TIMEOUT) { //Give the client some extra time before timeout
|
||||
foreach ($d as $k => $data) {
|
||||
if (time() > $data[3] + __CLIENT_TIMEOUT) { //Give the client some extra time before timeout
|
||||
unset($d[$k]); //Client has gone away, remove it
|
||||
}
|
||||
}
|
||||
|
@ -301,17 +341,18 @@ foreach($d as $k => $data) {
|
|||
db_save($d);
|
||||
|
||||
//Compare info_hash to the rest of our clients and remove anyone who does not have the correct torrent
|
||||
foreach($d as $id => $info) {
|
||||
foreach ($d as $id => $info) {
|
||||
if ($info[4] !== $_GET['info_hash']) {
|
||||
unset($d[$id]);
|
||||
}
|
||||
}
|
||||
|
||||
//Remove self from list, no point in having ourselfes in the client dictionary
|
||||
// Remove self from list, no point in having ourselfes in the client dictionary
|
||||
unset($d[$sum]);
|
||||
|
||||
//Add a few more seconds on the timeout to balance the load
|
||||
$interval += rand(0, 10);
|
||||
// Add a few more seconds on the timeout to balance the load
|
||||
$interval += mt_rand(0, 10);
|
||||
|
||||
//Bencode the dictionary and send it back
|
||||
die(track($d, $interval, $interval_min));
|
||||
// Bencode the dictionary and send it back
|
||||
echo track($d, $interval, $interval_min);
|
||||
exit(0);
|
5
peers.txt
Normal file
5
peers.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
a:8:{s:40:"383ad9e4e56df0d453245c07a8b91d328f9634b0";a:9:{i:0;s:9:"127.0.0.1";i:1;s:20:"-UM1870-¤¾Ý>>é”";i:2;s:5:"62348";i:3;i:1510303209;i:4;s:20:" "Âç]‰b¡Dð›Uõ3jhL´Ê";i:5;s:23:"uTorrentMac/1870(41986)";i:6;s:8:"E6597288";i:7;b:1;s:8:"get_parm";a:13:{s:9:"info_hash";s:20:" "Âç]‰b¡Dð›Uõ3jhL´Ê";s:7:"peer_id";s:20:"-UM1870-¤¾Ý>>é”";s:4:"port";s:5:"62348";s:8:"uploaded";s:1:"0";s:10:"downloaded";s:1:"0";s:4:"left";s:1:"0";s:7:"corrupt";s:1:"0";s:3:"key";s:8:"E6597288";s:5:"event";s:7:"started";s:7:"numwant";s:3:"200";s:7:"compact";s:1:"1";s:10:"no_peer_id";s:1:"1";s:4:"ipv6";s:23:"fe80::44:afa8:dc5d:52d5";}}s:40:"01200b02da39d0071c02d29b3f65bfb1bf757e19";a:9:{i:0;s:9:"127.0.0.1";i:1;s:20:"-UM1870-¤¾Ý>>é”";i:2;s:5:"62348";i:3;i:1510303213;i:4;s:20:"€TX±¼—Iñ—ö=WžñŸJ";i:5;s:23:"uTorrentMac/1870(41986)";i:6;s:8:"E6597288";i:7;b:1;s:8:"get_parm";a:13:{s:9:"info_hash";s:20:"€TX±¼—Iñ—ö=WžñŸJ";s:7:"peer_id";s:20:"-UM1870-¤¾Ý>>é”";s:4:"port";s:5:"62348";s:8:"uploaded";s:1:"0";s:10:"downloaded";s:1:"0";s:4:"left";s:1:"0";s:7:"corrupt";s:1:"0";s:3:"key";s:8:"E6597288";s:5:"event";s:7:"started";s:7:"numwant";s:3:"200";s:7:"compact";s:1:"1";s:10:"no_peer_id";s:1:"1";s:4:"ipv6";s:23:"fe80::44:afa8:dc5d:52d5";}}s:40:"6161de3ee5f8ae198b3ffe321992252b1a9698c6";a:9:{i:0;s:9:"127.0.0.1";i:1;s:20:"-UM1870-¤¾Ý>>é”";i:2;s:5:"62348";i:3;i:1510303217;i:4;s:20:"{~éG›±½Œ#
|
||||
ñL\“‡éƒ>{";i:5;s:23:"uTorrentMac/1870(41986)";i:6;s:8:"E6597288";i:7;b:1;s:8:"get_parm";a:13:{s:9:"info_hash";s:20:"{~éG›±½Œ#
|
||||
ñL\“‡éƒ>{";s:7:"peer_id";s:20:"-UM1870-¤¾Ý>>é”";s:4:"port";s:5:"62348";s:8:"uploaded";s:1:"0";s:10:"downloaded";s:1:"0";s:4:"left";s:1:"0";s:7:"corrupt";s:1:"0";s:3:"key";s:8:"E6597288";s:5:"event";s:7:"started";s:7:"numwant";s:3:"200";s:7:"compact";s:1:"1";s:10:"no_peer_id";s:1:"1";s:4:"ipv6";s:23:"fe80::44:afa8:dc5d:52d5";}}s:40:"e1db5d177c707ec86413406f0a3968a9106cf72b";a:9:{i:0;s:9:"127.0.0.1";i:1;s:20:"-UM1870-¤Ò£i¯7•:<3A> ";i:2;s:5:"62348";i:3;i:1510303285;i:4;s:20:" "Âç]‰b¡Dð›Uõ3jhL´Ê";i:5;s:23:"uTorrentMac/1870(41986)";i:6;s:8:"60913585";i:7;b:1;s:8:"get_parm";a:13:{s:9:"info_hash";s:20:" "Âç]‰b¡Dð›Uõ3jhL´Ê";s:7:"peer_id";s:20:"-UM1870-¤Ò£i¯7•:<3A> ";s:4:"port";s:5:"62348";s:8:"uploaded";s:1:"0";s:10:"downloaded";s:1:"0";s:4:"left";s:1:"0";s:7:"corrupt";s:1:"0";s:3:"key";s:8:"60913585";s:5:"event";s:7:"started";s:7:"numwant";s:3:"200";s:7:"compact";s:1:"1";s:10:"no_peer_id";s:1:"1";s:4:"ipv6";s:23:"fe80::44:afa8:dc5d:52d5";}}s:40:"1c27e306825d54b60b1f0e62651bf1e6197d915b";a:9:{i:0;s:9:"127.0.0.1";i:1;s:20:"-UM1870-¤Ò£i¯7•:<3A> ";i:2;s:5:"62348";i:3;i:1510303285;i:4;s:20:"€TX±¼—Iñ—ö=WžñŸJ";i:5;s:23:"uTorrentMac/1870(41986)";i:6;s:8:"60913585";i:7;b:1;s:8:"get_parm";a:13:{s:9:"info_hash";s:20:"€TX±¼—Iñ—ö=WžñŸJ";s:7:"peer_id";s:20:"-UM1870-¤Ò£i¯7•:<3A> ";s:4:"port";s:5:"62348";s:8:"uploaded";s:1:"0";s:10:"downloaded";s:1:"0";s:4:"left";s:1:"0";s:7:"corrupt";s:1:"0";s:3:"key";s:8:"60913585";s:5:"event";s:7:"started";s:7:"numwant";s:3:"200";s:7:"compact";s:1:"1";s:10:"no_peer_id";s:1:"1";s:4:"ipv6";s:23:"fe80::44:afa8:dc5d:52d5";}}s:40:"d96f7d0bc6372e37d3a0fed241b6d4571f612cf2";a:9:{i:0;s:9:"127.0.0.1";i:1;s:20:"-UM1870-¤Ò£i¯7•:<3A> ";i:2;s:5:"62348";i:3;i:1510303415;i:4;s:20:"{~éG›±½Œ#
|
||||
ñL\“‡éƒ>{";i:5;s:23:"uTorrentMac/1870(41986)";i:6;s:8:"11D0BC5F";i:7;b:1;s:8:"get_parm";a:13:{s:9:"info_hash";s:20:"{~éG›±½Œ#
|
||||
ñL\“‡éƒ>{";s:7:"peer_id";s:20:"-UM1870-¤Ò£i¯7•:<3A> ";s:4:"port";s:5:"62348";s:8:"uploaded";s:1:"0";s:10:"downloaded";s:1:"0";s:4:"left";s:1:"0";s:7:"corrupt";s:1:"0";s:3:"key";s:8:"11D0BC5F";s:5:"event";s:7:"started";s:7:"numwant";s:3:"200";s:7:"compact";s:1:"1";s:10:"no_peer_id";s:1:"1";s:4:"ipv6";s:23:"fe80::44:afa8:dc5d:52d5";}}s:40:"6e6755510b9e7d2be53ac83ee9d180d4b302d319";a:9:{i:0;s:9:"127.0.0.1";i:1;s:20:"-UM1870-¤£#9mmWV!Ð";i:2;s:5:"62348";i:3;i:1510303474;i:4;s:20:"€TX±¼—Iñ—ö=WžñŸJ";i:5;s:23:"uTorrentMac/1870(41986)";i:6;s:8:"DE9C3050";i:7;b:1;s:8:"get_parm";a:13:{s:9:"info_hash";s:20:"€TX±¼—Iñ—ö=WžñŸJ";s:7:"peer_id";s:20:"-UM1870-¤£#9mmWV!Ð";s:4:"port";s:5:"62348";s:8:"uploaded";s:1:"0";s:10:"downloaded";s:1:"0";s:4:"left";s:1:"0";s:7:"corrupt";s:1:"0";s:3:"key";s:8:"DE9C3050";s:5:"event";s:7:"started";s:7:"numwant";s:3:"200";s:7:"compact";s:1:"1";s:10:"no_peer_id";s:1:"1";s:4:"ipv6";s:23:"fe80::44:afa8:dc5d:52d5";}}s:40:"dbfb0ce142442b69313a86b8846df95d028f04ef";a:9:{i:0;s:9:"127.0.0.1";i:1;s:20:"-UM1870-¤£#9mmWV!Ð";i:2;s:5:"62348";i:3;i:1510303474;i:4;s:20:" "Âç]‰b¡Dð›Uõ3jhL´Ê";i:5;s:23:"uTorrentMac/1870(41986)";i:6;s:8:"DE9C3050";i:7;b:1;s:8:"get_parm";a:13:{s:9:"info_hash";s:20:" "Âç]‰b¡Dð›Uõ3jhL´Ê";s:7:"peer_id";s:20:"-UM1870-¤£#9mmWV!Ð";s:4:"port";s:5:"62348";s:8:"uploaded";s:1:"0";s:10:"downloaded";s:1:"0";s:4:"left";s:1:"0";s:7:"corrupt";s:1:"0";s:3:"key";s:8:"DE9C3050";s:5:"event";s:7:"started";s:7:"numwant";s:3:"200";s:7:"compact";s:1:"1";s:10:"no_peer_id";s:1:"1";s:4:"ipv6";s:23:"fe80::44:afa8:dc5d:52d5";}}}
|
Loading…
Reference in New Issue
Block a user