@@ -2,7 +2,10 @@ package basichost
22
33import (
44 "testing"
5+ "time"
56
7+ "github.com/libp2p/go-libp2p/core/network"
8+ swarmt "github.com/libp2p/go-libp2p/p2p/net/swarm/testing"
69 ma "github.com/multiformats/go-multiaddr"
710 manet "github.com/multiformats/go-multiaddr/net"
811 "github.com/stretchr/testify/require"
@@ -96,3 +99,174 @@ func TestAppendNATAddrs(t *testing.T) {
9699 })
97100 }
98101}
102+
103+ type mockNatManager struct {
104+ GetMappingFunc func (addr ma.Multiaddr ) ma.Multiaddr
105+ HasDiscoveredNATFunc func () bool
106+ }
107+
108+ func (m * mockNatManager ) Close () error {
109+ return nil
110+ }
111+
112+ func (m * mockNatManager ) GetMapping (addr ma.Multiaddr ) ma.Multiaddr {
113+ return m .GetMappingFunc (addr )
114+ }
115+
116+ func (m * mockNatManager ) HasDiscoveredNAT () bool {
117+ return m .HasDiscoveredNATFunc ()
118+ }
119+
120+ var _ NATManager = & mockNatManager {}
121+
122+ type mockObservedAddrs struct {
123+ OwnObservedAddrsFunc func () []ma.Multiaddr
124+ ObservedAddrsForFunc func (ma.Multiaddr ) []ma.Multiaddr
125+ }
126+
127+ func (m * mockObservedAddrs ) OwnObservedAddrs () []ma.Multiaddr {
128+ return m .OwnObservedAddrsFunc ()
129+ }
130+
131+ func (m * mockObservedAddrs ) ObservedAddrsFor (local ma.Multiaddr ) []ma.Multiaddr {
132+ return m .ObservedAddrsForFunc (local )
133+ }
134+
135+ func TestAddressService (t * testing.T ) {
136+ getAddrService := func () * addressService {
137+ h , err := NewHost (swarmt .GenSwarm (t ), & HostOpts {DisableIdentifyAddressDiscovery : true })
138+ require .NoError (t , err )
139+ t .Cleanup (func () { h .Close () })
140+
141+ as := h .addressService
142+ return as
143+ }
144+
145+ t .Run ("NAT Address" , func (t * testing.T ) {
146+ as := getAddrService ()
147+ as .natmgr = & mockNatManager {
148+ HasDiscoveredNATFunc : func () bool { return true },
149+ GetMappingFunc : func (addr ma.Multiaddr ) ma.Multiaddr {
150+ if _ , err := addr .ValueForProtocol (ma .P_UDP ); err == nil {
151+ return ma .StringCast ("/ip4/1.2.3.4/udp/1/quic-v1" )
152+ }
153+ return nil
154+ },
155+ }
156+ require .Contains (t , as .Addrs (), ma .StringCast ("/ip4/1.2.3.4/udp/1/quic-v1" ))
157+ })
158+
159+ t .Run ("NAT And Observed Address" , func (t * testing.T ) {
160+ as := getAddrService ()
161+ as .natmgr = & mockNatManager {
162+ HasDiscoveredNATFunc : func () bool { return true },
163+ GetMappingFunc : func (addr ma.Multiaddr ) ma.Multiaddr {
164+ if _ , err := addr .ValueForProtocol (ma .P_UDP ); err == nil {
165+ return ma .StringCast ("/ip4/1.2.3.4/udp/1/quic-v1" )
166+ }
167+ return nil
168+ },
169+ }
170+ as .observedAddrsService = & mockObservedAddrs {
171+ ObservedAddrsForFunc : func (addr ma.Multiaddr ) []ma.Multiaddr {
172+ if _ , err := addr .ValueForProtocol (ma .P_TCP ); err == nil {
173+ return []ma.Multiaddr {ma .StringCast ("/ip4/2.2.2.2/tcp/1" )}
174+ }
175+ return nil
176+ },
177+ }
178+ require .Contains (t , as .Addrs (), ma .StringCast ("/ip4/1.2.3.4/udp/1/quic-v1" ))
179+ require .Contains (t , as .Addrs (), ma .StringCast ("/ip4/2.2.2.2/tcp/1" ))
180+ })
181+ t .Run ("Only Observed Address" , func (t * testing.T ) {
182+ as := getAddrService ()
183+ as .natmgr = nil
184+ as .observedAddrsService = & mockObservedAddrs {
185+ ObservedAddrsForFunc : func (addr ma.Multiaddr ) []ma.Multiaddr {
186+ if _ , err := addr .ValueForProtocol (ma .P_TCP ); err == nil {
187+ return []ma.Multiaddr {ma .StringCast ("/ip4/2.2.2.2/tcp/1" )}
188+ }
189+ return nil
190+ },
191+ OwnObservedAddrsFunc : func () []ma.Multiaddr {
192+ return []ma.Multiaddr {ma .StringCast ("/ip4/3.3.3.3/udp/1/quic-v1" )}
193+ },
194+ }
195+ require .NotContains (t , as .Addrs (), ma .StringCast ("/ip4/2.2.2.2/tcp/1" ))
196+ require .Contains (t , as .Addrs (), ma .StringCast ("/ip4/3.3.3.3/udp/1/quic-v1" ))
197+ })
198+ t .Run ("Public Addrs Removed When Private" , func (t * testing.T ) {
199+ as := getAddrService ()
200+ as .natmgr = nil
201+ as .observedAddrsService = & mockObservedAddrs {
202+ OwnObservedAddrsFunc : func () []ma.Multiaddr {
203+ return []ma.Multiaddr {ma .StringCast ("/ip4/3.3.3.3/udp/1/quic-v1" )}
204+ },
205+ }
206+ as .reachability = func () network.Reachability {
207+ return network .ReachabilityPrivate
208+ }
209+ relayAddr := ma .StringCast ("/ip4/1.2.3.4/udp/1/quic-v1/p2p/QmdXGaeGiVA745XorV1jr11RHxB9z4fqykm6xCUPX1aTJo/p2p-circuit" )
210+ as .autoRelayAddrs = func () []ma.Multiaddr {
211+ return []ma.Multiaddr {relayAddr }
212+ }
213+ require .NotContains (t , as .Addrs (), ma .StringCast ("/ip4/3.3.3.3/udp/1/quic-v1" ))
214+ require .Contains (t , as .Addrs (), relayAddr )
215+ require .Contains (t , as .AllAddrs (), ma .StringCast ("/ip4/3.3.3.3/udp/1/quic-v1" ))
216+ })
217+
218+ t .Run ("AddressFactory gets relay addresses" , func (t * testing.T ) {
219+ as := getAddrService ()
220+ as .natmgr = nil
221+ as .observedAddrsService = & mockObservedAddrs {
222+ OwnObservedAddrsFunc : func () []ma.Multiaddr {
223+ return []ma.Multiaddr {ma .StringCast ("/ip4/3.3.3.3/udp/1/quic-v1" )}
224+ },
225+ }
226+ as .reachability = func () network.Reachability {
227+ return network .ReachabilityPrivate
228+ }
229+ relayAddr := ma .StringCast ("/ip4/1.2.3.4/udp/1/quic-v1/p2p/QmdXGaeGiVA745XorV1jr11RHxB9z4fqykm6xCUPX1aTJo/p2p-circuit" )
230+ as .autoRelayAddrs = func () []ma.Multiaddr {
231+ return []ma.Multiaddr {relayAddr }
232+ }
233+ as .addrsFactory = func (addrs []ma.Multiaddr ) []ma.Multiaddr {
234+ for _ , a := range addrs {
235+ if a .Equal (relayAddr ) {
236+ return []ma.Multiaddr {ma .StringCast ("/ip4/3.3.3.3/udp/1/quic-v1" )}
237+ }
238+ }
239+ return nil
240+ }
241+ require .Contains (t , as .Addrs (), ma .StringCast ("/ip4/3.3.3.3/udp/1/quic-v1" ))
242+ require .NotContains (t , as .Addrs (), relayAddr )
243+ })
244+
245+ t .Run ("updates addresses on signaling" , func (t * testing.T ) {
246+ as := getAddrService ()
247+ as .natmgr = nil
248+ updateChan := make (chan struct {})
249+ a1 := ma .StringCast ("/ip4/1.1.1.1/udp/1/quic-v1" )
250+ a2 := ma .StringCast ("/ip4/1.1.1.1/tcp/1" )
251+ as .addrsFactory = func (addrs []ma.Multiaddr ) []ma.Multiaddr {
252+ select {
253+ case <- updateChan :
254+ return []ma.Multiaddr {a2 }
255+ default :
256+ return []ma.Multiaddr {a1 }
257+ }
258+ }
259+ as .Start ()
260+ require .Contains (t , as .Addrs (), a1 )
261+ require .NotContains (t , as .Addrs (), a2 )
262+ close (updateChan )
263+ as .SignalAddressChange ()
264+ select {
265+ case <- as .AddrsUpdated ():
266+ require .Contains (t , as .Addrs (), a2 )
267+ require .NotContains (t , as .Addrs (), a1 )
268+ case <- time .After (2 * time .Second ):
269+ t .Fatal ("expected addrs to be updated" )
270+ }
271+ })
272+ }
0 commit comments