mirror of
https://github.com/golang/go
synced 2024-11-25 02:27:56 -07:00
net: enable SO_REUSEADDR, SO_REUSEPORT options on stream, multicast listeners only
This CL changes default SOL_SOCKET settings to mitigate connect failure on OpenBSD or similar platforms which support randomized transport protocol port number assignment. Fixes #2830. R=rsc, jsing CC=golang-dev https://golang.org/cl/5648044
This commit is contained in:
parent
21a3aceb4a
commit
0e3514eaac
@ -38,6 +38,11 @@ func listenerSockaddr(s, f int, la syscall.Sockaddr, toAddr func(syscall.Sockadd
|
|||||||
return la, nil
|
return la, nil
|
||||||
}
|
}
|
||||||
switch v := a.(type) {
|
switch v := a.(type) {
|
||||||
|
case *TCPAddr, *UnixAddr:
|
||||||
|
err := setDefaultListenerSockopts(s)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
case *UDPAddr:
|
case *UDPAddr:
|
||||||
if v.IP.IsMulticast() {
|
if v.IP.IsMulticast() {
|
||||||
err := setDefaultMulticastSockopts(s)
|
err := setDefaultMulticastSockopts(s)
|
||||||
|
@ -32,6 +32,11 @@ func listenerSockaddr(s, f int, la syscall.Sockaddr, toAddr func(syscall.Sockadd
|
|||||||
return la, nil
|
return la, nil
|
||||||
}
|
}
|
||||||
switch v := a.(type) {
|
switch v := a.(type) {
|
||||||
|
case *TCPAddr, *UnixAddr:
|
||||||
|
err := setDefaultListenerSockopts(s)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
case *UDPAddr:
|
case *UDPAddr:
|
||||||
if v.IP.IsMulticast() {
|
if v.IP.IsMulticast() {
|
||||||
err := setDefaultMulticastSockopts(s)
|
err := setDefaultMulticastSockopts(s)
|
||||||
|
@ -19,6 +19,11 @@ func listenerSockaddr(s syscall.Handle, f int, la syscall.Sockaddr, toAddr func(
|
|||||||
return la, nil
|
return la, nil
|
||||||
}
|
}
|
||||||
switch v := a.(type) {
|
switch v := a.(type) {
|
||||||
|
case *TCPAddr, *UnixAddr:
|
||||||
|
err := setDefaultListenerSockopts(s)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
case *UDPAddr:
|
case *UDPAddr:
|
||||||
if v.IP.IsMulticast() {
|
if v.IP.IsMulticast() {
|
||||||
err := setDefaultMulticastSockopts(s)
|
err := setDefaultMulticastSockopts(s)
|
||||||
|
@ -20,31 +20,28 @@ func setDefaultSockopts(s, f, t int) error {
|
|||||||
// Note that some operating systems never admit this option.
|
// Note that some operating systems never admit this option.
|
||||||
syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, 0)
|
syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
if f == syscall.AF_UNIX ||
|
|
||||||
(f == syscall.AF_INET || f == syscall.AF_INET6) && t == syscall.SOCK_STREAM {
|
|
||||||
// Allow reuse of recently-used addresses.
|
|
||||||
err := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1)
|
|
||||||
if err != nil {
|
|
||||||
return os.NewSyscallError("setsockopt", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allow reuse of recently-used ports.
|
|
||||||
// This option is supported only in descendants of 4.4BSD,
|
|
||||||
// to make an effective multicast application and an application
|
|
||||||
// that requires quick draw possible.
|
|
||||||
err = syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEPORT, 1)
|
|
||||||
if err != nil {
|
|
||||||
return os.NewSyscallError("setsockopt", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allow broadcast.
|
// Allow broadcast.
|
||||||
err := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1)
|
err := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return os.NewSyscallError("setsockopt", err)
|
return os.NewSyscallError("setsockopt", err)
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func setDefaultListenerSockopts(s int) error {
|
||||||
|
// Allow reuse of recently-used addresses.
|
||||||
|
err := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1)
|
||||||
|
if err != nil {
|
||||||
|
return os.NewSyscallError("setsockopt", err)
|
||||||
|
}
|
||||||
|
// Allow reuse of recently-used ports.
|
||||||
|
// This option is supported only in descendants of 4.4BSD,
|
||||||
|
// to make an effective multicast application and an application
|
||||||
|
// that requires quick draw possible.
|
||||||
|
err = syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEPORT, 1)
|
||||||
|
if err != nil {
|
||||||
|
return os.NewSyscallError("setsockopt", err)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,23 +18,20 @@ func setDefaultSockopts(s, f, t int) error {
|
|||||||
// Note that some operating systems never admit this option.
|
// Note that some operating systems never admit this option.
|
||||||
syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, 0)
|
syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
if f == syscall.AF_UNIX ||
|
|
||||||
(f == syscall.AF_INET || f == syscall.AF_INET6) && t == syscall.SOCK_STREAM {
|
|
||||||
// Allow reuse of recently-used addresses.
|
|
||||||
err := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1)
|
|
||||||
if err != nil {
|
|
||||||
return os.NewSyscallError("setsockopt", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allow broadcast.
|
// Allow broadcast.
|
||||||
err := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1)
|
err := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return os.NewSyscallError("setsockopt", err)
|
return os.NewSyscallError("setsockopt", err)
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func setDefaultListenerSockopts(s int) error {
|
||||||
|
// Allow reuse of recently-used addresses.
|
||||||
|
err := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1)
|
||||||
|
if err != nil {
|
||||||
|
return os.NewSyscallError("setsockopt", err)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,16 +18,18 @@ func setDefaultSockopts(s syscall.Handle, f, t int) error {
|
|||||||
// Note that some operating systems never admit this option.
|
// Note that some operating systems never admit this option.
|
||||||
syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, 0)
|
syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, 0)
|
||||||
}
|
}
|
||||||
|
// Allow broadcast.
|
||||||
|
syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func setDefaultListenerSockopts(s syscall.Handle, f, t int) error {
|
||||||
// Windows will reuse recently-used addresses by default.
|
// Windows will reuse recently-used addresses by default.
|
||||||
// SO_REUSEADDR should not be used here, as it allows
|
// SO_REUSEADDR should not be used here, as it allows
|
||||||
// a socket to forcibly bind to a port in use by another socket.
|
// a socket to forcibly bind to a port in use by another socket.
|
||||||
// This could lead to a non-deterministic behavior, where
|
// This could lead to a non-deterministic behavior, where
|
||||||
// connection requests over the port cannot be guaranteed
|
// connection requests over the port cannot be guaranteed
|
||||||
// to be handled by the correct socket.
|
// to be handled by the correct socket.
|
||||||
|
|
||||||
// Allow broadcast.
|
|
||||||
syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user