net: add addrman serialization.
This commit is contained in:
parent
d26204479a
commit
74dbff2377
252
lib/net/pool.js
252
lib/net/pool.js
@ -1036,7 +1036,7 @@ Pool.prototype.handleAddr = function handleAddr(addrs, peer) {
|
||||
for (i = 0; i < addrs.length; i++) {
|
||||
addr = addrs[i];
|
||||
|
||||
if (addr.isNull())
|
||||
if (!addr.isRoutable())
|
||||
continue;
|
||||
|
||||
if (!addr.hasServices(this.needed))
|
||||
@ -1574,7 +1574,7 @@ Pool.prototype.getHost = function getHost(unique) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (addr.isNull())
|
||||
if (!addr.isValid())
|
||||
continue;
|
||||
|
||||
if (!addr.hasServices(this.needed))
|
||||
@ -1820,7 +1820,6 @@ Pool.prototype.hasBlock = co(function* hasBlock(hash) {
|
||||
*/
|
||||
|
||||
Pool.prototype.getTX = function getTX(peer, hash) {
|
||||
var self = this;
|
||||
var item;
|
||||
|
||||
if (!this.loaded)
|
||||
@ -2889,6 +2888,136 @@ HostList.prototype.populate = co(function* populate(seed) {
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Convert host list to json-friendly object.
|
||||
* @returns {Object}
|
||||
*/
|
||||
|
||||
HostList.prototype.toJSON = function toJSON() {
|
||||
var addrs = [];
|
||||
var fresh = [];
|
||||
var used = [];
|
||||
var i, keys, key, bucket, entry;
|
||||
|
||||
keys = Object.keys(this.map);
|
||||
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
key = keys[i];
|
||||
entry = this.map[key];
|
||||
addrs.push(entry.toJSON());
|
||||
}
|
||||
|
||||
for (i = 0; i < this.fresh.length; i++) {
|
||||
bucket = this.fresh[i];
|
||||
keys = bucket.keys();
|
||||
fresh.push(keys);
|
||||
}
|
||||
|
||||
for (i = 0; i < this.used.length; i++) {
|
||||
bucket = this.used[i];
|
||||
keys = [];
|
||||
for (entry = bucket.head; entry; entry = entry.next)
|
||||
keys.push(entry.key());
|
||||
used.push(keys);
|
||||
}
|
||||
|
||||
return {
|
||||
version: 1,
|
||||
addrs: addrs,
|
||||
fresh: fresh,
|
||||
used: used
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from json object.
|
||||
* @private
|
||||
* @param {Object} json
|
||||
* @returns {HostList}
|
||||
*/
|
||||
|
||||
HostList.prototype.fromJSON = function fromJSON(json) {
|
||||
var sources = {};
|
||||
var i, j, bucket, keys, key, addr, entry, src;
|
||||
|
||||
assert(json && typeof json === 'object');
|
||||
assert(json.version === 1, 'Bad address serialization version.');
|
||||
|
||||
assert(Array.isArray(json.addrs));
|
||||
|
||||
for (i = 0; i < json.addrs.length; i++) {
|
||||
addr = json.addrs[i];
|
||||
entry = HostEntry.fromJSON(addr, this.network);
|
||||
src = sources[entry.src.hostname];
|
||||
|
||||
// Save some memory.
|
||||
if (!src) {
|
||||
src = entry.src;
|
||||
sources[src.hostname] = src;
|
||||
}
|
||||
|
||||
entry.src = src;
|
||||
|
||||
this.map[entry.key()] = entry;
|
||||
}
|
||||
|
||||
assert(Array.isArray(json.fresh));
|
||||
|
||||
for (i = 0; i < json.fresh.length; i++) {
|
||||
keys = json.fresh[i];
|
||||
bucket = this.fresh[i];
|
||||
assert(bucket, 'No bucket available.');
|
||||
for (j = 0; j < keys.length; j++) {
|
||||
key = keys[j];
|
||||
entry = this.map[key];
|
||||
assert(entry);
|
||||
if (entry.refCount === 0)
|
||||
this.totalFresh++;
|
||||
entry.refCount++;
|
||||
bucket.set(key, entry);
|
||||
}
|
||||
}
|
||||
|
||||
assert(Array.isArray(json.used));
|
||||
|
||||
for (i = 0; i < json.used.length; i++) {
|
||||
keys = json.used[i];
|
||||
bucket = this.used[i];
|
||||
assert(bucket, 'No bucket available.');
|
||||
for (j = 0; j < keys.length; j++) {
|
||||
key = keys[j];
|
||||
entry = this.map[key];
|
||||
assert(entry);
|
||||
assert(entry.refCount === 0);
|
||||
assert(!entry.used);
|
||||
entry.used = true;
|
||||
this.totalUsed++;
|
||||
bucket.push(entry);
|
||||
}
|
||||
}
|
||||
|
||||
keys = Object.keys(this.map);
|
||||
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
key = keys[i];
|
||||
entry = this.map[key];
|
||||
assert(entry.used || entry.refCount > 0);
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate host list from json object.
|
||||
* @param {Object} options
|
||||
* @param {Object} json
|
||||
* @returns {HostList}
|
||||
*/
|
||||
|
||||
HostList.fromJSON = function fromJSON(options, json) {
|
||||
return new HostEntry(options).fromJSON(json);
|
||||
};
|
||||
|
||||
/**
|
||||
* MapBucket
|
||||
* @constructor
|
||||
@ -2981,14 +3110,15 @@ MapBucket.prototype.reset = function reset() {
|
||||
* HostEntry
|
||||
* @constructor
|
||||
* @param {NetAddress} addr
|
||||
* @param {NetAddress} src
|
||||
*/
|
||||
|
||||
function HostEntry(addr, src) {
|
||||
assert(addr instanceof NetAddress);
|
||||
assert(src instanceof NetAddress);
|
||||
if (!(this instanceof HostEntry))
|
||||
return new HostEntry(addr, src);
|
||||
|
||||
this.addr = addr;
|
||||
this.src = src;
|
||||
this.addr = addr || new NetAddress();
|
||||
this.src = src || new NetAddress();
|
||||
this.prev = null;
|
||||
this.next = null;
|
||||
this.used = false;
|
||||
@ -2996,8 +3126,38 @@ function HostEntry(addr, src) {
|
||||
this.attempts = 0;
|
||||
this.lastSuccess = 0;
|
||||
this.lastAttempt = 0;
|
||||
|
||||
if (addr)
|
||||
this.fromOptions(addr, src);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject properties from options.
|
||||
* @private
|
||||
* @param {NetAddress} addr
|
||||
* @param {NetAddress} src
|
||||
* @returns {HostEntry}
|
||||
*/
|
||||
|
||||
HostEntry.prototype.fromOptions = function fromOptions(addr, src) {
|
||||
assert(addr instanceof NetAddress);
|
||||
assert(src instanceof NetAddress);
|
||||
this.addr = addr;
|
||||
this.src = src;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate host entry from options.
|
||||
* @param {NetAddress} addr
|
||||
* @param {NetAddress} src
|
||||
* @returns {HostEntry}
|
||||
*/
|
||||
|
||||
HostEntry.fromOptions = function fromOptions(addr, src) {
|
||||
return new HostEntry().fromOptions(addr, src);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get key suitable for a hash table (hostname).
|
||||
* @returns {String}
|
||||
@ -3042,6 +3202,84 @@ HostEntry.prototype.inspect = function inspect() {
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert host entry to json-friendly object.
|
||||
* @returns {Object}
|
||||
*/
|
||||
|
||||
HostEntry.prototype.toJSON = function toJSON() {
|
||||
return {
|
||||
addr: this.addr.hostname,
|
||||
src: this.src.hostname,
|
||||
services: this.addr.services.toString(2),
|
||||
ts: this.addr.ts,
|
||||
attempts: this.attempts,
|
||||
lastSuccess: this.lastSuccess,
|
||||
lastAttempt: this.lastAttempt
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from json object.
|
||||
* @private
|
||||
* @param {Object} json
|
||||
* @param {Network} network
|
||||
* @returns {HostEntry}
|
||||
*/
|
||||
|
||||
HostEntry.prototype.fromJSON = function fromJSON(json, network) {
|
||||
assert(json && typeof json === 'object');
|
||||
assert(typeof json.addr === 'string');
|
||||
assert(typeof json.src === 'string');
|
||||
|
||||
this.addr.fromHostname(json.addr, network);
|
||||
|
||||
if (json.services != null) {
|
||||
assert(typeof json.services === 'string');
|
||||
assert(json.services.length > 0);
|
||||
assert(json.services.length < 64);
|
||||
this.addr.services = parseInt(json.services, 2);
|
||||
}
|
||||
|
||||
if (json.ts != null) {
|
||||
assert(util.isNumber(json.ts));
|
||||
this.addr.ts = json.ts;
|
||||
}
|
||||
|
||||
if (json.src != null) {
|
||||
assert(typeof json.src === 'string');
|
||||
this.src.fromHostname(json.src, network);
|
||||
}
|
||||
|
||||
if (json.attempts != null) {
|
||||
assert(util.isNumber(json.attempts));
|
||||
this.attempts = json.attempts;
|
||||
}
|
||||
|
||||
if (json.lastSuccess != null) {
|
||||
assert(util.isNumber(json.lastSuccess));
|
||||
this.lastSuccess = json.lastSuccess;
|
||||
}
|
||||
|
||||
if (json.lastAttempt != null) {
|
||||
assert(util.isNumber(json.lastAttempt));
|
||||
this.lastAttempt = json.lastAttempt;
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate host entry from json object.
|
||||
* @param {Object} json
|
||||
* @param {Network} network
|
||||
* @returns {HostEntry}
|
||||
*/
|
||||
|
||||
HostEntry.fromJSON = function fromJSON(json, network) {
|
||||
return new HostEntry().fromJSON(json, network);
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents an in-flight block or transaction.
|
||||
* @exports LoadRequest
|
||||
|
||||
@ -135,7 +135,52 @@ NetAddress.prototype.hasServices = function hasServices(services) {
|
||||
*/
|
||||
|
||||
NetAddress.prototype.isNull = function isNull() {
|
||||
return this.host === '0.0.0.0' || this.host === '::';
|
||||
return IP.isNull(this.host);
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether the host is a broadcast address.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
NetAddress.prototype.isBroadcast = function isBroadcast() {
|
||||
return IP.isBroadcast(this.host);
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether the host is a local address.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
NetAddress.prototype.isLoopback = function isLoopback() {
|
||||
return IP.isLoopback(this.host);
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether the host is a private address.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
NetAddress.prototype.isPrivate = function isPrivate() {
|
||||
return IP.isPrivate(this.host);
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether the host is valid.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
NetAddress.prototype.isValid = function isValid() {
|
||||
return IP.isValid(this.host);
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether the host is routable.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
NetAddress.prototype.isRoutable = function isRoutable() {
|
||||
return IP.isRoutable(this.host);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -335,6 +380,51 @@ NetAddress.prototype.toRaw = function toRaw(full) {
|
||||
return this.toWriter(new StaticWriter(size), full).render();
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert net address to json-friendly object.
|
||||
* @returns {Object}
|
||||
*/
|
||||
|
||||
NetAddress.prototype.toJSON = function toJSON() {
|
||||
return {
|
||||
host: this.host,
|
||||
port: this.port,
|
||||
services: this.services,
|
||||
ts: this.ts
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from json object.
|
||||
* @private
|
||||
* @param {Object} json
|
||||
* @returns {NetAddress}
|
||||
*/
|
||||
|
||||
NetAddress.prototype.fromJSON = function fromJSON(json) {
|
||||
assert(IP.version(json.host) !== -1);
|
||||
assert(util.isNumber(json.port));
|
||||
assert(json.port >= 0 && json.port <= 0xffff);
|
||||
assert(util.isNumber(json.services));
|
||||
assert(util.isNumber(json.ts));
|
||||
this.host = json.host;
|
||||
this.port = json.port;
|
||||
this.services = json.services;
|
||||
this.ts = json.ts;
|
||||
this.hostname = IP.hostname(this.host, this.port);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate net address from json object.
|
||||
* @param {Object} json
|
||||
* @returns {NetAddress}
|
||||
*/
|
||||
|
||||
NetAddress.fromJSON = function fromJSON(json) {
|
||||
return new NetAddress().fromJSON(json);
|
||||
};
|
||||
|
||||
/**
|
||||
* Inspect the network address.
|
||||
* @returns {Object}
|
||||
|
||||
@ -157,7 +157,7 @@ IP.version = function version(str) {
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
IP.isV4Format = function(str) {
|
||||
IP.isV4Format = function isV4Format(str) {
|
||||
assert(typeof str === 'string');
|
||||
|
||||
if (str.length < 7)
|
||||
@ -175,7 +175,7 @@ IP.isV4Format = function(str) {
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
IP.isV6Format = function(str) {
|
||||
IP.isV6Format = function isV6Format(str) {
|
||||
assert(typeof str === 'string');
|
||||
|
||||
if (str.length < 2)
|
||||
@ -216,7 +216,7 @@ IP.isMapped = function isMapped(buf) {
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
IP.toBuffer = function(str) {
|
||||
IP.toBuffer = function toBuffer(str) {
|
||||
var buf = new Buffer(16);
|
||||
|
||||
assert(typeof str === 'string');
|
||||
@ -336,7 +336,7 @@ IP.parseV6 = function parseV6(str, buf, offset) {
|
||||
* @returns {String}
|
||||
*/
|
||||
|
||||
IP.toString = function(buf) {
|
||||
IP.toString = function toString(buf) {
|
||||
var str = '';
|
||||
var i;
|
||||
|
||||
@ -385,13 +385,54 @@ IP.normalize = function normalize(str) {
|
||||
return IP.toString(IP.toBuffer(str));
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether an IP is null.
|
||||
* @param {String} str - Normalized ip.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
IP.isNull = function isNull(str) {
|
||||
return str === '0.0.0.0' || str === '::';
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether the IP is a broadcast address.
|
||||
* @param {String} str - Normalized ip.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
IP.isBroadcast = function isBroadcast(str) {
|
||||
return str === '255.255.255.255'
|
||||
|| str === '::ffff:ffff:ffff';
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether the IP is valid.
|
||||
* @param {String} str - Normalized ip.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
IP.isValid = function isValid(str) {
|
||||
return !IP.isNull(str) && !IP.isBroadcast(str);
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether the IP is routable.
|
||||
* @param {String} str - Normalized ip.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
IP.isRoutable = function isRoutable(str) {
|
||||
return IP.isValid(str) && !IP.isLoopback(str);
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether a string is a private address.
|
||||
* @param {String} str
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
IP.isPrivate = function(str) {
|
||||
IP.isPrivate = function isPrivate(str) {
|
||||
assert(typeof str === 'string');
|
||||
|
||||
return /^(::f{4}:)?10\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(str)
|
||||
@ -411,7 +452,7 @@ IP.isPrivate = function(str) {
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
IP.isPublic = function(str) {
|
||||
IP.isPublic = function isPublic(str) {
|
||||
return !IP.isPrivate(str);
|
||||
};
|
||||
|
||||
@ -421,7 +462,7 @@ IP.isPublic = function(str) {
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
IP.isLoopback = function(str) {
|
||||
IP.isLoopback = function isLoopback(str) {
|
||||
assert(typeof str === 'string');
|
||||
|
||||
return /^(::f{4}:)?127\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})/.test(str)
|
||||
@ -436,7 +477,7 @@ IP.isLoopback = function(str) {
|
||||
* @returns {String}
|
||||
*/
|
||||
|
||||
IP.loopback = function(family) {
|
||||
IP.loopback = function loopback(family) {
|
||||
if (!family)
|
||||
family = 'ipv4';
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user