@@ -119,7 +119,7 @@ func (hs *Service) initiateHolePunch(rp peer.ID) ([]ma.Multiaddr, time.Duration,
119119 // send a CONNECT and start RTT measurement.
120120 msg := & pb.HolePunch {
121121 Type : pb .HolePunch_CONNECT .Enum (),
122- ObsAddrs : addrsToBytes (hs .ids .OwnObservedAddrs ()),
122+ ObsAddrs : addrsToBytes (removeRelayAddrs ( hs .ids .OwnObservedAddrs () )),
123123 }
124124
125125 start := time .Now ()
@@ -141,8 +141,10 @@ func (hs *Service) initiateHolePunch(rp peer.ID) ([]ma.Multiaddr, time.Duration,
141141 str .Reset ()
142142 return nil , 0 , fmt .Errorf ("expect CONNECT message, got %s" , t )
143143 }
144-
145- addrs := addrsFromBytes (msg .ObsAddrs )
144+ addrs := removeRelayAddrs (addrsFromBytes (msg .ObsAddrs ))
145+ if len (addrs ) == 0 {
146+ str .Reset ()
147+ }
146148
147149 msg .Reset ()
148150 msg .Type = pb .HolePunch_SYNC .Enum ()
@@ -219,6 +221,10 @@ func (hs *Service) directConnect(rp peer.ID) error {
219221 }
220222 }
221223
224+ if len (hs .ids .OwnObservedAddrs ()) == 0 {
225+ return errors .New ("can't initiate hole punch, as we don't have any public addresses" )
226+ }
227+
222228 // hole punch
223229 for i := 0 ; i < maxRetries ; i ++ {
224230 addrs , rtt , err := hs .initiateHolePunch (rp )
@@ -260,6 +266,11 @@ func (hs *Service) incomingHolePunch(s network.Stream) (rtt time.Duration, addrs
260266 if ! isRelayAddress (s .Conn ().RemoteMultiaddr ()) {
261267 return 0 , nil , fmt .Errorf ("received hole punch stream: %s" , s .Conn ().RemoteMultiaddr ())
262268 }
269+ ownAddrs := removeRelayAddrs (hs .ids .OwnObservedAddrs ())
270+ // If we can't tell the peer where to dial us, there's no point in starting the hole punching.
271+ if len (ownAddrs ) == 0 {
272+ return 0 , nil , errors .New ("rejecting hole punch request, as we don't have any public addresses" )
273+ }
263274
264275 s .SetDeadline (time .Now ().Add (StreamTimeout ))
265276 wr := protoio .NewDelimitedWriter (s )
@@ -273,13 +284,16 @@ func (hs *Service) incomingHolePunch(s network.Stream) (rtt time.Duration, addrs
273284 if t := msg .GetType (); t != pb .HolePunch_CONNECT {
274285 return 0 , nil , fmt .Errorf ("expected CONNECT message from initiator but got %d" , t )
275286 }
276- obsDial := addrsFromBytes (msg .ObsAddrs )
287+ obsDial := removeRelayAddrs ( addrsFromBytes (msg .ObsAddrs ) )
277288 log .Debugw ("received hole punch request" , "peer" , s .Conn ().RemotePeer (), "addrs" , obsDial )
289+ if len (obsDial ) == 0 {
290+ return 0 , nil , fmt .Errorf ("expected CONNECT message to contain at least one message" )
291+ }
278292
279293 // Write CONNECT message
280294 msg .Reset ()
281295 msg .Type = pb .HolePunch_CONNECT .Enum ()
282- msg .ObsAddrs = addrsToBytes (hs . ids . OwnObservedAddrs () )
296+ msg .ObsAddrs = addrsToBytes (ownAddrs )
283297 tstart := time .Now ()
284298 if err := wr .WriteMsg (msg ); err != nil {
285299 return 0 , nil , fmt .Errorf ("failed to write CONNECT message to initator: %w" , err )
@@ -349,6 +363,16 @@ func (hs *Service) holePunchConnect(pi peer.AddrInfo, isClient bool) error {
349363 return nil
350364}
351365
366+ func removeRelayAddrs (addrs []ma.Multiaddr ) []ma.Multiaddr {
367+ result := make ([]ma.Multiaddr , 0 , len (addrs ))
368+ for _ , addr := range addrs {
369+ if ! isRelayAddress (addr ) {
370+ result = append (result , addr )
371+ }
372+ }
373+ return result
374+ }
375+
352376func isRelayAddress (a ma.Multiaddr ) bool {
353377 _ , err := a .ValueForProtocol (ma .P_CIRCUIT )
354378 return err == nil
0 commit comments