Skip to content
This repository has been archived by the owner on May 26, 2022. It is now read-only.

set linger to 0 for both inbound and outbound connections #36

Merged
merged 3 commits into from
Apr 4, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ require (
github.com/libp2p/go-libp2p-transport v0.0.4
github.com/libp2p/go-libp2p-transport-upgrader v0.0.1
github.com/libp2p/go-reuseport v0.0.1
github.com/libp2p/go-reuseport-transport v0.0.1
github.com/libp2p/go-reuseport-transport v0.0.2
github.com/multiformats/go-multiaddr v0.0.1
github.com/multiformats/go-multiaddr-net v0.0.1
github.com/whyrusleeping/go-smux-multiplex v3.0.16+incompatible
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ github.com/libp2p/go-mplex v0.0.1 h1:dn2XGSrUxLtz3/8u85bGrwhUEKPX8MOF3lpmcWBZCWc
github.com/libp2p/go-mplex v0.0.1/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0=
github.com/libp2p/go-reuseport v0.0.1 h1:7PhkfH73VXfPJYKQ6JwS5I/eVcoyYi9IMNGc6FWpFLw=
github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA=
github.com/libp2p/go-reuseport-transport v0.0.1 h1:UIRneNxLDmEGNjGHpIiWzSWkZ5bhxMCP9x3Vh7BSc7E=
github.com/libp2p/go-reuseport-transport v0.0.1/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs=
github.com/libp2p/go-reuseport-transport v0.0.2 h1:WglMwyXyBu61CMkjCCtnmqNqnjib0GIEjMiHTwR/KN4=
github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs=
github.com/libp2p/go-stream-muxer v0.0.1 h1:Ce6e2Pyu+b5MC1k3eeFtAax0pW4gc6MosYSLV05UeLw=
github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14=
github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg=
Expand Down
29 changes: 29 additions & 0 deletions tcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package tcp

import (
"context"
"net"
"time"

logging "github.com/ipfs/go-log"
Expand All @@ -20,6 +21,29 @@ var DefaultConnectTimeout = 5 * time.Second

var log = logging.Logger("tcp-tpt")

// try to set linger on the connection, if possible.
func tryLinger(conn net.Conn, sec int) {
if lingerConn, ok := conn.(interface {
SetLinger(int) error
}); ok {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a handful, maybe worth naming the linger interface.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bah!

_ = lingerConn.SetLinger(sec)
}
}

type lingerListener struct {
manet.Listener
sec int
}

func (ll *lingerListener) Accept() (manet.Conn, error) {
c, err := ll.Listener.Accept()
if err != nil {
return nil, err
}
tryLinger(c, ll.sec)
return c, nil
}

// TcpTransport is the TCP transport.
type TcpTransport struct {
// Connection upgrader for upgrading insecure stream connections to
Expand Down Expand Up @@ -73,6 +97,10 @@ func (t *TcpTransport) Dial(ctx context.Context, raddr ma.Multiaddr, p peer.ID)
if err != nil {
return nil, err
}
// Set linger to 0 so we never get stuck in the TIME-WAIT state. When
// linger is 0, connections are _reset_ instead of closed with a FIN.
// This means we can immediately reuse the 5-tuple and reconnect.
tryLinger(conn, 0)
return t.Upgrader.UpgradeOutbound(ctx, t, conn, p)
}

Expand All @@ -94,6 +122,7 @@ func (t *TcpTransport) Listen(laddr ma.Multiaddr) (tpt.Listener, error) {
if err != nil {
return nil, err
}
list = &lingerListener{list, 0}
return t.Upgrader.UpgradeListener(t, list), nil
}

Expand Down