Skip to content

Commit

Permalink
feat: remove Mplex
Browse files Browse the repository at this point in the history
Mplex does not implement backpressure, our implementation will randomly reset streams if buffers overflow instead of risking deadlocks.

In the past we had a bug where kubo nodes would prefer mplex over yamux. Turning off mplex make our connections to thoses nodes negociate yamux.

Closes #9958
  • Loading branch information
Jorropo committed Aug 15, 2023
1 parent fe94dad commit eb45299
Show file tree
Hide file tree
Showing 8 changed files with 27 additions and 74 deletions.
48 changes: 9 additions & 39 deletions core/node/libp2p/smux.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@ package libp2p
import (
"fmt"
"os"
"strings"

"github.com/ipfs/kubo/config"

"github.com/libp2p/go-libp2p"
"github.com/libp2p/go-libp2p/core/network"
"github.com/libp2p/go-libp2p/p2p/muxer/mplex"
"github.com/libp2p/go-libp2p/p2p/muxer/yamux"
)

Expand All @@ -23,45 +21,17 @@ func yamuxTransport() network.Multiplexer {
}

func makeSmuxTransportOption(tptConfig config.Transports) (libp2p.Option, error) {
const yamuxID = "/yamux/1.0.0"
const mplexID = "/mplex/6.7.0"

if prefs := os.Getenv("LIBP2P_MUX_PREFS"); prefs != "" {
// Using legacy LIBP2P_MUX_PREFS variable.
log.Error("LIBP2P_MUX_PREFS is now deprecated.")
log.Error("Use the `Swarm.Transports.Multiplexers' config field.")
muxers := strings.Fields(prefs)
enabled := make(map[string]bool, len(muxers))

var opts []libp2p.Option
for _, tpt := range muxers {
if enabled[tpt] {
return nil, fmt.Errorf(
"duplicate muxer found in LIBP2P_MUX_PREFS: %s",
tpt,
)
}
switch tpt {
case yamuxID:
opts = append(opts, libp2p.Muxer(tpt, yamuxTransport()))
case mplexID:
opts = append(opts, libp2p.Muxer(tpt, mplex.DefaultTransport))
default:
return nil, fmt.Errorf("unknown muxer: %s", tpt)
}
}
return libp2p.ChainOptions(opts...), nil
} else {
return prioritizeOptions([]priorityOption{{
priority: tptConfig.Multiplexers.Yamux,
defaultPriority: 100,
opt: libp2p.Muxer(yamuxID, yamuxTransport()),
}, {
priority: tptConfig.Multiplexers.Mplex,
defaultPriority: 200,
opt: libp2p.Muxer(mplexID, mplex.DefaultTransport),
}}), nil
return nil, fmt.Errorf("configuring muxers with LIBP2P_MUX_PREFS is no longer supported")
}
if tptConfig.Multiplexers.Mplex != 0 {
return nil, fmt.Errorf("Swarm.Transports.Multiplexers.Mplex is no longer supported")
}
if tptConfig.Multiplexers.Yamux < 0 {
return nil, fmt.Errorf("Swarm.Transports.Multiplexers.Yamux is disabled even tho it is the only multiplexer available")
}

return libp2p.Muxer(yamux.ID, yamuxTransport()), nil
}

