Skip to content

Commit 4e86892

Browse files
committed
6️⃣ conn: drop getsockopt(IPPROTO_IPV6, IPV6_V6ONLY)
A user reports that TCP servers won't create MPTCP sockets when the option is enabled: #59 Turns out in addition to TCP keepalive socket options (multipath-tcp/mptcp_net-next#383), the MPTCP folks also forgot to implement getsockopt(2) for IPv6 socket options (multipath-tcp/mptcp_net-next#550). Our getsockopt(2) call fails with -EOPNOTSUPP and causes Go to silently fall back to standard TCP. A closer look at this reveals that the result of our getsockopt(2) call is only ever used on Windows to guide the setting of IP_MTU_DISCOVER and IP_PKTINFO socket options, and is unlikely to be useful elsewhere. All this seems like overkill. An extra bit of error handling should be enough to solve the original problem. This commit does exactly that, and adds tests to prevent regressions. This partially reverts commit 48be0ff.
1 parent acd4756 commit 4e86892

12 files changed

+56
-61
lines changed

conn/conn.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,6 @@ type SocketInfo struct {
1919

2020
// UDPGenericReceiveOffload indicates whether UDP GRO is enabled on the socket.
2121
UDPGenericReceiveOffload bool
22-
23-
// IPv6Only reports whether the socket is IPv6-only.
24-
IPv6Only bool
2522
}
2623

2724
type setFunc = func(fd int, network string, info *SocketInfo) error
Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,6 @@
22

33
package conn
44

