Skip to content
This repository was archived by the owner on Apr 24, 2023. It is now read-only.

Commit db5c97e

Browse files
authoredOct 2, 2019
refactor: switch to async iterators (#183)
BREAKING CHANGE: Switch to using async/await and async iterators. The transport and connection interfaces have changed.
1 parent 983f464 commit db5c97e

22 files changed

+739
-468
lines changed
 

‎.travis.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ stages:
77

88
node_js:
99
- '10'
10+
- '12'
1011

1112
os:
1213
- linux
@@ -19,7 +20,6 @@ jobs:
1920
include:
2021
- stage: check
2122
script:
22-
- npx aegir commitlint --travis
2323
- npx aegir dep-check -- -i wrtc -i electron-webrtc
2424
- npm run lint
2525

‎README.md

+28-1
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,35 @@ const ws2 = new WStar({ wrtc: electronWebRTC() })
5454

5555
```JavaScript
5656
const WStar = require('libp2p-webrtc-star')
57+
const multiaddr = require('multiaddr')
58+
const pipe = require('it-pipe')
59+
const { collect } = require('streaming-iterables')
5760

58-
const ws = new WStar()
61+
const addr = multiaddr('/ip4/188.166.203.82/tcp/20000/wss/p2p-webrtc-star/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSooo2a')
62+
63+
const ws = new WStar({ upgrader })
64+
65+
const listener = ws.createListener((socket) => {
66+
console.log('new connection opened')
67+
pipe(
68+
['hello'],
69+
socket
70+
)
71+
})
72+
73+
await listener.listen(addr)
74+
console.log('listening')
75+
76+
const socket = await ws.dial(addr)
77+
const values = await pipe(
78+
socket,
79+
collect
80+
)
81+
82+
console.log(`Value: ${values.toString()}`)
83+
84+
// Close connection after reading
85+
await listener.close()
5986
```
6087

6188
## API

‎package.json

+24-21
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,11 @@
2525
"coverage-publish": "aegir coverage --provider coveralls"
2626
},
2727
"pre-push": [
28-
"lint",
29-
"test"
28+
"lint"
3029
],
3130
"engines": {
32-
"node": ">=6.0.0",
33-
"npm": ">=3.0.0"
31+
"node": ">=10.0.0",
32+
"npm": ">=6.0.0"
3433
},
3534
"repository": {
3635
"type": "git",
@@ -46,32 +45,36 @@
4645
},
4746
"homepage": "https://github.com/libp2p/js-libp2p-webrtc-star#readme",
4847
"devDependencies": {
49-
"aegir": "^18.2.1",
48+
"aegir": "^20.3.1",
5049
"chai": "^4.2.0",
5150
"dirty-chai": "^2.0.1",
5251
"electron-webrtc": "~0.3.0",
53-
"prom-client": "^11.2.1",
54-
"wrtc": "~0.3.7"
52+
"interface-discovery": "~0.1.1",
53+
"interface-transport": "libp2p/interface-transport#chore/skip-abort-while-reading-for-webrtc",
54+
"prom-client": "^11.5.3",
55+
"wrtc": "~0.4.2"
5556
},
5657
"dependencies": {
57-
"@hapi/hapi": "^18.3.1",
58-
"@hapi/inert": "^5.2.0",
59-
"async": "^2.6.2",
58+
"@hapi/hapi": "^18.4.0",
59+
"@hapi/inert": "^5.2.2",
60+
"abortable-iterator": "^2.1.0",
6061
"class-is": "^1.1.0",
6162
"debug": "^4.1.1",
6263
"epimetheus": "^1.0.92",
63-
"interface-connection": "~0.3.3",
64-
"mafmt": "^6.0.7",
64+
"err-code": "^2.0.0",
65+
"it-pipe": "^1.0.1",
66+
"libp2p-utils": "^0.1.0",
67+
"mafmt": "^7.0.0",
6568
"minimist": "^1.2.0",
66-
"multiaddr": "^6.0.6",
67-
"once": "^1.4.0",
68-
"peer-id": "~0.12.2",
69-
"peer-info": "~0.15.1",
70-
"pull-stream": "^3.6.9",
71-
"simple-peer": "^9.3.0",
72-
"socket.io": "^2.1.1",
73-
"socket.io-client": "^2.1.1",
74-
"stream-to-pull-stream": "^1.7.3",
69+
"multiaddr": "^7.1.0",
70+
"p-defer": "^3.0.0",
71+
"peer-id": "~0.13.2",
72+
"peer-info": "~0.17.0",
73+
"simple-peer": "^9.6.0",
74+
"socket.io": "^2.3.0",
75+
"socket.io-client": "^2.3.0",
76+
"stream-to-it": "^0.1.1",
77+
"streaming-iterables": "^4.1.0",
7578
"webrtcsupport": "github:ipfs/webrtcsupport"
7679
},
7780
"contributors": [

‎src/constants.js

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
'use strict'
2+
3+
// p2p multi-address code
4+
exports.CODE_P2P = 421
5+
exports.CODE_CIRCUIT = 290
6+
7+
// Time to wait for a connection to close gracefully before destroying it manually
8+
exports.CLOSE_TIMEOUT = 2000

‎src/index.js

+149-170
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,41 @@
22

33
const debug = require('debug')
44
const log = debug('libp2p:webrtc-star')
5-
const multiaddr = require('multiaddr')
6-
const mafmt = require('mafmt')
5+
log.error = debug('libp2p:webrtc-star:error')
6+
7+
const assert = require('assert')
8+
const { EventEmitter } = require('events')
9+
const errcode = require('err-code')
710
const withIs = require('class-is')
8-
const io = require('socket.io-client')
9-
const EE = require('events').EventEmitter
11+
12+
const { AbortError } = require('abortable-iterator')
1013
const SimplePeer = require('simple-peer')
14+
const webrtcSupport = require('webrtcsupport')
15+
16+
const multiaddr = require('multiaddr')
17+
const mafmt = require('mafmt')
1118
const PeerId = require('peer-id')
1219
const PeerInfo = require('peer-info')
13-
const Connection = require('interface-connection').Connection
14-
const toPull = require('stream-to-pull-stream')
15-
const once = require('once')
16-
const setImmediate = require('async/setImmediate')
17-
const webrtcSupport = require('webrtcsupport')
18-
const utils = require('./utils')
19-
const cleanUrlSIO = utils.cleanUrlSIO
20-
const cleanMultiaddr = utils.cleanMultiaddr
2120

22-
const noop = once(() => {})
21+
const { CODE_CIRCUIT } = require('./constants')
22+
const createListener = require('./listener')
23+
const toConnection = require('./socket-to-conn')
24+
const { cleanMultiaddr } = require('./utils')
2325

24-
const sioOptions = {
25-
transports: ['websocket'],
26-
'force new connection': true
27-
}
26+
function noop () { }
2827

28+
/**
29+
* @class WebRTCStar
30+
*/
2931
class WebRTCStar {
30-
constructor (options) {
31-
options = options || {}
32+
/**
33+
* @constructor
34+
* @param {object} options
35+
* @param {Upgrader} options.upgrader
36+
*/
37+
constructor (options = {}) {
38+
assert(options.upgrader, 'An upgrader must be provided. See https://github.com/libp2p/interface-transport#upgrader.')
39+
this._upgrader = options.upgrader
3240

3341
this.maSelf = undefined
3442

@@ -41,201 +49,173 @@ class WebRTCStar {
4149
this.wrtc = options.wrtc
4250
}
4351

44-
this.discovery = new EE()
52+
this.listenersRefs = {}
53+
54+
// Discovery
55+
this.discovery = new EventEmitter()
4556
this.discovery.tag = 'webRTCStar'
4657
this.discovery._isStarted = false
47-
this.discovery.start = (callback) => {
58+
this.discovery.start = () => {
4859
this.discovery._isStarted = true
49-
setImmediate(callback)
5060
}
51-
this.discovery.stop = (callback) => {
61+
this.discovery.stop = () => {
5262
this.discovery._isStarted = false
53-
setImmediate(callback)
5463
}
55-
56-
this.listenersRefs = {}
5764
this._peerDiscovered = this._peerDiscovered.bind(this)
5865
}
5966

60-
dial (ma, options, callback) {
61-
if (typeof options === 'function') {
62-
callback = options
63-
options = {}
64-
}
65-
66-
callback = callback ? once(callback) : noop
67-
68-
const intentId = (~~(Math.random() * 1e9)).toString(36) + Date.now()
67+
/**
68+
* @async
69+
* @param {Multiaddr} ma
70+
* @param {object} options
71+
* @param {AbortSignal} options.signal Used to abort dial requests
72+
* @returns {Connection} An upgraded Connection
73+
*/
74+
async dial (ma, options = {}) {
75+
const rawConn = await this._connect(ma, options)
76+
const maConn = toConnection(rawConn, { remoteAddr: ma, signal: options.signal })
77+
log('new outbound connection %s', maConn.remoteAddr)
78+
const conn = await this._upgrader.upgradeOutbound(maConn)
79+
log('outbound connection %s upgraded', maConn.remoteAddr)
80+
return conn
81+
}
6982

70-
const sioClient = this
71-
.listenersRefs[Object.keys(this.listenersRefs)[0]].io
83+
/**
84+
* @private
85+
* @param {Multiaddr} ma
86+
* @param {object} options
87+
* @param {AbortSignal} options.signal Used to abort dial requests
88+
* @returns {Promise<SimplePeer>} Resolves a SimplePeer Webrtc channel
89+
*/
90+
_connect (ma, options = {}) {
91+
if (options.signal && options.signal.aborted) {
92+
throw new AbortError()
93+
}
7294

73-
const spOptions = { initiator: true, trickle: false }
95+
const spOptions = {
96+
initiator: true,
97+
trickle: false
98+
}
7499

75100
// Use custom WebRTC implementation
76101
if (this.wrtc) { spOptions.wrtc = this.wrtc }
77102

78-
let channel
79-
try {
80-
channel = new SimplePeer(spOptions)
81-
} catch (err) {
82-
log('Could not create connection:', err)
83-
return callback(err)
84-
}
103+
const cOpts = ma.toOptions()
85104

86-
const conn = new Connection(toPull.duplex(channel))
87-
let connected = false
105+
const intentId = (~~(Math.random() * 1e9)).toString(36) + Date.now()
106+
const sioClient = this
107+
.listenersRefs[Object.keys(this.listenersRefs)[0]].io
88108

89-
channel.on('signal', (signal) => {
90-
sioClient.emit('ss-handshake', {
91-
intentId: intentId,
92-
srcMultiaddr: this.maSelf.toString(),
93-
dstMultiaddr: ma.toString(),
94-
signal: signal
95-
})
96-
})
109+
return new Promise((resolve, reject) => {
110+
const start = Date.now()
111+
let connected
97112

98-
channel.once('timeout', () => callback(new Error('timeout')))
113+
log('dialing %s:%s', cOpts.host, cOpts.port)
114+
const channel = new SimplePeer(spOptions)
99115

100-
channel.once('error', (err) => {
101-
if (!connected) { callback(err) }
102-
})
116+
const onError = (err) => {
117+
if (!connected) {
118+
const msg = `connection error ${cOpts.host}:${cOpts.port}: ${err.message}`
103119

104-
// NOTE: aegir segfaults if we do .once on the socket.io event emitter and we
105-
// are clueless as to why.
106-
sioClient.on('ws-handshake', (offer) => {
107-
if (offer.intentId === intentId && offer.err) {
108-
return callback(new Error(offer.err))
120+
err.message = msg
121+
log.error(msg)
122+
done(err)
123+
}
109124
}
110125

111-
if (offer.intentId !== intentId || !offer.answer) {
112-
return
126+
const onTimeout = () => {
127+
log('connnection timeout %s:%s', cOpts.host, cOpts.port)
128+
const err = errcode(new Error(`connection timeout after ${Date.now() - start}ms`), 'ERR_CONNECT_TIMEOUT')
129+
// Note: this will result in onError() being called
130+
channel.emit('error', err)
113131
}
114132

115-
channel.once('connect', () => {
133+
const onConnect = () => {
116134
connected = true
117-
conn.destroy = channel.destroy.bind(channel)
118-
119-
channel.once('close', () => conn.destroy())
120-
121-
conn.getObservedAddrs = (callback) => callback(null, [ma])
122-
123-
callback(null, conn)
124-
})
125-
126-
channel.signal(offer.signal)
127-
})
128-
129-
return conn
130-
}
131135

132-
createListener (options, handler) {
133-
if (typeof options === 'function') {
134-
handler = options
135-
options = {}
136-
}
137-
138-
const listener = new EE()
139-
140-
listener.listen = (ma, callback) => {
141-
callback = callback ? once(callback) : noop
142-
143-
if (!webrtcSupport.support && !this.wrtc) {
144-
return setImmediate(() => callback(new Error('no WebRTC support')))
136+
log('connection opened %s:%s', cOpts.host, cOpts.port)
137+
done(null)
145138
}
146139

147-
this.maSelf = ma
148-
149-
const sioUrl = cleanUrlSIO(ma)
150-
151-
log('Dialing to Signalling Server on: ' + sioUrl)
152-
153-
listener.io = io.connect(sioUrl, sioOptions)
154-
155-
listener.io.once('connect_error', callback)
156-
listener.io.once('error', (err) => {
157-
listener.emit('error', err)
158-
listener.emit('close')
159-
})
140+
const onAbort = () => {
141+
log.error('connection aborted %s:%s', cOpts.host, cOpts.port)
142+
channel.destroy()
143+
done(new AbortError())
144+
}
160145

161-
listener.io.on('ws-handshake', incommingDial)
162-
listener.io.on('ws-peer', this._peerDiscovered)
146+
const done = (err) => {
147+
channel.removeListener('error', onError)
148+
channel.removeListener('timeout', onTimeout)
149+
channel.removeListener('connect', onConnect)
150+
options.signal && options.signal.removeEventListener('abort', onAbort)
163151

164-
listener.io.on('connect', () => {
165-
listener.io.emit('ss-join', ma.toString())
166-
})
152+
err ? reject(err) : resolve(channel)
153+
}
167154

168-
listener.io.once('connect', () => {
169-
listener.emit('listening')
170-
callback()
155+
channel.once('error', onError)
156+
channel.once('timeout', onTimeout)
157+
channel.once('connect', onConnect)
158+
channel.on('close', () => channel.destroy())
159+
options.signal && options.signal.addEventListener('abort', onAbort)
160+
161+
channel.on('signal', (signal) => {
162+
sioClient.emit('ss-handshake', {
163+
intentId: intentId,
164+
srcMultiaddr: this.maSelf.toString(),
165+
dstMultiaddr: ma.toString(),
166+
signal: signal
167+
})
171168
})
172169

173-
const self = this
174-
function incommingDial (offer) {
175-
if (offer.answer || offer.err) {
176-
return
170+
// NOTE: aegir segfaults if we do .once on the socket.io event emitter and we
171+
// are clueless as to why.
172+
sioClient.on('ws-handshake', (offer) => {
173+
if (offer.intentId === intentId && offer.err) {
174+
reject(offer.err)
177175
}
178176

179-
const spOptions = { trickle: false }
180-
181-
// Use custom WebRTC implementation
182-
if (self.wrtc) { spOptions.wrtc = self.wrtc }
183-
184-
let channel
185-
try {
186-
channel = new SimplePeer(spOptions)
187-
} catch (err) {
188-
log('Could not create incoming connection:', err)
189-
return callback(err)
177+
if (offer.intentId !== intentId || !offer.answer) {
178+
return
190179
}
191180

192-
const conn = new Connection(toPull.duplex(channel))
193-
194-
channel.once('connect', () => {
195-
conn.getObservedAddrs = (callback) => {
196-
return callback(null, [offer.srcMultiaddr])
197-
}
198-
199-
listener.emit('connection', conn)
200-
handler(conn)
201-
})
202-
203-
channel.once('signal', (signal) => {
204-
offer.signal = signal
205-
offer.answer = true
206-
listener.io.emit('ss-handshake', offer)
207-
})
208-
209181
channel.signal(offer.signal)
210-
}
211-
}
212-
213-
listener.close = (callback) => {
214-
callback = callback ? once(callback) : noop
215-
216-
listener.io.emit('ss-leave')
217-
218-
setImmediate(() => {
219-
listener.emit('close')
220-
callback()
221182
})
183+
})
184+
}
185+
186+
/**
187+
* Creates a WebrtcStar listener. The provided `handler` function will be called
188+
* anytime a new incoming Connection has been successfully upgraded via
189+
* `upgrader.upgradeInbound`.
190+
* @param {object} [options] simple-peer options for listener
191+
* @param {function (Connection)} handler
192+
* @returns {Listener} A WebrtcStar listener
193+
*/
194+
createListener (options = {}, handler) {
195+
if (!webrtcSupport.support && !this.wrtc) {
196+
throw errcode(new Error('no WebRTC support'), 'ERR_NO_WEBRTC_SUPPORT')
222197
}
223198

224-
listener.getAddrs = (callback) => {
225-
setImmediate(() => callback(null, [this.maSelf]))
199+
if (typeof options === 'function') {
200+
handler = options
201+
options = {}
226202
}
227203

228-
this.listenersRefs[multiaddr.toString()] = listener
229-
return listener
204+
handler = handler || noop
205+
206+
return createListener({ handler, upgrader: this._upgrader }, this, options)
230207
}
231208

209+
/**
210+
* Takes a list of `Multiaddr`s and returns only valid TCP addresses
211+
* @param {Multiaddr[]} multiaddrs
212+
* @returns {Multiaddr[]} Valid TCP multiaddrs
213+
*/
232214
filter (multiaddrs) {
233-
if (!Array.isArray(multiaddrs)) {
234-
multiaddrs = [multiaddrs]
235-
}
215+
multiaddrs = Array.isArray(multiaddrs) ? multiaddrs : [multiaddrs]
236216

237217
return multiaddrs.filter((ma) => {
238-
if (ma.protoNames().indexOf('p2p-circuit') > -1) {
218+
if (ma.protoCodes().includes(CODE_CIRCUIT)) {
239219
return false
240220
}
241221

@@ -249,11 +229,10 @@ class WebRTCStar {
249229
log('Peer Discovered:', maStr)
250230
maStr = cleanMultiaddr(maStr)
251231

252-
const split = maStr.split('/ipfs/')
253-
const peerIdStr = split[split.length - 1]
254-
const peerId = PeerId.createFromB58String(peerIdStr)
232+
const ma = multiaddr(maStr)
233+
const peerId = PeerId.createFromB58String(ma.getPeerId())
255234
const peerInfo = new PeerInfo(peerId)
256-
peerInfo.multiaddrs.add(multiaddr(maStr))
235+
peerInfo.multiaddrs.add(ma)
257236
this.discovery.emit('peer', peerInfo)
258237
}
259238
}

‎src/listener.js

+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
'use strict'
2+
3+
const EventEmitter = require('events')
4+
const log = require('debug')('libp2p:webrtc-star:listener')
5+
6+
const multiaddr = require('multiaddr')
7+
8+
const io = require('socket.io-client')
9+
const SimplePeer = require('simple-peer')
10+
const pDefer = require('p-defer')
11+
12+
const toConnection = require('./socket-to-conn')
13+
const { cleanUrlSIO } = require('./utils')
14+
15+
const sioOptions = {
16+
transports: ['websocket'],
17+
'force new connection': true
18+
}
19+
20+
module.exports = ({ handler, upgrader }, WebRTCStar, options = {}) => {
21+
const listener = new EventEmitter()
22+
23+
listener.__connections = []
24+
listener.listen = (ma) => {
25+
const defer = pDefer()
26+
27+
WebRTCStar.maSelf = ma
28+
const sioUrl = cleanUrlSIO(ma)
29+
30+
log('Dialing to Signalling Server on: ' + sioUrl)
31+
listener.io = io.connect(sioUrl, sioOptions)
32+
33+
const incommingDial = async (offer) => {
34+
if (offer.answer || offer.err) {
35+
return
36+
}
37+
38+
const spOptions = {
39+
trickle: false,
40+
...options
41+
}
42+
43+
// Use custom WebRTC implementation
44+
if (WebRTCStar.wrtc) { spOptions.wrtc = WebRTCStar.wrtc }
45+
46+
const channel = new SimplePeer(spOptions)
47+
48+
const maConn = toConnection(channel)
49+
log('new inbound connection %s', maConn.remoteAddr)
50+
51+
const conn = await upgrader.upgradeInbound(maConn)
52+
log('inbound connection %s upgraded', maConn.remoteAddr)
53+
54+
trackConn(listener, maConn)
55+
56+
channel.once('connect', () => {
57+
listener.emit('connection', conn)
58+
handler(conn)
59+
})
60+
61+
channel.once('signal', (signal) => {
62+
offer.signal = signal
63+
offer.answer = true
64+
listener.io.emit('ss-handshake', offer)
65+
})
66+
67+
channel.signal(offer.signal)
68+
}
69+
70+
listener.io.once('connect_error', (err) => defer.reject(err))
71+
listener.io.once('error', (err) => {
72+
listener.emit('error', err)
73+
listener.emit('close')
74+
})
75+
76+
listener.io.on('ws-handshake', incommingDial)
77+
listener.io.on('ws-peer', WebRTCStar._peerDiscovered)
78+
79+
listener.io.on('connect', () => {
80+
listener.io.emit('ss-join', ma.toString())
81+
})
82+
83+
listener.io.once('connect', () => {
84+
listener.emit('listening')
85+
defer.resolve()
86+
})
87+
88+
return defer.promise
89+
}
90+
91+
listener.close = () => {
92+
listener.__connections.forEach(maConn => maConn.close())
93+
listener.io && listener.io.emit('ss-leave')
94+
listener.emit('close')
95+
}
96+
97+
listener.getAddrs = () => {
98+
return [WebRTCStar.maSelf]
99+
}
100+
101+
WebRTCStar.listenersRefs[multiaddr.toString()] = listener
102+
return listener
103+
}
104+
105+
function trackConn (listener, maConn) {
106+
listener.__connections.push(maConn)
107+
108+
const untrackConn = () => {
109+
listener.__connections = listener.__connections.filter(c => c !== maConn)
110+
}
111+
112+
maConn.conn.once('close', untrackConn)
113+
}

‎src/sig-server/bin.js

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#!/usr/bin/env node
2+
/* eslint-disable no-console */
23

34
'use strict'
45

‎src/socket-to-conn.js

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
'use strict'
2+
3+
const abortable = require('abortable-iterator')
4+
const toIterable = require('stream-to-it')
5+
6+
const { CLOSE_TIMEOUT } = require('./constants')
7+
const toMultiaddr = require('libp2p-utils/src/ip-port-to-multiaddr')
8+
9+
const debug = require('debug')
10+
const log = debug('libp2p:webrtc-star:socket')
11+
log.error = debug('libp2p:webrtc-star:socket:error')
12+
13+
// Convert a socket into a MultiaddrConnection
14+
// https://github.com/libp2p/interface-transport#multiaddrconnection
15+
module.exports = (socket, options = {}) => {
16+
const { sink, source } = toIterable.duplex(socket)
17+
18+
const maConn = {
19+
async sink (source) {
20+
if (options.signal) {
21+
source = abortable(source, options.signal)
22+
}
23+
24+
try {
25+
await sink((async function * () {
26+
for await (const chunk of source) {
27+
// Convert BufferList to Buffer
28+
yield Buffer.isBuffer(chunk) ? chunk : chunk.slice()
29+
}
30+
})())
31+
} catch (err) {
32+
// If aborted we can safely ignore
33+
if (err.type !== 'aborted') {
34+
// If the source errored the socket will already have been destroyed by
35+
// toIterable.duplex(). If the socket errored it will already be
36+
// destroyed. There's nothing to do here except log the error & return.
37+
log.error(err)
38+
}
39+
}
40+
},
41+
42+
source: options.signal ? abortable(source, options.signal) : source,
43+
44+
conn: socket,
45+
46+
localAddr: socket.localAddress && socket.localPort
47+
? toMultiaddr(socket.localAddress, socket.localPort) : undefined,
48+
49+
// If the remote address was passed, use it - it may have the peer ID encapsulated
50+
remoteAddr: options.remoteAddr || (socket.remoteAddress && socket.remotePort
51+
? toMultiaddr(socket.remoteAddress, socket.remotePort) : undefined),
52+
53+
timeline: { open: Date.now() },
54+
55+
close () {
56+
if (socket.destroyed) return
57+
58+
return new Promise((resolve, reject) => {
59+
const start = Date.now()
60+
61+
// Attempt to end the socket. If it takes longer to close than the
62+
// timeout, destroy it manually.
63+
const timeout = setTimeout(() => {
64+
if (maConn.remoteAddr) {
65+
const { host, port } = maConn.remoteAddr.toOptions()
66+
log('timeout closing socket to %s:%s after %dms, destroying it manually',
67+
host, port, Date.now() - start)
68+
}
69+
70+
if (!socket.destroyed) {
71+
socket.destroy()
72+
}
73+
}, CLOSE_TIMEOUT)
74+
75+
socket.once('close', () => {
76+
resolve()
77+
})
78+
79+
socket.end(err => {
80+
clearTimeout(timeout)
81+
82+
maConn.timeline.close = Date.now()
83+
if (err) return reject(err)
84+
})
85+
})
86+
}
87+
}
88+
89+
socket.once('close', () => {
90+
// In instances where `close` was not explicitly called,
91+
// such as an iterable stream ending, ensure we have set the close
92+
// timeline
93+
if (!maConn.timeline.close) {
94+
maConn.timeline.close = Date.now()
95+
}
96+
})
97+
98+
return maConn
99+
}

‎src/utils.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ function cleanMultiaddr (maStr) {
3535
return tupple[0] === 421 // ipfs code
3636
})[0]
3737

38-
ma = ma.decapsulate('ipfs')
38+
ma = ma.decapsulate('p2p')
3939
ma = ma.encapsulate('/p2p-webrtc-star')
40-
ma = ma.encapsulate(`/ipfs/${tuppleIPFS[1]}`)
40+
ma = ma.encapsulate(`/p2p/${tuppleIPFS[1]}`)
4141
maStr = ma.toString()
4242
}
4343

‎test/browser.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,16 @@
33

44
const WStar = require('..')
55

6+
const mockUpgrader = {
7+
upgradeInbound: maConn => maConn,
8+
upgradeOutbound: maConn => maConn
9+
}
10+
611
const create = () => {
7-
return new WStar()
12+
return new WStar({ upgrader: mockUpgrader })
813
}
914

1015
require('./transport/dial.js')(create)
1116
require('./transport/listen.js')(create)
1217
require('./transport/discovery.js')(create)
1318
require('./transport/filter.js')(create)
14-
require('./transport/valid-connection.js')(create)

‎test/compliance.spec.js

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/* eslint-env mocha */
2+
'use strict'
3+
4+
const wrtc = require('wrtc')
5+
6+
const sinon = require('sinon')
7+
const testsTransport = require('interface-transport')
8+
const testsDiscovery = require('interface-discovery')
9+
const multiaddr = require('multiaddr')
10+
11+
const WStar = require('../src')
12+
13+
describe('interface-transport compliance', () => {
14+
testsTransport({
15+
setup ({ upgrader }) {
16+
const ws = new WStar({ upgrader, wrtc: wrtc })
17+
18+
const base = (id) => {
19+
return `/ip4/127.0.0.1/tcp/15555/ws/p2p-webrtc-star/p2p/${id}`
20+
}
21+
22+
const addrs = [
23+
multiaddr(base('QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSooo2a')),
24+
multiaddr(base('QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSooo2b')),
25+
multiaddr(base('QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSooo2c'))
26+
]
27+
28+
// Used by the dial tests to simulate a delayed connect
29+
const connector = {
30+
delay () {},
31+
restore () {
32+
sinon.restore()
33+
}
34+
}
35+
36+
return { transport: ws, addrs, connector }
37+
}
38+
})
39+
})
40+
41+
describe('interface-discovery compliance', () => {
42+
testsDiscovery({
43+
setup () {
44+
const mockUpgrader = {
45+
upgradeInbound: maConn => maConn,
46+
upgradeOutbound: maConn => maConn
47+
}
48+
const ws = new WStar({ upgrader: mockUpgrader, wrtc: wrtc })
49+
50+
return ws.discovery
51+
}
52+
})
53+
})

‎test/node.js

+9-4
Original file line numberDiff line numberDiff line change
@@ -7,30 +7,35 @@ const WStar = require('..')
77

88
require('./sig-server.js')
99

10+
const mockUpgrader = {
11+
upgradeInbound: maConn => maConn,
12+
upgradeOutbound: maConn => maConn
13+
}
14+
1015
describe('transport: with wrtc', () => {
1116
const create = () => {
12-
return new WStar({ wrtc: wrtc })
17+
return new WStar({ upgrader: mockUpgrader, wrtc: wrtc })
1318
}
1419

1520
require('./transport/dial.js')(create)
1621
require('./transport/listen.js')(create)
22+
require('./transport/track.js')(create)
1723
require('./transport/discovery.js')(create)
1824
require('./transport/filter.js')(create)
19-
require('./transport/valid-connection.js')(create)
2025
require('./transport/reconnect.node.js')(create)
2126
})
2227

2328
// TODO: Electron-webrtc is currently unreliable on linux
2429
describe.skip('transport: with electron-webrtc', () => {
2530
const create = () => {
26-
return new WStar({ wrtc: electronWebRTC() })
31+
return new WStar({ upgrader: mockUpgrader, wrtc: electronWebRTC() })
2732
}
2833

2934
require('./transport/dial.js')(create)
3035
require('./transport/listen.js')(create)
36+
require('./transport/track.js')(create)
3137
require('./transport/discovery.js')(create)
3238
require('./transport/filter.js')(create)
33-
require('./transport/valid-connection.js')(create)
3439
// TODO ensure that nodes from wrtc close properly (race issue in travis)
3540
// require('./transport/reconnect.node.js')(create)
3641
})

‎test/sig-server.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ describe('signalling', () => {
2828
return `/ip4/127.0.0.1/tcp/9090/ws/p2p-webrtc-star/ipfs/${id}`
2929
}
3030

31-
let c1mh = multiaddr(base('QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo1'))
32-
let c2mh = multiaddr(base('QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo2'))
33-
let c3mh = multiaddr(base('QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo3'))
34-
let c4mh = multiaddr(base('QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo4'))
31+
const c1mh = multiaddr(base('QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo1'))
32+
const c2mh = multiaddr(base('QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo2'))
33+
const c3mh = multiaddr(base('QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo3'))
34+
const c4mh = multiaddr(base('QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo4'))
3535

3636
it('start and stop signalling server (default port)', async () => {
3737
const server = await sigServer.start()

‎test/transport/dial.js

+33-36
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/* eslint-env mocha */
2+
/* eslint-disable no-console */
23

34
'use strict'
45

@@ -7,21 +8,22 @@ const dirtyChai = require('dirty-chai')
78
const expect = chai.expect
89
chai.use(dirtyChai)
910
const multiaddr = require('multiaddr')
10-
const series = require('async/series')
11-
const pull = require('pull-stream')
11+
const pipe = require('it-pipe')
12+
const { collect } = require('streaming-iterables')
1213

1314
module.exports = (create) => {
1415
describe('dial', () => {
1516
let ws1
1617
let ws2
1718
let ma1
1819
let ma2
20+
let listener2
1921

2022
const maHSDNS = '/dns/star-signal.cloud.ipfs.team'
2123
const maHSIP = '/ip4/188.166.203.82/tcp/20000'
2224

2325
const maLS = '/ip4/127.0.0.1/tcp/15555'
24-
const maGen = (base, id) => multiaddr(`${base}/wss/p2p-webrtc-star/ipfs/${id}`) // https
26+
const maGen = (base, id) => multiaddr(`${base}/wss/p2p-webrtc-star/p2p/${id}`) // https
2527
// const maGen = (base, id) => multiaddr(`${base}/ws/p2p-webrtc-star/ipfs/${id}`)
2628

2729
if (process.env.WEBRTC_STAR_REMOTE_SIGNAL_DNS) {
@@ -39,49 +41,44 @@ module.exports = (create) => {
3941
ma2 = maGen(maLS, 'QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSooo2b')
4042
}
4143

42-
before((done) => {
43-
series([first, second], done)
44+
beforeEach(async () => {
45+
// first
46+
ws1 = create()
47+
const listener1 = ws1.createListener((conn) => pipe(conn, conn))
4448

45-
function first (next) {
46-
ws1 = create()
47-
const listener = ws1.createListener((conn) => pull(conn, conn))
48-
listener.listen(ma1, next)
49-
}
49+
// second
50+
ws2 = create()
51+
listener2 = ws2.createListener((conn) => pipe(conn, conn))
5052

51-
function second (next) {
52-
ws2 = create()
53-
const listener = ws2.createListener((conn) => pull(conn, conn))
54-
listener.listen(ma2, next)
55-
}
53+
await Promise.all([listener1.listen(ma1), listener2.listen(ma2)])
5654
})
5755

58-
it('dial on IPv4, check callback', function (done) {
56+
it('dial on IPv4, check promise', async function () {
5957
this.timeout(20 * 1000)
6058

61-
ws1.dial(ma2, (err, conn) => {
62-
expect(err).to.not.exist()
63-
64-
const data = Buffer.from('some data')
65-
66-
pull(
67-
pull.values([data]),
68-
conn,
69-
pull.collect((err, values) => {
70-
expect(err).to.not.exist()
71-
expect(values).to.be.eql([data])
72-
done()
73-
})
74-
)
75-
})
59+
const conn = await ws1.dial(ma2)
60+
const data = Buffer.from('some data')
61+
const values = await pipe(
62+
[data],
63+
conn,
64+
collect
65+
)
66+
67+
expect(values).to.eql([data])
7668
})
7769

78-
it('dial offline / non-exist()ent node on IPv4, check callback', function (done) {
70+
it('dial offline / non-exist()ent node on IPv4, check promise rejected', async function () {
7971
this.timeout(20 * 1000)
80-
let maOffline = multiaddr('/ip4/127.0.0.1/tcp/15555/ws/p2p-webrtc-star/ipfs/ABCD')
81-
ws1.dial(maOffline, (err, conn) => {
72+
const maOffline = multiaddr('/ip4/127.0.0.1/tcp/15555/ws/p2p-webrtc-star/ipfs/ABCD')
73+
74+
try {
75+
await ws1.dial(maOffline)
76+
} catch (err) {
8277
expect(err).to.exist()
83-
done()
84-
})
78+
return
79+
}
80+
81+
throw new Error('dial did not fail')
8582
})
8683

8784
it.skip('dial on IPv6', (done) => {

‎test/transport/discovery.js

+50-74
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,13 @@ const dirtyChai = require('dirty-chai')
77
const expect = chai.expect
88
chai.use(dirtyChai)
99
const multiaddr = require('multiaddr')
10-
const series = require('async/series')
1110

1211
module.exports = (create) => {
1312
describe('peer discovery', () => {
1413
let ws1
1514
let ws1Listener
1615
const base = (id) => {
17-
return `/ip4/127.0.0.1/tcp/15555/ws/p2p-webrtc-star/ipfs/${id}`
16+
return `/ip4/127.0.0.1/tcp/15555/ws/p2p-webrtc-star/p2p/${id}`
1817
}
1918
const ma1 = multiaddr(base('QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSooo3A'))
2019

@@ -27,98 +26,75 @@ module.exports = (create) => {
2726
let ws4
2827
const ma4 = multiaddr(base('QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSooo3D'))
2928

30-
it('listen on the first', (done) => {
31-
series([
32-
(cb) => {
33-
ws1 = create()
34-
ws1Listener = ws1.createListener((conn) => {})
35-
ws1.discovery.start(cb)
36-
},
37-
(cb) => {
38-
ws1Listener.listen(ma1, cb)
39-
}
40-
], (err) => {
41-
expect(err).to.not.exist()
42-
done()
43-
})
29+
it('listen on the first', async () => {
30+
ws1 = create()
31+
ws1Listener = ws1.createListener(() => { })
32+
ws1.discovery.start()
33+
34+
await ws1Listener.listen(ma1)
4435
})
4536

46-
it('listen on the second, discover the first', (done) => {
47-
let listener
37+
it('listen on the second, discover the first', async () => {
38+
ws2 = create()
39+
const listener = ws2.createListener(() => { })
40+
ws2.discovery.start()
4841

49-
ws1.discovery.once('peer', (peerInfo) => {
50-
expect(peerInfo.multiaddrs.has(ma2)).to.equal(true)
51-
done()
42+
const p = new Promise((resolve) => {
43+
ws1.discovery.once('peer', (peerInfo) => {
44+
expect(peerInfo.multiaddrs.has(ma2)).to.equal(true)
45+
resolve()
46+
})
5247
})
5348

54-
series([
55-
(cb) => {
56-
ws2 = create()
57-
listener = ws2.createListener((conn) => {})
58-
ws2.discovery.start(cb)
59-
},
60-
(cb) => {
61-
listener.listen(ma2, cb)
62-
}
63-
], (err) => {
64-
expect(err).to.not.exist()
65-
})
49+
listener.listen(ma2)
50+
await p
6651
})
6752

6853
// this test is mostly validating the non-discovery test mechanism works
69-
it('listen on the third, verify ws-peer is discovered', (done) => {
70-
let listener
54+
it('listen on the third, verify ws-peer is discovered', async () => {
7155
let discoveredPeer = false
72-
// resolve on peer discovered
73-
ws1.discovery.once('peer', (peerInfo) => {
56+
57+
ws1.discovery.once('peer', () => {
7458
discoveredPeer = true
7559
})
76-
ws1Listener.io.once('ws-peer', (maStr) => {
77-
expect(discoveredPeer).to.equal(true)
78-
done()
79-
})
8060

81-
series([
82-
(cb) => {
83-
ws3 = create()
84-
listener = ws3.createListener((conn) => {})
85-
ws3.discovery.start(cb)
86-
},
87-
(cb) => {
88-
listener.listen(ma3, cb)
89-
}
90-
], (err) => {
91-
expect(err).to.not.exist()
61+
// resolve on peer discovered
62+
const p = new Promise((resolve) => {
63+
ws1Listener.io.once('ws-peer', () => {
64+
expect(discoveredPeer).to.equal(true)
65+
resolve()
66+
})
9267
})
68+
69+
ws3 = create()
70+
const listener = ws3.createListener(() => { })
71+
ws3.discovery.start()
72+
73+
await listener.listen(ma3)
74+
await p
9375
})
9476

95-
it('listen on the fourth, ws-peer is not discovered', (done) => {
96-
let listener
77+
it('listen on the fourth, ws-peer is not discovered', async () => {
9778
let discoveredPeer = false
98-
// resolve on peer discovered
99-
ws1.discovery.once('peer', (peerInfo) => {
79+
80+
ws1.discovery.once('peer', () => {
10081
discoveredPeer = true
10182
})
102-
ws1Listener.io.once('ws-peer', (maStr) => {
103-
expect(discoveredPeer).to.equal(false)
104-
done()
83+
// resolve on peer discovered
84+
const p = new Promise((resolve) => {
85+
ws1Listener.io.once('ws-peer', () => {
86+
expect(discoveredPeer).to.equal(false)
87+
resolve()
88+
})
10589
})
10690

107-
series([
108-
(cb) => {
109-
ws1.discovery.stop(cb)
110-
},
111-
(cb) => {
112-
ws4 = create()
113-
listener = ws4.createListener((conn) => {})
114-
ws4.discovery.start(cb)
115-
},
116-
(cb) => {
117-
listener.listen(ma4, cb)
118-
}
119-
], (err) => {
120-
expect(err).to.not.exist()
121-
})
91+
ws1.discovery.stop()
92+
ws4 = create()
93+
const listener = ws4.createListener(() => { })
94+
ws4.discovery.start()
95+
96+
await listener.listen(ma4)
97+
await p
12298
})
12399
})
124100
}

‎test/transport/filter.js

+13-12
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const chai = require('chai')
55
const dirtyChai = require('dirty-chai')
66
const expect = chai.expect
77
chai.use(dirtyChai)
8+
89
const multiaddr = require('multiaddr')
910

1011
module.exports = (create) => {
@@ -13,18 +14,18 @@ module.exports = (create) => {
1314
const ws = create()
1415

1516
const maArr = [
16-
multiaddr('/ip4/127.0.0.1/tcp/9090/ws/p2p-webrtc-star/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo1'),
17+
multiaddr('/ip4/127.0.0.1/tcp/9090/ws/p2p-webrtc-star/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo1'),
1718
multiaddr('/ip4/127.0.0.1/tcp/9090/ws/p2p-webrtc-star'),
18-
multiaddr('/dnsaddr/libp2p.io/ws/p2p-webrtc-star/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo1'),
19-
multiaddr('/dnsaddr/signal.libp2p.io/ws/p2p-webrtc-star/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo1'),
20-
multiaddr('/dnsaddr/signal.libp2p.io/wss/p2p-webrtc-star/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo1'),
21-
multiaddr('/ip4/127.0.0.1/tcp/9090/ws/p2p-webrtc-star/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo2'),
22-
multiaddr('/ip4/127.0.0.1/tcp/9090/ws/p2p-webrtc-star/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo3'),
23-
multiaddr('/ip4/127.0.0.1/tcp/9090/ws/p2p-webrtc-star/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo4'),
24-
multiaddr('/ip4/127.0.0.1/tcp/9090/ws/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo4'),
25-
multiaddr('/ip4/127.0.0.1/tcp/9090/p2p-webrtc-star/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo4'),
26-
multiaddr('/ip4/127.0.0.1/tcp/9090/p2p-webrtc-star/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo4' +
27-
'/p2p-circuit/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo1')
19+
multiaddr('/dnsaddr/libp2p.io/ws/p2p-webrtc-star/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo1'),
20+
multiaddr('/dnsaddr/signal.libp2p.io/ws/p2p-webrtc-star/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo1'),
21+
multiaddr('/dnsaddr/signal.libp2p.io/wss/p2p-webrtc-star/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo1'),
22+
multiaddr('/ip4/127.0.0.1/tcp/9090/ws/p2p-webrtc-star/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo2'),
23+
multiaddr('/ip4/127.0.0.1/tcp/9090/ws/p2p-webrtc-star/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo3'),
24+
multiaddr('/ip4/127.0.0.1/tcp/9090/ws/p2p-webrtc-star/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo4'),
25+
multiaddr('/ip4/127.0.0.1/tcp/9090/ws/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo4'),
26+
multiaddr('/ip4/127.0.0.1/tcp/9090/p2p-webrtc-star/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo4'),
27+
multiaddr('/ip4/127.0.0.1/tcp/9090/p2p-webrtc-star/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo4' +
28+
'/p2p-circuit/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo1')
2829
]
2930

3031
const filtered = ws.filter(maArr)
@@ -33,7 +34,7 @@ module.exports = (create) => {
3334

3435
it('filter a single addr for this transport', () => {
3536
const ws = create()
36-
const ma = multiaddr('/ip4/127.0.0.1/tcp/9090/ws/p2p-webrtc-star/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo1')
37+
const ma = multiaddr('/ip4/127.0.0.1/tcp/9090/ws/p2p-webrtc-star/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo1')
3738

3839
const filtered = ws.filter(ma)
3940
expect(filtered.length).to.equal(1)

‎test/transport/instance.spec.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,14 @@ chai.use(dirtyChai)
88

99
const WebRTCStar = require('../../src')
1010

11+
const mockUpgrader = {
12+
upgradeInbound: maConn => maConn,
13+
upgradeOutbound: maConn => maConn
14+
}
15+
1116
describe('instantiate the transport', () => {
1217
it('create', () => {
13-
const wstar = new WebRTCStar()
18+
const wstar = new WebRTCStar({ upgrader: mockUpgrader })
1419
expect(wstar).to.exist()
1520
})
1621

‎test/transport/listen.js

+33-30
Original file line numberDiff line numberDiff line change
@@ -18,49 +18,52 @@ module.exports = (create) => {
1818
ws = create()
1919
})
2020

21-
it('listen, check for callback', (done) => {
22-
const listener = ws.createListener((conn) => {})
21+
it('listen, check for promise', async () => {
22+
const listener = ws.createListener(() => {})
2323

24-
listener.listen(ma, (err) => {
25-
expect(err).to.not.exist()
26-
listener.close(done)
27-
})
24+
await listener.listen(ma)
25+
listener.close()
2826
})
2927

30-
it('listen, check for listening event', (done) => {
31-
const listener = ws.createListener((conn) => {})
28+
it('listen, check for listening event', async () => {
29+
const listener = ws.createListener(() => {})
30+
31+
const p = new Promise((resolve) => {
32+
listener.once('listening', () => {
33+
listener.close()
34+
resolve()
35+
})
36+
})
3237

33-
listener.once('listening', () => listener.close(done))
34-
listener.listen(ma)
38+
await listener.listen(ma)
39+
await p
3540
})
3641

37-
it('listen, check for the close event', (done) => {
38-
const listener = ws.createListener((conn) => {})
39-
listener.listen(ma, (err) => {
40-
expect(err).to.not.exist()
41-
listener.once('close', done)
42-
listener.close()
42+
it('listen, check for the close event', async () => {
43+
const listener = ws.createListener(() => {})
44+
45+
await listener.listen(ma)
46+
const p = new Promise((resolve) => {
47+
listener.once('close', () => resolve())
4348
})
44-
})
4549

46-
it.skip('close listener with connections, through timeout', (done) => {
47-
// TODO ? Should this apply ?
50+
listener.close()
51+
await p
4852
})
4953

50-
it.skip('listen on IPv6 addr', (done) => {
54+
it.skip('listen on IPv6 addr', () => {
5155
// TODO IPv6 not supported yet
5256
})
5357

54-
it('getAddrs', (done) => {
55-
const listener = ws.createListener((conn) => {})
56-
listener.listen(ma, (err) => {
57-
expect(err).to.not.exist()
58-
listener.getAddrs((err, addrs) => {
59-
expect(err).to.not.exist()
60-
expect(addrs[0]).to.deep.equal(ma)
61-
listener.close(done)
62-
})
63-
})
58+
it('getAddrs', async () => {
59+
const listener = ws.createListener(() => {})
60+
61+
await listener.listen(ma)
62+
63+
const addrs = listener.getAddrs()
64+
expect(addrs[0]).to.deep.equal(ma)
65+
66+
listener.close()
6467
})
6568
})
6669
}

‎test/transport/reconnect.node.js

+23-24
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
'use strict'
44

55
const chai = require('chai')
6-
const series = require('async/series')
76
const dirtyChai = require('dirty-chai')
87
const expect = chai.expect
98
chai.use(dirtyChai)
@@ -36,31 +35,29 @@ module.exports = (create) => {
3635
await sigS.stop()
3736
})
3837

39-
it('listen on the first', (done) => {
38+
it('listen on the first', async () => {
4039
ws1 = create()
4140

42-
const listener = ws1.createListener((conn) => {})
43-
series([
44-
(cb) => ws1.discovery.start(cb),
45-
(cb) => listener.listen(ma1, cb)
46-
], (err) => {
47-
expect(err).to.not.exist()
48-
done()
49-
})
41+
const listener = ws1.createListener(() => {})
42+
ws1.discovery.start()
43+
44+
await listener.listen(ma1)
5045
})
5146

52-
it('listen on the second, discover the first', (done) => {
47+
it('listen on the second, discover the first', async () => {
5348
ws2 = create()
5449

55-
ws1.discovery.once('peer', (peerInfo) => {
56-
expect(peerInfo.multiaddrs.has(ma2)).to.equal(true)
57-
done()
50+
const p = new Promise((resolve) => {
51+
ws1.discovery.once('peer', (peerInfo) => {
52+
expect(peerInfo.multiaddrs.has(ma2)).to.equal(true)
53+
resolve()
54+
})
5855
})
5956

60-
const listener = ws2.createListener((conn) => {})
61-
listener.listen(ma2, (err) => {
62-
expect(err).to.not.exist()
63-
})
57+
const listener = ws2.createListener(() => {})
58+
59+
await listener.listen(ma2)
60+
await p
6461
})
6562

6663
it('stops the server', async () => {
@@ -75,15 +72,17 @@ module.exports = (create) => {
7572
setTimeout(done, 2000)
7673
})
7774

78-
it('listen on the third, first discovers it', (done) => {
75+
it('listen on the third, first discovers it', async () => {
7976
ws3 = create()
8077

81-
const listener = ws3.createListener((conn) => {})
82-
listener.listen(ma3, (err) => expect(err).to.not.exist())
78+
const listener = ws3.createListener(() => {})
79+
await listener.listen(ma3)
8380

84-
ws1.discovery.once('peer', (peerInfo) => {
85-
expect(peerInfo.multiaddrs.has(ma3)).to.equal(true)
86-
done()
81+
await new Promise((resolve) => {
82+
ws1.discovery.once('peer', (peerInfo) => {
83+
expect(peerInfo.multiaddrs.has(ma3)).to.equal(true)
84+
resolve()
85+
})
8786
})
8887
})
8988
})

‎test/transport/track.js

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/* eslint-env mocha */
2+
/* eslint-disable no-console */
3+
4+
'use strict'
5+
6+
const chai = require('chai')
7+
const dirtyChai = require('dirty-chai')
8+
const expect = chai.expect
9+
chai.use(dirtyChai)
10+
const multiaddr = require('multiaddr')
11+
const pipe = require('it-pipe')
12+
13+
module.exports = (create) => {
14+
describe('track connections', () => {
15+
let ws1
16+
let ws2
17+
let ma1
18+
let ma2
19+
let listener
20+
21+
const maHSDNS = '/dns/star-signal.cloud.ipfs.team'
22+
const maHSIP = '/ip4/188.166.203.82/tcp/20000'
23+
24+
const maLS = '/ip4/127.0.0.1/tcp/15555'
25+
const maGen = (base, id) => multiaddr(`${base}/wss/p2p-webrtc-star/p2p/${id}`) // https
26+
// const maGen = (base, id) => multiaddr(`${base}/ws/p2p-webrtc-star/ipfs/${id}`)
27+
28+
if (process.env.WEBRTC_STAR_REMOTE_SIGNAL_DNS) {
29+
// test with deployed signalling server using DNS
30+
console.log('Using DNS:', maHSDNS)
31+
ma1 = maGen(maHSDNS, 'QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSooo2a')
32+
ma2 = maGen(maHSDNS, 'QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSooo2b')
33+
} else if (process.env.WEBRTC_STAR_REMOTE_SIGNAL_IP) {
34+
// test with deployed signalling server using IP
35+
console.log('Using IP:', maHSIP)
36+
ma1 = maGen(maHSIP, 'QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSooo2a')
37+
ma2 = maGen(maHSIP, 'QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSooo2b')
38+
} else {
39+
ma1 = maGen(maLS, 'QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSooo2a')
40+
ma2 = maGen(maLS, 'QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSooo2b')
41+
}
42+
43+
beforeEach(async () => {
44+
// first
45+
ws1 = create()
46+
listener = ws1.createListener((conn) => pipe(conn, conn))
47+
48+
// second
49+
ws2 = create()
50+
const listener2 = ws2.createListener((conn) => pipe(conn, conn))
51+
52+
await Promise.all([listener.listen(ma1), listener2.listen(ma2)])
53+
})
54+
55+
it('should untrack conn after being closed', async function () {
56+
this.timeout(20e3)
57+
expect(listener.__connections).to.have.lengthOf(0)
58+
59+
const conn = await ws1.dial(ma1)
60+
expect(listener.__connections).to.have.lengthOf(1)
61+
62+
await conn.close()
63+
64+
// wait for listener to know of the disconnect
65+
await new Promise((resolve) => {
66+
setTimeout(resolve, 5000)
67+
})
68+
69+
expect(listener.__connections).to.have.lengthOf(0)
70+
})
71+
})
72+
}

‎test/transport/valid-connection.js

-74
This file was deleted.

‎test/utils.spec.js

+12-12
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,23 @@ const dirtyChai = require('dirty-chai')
77
const expect = chai.expect
88
chai.use(dirtyChai)
99
const multiaddr = require('multiaddr')
10-
const cleanMultiaddr = require('../src/utils').cleanMultiaddr
11-
const cleanUrlSIO = require('../src/utils').cleanUrlSIO
10+
const { cleanMultiaddr } = require('../src/utils')
11+
const { cleanUrlSIO } = require('../src/utils')
1212

1313
describe('utils', () => {
14-
const legacyMultiaddrStringDNS = '/libp2p-webrtc-star/dns4/star-signal.cloud.ipfs.team/tcp/443/wss/ipfs/QmWxLfixekyv6GAzvDEtXfXjj7gb1z3G8i5aQNHLhw1zA1'
15-
const legacyMultiaddrStringIP = '/libp2p-webrtc-star/ip4/127.0.0.1/tcp/1212/wss/ipfs/QmWxLfixekyv6GAzvDEtXfXjj7gb1z3G8i5aQNHLhw1zA1'
14+
const legacyMultiaddrStringDNS = '/libp2p-webrtc-star/dns4/star-signal.cloud.ipfs.team/tcp/443/wss/p2p/QmWxLfixekyv6GAzvDEtXfXjj7gb1z3G8i5aQNHLhw1zA1'
15+
const legacyMultiaddrStringIP = '/libp2p-webrtc-star/ip4/127.0.0.1/tcp/1212/wss/p2p/QmWxLfixekyv6GAzvDEtXfXjj7gb1z3G8i5aQNHLhw1zA1'
1616

17-
const modernMultiaddrStringDNS = '/dns4/star-signal.cloud.ipfs.team/tcp/443/wss/p2p-webrtc-star/ipfs/QmWxLfixekyv6GAzvDEtXfXjj7gb1z3G8i5aQNHLhw1zA1'
18-
const modernMultiaddrStringIP = '/ip4/127.0.0.1/tcp/1212/wss/p2p-webrtc-star/ipfs/QmWxLfixekyv6GAzvDEtXfXjj7gb1z3G8i5aQNHLhw1zA1'
17+
const modernMultiaddrStringDNS = '/dns4/star-signal.cloud.ipfs.team/tcp/443/wss/p2p-webrtc-star/p2p/QmWxLfixekyv6GAzvDEtXfXjj7gb1z3G8i5aQNHLhw1zA1'
18+
const modernMultiaddrStringIP = '/ip4/127.0.0.1/tcp/1212/wss/p2p-webrtc-star/p2p/QmWxLfixekyv6GAzvDEtXfXjj7gb1z3G8i5aQNHLhw1zA1'
1919

20-
const modernMultiaddrStringDNS2 = '/dns4/star-signal.cloud.ipfs.team/tcp/9999/wss/p2p-webrtc-star/ipfs/QmWxLfixekyv6GAzvDEtXfXjj7gb1z3G8i5aQNHLhw1zA1'
21-
const modernMultiaddrStringDNS3 = '/dns4/star-signal.cloud.ipfs.team/tcp/80/ws/p2p-webrtc-star/ipfs/QmWxLfixekyv6GAzvDEtXfXjj7gb1z3G8i5aQNHLhw1zA1'
22-
const modernMultiaddrStringDNS4 = '/dns4/star-signal.cloud.ipfs.team/tcp/8080/ws/p2p-webrtc-star/ipfs/QmWxLfixekyv6GAzvDEtXfXjj7gb1z3G8i5aQNHLhw1zA1'
20+
const modernMultiaddrStringDNS2 = '/dns4/star-signal.cloud.ipfs.team/tcp/9999/wss/p2p-webrtc-star/p2p/QmWxLfixekyv6GAzvDEtXfXjj7gb1z3G8i5aQNHLhw1zA1'
21+
const modernMultiaddrStringDNS3 = '/dns4/star-signal.cloud.ipfs.team/tcp/80/ws/p2p-webrtc-star/p2p/QmWxLfixekyv6GAzvDEtXfXjj7gb1z3G8i5aQNHLhw1zA1'
22+
const modernMultiaddrStringDNS4 = '/dns4/star-signal.cloud.ipfs.team/tcp/8080/ws/p2p-webrtc-star/p2p/QmWxLfixekyv6GAzvDEtXfXjj7gb1z3G8i5aQNHLhw1zA1'
2323

24-
const invalidMultiaddrStringDNS = '/dns4/star-signal.cloud.ipfs.team/udp/8080/wss/p2p-webrtc-star/ipfs/QmWxLfixekyv6GAzvDEtXfXjj7gb1z3G8i5aQNHLhw1zA1'
25-
const invalidMultiaddrStringDNS2 = '/dns4/star-signal.cloud.ipfs.team/tcp/8080/p2p-webrtc-star/ipfs/QmWxLfixekyv6GAzvDEtXfXjj7gb1z3G8i5aQNHLhw1zA1'
26-
const invalidMultiaddrStringDNS3 = '/dns4/star-signal.cloud.ipfs.team/ws/p2p-webrtc-star/ipfs/QmWxLfixekyv6GAzvDEtXfXjj7gb1z3G8i5aQNHLhw1zA1'
24+
const invalidMultiaddrStringDNS = '/dns4/star-signal.cloud.ipfs.team/udp/8080/wss/p2p-webrtc-star/p2p/QmWxLfixekyv6GAzvDEtXfXjj7gb1z3G8i5aQNHLhw1zA1'
25+
const invalidMultiaddrStringDNS2 = '/dns4/star-signal.cloud.ipfs.team/tcp/8080/p2p-webrtc-star/p2p/QmWxLfixekyv6GAzvDEtXfXjj7gb1z3G8i5aQNHLhw1zA1'
26+
const invalidMultiaddrStringDNS3 = '/dns4/star-signal.cloud.ipfs.team/ws/p2p-webrtc-star/p2p/QmWxLfixekyv6GAzvDEtXfXjj7gb1z3G8i5aQNHLhw1zA1'
2727

2828
// Create actual multiaddrs
2929
const modernMultiaddrDNS = multiaddr(modernMultiaddrStringDNS)

0 commit comments

Comments
 (0)
This repository has been archived.