-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtor.php
122 lines (101 loc) · 4 KB
/
tor.php
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
<?php
if (php_sapi_name() !== 'cli') die("cli only");
$output_dir = dirname(__DIR__) . "/public/tor";
// Relay must be seen within the last 3 hours.
$last_seen_window = 10800;
// Wait between 2 and almost 10 minutes to start at the top of the hour.
$sleep = true;
$sleep_min = 120;
$sleep_max = 590;
if ($sleep) sleep(rand($sleep_min, $sleep_max));
function fetchRelays() {
$url = "https://onionoo.torproject.org/details";
$options = array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_USERAGENT => "lists.fissionrelays.net (admin@fissionrelays.net)"
);
$ch = curl_init($url);
curl_setopt_array($ch, $options);
$response_raw = curl_exec($ch);
$response = json_decode($response_raw, true);
return $response['relays'];
}
function parseAddresses($relays, $last_seen_window) {
$now = time();
$addresses = [
'ipv4' => [],
'ipv6' => [],
'ipv4_exit' => [],
'ipv6_exit' => []
];
foreach ($relays as $relay) {
$relay_addresses = [
'ipv4' => [],
'ipv6' => [],
'ipv4_exit' => [],
'ipv6_exit' => []
];
// Check if still up.
if (strtotime($relay['last_seen']) < $now - $last_seen_window) continue;
$is_exit = in_array("Exit", $relay['flags']);
foreach ($relay['or_addresses'] as $or_address) {
preg_match('/^\[?([0-9a-f:.]*)]?:\d+$/', $or_address, $or_address_matches);
if (count($or_address_matches) === 2) {
$address = $or_address_matches[1];
if (filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
$relay_addresses['ipv4'][] = $address;
if ($is_exit) $relay_addresses['ipv4_exit'] [] = $address;
}
elseif (filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
$relay_addresses['ipv6'][] = $address;
if ($is_exit) $relay_addresses['ipv6_exit'] [] = $address;
}
}
}
if (array_key_exists('exit_addresses', $relay)) {
foreach ($relay['exit_addresses'] as $exit_address) {
if (filter_var($exit_address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) && !in_array($exit_address, $relay_addresses['ipv4_exit'])) {
$relay_addresses['ipv4_exit'][] = $exit_address;
}
elseif (filter_var($exit_address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) && !in_array($exit_address, $relay_addresses['ipv6_exit'])) {
$relay_addresses['ipv6_exit'][] = $exit_address;
}
}
}
$addresses = array_merge_recursive($addresses, $relay_addresses);
}
return $addresses;
}
function sortAddresses($addresses) {
$result = [];
foreach ($addresses as $name => $list) {
$temp = array_unique($addresses[$name]);
natsort($temp);
$result[$name] = $temp;
}
return $result;
}
function writeArrayToFile($filename, $array) {
$f = fopen($filename, 'w');
foreach ($array as $line) {
fwrite($f, "{$line}\n");
}
fclose($f);
}
function writeStringToFile($filename, $string) {
$f = fopen($filename, 'w');
fwrite($f, "{$string}\n");
fclose($f);
}
$relays = fetchRelays();
$addresses = parseAddresses($relays, $last_seen_window);
$addresses = sortAddresses($addresses);
writeArrayToFile("{$output_dir}/relays.txt", array_merge($addresses['ipv4'], $addresses['ipv6']));
writeArrayToFile("{$output_dir}/exits.txt", array_merge($addresses['ipv4_exit'], $addresses['ipv6_exit']));
writeArrayToFile("{$output_dir}/relays-ipv4.txt", $addresses['ipv4']);
writeArrayToFile("{$output_dir}/relays-ipv6.txt", $addresses['ipv6']);
writeArrayToFile("{$output_dir}/exits-ipv4.txt", $addresses['ipv4_exit']);
writeArrayToFile("{$output_dir}/exits-ipv6.txt", $addresses['ipv6_exit']);
writeStringToFile("{$output_dir}/updated.txt", gmdate('Y-m-d H:i:s'));