Fix: fakeip udp should not replace with another ip
This commit is contained in:
parent
156a6e2e41
commit
e5f7d9b934
3 changed files with 33 additions and 24 deletions
|
@ -1,13 +1,13 @@
|
|||
package inbound
|
||||
|
||||
import (
|
||||
"github.com/Dreamacro/clash/common/nnip"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/Dreamacro/clash/common/nnip"
|
||||
C "github.com/Dreamacro/clash/constant"
|
||||
"github.com/Dreamacro/clash/transport/socks5"
|
||||
)
|
||||
|
@ -26,7 +26,8 @@ func parseSocksAddr(target socks5.Addr) *C.Metadata {
|
|||
metadata.DstIP = nnip.IpToAddr(net.IP(target[1 : 1+net.IPv4len]))
|
||||
metadata.DstPort = strconv.Itoa((int(target[1+net.IPv4len]) << 8) | int(target[1+net.IPv4len+1]))
|
||||
case socks5.AtypIPv6:
|
||||
metadata.DstIP = nnip.IpToAddr(net.IP(target[1 : 1+net.IPv6len]))
|
||||
ip6, _ := netip.AddrFromSlice(target[1 : 1+net.IPv6len])
|
||||
metadata.DstIP = ip6.Unmap()
|
||||
metadata.DstPort = strconv.Itoa((int(target[1+net.IPv6len]) << 8) | int(target[1+net.IPv6len+1]))
|
||||
}
|
||||
|
||||
|
|
|
@ -3,26 +3,17 @@ package tunnel
|
|||
import (
|
||||
"errors"
|
||||
"net"
|
||||
"net/netip"
|
||||
"time"
|
||||
|
||||
N "github.com/Dreamacro/clash/common/net"
|
||||
"github.com/Dreamacro/clash/common/pool"
|
||||
"github.com/Dreamacro/clash/component/resolver"
|
||||
C "github.com/Dreamacro/clash/constant"
|
||||
)
|
||||
|
||||
func handleUDPToRemote(packet C.UDPPacket, pc C.PacketConn, metadata *C.Metadata) error {
|
||||
defer packet.Drop()
|
||||
|
||||
// local resolve UDP dns
|
||||
if !metadata.Resolved() {
|
||||
ip, err := resolver.ResolveIP(metadata.Host)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
metadata.DstIP = ip
|
||||
}
|
||||
|
||||
addr := metadata.UDPAddr()
|
||||
if addr == nil {
|
||||
return errors.New("udp addr invalid")
|
||||
|
@ -32,29 +23,36 @@ func handleUDPToRemote(packet C.UDPPacket, pc C.PacketConn, metadata *C.Metadata
|
|||
return err
|
||||
}
|
||||
// reset timeout
|
||||
pc.SetReadDeadline(time.Now().Add(udpTimeout))
|
||||
_ = pc.SetReadDeadline(time.Now().Add(udpTimeout))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleUDPToLocal(packet C.UDPPacket, pc net.PacketConn, key string, fAddr net.Addr) {
|
||||
func handleUDPToLocal(packet C.UDPPacket, pc net.PacketConn, key string, oAddr, fAddr netip.Addr) {
|
||||
buf := pool.Get(pool.UDPBufferSize)
|
||||
defer pool.Put(buf)
|
||||
defer natTable.Delete(key)
|
||||
defer pc.Close()
|
||||
defer func() {
|
||||
_ = pc.Close()
|
||||
natTable.Delete(key)
|
||||
_ = pool.Put(buf)
|
||||
}()
|
||||
|
||||
for {
|
||||
pc.SetReadDeadline(time.Now().Add(udpTimeout))
|
||||
_ = pc.SetReadDeadline(time.Now().Add(udpTimeout))
|
||||
n, from, err := pc.ReadFrom(buf)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if fAddr != nil {
|
||||
from = fAddr
|
||||
fromUDPAddr := from.(*net.UDPAddr)
|
||||
if fAddr.IsValid() {
|
||||
fromAddr, _ := netip.AddrFromSlice(fromUDPAddr.IP)
|
||||
fromAddr.Unmap()
|
||||
if oAddr == fromAddr {
|
||||
fromUDPAddr.IP = fAddr.AsSlice()
|
||||
}
|
||||
}
|
||||
|
||||
_, err = packet.WriteBack(buf[:n], from)
|
||||
_, err = packet.WriteBack(buf[:n], fromUDPAddr)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -209,9 +209,9 @@ func handleUDPConn(packet *inbound.PacketAdapter) {
|
|||
}
|
||||
|
||||
// make a fAddr if request ip is fakeip
|
||||
var fAddr net.Addr
|
||||
var fAddr netip.Addr
|
||||
if resolver.IsExistFakeIP(metadata.DstIP) {
|
||||
fAddr = metadata.UDPAddr()
|
||||
fAddr = metadata.DstIP
|
||||
}
|
||||
|
||||
if err := preHandleMetadata(metadata); err != nil {
|
||||
|
@ -219,6 +219,15 @@ func handleUDPConn(packet *inbound.PacketAdapter) {
|
|||
return
|
||||
}
|
||||
|
||||
// local resolve UDP dns
|
||||
if !metadata.Resolved() {
|
||||
ip, err := resolver.ResolveIP(metadata.Host)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
metadata.DstIP = ip
|
||||
}
|
||||
|
||||
key := packet.LocalAddr().String()
|
||||
|
||||
handle := func() bool {
|
||||
|
@ -288,7 +297,8 @@ func handleUDPConn(packet *inbound.PacketAdapter) {
|
|||
log.Infoln("[UDP] %s --> %s doesn't match any rule using DIRECT", metadata.SourceDetail(), metadata.RemoteAddress())
|
||||
}
|
||||
|
||||
go handleUDPToLocal(packet.UDPPacket, pc, key, fAddr)
|
||||
oAddr := metadata.DstIP
|
||||
go handleUDPToLocal(packet.UDPPacket, pc, key, oAddr, fAddr)
|
||||
|
||||
natTable.Set(key, pc)
|
||||
handle()
|
||||
|
|
Loading…
Reference in a new issue