diff --git a/p2p/host/basic/basic_host.go b/p2p/host/basic/basic_host.go index 83c0f705..31681eda 100644 --- a/p2p/host/basic/basic_host.go +++ b/p2p/host/basic/basic_host.go @@ -2,6 +2,7 @@ package basichost import ( "io" + "time" peer "github.com/ipfs/go-libp2p-peer" pstore "github.com/ipfs/go-libp2p-peerstore" @@ -102,20 +103,29 @@ func (h *BasicHost) newConnHandler(c inet.Conn) { // newStreamHandler is the remote-opened stream handler for inet.Network // TODO: this feels a bit wonky func (h *BasicHost) newStreamHandler(s inet.Stream) { + before := time.Now() protoID, handle, err := h.Mux().Negotiate(s) + took := time.Now().Sub(before) if err != nil { if err == io.EOF { - log.Debugf("protocol EOF: %s", s.Conn().RemotePeer()) + logf := log.Debugf + if took > time.Second*10 { + logf = log.Warningf + } + logf("protocol EOF: %s (took %s)", s.Conn().RemotePeer(), took) } else { - log.Warning("protocol mux failed: %s", err) + log.Warning("protocol mux failed: %s (took %s)", err, took) } return } s.SetProtocol(protocol.ID(protoID)) - logStream := mstream.WrapStream(s, h.bwc) + if h.bwc != nil { + s = mstream.WrapStream(s, h.bwc) + } + log.Debugf("protocol negotiation took %s", took) - go handle(protoID, logStream) + go handle(protoID, s) } // ID returns the (local) peer.ID associated with this Host diff --git a/p2p/net/swarm/swarm_dial.go b/p2p/net/swarm/swarm_dial.go index 57365177..6d1abd33 100644 --- a/p2p/net/swarm/swarm_dial.go +++ b/p2p/net/swarm/swarm_dial.go @@ -372,10 +372,21 @@ func (s *Swarm) dialAddr(ctx context.Context, p peer.ID, addr ma.Multiaddr) (con return connC, nil } +var ConnSetupTimeout = time.Minute * 5 + // dialConnSetup is the setup logic for a connection from the dial side. it // needs to add the Conn to the StreamSwarm, then run newConnSetup func dialConnSetup(ctx context.Context, s *Swarm, connC conn.Conn) (*Conn, error) { + deadline, ok := ctx.Deadline() + if !ok { + deadline = time.Now().Add(ConnSetupTimeout) + } + + if err := connC.SetDeadline(deadline); err != nil { + return nil, err + } + psC, err := s.swarm.AddConn(connC) if err != nil { // connC is closed by caller if we fail. @@ -389,5 +400,10 @@ func dialConnSetup(ctx context.Context, s *Swarm, connC conn.Conn) (*Conn, error return nil, err } + if err := connC.SetDeadline(time.Time{}); err != nil { + log.Error("failed to reset connection deadline after setup: ", err) + return nil, err + } + return swarmC, err }