mirror of
https://github.com/golang/go
synced 2024-11-25 00:28:00 -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
|
||||
}
|
||||
switch v := a.(type) {
|
||||
case *TCPAddr, *UnixAddr:
|
||||
err := setDefaultListenerSockopts(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case *UDPAddr:
|
||||
if v.IP.IsMulticast() {
|
||||
err := setDefaultMulticastSockopts(s)
|
||||
|
@ -32,6 +32,11 @@ func listenerSockaddr(s, f int, la syscall.Sockaddr, toAddr func(syscall.Sockadd
|
||||
return la, nil
|
||||
}
|
||||
switch v := a.(type) {
|
||||
case *TCPAddr, *UnixAddr:
|
||||
err := setDefaultListenerSockopts(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case *UDPAddr:
|
||||
if v.IP.IsMulticast() {
|
||||
err := setDefaultMulticastSockopts(s)
|
||||
|
@ -19,6 +19,11 @@ func listenerSockaddr(s syscall.Handle, f int, la syscall.Sockaddr, toAddr func(
|
||||
return la, nil
|
||||
}
|
||||
switch v := a.(type) {
|
||||
case *TCPAddr, *UnixAddr:
|
||||
err := setDefaultListenerSockopts(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case *UDPAddr:
|
||||
if v.IP.IsMulticast() {
|
||||
err := setDefaultMulticastSockopts(s)
|
||||
|
@ -20,31 +20,28 @@ func setDefaultSockopts(s, f, t int) error {
|
||||
// Note that some operating systems never admit this option.
|
||||
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.
|
||||
err := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1)
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -18,23 +18,20 @@ func setDefaultSockopts(s, f, t int) error {
|
||||
// Note that some operating systems never admit this option.
|
||||
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.
|
||||
err := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1)
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -18,16 +18,18 @@ func setDefaultSockopts(s syscall.Handle, f, t int) error {
|
||||
// Note that some operating systems never admit this option.
|
||||
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.
|
||||
// SO_REUSEADDR should not be used here, as it allows
|
||||
// a socket to forcibly bind to a port in use by another socket.
|
||||
// This could lead to a non-deterministic behavior, where
|
||||
// connection requests over the port cannot be guaranteed
|
||||
// to be handled by the correct socket.
|
||||
|
||||
// Allow broadcast.
|
||||
syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user