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); var magicNumber = bitcore.Networks.defaultNetwork.networkMagic.readUInt32LE(0);
function VerackMessage(options) { function VerackMessage(options) {
if(!options) {
options = {};
}
Message.call(this, options); Message.call(this, options);
this.magicNumber = magicNumber; this.magicNumber = magicNumber;
this.command = 'verack'; this.command = 'verack';

View File

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

View File

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