2016-05-09 11:14:40 +02:00
|
|
|
'use strict'
|
|
|
|
|
2016-08-05 14:22:18 +02:00
|
|
|
const net = require('net')
|
|
|
|
const toPull = require('stream-to-pull-stream')
|
2016-03-14 16:57:54 +00:00
|
|
|
const mafmt = require('mafmt')
|
2018-04-02 18:57:59 +01:00
|
|
|
const withIs = require('class-is')
|
2016-12-04 20:28:18 +08:00
|
|
|
const includes = require('lodash.includes')
|
2016-08-05 14:22:18 +02:00
|
|
|
const isFunction = require('lodash.isfunction')
|
2016-06-15 03:22:09 -04:00
|
|
|
const Connection = require('interface-connection').Connection
|
2017-03-27 17:18:55 +02:00
|
|
|
const once = require('once')
|
2016-08-05 14:22:18 +02:00
|
|
|
const debug = require('debug')
|
2016-08-31 06:41:34 -04:00
|
|
|
const log = debug('libp2p:tcp:dial')
|
2015-09-15 19:08:19 +01:00
|
|
|
|
2016-08-05 14:22:18 +02:00
|
|
|
const createListener = require('./listener')
|
2016-03-04 18:58:01 +00:00
|
|
|
|
2017-04-07 11:51:56 -04:00
|
|
|
function noop () {}
|
|
|
|
|
2016-12-08 12:27:08 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
2017-04-07 11:51:56 -04:00
|
|
|
class TCP {
|
2016-12-08 12:27:08 +01:00
|
|
|
/**
|
|
|
|
* Dial to another peer.
|
|
|
|
*
|
|
|
|
* @param {Multiaddr} ma - The address of the peer we want to dial to.
|
|
|
|
* @param {Object} [options={}]
|
|
|
|
* @param {function(Error?, Array<Multiaddr>?)} [callback]
|
|
|
|
* @returns {Connection}
|
|
|
|
*/
|
2017-04-07 11:51:56 -04:00
|
|
|
dial (ma, options, callback) {
|
2016-08-05 14:22:18 +02:00
|
|
|
if (isFunction(options)) {
|
2017-04-07 11:51:56 -04:00
|
|
|
callback = options
|
2016-03-04 18:58:01 +00:00
|
|
|
options = {}
|
|
|
|
}
|
2016-06-15 03:22:09 -04:00
|
|
|
|
2018-02-07 06:26:02 +00:00
|
|
|
callback = once(callback || noop)
|
2016-06-15 03:22:09 -04:00
|
|
|
|
2016-08-05 14:22:18 +02:00
|
|
|
const cOpts = ma.toOptions()
|
|
|
|
log('Connecting to %s %s', cOpts.port, cOpts.host)
|
2016-06-15 03:22:09 -04:00
|
|
|
|
2017-03-27 17:18:55 +02:00
|
|
|
const rawSocket = net.connect(cOpts)
|
2017-04-07 11:51:56 -04:00
|
|
|
|
2016-08-31 06:41:34 -04:00
|
|
|
rawSocket.once('timeout', () => {
|
|
|
|
log('timeout')
|
|
|
|
rawSocket.emit('error', new Error('Timeout'))
|
|
|
|
})
|
|
|
|
|
2017-04-07 11:51:56 -04:00
|
|
|
rawSocket.once('error', callback)
|
2017-03-27 17:18:55 +02:00
|
|
|
|
|
|
|
rawSocket.once('connect', () => {
|
2017-04-07 11:51:56 -04:00
|
|
|
rawSocket.removeListener('error', callback)
|
|
|
|
callback()
|
2017-03-27 17:18:55 +02:00
|
|
|
})
|
|
|
|
|
2016-08-31 06:41:34 -04:00
|
|
|
const socket = toPull.duplex(rawSocket)
|
|
|
|
|
|
|
|
const conn = new Connection(socket)
|
|
|
|
|
2017-04-07 11:51:56 -04:00
|
|
|
conn.getObservedAddrs = (callback) => {
|
|
|
|
return callback(null, [ma])
|
2016-03-10 10:24:48 +00:00
|
|
|
}
|
2016-06-15 03:22:09 -04:00
|
|
|
|
2016-08-31 06:41:34 -04:00
|
|
|
return conn
|
2016-03-04 18:58:01 +00:00
|
|
|
}
|
|
|
|
|
2016-12-08 12:27:08 +01:00
|
|
|
/**
|
|
|
|
* Listen for incoming `TCP` connetions.
|
|
|
|
*
|
|
|
|
* @param {Object} [options={}]
|
|
|
|
* @param {function(Connection)} [handler] - Called with newly incomin connections.
|
|
|
|
* @returns {Listener}
|
|
|
|
*/
|
2016-08-05 14:22:18 +02:00
|
|
|
createListener (options, handler) {
|
|
|
|
if (isFunction(options)) {
|
2016-06-15 03:22:09 -04:00
|
|
|
handler = options
|
|
|
|
options = {}
|
2016-03-04 18:58:01 +00:00
|
|
|
}
|
|
|
|
|
2018-02-07 06:40:00 +00:00
|
|
|
handler = handler || noop
|
2016-08-31 06:41:34 -04:00
|
|
|
|
2016-08-05 14:22:18 +02:00
|
|
|
return createListener(handler)
|
2016-03-04 18:58:01 +00:00
|
|
|
}
|
2016-03-14 16:57:54 +00:00
|
|
|
|
2016-12-08 12:27:08 +01:00
|
|
|
/**
|
|
|
|
* Filter a list of multiaddrs for those which contain
|
|
|
|
* valid `TCP` addresses.
|
|
|
|
*
|
|
|
|
* @param {Multiaddr|Array<Multiaddr>} multiaddrs
|
|
|
|
* @returns {Array<Multiaddr>}
|
|
|
|
*/
|
2016-08-05 14:22:18 +02:00
|
|
|
filter (multiaddrs) {
|
2016-03-14 16:57:54 +00:00
|
|
|
if (!Array.isArray(multiaddrs)) {
|
|
|
|
multiaddrs = [multiaddrs]
|
|
|
|
}
|
2017-10-13 08:13:28 -07:00
|
|
|
|
2016-03-14 16:57:54 +00:00
|
|
|
return multiaddrs.filter((ma) => {
|
2017-10-13 08:13:28 -07:00
|
|
|
if (includes(ma.protoNames(), 'p2p-circuit')) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2016-12-04 20:28:18 +08:00
|
|
|
if (includes(ma.protoNames(), 'ipfs')) {
|
2016-05-29 08:56:24 +01:00
|
|
|
ma = ma.decapsulate('ipfs')
|
|
|
|
}
|
2017-10-13 08:13:28 -07:00
|
|
|
|
2016-03-14 16:57:54 +00:00
|
|
|
return mafmt.TCP.matches(ma)
|
|
|
|
})
|
|
|
|
}
|
2015-09-15 19:08:19 +01:00
|
|
|
}
|
2017-04-07 11:51:56 -04:00
|
|
|
|
2018-04-02 18:57:59 +01:00
|
|
|
module.exports = withIs(TCP, { className: 'TCP', symbolName: '@libp2p/js-libp2p-tcp/tcp' })
|