@@ -4,9 +4,10 @@ import { publicKeyFromProtobuf, publicKeyToProtobuf } from '@libp2p/crypto/keys'
4
4
import { InvalidMessageError , UnsupportedProtocolError , serviceCapabilities , setMaxListeners } from '@libp2p/interface'
5
5
import { peerIdFromCID } from '@libp2p/peer-id'
6
6
import { RecordEnvelope , PeerRecord } from '@libp2p/peer-record'
7
+ import { isGlobalUnicast } from '@libp2p/utils/multiaddr/is-global-unicast'
7
8
import { isPrivate } from '@libp2p/utils/multiaddr/is-private'
8
9
import { protocols } from '@multiformats/multiaddr'
9
- import { IP_OR_DOMAIN } from '@multiformats/multiaddr-matcher'
10
+ import { IP_OR_DOMAIN , TCP } from '@multiformats/multiaddr-matcher'
10
11
import { pbStream } from 'it-protobuf-stream'
11
12
import {
12
13
MULTICODEC_IDENTIFY_PROTOCOL_NAME ,
@@ -18,6 +19,8 @@ import type { Identify as IdentifyInterface, IdentifyComponents, IdentifyInit }
18
19
import type { IdentifyResult , AbortOptions , Connection , Stream , Startable } from '@libp2p/interface'
19
20
import type { IncomingStreamData } from '@libp2p/interface-internal'
20
21
22
+ const CODEC_IP6 = 0x29
23
+
21
24
export class Identify extends AbstractIdentify implements Startable , IdentifyInterface {
22
25
constructor ( components : IdentifyComponents , init : IdentifyInit = { } ) {
23
26
super ( components , {
@@ -105,22 +108,45 @@ export class Identify extends AbstractIdentify implements Startable, IdentifyInt
105
108
}
106
109
107
110
// Get the observedAddr if there is one
108
- const cleanObservedAddr = getCleanMultiaddr ( observedAddr )
111
+ this . maybeAddObservedAddress ( observedAddr )
109
112
110
113
this . log ( 'identify completed for peer %p and protocols %o' , id , protocols )
111
114
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
+ }
114
117
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
121
124
}
122
125
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 )
124
150
}
125
151
126
152
/**
0 commit comments