Skip to content

Commit 3d4daa3

Browse files
Aperencegopherbot
authored andcommitted
net: enable multipath TCP by default for listeners
A previous change [1] was introduced to enable MPTCP by default for both the clients and servers, based on the discussions [2] in #56539, where MPTCP would be an opt-in for a release or two, and then would become an opt-out. This change was not accepted at the time because the support for a few socket options was missing [3]. Now that this support has been added [4] and backported to stable versions not to block MPTCP deployment with Go, it sounds like a good time to reconsider the use of MPTCP by default. Instead of enabling MPTCP on both ends by default, as a first step, it seems safer to change the default behaviour only for the server side (Listeners). On the server side, the impact is minimal: when clients don't request to use MPTCP, server applications will create "plain" TCP sockets within the kernel when connections are accepted, making the performance impact minimal. This should also ease experiments where MPTCP is enabled by default on the client side (Dialer). The changes in this patch consist of a duplication of the mptcpStatus enumeration to have both a mptcpStatusDial and a mptcpStatusListen, where MPTCP is enabled by default in mptcpStatusListen, but disabled by default in mptcpStatusDial. It is still possible to turn MPTCP support on and off by using GODEBUG=multipathtcp=1. [1] https://go-review.googlesource.com/c/go/+/563575 [2] https://go.dev/issue/56539#issuecomment-1309294637 [3] multipath-tcp/mptcp_net-next#383 [4] torvalds/linux@bd11dc4 [5] https://www.mptcp.dev/faq.html#why--when-should-mptcp-be-enabled-by-default Updates #56539 Change-Id: I1ca0d6aaf74d3bda5468af135e29cdb405d3fd00 GitHub-Last-Rev: 5f9f29b GitHub-Pull-Request: #69016 Reviewed-on: https://go-review.googlesource.com/c/go/+/607715 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> Reviewed-by: Matthieu Baerts <[email protected]> Auto-Submit: Ian Lance Taylor <[email protected]>
1 parent a9e6a96 commit 3d4daa3

File tree

4 files changed

+79
-19
lines changed

4 files changed

+79
-19
lines changed

doc/godebug.md

+11
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,17 @@ no-op. This behavior is controlled by the `randseednop` setting.
157157
For Go 1.24 it defaults to `randseednop=1`.
158158
Using `randseednop=0` reverts to the pre-Go 1.24 behavior.
159159

160+
Go 1.24 added new values for the `multipathtcp` setting.
161+
The possible values for `multipathtcp` are now:
162+
- "0": disable MPTCP on dialers and listeners by default
163+
- "1": enable MPTCP on dialers and listeners by default
164+
- "2": enable MPTCP on listeners only by default
165+
- "3": enable MPTCP on dialers only by default
166+
167+
For Go 1.24, it now defaults to multipathtcp="2", thus
168+
enabled by default on listerners. Using multipathtcp="0" reverts to the
169+
pre-Go 1.24 behavior.
170+
160171
### Go 1.23
161172

162173
Go 1.23 changed the channels created by package time to be unbuffered
+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[ListenConfig] now uses MPTCP by default on systems where it is supported
2+
(currently on Linux only).

