Skip to content

Commit c8bd6b5

Browse files
authored
fix: return the best _acceptable_ conn in NewStream (#1604)
* fix: return the best _acceptable_ conn in NewStream Otherwise, we can return, e.g., a transient connection that can't actually be used. * fix: fail dial if we can't have a usable connection If we have a transient connection, don't want to use a transient connection, and haven't specified "force direct dial", fail the dial.
1 parent e477efd commit c8bd6b5

File tree

3 files changed

+32
-16
lines changed

3 files changed

+32
-16
lines changed

p2p/net/swarm/dial_worker.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,9 @@ loop:
8989
return
9090
}
9191

92-
c := w.s.bestAcceptableConnToPeer(req.ctx, w.peer)
93-
if c != nil {
94-
req.resch <- dialResponse{conn: c}
92+
c, err := w.s.bestAcceptableConnToPeer(req.ctx, w.peer)
93+
if c != nil || err != nil {
94+
req.resch <- dialResponse{conn: c, err: err}
9595
continue loop
9696
}
9797

@@ -255,7 +255,7 @@ func (w *dialWorker) dispatchError(ad *addrDial, err error) {
255255
// all addrs have erred, dispatch dial error
256256
// but first do a last one check in case an acceptable connection has landed from
257257
// a simultaneous dial that started later and added new acceptable addrs
258-
c := w.s.bestAcceptableConnToPeer(pr.req.ctx, w.peer)
258+
c, _ := w.s.bestAcceptableConnToPeer(pr.req.ctx, w.peer)
259259
if c != nil {
260260
pr.req.resch <- dialResponse{conn: c}
261261
} else {

p2p/net/swarm/swarm.go

+23-8
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,11 @@ func (s *Swarm) NewStream(ctx context.Context, p peer.ID) (network.Stream, error
350350
dials := 0
351351
for {
352352
// will prefer direct connections over relayed connections for opening streams
353-
c := s.bestConnToPeer(p)
353+
c, err := s.bestAcceptableConnToPeer(ctx, p)
354+
if err != nil {
355+
return nil, err
356+
}
357+
354358
if c == nil {
355359
if nodial, _ := network.GetNoDial(ctx); nodial {
356360
return nil, network.ErrNoConn
@@ -447,15 +451,26 @@ func (s *Swarm) bestConnToPeer(p peer.ID) *Conn {
447451
return best
448452
}
449453

450-
func (s *Swarm) bestAcceptableConnToPeer(ctx context.Context, p peer.ID) *Conn {
454+
// - Returns the best "acceptable" connection, if available.
455+
// - Returns nothing if no such connection exists, but if we should try dialing anyways.
456+
// - Returns an error if no such connection exists, but we should not try dialing.
457+
func (s *Swarm) bestAcceptableConnToPeer(ctx context.Context, p peer.ID) (*Conn, error) {
451458
conn := s.bestConnToPeer(p)
452-
if conn != nil {
453-
forceDirect, _ := network.GetForceDirectDial(ctx)
454-
if !forceDirect || isDirectConn(conn) {
455-
return conn
456-
}
459+
if conn == nil {
460+
return nil, nil
457461
}
458-
return nil
462+
463+
forceDirect, _ := network.GetForceDirectDial(ctx)
464+
if forceDirect && !isDirectConn(conn) {
465+
return nil, nil
466+
}
467+
468+
useTransient, _ := network.GetUseTransient(ctx)
469+
if useTransient || !conn.Stat().Transient {
470+
return conn, nil
471+
}
472+
473+
return nil, network.ErrTransientConn
459474
}
460475

461476
func isDirectConn(c *Conn) bool {

p2p/net/swarm/swarm_dial.go

+5-4
Original file line numberDiff line numberDiff line change
@@ -244,10 +244,11 @@ func (s *Swarm) dialPeer(ctx context.Context, p peer.ID) (*Conn, error) {
244244
return nil, ErrDialToSelf
245245
}
246246

247-
// check if we already have an open (usable) connection first
248-
conn := s.bestAcceptableConnToPeer(ctx, p)
249-
if conn != nil {
250-
return conn, nil
247+
// check if we already have an open (usable) connection first, or can't have a usable
248+
// connection.
249+
conn, err := s.bestAcceptableConnToPeer(ctx, p)
250+
if conn != nil || err != nil {
251+
return conn, err
251252
}
252253

253254
if s.gater != nil && !s.gater.InterceptPeerDial(p) {

0 commit comments

Comments
 (0)