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,12 +40,13 @@ func handleUDPToLocal(packet C.UDPPacket, pc N.EnhancePacketConn, key string, oA
return return
} }
fromUDPAddr := from.(*net.UDPAddr) fromUDPAddr, isUDPAddr := from.(*net.UDPAddr)
if isUDPAddr {
_fromUDPAddr := *fromUDPAddr _fromUDPAddr := *fromUDPAddr
fromUDPAddr = &_fromUDPAddr // make a copy fromUDPAddr = &_fromUDPAddr // make a copy
if fromAddr, ok := netip.AddrFromSlice(fromUDPAddr.IP); ok { if fromAddr, ok := netip.AddrFromSlice(fromUDPAddr.IP); ok {
fromAddr = fromAddr.Unmap() fromAddr = fromAddr.Unmap()
if fAddr.IsValid() && (oAddr.Unmap() == fromAddr) { if fAddr.IsValid() && (oAddrPort.Addr() == fromAddr) { // oAddrPort was Unmapped
fromAddr = fAddr.Unmap() fromAddr = fAddr.Unmap()
} }
fromUDPAddr.IP = fromAddr.AsSlice() fromUDPAddr.IP = fromAddr.AsSlice()
@ -53,6 +54,10 @@ func handleUDPToLocal(packet C.UDPPacket, pc N.EnhancePacketConn, key string, oA
fromUDPAddr.Zone = "" // only ipv6 can have the zone 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)
if put != nil { if put != nil {

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