fix: udp panic when server return a domain name

This commit is contained in:
gVisor bot 2023-05-27 13:43:41 +08:00
parent 344533fd11
commit 50968b9667
3 changed files with 25 additions and 19 deletions

View file

@ -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 {

View file

@ -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)

View file

@ -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()
}() }()