Skip to content

Commit 1f5db5a

Browse files
reject hole punching attempts when we don't have any public addresses
1 parent db8f9c6 commit 1f5db5a

File tree

1 file changed

+29
-5
lines changed

1 file changed

+29
-5
lines changed

p2p/protocol/holepunch/coordination.go

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
352376
func isRelayAddress(a ma.Multiaddr) bool {
353377
_, err := a.ValueForProtocol(ma.P_CIRCUIT)
354378
return err == nil

0 commit comments

Comments
 (0)