mirror of
https://github.com/SagerNet/sing-tun.git
synced 2026-04-22 16:07: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
|
||||
vnetHdr bool
|
||||
writeBuffer []byte
|
||||
vnetHdrWriteBuf []byte
|
||||
gsoToWrite []int
|
||||
tcpGROTable *tcpGROTable
|
||||
udpGroAccess sync.Mutex
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
package tun
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/sagernet/gvisor/pkg/rawfile"
|
||||
"github.com/sagernet/gvisor/pkg/tcpip/link/fdbased"
|
||||
"github.com/sagernet/gvisor/pkg/tcpip/stack"
|
||||
@@ -18,6 +20,37 @@ var _ GVisorTun = (*NativeTun)(nil)
|
||||
|
||||
func (t *NativeTun) WritePacket(pkt *stack.PacketBuffer) (int, error) {
|
||||
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
|
||||
for _, packetSlice := range pkt.AsSlices() {
|
||||
dataLen += len(packetSlice)
|
||||
|
||||
Reference in New Issue
Block a user