Skip to content

Commit 4c2639e

Browse files
authored
identify: reduce timeout to 5 seconds (#3259)
The max message size is about 100kB. 5 seconds are enough to transfer this.
1 parent 88b1a70 commit 4c2639e

3 files changed

Lines changed: 35 additions & 30 deletions

File tree

p2p/protocol/identify/id.go

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,15 @@ import (
3232

3333
var log = logging.Logger("net/identify")
3434

35-
var Timeout = 30 * time.Second // timeout on all incoming Identify interactions
36-
3735
const (
3836
// ID is the protocol.ID of version 1.0.0 of the identify service.
3937
ID = "/ipfs/id/1.0.0"
4038
// IDPush is the protocol.ID of the Identify push protocol.
4139
// It sends full identify messages containing the current state of the peer.
4240
IDPush = "/ipfs/id/push/1.0.0"
43-
41+
// DefaultTimeout for all id interactions, incoming / outgoing, id / id-push.
42+
DefaultTimeout = 5 * time.Second
43+
// ServiceName is the default identify service name
4444
ServiceName = "libp2p.identify"
4545

4646
legacyIDSize = 2 * 1024
@@ -148,6 +148,7 @@ type idService struct {
148148
refCount sync.WaitGroup
149149

150150
disableSignedPeerRecord bool
151+
timeout time.Duration
151152

152153
connsMu sync.RWMutex
153154
// The conns map contains all connections we're currently handling.
@@ -182,7 +183,9 @@ type normalizer interface {
182183
// NewIDService constructs a new *idService and activates it by
183184
// attaching its stream handler to the given host.Host.
184185
func NewIDService(h host.Host, opts ...Option) (*idService, error) {
185-
var cfg config
186+
cfg := config{
187+
timeout: DefaultTimeout,
188+
}
186189
for _, opt := range opts {
187190
opt(&cfg)
188191
}
@@ -203,6 +206,7 @@ func NewIDService(h host.Host, opts ...Option) (*idService, error) {
203206
disableSignedPeerRecord: cfg.disableSignedPeerRecord,
204207
setupCompleted: make(chan struct{}),
205208
metricsTracer: cfg.metricsTracer,
209+
timeout: cfg.timeout,
206210
}
207211

208212
var normalize func(ma.Multiaddr) ma.Multiaddr
@@ -344,10 +348,10 @@ func (ids *idService) sendPushes(ctx context.Context) {
344348
go func(c network.Conn) {
345349
defer wg.Done()
346350
defer func() { <-sem }()
347-
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
351+
ctx, cancel := context.WithTimeout(ctx, ids.timeout)
348352
defer cancel()
349353

350-
str, err := newStreamAndNegotiate(ctx, c, IDPush)
354+
str, err := newStreamAndNegotiate(ctx, c, IDPush, ids.timeout)
351355
if err != nil { // connection might have been closed recently
352356
return
353357
}
@@ -438,34 +442,35 @@ func (ids *idService) IdentifyWait(c network.Conn) <-chan struct{} {
438442
}
439443

440444
// newStreamAndNegotiate opens a new stream on the given connection and negotiates the given protocol.
441-
func newStreamAndNegotiate(ctx context.Context, c network.Conn, proto protocol.ID) (network.Stream, error) {
445+
func newStreamAndNegotiate(ctx context.Context, c network.Conn, proto protocol.ID, timeout time.Duration) (network.Stream, error) {
442446
s, err := c.NewStream(network.WithAllowLimitedConn(ctx, "identify"))
443447
if err != nil {
444448
log.Debugw("error opening identify stream", "peer", c.RemotePeer(), "error", err)
445-
return nil, err
449+
return nil, fmt.Errorf("failed to open new stream: %w", err)
446450
}
447451

448452
// Ignore the error. Consistent with our previous behavior. (See https://github.com/libp2p/go-libp2p/issues/3109)
449-
_ = s.SetDeadline(time.Now().Add(Timeout))
453+
_ = s.SetDeadline(time.Now().Add(timeout))
450454

451455
if err := s.SetProtocol(proto); err != nil {
452456
log.Warnf("error setting identify protocol for stream: %s", err)
453457
_ = s.Reset()
458+
return nil, fmt.Errorf("failed to set protocol: %w", err)
454459
}
455460

456461
// ok give the response to our handler.
457462
if err := msmux.SelectProtoOrFail(proto, s); err != nil {
458463
log.Infow("failed negotiate identify protocol with peer", "peer", c.RemotePeer(), "error", err)
459464
_ = s.Reset()
460-
return nil, err
465+
return nil, fmt.Errorf("multistream mux select protocol failed: %w", err)
461466
}
462467
return s, nil
463468
}
464469

465470
func (ids *idService) identifyConn(c network.Conn) error {
466-
ctx, cancel := context.WithTimeout(context.Background(), Timeout)
471+
ctx, cancel := context.WithTimeout(context.Background(), ids.timeout)
467472
defer cancel()
468-
s, err := newStreamAndNegotiate(network.WithAllowLimitedConn(ctx, "identify"), c, ID)
473+
s, err := newStreamAndNegotiate(network.WithAllowLimitedConn(ctx, "identify"), c, ID, ids.timeout)
469474
if err != nil {
470475
log.Debugw("error opening identify stream", "peer", c.RemotePeer(), "error", err)
471476
return err
@@ -476,8 +481,10 @@ func (ids *idService) identifyConn(c network.Conn) error {
476481

477482
// handlePush handles incoming identify push streams
478483
func (ids *idService) handlePush(s network.Stream) {
479-
s.SetDeadline(time.Now().Add(Timeout))
480-
ids.handleIdentifyResponse(s, true)
484+
s.SetDeadline(time.Now().Add(ids.timeout))
485+
if err := ids.handleIdentifyResponse(s, true); err != nil {
486+
log.Debugf("failed to handle identify push: %s", err)
487+
}
481488
}
482489

483490
func (ids *idService) handleIdentifyRequest(s network.Stream) {

p2p/protocol/identify/id_test.go

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -817,12 +817,6 @@ func TestLargePushMessage(t *testing.T) {
817817
}
818818

819819
func TestIdentifyResponseReadTimeout(t *testing.T) {
820-
timeout := identify.Timeout
821-
identify.Timeout = 100 * time.Millisecond
822-
defer func() {
823-
identify.Timeout = timeout
824-
}()
825-
826820
ctx, cancel := context.WithCancel(context.Background())
827821
defer cancel()
828822

@@ -832,12 +826,12 @@ func TestIdentifyResponseReadTimeout(t *testing.T) {
832826
defer h2.Close()
833827

834828
h2p := h2.ID()
835-
ids1, err := identify.NewIDService(h1)
829+
ids1, err := identify.NewIDService(h1, identify.WithTimeout(100*time.Millisecond))
836830
require.NoError(t, err)
837831
defer ids1.Close()
838832
ids1.Start()
839833

840-
ids2, err := identify.NewIDService(h2)
834+
ids2, err := identify.NewIDService(h2, identify.WithTimeout(100*time.Millisecond))
841835
require.NoError(t, err)
842836
defer ids2.Close()
843837
ids2.Start()
@@ -863,12 +857,6 @@ func TestIdentifyResponseReadTimeout(t *testing.T) {
863857
}
864858

865859
func TestIncomingIDStreamsTimeout(t *testing.T) {
866-
timeout := identify.Timeout
867-
identify.Timeout = 100 * time.Millisecond
868-
defer func() {
869-
identify.Timeout = timeout
870-
}()
871-
872860
ctx, cancel := context.WithCancel(context.Background())
873861
defer cancel()
874862

@@ -880,12 +868,12 @@ func TestIncomingIDStreamsTimeout(t *testing.T) {
880868
defer h1.Close()
881869
defer h2.Close()
882870

883-
ids1, err := identify.NewIDService(h1)
871+
ids1, err := identify.NewIDService(h1, identify.WithTimeout(100*time.Millisecond))
884872
require.NoError(t, err)
885873
defer ids1.Close()
886874
ids1.Start()
887875

888-
ids2, err := identify.NewIDService(h2)
876+
ids2, err := identify.NewIDService(h2, identify.WithTimeout(100*time.Millisecond))
889877
require.NoError(t, err)
890878
defer ids2.Close()
891879
ids2.Start()

p2p/protocol/identify/opts.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package identify
22

3+
import "time"
4+
35
type config struct {
46
protocolVersion string
57
userAgent string
68
disableSignedPeerRecord bool
79
metricsTracer MetricsTracer
810
disableObservedAddrManager bool
11+
timeout time.Duration
912
}
1013

1114
// Option is an option function for identify.
@@ -47,3 +50,10 @@ func DisableObservedAddrManager() Option {
4750
cfg.disableObservedAddrManager = true
4851
}
4952
}
53+
54+
// WithTimeout sets the timeout for identify interactions.
55+
func WithTimeout(timeout time.Duration) Option {
56+
return func(cfg *config) {
57+
cfg.timeout = timeout
58+
}
59+
}

0 commit comments

Comments
 (0)