func SmuxTransport(tptConfig config.Transports) func() (opts Libp2pOpts, err error) {
Expand Down
11 changes: 10 additions & 1 deletion docs/changelogs/v0.23.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,23 @@

- [Overview](#overview)
- [🔦 Highlights](#-highlights)
- [Mplex removal](#mplex-removal)
- [📝 Changelog](#-changelog)
- [👨‍👩‍👧‍👦 Contributors](#-contributors)

### Overview

### 🔦 Highlights

#### Mplex removal

Support for Mplex was removed, this is because it is unreliable and would
randomly drop streams when sending data too fast.

New pieces of code rely on backpressure, that means the stream will dynamicaly
slow down if the sending rate if data is getting backed up.
Backpressure is provided by Yamux and QUIC.

### 📝 Changelog

### 👨‍👩‍👧‍👦 Contributors

24 changes: 8 additions & 16 deletions docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -2052,6 +2052,8 @@ Type: `flag`
Configuration section for libp2p _security_ transports. Transports enabled in
this section will be used to secure unencrypted connections.

This does not concern all the QUIC transports which use QUIC's builtin encryption.

Security transports are configured with the `priority` type.

When establishing an _outbound_ connection, Kubo will try each security
Expand Down Expand Up @@ -2094,11 +2096,13 @@ Type: `priority`
Configuration section for libp2p _multiplexer_ transports. Transports enabled in
this section will be used to multiplex duplex connections.

Multiplexer transports are secured the same way security transports are, with
This does not concern all the QUIC transports which use QUIC's builtin muxing.

Multiplexer transports are configured the same way security transports are, with
the `priority` type. Like with security transports, the initiator gets their
first choice.

Supported transports are: Yamux (priority 100) and Mplex (priority 200)
Supported transport is only: Yamux (priority 100)

No default priority will ever be less than 100.

Expand All @@ -2112,21 +2116,9 @@ Type: `priority`

### `Swarm.Transports.Multiplexers.Mplex`

Mplex is the default multiplexer used when communicating between Kubo and all
other IPFS and libp2p implementations. Unlike Yamux:

* Mplex is a simpler protocol.
* Mplex is more efficient.
* Mplex does not have built-in keepalives.
* Mplex does not support backpressure. Unfortunately, this means that, if a
single stream to a peer gets backed up for a period of time, the mplex
transport will kill the stream to allow the others to proceed. On the other
hand, the lack of backpressure means mplex can be significantly faster on some
high-latency connections.
**DEPRECATED**: See https://github.com/ipfs/kubo/issues/9958

Default: `200`

Type: `priority`
Support for Mplex has been removed. Please remove this option from your config.

## `DNS`

Expand Down
1 change: 0 additions & 1 deletion docs/examples/kubo-as-a-library/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,6 @@ require (
github.com/libp2p/go-libp2p-record v0.2.0 // indirect
github.com/libp2p/go-libp2p-routing-helpers v0.7.1 // indirect
github.com/libp2p/go-libp2p-xor v0.1.0 // indirect
github.com/libp2p/go-mplex v0.7.0 // indirect
github.com/libp2p/go-msgio v0.3.0 // indirect
github.com/libp2p/go-nat v0.2.0 // indirect
github.com/libp2p/go-netroute v0.2.1 // indirect
Expand Down
2 changes: 0 additions & 2 deletions docs/examples/kubo-as-a-library/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -482,8 +482,6 @@ github.com/libp2p/go-libp2p-routing-helpers v0.7.1/go.mod h1:cHStPSRC/wgbfpb5jYd
github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA=
github.com/libp2p/go-libp2p-xor v0.1.0 h1:hhQwT4uGrBcuAkUGXADuPltalOdpf9aag9kaYNT2tLA=
github.com/libp2p/go-libp2p-xor v0.1.0/go.mod h1:LSTM5yRnjGZbWNTA/hRwq2gGFrvRIbQJscoIL/u6InY=
github.com/libp2p/go-mplex v0.7.0 h1:BDhFZdlk5tbr0oyFq/xv/NPGfjbnrsDam1EvutpBDbY=
github.com/libp2p/go-mplex v0.7.0/go.mod h1:rW8ThnRcYWft/Jb2jeORBmPd6xuG3dGxWN/W168L9EU=
github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ=
github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0=
github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM=
Expand Down
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,6 @@ require (
github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect
github.com/libp2p/go-libp2p-gostream v0.6.0 // indirect
github.com/libp2p/go-libp2p-xor v0.1.0 // indirect
github.com/libp2p/go-mplex v0.7.0 // indirect
github.com/libp2p/go-msgio v0.3.0 // indirect
github.com/libp2p/go-nat v0.2.0 // indirect
github.com/libp2p/go-netroute v0.2.1 // indirect
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -545,8 +545,6 @@ github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUI
github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg=
github.com/libp2p/go-libp2p-xor v0.1.0 h1:hhQwT4uGrBcuAkUGXADuPltalOdpf9aag9kaYNT2tLA=
github.com/libp2p/go-libp2p-xor v0.1.0/go.mod h1:LSTM5yRnjGZbWNTA/hRwq2gGFrvRIbQJscoIL/u6InY=
github.com/libp2p/go-mplex v0.7.0 h1:BDhFZdlk5tbr0oyFq/xv/NPGfjbnrsDam1EvutpBDbY=
github.com/libp2p/go-mplex v0.7.0/go.mod h1:rW8ThnRcYWft/Jb2jeORBmPd6xuG3dGxWN/W168L9EU=
github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ=
github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0=
github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM=
Expand Down
12 changes: 0 additions & 12 deletions test/cli/transports_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,18 +71,6 @@ func TestTransports(t *testing.T) {
runTests(nodes)
})

t.Run("tcp with mplex", func(t *testing.T) {
t.Parallel()
nodes := tcpNodes(t)
nodes.ForEachPar(func(n *harness.Node) {
n.UpdateConfig(func(cfg *config.Config) {
cfg.Swarm.Transports.Multiplexers.Yamux = config.Disabled
})
})
nodes.StartDaemons().Connect()
runTests(nodes)
})

t.Run("tcp with NOISE", func(t *testing.T) {
t.Parallel()
nodes := tcpNodes(t)
Expand Down

0 comments on commit eb45299

Please sign in to comment.