@@ -4,9 +4,10 @@ import { publicKeyFromProtobuf, publicKeyToProtobuf } from '@libp2p/crypto/keys'
44import { InvalidMessageError , UnsupportedProtocolError , serviceCapabilities , setMaxListeners } from '@libp2p/interface'
55import { peerIdFromCID } from '@libp2p/peer-id'
66import { RecordEnvelope , PeerRecord } from '@libp2p/peer-record'
7+ import { isGlobalUnicast } from '@libp2p/utils/multiaddr/is-global-unicast'
78import { isPrivate } from '@libp2p/utils/multiaddr/is-private'
89import { protocols } from '@multiformats/multiaddr'
9- import { IP_OR_DOMAIN } from '@multiformats/multiaddr-matcher'
10+ import { IP_OR_DOMAIN , TCP } from '@multiformats/multiaddr-matcher'
1011import { pbStream } from 'it-protobuf-stream'
1112import {
1213 MULTICODEC_IDENTIFY_PROTOCOL_NAME ,
@@ -18,6 +19,8 @@ import type { Identify as IdentifyInterface, IdentifyComponents, IdentifyInit }
1819import type { IdentifyResult , AbortOptions , Connection , Stream , Startable } from '@libp2p/interface'
1920import type { IncomingStreamData } from '@libp2p/interface-internal'
2021
22+ const CODEC_IP6 = 0x29
23+
2124export class Identify extends AbstractIdentify implements Startable , IdentifyInterface {
2225 constructor ( components : IdentifyComponents , init : IdentifyInit = { } ) {
2326 super ( components , {
@@ -105,22 +108,45 @@ export class Identify extends AbstractIdentify implements Startable, IdentifyInt
105108 }
106109
107110 // Get the observedAddr if there is one
108- const cleanObservedAddr = getCleanMultiaddr ( observedAddr )
111+ this . maybeAddObservedAddress ( observedAddr )
109112
110113 this . log ( 'identify completed for peer %p and protocols %o' , id , protocols )
111114
112- if ( cleanObservedAddr != null ) {
113- this . log ( 'our observed address was %a' , cleanObservedAddr )
115+ return consumeIdentifyMessage ( this . peerStore , this . events , this . log , connection , message )
116+ }
114117
115- if ( isPrivate ( cleanObservedAddr ) ) {
116- this . log ( 'our observed address was private' )
117- } else if ( this . addressManager . getObservedAddrs ( ) . length < ( this . maxObservedAddresses ?? Infinity ) ) {
118- this . log ( 'storing our observed address' )
119- this . addressManager . addObservedAddr ( cleanObservedAddr )
120- }
118+ private maybeAddObservedAddress ( observedAddr : Uint8Array | undefined ) : void {
119+ // Get the observedAddr if there is one
120+ const cleanObservedAddr = getCleanMultiaddr ( observedAddr )
121+
122+ if ( cleanObservedAddr == null ) {
123+ return
121124 }
122125
123- return consumeIdentifyMessage ( this . peerStore , this . events , this . log , connection , message )
126+ this . log . trace ( 'our observed address was %a' , cleanObservedAddr )
127+
128+ if ( isPrivate ( cleanObservedAddr ) ) {
129+ this . log . trace ( 'our observed address was private' )
130+ return
131+ }
132+
133+ const tuples = cleanObservedAddr . stringTuples ( )
134+
135+ if ( tuples [ 0 ] [ 0 ] === CODEC_IP6 && ! isGlobalUnicast ( cleanObservedAddr ) ) {
136+ this . log . trace ( 'our observed address was IPv6 but not a global unicast address' )
137+ return
138+ }
139+
140+ if ( TCP . exactMatch ( cleanObservedAddr ) ) {
141+ // TODO: because socket dials can't use the same local port as the TCP
142+ // listener, many unique observed addresses are reported so ignore all
143+ // TCP addresses until https://github.com/libp2p/js-libp2p/issues/2620
144+ // is resolved
145+ return
146+ }
147+
148+ this . log . trace ( 'storing the observed address' )
149+ this . addressManager . addObservedAddr ( cleanObservedAddr )
124150 }
125151
126152 /**
0 commit comments