5-
func (fns setFuncSlice) appendGetIPv6Only() setFuncSlice {
6-
return append(fns, getIPv6Only)
7-
}
8-
95
func (fns setFuncSlice) appendSetSendBufferSize(size int) setFuncSlice {
106
if size > 0 {
117
return append(fns, func(fd int, _ string, _ *SocketInfo) error {

conn/conn_bufsize_reuseport_tclass_v6only.go renamed to conn/conn_bufsize_reuseport_tclass.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ package conn
44

55
func (lso ListenerSocketOptions) buildSetFns() setFuncSlice {
66
return setFuncSlice{}.
7-
appendGetIPv6Only().
87
appendSetSendBufferSize(lso.SendBufferSize).
98
appendSetRecvBufferSize(lso.ReceiveBufferSize).
109
appendSetTrafficClassFunc(lso.TrafficClass).

conn/conn_darwin.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import (
66
"golang.org/x/sys/unix"
77
)
88

9-
func setRecvPktinfo(fd int, network string, _ *SocketInfo) error {
9+
func setRecvPktinfo(fd int, network string) error {
1010
switch network {
1111
case "udp4":
1212
if err := unix.SetsockoptInt(fd, unix.IPPROTO_IP, unix.IP_RECVPKTINFO, 1); err != nil {
@@ -24,7 +24,6 @@ func setRecvPktinfo(fd int, network string, _ *SocketInfo) error {
2424

2525
func (lso ListenerSocketOptions) buildSetFns() setFuncSlice {
2626
return setFuncSlice{}.
27-
appendGetIPv6Only().
2827
appendSetSendBufferSize(lso.SendBufferSize).
2928
appendSetRecvBufferSize(lso.ReceiveBufferSize).
3029
appendSetTrafficClassFunc(lso.TrafficClass).

conn/conn_darwinfreebsd.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88
"golang.org/x/sys/unix"
99
)
1010

11-
func setPMTUD(fd int, network string, _ *SocketInfo) error {
11+
func setPMTUD(fd int, network string) error {
1212
switch network {
1313
case "udp4":
1414
if err := unix.SetsockoptInt(int(fd), unix.IPPROTO_IP, unix.IP_DONTFRAG, 1); err != nil {

conn/conn_darwinlinuxwindows.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ package conn
44

55
func (fns setFuncSlice) appendSetRecvPktinfoFunc(recvPktinfo bool) setFuncSlice {
66
if recvPktinfo {
7-
return append(fns, setRecvPktinfo)
7+
return append(fns, func(fd int, network string, _ *SocketInfo) error {
8+
return setRecvPktinfo(fd, network)
9+
})
810
}
911
return fns
1012
}

conn/conn_freebsd.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ func setFwmark(fd, fwmark int) error {
1515

1616
func (lso ListenerSocketOptions) buildSetFns() setFuncSlice {
1717
return setFuncSlice{}.
18-
appendGetIPv6Only().
1918
appendSetSendBufferSize(lso.SendBufferSize).
2019
appendSetRecvBufferSize(lso.ReceiveBufferSize).
2120
appendSetFwmarkFunc(lso.Fwmark).

conn/conn_linux.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ func setTransparent(fd int, network string) error {
9898
return nil
9999
}
100100

101-
func setPMTUD(fd int, network string, _ *SocketInfo) error {
101+
func setPMTUD(fd int, network string) error {
102102
// Set IP_MTU_DISCOVER for both v4 and v6.
103103
if err := unix.SetsockoptInt(fd, unix.IPPROTO_IP, unix.IP_MTU_DISCOVER, unix.IP_PMTUDISC_DO); err != nil {
104104
return fmt.Errorf("failed to set socket option IP_MTU_DISCOVER: %w", err)
@@ -117,7 +117,7 @@ func setPMTUD(fd int, network string, _ *SocketInfo) error {
117117
return nil
118118
}
119119

120-
func setRecvPktinfo(fd int, network string, _ *SocketInfo) error {
120+
func setRecvPktinfo(fd int, network string) error {
121121
switch network {
122122
case "udp4":
123123
if err := unix.SetsockoptInt(fd, unix.IPPROTO_IP, unix.IP_PKTINFO, 1); err != nil {
@@ -190,7 +190,6 @@ func (fns setFuncSlice) appendSetRecvOrigDstAddrFunc(recvOrigDstAddr bool) setFu
190190

191191
func (lso ListenerSocketOptions) buildSetFns() setFuncSlice {
192192
return setFuncSlice{}.
193-
appendGetIPv6Only().
194193
appendSetSendBufferSize(lso.SendBufferSize).
195194
appendSetRecvBufferSize(lso.ReceiveBufferSize).
196195
appendSetFwmarkFunc(lso.Fwmark).

conn/conn_pmtud.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ package conn
44

55
func (fns setFuncSlice) appendSetPMTUDFunc(pmtud bool) setFuncSlice {
66
if pmtud {
7-
return append(fns, setPMTUD)
7+
return append(fns, func(fd int, network string, _ *SocketInfo) error {
8+
return setPMTUD(fd, network)
9+
})
810
}
911
return fns
1012
}

conn/conn_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package conn
2+
3+
import "testing"
4+
5+
func TestListenUDP(t *testing.T) {
6+
for _, lcc := range []struct {
7+
name string
8+
lc ListenConfig
9+
}{
10+
{"DefaultUDPServerListenConfig", DefaultUDPServerListenConfig},
11+
{"DefaultUDPClientListenConfig", DefaultUDPClientListenConfig},
12+
} {
13+
t.Run(lcc.name, func(t *testing.T) {
14+
for _, nac := range []struct {
15+
name string
16+
network string
17+
address string
18+
}{
19+
{"udp+zero", "udp", ""},
20+
{"udp+loopback4", "udp4", "127.0.0.1:"},
21+
{"udp+loopback6", "udp6", "[::1]:"},
22+
{"udp4+zero", "udp4", ""},
23+
{"udp4+loopback4", "udp4", "127.0.0.1:"},
24+
{"udp6+zero", "udp6", ""},
25+
{"udp6+loopback6", "udp6", "[::1]:"},
26+
} {
27+
t.Run(nac.name, func(t *testing.T) {
28+
uc, _, err := lcc.lc.ListenUDP(t.Context(), nac.network, nac.address)
29+
if err != nil {
30+
t.Fatal(err)
31+
}
32+
_ = uc.Close()
33+
})
34+
}
35+
})
36+
}
37+
}

0 commit comments

Comments
 (0)