Merge branch 'dev' of https://github.com/Dreamacro/clash into Alpha
This commit is contained in:
commit
7a64c432b1
2 changed files with 28 additions and 27 deletions
|
@ -28,6 +28,11 @@ const (
|
|||
)
|
||||
|
||||
func putMsgToCache(c *cache.LruCache[string, *D.Msg], key string, msg *D.Msg) {
|
||||
// skip dns cache for acme challenge
|
||||
if q := msg.Question[0]; q.Qtype == D.TypeTXT && strings.HasPrefix(q.Name, "_acme-challenge") {
|
||||
log.Debugln("[DNS] dns cache ignored because of acme challenge for: %s", q.Name)
|
||||
return
|
||||
}
|
||||
var ttl uint32
|
||||
switch {
|
||||
case len(msg.Answer) != 0:
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
package redir
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"net"
|
||||
"net/netip"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/Dreamacro/clash/transport/socks5"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -25,44 +29,36 @@ func parserPacket(conn net.Conn) (socks5.Addr, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
var addr socks5.Addr
|
||||
var addr netip.AddrPort
|
||||
|
||||
rc.Control(func(fd uintptr) {
|
||||
if ip4 := c.LocalAddr().(*net.TCPAddr).IP.To4(); ip4 != nil {
|
||||
addr, err = getorigdst(fd)
|
||||
if err != nil {
|
||||
} else {
|
||||
addr, err = getorigdst6(fd)
|
||||
}
|
||||
})
|
||||
|
||||
return addr, err
|
||||
return socks5.AddrFromStdAddrPort(addr), err
|
||||
}
|
||||
|
||||
// Call getorigdst() from linux/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
|
||||
func getorigdst(fd uintptr) (socks5.Addr, error) {
|
||||
raw := syscall.RawSockaddrInet4{}
|
||||
siz := uint32(unsafe.Sizeof(raw))
|
||||
if err := socketcall(GETSOCKOPT, fd, syscall.IPPROTO_IP, SO_ORIGINAL_DST, uintptr(unsafe.Pointer(&raw)), uintptr(unsafe.Pointer(&siz)), 0); err != nil {
|
||||
return nil, err
|
||||
func getorigdst(fd uintptr) (netip.AddrPort, error) {
|
||||
addr := unix.RawSockaddrInet4{}
|
||||
size := uint32(unsafe.Sizeof(addr))
|
||||
if err := socketcall(GETSOCKOPT, fd, syscall.IPPROTO_IP, SO_ORIGINAL_DST, uintptr(unsafe.Pointer(&addr)), uintptr(unsafe.Pointer(&size)), 0); err != nil {
|
||||
return netip.AddrPort{}, err
|
||||
}
|
||||
port := binary.BigEndian.Uint16((*(*[2]byte)(unsafe.Pointer(&addr.Port)))[:])
|
||||
return netip.AddrPortFrom(netip.AddrFrom4(addr.Addr), port), nil
|
||||
}
|
||||
|
||||
addr := make([]byte, 1+net.IPv4len+2)
|
||||
addr[0] = socks5.AtypIPv4
|
||||
copy(addr[1:1+net.IPv4len], raw.Addr[:])
|
||||
port := (*[2]byte)(unsafe.Pointer(&raw.Port)) // big-endian
|
||||
addr[1+net.IPv4len], addr[1+net.IPv4len+1] = port[0], port[1]
|
||||
return addr, nil
|
||||
func getorigdst6(fd uintptr) (netip.AddrPort, error) {
|
||||
addr := unix.RawSockaddrInet6{}
|
||||
size := uint32(unsafe.Sizeof(addr))
|
||||
if err := socketcall(GETSOCKOPT, fd, syscall.IPPROTO_IPV6, IP6T_SO_ORIGINAL_DST, uintptr(unsafe.Pointer(&addr)), uintptr(unsafe.Pointer(&size)), 0); err != nil {
|
||||
return netip.AddrPort{}, err
|
||||
}
|
||||
|
||||
func getorigdst6(fd uintptr) (socks5.Addr, error) {
|
||||
raw := syscall.RawSockaddrInet6{}
|
||||
siz := uint32(unsafe.Sizeof(raw))
|
||||
if err := socketcall(GETSOCKOPT, fd, syscall.IPPROTO_IPV6, IP6T_SO_ORIGINAL_DST, uintptr(unsafe.Pointer(&raw)), uintptr(unsafe.Pointer(&siz)), 0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
addr := make([]byte, 1+net.IPv6len+2)
|
||||
addr[0] = socks5.AtypIPv6
|
||||
copy(addr[1:1+net.IPv6len], raw.Addr[:])
|
||||
port := (*[2]byte)(unsafe.Pointer(&raw.Port)) // big-endian
|
||||
addr[1+net.IPv6len], addr[1+net.IPv6len+1] = port[0], port[1]
|
||||
return addr, nil
|
||||
port := binary.BigEndian.Uint16((*(*[2]byte)(unsafe.Pointer(&addr.Port)))[:])
|
||||
return netip.AddrPortFrom(netip.AddrFrom16(addr.Addr), port), nil
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue