net: tor support for outgoing conns.
This commit is contained in:
parent
5288e8a619
commit
5073c1508f
@ -162,7 +162,7 @@ WSProxy.prototype._handleConnect = function _handleConnect(ws, port, host, nonce
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IP.isRoutable(raw) || IP.isTor(raw)) {
|
||||
if (!IP.isRoutable(raw) || IP.isOnion(raw)) {
|
||||
this.log(
|
||||
'Client is trying to connect to a bad ip: %s (%s).',
|
||||
host, state.host);
|
||||
|
||||
@ -59,8 +59,9 @@ listen: true
|
||||
max-outbound: 8
|
||||
max-inbound: 30
|
||||
|
||||
# Websocket Proxy Server (Browser Only)
|
||||
proxy-server: localhost
|
||||
# Proxy Server (browser=websockets, node=socks)
|
||||
# proxy: foo:bar@127.0.0.1:9050
|
||||
# onion: true
|
||||
|
||||
# Custom list of DNS seeds
|
||||
# seeds: seed.bitcoin.sipa.be
|
||||
|
||||
@ -468,7 +468,6 @@ function AuthDB(options) {
|
||||
|
||||
this.logger = null;
|
||||
this.resolve = dns.resolve;
|
||||
this.proxyServer = null;
|
||||
this.dnsKnown = [];
|
||||
|
||||
this.known = {};
|
||||
@ -496,11 +495,6 @@ AuthDB.prototype._init = function _init(options) {
|
||||
this.resolve = options.resolve;
|
||||
}
|
||||
|
||||
if (options.proxyServer != null) {
|
||||
assert(typeof options.proxyServer === 'string');
|
||||
this.proxyServer = options.proxyServer;
|
||||
}
|
||||
|
||||
if (options.knownPeers != null) {
|
||||
assert(typeof options.knownPeers === 'object');
|
||||
this.setKnown(options.knownPeers);
|
||||
@ -638,7 +632,7 @@ AuthDB.prototype.populate = co(function* populate(addr, key) {
|
||||
this.logger.info('Resolving authorized hosts from: %s.', addr.host);
|
||||
|
||||
try {
|
||||
hosts = yield this.resolve(addr.host, this.proxyServer);
|
||||
hosts = yield this.resolve(addr.host);
|
||||
} catch (e) {
|
||||
if (this.logger)
|
||||
this.logger.error(e);
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
var ProxySocket = require('./proxysocket');
|
||||
var socket;
|
||||
|
||||
exports.resolve = function resolve(host, proxy) {
|
||||
exports.resolve = function resolve(host, proxy, onion) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
if (!socket)
|
||||
socket = new ProxySocket(proxy);
|
||||
@ -30,6 +30,6 @@ exports.resolve = function resolve(host, proxy) {
|
||||
});
|
||||
};
|
||||
|
||||
exports.lookup = function lookup(host, proxy) {
|
||||
return exports.resolve(host, proxy);
|
||||
exports.lookup = function lookup(host, proxy, onion) {
|
||||
return exports.resolve(host, proxy, onion);
|
||||
};
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
'use strict';
|
||||
|
||||
var dns = require('dns');
|
||||
var socks = require('./socks');
|
||||
|
||||
var options = {
|
||||
family: 4,
|
||||
@ -14,7 +15,10 @@ var options = {
|
||||
all: true
|
||||
};
|
||||
|
||||
exports.resolve = function resolve(host, proxy) {
|
||||
exports.resolve = function resolve(host, proxy, onion) {
|
||||
if (proxy && onion)
|
||||
return socks.resolve(host, proxy);
|
||||
|
||||
return new Promise(function(resolve, reject) {
|
||||
dns.resolve(host, 'A', function(err, result) {
|
||||
if (err) {
|
||||
@ -32,7 +36,10 @@ exports.resolve = function resolve(host, proxy) {
|
||||
});
|
||||
};
|
||||
|
||||
exports.lookup = function lookup(host, proxy) {
|
||||
exports.lookup = function lookup(host, proxy, onion) {
|
||||
if (proxy && onion)
|
||||
return socks.resolve(host, proxy);
|
||||
|
||||
return new Promise(function(resolve, reject) {
|
||||
var addrs = [];
|
||||
var i, addr;
|
||||
|
||||
@ -32,7 +32,6 @@ function HostList(options) {
|
||||
this.network = Network.primary;
|
||||
this.logger = null;
|
||||
this.address = new NetAddress();
|
||||
this.proxyServer = null;
|
||||
this.resolve = dns.resolve;
|
||||
this.banTime = common.BAN_TIME;
|
||||
|
||||
@ -89,11 +88,6 @@ HostList.prototype._initOptions = function initOptions(options) {
|
||||
this.address = options.address;
|
||||
}
|
||||
|
||||
if (options.proxyServer != null) {
|
||||
assert(typeof options.proxyServer === 'string');
|
||||
this.proxyServer = options.proxyServer;
|
||||
}
|
||||
|
||||
if (options.resolve != null) {
|
||||
assert(typeof options.resolve === 'function');
|
||||
this.resolve = options.resolve;
|
||||
@ -804,7 +798,7 @@ HostList.prototype.populate = co(function* populate(target) {
|
||||
this.logger.info('Resolving host: %s.', target.host);
|
||||
|
||||
try {
|
||||
hosts = yield this.resolve(target.host, this.proxyServer);
|
||||
hosts = yield this.resolve(target.host);
|
||||
} catch (e) {
|
||||
if (this.logger)
|
||||
this.logger.error(e);
|
||||
|
||||
@ -417,12 +417,11 @@ Peer.prototype.accept = function accept(socket) {
|
||||
*/
|
||||
|
||||
Peer.prototype.connect = function connect(addr) {
|
||||
var proxy = this.options.proxyServer;
|
||||
var socket;
|
||||
|
||||
assert(!this.socket);
|
||||
|
||||
socket = this.options.createSocket(addr.port, addr.host, proxy);
|
||||
socket = this.options.createSocket(addr.port, addr.host);
|
||||
|
||||
this.address = addr;
|
||||
this.ts = util.now();
|
||||
@ -2156,7 +2155,6 @@ function PeerOptions(options) {
|
||||
this.network = Network.primary;
|
||||
this.logger = Logger.global;
|
||||
|
||||
this.proxyServer = null;
|
||||
this.createSocket = tcp.createSocket;
|
||||
this.version = common.PROTOCOL_VERSION;
|
||||
this.services = common.LOCAL_SERVICES;
|
||||
@ -2197,11 +2195,6 @@ PeerOptions.prototype.fromOptions = function fromOptions(options) {
|
||||
this.logger = options.logger;
|
||||
}
|
||||
|
||||
if (options.proxyServer != null) {
|
||||
assert(typeof options.proxyServer === 'string');
|
||||
this.proxyServer = options.proxyServer;
|
||||
}
|
||||
|
||||
if (options.createSocket != null) {
|
||||
assert(typeof options.createSocket === 'function');
|
||||
this.createSocket = options.createSocket;
|
||||
|
||||
@ -291,7 +291,7 @@ Pool.prototype._connect = co(function* connect() {
|
||||
|
||||
yield this.listen();
|
||||
|
||||
if (this.address.isNull()) {
|
||||
if (this.address.isNull() && !this.options.proxy) {
|
||||
try {
|
||||
ip = yield this.getIP();
|
||||
} catch (e) {
|
||||
@ -1291,6 +1291,9 @@ Pool.prototype.handleAddr = co(function* handleAddr(peer, packet) {
|
||||
if (!addr.hasServices(services))
|
||||
continue;
|
||||
|
||||
if (!this.options.onion && addr.isOnion())
|
||||
continue;
|
||||
|
||||
if (addr.ts <= 100000000 || addr.ts > now + 10 * 60)
|
||||
addr.ts = now - 5 * 24 * 60 * 60;
|
||||
|
||||
@ -2653,6 +2656,9 @@ Pool.prototype.getHost = function getHost() {
|
||||
if (!addr.hasServices(services))
|
||||
continue;
|
||||
|
||||
if (!this.options.onion && addr.isOnion())
|
||||
continue;
|
||||
|
||||
if (i < 30 && now - entry.lastAttempt < 600)
|
||||
continue;
|
||||
|
||||
@ -3222,10 +3228,11 @@ function PoolOptions(options) {
|
||||
this.port = this.network.port;
|
||||
this.maxOutbound = 8;
|
||||
this.maxInbound = 8;
|
||||
this.createSocket = tcp.createSocket;
|
||||
this.createSocket = this._createSocket;
|
||||
this.createServer = tcp.createServer;
|
||||
this.resolve = dns.resolve;
|
||||
this.proxyServer = null;
|
||||
this.resolve = this._resolve;
|
||||
this.proxy = null;
|
||||
this.onion = false;
|
||||
this.selfish = false;
|
||||
this.version = common.PROTOCOL_VERSION;
|
||||
this.agent = common.USER_AGENT;
|
||||
@ -3362,9 +3369,14 @@ PoolOptions.prototype.fromOptions = function fromOptions(options) {
|
||||
this.resolve = options.resolve;
|
||||
}
|
||||
|
||||
if (options.proxyServer) {
|
||||
assert(typeof options.proxyServer === 'string');
|
||||
this.proxyServer = options.proxyServer;
|
||||
if (options.proxy) {
|
||||
assert(typeof options.proxy === 'string');
|
||||
this.proxy = options.proxy;
|
||||
}
|
||||
|
||||
if (options.onion) {
|
||||
assert(typeof options.onion === 'boolean');
|
||||
this.onion = options.onion;
|
||||
}
|
||||
|
||||
if (options.selfish) {
|
||||
@ -3454,6 +3466,7 @@ PoolOptions.prototype.fromOptions = function fromOptions(options) {
|
||||
this.checkpoints = true;
|
||||
this.compact = false;
|
||||
this.bip37 = false;
|
||||
this.listen = false;
|
||||
}
|
||||
|
||||
if (this.selfish) {
|
||||
@ -3464,6 +3477,9 @@ PoolOptions.prototype.fromOptions = function fromOptions(options) {
|
||||
if (this.bip37)
|
||||
this.services |= common.services.BLOOM;
|
||||
|
||||
if (this.proxy)
|
||||
this.listen = false;
|
||||
|
||||
if (options.services != null) {
|
||||
assert(util.isUInt32(options.services));
|
||||
this.services = options.services;
|
||||
@ -3576,6 +3592,29 @@ PoolOptions.prototype.getRate = function getRate(hash) {
|
||||
return entry.getRate();
|
||||
};
|
||||
|
||||
/**
|
||||
* Default createSocket call.
|
||||
* @private
|
||||
* @param {Number} port
|
||||
* @param {String} host
|
||||
* @returns {net.Socket}
|
||||
*/
|
||||
|
||||
PoolOptions.prototype._createSocket = function createSocket(port, host) {
|
||||
return tcp.createSocket(port, host, this.proxy);
|
||||
};
|
||||
|
||||
/**
|
||||
* Default resolve call.
|
||||
* @private
|
||||
* @param {String} name
|
||||
* @returns {String[]}
|
||||
*/
|
||||
|
||||
PoolOptions.prototype._resolve = function resolve(name) {
|
||||
return dns.resolve(name, this.proxy, this.onion);
|
||||
};
|
||||
|
||||
/**
|
||||
* Peer List
|
||||
* @constructor
|
||||
|
||||
@ -8,9 +8,12 @@
|
||||
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
var net = require('net');
|
||||
var socks = require('./socks');
|
||||
var tcp = exports;
|
||||
|
||||
tcp.createSocket = function createSocket(port, host, proxy) {
|
||||
if (proxy)
|
||||
return socks.connect(proxy, port, host);
|
||||
return net.connect(port, host);
|
||||
};
|
||||
|
||||
|
||||
@ -192,7 +192,8 @@ config.parseData = function parseData(data, prefix, dirname) {
|
||||
options.bip151 = bool(data.bip151);
|
||||
options.bip150 = bool(data.bip150);
|
||||
options.identityKey = key(data.identitykey);
|
||||
options.proxyServer = str(data.proxyserver);
|
||||
options.proxy = str(data.proxy);
|
||||
options.onion = bool(data.onion);
|
||||
options.seeds = list(data.seeds);
|
||||
options.nodes = list(data.nodes);
|
||||
options.maxOutbound = num(data.maxoutbound);
|
||||
|
||||
@ -110,7 +110,8 @@ function FullNode(options) {
|
||||
identityKey: this.options.identityKey,
|
||||
maxOutbound: this.options.maxOutbound,
|
||||
maxInbound: this.options.maxInbound,
|
||||
proxyServer: this.options.proxyServer,
|
||||
proxy: this.options.proxy,
|
||||
onion: this.options.onion,
|
||||
seeds: this.options.seeds,
|
||||
nodes: this.options.nodes,
|
||||
publicHost: this.options.publicHost,
|
||||
|
||||
@ -60,7 +60,8 @@ function SPVNode(options) {
|
||||
network: this.network,
|
||||
logger: this.logger,
|
||||
chain: this.chain,
|
||||
proxyServer: this.options.proxyServer,
|
||||
proxy: this.options.proxy,
|
||||
onion: this.options.onion,
|
||||
seeds: this.options.seeds,
|
||||
nodes: this.options.nodes,
|
||||
bip151: this.options.bip151,
|
||||
|
||||
@ -164,8 +164,8 @@ NetAddress.prototype.isRoutable = function isRoutable() {
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
NetAddress.prototype.isTor = function isTor() {
|
||||
return IP.isTor(this.raw);
|
||||
NetAddress.prototype.isOnion = function isOnion() {
|
||||
return IP.isOnion(this.raw);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -47,7 +47,7 @@ IP.types = {
|
||||
DNS: -1,
|
||||
IPV4: 4,
|
||||
IPV6: 6,
|
||||
TOR: 10
|
||||
ONION: 10
|
||||
};
|
||||
|
||||
/**
|
||||
@ -178,8 +178,8 @@ IP.getStringType = function getStringType(str) {
|
||||
if (IP.isV6String(str))
|
||||
return IP.types.IPV6;
|
||||
|
||||
if (IP.isTorString(str))
|
||||
return IP.types.TOR;
|
||||
if (IP.isOnionString(str))
|
||||
return IP.types.ONION;
|
||||
|
||||
return IP.types.DNS;
|
||||
};
|
||||
@ -226,7 +226,7 @@ IP.isV6String = function isV6String(str) {
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
IP.isTorString = function isTorString(str) {
|
||||
IP.isOnionString = function isOnionString(str) {
|
||||
assert(typeof str === 'string');
|
||||
|
||||
if (str.length < 7)
|
||||
@ -278,7 +278,7 @@ IP.toBuffer = function toBuffer(str) {
|
||||
return IP.parseV4(str, raw, 12);
|
||||
}
|
||||
|
||||
if (IP.isTorString(str)) {
|
||||
if (IP.isOnionString(str)) {
|
||||
data = TOR_ONION;
|
||||
data.copy(raw, 0);
|
||||
data = base32.decode(str.slice(0, -6));
|
||||
@ -420,7 +420,7 @@ IP.toString = function toString(raw) {
|
||||
return host;
|
||||
}
|
||||
|
||||
if (IP.isTor(raw)) {
|
||||
if (IP.isOnion(raw)) {
|
||||
host = base32.encode(raw.slice(6));
|
||||
return host + '.onion';
|
||||
}
|
||||
@ -466,7 +466,7 @@ IP.isIPv4 = function isIPv4(raw) {
|
||||
*/
|
||||
|
||||
IP.isIPv6 = function isIPv6(raw) {
|
||||
return !IP.isMapped(raw) && !IP.isTor(raw);
|
||||
return !IP.isMapped(raw) && !IP.isOnion(raw);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -482,8 +482,8 @@ IP.getType = function getType(raw) {
|
||||
if (IP.isIPv6(raw))
|
||||
return IP.types.IPV6;
|
||||
|
||||
if (IP.isTor(raw))
|
||||
return IP.types.TOR;
|
||||
if (IP.isOnion(raw))
|
||||
return IP.types.ONION;
|
||||
|
||||
assert(false, 'Unknown type.');
|
||||
};
|
||||
@ -727,7 +727,7 @@ IP.isRFC4843 = function isRFC4843(raw) {
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
IP.isTor = function isTor(raw) {
|
||||
IP.isOnion = function isOnion(raw) {
|
||||
return IP.hasPrefix(raw, TOR_ONION);
|
||||
};
|
||||
|
||||
@ -815,7 +815,7 @@ IP.isRoutable = function isRoutable(raw) {
|
||||
if (IP.isRFC5737(raw))
|
||||
return false;
|
||||
|
||||
if (IP.isRFC4193(raw) && !IP.isTor(raw))
|
||||
if (IP.isRFC4193(raw) && !IP.isOnion(raw))
|
||||
return false;
|
||||
|
||||
if (IP.isRFC4843(raw))
|
||||
|
||||
Loading…
Reference in New Issue
Block a user