listen for incoming connections

This commit is contained in:
Patrick Nagurny 2015-03-12 18:22:45 -04:00
parent faf2bb1868
commit 7f61fc62d4
3 changed files with 93 additions and 22 deletions

View File

@ -8,6 +8,10 @@ var BufferUtil = bitcore.util.buffer;
var magicNumber = bitcore.Networks.defaultNetwork.networkMagic.readUInt32LE(0);
function VerackMessage(options) {
if(!options) {
options = {};
}
Message.call(this, options);
this.magicNumber = magicNumber;
this.command = 'verack';

View File

@ -38,10 +38,17 @@ function Peer(options) {
return new Peer(options);
}
this.host = options.host || 'localhost';
this.status = Peer.STATUS.DISCONNECTED;
this.port = options.port;
if(options.socket) {
this.socket = options.socket;
this.host = this.socket.remoteAddress;
this.port = this.socket.remotePort;
this.status = Peer.STATUS.CONNECTED;
this._addSocketEventHandlers();
} else {
this.host = options.host || 'localhost';
this.status = Peer.STATUS.DISCONNECTED;
this.port = options.port;
}
this.network = Networks.get(options.network) || Networks.defaultNetwork;
if (!this.port) {
@ -61,6 +68,8 @@ function Peer(options) {
this.subversion = null;
this.relay = options.relay === false ? false : true;
this.versionSent = false;
// set message handlers
var self = this;
this.on('verack', function() {
@ -72,6 +81,13 @@ function Peer(options) {
self.version = message.version;
self.subversion = message.subversion;
self.bestHeight = message.startHeight;
var verackResponse = self.messages.build('verack');
self.sendMessage(verackResponse);
if(!self.versionSent) {
self._sendVersion();
}
});
this.on('ping', function(message) {
@ -122,6 +138,14 @@ Peer.prototype.connect = function() {
self._sendVersion();
});
this._addSocketEventHandlers();
this.socket.connect(this.port, this.host);
return this;
};
Peer.prototype._addSocketEventHandlers = function() {
var self = this;
this.socket.on('error', self._onError.bind(this));
this.socket.on('end', self.disconnect.bind(this));
@ -134,13 +158,11 @@ Peer.prototype.connect = function() {
}
self._readMessage();
});
this.socket.connect(this.port, this.host);
return this;
};
Peer.prototype._onError = function(e) {
this.emit('error', e);
this.disconnect();
};
/**
@ -172,6 +194,7 @@ Peer.prototype._sendVersion = function() {
var message = this.messages.build('version', {
relay: this.relay
});
this.versionSent = true;
this.sendMessage(message);
};

View File

@ -7,6 +7,7 @@ var sha256 = bitcore.crypto.Hash.sha256;
var Peer = require('./peer');
var Networks = bitcore.Networks;
var util = require('util');
var net = require('net');
function now() {
return Math.floor(new Date().getTime() / 1000);
@ -126,6 +127,8 @@ Pool.prototype.connect = function connect() {
} else {
self._fillConnections();
}
this.listen();
return this;
};
@ -185,40 +188,61 @@ Pool.prototype._removeConnectedPeer = function _removeConnectedPeer(addr) {
Pool.prototype._connectPeer = function _connectPeer(addr) {
var self = this;
function addConnectedPeer(addr) {
if (!this._connectedPeers[addr.hash]) {
var port = addr.port || self.network.port;
var ip = addr.ip.v4 || addr.ip.v6;
var peer = new Peer({
ip: ip,
host: ip,
port: port,
messages: self.messages,
relay: self.relay
});
peer.on('disconnect', function peerDisconnect() {
self.emit('peerdisconnect', peer, addr);
});
peer.on('connect', function peerConnect() {
self.emit('peerconnect', peer, addr);
});
peer.on('ready', function peerReady() {
self.emit('peerready', peer, addr);
});
Pool.PeerEvents.forEach(function addPeerEvents(event) {
peer.on(event, function peerEvent(message) {
self.emit('peer' + event, peer, message);
});
});
self._addPeerEventHandlers(peer, addr);
peer.connect();
self._connectedPeers[addr.hash] = peer;
}
return this;
};
Pool.prototype._addConnectedPeer = function _addConnectedPeer(socket, addr) {
var self = this;
if (!this._connectedPeers[addr.hash]) {
addConnectedPeer(addr);
var peer = new Peer({
socket: socket,
messages: self.messages
});
self._addPeerEventHandlers(peer, addr);
self._connectedPeers[addr.hash] = peer;
self.emit('peerconnect', peer, addr);
}
return this;
};
Pool.prototype._addPeerEventHandlers = function(peer, addr) {
var self = this;
peer.on('disconnect', function peerDisconnect() {
self.emit('peerdisconnect', peer, addr);
});
peer.on('ready', function peerReady() {
self.emit('peerready', peer, addr);
});
Pool.PeerEvents.forEach(function addPeerEvents(event) {
peer.on(event, function peerEvent(message) {
self.emit('peer' + event, peer, message);
});
});
};
/**
* Will deprioritize an addr in the list of addrs by moving it to the end
* of the array, and setting a retryTime
@ -257,7 +281,7 @@ Pool.prototype._addAddr = function _addAddr(addr) {
if (!exists) {
this._addrs.unshift(addr);
}
return this;
return addr;
};
/**
@ -313,4 +337,24 @@ Pool.prototype.sendMessage = function(message) {
}
};
Pool.prototype.listen = function() {
var self = this;
// Create server
this.server = net.createServer(function(socket) {
var addr = {
ip: {}
};
if(net.isIPv6(socket.remoteAddress)) {
addr.ip.v6 = socket.remoteAddress;
} else {
addr.ip.v4 = socket.remoteAddress;
}
addr = self._addAddr(addr);
self._addConnectedPeer(socket, addr);
});
this.server.listen(this.network.port);
};
module.exports = Pool;