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
|
package inbound
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/Dreamacro/clash/common/nnip"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/Dreamacro/clash/common/nnip"
|
|
||||||
C "github.com/Dreamacro/clash/constant"
|
C "github.com/Dreamacro/clash/constant"
|
||||||
"github.com/Dreamacro/clash/transport/socks5"
|
"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.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]))
|
metadata.DstPort = strconv.Itoa((int(target[1+net.IPv4len]) << 8) | int(target[1+net.IPv4len+1]))
|
||||||
case socks5.AtypIPv6:
|
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]))
|
metadata.DstPort = strconv.Itoa((int(target[1+net.IPv6len]) << 8) | int(target[1+net.IPv6len+1]))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,26 +3,17 @@ package tunnel
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"net"
|
"net"
|
||||||
|
"net/netip"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
N "github.com/Dreamacro/clash/common/net"
|
N "github.com/Dreamacro/clash/common/net"
|
||||||
"github.com/Dreamacro/clash/common/pool"
|
"github.com/Dreamacro/clash/common/pool"
|
||||||
"github.com/Dreamacro/clash/component/resolver"
|
|
||||||
C "github.com/Dreamacro/clash/constant"
|
C "github.com/Dreamacro/clash/constant"
|
||||||
)
|
)
|
||||||
|
|
||||||
func handleUDPToRemote(packet C.UDPPacket, pc C.PacketConn, metadata *C.Metadata) error {
|
func handleUDPToRemote(packet C.UDPPacket, pc C.PacketConn, metadata *C.Metadata) error {
|
||||||
defer packet.Drop()
|
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()
|
addr := metadata.UDPAddr()
|
||||||
if addr == nil {
|
if addr == nil {
|
||||||
return errors.New("udp addr invalid")
|
return errors.New("udp addr invalid")
|
||||||
|
@ -32,29 +23,36 @@ func handleUDPToRemote(packet C.UDPPacket, pc C.PacketConn, metadata *C.Metadata
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// reset timeout
|
// reset timeout
|
||||||
pc.SetReadDeadline(time.Now().Add(udpTimeout))
|
_ = pc.SetReadDeadline(time.Now().Add(udpTimeout))
|
||||||
|
|
||||||
return nil
|
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)
|
buf := pool.Get(pool.UDPBufferSize)
|
||||||
defer pool.Put(buf)
|
defer func() {
|
||||||
defer natTable.Delete(key)
|
_ = pc.Close()
|
||||||
defer pc.Close()
|
natTable.Delete(key)
|
||||||
|
_ = pool.Put(buf)
|
||||||
|
}()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
pc.SetReadDeadline(time.Now().Add(udpTimeout))
|
_ = pc.SetReadDeadline(time.Now().Add(udpTimeout))
|
||||||
n, from, err := pc.ReadFrom(buf)
|
n, from, err := pc.ReadFrom(buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if fAddr != nil {
|
fromUDPAddr := from.(*net.UDPAddr)
|
||||||
from = fAddr
|
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 {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -209,9 +209,9 @@ func handleUDPConn(packet *inbound.PacketAdapter) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// make a fAddr if request ip is fakeip
|
// make a fAddr if request ip is fakeip
|
||||||
var fAddr net.Addr
|
var fAddr netip.Addr
|
||||||
if resolver.IsExistFakeIP(metadata.DstIP) {
|
if resolver.IsExistFakeIP(metadata.DstIP) {
|
||||||
fAddr = metadata.UDPAddr()
|
fAddr = metadata.DstIP
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := preHandleMetadata(metadata); err != nil {
|
if err := preHandleMetadata(metadata); err != nil {
|
||||||
|
@ -219,6 +219,15 @@ func handleUDPConn(packet *inbound.PacketAdapter) {
|
||||||
return
|
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()
|
key := packet.LocalAddr().String()
|
||||||
|
|
||||||
handle := func() bool {
|
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())
|
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)
|
natTable.Set(key, pc)
|
||||||
handle()
|
handle()
|
||||||
|
|
Loading…
Reference in a new issue