fix ipv4/ipv6 address parsing and writing

This commit is contained in:
Manuel Araoz 2015-02-06 13:29:16 -03:00
parent 2489750913
commit 7119fad398
2 changed files with 53 additions and 40 deletions

View File

@ -39,7 +39,7 @@ var txHash = {
describe('Integration with ' + network.name + ' bitcoind', function() {
this.timeout(15000);
it.only('handshakes', function(cb) {
it('handshakes', function(cb) {
var peer = new Peer('localhost', network);
peer.once('version', function(m) {
m.version.should.be.above(70000);
@ -84,11 +84,9 @@ describe('Integration with ' + network.name + ' bitcoind', function() {
});
});
});
it.only('handles addr', function(cb) {
it('handles addr', function(cb) {
connect(function(peer) {
peer.once('addr', function(message) {
console.log(message.serialize(network).toString('hex'));
console.log(message.getPayload().toString('hex'));
message.addresses.forEach(function(address) {
// console.log(address.ip.v4 + ':' + address.port);
(address.time instanceof Date).should.equal(true);

View File

@ -254,28 +254,17 @@ Version.prototype.fromBuffer = function(payload) {
*/
this.relay = !!parser.readUInt8();
console.log(this);
$.checkState(parser.finished());
return this;
};
Version.writeAddr = function(addr, parser) {
if (_.isUndefined(addr)) {
parser.pad(26);
return;
}
parser.word64le(addr.services);
parser.put(addr.ip);
parser.word16be(addr.port);
};
Version.prototype.getPayload = function() {
var put = new Put();
put.word32le(this.version);
put.word64le(1); // services
put.word64le(Math.round(new Date().getTime() / 1000)); // timestamp
Version.writeAddr(this.addr_me, put);
Version.writeAddr(this.addr_you, put);
Addresses.writeAddr(this.addr_me, put);
Addresses.writeAddr(this.addr_you, put);
put.put(this.nonce);
put.varint(this.subversion.length);
put.put(new Buffer(this.subversion, 'ascii'));
@ -475,26 +464,58 @@ function Addresses(addresses) {
}
util.inherits(Addresses, Message);
Addresses.writeAddr = function(addr, put) {
if (_.isUndefined(addr)) {
put.pad(26);
return;
}
put.word64le(addr.services);
Addresses.writeIP(addr.ip, put);
put.word16be(addr.port);
};
Addresses.writeIP = function(ip, put) {
$.checkArgument(ip.v6, 'Need ipv6 to write IP');
var words = ip.v6.split(':').map(function(s) {
return new Buffer(s, 'hex');
});
for (var i = 0; i < words.length; i++) {
var word = words[i];
put.put(word);
}
};
// http://en.wikipedia.org/wiki/IPv6#IPv4-mapped_IPv6_addresses
Addresses.parseIP = function(parser) {
// parse the ipv6 to a string
var ipv6 = [];
for (var a = 0; a < 6; a++) {
ipv6.push(parser.read(2).toString('hex'));
var ipv4 = [];
for (var a = 0; a < 8; a++) {
var word = parser.read(2);
ipv6.push(word.toString('hex'));
if (a >= 6) {
ipv4.push(word[0]);
ipv4.push(word[1]);
}
}
ipv6 = ipv6.join(':');
// parse the ipv4 to a string
var ipv4 = [];
for (var b = 0; b < 4; b++) {
ipv4.push(parser.read(1)[0]);
}
ipv4 = ipv4.join('.');
return {
v6: ipv6,
v4: ipv4
};
};
Addresses.parseAddr = function(parser) {
var services = parser.readUInt64LEBN();
var ip = Addresses.parseIP(parser);
var port = parser.readUInt16BE();
return {
services: services,
ip: ip,
port: port
};
};
Addresses.prototype.fromBuffer = function(payload) {
var parser = new BufferReader(payload);
@ -503,18 +524,12 @@ Addresses.prototype.fromBuffer = function(payload) {
this.addresses = [];
for (var i = 0; i < addrCount; i++) {
// TODO: Time actually depends on the version of the other peer (>=31402)
var time = new Date(parser.readUInt32LE() * 1000);
var services = parser.readUInt64LEBN();
var ip = Addresses.parseIP(parser);
var port = parser.readUInt16BE();
this.addresses.push({
time: time,
services: services,
ip: ip,
port: port
});
var addr = Addresses.parseAddr(parser);
addr.time = time;
this.addresses.push(addr);
}
$.checkState(parser.finished());
@ -526,10 +541,10 @@ Addresses.prototype.getPayload = function() {
put.varint(this.addresses.length);
for (var i = 0; i < this.addresses.length; i++) {
put.word32le(this.addresses[i].time);
put.word64le(this.addresses[i].services);
put.put(this.addresses[i].ip);
put.word16be(this.addresses[i].port);
var addr = this.addresses[i];
put.word32le(addr.time);
Addresses.writeAddr(addr, put);
break;
}
return put.buffer();