1
- import { InvalidMultiaddrError , InvalidParametersError , InvalidPeerIdError , NotStartedError , start , stop } from '@libp2p/interface'
1
+ import { ConnectionClosedError , InvalidMultiaddrError , InvalidParametersError , InvalidPeerIdError , NotStartedError , start , stop } from '@libp2p/interface'
2
2
import { PeerMap } from '@libp2p/peer-collections'
3
3
import { defaultAddressSort } from '@libp2p/utils/address-sort'
4
4
import { RateLimiter } from '@libp2p/utils/rate-limiter'
@@ -214,8 +214,6 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
214
214
215
215
this . onConnect = this . onConnect . bind ( this )
216
216
this . onDisconnect = this . onDisconnect . bind ( this )
217
- this . events . addEventListener ( 'connection:open' , this . onConnect )
218
- this . events . addEventListener ( 'connection:close' , this . onDisconnect )
219
217
220
218
// allow/deny lists
221
219
this . allow = ( init . allow ?? [ ] ) . map ( ma => multiaddr ( ma ) )
@@ -268,10 +266,6 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
268
266
269
267
readonly [ Symbol . toStringTag ] = '@libp2p/connection-manager'
270
268
271
- isStarted ( ) : boolean {
272
- return this . started
273
- }
274
-
275
269
/**
276
270
* Starts the Connection Manager. If Metrics are not enabled on libp2p
277
271
* only event loop and connection limits will be monitored.
@@ -288,11 +282,7 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
288
282
289
283
for ( const conns of this . connections . values ( ) ) {
290
284
for ( const conn of conns ) {
291
- if ( conn . direction === 'inbound' ) {
292
- metric . inbound ++
293
- } else {
294
- metric . outbound ++
295
- }
285
+ metric [ conn . direction ] ++
296
286
}
297
287
}
298
288
@@ -356,9 +346,13 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
356
346
}
357
347
} )
358
348
349
+ this . events . addEventListener ( 'connection:open' , this . onConnect )
350
+ this . events . addEventListener ( 'connection:close' , this . onDisconnect )
351
+
359
352
await start (
360
353
this . dialQueue ,
361
- this . reconnectQueue
354
+ this . reconnectQueue ,
355
+ this . connectionPruner
362
356
)
363
357
364
358
this . started = true
@@ -369,9 +363,13 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
369
363
* Stops the Connection Manager
370
364
*/
371
365
async stop ( ) : Promise < void > {
366
+ this . events . removeEventListener ( 'connection:open' , this . onConnect )
367
+ this . events . removeEventListener ( 'connection:close' , this . onDisconnect )
368
+
372
369
await stop (
373
370
this . reconnectQueue ,
374
- this . dialQueue
371
+ this . dialQueue ,
372
+ this . connectionPruner
375
373
)
376
374
377
375
// Close all connections we're tracking
@@ -413,17 +411,19 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
413
411
return
414
412
}
415
413
416
- const peerId = connection . remotePeer
417
- const storedConns = this . connections . get ( peerId )
418
- let isNewPeer = false
419
-
420
- if ( storedConns != null ) {
421
- storedConns . push ( connection )
422
- } else {
423
- isNewPeer = true
424
- this . connections . set ( peerId , [ connection ] )
414
+ if ( connection . status !== 'open' ) {
415
+ // this can happen when the remote closes the connection immediately after
416
+ // opening
417
+ return
425
418
}
426
419
420
+ const peerId = connection . remotePeer
421
+ const isNewPeer = ! this . connections . has ( peerId )
422
+ const storedConns = this . connections . get ( peerId ) ?? [ ]
423
+ storedConns . push ( connection )
424
+
425
+ this . connections . set ( peerId , storedConns )
426
+
427
427
// only need to store RSA public keys, all other types are embedded in the peer id
428
428
if ( peerId . publicKey != null && peerId . type === 'RSA' ) {
429
429
await this . peerStore . patch ( peerId , {
@@ -441,20 +441,21 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
441
441
*/
442
442
onDisconnect ( evt : CustomEvent < Connection > ) : void {
443
443
const { detail : connection } = evt
444
+ const peerId = connection . remotePeer
445
+ const peerConns = this . connections . get ( peerId ) ?? [ ]
444
446
445
- if ( ! this . started ) {
446
- // This can happen when we are in the process of shutting down the node
447
- return
448
- }
447
+ // remove closed connection
448
+ const filteredPeerConns = peerConns . filter ( conn => conn . id !== connection . id )
449
449
450
- const peerId = connection . remotePeer
451
- let storedConn = this . connections . get ( peerId )
450
+ // update peer connections
451
+ this . connections . set ( peerId , filteredPeerConns )
452
452
453
- if ( storedConn != null && storedConn . length > 1 ) {
454
- storedConn = storedConn . filter ( ( conn ) => conn . id !== connection . id )
455
- this . connections . set ( peerId , storedConn )
456
- } else if ( storedConn != null ) {
453
+ if ( filteredPeerConns . length === 0 ) {
454
+ // trigger disconnect event if no connections remain
455
+ this . log ( 'onDisconnect remove all connections for peer %p' , peerId )
457
456
this . connections . delete ( peerId )
457
+
458
+ // broadcast disconnect event
458
459
this . events . safeDispatchEvent ( 'peer:disconnect' , { detail : connection . remotePeer } )
459
460
}
460
461
}
@@ -478,7 +479,7 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
478
479
}
479
480
480
481
async openConnection ( peerIdOrMultiaddr : PeerId | Multiaddr | Multiaddr [ ] , options : OpenConnectionOptions = { } ) : Promise < Connection > {
481
- if ( ! this . isStarted ( ) ) {
482
+ if ( ! this . started ) {
482
483
throw new NotStartedError ( 'Not started' )
483
484
}
484
485
@@ -508,10 +509,8 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
508
509
priority : options . priority ?? DEFAULT_DIAL_PRIORITY
509
510
} )
510
511
511
- if ( connection . remotePeer . equals ( this . peerId ) ) {
512
- const err = new InvalidPeerIdError ( 'Can not dial self' )
513
- connection . abort ( err )
514
- throw err
512
+ if ( connection . status !== 'open' ) {
513
+ throw new ConnectionClosedError ( 'Remote closed connection during opening' )
515
514
}
516
515
517
516
let peerConnections = this . connections . get ( connection . remotePeer )
0 commit comments