[Fixed] handle network protocol[0] panic (not pretty)

This commit is contained in:
gVisor bot 2022-03-13 18:34:49 +08:00
parent 4389f8918e
commit b76d0e2109
2 changed files with 24 additions and 5 deletions

View file

@ -85,7 +85,8 @@ func (e *dnsEndpoint) HandlePacket(id stack.TransportEndpointID, pkt *stack.Pack
var msg D.Msg var msg D.Msg
msg.Unpack(pkt.Data().AsRange().ToOwnedView()) msg.Unpack(pkt.Data().AsRange().ToOwnedView())
writer := dnsResponseWriter{s: e.stack, pkt: pkt, id: id} writer := dnsResponseWriter{s: e.stack, pkt: pkt, id: id}
log.Debugln("[DNS] hijack udp:%s:%d", id.LocalAddress.String(), id.LocalPort) log.Debugln("[DNS] hijack udp:%s:%d from %s:%d", id.LocalAddress.String(), id.LocalPort,
id.RemoteAddress.String(), id.RemotePort)
go e.server.ServeDNS(&writer, &msg) go e.server.ServeDNS(&writer, &msg)
} }
@ -139,9 +140,17 @@ func (w *dnsResponseWriter) Write(b []byte) (int, error) {
v := buffer.NewView(len(b)) v := buffer.NewView(len(b))
copy(v, b) copy(v, b)
data := v.ToVectorisedView() data := v.ToVectorisedView()
// w.id.LocalAddress is the source ip of DNS response // w.id.LocalAddress is the source ip of DNS response
r, _ := w.s.FindRoute(w.pkt.NICID, w.id.LocalAddress, w.id.RemoteAddress, w.pkt.NetworkProtocolNumber, false /* multicastLoop */) if !w.pkt.NetworkHeader().View().IsEmpty() &&
return writeUDP(r, data, w.id.LocalPort, w.id.RemotePort) (w.pkt.NetworkProtocolNumber == ipv4.ProtocolNumber ||
w.pkt.NetworkProtocolNumber == ipv6.ProtocolNumber) {
r, _ := w.s.FindRoute(w.pkt.NICID, w.id.LocalAddress, w.id.RemoteAddress, w.pkt.NetworkProtocolNumber, false /* multicastLoop */)
return writeUDP(r, data, w.id.LocalPort, w.id.RemotePort)
} else {
log.Debugln("the network protocl[%d] is not available", w.pkt.NetworkProtocolNumber)
return 0, fmt.Errorf("the network protocl[%d] is not available", w.pkt.NetworkProtocolNumber)
}
} }
func (w *dnsResponseWriter) Close() error { func (w *dnsResponseWriter) Close() error {

View file

@ -2,6 +2,9 @@ package gvisor
import ( import (
"fmt" "fmt"
"github.com/Dreamacro/clash/log"
"gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
"gvisor.dev/gvisor/pkg/tcpip/network/ipv6"
"net" "net"
"github.com/Dreamacro/clash/component/resolver" "github.com/Dreamacro/clash/component/resolver"
@ -40,8 +43,15 @@ func (c *fakeConn) WriteBack(b []byte, addr net.Addr) (n int, err error) {
localPort = uint16(udpaddr.Port) localPort = uint16(udpaddr.Port)
} }
r, _ := c.s.FindRoute(c.pkt.NICID, localAddress, c.id.RemoteAddress, c.pkt.NetworkProtocolNumber, false /* multicastLoop */) if !c.pkt.NetworkHeader().View().IsEmpty() &&
return writeUDP(r, data, localPort, c.id.RemotePort) (c.pkt.NetworkProtocolNumber == ipv4.ProtocolNumber ||
c.pkt.NetworkProtocolNumber == ipv6.ProtocolNumber) {
r, _ := c.s.FindRoute(c.pkt.NICID, localAddress, c.id.RemoteAddress, c.pkt.NetworkProtocolNumber, false /* multicastLoop */)
return writeUDP(r, data, localPort, c.id.RemotePort)
} else {
log.Debugln("the network protocl[%d] is not available", c.pkt.NetworkProtocolNumber)
return 0, fmt.Errorf("the network protocl[%d] is not available", c.pkt.NetworkProtocolNumber)
}
} }
func (c *fakeConn) LocalAddr() net.Addr { func (c *fakeConn) LocalAddr() net.Addr {