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

add options to the constructor #99

Merged
merged 2 commits into from
Sep 27, 2021
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ require (
github.com/multiformats/go-multiaddr-fmt v0.1.0
github.com/multiformats/go-multihash v0.0.15 // indirect
github.com/prometheus/client_golang v1.10.0
github.com/stretchr/testify v1.7.0
)
3 changes: 3 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,10 @@ github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa02
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs=
github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM=
Expand Down Expand Up @@ -581,6 +583,7 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
Expand Down
44 changes: 33 additions & 11 deletions tcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ import (
manet "github.com/multiformats/go-multiaddr/net"
)

// DefaultConnectTimeout is the (default) maximum amount of time the TCP
// transport will spend on the initial TCP connect before giving up.
var DefaultConnectTimeout = 5 * time.Second
const defaultConnectTimeout = 5 * time.Second

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

Expand Down Expand Up @@ -89,27 +87,51 @@ func (ll *tcpListener) Accept() (manet.Conn, error) {
return c, nil
}

type Option func(*TcpTransport) error

func DisableReuseport() Option {
return func(tr *TcpTransport) error {
tr.disableReuseport = true
return nil
}
}
func WithConnectionTimeout(d time.Duration) Option {
return func(tr *TcpTransport) error {
tr.connectTimeout = d
return nil
}
}

// TcpTransport is the TCP transport.
type TcpTransport struct {
// Connection upgrader for upgrading insecure stream connections to
// secure multiplex connections.
Upgrader *tptu.Upgrader

// Explicitly disable reuseport.
DisableReuseport bool
disableReuseport bool

// TCP connect timeout
ConnectTimeout time.Duration
connectTimeout time.Duration

reuse rtpt.Transport
}

var _ transport.Transport = &TcpTransport{}

// NewTCPTransport creates a tcp transport object that tracks dialers and listeners
// created. It represents an entire tcp stack (though it might not necessarily be)
func NewTCPTransport(upgrader *tptu.Upgrader) *TcpTransport {
return &TcpTransport{Upgrader: upgrader, ConnectTimeout: DefaultConnectTimeout}
// created. It represents an entire TCP stack (though it might not necessarily be).
func NewTCPTransport(upgrader *tptu.Upgrader, opts ...Option) (*TcpTransport, error) {
tr := &TcpTransport{
Upgrader: upgrader,
connectTimeout: defaultConnectTimeout, // can be set by using the WithConnectionTimeout option
}
for _, o := range opts {
if err := o(tr); err != nil {
return nil, err
}
}
return tr, nil
}

var dialMatcher = mafmt.And(mafmt.IP, mafmt.Base(ma.P_TCP))
Expand All @@ -122,9 +144,9 @@ func (t *TcpTransport) CanDial(addr ma.Multiaddr) bool {

func (t *TcpTransport) maDial(ctx context.Context, raddr ma.Multiaddr) (manet.Conn, error) {
// Apply the deadline iff applicable
if t.ConnectTimeout > 0 {
if t.connectTimeout > 0 {
var cancel context.CancelFunc
ctx, cancel = context.WithTimeout(ctx, t.ConnectTimeout)
ctx, cancel = context.WithTimeout(ctx, t.connectTimeout)
defer cancel()
}

Expand Down Expand Up @@ -159,7 +181,7 @@ func (t *TcpTransport) Dial(ctx context.Context, raddr ma.Multiaddr, p peer.ID)

// UseReuseport returns true if reuseport is enabled and available.
func (t *TcpTransport) UseReuseport() bool {
return !t.DisableReuseport && ReuseportIsAvailable()
return !t.disableReuseport && ReuseportIsAvailable()
}

func (t *TcpTransport) maListen(laddr ma.Multiaddr) (manet.Listener, error) {
Expand Down
34 changes: 15 additions & 19 deletions tcp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,25 @@ import (
tptu "github.com/libp2p/go-libp2p-transport-upgrader"

ma "github.com/multiformats/go-multiaddr"

"github.com/stretchr/testify/require"
)

func TestTcpTransport(t *testing.T) {
for i := 0; i < 2; i++ {
peerA, ia := makeInsecureMuxer(t)
_, ib := makeInsecureMuxer(t)

ta := NewTCPTransport(&tptu.Upgrader{
ta, err := NewTCPTransport(&tptu.Upgrader{
Secure: ia,
Muxer: new(mplex.Transport),
})
tb := NewTCPTransport(&tptu.Upgrader{
require.NoError(t, err)
tb, err := NewTCPTransport(&tptu.Upgrader{
Secure: ib,
Muxer: new(mplex.Transport),
})
require.NoError(t, err)

zero := "/ip4/127.0.0.1/tcp/0"
ttransport.SubtestTransport(t, ta, tb, zero, peerA)
Expand All @@ -40,15 +44,14 @@ func TestTcpTransport(t *testing.T) {
func TestTcpTransportCantDialDNS(t *testing.T) {
for i := 0; i < 2; i++ {
dnsa, err := ma.NewMultiaddr("/dns4/example.com/tcp/1234")
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)

_, sm := makeInsecureMuxer(t)
tpt := NewTCPTransport(&tptu.Upgrader{
tpt, err := NewTCPTransport(&tptu.Upgrader{
Secure: sm,
Muxer: new(mplex.Transport),
})
require.NoError(t, err)

if tpt.CanDial(dnsa) {
t.Fatal("shouldn't be able to dial dns")
Expand All @@ -62,20 +65,17 @@ func TestTcpTransportCantDialDNS(t *testing.T) {
func TestTcpTransportCantListenUtp(t *testing.T) {
for i := 0; i < 2; i++ {
utpa, err := ma.NewMultiaddr("/ip4/127.0.0.1/udp/0/utp")
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)

_, sm := makeInsecureMuxer(t)
tpt := NewTCPTransport(&tptu.Upgrader{
tpt, err := NewTCPTransport(&tptu.Upgrader{
Secure: sm,
Muxer: new(mplex.Transport),
})
require.NoError(t, err)

_, err = tpt.Listen(utpa)
if err == nil {
t.Fatal("shouldnt be able to listen on utp addr with tcp transport")
}
require.Error(t, err, "shouldnt be able to listen on utp addr with tcp transport")

envReuseportVal = false
}
Expand All @@ -85,13 +85,9 @@ func TestTcpTransportCantListenUtp(t *testing.T) {
func makeInsecureMuxer(t *testing.T) (peer.ID, sec.SecureMuxer) {
t.Helper()
priv, _, err := crypto.GenerateKeyPair(crypto.Ed25519, 256)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
id, err := peer.IDFromPrivateKey(priv)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
var secMuxer csms.SSMuxer
secMuxer.AddTransport(insecure.ID, insecure.NewWithIdentity(id, priv))
return id, &secMuxer
Expand Down