mirror of
https://github.com/fluencelabs/js-libp2p-tcp
synced 2025-07-02 05:51:49 +00:00
Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
730a477bd8 | |||
19b29fe40b | |||
073e14553b | |||
2ed01e8f5b | |||
4a121696d1 | |||
a008d1db34 | |||
f50b9bafdd | |||
abd71d76e4 |
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "libp2p-tcp",
|
||||
"version": "0.6.0",
|
||||
"version": "0.6.2",
|
||||
"description": "Node.js implementation of the TCP module that libp2p uses, which implements the interface-connection and interface-transport interfaces",
|
||||
"main": "lib/index.js",
|
||||
"jsnext:main": "src/index.js",
|
||||
@ -41,15 +41,16 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"ip-address": "^5.8.0",
|
||||
"lodash.contains": "^2.4.3",
|
||||
"mafmt": "^2.1.0",
|
||||
"multiaddr": "^2.0.2",
|
||||
"run-parallel": "^1.1.6"
|
||||
},
|
||||
"contributors": [
|
||||
"David Dias <daviddias.p@gmail.com>",
|
||||
"Friedel Ziegelmayer <dignifiedquire@gmail.com>",
|
||||
"João Antunes <j.goncalo.antunes@gmail.com>",
|
||||
"Richard Littauer <richard.littauer@gmail.com>",
|
||||
"Stephen Whitmore <stephen.whitmore@gmail.com>"
|
||||
"Stephen Whitmore <stephen.whitmore@gmail.com>",
|
||||
"dignifiedquire <dignifiedquire@gmail.com>"
|
||||
]
|
||||
}
|
50
src/index.js
50
src/index.js
@ -7,9 +7,13 @@ const multiaddr = require('multiaddr')
|
||||
const Address6 = require('ip-address').Address6
|
||||
const mafmt = require('mafmt')
|
||||
const parallel = require('run-parallel')
|
||||
const contains = require('lodash.contains')
|
||||
|
||||
exports = module.exports = TCP
|
||||
|
||||
const IPFS_CODE = 421
|
||||
const CLOSE_TIMEOUT = 300
|
||||
|
||||
function TCP () {
|
||||
if (!(this instanceof TCP)) {
|
||||
return new TCP()
|
||||
@ -37,23 +41,52 @@ function TCP () {
|
||||
const freshMultiaddrs = []
|
||||
|
||||
parallel(multiaddrs.map((m) => (cb) => {
|
||||
let ipfsHashId
|
||||
if (contains(m.protoNames(), 'ipfs')) {
|
||||
ipfsHashId = m.stringTuples().filter((tuple) => {
|
||||
if (tuple[0] === IPFS_CODE) {
|
||||
return true
|
||||
}
|
||||
})[0][1]
|
||||
m = m.decapsulate('ipfs')
|
||||
}
|
||||
|
||||
const listener = tcp.createServer((conn) => {
|
||||
conn.getObservedAddrs = () => {
|
||||
return [getMultiaddr(conn)]
|
||||
}
|
||||
handler(conn)
|
||||
})
|
||||
|
||||
listener.__connections = {}
|
||||
listener.on('connection', (conn) => {
|
||||
const key = `${conn.remoteAddress}:${conn.remotePort}`
|
||||
listener.__connections[key] = conn
|
||||
|
||||
conn.on('close', () => {
|
||||
delete listener.__connections[key]
|
||||
})
|
||||
})
|
||||
|
||||
listener.listen(m.toOptions(), () => {
|
||||
// Node.js likes to convert addr to IPv6 (when 0.0.0.0 for e.g)
|
||||
const address = listener.address()
|
||||
if (m.toString().indexOf('ip4')) {
|
||||
m = m.decapsulate('tcp')
|
||||
m = m.encapsulate('/tcp/' + address.port)
|
||||
if (ipfsHashId) {
|
||||
m = m.encapsulate('/ipfs/' + ipfsHashId)
|
||||
}
|
||||
freshMultiaddrs.push(m)
|
||||
}
|
||||
|
||||
if (address.family === 'IPv6') {
|
||||
freshMultiaddrs.push(multiaddr('/ip6/' + address.address + '/tcp/' + address.port))
|
||||
let mh = multiaddr('/ip6/' + address.address + '/tcp/' + address.port)
|
||||
if (ipfsHashId) {
|
||||
mh = mh.encapsulate('/ipfs/' + ipfsHashId)
|
||||
}
|
||||
|
||||
freshMultiaddrs.push(mh)
|
||||
}
|
||||
|
||||
cb()
|
||||
@ -65,13 +98,21 @@ function TCP () {
|
||||
}
|
||||
|
||||
this.close = (callback) => {
|
||||
log('closing')
|
||||
if (listeners.length === 0) {
|
||||
log('Called close with no active listeners')
|
||||
return callback()
|
||||
}
|
||||
|
||||
parallel(listeners.map((listener) => {
|
||||
return (cb) => listener.close(cb)
|
||||
parallel(listeners.map((listener) => (cb) => {
|
||||
setTimeout(() => {
|
||||
Object.keys(listener.__connections).forEach((key) => {
|
||||
log('destroying %s', key)
|
||||
listener.__connections[key].destroy()
|
||||
})
|
||||
}, CLOSE_TIMEOUT)
|
||||
|
||||
listener.close(cb)
|
||||
}), callback)
|
||||
}
|
||||
|
||||
@ -80,6 +121,9 @@ function TCP () {
|
||||
multiaddrs = [multiaddrs]
|
||||
}
|
||||
return multiaddrs.filter((ma) => {
|
||||
if (contains(ma.protoNames(), 'ipfs')) {
|
||||
ma = ma.decapsulate('ipfs')
|
||||
}
|
||||
return mafmt.TCP.matches(ma)
|
||||
})
|
||||
}
|
||||
|
@ -37,12 +37,30 @@ describe('libp2p-tcp', function () {
|
||||
tcp.close(() => {
|
||||
done()
|
||||
})
|
||||
}, () => {
|
||||
}, (err, freshMultiaddrs) => {
|
||||
expect(err).to.not.exist
|
||||
expect(mh).to.deep.equal(freshMultiaddrs[0])
|
||||
const socket = net.connect({ host: '127.0.0.1', port: 9090 })
|
||||
socket.end()
|
||||
})
|
||||
})
|
||||
|
||||
it('listen on addr with /ipfs/QmHASH', (done) => {
|
||||
const mh = multiaddr('/ip4/127.0.0.1/tcp/14090/ipfs/Qmb6owHp6eaWArVbcJJbQSyifyJBttMMjYV76N2hMbf5Vw')
|
||||
tcp.createListener(mh, (socket) => {
|
||||
expect(socket).to.exist
|
||||
socket.end()
|
||||
tcp.close(() => {
|
||||
done()
|
||||
})
|
||||
}, (err, freshMultiaddrs) => {
|
||||
expect(err).to.not.exist
|
||||
expect(mh).to.deep.equal(freshMultiaddrs[0])
|
||||
const socket = net.connect({ host: '127.0.0.1', port: 14090 })
|
||||
socket.end()
|
||||
})
|
||||
})
|
||||
|
||||
it('dial', (done) => {
|
||||
const server = net.createServer((socket) => {
|
||||
expect(socket).to.exist
|
||||
@ -114,9 +132,10 @@ describe('libp2p-tcp', function () {
|
||||
const mh1 = multiaddr('/ip4/127.0.0.1/tcp/9090')
|
||||
const mh2 = multiaddr('/ip4/127.0.0.1/udp/9090')
|
||||
const mh3 = multiaddr('/ip4/127.0.0.1/tcp/9090/http')
|
||||
const mh4 = multiaddr('/ip4/127.0.0.1/tcp/9090/ipfs/Qmb6owHp6eaWArVbcJJbQSyifyJBttMMjYV76N2hMbf5Vw')
|
||||
|
||||
const valid = tcp.filter([mh1, mh2, mh3])
|
||||
expect(valid.length).to.equal(1)
|
||||
const valid = tcp.filter([mh1, mh2, mh3, mh4])
|
||||
expect(valid.length).to.equal(2)
|
||||
expect(valid[0]).to.deep.equal(mh1)
|
||||
done()
|
||||
})
|
||||
@ -129,4 +148,35 @@ describe('libp2p-tcp', function () {
|
||||
expect(valid[0]).to.deep.equal(mh1)
|
||||
done()
|
||||
})
|
||||
|
||||
it('destroys after timeout', (done) => {
|
||||
const server = new TCPlibp2p()
|
||||
const mh = multiaddr('/ip4/127.0.0.1/tcp/9090')
|
||||
server.createListener(mh, (conn) => {
|
||||
const i = setInterval(() => {
|
||||
conn.read()
|
||||
conn.write('hi\n')
|
||||
}, 100)
|
||||
i.unref()
|
||||
}, () => {
|
||||
let connected = 0
|
||||
const connectHandler = () => {
|
||||
connected++
|
||||
if (connected === 10) {
|
||||
setTimeout(() => {
|
||||
server.close(done)
|
||||
}, 1)
|
||||
}
|
||||
}
|
||||
const errorHandler = () => {}
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const client = net.connect(9090)
|
||||
client.on('connect', connectHandler)
|
||||
|
||||
// just ignore the resets
|
||||
client.on('error', errorHandler)
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
Reference in New Issue
Block a user