src/internal/godebugs/table.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ var All = []Info{
4242
//{Name: "multipartfiles", Package: "mime/multipart"},
4343
{Name: "multipartmaxheaders", Package: "mime/multipart"},
4444
{Name: "multipartmaxparts", Package: "mime/multipart"},
45-
{Name: "multipathtcp", Package: "net"},
45+
{Name: "multipathtcp", Package: "net", Changed: 24, Old: "0"},
4646
{Name: "netdns", Package: "net", Opaque: true},
4747
{Name: "netedns0", Package: "net", Changed: 19, Old: "0"},
4848
{Name: "panicnil", Package: "runtime", Changed: 21, Old: "1"},

src/net/dial.go

+65-18
Original file line numberDiff line numberDiff line change
@@ -25,46 +25,93 @@ const (
2525
// defaultTCPKeepAliveCount is a default constant value for TCP_KEEPCNT.
2626
defaultTCPKeepAliveCount = 9
2727

28-
// For the moment, MultiPath TCP is not used by default
28+
// For the moment, MultiPath TCP is used by default with listeners, if
29+
// available, but not with dialers.
2930
// See go.dev/issue/56539
30-
defaultMPTCPEnabled = false
31+
defaultMPTCPEnabledListen = true
32+
defaultMPTCPEnabledDial = false
3133
)
3234

35+
// The type of service offered
36+
//
37+
// 0 == MPTCP disabled
38+
// 1 == MPTCP enabled
39+
// 2 == MPTCP enabled on listeners only
40+
// 3 == MPTCP enabled on dialers only
3341
var multipathtcp = godebug.New("multipathtcp")
3442

35-
// mptcpStatus is a tristate for Multipath TCP, see go.dev/issue/56539
36-
type mptcpStatus uint8
43+
// mptcpStatusDial is a tristate for Multipath TCP on clients,
44+
// see go.dev/issue/56539
45+
type mptcpStatusDial uint8
3746

3847
const (
39-
// The value 0 is the system default, linked to defaultMPTCPEnabled
40-
mptcpUseDefault mptcpStatus = iota
41-
mptcpEnabled
42-
mptcpDisabled
48+
// The value 0 is the system default, linked to defaultMPTCPEnabledDial
49+
mptcpUseDefaultDial mptcpStatusDial = iota
50+
mptcpEnabledDial
51+
mptcpDisabledDial
4352
)
4453

45-
func (m *mptcpStatus) get() bool {
54+
func (m *mptcpStatusDial) get() bool {
4655
switch *m {
47-
case mptcpEnabled:
56+
case mptcpEnabledDial:
4857
return true
49-
case mptcpDisabled:
58+
case mptcpDisabledDial:
5059
return false
5160
}
5261

5362
// If MPTCP is forced via GODEBUG=multipathtcp=1
54-
if multipathtcp.Value() == "1" {
63+
if multipathtcp.Value() == "1" || multipathtcp.Value() == "3" {
5564
multipathtcp.IncNonDefault()
5665

5766
return true
5867
}
5968

60-
return defaultMPTCPEnabled
69+
return defaultMPTCPEnabledDial
70+
}
71+
72+
func (m *mptcpStatusDial) set(use bool) {
73+
if use {
74+
*m = mptcpEnabledDial
75+
} else {
76+
*m = mptcpDisabledDial
77+
}
78+
}
79+
80+
// mptcpStatusListen is a tristate for Multipath TCP on servers,
81+
// see go.dev/issue/56539
82+
type mptcpStatusListen uint8
83+
84+
const (
85+
// The value 0 is the system default, linked to defaultMPTCPEnabledListen
86+
mptcpUseDefaultListen mptcpStatusListen = iota
87+
mptcpEnabledListen
88+
mptcpDisabledListen
89+
)
90+
91+
func (m *mptcpStatusListen) get() bool {
92+
switch *m {
93+
case mptcpEnabledListen:
94+
return true
95+
case mptcpDisabledListen:
96+
return false
97+
}
98+
99+
// If MPTCP is disabled via GODEBUG=multipathtcp=0 or only
100+
// enabled on dialers, but not on listeners.
101+
if multipathtcp.Value() == "0" || multipathtcp.Value() == "3" {
102+
multipathtcp.IncNonDefault()
103+
104+
return false
105+
}
106+
107+
return defaultMPTCPEnabledListen
61108
}
62109

63-
func (m *mptcpStatus) set(use bool) {
110+
func (m *mptcpStatusListen) set(use bool) {
64111
if use {
65-
*m = mptcpEnabled
112+
*m = mptcpEnabledListen
66113
} else {
67-
*m = mptcpDisabled
114+
*m = mptcpDisabledListen
68115
}
69116
}
70117

@@ -175,7 +222,7 @@ type Dialer struct {
175222
// If mptcpStatus is set to a value allowing Multipath TCP (MPTCP) to be
176223
// used, any call to Dial with "tcp(4|6)" as network will use MPTCP if
177224
// supported by the operating system.
178-
mptcpStatus mptcpStatus
225+
mptcpStatus mptcpStatusDial
179226
}
180227

181228
func (d *Dialer) dualStack() bool { return d.FallbackDelay >= 0 }
@@ -720,7 +767,7 @@ type ListenConfig struct {
720767
// If mptcpStatus is set to a value allowing Multipath TCP (MPTCP) to be
721768
// used, any call to Listen with "tcp(4|6)" as network will use MPTCP if
722769
// supported by the operating system.
723-
mptcpStatus mptcpStatus
770+
mptcpStatus mptcpStatusListen
724771
}
725772

726773
// MultipathTCP reports whether MPTCP will be used.

0 commit comments

Comments
 (0)