fix: udp panic when server return a domain name
This commit is contained in:
parent
344533fd11
commit
50968b9667
3 changed files with 25 additions and 19 deletions
|
@ -205,15 +205,16 @@ func (m *Metadata) Pure() *Metadata {
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Metadata) AddrPort() netip.AddrPort {
|
||||||
|
port, _ := strconv.ParseUint(m.DstPort, 10, 16)
|
||||||
|
return netip.AddrPortFrom(m.DstIP.Unmap(), uint16(port))
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Metadata) UDPAddr() *net.UDPAddr {
|
func (m *Metadata) UDPAddr() *net.UDPAddr {
|
||||||
if m.NetWork != UDP || !m.DstIP.IsValid() {
|
if m.NetWork != UDP || !m.DstIP.IsValid() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
port, _ := strconv.ParseUint(m.DstPort, 10, 16)
|
return net.UDPAddrFromAddrPort(m.AddrPort())
|
||||||
return &net.UDPAddr{
|
|
||||||
IP: m.DstIP.AsSlice(),
|
|
||||||
Port: int(port),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Metadata) String() string {
|
func (m *Metadata) String() string {
|
||||||
|
|
|
@ -26,7 +26,7 @@ func handleUDPToRemote(packet C.UDPPacket, pc C.PacketConn, metadata *C.Metadata
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleUDPToLocal(packet C.UDPPacket, pc N.EnhancePacketConn, key string, oAddr, fAddr netip.Addr) {
|
func handleUDPToLocal(packet C.UDPPacket, pc N.EnhancePacketConn, key string, oAddrPort netip.AddrPort, fAddr netip.Addr) {
|
||||||
defer func() {
|
defer func() {
|
||||||
_ = pc.Close()
|
_ = pc.Close()
|
||||||
closeAllLocalCoon(key)
|
closeAllLocalCoon(key)
|
||||||
|
@ -40,18 +40,23 @@ func handleUDPToLocal(packet C.UDPPacket, pc N.EnhancePacketConn, key string, oA
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
fromUDPAddr := from.(*net.UDPAddr)
|
fromUDPAddr, isUDPAddr := from.(*net.UDPAddr)
|
||||||
_fromUDPAddr := *fromUDPAddr
|
if isUDPAddr {
|
||||||
fromUDPAddr = &_fromUDPAddr // make a copy
|
_fromUDPAddr := *fromUDPAddr
|
||||||
if fromAddr, ok := netip.AddrFromSlice(fromUDPAddr.IP); ok {
|
fromUDPAddr = &_fromUDPAddr // make a copy
|
||||||
fromAddr = fromAddr.Unmap()
|
if fromAddr, ok := netip.AddrFromSlice(fromUDPAddr.IP); ok {
|
||||||
if fAddr.IsValid() && (oAddr.Unmap() == fromAddr) {
|
fromAddr = fromAddr.Unmap()
|
||||||
fromAddr = fAddr.Unmap()
|
if fAddr.IsValid() && (oAddrPort.Addr() == fromAddr) { // oAddrPort was Unmapped
|
||||||
}
|
fromAddr = fAddr.Unmap()
|
||||||
fromUDPAddr.IP = fromAddr.AsSlice()
|
}
|
||||||
if fromAddr.Is4() {
|
fromUDPAddr.IP = fromAddr.AsSlice()
|
||||||
fromUDPAddr.Zone = "" // only ipv6 can have the zone
|
if fromAddr.Is4() {
|
||||||
|
fromUDPAddr.Zone = "" // only ipv6 can have the zone
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
fromUDPAddr = net.UDPAddrFromAddrPort(oAddrPort) // oAddrPort was Unmapped
|
||||||
|
log.Warnln("server return a [%T](%s) which isn't a *net.UDPAddr, force replace to (%s), this may be caused by a wrongly implemented server", from, from, oAddrPort)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = packet.WriteBack(data, fromUDPAddr)
|
_, err = packet.WriteBack(data, fromUDPAddr)
|
||||||
|
|
|
@ -383,10 +383,10 @@ func handleUDPConn(packet C.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())
|
||||||
}
|
}
|
||||||
|
|
||||||
oAddr := metadata.DstIP
|
oAddrPort := metadata.AddrPort()
|
||||||
natTable.Set(key, pc)
|
natTable.Set(key, pc)
|
||||||
|
|
||||||
go handleUDPToLocal(packet, pc, key, oAddr, fAddr)
|
go handleUDPToLocal(packet, pc, key, oAddrPort, fAddr)
|
||||||
|
|
||||||
handle()
|
handle()
|
||||||
}()
|
}()
|
||||||
|
|
Loading…
Reference in a new issue