From a94d5e414eec67fd89b7fdb394a6a312258727df Mon Sep 17 00:00:00 2001 From: librelois <elois@ifee.fr> Date: Sun, 29 Oct 2017 04:43:59 +0100 Subject: [PATCH 01/34] add dependence socks-proxy-agent --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 524a17cfa..97649b314 100644 --- a/package.json +++ b/package.json @@ -92,6 +92,7 @@ "scryptb": "6.0.4", "seedrandom": "^2.4.3", "sha1": "1.1.1", + "socks-proxy-agent": "^3.0.1", "sqlite3": "3.1.4", "tail": "^1.2.1", "tweetnacl": "0.14.3", -- GitLab From 005a8c2db82727021dc520150c23a086a2c04d06 Mon Sep 17 00:00:00 2001 From: librelois <elois@ifee.fr> Date: Sun, 29 Oct 2017 04:44:47 +0100 Subject: [PATCH 02/34] [enh] add Proxy type --- app/lib/proxy.ts | 80 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 app/lib/proxy.ts diff --git a/app/lib/proxy.ts b/app/lib/proxy.ts new file mode 100644 index 000000000..cdcb039dd --- /dev/null +++ b/app/lib/proxy.ts @@ -0,0 +1,80 @@ +const SocksProxyAgent = require('socks-proxy-agent'); + +const constants = require('./constants'); +const WS2PConstants = require('../modules/ws2p/lib/constants'); + +export interface Proxies { + proxySocks: Proxy|undefined, + proxyTor: Proxy|undefined +} + +export interface ProxyConf { + proxySocksAddress: string|undefined, + proxyTorAddress: string|undefined, + alwaysUseTor: boolean|undefined, + proxies: Proxies|undefined +} + +export class Proxy { + private agent: any + + constructor(proxy:string, type:string = "socks") { + if (type === "socks") { + this.agent = SocksProxyAgent("socks://"+proxy) + } + else { + this.agent = undefined + } + } + + getAgent() { + return this.agent; + } + + static defaultConf():ProxyConf { + return { + proxySocksAddress: undefined, + proxyTorAddress: undefined, + alwaysUseTor: undefined, + proxies: undefined + } + } + + static createProxies(proxyConf: ProxyConf|undefined) : Proxies|undefined + { + if (proxyConf !== undefined) { + return { + proxySocks: (proxyConf.proxySocksAddress !== undefined) ? new Proxy(proxyConf.proxySocksAddress, "socks"):undefined, + proxyTor: (proxyConf.proxyTorAddress !== undefined) ? new Proxy(proxyConf.proxyTorAddress, "socks"):undefined + } + } else { + return undefined + } + } + + static httpProxy(url:string, proxyConf: ProxyConf|undefined) { + return Proxy.chooseProxy(url, proxyConf, constants.ONION_ENDPOINT_REGEX) + } + + static wsProxy(address:string, proxyConf: ProxyConf|undefined) { + return Proxy.chooseProxy(address, proxyConf, WS2PConstants.ONION_ENDPOINT_REGEX) + } + + private static chooseProxy(address:string, proxyConf: ProxyConf|undefined, onionRegex:RegExp): Proxy|undefined { + if (proxyConf !== undefined) { + if (proxyConf.proxies === undefined) { + proxyConf.proxies = Proxy.createProxies(proxyConf) + } + if (proxyConf.proxies !== undefined) { + if ( proxyConf.proxies.proxyTor !== undefined && proxyConf.proxies.proxyTor.getAgent() !== undefined && (proxyConf.alwaysUseTor || address.match(onionRegex))) + { + return proxyConf.proxies.proxyTor + } + else if (proxyConf.proxies.proxySocks !== undefined && proxyConf.proxies.proxySocks.getAgent() !== undefined) { + return proxyConf.proxies.proxyTor + } + } + } + return undefined + } +} -- GitLab From cbcfd1b694b8e9763ebfed08681b965da08ee9cf Mon Sep 17 00:00:00 2001 From: librelois <elois@ifee.fr> Date: Sun, 29 Oct 2017 04:47:01 +0100 Subject: [PATCH 03/34] [enh] add cli options for proxies conf --- app/cli.ts | 5 +++++ index.ts | 43 +++++++++++++++++++++++++------------------ server.ts | 5 ++++- 3 files changed, 34 insertions(+), 19 deletions(-) diff --git a/app/cli.ts b/app/cli.ts index cedf3a7fa..bab8e0d65 100644 --- a/app/cli.ts +++ b/app/cli.ts @@ -49,6 +49,11 @@ 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('--timeout <milliseconds>', 'Timeout to use when contacting peers', parseInt) .option('--httplogs', 'Enable HTTP logs') .option('--nohttplogs', 'Disable HTTP logs') diff --git a/index.ts b/index.ts index 3c6b04bc5..b1d842581 100644 --- a/index.ts +++ b/index.ts @@ -8,6 +8,7 @@ import {CrawlerDependency} from "./app/modules/crawler/index" import {BmaDependency} from "./app/modules/bma/index" import {WS2PDependency} from "./app/modules/ws2p/index" import {Constants} from "./app/modules/prover/lib/constants" +import { Proxy } from './app/lib/proxy'; const path = require('path'); const _ = require('underscore'); @@ -437,10 +438,9 @@ class Stack { } } -function commandLineConf(program:any, conf:any = {}) { +function commandLineConf(program:any, conf:ConfDTO = ConfDTO.mock()) { conf = conf || {}; - conf.sync = conf.sync || {}; const cli = { currency: program.currency, cpu: program.cpu, @@ -448,10 +448,11 @@ function commandLineConf(program:any, conf:any = {}) { server: { port: program.port, }, - db: { - mport: program.mport, - mdb: program.mdb, - home: program.home + proxies: { + proxySocks: program.proxySocks, + proxyTor: program.proxyTor, + torAlways: program.torAlways, + torMixed: program.torMixed }, logs: { http: program.httplogs, @@ -465,19 +466,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) { + conf.proxyConf = Proxy.defaultConf() + } + // Update 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.logs.http) conf.httplogs = true; - if (cli.logs.nohttp) conf.httplogs = false; - if (cli.db.mport) conf.mport = cli.db.mport; - if (cli.db.home) conf.home = cli.db.home; - if (cli.db.mdb) conf.mdb = cli.db.mdb; - if (cli.isolate) conf.isolate = cli.isolate; - if (cli.timeout) conf.timeout = cli.timeout; - if (cli.forksize != null) conf.forksize = cli.forksize; + 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; + if (cli.timeout) conf.timeout = cli.timeout; + if (cli.forksize != null) conf.forksize = cli.forksize; return conf; } diff --git a/server.ts b/server.ts index 2f7fbc5c1..f91364b26 100644 --- a/server.ts +++ b/server.ts @@ -24,6 +24,7 @@ import {PeerDTO} from "./app/lib/dto/PeerDTO" import {OtherConstants} from "./app/lib/other_constants" import {WS2PCluster} from "./app/modules/ws2p/lib/WS2PCluster" import {DBBlock} from "./app/lib/db/DBBlock" +import { Proxy } from './app/lib/proxy'; export interface HookableServer { generatorGetJoinData: (...args:any[]) => Promise<any> @@ -72,7 +73,7 @@ export class Server extends stream.Duplex implements HookableServer { TransactionsService:TransactionService private documentFIFO:GlobalFifoPromise - constructor(home:string, memoryOnly:boolean, private overrideConf:any) { + constructor(home:string, memoryOnly:boolean, private overrideConf:ConfDTO) { super({ objectMode: true }) this.home = home; @@ -148,6 +149,8 @@ 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 ? Proxy.defaultConf() : this.conf.proxyConf + this.conf.proxyConf.alwaysUseTor = this.conf.proxyConf.alwaysUseTor === undefined ? false : this.conf.proxyConf.alwaysUseTor 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 -- GitLab From db6f31b29359bc41911741edc8700f1beccb5727 Mon Sep 17 00:00:00 2001 From: librelois <elois@ifee.fr> Date: Sun, 29 Oct 2017 04:47:58 +0100 Subject: [PATCH 04/34] add .onion regex --- app/lib/constants.ts | 3 ++- app/modules/ws2p/lib/constants.ts | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/lib/constants.ts b/app/lib/constants.ts index cac2f7a07..26180e81d 100644 --- a/app/lib/constants.ts +++ b/app/lib/constants.ts @@ -109,7 +109,8 @@ module.exports = { STATUS_INTERVAL: { UPDATE: 2, // Every X blocks MAX: 20 // MAX Y blocks - } + }, + ONION_ENDPOINT_REGEX: new RegExp('(?:https?:\/\/)?(?:www)?(\S*?\.onion)(\/[-\w]*)*') }, PROOF_OF_WORK: { EVALUATION: 1000, diff --git a/app/modules/ws2p/lib/constants.ts b/app/modules/ws2p/lib/constants.ts index ace1fe96e..59ee7386c 100644 --- a/app/modules/ws2p/lib/constants.ts +++ b/app/modules/ws2p/lib/constants.ts @@ -8,6 +8,7 @@ export const WS2PConstants = { CONNEXION_TIMEOUT: 10000, REQUEST_TIMEOUT: 10000, + RECONNEXION_INTERVAL_IN_SEC: 60 * 10, // 10 minutes BLOCK_PULLING_INTERVAL: 300 * 2, // 10 minutes DOCPOOL_PULLING_INTERVAL: 3600 * 4, // 4 hours @@ -36,5 +37,7 @@ export const WS2PConstants = { + '(' + CommonConstants.FORMATS.POW_PREFIX + ')' + '$'), + ONION_ENDPOINT_REGEX: new RegExp('(?:wss?:\/\/)?(?:www)?(\S*?\.onion)(\/[-\w]*)*'), + HEADS_SPREAD_TIMEOUT: 100 // Wait 100ms before sending a bunch of signed heads } \ No newline at end of file -- GitLab From 13823417c0795786bd55b8f2215d0cfbcc48d56f Mon Sep 17 00:00:00 2001 From: librelois <elois@ifee.fr> Date: Sun, 29 Oct 2017 18:03:05 +0100 Subject: [PATCH 05/34] [mod] add custom timeout by proxy --- app/lib/proxy.ts | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/app/lib/proxy.ts b/app/lib/proxy.ts index cdcb039dd..c70dcf423 100644 --- a/app/lib/proxy.ts +++ b/app/lib/proxy.ts @@ -3,6 +3,11 @@ const SocksProxyAgent = require('socks-proxy-agent'); const constants = require('./constants'); const WS2PConstants = require('../modules/ws2p/lib/constants'); +const DEFAULT_PROXY_TIMEOUT:number = 30000 +const TOR_PROXY_TIMEOUT:number = 60000 +const HTTP_ENDPOINT_ONION_REGEX = new RegExp('(?:https?:\/\/)?(?:www)?(\S*?\.onion)(\/[-\w]*)*') +const WS_ENDPOINT_ONION_REGEX = new RegExp('(?:wss?:\/\/)?(?:www)?(\S*?\.onion)(\/[-\w]*)*') + export interface Proxies { proxySocks: Proxy|undefined, proxyTor: Proxy|undefined @@ -17,20 +22,26 @@ export interface ProxyConf { export class Proxy { private agent: any + private timeout:number - constructor(proxy:string, type:string = "socks") { + constructor(proxy:string, type:string = "socks", timeout:number = DEFAULT_PROXY_TIMEOUT) { if (type === "socks") { this.agent = SocksProxyAgent("socks://"+proxy) } else { this.agent = undefined } + this.timeout = timeout } getAgent() { return this.agent; } + getTimeout() { + return this.timeout; + } + static defaultConf():ProxyConf { return { proxySocksAddress: undefined, @@ -45,7 +56,7 @@ export class Proxy { if (proxyConf !== undefined) { return { proxySocks: (proxyConf.proxySocksAddress !== undefined) ? new Proxy(proxyConf.proxySocksAddress, "socks"):undefined, - proxyTor: (proxyConf.proxyTorAddress !== undefined) ? new Proxy(proxyConf.proxyTorAddress, "socks"):undefined + proxyTor: (proxyConf.proxyTorAddress !== undefined) ? new Proxy(proxyConf.proxyTorAddress, "socks", TOR_PROXY_TIMEOUT):undefined } } else { return undefined @@ -53,25 +64,25 @@ export class Proxy { } static httpProxy(url:string, proxyConf: ProxyConf|undefined) { - return Proxy.chooseProxy(url, proxyConf, constants.ONION_ENDPOINT_REGEX) + return Proxy.chooseProxy(url, proxyConf, HTTP_ENDPOINT_ONION_REGEX) } - static wsProxy(address:string, proxyConf: ProxyConf|undefined) { - return Proxy.chooseProxy(address, proxyConf, WS2PConstants.ONION_ENDPOINT_REGEX) + static wsProxy(address:string, proxyConf: ProxyConf|undefined, mySelf:boolean = false) { + return Proxy.chooseProxy(address, proxyConf, WS_ENDPOINT_ONION_REGEX, mySelf) } - private static chooseProxy(address:string, proxyConf: ProxyConf|undefined, onionRegex:RegExp): Proxy|undefined { + private static chooseProxy(address:string, proxyConf: ProxyConf|undefined, onionRegex:RegExp, mySelf:boolean = false): Proxy|undefined { if (proxyConf !== undefined) { if (proxyConf.proxies === undefined) { proxyConf.proxies = Proxy.createProxies(proxyConf) } if (proxyConf.proxies !== undefined) { - if ( proxyConf.proxies.proxyTor !== undefined && proxyConf.proxies.proxyTor.getAgent() !== undefined && (proxyConf.alwaysUseTor || address.match(onionRegex))) + if ( proxyConf.proxies.proxyTor !== undefined && proxyConf.proxies.proxyTor.getAgent() !== undefined && (proxyConf.alwaysUseTor || address.match(onionRegex)) && !mySelf ) { return proxyConf.proxies.proxyTor } else if (proxyConf.proxies.proxySocks !== undefined && proxyConf.proxies.proxySocks.getAgent() !== undefined) { - return proxyConf.proxies.proxyTor + return proxyConf.proxies.proxySocks } } } -- GitLab From 4e0c3bcb7e4d6ed771ee3a12ce36d0376be46633 Mon Sep 17 00:00:00 2001 From: librelois <elois@ifee.fr> Date: Sun, 29 Oct 2017 18:03:52 +0100 Subject: [PATCH 06/34] move onion regex --- app/modules/ws2p/lib/constants.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/modules/ws2p/lib/constants.ts b/app/modules/ws2p/lib/constants.ts index 59ee7386c..ba78a6f1a 100644 --- a/app/modules/ws2p/lib/constants.ts +++ b/app/modules/ws2p/lib/constants.ts @@ -37,7 +37,5 @@ export const WS2PConstants = { + '(' + CommonConstants.FORMATS.POW_PREFIX + ')' + '$'), - ONION_ENDPOINT_REGEX: new RegExp('(?:wss?:\/\/)?(?:www)?(\S*?\.onion)(\/[-\w]*)*'), - HEADS_SPREAD_TIMEOUT: 100 // Wait 100ms before sending a bunch of signed heads } \ No newline at end of file -- GitLab From 6b022bce45a6dca72f7c0cb1d30ac0790a6ce397 Mon Sep 17 00:00:00 2001 From: librelois <elois@ifee.fr> Date: Sun, 29 Oct 2017 18:04:29 +0100 Subject: [PATCH 07/34] [enh] sock proxy for ws2p private --- app/modules/ws2p/lib/WS2PClient.ts | 10 +++++++++- app/modules/ws2p/lib/WS2PCluster.ts | 4 ++-- app/modules/ws2p/lib/WS2PConnection.ts | 12 ++++++++++-- test/integration/ws2p_connection.ts | 8 ++++---- 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/app/modules/ws2p/lib/WS2PClient.ts b/app/modules/ws2p/lib/WS2PClient.ts index 34710012a..0ff0b6178 100644 --- a/app/modules/ws2p/lib/WS2PClient.ts +++ b/app/modules/ws2p/lib/WS2PClient.ts @@ -1,3 +1,4 @@ +import { WS2PCluster } from './WS2PCluster'; import {Server} from "../../../../server" import {WS2PConnection, WS2PPubkeyLocalAuth, WS2PPubkeyRemoteAuth} from "./WS2PConnection" import {Key} from "../../../lib/common-libs/crypto/keyring" @@ -5,18 +6,25 @@ import {WS2PMessageHandler} from "./impl/WS2PMessageHandler" import {WS2PConstants} from "./constants" import {WS2PStreamer} from "./WS2PStreamer" import {WS2PSingleWriteStream} from "./WS2PSingleWriteStream" +import { Proxies, ProxyConf, Proxy } from '../../../lib/proxy'; +import { server } from '../../../../test/integration/tools/toolbox'; export class WS2PClient { private constructor(public connection:WS2PConnection) {} - static async connectTo(server:Server, fullEndpointAddress:string, messageHandler:WS2PMessageHandler, expectedPub:string, allowKey:(pub:string)=>Promise<boolean> ) { + static async connectTo(server:Server, fullEndpointAddress:string, uuid:string, messageHandler:WS2PMessageHandler, expectedPub:string, allowKey:(pub:string)=>Promise<boolean> ) { const k2 = new Key(server.conf.pair.pub, server.conf.pair.sec) + let mySelf = false; + if (server.conf.ws2p && server.conf.ws2p.uuid === uuid) { + let mySelf = true; + } const c = WS2PConnection.newConnectionToAddress( fullEndpointAddress, messageHandler, new WS2PPubkeyLocalAuth(server.conf.currency , k2, allowKey), new WS2PPubkeyRemoteAuth(server.conf.currency, k2, allowKey), + Proxy.wsProxy(fullEndpointAddress, server.conf.proxyConf, mySelf), { connectionTimeout: WS2PConstants.REQUEST_TIMEOUT, requestTimeout: WS2PConstants.REQUEST_TIMEOUT diff --git a/app/modules/ws2p/lib/WS2PCluster.ts b/app/modules/ws2p/lib/WS2PCluster.ts index 7f015e75e..caa75b678 100644 --- a/app/modules/ws2p/lib/WS2PCluster.ts +++ b/app/modules/ws2p/lib/WS2PCluster.ts @@ -293,7 +293,7 @@ export class WS2PCluster { let pub = "--------" try { const fullEndpointAddress = WS2PCluster.getFullAddress(host, port, path) - const ws2pc = await WS2PClient.connectTo(this.server, fullEndpointAddress, messageHandler, expectedPub, (pub:string) => { + const ws2pc = await WS2PClient.connectTo(this.server, fullEndpointAddress, ws2pEndpointUUID, messageHandler, expectedPub, (pub:string) => { const connectedPubkeys = this.getConnectedPubkeys() return this.acceptPubkey(expectedPub, connectedPubkeys, () => this.clientsCount(), this.maxLevel1Size, (this.server.conf.ws2p && this.server.conf.ws2p.preferedNodes || []), ws2pEndpointUUID) }) @@ -626,7 +626,7 @@ export class WS2PCluster { async startCrawling(waitConnection = false) { // For connectivity - this.reconnectionInteval = setInterval(() => this.server.push({ ws2p: 'disconnected' }), 1000 * 60 * 10) + this.reconnectionInteval = setInterval(() => this.server.push({ ws2p: 'disconnected' }), 1000 * WS2PConstants.RECONNEXION_INTERVAL_IN_SEC) // For blocks if (this.syncBlockInterval) clearInterval(this.syncBlockInterval); diff --git a/app/modules/ws2p/lib/WS2PConnection.ts b/app/modules/ws2p/lib/WS2PConnection.ts index e97bde407..7d0b96a02 100644 --- a/app/modules/ws2p/lib/WS2PConnection.ts +++ b/app/modules/ws2p/lib/WS2PConnection.ts @@ -7,6 +7,7 @@ import {MembershipDTO} from "../../../lib/dto/MembershipDTO" import {TransactionDTO} from "../../../lib/dto/TransactionDTO" import {PeerDTO} from "../../../lib/dto/PeerDTO" import {WS2PConstants} from "./constants" +import { Proxy } from '../../../lib/proxy'; const ws = require('ws') const nuuid = require('node-uuid'); const logger = require('../../../lib/logger').NewLogger('ws2p') @@ -267,15 +268,22 @@ export class WS2PConnection { messageHandler:WS2PMessageHandler, localAuth:WS2PLocalAuth, remoteAuth:WS2PRemoteAuth, + proxy:Proxy|undefined = undefined, options:{ - connectionTimeout:number + connectionTimeout:number, requestTimeout:number } = { connectionTimeout: REQUEST_TIMEOUT_VALUE, requestTimeout: REQUEST_TIMEOUT_VALUE }, expectedPub:string = "") { - const websocket = new ws(address) + if (proxy !== undefined) { + options = { + connectionTimeout: proxy.getTimeout(), + requestTimeout: proxy.getTimeout() + } + } + const websocket = (proxy !== undefined) ? new ws(address, { agent: proxy.getAgent() }):new ws(address) const onWsOpened:Promise<void> = new Promise(res => { websocket.on('open', () => res()) }) diff --git a/test/integration/ws2p_connection.ts b/test/integration/ws2p_connection.ts index 894c2ac29..c84d9a42e 100644 --- a/test/integration/ws2p_connection.ts +++ b/test/integration/ws2p_connection.ts @@ -95,7 +95,7 @@ describe('WS2P', () => { it('should refuse the connection if the server does not answer', async () => { const keypair = new Key('HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP') - const ws2p = WS2PConnection.newConnectionToAddress('ws://localhost:20903', new WS2PMutedHandler(), new WS2PPubkeyLocalAuth(gtest, keypair), new WS2PPubkeyRemoteAuth(gtest, keypair), { + const ws2p = WS2PConnection.newConnectionToAddress('ws://localhost:20903', new WS2PMutedHandler(), new WS2PPubkeyLocalAuth(gtest, keypair), new WS2PPubkeyRemoteAuth(gtest, keypair), undefined, { connectionTimeout: 100, requestTimeout: 100 }) @@ -104,7 +104,7 @@ describe('WS2P', () => { it('should refuse the connection if the server answers with a wrong signature', async () => { const keypair = new Key('HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP') - const ws2p = WS2PConnection.newConnectionToAddress('ws://localhost:20903', new WS2PMutedHandler(), new WS2PPubkeyLocalAuth(gtest, keypair), new WS2PPubkeyRemoteAuth(gtest, keypair), { + const ws2p = WS2PConnection.newConnectionToAddress('ws://localhost:20903', new WS2PMutedHandler(), new WS2PPubkeyLocalAuth(gtest, keypair), new WS2PPubkeyRemoteAuth(gtest, keypair), undefined, { connectionTimeout: 100, requestTimeout: 100 }) @@ -113,7 +113,7 @@ describe('WS2P', () => { it('should refuse the connection if the server refuses our signature', async () => { const keypair = new Key('HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP') - const ws2p = WS2PConnection.newConnectionToAddress('ws://localhost:20903', new WS2PMutedHandler(), new WS2PPubkeyLocalAuth(gtest, keypair), new WS2PPubkeyRemoteAuth(gtest, keypair), { + const ws2p = WS2PConnection.newConnectionToAddress('ws://localhost:20903', new WS2PMutedHandler(), new WS2PPubkeyLocalAuth(gtest, keypair), new WS2PPubkeyRemoteAuth(gtest, keypair), undefined, { connectionTimeout: 100, requestTimeout: 100 }) @@ -123,7 +123,7 @@ describe('WS2P', () => { it('should accept the connection if the server answers with a good signature', async () => { const keypair = new Key('HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP') - const ws2p = WS2PConnection.newConnectionToAddress('ws://localhost:20903', new WS2PMutedHandler(), new WS2PPubkeyLocalAuth(gtest, keypair), new WS2PNoRemoteAuth(), { + const ws2p = WS2PConnection.newConnectionToAddress('ws://localhost:20903', new WS2PMutedHandler(), new WS2PPubkeyLocalAuth(gtest, keypair), new WS2PNoRemoteAuth(), undefined, { connectionTimeout: 1000, requestTimeout: 1000 }) -- GitLab From ffa0156e8481b08f4149b1dc111be41b45251ea5 Mon Sep 17 00:00:00 2001 From: librelois <elois@ifee.fr> Date: Sun, 29 Oct 2017 18:26:16 +0100 Subject: [PATCH 08/34] [fix] repair test (typage) --- test/integration/tools/toolbox.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/tools/toolbox.ts b/test/integration/tools/toolbox.ts index fcf1e9670..85c317dff 100644 --- a/test/integration/tools/toolbox.ts +++ b/test/integration/tools/toolbox.ts @@ -170,7 +170,7 @@ export const fakeSyncServer = async (readBlocksMethod:any, readParticularBlockMe processRequest: () => { /* Does nothing */ } }; - const fakeServer = await Network.createServersAndListen("Fake Duniter Server", new Server("", true, {}), [{ + const fakeServer = await Network.createServersAndListen("Fake Duniter Server", new Server("", true, ConfDTO.mock()), [{ ip: host, port: port }], NO_HTTP_LOGS, logger, NO_STATIC_PATH, (app:any, httpMethods:any) => { -- GitLab From 33ed8c138de076201163f44c08c57561ad0e8ced Mon Sep 17 00:00:00 2001 From: librelois <elois@ifee.fr> Date: Sun, 29 Oct 2017 18:37:33 +0100 Subject: [PATCH 09/34] add proxyConf --- app/lib/dto/ConfDTO.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/lib/dto/ConfDTO.ts b/app/lib/dto/ConfDTO.ts index 361eb49c9..cdedf5037 100644 --- a/app/lib/dto/ConfDTO.ts +++ b/app/lib/dto/ConfDTO.ts @@ -1,4 +1,5 @@ import {CommonConstants} from "../common-libs/constants" +import { Proxy, ProxyConf } from '../proxy'; const _ = require('underscore'); const constants = require('../constants'); @@ -46,6 +47,7 @@ export interface KeypairConfDTO { } export interface NetworkConfDTO { + proxyConf: ProxyConf|undefined nobma: boolean remoteport: number remotehost: string|null @@ -134,6 +136,7 @@ export class ConfDTO implements CurrencyConfDTO, KeypairConfDTO, NetworkConfDTO, public homename: string, public memory: boolean, public nobma: boolean, + public proxyConf: ProxyConf|undefined, public ws2p?: { privateAccess: boolean publicAccess: boolean @@ -152,7 +155,7 @@ export class ConfDTO implements CurrencyConfDTO, KeypairConfDTO, NetworkConfDTO, ) {} static mock() { - return new ConfDTO("", "", [], [], 0, 0, 0.6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, false, 0, false, 0, 0, 0, 0, 0, { pub:'', sec:'' }, null, "", "", 0, "", "", "", 0, "", "", null, false, "", true, true) + return new ConfDTO("", "", [], [], 0, 0, 0.6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, false, 0, false, 0, 0, 0, 0, 0, { pub:'', sec:'' }, null, "", "", 0, "", "", "", 0, "", "", null, false, "", true, true, undefined) } static defaultConf() { -- GitLab From 7dd71740114ea4f8c27e03c9974008a7c4d0f039 Mon Sep 17 00:00:00 2001 From: librelois <elois@ifee.fr> Date: Sun, 29 Oct 2017 18:43:40 +0100 Subject: [PATCH 10/34] add proxyConf (just for respect typage) --- app/modules/bma/lib/network.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/app/modules/bma/lib/network.ts b/app/modules/bma/lib/network.ts index 33b994afe..ae3459eb9 100644 --- a/app/modules/bma/lib/network.ts +++ b/app/modules/bma/lib/network.ts @@ -337,6 +337,7 @@ async function upnpConf (noupnp:boolean, logger:any) { const publicPort = await getAvailablePort(client) const privatePort = publicPort const conf:NetworkConfDTO = { + proxyConf: undefined, nobma: true, port: privatePort, ipv4: '127.0.0.1', -- GitLab From 927da9f83889f9906a611a79b790dc7a85006a7f Mon Sep 17 00:00:00 2001 From: librelois <elois@ifee.fr> Date: Sun, 29 Oct 2017 18:45:26 +0100 Subject: [PATCH 11/34] add command --rm-proxies --- app/cli.ts | 1 + index.ts | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/cli.ts b/app/cli.ts index bab8e0d65..187022269 100644 --- a/app/cli.ts +++ b/app/cli.ts @@ -53,6 +53,7 @@ export const ExecuteCommand = () => { .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('--rm-proxies', 'Remove all proxies') .option('--timeout <milliseconds>', 'Timeout to use when contacting peers', parseInt) .option('--httplogs', 'Enable HTTP logs') diff --git a/index.ts b/index.ts index b1d842581..60adec394 100644 --- a/index.ts +++ b/index.ts @@ -452,7 +452,8 @@ function commandLineConf(program:any, conf:ConfDTO = ConfDTO.mock()) { proxySocks: program.proxySocks, proxyTor: program.proxyTor, torAlways: program.torAlways, - torMixed: program.torMixed + torMixed: program.torMixed, + rmProxies: program.rmProxies }, logs: { http: program.httplogs, @@ -467,7 +468,7 @@ function commandLineConf(program:any, conf:ConfDTO = ConfDTO.mock()) { }; // Declare proxyConf - if (cli.proxies.proxySocks || cli.proxies.proxyTor || cli.proxies.torAlways || cli.proxies.torMixed) { + if (cli.proxies.proxySocks || cli.proxies.proxyTor || cli.proxies.torAlways || cli.proxies.torMixed || cli.proxies.rmProxies) { conf.proxyConf = Proxy.defaultConf() } -- GitLab From d125e080a10e8cf5d2cf010d70b59eb5f94f9316 Mon Sep 17 00:00:00 2001 From: librelois <elois@ifee.fr> Date: Sun, 29 Oct 2017 21:31:26 +0100 Subject: [PATCH 12/34] [fix] persistent proxyConf --- app/lib/dal/fileDAL.ts | 5 +++++ index.ts | 2 +- server.ts | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/app/lib/dal/fileDAL.ts b/app/lib/dal/fileDAL.ts index 6281d83fb..3eec9daed 100644 --- a/app/lib/dal/fileDAL.ts +++ b/app/lib/dal/fileDAL.ts @@ -15,6 +15,7 @@ import {DBBlock} from "../db/DBBlock" import {DBMembership} from "./sqliteDAL/MembershipDAL" import {MerkleDTO} from "../dto/MerkleDTO" import {CommonConstants} from "../common-libs/constants" +import { ProxyConf } from '../proxy'; const fs = require('fs') const path = require('path') @@ -842,7 +843,11 @@ export class FileDAL { let conf = ConfDTO.complete(overrideConf || {}); if (!defaultConf) { const savedConf = await this.confDAL.loadConf(); + const savedProxyConf = _(savedConf.proxyConf).extend({}); conf = _(savedConf).extend(overrideConf || {}); + if (overrideConf.proxyConf !== undefined) {} else { + conf.proxyConf = _(savedProxyConf).extend({}); + } } if (this.loadConfHook) { await this.loadConfHook(conf) diff --git a/index.ts b/index.ts index 60adec394..ada66317c 100644 --- a/index.ts +++ b/index.ts @@ -438,7 +438,7 @@ class Stack { } } -function commandLineConf(program:any, conf:ConfDTO = ConfDTO.mock()) { +function commandLineConf(program:any, conf:any = {}) { conf = conf || {}; const cli = { diff --git a/server.ts b/server.ts index f91364b26..89772dbf0 100644 --- a/server.ts +++ b/server.ts @@ -73,7 +73,7 @@ export class Server extends stream.Duplex implements HookableServer { TransactionsService:TransactionService private documentFIFO:GlobalFifoPromise - constructor(home:string, memoryOnly:boolean, private overrideConf:ConfDTO) { + constructor(home:string, memoryOnly:boolean, private overrideConf:any) { super({ objectMode: true }) this.home = home; -- GitLab From 8db926f94186ac63432c0ab8cab7e24c93769966 Mon Sep 17 00:00:00 2001 From: librelois <elois@ifee.fr> Date: Sun, 29 Oct 2017 22:56:41 +0100 Subject: [PATCH 13/34] [enh] WS2PTOR endpoint --- app/lib/common-libs/constants.ts | 2 ++ app/lib/dal/fileDAL.ts | 2 +- app/lib/dto/PeerDTO.ts | 3 ++- app/modules/ws2p/index.ts | 30 ++++++++++++++--------- app/modules/ws2p/lib/WS2PCluster.ts | 37 +++++++++++++++++++++++------ app/modules/ws2p/lib/constants.ts | 2 ++ 6 files changed, 56 insertions(+), 20 deletions(-) diff --git a/app/lib/common-libs/constants.ts b/app/lib/common-libs/constants.ts index 14465aade..a49a01138 100644 --- a/app/lib/common-libs/constants.ts +++ b/app/lib/common-libs/constants.ts @@ -32,6 +32,7 @@ const CONDITIONS = "(&&|\\|\\|| |[()]|(SIG\\(" + PUBKEY + "\\)|(XHX\\([A-F0-9] const BMA_REGEXP = /^BASIC_MERKLED_API( ([a-z_][a-z0-9-_.]*))?( ([0-9.]+))?( ([0-9a-f:]+))?( ([0-9]+))$/ const WS2P_REGEXP = /^WS2P ([a-f0-9]{8}) ([a-z_][a-z0-9-_.]*|[0-9.]+|[0-9a-f:]+) ([0-9]+)(?: (.+))?$/ +const WS2PTOR_REGEXP = /^WS2PTOR ([a-f0-9]{8}) ([a-z_][a-z0-9-_.]*|[0-9.]+|[0-9a-f:]+).onion ([0-9]+)(?: (.+))?$/ const IPV4_REGEXP = /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/; const IPV6_REGEXP = /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(([0-9A-Fa-f]{1,4}:){0,5}:((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(::([0-9A-Fa-f]{1,4}:){0,5}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/; @@ -90,6 +91,7 @@ export const CommonConstants = { BMA_REGEXP, WS2P_REGEXP, + WS2PTOR_REGEXP, IPV4_REGEXP, IPV6_REGEXP, PUBLIC_KEY: exact(PUBKEY), diff --git a/app/lib/dal/fileDAL.ts b/app/lib/dal/fileDAL.ts index 3eec9daed..9e5865182 100644 --- a/app/lib/dal/fileDAL.ts +++ b/app/lib/dal/fileDAL.ts @@ -143,7 +143,7 @@ export class FileDAL { } async getWS2Peers() { - return this.peerDAL.getPeersWithEndpointsLike('WS2P ') + return this.peerDAL.getPeersWithEndpointsLike('WS2P ').concat(this.peerDAL.getPeersWithEndpointsLike('WS2PTOR ')) } async getBlock(number:number) { diff --git a/app/lib/dto/PeerDTO.ts b/app/lib/dto/PeerDTO.ts index 738c54063..e2ffcf333 100644 --- a/app/lib/dto/PeerDTO.ts +++ b/app/lib/dto/PeerDTO.ts @@ -94,8 +94,9 @@ export class PeerDTO implements Cloneable { return bma || {}; } - getWS2P() { + getWS2P(tor:boolean = false) { let api:{ uuid:string, host:string, port:number, path:string }|null = null + const endpointRegexp = (tor) ? CommonConstants.WS2PTOR_REGEXP:CommonConstants.WS2P_REGEXP for (const ep of this.endpoints) { const matches:any = !api && ep.match(CommonConstants.WS2P_REGEXP) if (matches) { diff --git a/app/modules/ws2p/index.ts b/app/modules/ws2p/index.ts index 53e311b02..6a3dd8fbc 100644 --- a/app/modules/ws2p/index.ts +++ b/app/modules/ws2p/index.ts @@ -1,7 +1,8 @@ "use strict"; +import { WS2PConstants } from './lib/constants'; import {ConfDTO, WS2PConfDTO} from "../../lib/dto/ConfDTO" import {Server} from "../../../server" -import * as stream from "stream" +import * as stream from 'stream'; import {WS2PCluster} from "./lib/WS2PCluster" import {WS2PUpnp} from "./lib/ws2p-upnp" import {CommonConstants} from "../../lib/common-libs/constants" @@ -242,22 +243,29 @@ export class WS2PAPI extends stream.Transform { // If WS2P defined and enabled if (this.server.conf.ws2p !== undefined && (this.server.conf.ws2p.publicAccess || this.server.conf.ws2p.privateAccess)) { + let endpointType = "WS2P" if (this.server.conf.upnp && this.upnpAPI) { const config = this.upnpAPI.getCurrentConfig() - return !config ? '' : ['WS2P', this.server.conf.ws2p.uuid, config.remotehost, config.port].join(' ') + if (config) { + if (config.remotehost.match(WS2PConstants.HOST_ONION_REGEX)) { endpointType += "TOR"; } + return [endpointType, this.server.conf.ws2p.uuid, config.remotehost, config.port].join(' ') + } else { + return '' + } } else if (this.server.conf.ws2p.uuid && this.server.conf.ws2p.remotehost && this.server.conf.ws2p.remoteport) { - let ep = ['WS2P', - this.server.conf.ws2p.uuid, - this.server.conf.ws2p.remotehost, - this.server.conf.ws2p.remoteport - ].join(' ') - if (this.server.conf.ws2p.remotepath) { - ep += ` ${this.server.conf.ws2p.remotepath}` - } - return ep + if (this.server.conf.ws2p.remotehost.match(WS2PConstants.HOST_ONION_REGEX)) { endpointType += "TOR"; } + let ep = [endpointType, + this.server.conf.ws2p.uuid, + this.server.conf.ws2p.remotehost, + this.server.conf.ws2p.remoteport + ].join(' ') + if (this.server.conf.ws2p.remotepath) { + ep += ` ${this.server.conf.ws2p.remotepath}` + } + return ep } } return '' diff --git a/app/modules/ws2p/lib/WS2PCluster.ts b/app/modules/ws2p/lib/WS2PCluster.ts index caa75b678..5282a1090 100644 --- a/app/modules/ws2p/lib/WS2PCluster.ts +++ b/app/modules/ws2p/lib/WS2PCluster.ts @@ -13,7 +13,7 @@ import {OtherConstants} from "../../../lib/other_constants" import {Key, verify} from "../../../lib/common-libs/crypto/keyring" import {WS2PServerMessageHandler} from "./interface/WS2PServerMessageHandler" import {WS2PMessageHandler} from "./impl/WS2PMessageHandler" -import { CommonConstants } from "../../../lib/common-libs/constants"; +import { CommonConstants } from '../../../lib/common-libs/constants'; import { Package } from "../../../lib/common/package"; import { Constants } from "../../prover/lib/constants"; @@ -330,21 +330,44 @@ 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 imTorPeer = this.server.conf.proxyConf && this.server.conf.proxyConf.proxies && this.server.conf.proxyConf.proxies.proxyTor peers.sort((a, b) => { const aIsPrefered = prefered.indexOf(a.pubkey) !== -1 const bIsPrefered = prefered.indexOf(b.pubkey) !== -1 - if ((aIsPrefered && bIsPrefered) || (!aIsPrefered && !bIsPrefered)) { - return 0 - } else if (aIsPrefered) { - return -1 + + if (imTorPeer) { + 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 + + if ( (aAtWs2pTorEnpoint && bAtWs2pTorEnpoint) || (!aAtWs2pTorEnpoint && !bAtWs2pTorEnpoint) ) { + if ((aIsPrefered && bIsPrefered) || (!aIsPrefered && !bIsPrefered)) { + return 0 + } else if (aIsPrefered) { + return -1 + } else { + return 1 + } + } else { + if (aAtWs2pTorEnpoint) { + return -1 + } else { + return 1 + } + } } else { - return 1 + if ((aIsPrefered && bIsPrefered) || (!aIsPrefered && !bIsPrefered)) { + return 0 + } else if (aIsPrefered) { + return -1 + } else { + return 1 + } } }) let i = 0 while (i < peers.length && this.clientsCount() < this.maxLevel1Size) { const p = peers[i] - const api = p.getWS2P() + const api = p.getWS2P(imTorPeer !== undefined) if (api) { try { await this.connectToRemoteWS(api.host, api.port, api.path, this.messageHandler, p.pubkey, api.uuid) diff --git a/app/modules/ws2p/lib/constants.ts b/app/modules/ws2p/lib/constants.ts index ba78a6f1a..92c69becc 100644 --- a/app/modules/ws2p/lib/constants.ts +++ b/app/modules/ws2p/lib/constants.ts @@ -37,5 +37,7 @@ export const WS2PConstants = { + '(' + CommonConstants.FORMATS.POW_PREFIX + ')' + '$'), + HOST_ONION_REGEX: new RegExp('(\S*?\.onion)$'), + HEADS_SPREAD_TIMEOUT: 100 // Wait 100ms before sending a bunch of signed heads } \ No newline at end of file -- GitLab From 291f32bcd60b829f17a113e3584ad5c3842af6b9 Mon Sep 17 00:00:00 2001 From: librelois <elois@ifee.fr> Date: Mon, 30 Oct 2017 01:14:22 +0100 Subject: [PATCH 14/34] [fix] get WS2P peers --- app/lib/dal/fileDAL.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/lib/dal/fileDAL.ts b/app/lib/dal/fileDAL.ts index 9e5865182..1298d6a12 100644 --- a/app/lib/dal/fileDAL.ts +++ b/app/lib/dal/fileDAL.ts @@ -143,7 +143,7 @@ export class FileDAL { } async getWS2Peers() { - return this.peerDAL.getPeersWithEndpointsLike('WS2P ').concat(this.peerDAL.getPeersWithEndpointsLike('WS2PTOR ')) + return this.peerDAL.getPeersWithEndpointsLike('WS2P') } async getBlock(number:number) { -- GitLab From 02883fa265f26156f2047742a33afc35d5961f85 Mon Sep 17 00:00:00 2001 From: librelois <elois@ifee.fr> Date: Mon, 30 Oct 2017 18:08:07 +0100 Subject: [PATCH 15/34] getWS2P apply tor regex --- app/lib/common-libs/constants.ts | 2 +- app/lib/dto/PeerDTO.ts | 2 +- app/lib/proxy.ts | 24 +++++++++++++----------- app/modules/ws2p/lib/WS2PCluster.ts | 14 ++++++++------ app/modules/ws2p/lib/WS2PConnection.ts | 6 +++--- 5 files changed, 26 insertions(+), 22 deletions(-) diff --git a/app/lib/common-libs/constants.ts b/app/lib/common-libs/constants.ts index a49a01138..e44639342 100644 --- a/app/lib/common-libs/constants.ts +++ b/app/lib/common-libs/constants.ts @@ -32,7 +32,7 @@ const CONDITIONS = "(&&|\\|\\|| |[()]|(SIG\\(" + PUBKEY + "\\)|(XHX\\([A-F0-9] const BMA_REGEXP = /^BASIC_MERKLED_API( ([a-z_][a-z0-9-_.]*))?( ([0-9.]+))?( ([0-9a-f:]+))?( ([0-9]+))$/ const WS2P_REGEXP = /^WS2P ([a-f0-9]{8}) ([a-z_][a-z0-9-_.]*|[0-9.]+|[0-9a-f:]+) ([0-9]+)(?: (.+))?$/ -const WS2PTOR_REGEXP = /^WS2PTOR ([a-f0-9]{8}) ([a-z_][a-z0-9-_.]*|[0-9.]+|[0-9a-f:]+).onion ([0-9]+)(?: (.+))?$/ +const WS2PTOR_REGEXP = /^WS2PTOR ([a-f0-9]{8}) ([a-z0-9-_.]*|[0-9.]+|[0-9a-f:]+.onion) ([0-9]+)(?: (.+))?$/ const IPV4_REGEXP = /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/; const IPV6_REGEXP = /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(([0-9A-Fa-f]{1,4}:){0,5}:((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(::([0-9A-Fa-f]{1,4}:){0,5}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/; diff --git a/app/lib/dto/PeerDTO.ts b/app/lib/dto/PeerDTO.ts index e2ffcf333..d0e661bb8 100644 --- a/app/lib/dto/PeerDTO.ts +++ b/app/lib/dto/PeerDTO.ts @@ -98,7 +98,7 @@ export class PeerDTO implements Cloneable { let api:{ uuid:string, host:string, port:number, path:string }|null = null const endpointRegexp = (tor) ? CommonConstants.WS2PTOR_REGEXP:CommonConstants.WS2P_REGEXP for (const ep of this.endpoints) { - const matches:any = !api && ep.match(CommonConstants.WS2P_REGEXP) + const matches:any = !api && ep.match(endpointRegexp) if (matches) { api = { uuid: matches[1], diff --git a/app/lib/proxy.ts b/app/lib/proxy.ts index c70dcf423..3627314db 100644 --- a/app/lib/proxy.ts +++ b/app/lib/proxy.ts @@ -21,25 +21,23 @@ export interface ProxyConf { } export class Proxy { - private agent: any - private timeout:number + public agent: any + private url:string - constructor(proxy:string, type:string = "socks", timeout:number = DEFAULT_PROXY_TIMEOUT) { + constructor(proxy:string, type:string = "socks", public timeout:number = DEFAULT_PROXY_TIMEOUT) { if (type === "socks") { this.agent = SocksProxyAgent("socks://"+proxy) + this.url = "socks://"+proxy } else { + this.url = "" this.agent = undefined } this.timeout = timeout } - getAgent() { - return this.agent; - } - - getTimeout() { - return this.timeout; + getUrl() { + return this.url; } static defaultConf():ProxyConf { @@ -51,6 +49,10 @@ export class Proxy { } } + static canReachTorEndpoint(proxyConf: ProxyConf|undefined):boolean { + return (proxyConf !== undefined && (proxyConf.alwaysUseTor === true || (proxyConf.proxies !== undefined && proxyConf.proxies.proxyTor !== undefined) ) ) + } + static createProxies(proxyConf: ProxyConf|undefined) : Proxies|undefined { if (proxyConf !== undefined) { @@ -77,11 +79,11 @@ export class Proxy { proxyConf.proxies = Proxy.createProxies(proxyConf) } if (proxyConf.proxies !== undefined) { - if ( proxyConf.proxies.proxyTor !== undefined && proxyConf.proxies.proxyTor.getAgent() !== undefined && (proxyConf.alwaysUseTor || address.match(onionRegex)) && !mySelf ) + if ( proxyConf.proxies.proxyTor !== undefined && proxyConf.proxies.proxyTor.agent !== undefined && (proxyConf.alwaysUseTor || address.match(onionRegex)) && !mySelf ) { return proxyConf.proxies.proxyTor } - else if (proxyConf.proxies.proxySocks !== undefined && proxyConf.proxies.proxySocks.getAgent() !== undefined) { + else if (proxyConf.proxies.proxySocks !== undefined && proxyConf.proxies.proxySocks.agent !== undefined) { return proxyConf.proxies.proxySocks } } diff --git a/app/modules/ws2p/lib/WS2PCluster.ts b/app/modules/ws2p/lib/WS2PCluster.ts index 5282a1090..d1aa4ece5 100644 --- a/app/modules/ws2p/lib/WS2PCluster.ts +++ b/app/modules/ws2p/lib/WS2PCluster.ts @@ -16,6 +16,7 @@ import {WS2PMessageHandler} from "./impl/WS2PMessageHandler" import { CommonConstants } from '../../../lib/common-libs/constants'; import { Package } from "../../../lib/common/package"; import { Constants } from "../../prover/lib/constants"; +import { ProxyConf, Proxy } from '../../../lib/proxy'; const es = require('event-stream') const nuuid = require('node-uuid') @@ -291,6 +292,7 @@ export class WS2PCluster { async connectToRemoteWS(host: string, port: number, path:string, messageHandler:WS2PMessageHandler, expectedPub:string, ws2pEndpointUUID:string = ""): Promise<WS2PConnection> { const uuid = nuuid.v4() let pub = "--------" + const api:string = (host.match(WS2PConstants.HOST_ONION_REGEX) !== null) ? 'WS2PTOR':'WS2P' try { const fullEndpointAddress = WS2PCluster.getFullAddress(host, port, path) const ws2pc = await WS2PClient.connectTo(this.server, fullEndpointAddress, ws2pEndpointUUID, messageHandler, expectedPub, (pub:string) => { @@ -300,7 +302,7 @@ export class WS2PCluster { this.ws2pClients[uuid] = ws2pc pub = ws2pc.connection.pubkey ws2pc.connection.closed.then(() => { - this.server.logger.info('WS2P: connection [%s `WS2P %s %s`] has been closed', pub.slice(0, 8), host, port) + this.server.logger.info(api+': connection [%s `'+api+' %s %s`] has been closed', pub.slice(0, 8), host, port) this.server.push({ ws2p: 'disconnected', peer: { @@ -311,7 +313,7 @@ export class WS2PCluster { delete this.ws2pClients[uuid] } }) - this.server.logger.info('WS2P: connected to peer %s using `WS2P %s %s`!', pub.slice(0, 8), host, port) + this.server.logger.info(api+': connected to peer %s using `'+api+' %s %s`!', pub.slice(0, 8), host, port) this.server.push({ ws2p: 'connected', to: { host, port, pubkey: pub } @@ -319,7 +321,7 @@ export class WS2PCluster { await this.server.dal.setPeerUP(pub) return ws2pc.connection } catch (e) { - this.server.logger.info('WS2P: Could not connect to peer %s using `WS2P %s %s: %s`', pub.slice(0, 8), host, port, (e && e.message || e)) + this.server.logger.info(api+': Could not connect to peer %s using `'+api+' %s %s: %s`', pub.slice(0, 8), host, port, (e && e.message || e)) throw e } } @@ -330,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 imTorPeer = this.server.conf.proxyConf && this.server.conf.proxyConf.proxies && this.server.conf.proxyConf.proxies.proxyTor + const imCanReachTorEndpoint = Proxy.canReachTorEndpoint(this.server.conf.proxyConf) peers.sort((a, b) => { const aIsPrefered = prefered.indexOf(a.pubkey) !== -1 const bIsPrefered = prefered.indexOf(b.pubkey) !== -1 - if (imTorPeer) { + if (imCanReachTorEndpoint) { 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,7 +369,7 @@ export class WS2PCluster { let i = 0 while (i < peers.length && this.clientsCount() < this.maxLevel1Size) { const p = peers[i] - const api = p.getWS2P(imTorPeer !== undefined) + const api = p.getWS2P(imCanReachTorEndpoint !== undefined) if (api) { try { await this.connectToRemoteWS(api.host, api.port, api.path, this.messageHandler, p.pubkey, api.uuid) diff --git a/app/modules/ws2p/lib/WS2PConnection.ts b/app/modules/ws2p/lib/WS2PConnection.ts index 7d0b96a02..06de3fc44 100644 --- a/app/modules/ws2p/lib/WS2PConnection.ts +++ b/app/modules/ws2p/lib/WS2PConnection.ts @@ -279,11 +279,11 @@ export class WS2PConnection { expectedPub:string = "") { if (proxy !== undefined) { options = { - connectionTimeout: proxy.getTimeout(), - requestTimeout: proxy.getTimeout() + connectionTimeout: proxy.timeout, + requestTimeout: proxy.timeout } } - const websocket = (proxy !== undefined) ? new ws(address, { agent: proxy.getAgent() }):new ws(address) + const websocket = (proxy !== undefined) ? new ws(address, { agent: proxy.agent }):new ws(address) const onWsOpened:Promise<void> = new Promise(res => { websocket.on('open', () => res()) }) -- GitLab From 3e117452ef60a21af582852878dd8ee37ca70be7 Mon Sep 17 00:00:00 2001 From: librelois <elois@ifee.fr> Date: Mon, 30 Oct 2017 19:23:15 +0100 Subject: [PATCH 16/34] proxy attribute re-encapsulation --- app/lib/proxy.ts | 24 ++++++++++++++---------- app/modules/ws2p/lib/WS2PConnection.ts | 6 +++--- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/app/lib/proxy.ts b/app/lib/proxy.ts index 3627314db..8c7016890 100644 --- a/app/lib/proxy.ts +++ b/app/lib/proxy.ts @@ -1,8 +1,5 @@ const SocksProxyAgent = require('socks-proxy-agent'); -const constants = require('./constants'); -const WS2PConstants = require('../modules/ws2p/lib/constants'); - const DEFAULT_PROXY_TIMEOUT:number = 30000 const TOR_PROXY_TIMEOUT:number = 60000 const HTTP_ENDPOINT_ONION_REGEX = new RegExp('(?:https?:\/\/)?(?:www)?(\S*?\.onion)(\/[-\w]*)*') @@ -21,25 +18,32 @@ export interface ProxyConf { } export class Proxy { - public agent: any + private agent: any private url:string - constructor(proxy:string, type:string = "socks", public timeout:number = DEFAULT_PROXY_TIMEOUT) { + constructor(proxy:string, type:string = "socks", private timeout:number = DEFAULT_PROXY_TIMEOUT) { if (type === "socks") { - this.agent = SocksProxyAgent("socks://"+proxy) - this.url = "socks://"+proxy + this.agent = SocksProxyAgent("socks://"+proxy) + this.url = "socks://"+proxy } else { - this.url = "" - this.agent = undefined + this.agent = undefined + this.url = "" } - this.timeout = timeout + } + + getAgent() { + return this.agent; } getUrl() { return this.url; } + getTimeout() { + return this.timeout; + } + static defaultConf():ProxyConf { return { proxySocksAddress: undefined, diff --git a/app/modules/ws2p/lib/WS2PConnection.ts b/app/modules/ws2p/lib/WS2PConnection.ts index 06de3fc44..7d0b96a02 100644 --- a/app/modules/ws2p/lib/WS2PConnection.ts +++ b/app/modules/ws2p/lib/WS2PConnection.ts @@ -279,11 +279,11 @@ export class WS2PConnection { expectedPub:string = "") { if (proxy !== undefined) { options = { - connectionTimeout: proxy.timeout, - requestTimeout: proxy.timeout + connectionTimeout: proxy.getTimeout(), + requestTimeout: proxy.getTimeout() } } - const websocket = (proxy !== undefined) ? new ws(address, { agent: proxy.agent }):new ws(address) + const websocket = (proxy !== undefined) ? new ws(address, { agent: proxy.getAgent() }):new ws(address) const onWsOpened:Promise<void> = new Promise(res => { websocket.on('open', () => res()) }) -- GitLab From b280d826343788e9f8a9e50ef06f73333cc7ca62 Mon Sep 17 00:00:00 2001 From: librelois <elois@ifee.fr> Date: Mon, 30 Oct 2017 20:43:23 +0100 Subject: [PATCH 17/34] [ifx] getWS2P : return WS2P endpoint if there not WS2PTOR --- app/lib/dto/PeerDTO.ts | 13 ++++++++++++- app/modules/ws2p/index.ts | 2 +- app/modules/ws2p/lib/WS2PCluster.ts | 2 +- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/app/lib/dto/PeerDTO.ts b/app/lib/dto/PeerDTO.ts index d0e661bb8..2bb2e91cd 100644 --- a/app/lib/dto/PeerDTO.ts +++ b/app/lib/dto/PeerDTO.ts @@ -98,7 +98,18 @@ export class PeerDTO implements Cloneable { let api:{ uuid:string, host:string, port:number, path:string }|null = null const endpointRegexp = (tor) ? CommonConstants.WS2PTOR_REGEXP:CommonConstants.WS2P_REGEXP for (const ep of this.endpoints) { - const matches:any = !api && ep.match(endpointRegexp) + if (tor) { + const matches:any = ep.match(CommonConstants.WS2PTOR_REGEXP) + if (matches) { + return { + uuid: matches[1], + host: matches[2] || '', + port: parseInt(matches[3]) || 0, + path: matches[4] + } + } + } + const matches:any = !api && ep.match(CommonConstants.WS2P_REGEXP) if (matches) { api = { uuid: matches[1], diff --git a/app/modules/ws2p/index.ts b/app/modules/ws2p/index.ts index 6a3dd8fbc..a225e63ec 100644 --- a/app/modules/ws2p/index.ts +++ b/app/modules/ws2p/index.ts @@ -141,7 +141,7 @@ export const WS2PDependency = { const peers = await server.dal.getWS2Peers() for (const p of peers) { for (const ep of p.endpoints) { - if (ep.match(/^WS2P /)) { + if (ep.match(/^WS2P/)) { console.log(p.pubkey, ep) } } diff --git a/app/modules/ws2p/lib/WS2PCluster.ts b/app/modules/ws2p/lib/WS2PCluster.ts index d1aa4ece5..93e8119d8 100644 --- a/app/modules/ws2p/lib/WS2PCluster.ts +++ b/app/modules/ws2p/lib/WS2PCluster.ts @@ -369,7 +369,7 @@ export class WS2PCluster { let i = 0 while (i < peers.length && this.clientsCount() < this.maxLevel1Size) { const p = peers[i] - const api = p.getWS2P(imCanReachTorEndpoint !== undefined) + const api = p.getWS2P(imCanReachTorEndpoint) if (api) { try { await this.connectToRemoteWS(api.host, api.port, api.path, this.messageHandler, p.pubkey, api.uuid) -- GitLab From 8198ed468bcbb3faf01b4d4d54568b7975ea9aa9 Mon Sep 17 00:00:00 2001 From: librelois <elois@ifee.fr> Date: Tue, 31 Oct 2017 03:01:20 +0100 Subject: [PATCH 18/34] rename ProxyConf -> ProxiesConf --- app/lib/dal/fileDAL.ts | 2 +- app/lib/dto/ConfDTO.ts | 6 +++--- app/modules/ws2p/lib/WS2PClient.ts | 8 ++------ app/modules/ws2p/lib/WS2PCluster.ts | 4 ++-- 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/app/lib/dal/fileDAL.ts b/app/lib/dal/fileDAL.ts index 1298d6a12..267d0f184 100644 --- a/app/lib/dal/fileDAL.ts +++ b/app/lib/dal/fileDAL.ts @@ -15,7 +15,7 @@ import {DBBlock} from "../db/DBBlock" import {DBMembership} from "./sqliteDAL/MembershipDAL" import {MerkleDTO} from "../dto/MerkleDTO" import {CommonConstants} from "../common-libs/constants" -import { ProxyConf } from '../proxy'; +import { ProxiesConf } from '../proxy'; const fs = require('fs') const path = require('path') diff --git a/app/lib/dto/ConfDTO.ts b/app/lib/dto/ConfDTO.ts index cdedf5037..fdd2038b7 100644 --- a/app/lib/dto/ConfDTO.ts +++ b/app/lib/dto/ConfDTO.ts @@ -1,5 +1,5 @@ import {CommonConstants} from "../common-libs/constants" -import { Proxy, ProxyConf } from '../proxy'; +import { ProxiesConf } from '../proxy'; const _ = require('underscore'); const constants = require('../constants'); @@ -47,7 +47,7 @@ export interface KeypairConfDTO { } export interface NetworkConfDTO { - proxyConf: ProxyConf|undefined + proxyConf: 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: ProxyConf|undefined, + public proxyConf: ProxiesConf|undefined, public ws2p?: { privateAccess: boolean publicAccess: boolean diff --git a/app/modules/ws2p/lib/WS2PClient.ts b/app/modules/ws2p/lib/WS2PClient.ts index 0ff0b6178..80a4fd1bd 100644 --- a/app/modules/ws2p/lib/WS2PClient.ts +++ b/app/modules/ws2p/lib/WS2PClient.ts @@ -6,7 +6,7 @@ import {WS2PMessageHandler} from "./impl/WS2PMessageHandler" import {WS2PConstants} from "./constants" import {WS2PStreamer} from "./WS2PStreamer" import {WS2PSingleWriteStream} from "./WS2PSingleWriteStream" -import { Proxies, ProxyConf, Proxy } from '../../../lib/proxy'; +import { ProxiesConf } from '../../../lib/proxy'; import { server } from '../../../../test/integration/tools/toolbox'; export class WS2PClient { @@ -15,16 +15,12 @@ export class WS2PClient { static async connectTo(server:Server, fullEndpointAddress:string, uuid:string, messageHandler:WS2PMessageHandler, expectedPub:string, allowKey:(pub:string)=>Promise<boolean> ) { const k2 = new Key(server.conf.pair.pub, server.conf.pair.sec) - let mySelf = false; - if (server.conf.ws2p && server.conf.ws2p.uuid === uuid) { - let mySelf = true; - } const c = WS2PConnection.newConnectionToAddress( fullEndpointAddress, messageHandler, new WS2PPubkeyLocalAuth(server.conf.currency , k2, allowKey), new WS2PPubkeyRemoteAuth(server.conf.currency, k2, allowKey), - Proxy.wsProxy(fullEndpointAddress, server.conf.proxyConf, mySelf), + ProxiesConf.wsProxy(fullEndpointAddress, server.conf.proxyConf), { connectionTimeout: WS2PConstants.REQUEST_TIMEOUT, requestTimeout: WS2PConstants.REQUEST_TIMEOUT diff --git a/app/modules/ws2p/lib/WS2PCluster.ts b/app/modules/ws2p/lib/WS2PCluster.ts index 93e8119d8..5e785d9ef 100644 --- a/app/modules/ws2p/lib/WS2PCluster.ts +++ b/app/modules/ws2p/lib/WS2PCluster.ts @@ -16,7 +16,7 @@ import {WS2PMessageHandler} from "./impl/WS2PMessageHandler" import { CommonConstants } from '../../../lib/common-libs/constants'; import { Package } from "../../../lib/common/package"; import { Constants } from "../../prover/lib/constants"; -import { ProxyConf, Proxy } from '../../../lib/proxy'; +import { ProxiesConf } from '../../../lib/proxy'; const es = require('event-stream') const nuuid = require('node-uuid') @@ -332,7 +332,7 @@ 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 = Proxy.canReachTorEndpoint(this.server.conf.proxyConf) + const imCanReachTorEndpoint = ProxiesConf.canReachTorEndpoint(this.server.conf.proxyConf) peers.sort((a, b) => { const aIsPrefered = prefered.indexOf(a.pubkey) !== -1 const bIsPrefered = prefered.indexOf(b.pubkey) !== -1 -- GitLab From 89a716bfac62b6a7a521ceca25f00cbdc39eea88 Mon Sep 17 00:00:00 2001 From: librelois <elois@ifee.fr> Date: Tue, 31 Oct 2017 03:02:43 +0100 Subject: [PATCH 19/34] rewrite proxiesConf type --- app/lib/proxy.ts | 104 +++++++++++------------------------------------ index.ts | 4 +- server.ts | 4 +- 3 files changed, 28 insertions(+), 84 deletions(-) diff --git a/app/lib/proxy.ts b/app/lib/proxy.ts index 8c7016890..051a57d3a 100644 --- a/app/lib/proxy.ts +++ b/app/lib/proxy.ts @@ -1,97 +1,41 @@ const SocksProxyAgent = require('socks-proxy-agent'); -const DEFAULT_PROXY_TIMEOUT:number = 30000 -const TOR_PROXY_TIMEOUT:number = 60000 -const HTTP_ENDPOINT_ONION_REGEX = new RegExp('(?:https?:\/\/)?(?:www)?(\S*?\.onion)(\/[-\w]*)*') -const WS_ENDPOINT_ONION_REGEX = new RegExp('(?:wss?:\/\/)?(?:www)?(\S*?\.onion)(\/[-\w]*)*') +const HOST_ONION_REGEX = new RegExp('(\S*?\.onion)$'); +const WS_ENDPOINT_ONION_REGEX = new RegExp('(?:wss?:\/\/)?(?:www)?(\S*?\.onion)(\/[-\w]*)*'); -export interface Proxies { - proxySocks: Proxy|undefined, - proxyTor: Proxy|undefined -} +export class ProxiesConf { + public proxySocksAddress: string|undefined + public proxyTorAddress: string|undefined + public alwaysUseTor: boolean|undefined -export interface ProxyConf { - proxySocksAddress: string|undefined, - proxyTorAddress: string|undefined, - alwaysUseTor: boolean|undefined, - proxies: Proxies|undefined -} - -export class Proxy { - private agent: any - private url:string - - constructor(proxy:string, type:string = "socks", private timeout:number = DEFAULT_PROXY_TIMEOUT) { - if (type === "socks") { - this.agent = SocksProxyAgent("socks://"+proxy) - this.url = "socks://"+proxy - } - else { - this.agent = undefined - this.url = "" - } + constructor () { + this.proxySocksAddress = undefined + this.proxyTorAddress = undefined + this.alwaysUseTor = undefined } - getAgent() { - return this.agent; + static canReachTorEndpoint(proxyConf: ProxiesConf|undefined):boolean { + return (proxyConf !== undefined && (proxyConf.alwaysUseTor === true || (proxyConf.proxyTorAddress !== undefined) ) ) } - getUrl() { - return this.url; - } - - getTimeout() { - return this.timeout; - } - - static defaultConf():ProxyConf { - return { - proxySocksAddress: undefined, - proxyTorAddress: undefined, - alwaysUseTor: undefined, - proxies: undefined - } + static httpProxy(url:string, proxyConf: ProxiesConf|undefined):string|undefined { + return ProxiesConf.chooseProxyAgent(url, proxyConf, HOST_ONION_REGEX) } - static canReachTorEndpoint(proxyConf: ProxyConf|undefined):boolean { - return (proxyConf !== undefined && (proxyConf.alwaysUseTor === true || (proxyConf.proxies !== undefined && proxyConf.proxies.proxyTor !== undefined) ) ) + static wsProxy(address:string, proxyConf: ProxiesConf|undefined):string|undefined { + return ProxiesConf.chooseProxyAgent(address, proxyConf, WS_ENDPOINT_ONION_REGEX) } - static createProxies(proxyConf: ProxyConf|undefined) : Proxies|undefined - { + private static chooseProxyAgent(address:string, proxyConf: ProxiesConf|undefined, onionRegex:RegExp):string|undefined { if (proxyConf !== undefined) { - return { - proxySocks: (proxyConf.proxySocksAddress !== undefined) ? new Proxy(proxyConf.proxySocksAddress, "socks"):undefined, - proxyTor: (proxyConf.proxyTorAddress !== undefined) ? new Proxy(proxyConf.proxyTorAddress, "socks", TOR_PROXY_TIMEOUT):undefined + if ( proxyConf.proxyTorAddress !== undefined && (proxyConf.alwaysUseTor || address.match(onionRegex))) + { + return proxyConf.proxyTorAddress + } + else if (proxyConf.proxySocksAddress !== undefined) { + return proxyConf.proxySocksAddress } - } else { - return undefined - } - } - - static httpProxy(url:string, proxyConf: ProxyConf|undefined) { - return Proxy.chooseProxy(url, proxyConf, HTTP_ENDPOINT_ONION_REGEX) - } - - static wsProxy(address:string, proxyConf: ProxyConf|undefined, mySelf:boolean = false) { - return Proxy.chooseProxy(address, proxyConf, WS_ENDPOINT_ONION_REGEX, mySelf) - } - - private static chooseProxy(address:string, proxyConf: ProxyConf|undefined, onionRegex:RegExp, mySelf:boolean = false): Proxy|undefined { - if (proxyConf !== undefined) { - if (proxyConf.proxies === undefined) { - proxyConf.proxies = Proxy.createProxies(proxyConf) - } - if (proxyConf.proxies !== undefined) { - if ( proxyConf.proxies.proxyTor !== undefined && proxyConf.proxies.proxyTor.agent !== undefined && (proxyConf.alwaysUseTor || address.match(onionRegex)) && !mySelf ) - { - return proxyConf.proxies.proxyTor - } - else if (proxyConf.proxies.proxySocks !== undefined && proxyConf.proxies.proxySocks.agent !== undefined) { - return proxyConf.proxies.proxySocks - } - } } return undefined } -} +} \ No newline at end of file diff --git a/index.ts b/index.ts index ada66317c..70b7bd28a 100644 --- a/index.ts +++ b/index.ts @@ -8,7 +8,7 @@ import {CrawlerDependency} from "./app/modules/crawler/index" import {BmaDependency} from "./app/modules/bma/index" import {WS2PDependency} from "./app/modules/ws2p/index" import {Constants} from "./app/modules/prover/lib/constants" -import { Proxy } from './app/lib/proxy'; +import { ProxiesConf } from './app/lib/proxy'; const path = require('path'); const _ = require('underscore'); @@ -469,7 +469,7 @@ function commandLineConf(program:any, conf:any = {}) { // Declare proxyConf if (cli.proxies.proxySocks || cli.proxies.proxyTor || cli.proxies.torAlways || cli.proxies.torMixed || cli.proxies.rmProxies) { - conf.proxyConf = Proxy.defaultConf() + conf.proxyConf = new ProxiesConf() } // Update conf diff --git a/server.ts b/server.ts index 89772dbf0..9eca4b855 100644 --- a/server.ts +++ b/server.ts @@ -24,7 +24,7 @@ import {PeerDTO} from "./app/lib/dto/PeerDTO" import {OtherConstants} from "./app/lib/other_constants" import {WS2PCluster} from "./app/modules/ws2p/lib/WS2PCluster" import {DBBlock} from "./app/lib/db/DBBlock" -import { Proxy } from './app/lib/proxy'; +import { ProxiesConf } from './app/lib/proxy'; export interface HookableServer { generatorGetJoinData: (...args:any[]) => Promise<any> @@ -149,7 +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 ? Proxy.defaultConf() : this.conf.proxyConf + 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.remoteipv6 = this.conf.remoteipv6 === undefined ? this.conf.ipv6 : this.conf.remoteipv6 this.conf.remoteport = this.conf.remoteport === undefined ? this.conf.port : this.conf.remoteport -- GitLab From 87721f1e963a05276c6a0558e76c95aa4e0e142f Mon Sep 17 00:00:00 2001 From: librelois <elois@ifee.fr> Date: Tue, 31 Oct 2017 03:03:44 +0100 Subject: [PATCH 20/34] add constant PROXY_TIMEOUT --- app/modules/ws2p/lib/constants.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/app/modules/ws2p/lib/constants.ts b/app/modules/ws2p/lib/constants.ts index 92c69becc..6a5e93f24 100644 --- a/app/modules/ws2p/lib/constants.ts +++ b/app/modules/ws2p/lib/constants.ts @@ -8,6 +8,7 @@ export const WS2PConstants = { CONNEXION_TIMEOUT: 10000, REQUEST_TIMEOUT: 10000, + PROXY_TIMEOUT: 30000, RECONNEXION_INTERVAL_IN_SEC: 60 * 10, // 10 minutes BLOCK_PULLING_INTERVAL: 300 * 2, // 10 minutes -- GitLab From d0acedd5a1264c95ed6d32e53bfc91f0812df94e Mon Sep 17 00:00:00 2001 From: librelois <elois@ifee.fr> Date: Tue, 31 Oct 2017 03:05:36 +0100 Subject: [PATCH 21/34] change proxy agent application --- app/modules/ws2p/lib/WS2PConnection.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/app/modules/ws2p/lib/WS2PConnection.ts b/app/modules/ws2p/lib/WS2PConnection.ts index 7d0b96a02..9a08ac742 100644 --- a/app/modules/ws2p/lib/WS2PConnection.ts +++ b/app/modules/ws2p/lib/WS2PConnection.ts @@ -7,8 +7,9 @@ import {MembershipDTO} from "../../../lib/dto/MembershipDTO" import {TransactionDTO} from "../../../lib/dto/TransactionDTO" import {PeerDTO} from "../../../lib/dto/PeerDTO" import {WS2PConstants} from "./constants" -import { Proxy } from '../../../lib/proxy'; +import { ProxiesConf } from '../../../lib/proxy'; const ws = require('ws') +const SocksProxyAgent = require('socks-proxy-agent'); const nuuid = require('node-uuid'); const logger = require('../../../lib/logger').NewLogger('ws2p') @@ -268,7 +269,7 @@ export class WS2PConnection { messageHandler:WS2PMessageHandler, localAuth:WS2PLocalAuth, remoteAuth:WS2PRemoteAuth, - proxy:Proxy|undefined = undefined, + proxySocksAddress:string|undefined = undefined, options:{ connectionTimeout:number, requestTimeout:number @@ -277,13 +278,13 @@ export class WS2PConnection { requestTimeout: REQUEST_TIMEOUT_VALUE }, expectedPub:string = "") { - if (proxy !== undefined) { + if (proxySocksAddress !== undefined) { options = { - connectionTimeout: proxy.getTimeout(), - requestTimeout: proxy.getTimeout() + connectionTimeout: WS2PConstants.PROXY_TIMEOUT, + requestTimeout: WS2PConstants.PROXY_TIMEOUT } } - const websocket = (proxy !== undefined) ? new ws(address, { agent: proxy.getAgent() }):new ws(address) + const websocket = (proxySocksAddress !== undefined) ? new ws(address, { agent: SocksProxyAgent("socks://"+proxySocksAddress) }):new ws(address) const onWsOpened:Promise<void> = new Promise(res => { websocket.on('open', () => res()) }) -- GitLab From 1174af18c7ee602d9010619cde287720abbb028f Mon Sep 17 00:00:00 2001 From: librelois <elois@ifee.fr> Date: Tue, 31 Oct 2017 03:07:34 +0100 Subject: [PATCH 22/34] ignore proxies test compiled files --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 3b71ae8db..8d7e9c280 100644 --- a/.gitignore +++ b/.gitignore @@ -54,5 +54,7 @@ test/fast/modules/crawler/block_pulling.js* test/fast/modules/crawler/block_pulling.d.ts test/fast/fork*.js* test/fast/fork*.d.ts +test/fast/proxies*.js* +test/fast/proxies*.d.ts test/fast/modules/ws2p/*.js* test/fast/modules/ws2p/*.d.ts -- GitLab From e1f8f6f7fc42a60bd21413a9ff59e25f8275e59d Mon Sep 17 00:00:00 2001 From: librelois <elois@ifee.fr> Date: Tue, 31 Oct 2017 03:09:02 +0100 Subject: [PATCH 23/34] add proxies conf unit test --- test/fast/proxies.ts | 51 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 test/fast/proxies.ts diff --git a/test/fast/proxies.ts b/test/fast/proxies.ts new file mode 100644 index 000000000..c47468092 --- /dev/null +++ b/test/fast/proxies.ts @@ -0,0 +1,51 @@ +import * as assert from 'assert' +import { ProxiesConf } from '../../app/lib/proxy'; + +describe("Proxies Conf", function() { + + // First conf : do not use any sock proxy + let proxiesConf1 = new ProxiesConf() + + // Second conf : use tor only to reach ".onion" endpoints + let proxiesConf2 = new ProxiesConf() + proxiesConf2.proxyTorAddress = "127.0.0.1:9050" + + // Third conf : always use tor + let proxiesConf3 = new ProxiesConf() + proxiesConf3.proxyTorAddress = "127.0.0.1:9050" + proxiesConf3.alwaysUseTor = true + + // Fourth cont : 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 + let proxiesConf5 = new ProxiesConf() + proxiesConf5.proxySocksAddress = "127.0.0.1:8888" + proxiesConf5.proxyTorAddress = "127.0.0.1:9050" + + 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) + }) + + 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) + }) + + 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) + }) + + 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) + }) + + 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) + }) +}); -- GitLab From f231daf660e08430b029cbd93744332a0f0e7de0 Mon Sep 17 00:00:00 2001 From: librelois <elois@ifee.fr> Date: Fri, 3 Nov 2017 03:34:12 +0100 Subject: [PATCH 24/34] [enh] improving tor config and timeout management --- app/cli.ts | 8 +-- app/lib/dal/fileDAL.ts | 2 +- app/lib/dto/ConfDTO.ts | 4 +- app/lib/dto/PeerDTO.ts | 22 ++++---- app/lib/proxy.ts | 48 ++++++++++------- app/modules/bma/lib/network.ts | 2 +- app/modules/ws2p/lib/WS2PClient.ts | 2 +- app/modules/ws2p/lib/WS2PCluster.ts | 9 ++-- app/modules/ws2p/lib/WS2PConnection.ts | 6 +-- app/modules/ws2p/lib/WS2PServer.ts | 15 ++++-- app/modules/ws2p/lib/constants.ts | 10 ++-- index.ts | 29 +++++----- server.ts | 3 +- test/fast/proxies.ts | 75 +++++++++++++++++++++----- 14 files changed, 155 insertions(+), 80 deletions(-) diff --git a/app/cli.ts b/app/cli.ts index 187022269..26accf24f 100644 --- a/app/cli.ts +++ b/app/cli.ts @@ -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) diff --git a/app/lib/dal/fileDAL.ts b/app/lib/dal/fileDAL.ts index 267d0f184..600226123 100644 --- a/app/lib/dal/fileDAL.ts +++ b/app/lib/dal/fileDAL.ts @@ -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({}); } } diff --git a/app/lib/dto/ConfDTO.ts b/app/lib/dto/ConfDTO.ts index fdd2038b7..1227913e3 100644 --- a/app/lib/dto/ConfDTO.ts +++ b/app/lib/dto/ConfDTO.ts @@ -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 diff --git a/app/lib/dto/PeerDTO.ts b/app/lib/dto/PeerDTO.ts index 2bb2e91cd..dc5754b68 100644 --- a/app/lib/dto/PeerDTO.ts +++ b/app/lib/dto/PeerDTO.ts @@ -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] + } } } } diff --git a/app/lib/proxy.ts b/app/lib/proxy.ts index 051a57d3a..43b000a22 100644 --- a/app/lib/proxy.ts +++ b/app/lib/proxy.ts @@ -1,39 +1,51 @@ 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 diff --git a/app/modules/bma/lib/network.ts b/app/modules/bma/lib/network.ts index ae3459eb9..250a622bf 100644 --- a/app/modules/bma/lib/network.ts +++ b/app/modules/bma/lib/network.ts @@ -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', diff --git a/app/modules/ws2p/lib/WS2PClient.ts b/app/modules/ws2p/lib/WS2PClient.ts index 80a4fd1bd..569609f6e 100644 --- a/app/modules/ws2p/lib/WS2PClient.ts +++ b/app/modules/ws2p/lib/WS2PClient.ts @@ -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 diff --git a/app/modules/ws2p/lib/WS2PCluster.ts b/app/modules/ws2p/lib/WS2PCluster.ts index 5cc022579..875c552dd 100644 --- a/app/modules/ws2p/lib/WS2PCluster.ts +++ b/app/modules/ws2p/lib/WS2PCluster.ts @@ -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() diff --git a/app/modules/ws2p/lib/WS2PConnection.ts b/app/modules/ws2p/lib/WS2PConnection.ts index 9a08ac742..0595e5626 100644 --- a/app/modules/ws2p/lib/WS2PConnection.ts +++ b/app/modules/ws2p/lib/WS2PConnection.ts @@ -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) diff --git a/app/modules/ws2p/lib/WS2PServer.ts b/app/modules/ws2p/lib/WS2PServer.ts index c9d3dc9fb..ae79815fe 100644 --- a/app/modules/ws2p/lib/WS2PServer.ts +++ b/app/modules/ws2p/lib/WS2PServer.ts @@ -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 { diff --git a/app/modules/ws2p/lib/constants.ts b/app/modules/ws2p/lib/constants.ts index 6a5e93f24..28df5f5fb 100644 --- a/app/modules/ws2p/lib/constants.ts +++ b/app/modules/ws2p/lib/constants.ts @@ -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 diff --git a/index.ts b/index.ts index 70b7bd28a..f9e3cf445 100644 --- a/index.ts +++ b/index.ts @@ -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; diff --git a/server.ts b/server.ts index 9eca4b855..fff2e8acc 100644 --- a/server.ts +++ b/server.ts @@ -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 diff --git a/test/fast/proxies.ts b/test/fast/proxies.ts index c47468092..73377bf21 100644 --- a/test/fast/proxies.ts +++ b/test/fast/proxies.ts @@ -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) }) }); -- GitLab From 15d534149e5c5089addcd27576b1e82575d8445b Mon Sep 17 00:00:00 2001 From: librelois <elois@ifee.fr> Date: Fri, 3 Nov 2017 16:20:57 +0100 Subject: [PATCH 25/34] [enh] add option to use bma without crawler #1174 --- app/lib/dto/ConfDTO.ts | 4 +++- app/modules/bma/index.ts | 7 +++++++ app/modules/bma/lib/network.ts | 1 + app/modules/crawler/lib/crawler.ts | 4 ++-- app/modules/router.ts | 4 ++-- 5 files changed, 15 insertions(+), 5 deletions(-) diff --git a/app/lib/dto/ConfDTO.ts b/app/lib/dto/ConfDTO.ts index 1227913e3..f6c57cc5e 100644 --- a/app/lib/dto/ConfDTO.ts +++ b/app/lib/dto/ConfDTO.ts @@ -49,6 +49,7 @@ export interface KeypairConfDTO { export interface NetworkConfDTO { proxiesConf: ProxiesConf|undefined nobma: boolean + bmaWithCrawler: boolean remoteport: number remotehost: string|null remoteipv4: string|null @@ -136,6 +137,7 @@ export class ConfDTO implements CurrencyConfDTO, KeypairConfDTO, NetworkConfDTO, public homename: string, public memory: boolean, public nobma: boolean, + public bmaWithCrawler: boolean, public proxiesConf: ProxiesConf|undefined, public ws2p?: { privateAccess: boolean @@ -155,7 +157,7 @@ export class ConfDTO implements CurrencyConfDTO, KeypairConfDTO, NetworkConfDTO, ) {} static mock() { - return new ConfDTO("", "", [], [], 0, 0, 0.6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, false, 0, false, 0, 0, 0, 0, 0, { pub:'', sec:'' }, null, "", "", 0, "", "", "", 0, "", "", null, false, "", true, true, undefined) + return new ConfDTO("", "", [], [], 0, 0, 0.6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, false, 0, false, 0, 0, 0, 0, 0, { pub:'', sec:'' }, null, "", "", 0, "", "", "", 0, "", "", null, false, "", true, false, true, undefined) } static defaultConf() { diff --git a/app/modules/bma/index.ts b/app/modules/bma/index.ts index 914a6ecf4..2abe0ba7a 100644 --- a/app/modules/bma/index.ts +++ b/app/modules/bma/index.ts @@ -29,6 +29,8 @@ export const BmaDependency = { { value: '--noupnp', desc: 'Do not use UPnP to open remote port.' }, { value: '--bma', desc: 'Enables BMA API and its crawlers.' }, { value: '--nobma', desc: 'Disables BMA API and its crawlers.' }, + { value: '--bma-with-crawler', desc: 'Enables BMA Crawler.' }, + { value: '--bma-without-crawler', desc: 'Disable BMA Crawler.' }, { value: '-p, --port <port>', desc: 'Port to listen for requests', parser: (val:string) => parseInt(val) }, { value: '--ipv4 <address>', desc: 'IPv4 interface to listen for requests' }, { value: '--ipv6 <address>', desc: 'IPv6 interface to listen for requests' }, @@ -73,6 +75,9 @@ export const BmaDependency = { } } + // If bmaWithCrawler hasn't been defined yet + if (conf.bmaWithCrawler === undefined) { conf.bmaWithCrawler = false } + if (program.port !== undefined) conf.port = parseInt(program.port) if (program.ipv4 !== undefined) conf.ipv4 = program.ipv4; if (program.ipv6 !== undefined) conf.ipv6 = program.ipv6; @@ -82,6 +87,8 @@ export const BmaDependency = { if (program.remotep !== undefined) conf.remoteport = parseInt(program.remotep) if (program.bma !== undefined) conf.nobma = false if (program.nobma !== undefined) conf.nobma = true + if (program.bmaWithCrawler !== undefined) conf.bmaWithCrawler = true + if (program.bmaWithoutCrawler !== undefined) conf.bmaWithCrawler = false if (!conf.ipv4) delete conf.ipv4; if (!conf.ipv6) delete conf.ipv6; diff --git a/app/modules/bma/lib/network.ts b/app/modules/bma/lib/network.ts index 250a622bf..3e9e026f9 100644 --- a/app/modules/bma/lib/network.ts +++ b/app/modules/bma/lib/network.ts @@ -339,6 +339,7 @@ async function upnpConf (noupnp:boolean, logger:any) { const conf:NetworkConfDTO = { proxiesConf: undefined, nobma: true, + bmaWithCrawler: false, port: privatePort, ipv4: '127.0.0.1', ipv6: '::1', diff --git a/app/modules/crawler/lib/crawler.ts b/app/modules/crawler/lib/crawler.ts index 44bf5a217..9520c5e3a 100644 --- a/app/modules/crawler/lib/crawler.ts +++ b/app/modules/crawler/lib/crawler.ts @@ -48,7 +48,7 @@ export class Crawler extends stream.Transform implements DuniterService { } startService() { - if (this.conf.nobma) { + if (this.conf.nobma || !this.conf.bmaWithCrawler) { return Promise.resolve() } return Promise.all([ @@ -60,7 +60,7 @@ export class Crawler extends stream.Transform implements DuniterService { } stopService() { - if (this.conf.nobma) { + if (this.conf.nobma || !this.conf.bmaWithCrawler) { return Promise.resolve() } return Promise.all([ diff --git a/app/modules/router.ts b/app/modules/router.ts index 1530cc43e..d6484f05b 100644 --- a/app/modules/router.ts +++ b/app/modules/router.ts @@ -44,7 +44,7 @@ class Router extends stream.Transform { }; async startService() { - if (this.server.conf.nobma) { + if (this.server.conf.nobma || !this.server.conf.bmaWithCrawler) { // Disable BMA return Promise.resolve() } @@ -69,7 +69,7 @@ class Router extends stream.Transform { } async stopService() { - if (this.server.conf.nobma) { + if (this.server.conf.nobma || !this.server.conf.bmaWithCrawler) { // Disable BMA return Promise.resolve() } -- GitLab From da51665ce8a0a42d29238f73c60d14f7adbeda2b Mon Sep 17 00:00:00 2001 From: librelois <elois@ifee.fr> Date: Fri, 3 Nov 2017 16:38:55 +0100 Subject: [PATCH 26/34] [enh] create automatically BMATOR endpoint --- app/lib/common-libs/constants.ts | 6 ++++++ app/lib/proxy.ts | 2 ++ app/modules/bma/index.ts | 3 +++ app/modules/bma/lib/constants.ts | 2 ++ app/modules/ws2p/lib/constants.ts | 4 ++-- 5 files changed, 15 insertions(+), 2 deletions(-) diff --git a/app/lib/common-libs/constants.ts b/app/lib/common-libs/constants.ts index e44639342..98623e305 100644 --- a/app/lib/common-libs/constants.ts +++ b/app/lib/common-libs/constants.ts @@ -31,10 +31,13 @@ const UNLOCK = "(SIG\\(" + INTEGER + "\\)|XHX\\(" + XUNLOCK + "\\))" const CONDITIONS = "(&&|\\|\\|| |[()]|(SIG\\(" + PUBKEY + "\\)|(XHX\\([A-F0-9]{64}\\)|CLTV\\(" + CLTV_INTEGER + "\\)|CSV\\(" + CSV_INTEGER + "\\))))*" const BMA_REGEXP = /^BASIC_MERKLED_API( ([a-z_][a-z0-9-_.]*))?( ([0-9.]+))?( ([0-9a-f:]+))?( ([0-9]+))$/ +const BMATOR_REGEXP = /^BMATOR( ([a-z0-9]{16})\.onion)( ([0-9.]+))?( ([0-9a-f:]+))?( ([0-9]+))$/ const WS2P_REGEXP = /^WS2P ([a-f0-9]{8}) ([a-z_][a-z0-9-_.]*|[0-9.]+|[0-9a-f:]+) ([0-9]+)(?: (.+))?$/ const WS2PTOR_REGEXP = /^WS2PTOR ([a-f0-9]{8}) ([a-z0-9-_.]*|[0-9.]+|[0-9a-f:]+.onion) ([0-9]+)(?: (.+))?$/ +const WS_FULL_ADDRESS_ONION_REGEX = /'^(?:wss?:\/\/)(?:www\.)?([0-9a-z]{16}\.onion)(:[0-9]+)?(\/[-\w]*)*/ const IPV4_REGEXP = /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/; const IPV6_REGEXP = /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(([0-9A-Fa-f]{1,4}:){0,5}:((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(::([0-9A-Fa-f]{1,4}:){0,5}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/; +const HOST_ONION_REGEX = /'^(?:www\.)?([0-9a-z]{16}\.onion)$'/ const MAXIMUM_LEN_OF_COMPACT_TX = 100 const MAXIMUM_LEN_OF_OUTPUT = 2000 @@ -90,10 +93,13 @@ export const CommonConstants = { SWITCH_ON_BRANCH_AHEAD_BY_X_BLOCKS: 3, BMA_REGEXP, + BMATOR_REGEXP, WS2P_REGEXP, WS2PTOR_REGEXP, + WS_FULL_ADDRESS_ONION_REGEX, IPV4_REGEXP, IPV6_REGEXP, + HOST_ONION_REGEX, PUBLIC_KEY: exact(PUBKEY), INTEGER: /^\d+$/, BASE58: exact(BASE58), diff --git a/app/lib/proxy.ts b/app/lib/proxy.ts index 43b000a22..7df0703de 100644 --- a/app/lib/proxy.ts +++ b/app/lib/proxy.ts @@ -1,3 +1,5 @@ +import {CommonConstants} from "./common-libs/constants" + const SocksProxyAgent = require('socks-proxy-agent'); const HOST_ONION_REGEX = new RegExp('(?:www\.)?([0-9a-z]{16}?\.onion)$'); diff --git a/app/modules/bma/index.ts b/app/modules/bma/index.ts index 2abe0ba7a..d9b4c2d02 100644 --- a/app/modules/bma/index.ts +++ b/app/modules/bma/index.ts @@ -260,6 +260,9 @@ export class BMAPI extends stream.Transform { function getEndpoint(theConf:NetworkConfDTO) { let endpoint = 'BASIC_MERKLED_API'; if (theConf.remotehost) { + if (theConf.remotehost.match(BMAConstants.HOST_ONION_REGEX)) { + endpoint = 'BMATOR'; + } endpoint += ' ' + theConf.remotehost; } if (theConf.remoteipv4) { diff --git a/app/modules/bma/lib/constants.ts b/app/modules/bma/lib/constants.ts index 6caa2204b..20a76a6eb 100644 --- a/app/modules/bma/lib/constants.ts +++ b/app/modules/bma/lib/constants.ts @@ -1,3 +1,4 @@ +import {CommonConstants} from "../../../lib/common-libs/constants" export const BMAConstants = { BMA_PORTS_START: 10901, @@ -6,6 +7,7 @@ export const BMAConstants = { DEFAULT_PORT: 10901, IPV4_REGEXP: /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/, IPV6_REGEXP: /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(([0-9A-Fa-f]{1,4}:){0,5}:((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(::([0-9A-Fa-f]{1,4}:){0,5}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/, + HOST_ONION_REGEX: CommonConstants.HOST_ONION_REGEX, PORT_START: 15000, UPNP_INTERVAL: 300, UPNP_TTL: 600, diff --git a/app/modules/ws2p/lib/constants.ts b/app/modules/ws2p/lib/constants.ts index 28df5f5fb..1607a537c 100644 --- a/app/modules/ws2p/lib/constants.ts +++ b/app/modules/ws2p/lib/constants.ts @@ -39,8 +39,8 @@ export const WS2PConstants = { + '(' + CommonConstants.FORMATS.POW_PREFIX + ')' + '$'), - 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]*)*'), + HOST_ONION_REGEX: CommonConstants.HOST_ONION_REGEX, + FULL_ADDRESS_ONION_REGEX: CommonConstants.WS_FULL_ADDRESS_ONION_REGEX, HEADS_SPREAD_TIMEOUT: 100 // Wait 100ms before sending a bunch of signed heads } \ No newline at end of file -- GitLab From cef5096e5886ecdcadb060ab664a3d060dc8fe32 Mon Sep 17 00:00:00 2001 From: librelois <elois@ifee.fr> Date: Fri, 3 Nov 2017 16:45:26 +0100 Subject: [PATCH 27/34] [fix] enable bma crawler for test integration --- test/integration/tools/toolbox.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/test/integration/tools/toolbox.ts b/test/integration/tools/toolbox.ts index 85c317dff..d0db935b4 100644 --- a/test/integration/tools/toolbox.ts +++ b/test/integration/tools/toolbox.ts @@ -226,6 +226,7 @@ export const NewTestingServer = (conf:any) => { const port = conf.port ||Â PORT++ const commonConf = { nobma: false, + bmaWithCrawler: true, port: port, ipv4: host, remoteipv4: host, -- GitLab From a0b0f3ac672761c02fd1073aabae76b74f8f4b7c Mon Sep 17 00:00:00 2001 From: librelois <elois@ifee.fr> Date: Fri, 3 Nov 2017 17:02:48 +0100 Subject: [PATCH 28/34] [fix] repair integration tests forwarding and network --- test/integration/forwarding.js | 2 +- test/integration/network.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/test/integration/forwarding.js b/test/integration/forwarding.js index b550a400b..ba392a69a 100644 --- a/test/integration/forwarding.js +++ b/test/integration/forwarding.js @@ -19,7 +19,7 @@ describe("Forwarding", function() { describe("Nodes", function() { - const common = { currency: 'bb', nobma: false, ws2p: { upnp: false }, ipv4: '127.0.0.1', remoteipv4: '127.0.0.1', rootoffset: 0, sigQty: 1 }; + const common = { currency: 'bb', nobma: false, bmaWithCrawler:true, ws2p: { upnp: false }, ipv4: '127.0.0.1', remoteipv4: '127.0.0.1', rootoffset: 0, sigQty: 1 }; const node1 = node('db_1', _({ upnp: false, httplogs: false, port: 9600, remoteport: 9600, pair: { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP'} }).extend(common)); const node2 = node('db_2', _({ upnp: false, httplogs: false, port: 9601, remoteport: 9601, pair: { pub: 'G2CBgZBPLe6FSFUgpx2Jf1Aqsgta6iib3vmDRA1yLiqU', sec: '58LDg8QLmF5pv6Dn9h7X4yFKfMTdP8fdAiWVcyDoTRJu454fwRihCLULH4MW37zncsg4ruoTGJPZneWk22QmG1w4'} }).extend(common)); diff --git a/test/integration/network.js b/test/integration/network.js index 32c2fae9e..88a4afa84 100644 --- a/test/integration/network.js +++ b/test/integration/network.js @@ -11,6 +11,7 @@ const expectAnswer = httpTest.expectAnswer; const MEMORY_MODE = true; const commonConf = { + bmaWithCrawler: true, ipv4: '127.0.0.1', remoteipv4: '127.0.0.1', currency: 'bb', -- GitLab From 7ec8440d7d23f92e12976f1aa090ad10cdd103df Mon Sep 17 00:00:00 2001 From: librelois <elois@ifee.fr> Date: Fri, 3 Nov 2017 17:47:27 +0100 Subject: [PATCH 29/34] [fix] test start_generate_blocks --- test/integration/start_generate_blocks.js | 1 + test/integration/tools/toolbox.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/test/integration/start_generate_blocks.js b/test/integration/start_generate_blocks.js index e700d38d5..c71bd8c80 100644 --- a/test/integration/start_generate_blocks.js +++ b/test/integration/start_generate_blocks.js @@ -19,6 +19,7 @@ const expectJSON = httpTest.expectJSON; const MEMORY_MODE = true; const commonConf = { + bmaWithCrawler: true, ipv4: '127.0.0.1', remoteipv4: '127.0.0.1', currency: 'bb', diff --git a/test/integration/tools/toolbox.ts b/test/integration/tools/toolbox.ts index d0db935b4..cbbe1d156 100644 --- a/test/integration/tools/toolbox.ts +++ b/test/integration/tools/toolbox.ts @@ -697,6 +697,7 @@ export const simpleWS2PNetwork: (s1: TestingServer, s2: TestingServer) => Promis export function simpleTestingConf(now = 1500000000, pair:{ pub:string, sec:string }): any { return { + bmaWithCrawler: true, pair, nbCores: 1, udTime0: now, -- GitLab From 94a394ee713208e128b744d7ad0028f3c5e3e879 Mon Sep 17 00:00:00 2001 From: librelois <elois@ifee.fr> Date: Fri, 3 Nov 2017 18:00:35 +0100 Subject: [PATCH 30/34] [fix] test peerings --- test/integration/peerings.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/integration/peerings.js b/test/integration/peerings.js index b9a729613..da7f16c6e 100644 --- a/test/integration/peerings.js +++ b/test/integration/peerings.js @@ -22,6 +22,7 @@ const expectJSON = httpTest.expectJSON; const MEMORY_MODE = true; const commonConf = { + bmaWithCrawler: true, ipv4: '127.0.0.1', remoteipv4: '127.0.0.1', currency: 'bb', -- GitLab From 40e3c3a7de5fce3eae19a01ea42e2dbb9eadd6f0 Mon Sep 17 00:00:00 2001 From: librelois <elois@ifee.fr> Date: Fri, 3 Nov 2017 21:44:01 +0100 Subject: [PATCH 31/34] [fix] regex HOST_ONION_REGEX (and increase REQUEST_TOR_TIMEOUT) --- app/lib/common-libs/constants.ts | 2 +- app/modules/ws2p/lib/constants.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/lib/common-libs/constants.ts b/app/lib/common-libs/constants.ts index 98623e305..d67a34036 100644 --- a/app/lib/common-libs/constants.ts +++ b/app/lib/common-libs/constants.ts @@ -37,7 +37,7 @@ const WS2PTOR_REGEXP = /^WS2PTOR ([a-f0-9]{8}) ([a-z0-9-_.]*|[0-9.]+|[0-9a-f:]+. const WS_FULL_ADDRESS_ONION_REGEX = /'^(?:wss?:\/\/)(?:www\.)?([0-9a-z]{16}\.onion)(:[0-9]+)?(\/[-\w]*)*/ const IPV4_REGEXP = /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/; const IPV6_REGEXP = /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(([0-9A-Fa-f]{1,4}:){0,5}:((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(::([0-9A-Fa-f]{1,4}:){0,5}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/; -const HOST_ONION_REGEX = /'^(?:www\.)?([0-9a-z]{16}\.onion)$'/ +const HOST_ONION_REGEX = /^(?:www\.)?([0-9a-z]{16}\.onion)$/ const MAXIMUM_LEN_OF_COMPACT_TX = 100 const MAXIMUM_LEN_OF_OUTPUT = 2000 diff --git a/app/modules/ws2p/lib/constants.ts b/app/modules/ws2p/lib/constants.ts index 1607a537c..ca457f1a9 100644 --- a/app/modules/ws2p/lib/constants.ts +++ b/app/modules/ws2p/lib/constants.ts @@ -9,7 +9,7 @@ export const WS2PConstants = { CONNEXION_TIMEOUT: 15000, REQUEST_TIMEOUT: 15000, CONNEXION_TOR_TIMEOUT: 30000, - REQUEST_TOR_TIMEOUT: 30000, + REQUEST_TOR_TIMEOUT: 60000, RECONNEXION_INTERVAL_IN_SEC: 60 * 10, // 10 minutes BLOCK_PULLING_INTERVAL: 300 * 2, // 10 minutes -- GitLab From 5e4997b5ef4f1ad569110835e5cb7dbb3b252a9e Mon Sep 17 00:00:00 2001 From: librelois <elois@ifee.fr> Date: Fri, 3 Nov 2017 21:48:48 +0100 Subject: [PATCH 32/34] [fix] wrong format WS_FULL_ADDRESS_ONION_REGEX --- app/lib/common-libs/constants.ts | 2 +- app/lib/proxy.ts | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/app/lib/common-libs/constants.ts b/app/lib/common-libs/constants.ts index d67a34036..89b6e7dba 100644 --- a/app/lib/common-libs/constants.ts +++ b/app/lib/common-libs/constants.ts @@ -34,7 +34,7 @@ const BMA_REGEXP = /^BASIC_MERKLED_API( ([a-z_][a-z0-9-_.]*))?( ([0-9.]+))?( ([ const BMATOR_REGEXP = /^BMATOR( ([a-z0-9]{16})\.onion)( ([0-9.]+))?( ([0-9a-f:]+))?( ([0-9]+))$/ const WS2P_REGEXP = /^WS2P ([a-f0-9]{8}) ([a-z_][a-z0-9-_.]*|[0-9.]+|[0-9a-f:]+) ([0-9]+)(?: (.+))?$/ const WS2PTOR_REGEXP = /^WS2PTOR ([a-f0-9]{8}) ([a-z0-9-_.]*|[0-9.]+|[0-9a-f:]+.onion) ([0-9]+)(?: (.+))?$/ -const WS_FULL_ADDRESS_ONION_REGEX = /'^(?:wss?:\/\/)(?:www\.)?([0-9a-z]{16}\.onion)(:[0-9]+)?(\/[-\w]*)*/ +const WS_FULL_ADDRESS_ONION_REGEX = /^(?:wss?:\/\/)(?:www\.)?([0-9a-z]{16}\.onion)(:[0-9]+)?$/ const IPV4_REGEXP = /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/; const IPV6_REGEXP = /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(([0-9A-Fa-f]{1,4}:){0,5}:((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(::([0-9A-Fa-f]{1,4}:){0,5}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/; const HOST_ONION_REGEX = /^(?:www\.)?([0-9a-z]{16}\.onion)$/ diff --git a/app/lib/proxy.ts b/app/lib/proxy.ts index 7df0703de..340de605c 100644 --- a/app/lib/proxy.ts +++ b/app/lib/proxy.ts @@ -2,9 +2,6 @@ import {CommonConstants} from "./common-libs/constants" const SocksProxyAgent = require('socks-proxy-agent'); -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 @@ -27,11 +24,11 @@ export class ProxiesConf { } static httpProxy(url:string, proxiesConf: ProxiesConf|undefined):string|undefined { - return ProxiesConf.chooseProxyAgent(url, proxiesConf, HOST_ONION_REGEX) + return ProxiesConf.chooseProxyAgent(url, proxiesConf, CommonConstants.HOST_ONION_REGEX) } static wsProxy(address:string, proxiesConf: ProxiesConf|undefined):string|undefined { - return ProxiesConf.chooseProxyAgent(address, proxiesConf, WS_FULL_ADDRESS_ONION_REGEX) + return ProxiesConf.chooseProxyAgent(address, proxiesConf, CommonConstants.WS_FULL_ADDRESS_ONION_REGEX) } private static chooseProxyAgent(address:string, proxiesConf: ProxiesConf|undefined, onionRegex:RegExp):string|undefined { -- GitLab From 8c33efe2fe7f7e2a706be0feccbc633e51e273e4 Mon Sep 17 00:00:00 2001 From: librelois <elois@ifee.fr> Date: Sat, 4 Nov 2017 01:45:27 +0100 Subject: [PATCH 33/34] [enh] prepare api type in head mesage --- app/modules/ws2p/lib/WS2PCluster.ts | 5 +++-- app/modules/ws2p/lib/constants.ts | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/modules/ws2p/lib/WS2PCluster.ts b/app/modules/ws2p/lib/WS2PCluster.ts index 875c552dd..701973334 100644 --- a/app/modules/ws2p/lib/WS2PCluster.ts +++ b/app/modules/ws2p/lib/WS2PCluster.ts @@ -291,7 +291,7 @@ export class WS2PCluster { async connectToRemoteWS(host: string, port: number, path:string, messageHandler:WS2PMessageHandler, expectedPub:string, ws2pEndpointUUID:string = ""): Promise<WS2PConnection> { const uuid = nuuid.v4() - let pub = "--------" + let pub = expectedPub.slice(0, 8) const api:string = (host.match(WS2PConstants.HOST_ONION_REGEX) !== null) ? 'WS2PTOR':'WS2P' try { const fullEndpointAddress = WS2PCluster.getFullAddress(host, port, path) @@ -463,13 +463,14 @@ export class WS2PCluster { } private sayHeadChangedTo(number:number, hash:string) { + const api = (this.server.conf.ws2p && this.server.conf.ws2p.remotehost && this.server.conf.ws2p.remotehost.match(WS2PConstants.HOST_ONION_REGEX)) ? 'WS2P':'WS2P' const key = new Key(this.server.conf.pair.pub, this.server.conf.pair.sec) const pub = key.publicKey const software = 'duniter' const softVersion = Package.getInstance().version const ws2pId = (this.server.conf.ws2p && this.server.conf.ws2p.uuid) || '00000000' const prefix = this.server.conf.prefix || Constants.DEFAULT_PEER_ID - const message = `WS2P:HEAD:1:${pub}:${number}-${hash}:${ws2pId}:${software}:${softVersion}:${prefix}` + const message = `${api}:HEAD:1:${pub}:${number}-${hash}:${ws2pId}:${software}:${softVersion}:${prefix}` const sig = key.signSync(message) return { sig, message, pub } } diff --git a/app/modules/ws2p/lib/constants.ts b/app/modules/ws2p/lib/constants.ts index ca457f1a9..8338f8dbf 100644 --- a/app/modules/ws2p/lib/constants.ts +++ b/app/modules/ws2p/lib/constants.ts @@ -30,7 +30,7 @@ export const WS2PConstants = { + CommonConstants.FORMATS.BLOCKSTAMP + '$'), - HEAD_V1_REGEXP: new RegExp('^WS2P:HEAD:1:' + HEAD_V1_REGEXP: new RegExp('^WS2P(?:TOR)?:HEAD:1:' + '(' + CommonConstants.FORMATS.PUBKEY + '):' + '(' + CommonConstants.FORMATS.BLOCKSTAMP + '):' + '(' + CommonConstants.FORMATS.WS2PID + '):' -- GitLab From b3100e4bbaa7174bc35f0a99e33c9d308bac7f37 Mon Sep 17 00:00:00 2001 From: librelois <elois@ifee.fr> Date: Sat, 4 Nov 2017 18:05:44 +0100 Subject: [PATCH 34/34] prepare api type details in head mesage --- app/modules/ws2p/lib/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/modules/ws2p/lib/constants.ts b/app/modules/ws2p/lib/constants.ts index 8338f8dbf..51972d7f7 100644 --- a/app/modules/ws2p/lib/constants.ts +++ b/app/modules/ws2p/lib/constants.ts @@ -30,7 +30,7 @@ export const WS2PConstants = { + CommonConstants.FORMATS.BLOCKSTAMP + '$'), - HEAD_V1_REGEXP: new RegExp('^WS2P(?:TOR)?:HEAD:1:' + HEAD_V1_REGEXP: new RegExp('^WS2P(?:O[CT][SAM])?(?:I[CT])?:HEAD:1:' + '(' + CommonConstants.FORMATS.PUBKEY + '):' + '(' + CommonConstants.FORMATS.BLOCKSTAMP + '):' + '(' + CommonConstants.FORMATS.WS2PID + '):' -- GitLab