Fix: set SO_REUSEADDR for UDP listeners on linux (#630)
This commit is contained in:
parent
3ccd7def86
commit
2750c7ead0
5 changed files with 48 additions and 1 deletions
19
common/sockopt/reuseaddr_linux.go
Normal file
19
common/sockopt/reuseaddr_linux.go
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
package sockopt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
func UDPReuseaddr(c *net.UDPConn) (err error) {
|
||||||
|
rc, err := c.SyscallConn()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
rc.Control(func(fd uintptr) {
|
||||||
|
err = syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1)
|
||||||
|
})
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
11
common/sockopt/reuseaddr_other.go
Normal file
11
common/sockopt/reuseaddr_other.go
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
// +build !linux
|
||||||
|
|
||||||
|
package sockopt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
func UDPReuseaddr(c *net.UDPConn) (err error) {
|
||||||
|
return
|
||||||
|
}
|
|
@ -3,6 +3,8 @@ package dns
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
|
"github.com/Dreamacro/clash/common/sockopt"
|
||||||
|
|
||||||
D "github.com/miekg/dns"
|
D "github.com/miekg/dns"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -58,6 +60,11 @@ func ReCreateServer(addr string, resolver *Resolver) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = sockopt.UDPReuseaddr(p)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
address = addr
|
address = addr
|
||||||
handler := newHandler(resolver)
|
handler := newHandler(resolver)
|
||||||
server = &Server{handler: handler}
|
server = &Server{handler: handler}
|
||||||
|
|
|
@ -31,7 +31,11 @@ func setsockopt(c *net.UDPConn, addr string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
rc.Control(func(fd uintptr) {
|
rc.Control(func(fd uintptr) {
|
||||||
err = syscall.SetsockoptInt(int(fd), syscall.SOL_IP, syscall.IP_TRANSPARENT, 1)
|
err = syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
err = syscall.SetsockoptInt(int(fd), syscall.SOL_IP, syscall.IP_TRANSPARENT, 1)
|
||||||
|
}
|
||||||
if err == nil && isIPv6 {
|
if err == nil && isIPv6 {
|
||||||
err = syscall.SetsockoptInt(int(fd), syscall.SOL_IPV6, IPV6_TRANSPARENT, 1)
|
err = syscall.SetsockoptInt(int(fd), syscall.SOL_IPV6, IPV6_TRANSPARENT, 1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
|
|
||||||
adapters "github.com/Dreamacro/clash/adapters/inbound"
|
adapters "github.com/Dreamacro/clash/adapters/inbound"
|
||||||
"github.com/Dreamacro/clash/common/pool"
|
"github.com/Dreamacro/clash/common/pool"
|
||||||
|
"github.com/Dreamacro/clash/common/sockopt"
|
||||||
"github.com/Dreamacro/clash/component/socks5"
|
"github.com/Dreamacro/clash/component/socks5"
|
||||||
C "github.com/Dreamacro/clash/constant"
|
C "github.com/Dreamacro/clash/constant"
|
||||||
"github.com/Dreamacro/clash/tunnel"
|
"github.com/Dreamacro/clash/tunnel"
|
||||||
|
@ -22,6 +23,11 @@ func NewSocksUDPProxy(addr string) (*SockUDPListener, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = sockopt.UDPReuseaddr(l.(*net.UDPConn))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
sl := &SockUDPListener{l, addr, false}
|
sl := &SockUDPListener{l, addr, false}
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
|
|
Loading…
Reference in a new issue