Mise à jour de GitLab prévue ce samedi 23 octobre 2021 à partir de 9h00 CET

Commit f231daf6 authored by Éloïs's avatar Éloïs
Browse files

[enh] improving tor config and timeout management

parent 5a57cc78
......@@ -49,10 +49,10 @@ export const ExecuteCommand = () => {
.option('--nostdout', 'Disable stdout printing for `export-bc` command')
.option('--noshuffle', 'Disable peers shuffling for `sync` command')
.option('--proxy-socks <host:port>', 'Use Socks Proxy')
.option('--proxy-tor <host:port>', 'Use Tor Socks Proxy')
.option('--tor-always', 'Pass all outgoing requests through the tor network')
.option('--tor-mixed', 'Pass only ".onion" outgoing requests through the tor network. It\'s the default behavior')
.option('--socks-proxy <host:port>', 'Use Socks Proxy')
.option('--tor-proxy <host:port>', 'Use Tor Socks Proxy')
.option('--reaching-clear-ep <clear|tor|none>', 'method for reaching an clear endpoint')
.option('--force-tor', 'force duniter to contact endpoint tor (if you redirect the traffic to tor yourself)')
.option('--rm-proxies', 'Remove all proxies')
.option('--timeout <milliseconds>', 'Timeout to use when contacting peers', parseInt)
......
......@@ -845,7 +845,7 @@ export class FileDAL {
const savedConf = await this.confDAL.loadConf();
const savedProxyConf = _(savedConf.proxyConf).extend({});
conf = _(savedConf).extend(overrideConf || {});
if (overrideConf.proxyConf !== undefined) {} else {
if (overrideConf.proxiesConf !== undefined) {} else {
conf.proxyConf = _(savedProxyConf).extend({});
}
}
......
......@@ -47,7 +47,7 @@ export interface KeypairConfDTO {
}
export interface NetworkConfDTO {
proxyConf: ProxiesConf|undefined
proxiesConf: ProxiesConf|undefined
nobma: boolean
remoteport: number
remotehost: string|null
......@@ -136,7 +136,7 @@ export class ConfDTO implements CurrencyConfDTO, KeypairConfDTO, NetworkConfDTO,
public homename: string,
public memory: boolean,
public nobma: boolean,
public proxyConf: ProxiesConf|undefined,
public proxiesConf: ProxiesConf|undefined,
public ws2p?: {
privateAccess: boolean
publicAccess: boolean
......
......@@ -94,11 +94,11 @@ export class PeerDTO implements Cloneable {
return bma || {};
}
getWS2P(tor:boolean = false) {
getWS2P(canReachTorEp:boolean, canReachClearEp:boolean) {
let api:{ uuid:string, host:string, port:number, path:string }|null = null
const endpointRegexp = (tor) ? CommonConstants.WS2PTOR_REGEXP:CommonConstants.WS2P_REGEXP
const endpointRegexp = (canReachTorEp) ? CommonConstants.WS2PTOR_REGEXP:CommonConstants.WS2P_REGEXP
for (const ep of this.endpoints) {
if (tor) {
if (canReachTorEp) {
const matches:any = ep.match(CommonConstants.WS2PTOR_REGEXP)
if (matches) {
return {
......@@ -109,13 +109,15 @@ export class PeerDTO implements Cloneable {
}
}
}
const matches:any = !api && ep.match(CommonConstants.WS2P_REGEXP)
if (matches) {
api = {
uuid: matches[1],
host: matches[2] || '',
port: parseInt(matches[3]) || 0,
path: matches[4]
if (canReachClearEp) {
const matches:any = !api && ep.match(CommonConstants.WS2P_REGEXP)
if (matches) {
api = {
uuid: matches[1],
host: matches[2] || '',
port: parseInt(matches[3]) || 0,
path: matches[4]
}
}
}
}
......
const SocksProxyAgent = require('socks-proxy-agent');
const HOST_ONION_REGEX = new RegExp('(\S*?\.onion)$');
const WS_ENDPOINT_ONION_REGEX = new RegExp('(?:wss?:\/\/)?(?:www)?(\S*?\.onion)(\/[-\w]*)*');
const HOST_ONION_REGEX = new RegExp('(?:www\.)?([0-9a-z]{16}?\.onion)$');
const WS_FULL_ADDRESS_ONION_REGEX = new RegExp('^(?:wss?:\/\/)(?:www\.)?([0-9a-z]{16}\.onion)(:[0-9]+)?(\/[-\w]*)*');
export class ProxiesConf {
public proxySocksAddress: string|undefined
public proxyTorAddress: string|undefined
public alwaysUseTor: boolean|undefined
public reachingClearEp: string
public forceTor: boolean
constructor () {
this.proxySocksAddress = undefined
this.proxyTorAddress = undefined
this.alwaysUseTor = undefined
this.reachingClearEp = 'clear'
this.forceTor = false
}
static canReachTorEndpoint(proxyConf: ProxiesConf|undefined):boolean {
return (proxyConf !== undefined && (proxyConf.alwaysUseTor === true || (proxyConf.proxyTorAddress !== undefined) ) )
static canReachClearEndpoint(proxiesConf: ProxiesConf|undefined):boolean {
return (proxiesConf === undefined || proxiesConf.reachingClearEp !== 'none')
}
static httpProxy(url:string, proxyConf: ProxiesConf|undefined):string|undefined {
return ProxiesConf.chooseProxyAgent(url, proxyConf, HOST_ONION_REGEX)
static canReachTorEndpoint(proxiesConf: ProxiesConf|undefined):boolean {
return (proxiesConf !== undefined && (proxiesConf.forceTor || proxiesConf.proxyTorAddress !== undefined) )
}
static wsProxy(address:string, proxyConf: ProxiesConf|undefined):string|undefined {
return ProxiesConf.chooseProxyAgent(address, proxyConf, WS_ENDPOINT_ONION_REGEX)
static httpProxy(url:string, proxiesConf: ProxiesConf|undefined):string|undefined {
return ProxiesConf.chooseProxyAgent(url, proxiesConf, HOST_ONION_REGEX)
}
private static chooseProxyAgent(address:string, proxyConf: ProxiesConf|undefined, onionRegex:RegExp):string|undefined {
if (proxyConf !== undefined) {
if ( proxyConf.proxyTorAddress !== undefined && (proxyConf.alwaysUseTor || address.match(onionRegex)))
{
return proxyConf.proxyTorAddress
}
else if (proxyConf.proxySocksAddress !== undefined) {
return proxyConf.proxySocksAddress
static wsProxy(address:string, proxiesConf: ProxiesConf|undefined):string|undefined {
return ProxiesConf.chooseProxyAgent(address, proxiesConf, WS_FULL_ADDRESS_ONION_REGEX)
}
private static chooseProxyAgent(address:string, proxiesConf: ProxiesConf|undefined, onionRegex:RegExp):string|undefined {
if (proxiesConf !== undefined) {
if (address.match(onionRegex)) {
if (ProxiesConf.canReachTorEndpoint(proxiesConf)) {
return proxiesConf.proxyTorAddress
}
} else {
if (ProxiesConf.canReachClearEndpoint(proxiesConf)) {
if (proxiesConf.reachingClearEp == 'tor') {
return proxiesConf.proxyTorAddress
} else {
return proxiesConf.proxySocksAddress
}
}
}
}
return undefined
......
......@@ -337,7 +337,7 @@ async function upnpConf (noupnp:boolean, logger:any) {
const publicPort = await getAvailablePort(client)
const privatePort = publicPort
const conf:NetworkConfDTO = {
proxyConf: undefined,
proxiesConf: undefined,
nobma: true,
port: privatePort,
ipv4: '127.0.0.1',
......
......@@ -20,7 +20,7 @@ export class WS2PClient {
messageHandler,
new WS2PPubkeyLocalAuth(server.conf.currency , k2, allowKey),
new WS2PPubkeyRemoteAuth(server.conf.currency, k2, allowKey),
ProxiesConf.wsProxy(fullEndpointAddress, server.conf.proxyConf),
ProxiesConf.wsProxy(fullEndpointAddress, server.conf.proxiesConf),
{
connectionTimeout: WS2PConstants.REQUEST_TIMEOUT,
requestTimeout: WS2PConstants.REQUEST_TIMEOUT
......
......@@ -332,12 +332,12 @@ export class WS2PCluster {
const prefered = ((this.server.conf.ws2p && this.server.conf.ws2p.preferedNodes) || []).slice() // Copy
// Our key is also a prefered one, so we connect to our siblings
prefered.push(this.server.conf.pair.pub)
const imCanReachTorEndpoint = ProxiesConf.canReachTorEndpoint(this.server.conf.proxyConf)
const canReachTorEndpoint = ProxiesConf.canReachTorEndpoint(this.server.conf.proxiesConf)
peers.sort((a, b) => {
const aIsPrefered = prefered.indexOf(a.pubkey) !== -1
const bIsPrefered = prefered.indexOf(b.pubkey) !== -1
if (imCanReachTorEndpoint) {
if (canReachTorEndpoint) {
const aAtWs2pTorEnpoint = a.endpoints.filter(function (element) { return element.match(CommonConstants.WS2PTOR_REGEXP); }).length > 0
const bAtWs2pTorEnpoint = b.endpoints.filter(function (element) { return element.match(CommonConstants.WS2PTOR_REGEXP); }).length > 0
......@@ -367,9 +367,10 @@ export class WS2PCluster {
}
})
let i = 0
const canReachClearEndpoint = ProxiesConf.canReachClearEndpoint(this.server.conf.proxiesConf)
while (i < peers.length && this.clientsCount() < this.maxLevel1Size) {
const p = peers[i]
const api = p.getWS2P(imCanReachTorEndpoint)
const api = p.getWS2P(canReachTorEndpoint, canReachClearEndpoint)
if (api) {
try {
// We do not connect to local host
......@@ -396,7 +397,7 @@ export class WS2PCluster {
// New peer
if (data.endpoints) {
const peer = PeerDTO.fromJSONObject(data)
const ws2pEnpoint = peer.getWS2P()
const ws2pEnpoint = peer.getWS2P(ProxiesConf.canReachTorEndpoint(this.server.conf.proxiesConf), ProxiesConf.canReachClearEndpoint(this.server.conf.proxiesConf))
if (ws2pEnpoint) {
// Check if already connected to the pubkey (in any way: server or client)
const connectedPubkeys = this.getConnectedPubkeys()
......
......@@ -278,10 +278,10 @@ export class WS2PConnection {
requestTimeout: REQUEST_TIMEOUT_VALUE
},
expectedPub:string = "") {
if (proxySocksAddress !== undefined) {
if (address.match(WS2PConstants.FULL_ADDRESS_ONION_REGEX)) {
options = {
connectionTimeout: WS2PConstants.PROXY_TIMEOUT,
requestTimeout: WS2PConstants.PROXY_TIMEOUT
connectionTimeout: WS2PConstants.CONNEXION_TOR_TIMEOUT,
requestTimeout: WS2PConstants.REQUEST_TOR_TIMEOUT
}
}
const websocket = (proxySocksAddress !== undefined) ? new ws(address, { agent: SocksProxyAgent("socks://"+proxySocksAddress) }):new ws(address)
......
......@@ -63,16 +63,23 @@ export class WS2PServer extends events.EventEmitter {
}
return await this.shouldAcceptConnection(pub, this.getConnexions().map(c => c.pubkey))
}
let timeout = {
connectionTimeout: WS2PConstants.CONNEXION_TIMEOUT,
requestTimeout: WS2PConstants.REQUEST_TIMEOUT
}
if (this.server.conf.ws2p && this.server.conf.ws2p.remotehost && this.server.conf.ws2p.remotehost.match(WS2PConstants.HOST_ONION_REGEX)) {
timeout = {
connectionTimeout: WS2PConstants.CONNEXION_TOR_TIMEOUT,
requestTimeout: WS2PConstants.REQUEST_TOR_TIMEOUT
}
}
const c = WS2PConnection.newConnectionFromWebSocketServer(
ws,
messageHandler,
new WS2PPubkeyLocalAuth(this.server.conf.currency, key, acceptPubkey),
new WS2PPubkeyRemoteAuth(this.server.conf.currency, key, acceptPubkey),
{
connectionTimeout: WS2PConstants.CONNEXION_TIMEOUT,
requestTimeout: WS2PConstants.REQUEST_TIMEOUT
}
timeout
)
try {
......
......@@ -6,9 +6,10 @@ export const WS2PConstants = {
WS2P_PORTS_END: 20999,
WS2P_UPNP_INTERVAL: 300,
CONNEXION_TIMEOUT: 10000,
REQUEST_TIMEOUT: 10000,
PROXY_TIMEOUT: 30000,
CONNEXION_TIMEOUT: 15000,
REQUEST_TIMEOUT: 15000,
CONNEXION_TOR_TIMEOUT: 30000,
REQUEST_TOR_TIMEOUT: 30000,
RECONNEXION_INTERVAL_IN_SEC: 60 * 10, // 10 minutes
BLOCK_PULLING_INTERVAL: 300 * 2, // 10 minutes
......@@ -38,7 +39,8 @@ export const WS2PConstants = {
+ '(' + CommonConstants.FORMATS.POW_PREFIX + ')'
+ '$'),
HOST_ONION_REGEX: new RegExp('(\S*?\.onion)$'),
HOST_ONION_REGEX: new RegExp('^(?:www\.)?([0-9a-z]{16}\.onion)$'),
FULL_ADDRESS_ONION_REGEX: new RegExp('^(?:wss?:\/\/)(?:www\.)?([0-9a-z]{16}\.onion)(:[0-9]+)?(\/[-\w]*)*'),
HEADS_SPREAD_TIMEOUT: 100 // Wait 100ms before sending a bunch of signed heads
}
\ No newline at end of file
......@@ -449,10 +449,10 @@ function commandLineConf(program:any, conf:any = {}) {
port: program.port,
},
proxies: {
proxySocks: program.proxySocks,
proxyTor: program.proxyTor,
torAlways: program.torAlways,
torMixed: program.torMixed,
proxySocks: program.socksProxy,
proxyTor: program.torProxy,
reachingClearEp: program.reachingClearEp,
forceTor: program.forceTor,
rmProxies: program.rmProxies
},
logs: {
......@@ -467,20 +467,25 @@ function commandLineConf(program:any, conf:any = {}) {
timeout: program.timeout
};
// Declare proxyConf
if (cli.proxies.proxySocks || cli.proxies.proxyTor || cli.proxies.torAlways || cli.proxies.torMixed || cli.proxies.rmProxies) {
conf.proxyConf = new ProxiesConf()
// Declare and update proxiesConf
if (cli.proxies.proxySocks || cli.proxies.proxyTor || cli.proxies.reachingClearEp || cli.proxies.forceTor || cli.proxies.rmProxies) {
conf.proxiesConf = new ProxiesConf()
if (cli.proxies.proxySocks) conf.proxiesConf.proxySocksAddress = cli.proxies.proxySocks;
if (cli.proxies.proxyTor) conf.proxiesConf.proxyTorAddress = cli.proxies.proxyTor;
if (cli.proxies.reachingClearEp) {
switch (cli.proxies.reachingClearEp) {
case 'tor': conf.proxiesConf.reachingClearEp = 'tor'; break;
case 'none': conf.proxiesConf.reachingClearEp = 'none'; break;
}
}
if (cli.proxies.forceTor) conf.proxiesConf.forceTor = true
}
// Update conf
// Update the rest of the conf
if (cli.currency) conf.currency = cli.currency;
if (cli.server.port) conf.port = cli.server.port;
if (cli.cpu) conf.cpu = Math.max(0.01, Math.min(1.0, cli.cpu));
if (cli.prefix) conf.prefix = Math.max(Constants.MIN_PEER_ID, Math.min(Constants.MAX_PEER_ID, cli.prefix));
if (cli.proxies.proxySocks && conf.proxyConf) conf.proxyConf.proxySocksAddress = cli.proxies.proxySocks;
if (cli.proxies.proxyTor && conf.proxyConf) conf.proxyConf.proxyTorAddress = cli.proxies.proxyTor;
if (cli.proxies.torAlways && conf.proxyConf) conf.proxyConf.alwaysUseTor = true;
if (cli.proxies.torMixed && conf.proxyConf) conf.proxyConf.alwaysUseTor = false;
if (cli.logs.http) conf.httplogs = true;
if (cli.logs.nohttp) conf.httplogs = false;
if (cli.isolate) conf.isolate = cli.isolate;
......
......@@ -149,8 +149,7 @@ export class Server extends stream.Duplex implements HookableServer {
logger.debug('Loading conf...');
this.conf = await this.dal.loadConf(this.overrideConf, useDefaultConf)
// Default values
this.conf.proxyConf = this.conf.proxyConf === undefined ? new ProxiesConf() : this.conf.proxyConf
this.conf.proxyConf.alwaysUseTor = this.conf.proxyConf.alwaysUseTor === undefined ? false : this.conf.proxyConf.alwaysUseTor
this.conf.proxiesConf = this.conf.proxiesConf === undefined ? new ProxiesConf() : this.conf.proxiesConf
this.conf.remoteipv6 = this.conf.remoteipv6 === undefined ? this.conf.ipv6 : this.conf.remoteipv6
this.conf.remoteport = this.conf.remoteport === undefined ? this.conf.port : this.conf.remoteport
this.conf.c = this.conf.c === undefined ? constants.CONTRACT.DEFAULT.C : this.conf.c
......
......@@ -13,39 +13,86 @@ describe("Proxies Conf", function() {
// Third conf : always use tor
let proxiesConf3 = new ProxiesConf()
proxiesConf3.proxyTorAddress = "127.0.0.1:9050"
proxiesConf3.alwaysUseTor = true
proxiesConf3.reachingClearEp = 'tor'
// Fourth cont : use classical socks proxy
// Fourth conf : use classical socks proxy
let proxiesConf4 = new ProxiesConf()
proxiesConf4.proxySocksAddress = "127.0.0.1:8888"
// Fifth : use classical socks proxy + use tor proxy only to reach ".onion" endpoints
// Fifth conf : use classical socks proxy + use tor proxy only to reach ".onion" endpoints
let proxiesConf5 = new ProxiesConf()
proxiesConf5.proxySocksAddress = "127.0.0.1:8888"
proxiesConf5.proxyTorAddress = "127.0.0.1:9050"
// Sixth conf : always use tor and contact only tor endpoints
let proxiesConf6 = new ProxiesConf()
proxiesConf6.proxyTorAddress = "127.0.0.1:9050"
proxiesConf6.reachingClearEp = 'none'
// Seventh conf : force duniter to contact endpoint tor (if user redirect the traffic to tor himself)
let proxiesConf7 = new ProxiesConf()
proxiesConf7.forceTor = true;
it('should do not use any sock proxy', () => {
assert.equal(ProxiesConf.wsProxy("ws://3asufnydqmup533h.onion:80", proxiesConf1) === undefined, true)
assert.equal(ProxiesConf.wsProxy("ws://domain.tld:20900", proxiesConf1) === undefined, true)
assert.equal(ProxiesConf.canReachClearEndpoint(proxiesConf1), true)
assert.equal(ProxiesConf.canReachTorEndpoint(proxiesConf1), false)
assert.equal(ProxiesConf.httpProxy("3asufnydqmup533h.onion", proxiesConf1), undefined)
assert.equal(ProxiesConf.httpProxy("domain.tld", proxiesConf1), undefined)
assert.equal(ProxiesConf.wsProxy("ws://3asufnydqmup533h.onion:80", proxiesConf1), undefined)
assert.equal(ProxiesConf.wsProxy("ws://domain.tld:20900", proxiesConf1), undefined)
})
it('should use tor proxy only to reach ".onion" endpoints', () => {
assert.equal(ProxiesConf.wsProxy("ws://3asufnydqmup533h.onion:80", proxiesConf2) === proxiesConf2.proxyTorAddress, true)
assert.equal(ProxiesConf.wsProxy("ws://domain.tld:20900", proxiesConf2) === undefined, true)
assert.equal(ProxiesConf.canReachClearEndpoint(proxiesConf2), true)
assert.equal(ProxiesConf.canReachTorEndpoint(proxiesConf2), true)
assert.equal(ProxiesConf.httpProxy("3asufnydqmup533h.onion", proxiesConf2), proxiesConf2.proxyTorAddress)
assert.equal(ProxiesConf.httpProxy("domain.tld", proxiesConf2), undefined)
assert.equal(ProxiesConf.wsProxy("ws://3asufnydqmup533h.onion:80", proxiesConf2), proxiesConf2.proxyTorAddress)
assert.equal(ProxiesConf.wsProxy("ws://domain.tld:20900", proxiesConf2), undefined)
})
it('should always use tor proxy', () => {
assert.equal(ProxiesConf.wsProxy("ws://3asufnydqmup533h.onion:80", proxiesConf3) === proxiesConf3.proxyTorAddress, true)
assert.equal(ProxiesConf.wsProxy("ws://domain.tld:20900", proxiesConf3) === proxiesConf3.proxyTorAddress, true)
assert.equal(ProxiesConf.canReachClearEndpoint(proxiesConf3), true)
assert.equal(ProxiesConf.canReachTorEndpoint(proxiesConf3), true)
assert.equal(ProxiesConf.httpProxy("3asufnydqmup533h.onion", proxiesConf3), proxiesConf3.proxyTorAddress)
assert.equal(ProxiesConf.httpProxy("domain.tld", proxiesConf3), proxiesConf3.proxyTorAddress)
assert.equal(ProxiesConf.wsProxy("ws://3asufnydqmup533h.onion:80", proxiesConf3), proxiesConf3.proxyTorAddress)
assert.equal(ProxiesConf.wsProxy("ws://domain.tld:20900", proxiesConf3), proxiesConf3.proxyTorAddress)
})
it('should always use classical socks proxy', () => {
assert.equal(ProxiesConf.wsProxy("ws://3asufnydqmup533h.onion:80", proxiesConf4) === proxiesConf4.proxySocksAddress, true)
assert.equal(ProxiesConf.wsProxy("ws://domain.tld:20900", proxiesConf4) === proxiesConf4.proxySocksAddress, true)
assert.equal(ProxiesConf.canReachClearEndpoint(proxiesConf4), true)
assert.equal(ProxiesConf.canReachTorEndpoint(proxiesConf4), false)
assert.equal(ProxiesConf.httpProxy("3asufnydqmup533h.onion", proxiesConf4), undefined)
assert.equal(ProxiesConf.httpProxy("domain.tld", proxiesConf4), proxiesConf4.proxySocksAddress)
assert.equal(ProxiesConf.wsProxy("ws://3asufnydqmup533h.onion:80", proxiesConf4), undefined)
assert.equal(ProxiesConf.wsProxy("ws://domain.tld:20900", proxiesConf4), proxiesConf4.proxySocksAddress)
})
it('should use tor proxy for ".onion" endpoints and classical socks proxy for everyone else', () => {
assert.equal(ProxiesConf.canReachClearEndpoint(proxiesConf5), true)
assert.equal(ProxiesConf.canReachTorEndpoint(proxiesConf5), true)
assert.equal(ProxiesConf.httpProxy("3asufnydqmup533h.onion", proxiesConf5), proxiesConf5.proxyTorAddress)
assert.equal(ProxiesConf.httpProxy("domain.tld", proxiesConf5), proxiesConf5.proxySocksAddress)
assert.equal(ProxiesConf.wsProxy("ws://3asufnydqmup533h.onion:80", proxiesConf5), proxiesConf5.proxyTorAddress)
assert.equal(ProxiesConf.wsProxy("ws://domain.tld:20900", proxiesConf5), proxiesConf5.proxySocksAddress)
})
it('should always use tor proxy and contact only tor endpoints', () => {
assert.equal(ProxiesConf.canReachClearEndpoint(proxiesConf6), false)
assert.equal(ProxiesConf.canReachTorEndpoint(proxiesConf6), true)
assert.equal(ProxiesConf.httpProxy("3asufnydqmup533h.onion", proxiesConf6), proxiesConf6.proxyTorAddress)
assert.equal(ProxiesConf.httpProxy("domain.tld", proxiesConf6), undefined)
assert.equal(ProxiesConf.wsProxy("ws://3asufnydqmup533h.onion:80", proxiesConf6), proxiesConf6.proxyTorAddress)
assert.equal(ProxiesConf.wsProxy("ws://domain.tld:20900", proxiesConf6), undefined)
})
it('should use or tor proxy for ".onion" endpoints and classical socks proxy for everyone else', () => {
assert.equal(ProxiesConf.wsProxy("ws://3asufnydqmup533h.onion:80", proxiesConf5) === proxiesConf5.proxyTorAddress, true)
assert.equal(ProxiesConf.wsProxy("ws://domain.tld:20900", proxiesConf5) === proxiesConf5.proxySocksAddress, true)
it('should never use proxy and contact tor endpoints (user redirect the traffic to tor himself)', () => {
assert.equal(ProxiesConf.canReachClearEndpoint(proxiesConf7), true)
assert.equal(ProxiesConf.canReachTorEndpoint(proxiesConf7), true)
assert.equal(ProxiesConf.httpProxy("3asufnydqmup533h.onion", proxiesConf7), undefined)
assert.equal(ProxiesConf.httpProxy("domain.tld", proxiesConf7), undefined)
assert.equal(ProxiesConf.wsProxy("ws://3asufnydqmup533h.onion:80", proxiesConf7), undefined)
assert.equal(ProxiesConf.wsProxy("ws://domain.tld:20900", proxiesConf7), undefined)
})
});
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment