-
Notifications
You must be signed in to change notification settings - Fork 8
/
ip_worker.ts
131 lines (117 loc) · 4.68 KB
/
ip_worker.ts
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
123
124
125
126
127
128
129
130
131
import axios from "axios";
import { wait } from "./action";
import { MockedTorInstance, TorConfig, TorInstance } from "./tor";
import { Proxy, ProxyProvider, base, getUnusedIp } from "./proxy_provider";
export class IpWorker extends ProxyProvider{
private torInstances: { [key: string]: TorInstance } = {};
async createProxy(): Promise<Proxy> {
console.log('🛜 Creating tor instance...');
const config: TorConfig = {
ExitNodes: ['de'],
StrictNodes: true,
};
const temporaryWaitlist: TorInstance[] = [];
const geoIssues = await getGeoIssues();
while (true) {
const tor = await TorInstance.create(config);
// check if instance already exists
const endpoint = tor.info.ip;
console.log(`🤖 Created tor instance ${tor.info.info}`);
if (this.torInstances[endpoint] || geoIssues.includes(endpoint)) {
console.log('🟡 Had issues with this IP before, switching...');
await tor.close();
console.log('🟡 Closed instance:', tor.info.ip);
await wait(200);
continue;
}
this.torInstances[endpoint] = tor;
await registerIp(endpoint);
console.log(`🟢 Checking waitlist... (${temporaryWaitlist.length} instances)`);
const waitListIp = await getUnusedIp(56000, temporaryWaitlist.map(t => t.info.ip));
if (waitListIp) {
console.log(`🟢 Found unused IP in waitlist: ${waitListIp}`);
return tor;
}
const check = await checkIfNewTorInstanceIsUsedBySomeoneElse(endpoint, 55000);
if (check) {
temporaryWaitlist.push(tor);
console.log(`🟡 Someone else is using this IP, but we keep it open for later...`);
continue;
} else {
// try to reserve it
const reserved = await getUnusedIp(55000, [endpoint]);
if (reserved === undefined) {
console.log(`🟡 Could not reserve IP, but we keep it open for later...`);
temporaryWaitlist.push(tor);
continue;
}
}
return tor;
}
}
async prepare(count: number): Promise<void> {
console.log(`🟢 Preparing ${count} connections...`);
const tasks: Promise<any>[] = [];
for (let i = 0; i < count; i++) {
tasks.push(this.createProxy());
}
await Promise.all(tasks);
console.log(`🟢 Prepared ${count} connections.`);
}
async closeProxy(endpoint: string): Promise<void> {
console.log(`🟠 Closing tor instance ${endpoint}`);
const tor = this.torInstances[endpoint];
delete this.torInstances[endpoint];
if (tor) {
await tor.close();
}
}
async getUnusedProxy(age: number, ownIp?: string): Promise<Proxy> {
const available = Object.keys(this.torInstances);
if (ownIp) {
available.push(ownIp);
}
const ip = await getUnusedIp(age, available);
if (ip) {
console.log(`🟢 Got unused IP from manager: ${ip}`);
} else {
console.log(`🆕 No unused IP available, creating new one...`);
}
if (ip !== undefined && ip === ownIp) {
// we can use our own IP
console.log(`🟢 📣 Using own IP ${ip}`);
return new MockedTorInstance(ip);
}
if (ip) {
console.log(`🛜 Reusing tor instance ${ip}`);
return this.torInstances[ip];
}
return await this.createProxy();
}
}
async function registerIp(ip: string): Promise<void> {
const url = base + '/register-ip?ip=' + ip;
await axios.get(url);
}
async function getGeoIssues(): Promise<string[]> {
const url = base;
const res = await axios.get(url);
return [...(res.data.geoIssues ?? []), ...(res.data.tempBlocked ?? [])];
}
async function checkIfNewTorInstanceIsUsedBySomeoneElse(ip: string, unusedSince: number): Promise<boolean> {
const res = await axios.get(base);
const ips = res.data.ips as { [key: string]: string };
// map to as { [key: string]: Date }
const dateMap: { [key: string]: Date } = {};
for (const key in ips) {
dateMap[key] = new Date(ips[key]);
}
const now = new Date();
const usedIp = dateMap[ip];
if (!usedIp) {
return false;
}
const diff = now.getTime() - usedIp.getTime();
return diff < unusedSince;
}
//git clone https://github.com/jannikhst/unblocked-browser.git && cd unblocked-browser && ./builder.sh