mirror of
https://github.com/SagerNet/sing-tun.git
synced 2026-04-23 00:17:19 +08:00
Fix udp/icmp not work on gso with mixed stack
This commit is contained in:
@@ -39,6 +39,7 @@ type NativeTun struct {
|
|||||||
writeAccess sync.Mutex
|
writeAccess sync.Mutex
|
||||||
vnetHdr bool
|
vnetHdr bool
|
||||||
writeBuffer []byte
|
writeBuffer []byte
|
||||||
|
vnetHdrWriteBuf []byte
|
||||||
gsoToWrite []int
|
gsoToWrite []int
|
||||||
tcpGROTable *tcpGROTable
|
tcpGROTable *tcpGROTable
|
||||||
udpGroAccess sync.Mutex
|
udpGroAccess sync.Mutex
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
package tun
|
package tun
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/sagernet/gvisor/pkg/rawfile"
|
"github.com/sagernet/gvisor/pkg/rawfile"
|
||||||
"github.com/sagernet/gvisor/pkg/tcpip/link/fdbased"
|
"github.com/sagernet/gvisor/pkg/tcpip/link/fdbased"
|
||||||
"github.com/sagernet/gvisor/pkg/tcpip/stack"
|
"github.com/sagernet/gvisor/pkg/tcpip/stack"
|
||||||
@@ -18,6 +20,37 @@ var _ GVisorTun = (*NativeTun)(nil)
|
|||||||
|
|
||||||
func (t *NativeTun) WritePacket(pkt *stack.PacketBuffer) (int, error) {
|
func (t *NativeTun) WritePacket(pkt *stack.PacketBuffer) (int, error) {
|
||||||
iovecs := t.iovecsOutputDefault
|
iovecs := t.iovecsOutputDefault
|
||||||
|
if t.vnetHdr {
|
||||||
|
if t.vnetHdrWriteBuf == nil {
|
||||||
|
t.vnetHdrWriteBuf = make([]byte, virtioNetHdrLen)
|
||||||
|
}
|
||||||
|
vnetHdr := virtioNetHdr{}
|
||||||
|
if pkt.GSOOptions.Type != stack.GSONone {
|
||||||
|
vnetHdr.hdrLen = uint16(pkt.HeaderSize())
|
||||||
|
if pkt.GSOOptions.NeedsCsum {
|
||||||
|
vnetHdr.flags = unix.VIRTIO_NET_HDR_F_NEEDS_CSUM
|
||||||
|
vnetHdr.csumStart = pkt.GSOOptions.L3HdrLen
|
||||||
|
vnetHdr.csumOffset = pkt.GSOOptions.CsumOffset
|
||||||
|
}
|
||||||
|
if uint16(pkt.Data().Size()) > pkt.GSOOptions.MSS {
|
||||||
|
switch pkt.GSOOptions.Type {
|
||||||
|
case stack.GSOTCPv4:
|
||||||
|
vnetHdr.gsoType = unix.VIRTIO_NET_HDR_GSO_TCPV4
|
||||||
|
case stack.GSOTCPv6:
|
||||||
|
vnetHdr.gsoType = unix.VIRTIO_NET_HDR_GSO_TCPV6
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("Unknown gso type: %v", pkt.GSOOptions.Type))
|
||||||
|
}
|
||||||
|
vnetHdr.gsoSize = pkt.GSOOptions.MSS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := vnetHdr.encode(t.vnetHdrWriteBuf); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
iovec := unix.Iovec{Base: &t.vnetHdrWriteBuf[0]}
|
||||||
|
iovec.SetLen(virtioNetHdrLen)
|
||||||
|
iovecs = append(iovecs, iovec)
|
||||||
|
}
|
||||||
var dataLen int
|
var dataLen int
|
||||||
for _, packetSlice := range pkt.AsSlices() {
|
for _, packetSlice := range pkt.AsSlices() {
|
||||||
dataLen += len(packetSlice)
|
dataLen += len(packetSlice)
|
||||||
|
|||||||
Reference in New Issue
Block a user