global: buff -> buf
This always struck me as kind of weird and non-standard. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
@@ -95,28 +95,28 @@ func newFlowKey(pkt []byte, srcAddr, dstAddr, tcphOffset int) flowKey {
|
||||
// lookupOrInsert looks up a flow for the provided packet and metadata,
|
||||
// returning the packets found for the flow, or inserting a new one if none
|
||||
// is found.
|
||||
func (t *tcpGROTable) lookupOrInsert(pkt []byte, srcAddrOffset, dstAddrOffset, tcphOffset, tcphLen, buffsIndex int) ([]tcpGROItem, bool) {
|
||||
func (t *tcpGROTable) lookupOrInsert(pkt []byte, srcAddrOffset, dstAddrOffset, tcphOffset, tcphLen, bufsIndex int) ([]tcpGROItem, bool) {
|
||||
key := newFlowKey(pkt, srcAddrOffset, dstAddrOffset, tcphOffset)
|
||||
items, ok := t.itemsByFlow[key]
|
||||
if ok {
|
||||
return items, ok
|
||||
}
|
||||
// TODO: insert() performs another map lookup. This could be rearranged to avoid.
|
||||
t.insert(pkt, srcAddrOffset, dstAddrOffset, tcphOffset, tcphLen, buffsIndex)
|
||||
t.insert(pkt, srcAddrOffset, dstAddrOffset, tcphOffset, tcphLen, bufsIndex)
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// insert an item in the table for the provided packet and packet metadata.
|
||||
func (t *tcpGROTable) insert(pkt []byte, srcAddrOffset, dstAddrOffset, tcphOffset, tcphLen, buffsIndex int) {
|
||||
func (t *tcpGROTable) insert(pkt []byte, srcAddrOffset, dstAddrOffset, tcphOffset, tcphLen, bufsIndex int) {
|
||||
key := newFlowKey(pkt, srcAddrOffset, dstAddrOffset, tcphOffset)
|
||||
item := tcpGROItem{
|
||||
key: key,
|
||||
buffsIndex: uint16(buffsIndex),
|
||||
gsoSize: uint16(len(pkt[tcphOffset+tcphLen:])),
|
||||
iphLen: uint8(tcphOffset),
|
||||
tcphLen: uint8(tcphLen),
|
||||
sentSeq: binary.BigEndian.Uint32(pkt[tcphOffset+4:]),
|
||||
pshSet: pkt[tcphOffset+tcpFlagsOffset]&tcpFlagPSH != 0,
|
||||
key: key,
|
||||
bufsIndex: uint16(bufsIndex),
|
||||
gsoSize: uint16(len(pkt[tcphOffset+tcphLen:])),
|
||||
iphLen: uint8(tcphOffset),
|
||||
tcphLen: uint8(tcphLen),
|
||||
sentSeq: binary.BigEndian.Uint32(pkt[tcphOffset+4:]),
|
||||
pshSet: pkt[tcphOffset+tcpFlagsOffset]&tcpFlagPSH != 0,
|
||||
}
|
||||
items, ok := t.itemsByFlow[key]
|
||||
if !ok {
|
||||
@@ -140,14 +140,14 @@ func (t *tcpGROTable) deleteAt(key flowKey, i int) {
|
||||
// tcpGROItem represents bookkeeping data for a TCP packet during the lifetime
|
||||
// of a GRO evaluation across a vector of packets.
|
||||
type tcpGROItem struct {
|
||||
key flowKey
|
||||
sentSeq uint32 // the sequence number
|
||||
buffsIndex uint16 // the index into the original buffs slice
|
||||
numMerged uint16 // the number of packets merged into this item
|
||||
gsoSize uint16 // payload size
|
||||
iphLen uint8 // ip header len
|
||||
tcphLen uint8 // tcp header len
|
||||
pshSet bool // psh flag is set
|
||||
key flowKey
|
||||
sentSeq uint32 // the sequence number
|
||||
bufsIndex uint16 // the index into the original bufs slice
|
||||
numMerged uint16 // the number of packets merged into this item
|
||||
gsoSize uint16 // payload size
|
||||
iphLen uint8 // ip header len
|
||||
tcphLen uint8 // tcp header len
|
||||
pshSet bool // psh flag is set
|
||||
}
|
||||
|
||||
func (t *tcpGROTable) newItems() []tcpGROItem {
|
||||
@@ -177,8 +177,8 @@ const (
|
||||
// tcpPacketsCanCoalesce evaluates if pkt can be coalesced with the packet
|
||||
// described by item. This function makes considerations that match the kernel's
|
||||
// GRO self tests, which can be found in tools/testing/selftests/net/gro.c.
|
||||
func tcpPacketsCanCoalesce(pkt []byte, iphLen, tcphLen uint8, seq uint32, pshSet bool, gsoSize uint16, item tcpGROItem, buffs [][]byte, buffsOffset int) canCoalesce {
|
||||
pktTarget := buffs[item.buffsIndex][buffsOffset:]
|
||||
func tcpPacketsCanCoalesce(pkt []byte, iphLen, tcphLen uint8, seq uint32, pshSet bool, gsoSize uint16, item tcpGROItem, bufs [][]byte, bufsOffset int) canCoalesce {
|
||||
pktTarget := bufs[item.bufsIndex][bufsOffset:]
|
||||
if tcphLen != item.tcphLen {
|
||||
// cannot coalesce with unequal tcp options len
|
||||
return coalesceUnavailable
|
||||
@@ -262,18 +262,18 @@ const (
|
||||
)
|
||||
|
||||
// coalesceTCPPackets attempts to coalesce pkt with the packet described by
|
||||
// item, returning the outcome. This function may swap buffs elements in the
|
||||
// event of a prepend as item's buffs index is already being tracked for writing
|
||||
// item, returning the outcome. This function may swap bufs elements in the
|
||||
// event of a prepend as item's bufs index is already being tracked for writing
|
||||
// to a Device.
|
||||
func coalesceTCPPackets(mode canCoalesce, pkt []byte, pktBuffsIndex int, gsoSize uint16, seq uint32, pshSet bool, item *tcpGROItem, buffs [][]byte, buffsOffset int, isV6 bool) coalesceResult {
|
||||
func coalesceTCPPackets(mode canCoalesce, pkt []byte, pktBuffsIndex int, gsoSize uint16, seq uint32, pshSet bool, item *tcpGROItem, bufs [][]byte, bufsOffset int, isV6 bool) coalesceResult {
|
||||
var pktHead []byte // the packet that will end up at the front
|
||||
headersLen := item.iphLen + item.tcphLen
|
||||
coalescedLen := len(buffs[item.buffsIndex][buffsOffset:]) + len(pkt) - int(headersLen)
|
||||
coalescedLen := len(bufs[item.bufsIndex][bufsOffset:]) + len(pkt) - int(headersLen)
|
||||
|
||||
// Copy data
|
||||
if mode == coalescePrepend {
|
||||
pktHead = pkt
|
||||
if cap(pkt)-buffsOffset < coalescedLen {
|
||||
if cap(pkt)-bufsOffset < coalescedLen {
|
||||
// We don't want to allocate a new underlying array if capacity is
|
||||
// too small.
|
||||
return coalesceInsufficientCap
|
||||
@@ -282,7 +282,7 @@ func coalesceTCPPackets(mode canCoalesce, pkt []byte, pktBuffsIndex int, gsoSize
|
||||
return coalescePSHEnding
|
||||
}
|
||||
if item.numMerged == 0 {
|
||||
if !tcpChecksumValid(buffs[item.buffsIndex][buffsOffset:], item.iphLen, isV6) {
|
||||
if !tcpChecksumValid(bufs[item.bufsIndex][bufsOffset:], item.iphLen, isV6) {
|
||||
return coalesceItemInvalidCSum
|
||||
}
|
||||
}
|
||||
@@ -291,20 +291,20 @@ func coalesceTCPPackets(mode canCoalesce, pkt []byte, pktBuffsIndex int, gsoSize
|
||||
}
|
||||
item.sentSeq = seq
|
||||
extendBy := coalescedLen - len(pktHead)
|
||||
buffs[pktBuffsIndex] = append(buffs[pktBuffsIndex], make([]byte, extendBy)...)
|
||||
copy(buffs[pktBuffsIndex][buffsOffset+len(pkt):], buffs[item.buffsIndex][buffsOffset+int(headersLen):])
|
||||
// Flip the slice headers in buffs as part of prepend. The index of item
|
||||
bufs[pktBuffsIndex] = append(bufs[pktBuffsIndex], make([]byte, extendBy)...)
|
||||
copy(bufs[pktBuffsIndex][bufsOffset+len(pkt):], bufs[item.bufsIndex][bufsOffset+int(headersLen):])
|
||||
// Flip the slice headers in bufs as part of prepend. The index of item
|
||||
// is already being tracked for writing.
|
||||
buffs[item.buffsIndex], buffs[pktBuffsIndex] = buffs[pktBuffsIndex], buffs[item.buffsIndex]
|
||||
bufs[item.bufsIndex], bufs[pktBuffsIndex] = bufs[pktBuffsIndex], bufs[item.bufsIndex]
|
||||
} else {
|
||||
pktHead = buffs[item.buffsIndex][buffsOffset:]
|
||||
if cap(pktHead)-buffsOffset < coalescedLen {
|
||||
pktHead = bufs[item.bufsIndex][bufsOffset:]
|
||||
if cap(pktHead)-bufsOffset < coalescedLen {
|
||||
// We don't want to allocate a new underlying array if capacity is
|
||||
// too small.
|
||||
return coalesceInsufficientCap
|
||||
}
|
||||
if item.numMerged == 0 {
|
||||
if !tcpChecksumValid(buffs[item.buffsIndex][buffsOffset:], item.iphLen, isV6) {
|
||||
if !tcpChecksumValid(bufs[item.bufsIndex][bufsOffset:], item.iphLen, isV6) {
|
||||
return coalesceItemInvalidCSum
|
||||
}
|
||||
}
|
||||
@@ -317,8 +317,8 @@ func coalesceTCPPackets(mode canCoalesce, pkt []byte, pktBuffsIndex int, gsoSize
|
||||
pktHead[item.iphLen+tcpFlagsOffset] |= tcpFlagPSH
|
||||
}
|
||||
extendBy := len(pkt) - int(headersLen)
|
||||
buffs[item.buffsIndex] = append(buffs[item.buffsIndex], make([]byte, extendBy)...)
|
||||
copy(buffs[item.buffsIndex][buffsOffset+len(pktHead):], pkt[headersLen:])
|
||||
bufs[item.bufsIndex] = append(bufs[item.bufsIndex], make([]byte, extendBy)...)
|
||||
copy(bufs[item.bufsIndex][bufsOffset+len(pktHead):], pkt[headersLen:])
|
||||
}
|
||||
|
||||
if gsoSize > item.gsoSize {
|
||||
@@ -344,7 +344,7 @@ func coalesceTCPPackets(mode canCoalesce, pkt []byte, pktBuffsIndex int, gsoSize
|
||||
iphCSum := ^checksum(pktHead[:item.iphLen], 0) // compute checksum
|
||||
binary.BigEndian.PutUint16(pktHead[10:], iphCSum) // set checksum field
|
||||
}
|
||||
hdr.encode(buffs[item.buffsIndex][buffsOffset-virtioNetHdrLen:])
|
||||
hdr.encode(bufs[item.bufsIndex][bufsOffset-virtioNetHdrLen:])
|
||||
|
||||
// Calculate the pseudo header checksum and place it at the TCP checksum
|
||||
// offset. Downstream checksum offloading will combine this with computation
|
||||
@@ -355,9 +355,9 @@ func coalesceTCPPackets(mode canCoalesce, pkt []byte, pktBuffsIndex int, gsoSize
|
||||
addrLen = 16
|
||||
addrOffset = ipv6SrcAddrOffset
|
||||
}
|
||||
srcAddrAt := buffsOffset + addrOffset
|
||||
srcAddr := buffs[item.buffsIndex][srcAddrAt : srcAddrAt+addrLen]
|
||||
dstAddr := buffs[item.buffsIndex][srcAddrAt+addrLen : srcAddrAt+addrLen*2]
|
||||
srcAddrAt := bufsOffset + addrOffset
|
||||
srcAddr := bufs[item.bufsIndex][srcAddrAt : srcAddrAt+addrLen]
|
||||
dstAddr := bufs[item.bufsIndex][srcAddrAt+addrLen : srcAddrAt+addrLen*2]
|
||||
psum := pseudoHeaderChecksumNoFold(unix.IPPROTO_TCP, srcAddr, dstAddr, uint16(coalescedLen-int(item.iphLen)))
|
||||
binary.BigEndian.PutUint16(pktHead[hdr.csumStart+hdr.csumOffset:], checksum([]byte{}, psum))
|
||||
|
||||
@@ -375,12 +375,12 @@ const (
|
||||
maxUint16 = 1<<16 - 1
|
||||
)
|
||||
|
||||
// tcpGRO evaluates the TCP packet at pktI in buffs for coalescing with
|
||||
// tcpGRO evaluates the TCP packet at pktI in bufs for coalescing with
|
||||
// existing packets tracked in table. It will return false when pktI is not
|
||||
// coalesced, otherwise true. This indicates to the caller if buffs[pktI]
|
||||
// coalesced, otherwise true. This indicates to the caller if bufs[pktI]
|
||||
// should be written to the Device.
|
||||
func tcpGRO(buffs [][]byte, offset int, pktI int, table *tcpGROTable, isV6 bool) (pktCoalesced bool) {
|
||||
pkt := buffs[pktI][offset:]
|
||||
func tcpGRO(bufs [][]byte, offset int, pktI int, table *tcpGROTable, isV6 bool) (pktCoalesced bool) {
|
||||
pkt := bufs[pktI][offset:]
|
||||
if len(pkt) > maxUint16 {
|
||||
// A valid IPv4 or IPv6 packet will never exceed this.
|
||||
return false
|
||||
@@ -452,9 +452,9 @@ func tcpGRO(buffs [][]byte, offset int, pktI int, table *tcpGROTable, isV6 bool)
|
||||
// sequence number perspective, however once an item is inserted into
|
||||
// the table it is never compared across other items later.
|
||||
item := items[i]
|
||||
can := tcpPacketsCanCoalesce(pkt, uint8(iphLen), uint8(tcphLen), seq, pshSet, gsoSize, item, buffs, offset)
|
||||
can := tcpPacketsCanCoalesce(pkt, uint8(iphLen), uint8(tcphLen), seq, pshSet, gsoSize, item, bufs, offset)
|
||||
if can != coalesceUnavailable {
|
||||
result := coalesceTCPPackets(can, pkt, pktI, gsoSize, seq, pshSet, &item, buffs, offset, isV6)
|
||||
result := coalesceTCPPackets(can, pkt, pktI, gsoSize, seq, pshSet, &item, bufs, offset, isV6)
|
||||
switch result {
|
||||
case coalesceSuccess:
|
||||
table.updateAt(item, i)
|
||||
@@ -500,25 +500,25 @@ func isTCP6NoEH(b []byte) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// handleGRO evaluates buffs for GRO, and writes the indices of the resulting
|
||||
// handleGRO evaluates bufs for GRO, and writes the indices of the resulting
|
||||
// packets into toWrite. toWrite, tcp4Table, and tcp6Table should initially be
|
||||
// empty (but non-nil), and are passed in to save allocs as the caller may reset
|
||||
// and recycle them across vectors of packets.
|
||||
func handleGRO(buffs [][]byte, offset int, tcp4Table, tcp6Table *tcpGROTable, toWrite *[]int) error {
|
||||
for i := range buffs {
|
||||
if offset < virtioNetHdrLen || offset > len(buffs[i])-1 {
|
||||
func handleGRO(bufs [][]byte, offset int, tcp4Table, tcp6Table *tcpGROTable, toWrite *[]int) error {
|
||||
for i := range bufs {
|
||||
if offset < virtioNetHdrLen || offset > len(bufs[i])-1 {
|
||||
return errors.New("invalid offset")
|
||||
}
|
||||
var coalesced bool
|
||||
switch {
|
||||
case isTCP4(buffs[i][offset:]):
|
||||
coalesced = tcpGRO(buffs, offset, i, tcp4Table, false)
|
||||
case isTCP6NoEH(buffs[i][offset:]): // ipv6 packets w/extension headers do not coalesce
|
||||
coalesced = tcpGRO(buffs, offset, i, tcp6Table, true)
|
||||
case isTCP4(bufs[i][offset:]):
|
||||
coalesced = tcpGRO(bufs, offset, i, tcp4Table, false)
|
||||
case isTCP6NoEH(bufs[i][offset:]): // ipv6 packets w/extension headers do not coalesce
|
||||
coalesced = tcpGRO(bufs, offset, i, tcp6Table, true)
|
||||
}
|
||||
if !coalesced {
|
||||
hdr := virtioNetHdr{}
|
||||
err := hdr.encode(buffs[i][offset-virtioNetHdrLen:])
|
||||
err := hdr.encode(bufs[i][offset-virtioNetHdrLen:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
10
tun/tun.go
10
tun/tun.go
@@ -23,16 +23,16 @@ type Device interface {
|
||||
|
||||
// Read one or more packets from the Device (without any additional headers).
|
||||
// On a successful read it returns the number of packets read, and sets
|
||||
// packet lengths within the sizes slice. len(sizes) must be >= len(buffs).
|
||||
// packet lengths within the sizes slice. len(sizes) must be >= len(bufs).
|
||||
// A nonzero offset can be used to instruct the Device on where to begin
|
||||
// reading into each element of the buffs slice.
|
||||
Read(buffs [][]byte, sizes []int, offset int) (n int, err error)
|
||||
// reading into each element of the bufs slice.
|
||||
Read(bufs [][]byte, sizes []int, offset int) (n int, err error)
|
||||
|
||||
// Write one or more packets to the device (without any additional headers).
|
||||
// On a successful write it returns the number of packets written. A nonzero
|
||||
// offset can be used to instruct the Device on where to begin writing from
|
||||
// each packet contained within the buffs slice.
|
||||
Write(buffs [][]byte, offset int) (int, error)
|
||||
// each packet contained within the bufs slice.
|
||||
Write(bufs [][]byte, offset int) (int, error)
|
||||
|
||||
// MTU returns the MTU of the Device.
|
||||
MTU() (int, error)
|
||||
|
||||
@@ -217,7 +217,7 @@ func (tun *NativeTun) Events() <-chan Event {
|
||||
return tun.events
|
||||
}
|
||||
|
||||
func (tun *NativeTun) Read(buffs [][]byte, sizes []int, offset int) (int, error) {
|
||||
func (tun *NativeTun) Read(bufs [][]byte, sizes []int, offset int) (int, error) {
|
||||
// TODO: the BSDs look very similar in Read() and Write(). They should be
|
||||
// collapsed, with platform-specific files containing the varying parts of
|
||||
// their implementations.
|
||||
@@ -225,8 +225,8 @@ func (tun *NativeTun) Read(buffs [][]byte, sizes []int, offset int) (int, error)
|
||||
case err := <-tun.errors:
|
||||
return 0, err
|
||||
default:
|
||||
buff := buffs[0][offset-4:]
|
||||
n, err := tun.tunFile.Read(buff[:])
|
||||
buf := bufs[0][offset-4:]
|
||||
n, err := tun.tunFile.Read(buf[:])
|
||||
if n < 4 {
|
||||
return 0, err
|
||||
}
|
||||
@@ -235,11 +235,11 @@ func (tun *NativeTun) Read(buffs [][]byte, sizes []int, offset int) (int, error)
|
||||
}
|
||||
}
|
||||
|
||||
func (tun *NativeTun) Write(buffs [][]byte, offset int) (int, error) {
|
||||
func (tun *NativeTun) Write(bufs [][]byte, offset int) (int, error) {
|
||||
if offset < 4 {
|
||||
return 0, io.ErrShortBuffer
|
||||
}
|
||||
for i, buf := range buffs {
|
||||
for i, buf := range bufs {
|
||||
buf = buf[offset-4:]
|
||||
buf[0] = 0x00
|
||||
buf[1] = 0x00
|
||||
@@ -256,7 +256,7 @@ func (tun *NativeTun) Write(buffs [][]byte, offset int) (int, error) {
|
||||
return i, err
|
||||
}
|
||||
}
|
||||
return len(buffs), nil
|
||||
return len(bufs), nil
|
||||
}
|
||||
|
||||
func (tun *NativeTun) Close() error {
|
||||
|
||||
@@ -333,13 +333,13 @@ func (tun *NativeTun) Events() <-chan Event {
|
||||
return tun.events
|
||||
}
|
||||
|
||||
func (tun *NativeTun) Read(buffs [][]byte, sizes []int, offset int) (int, error) {
|
||||
func (tun *NativeTun) Read(bufs [][]byte, sizes []int, offset int) (int, error) {
|
||||
select {
|
||||
case err := <-tun.errors:
|
||||
return 0, err
|
||||
default:
|
||||
buff := buffs[0][offset-4:]
|
||||
n, err := tun.tunFile.Read(buff[:])
|
||||
buf := bufs[0][offset-4:]
|
||||
n, err := tun.tunFile.Read(buf[:])
|
||||
if n < 4 {
|
||||
return 0, err
|
||||
}
|
||||
@@ -348,11 +348,11 @@ func (tun *NativeTun) Read(buffs [][]byte, sizes []int, offset int) (int, error)
|
||||
}
|
||||
}
|
||||
|
||||
func (tun *NativeTun) Write(buffs [][]byte, offset int) (int, error) {
|
||||
func (tun *NativeTun) Write(bufs [][]byte, offset int) (int, error) {
|
||||
if offset < 4 {
|
||||
return 0, io.ErrShortBuffer
|
||||
}
|
||||
for i, buf := range buffs {
|
||||
for i, buf := range bufs {
|
||||
buf = buf[offset-4:]
|
||||
if len(buf) < 5 {
|
||||
return i, io.ErrShortBuffer
|
||||
@@ -372,7 +372,7 @@ func (tun *NativeTun) Write(buffs [][]byte, offset int) (int, error) {
|
||||
return i, err
|
||||
}
|
||||
}
|
||||
return len(buffs), nil
|
||||
return len(bufs), nil
|
||||
}
|
||||
|
||||
func (tun *NativeTun) Close() error {
|
||||
|
||||
@@ -330,7 +330,7 @@ func (tun *NativeTun) nameSlow() (string, error) {
|
||||
return unix.ByteSliceToString(ifr[:]), nil
|
||||
}
|
||||
|
||||
func (tun *NativeTun) Write(buffs [][]byte, offset int) (int, error) {
|
||||
func (tun *NativeTun) Write(bufs [][]byte, offset int) (int, error) {
|
||||
tun.writeOpMu.Lock()
|
||||
defer func() {
|
||||
tun.tcp4GROTable.reset()
|
||||
@@ -343,18 +343,18 @@ func (tun *NativeTun) Write(buffs [][]byte, offset int) (int, error) {
|
||||
)
|
||||
tun.toWrite = tun.toWrite[:0]
|
||||
if tun.vnetHdr {
|
||||
err := handleGRO(buffs, offset, tun.tcp4GROTable, tun.tcp6GROTable, &tun.toWrite)
|
||||
err := handleGRO(bufs, offset, tun.tcp4GROTable, tun.tcp6GROTable, &tun.toWrite)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
offset -= virtioNetHdrLen
|
||||
} else {
|
||||
for i := range buffs {
|
||||
for i := range bufs {
|
||||
tun.toWrite = append(tun.toWrite, i)
|
||||
}
|
||||
}
|
||||
for _, buffsI := range tun.toWrite {
|
||||
n, err := tun.tunFile.Write(buffs[buffsI][offset:])
|
||||
for _, bufsI := range tun.toWrite {
|
||||
n, err := tun.tunFile.Write(bufs[bufsI][offset:])
|
||||
if errors.Is(err, syscall.EBADFD) {
|
||||
return total, os.ErrClosed
|
||||
}
|
||||
@@ -367,10 +367,10 @@ func (tun *NativeTun) Write(buffs [][]byte, offset int) (int, error) {
|
||||
return total, ErrorBatch(errs)
|
||||
}
|
||||
|
||||
// handleVirtioRead splits in into buffs, leaving offset bytes at the front of
|
||||
// each buffer. It mutates sizes to reflect the size of each element of buffs,
|
||||
// handleVirtioRead splits in into bufs, leaving offset bytes at the front of
|
||||
// each buffer. It mutates sizes to reflect the size of each element of bufs,
|
||||
// and returns the number of packets read.
|
||||
func handleVirtioRead(in []byte, buffs [][]byte, sizes []int, offset int) (int, error) {
|
||||
func handleVirtioRead(in []byte, bufs [][]byte, sizes []int, offset int) (int, error) {
|
||||
var hdr virtioNetHdr
|
||||
err := hdr.decode(in)
|
||||
if err != nil {
|
||||
@@ -387,10 +387,10 @@ func handleVirtioRead(in []byte, buffs [][]byte, sizes []int, offset int) (int,
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
if len(in) > len(buffs[0][offset:]) {
|
||||
return 0, fmt.Errorf("read len %d overflows buffs element len %d", len(in), len(buffs[0][offset:]))
|
||||
if len(in) > len(bufs[0][offset:]) {
|
||||
return 0, fmt.Errorf("read len %d overflows bufs element len %d", len(in), len(bufs[0][offset:]))
|
||||
}
|
||||
n := copy(buffs[0][offset:], in)
|
||||
n := copy(bufs[0][offset:], in)
|
||||
sizes[0] = n
|
||||
return 1, nil
|
||||
}
|
||||
@@ -438,17 +438,17 @@ func handleVirtioRead(in []byte, buffs [][]byte, sizes []int, offset int) (int,
|
||||
return 0, fmt.Errorf("end of checksum offset (%d) exceeds packet length (%d)", cSumAt+1, len(in))
|
||||
}
|
||||
|
||||
return tcpTSO(in, hdr, buffs, sizes, offset)
|
||||
return tcpTSO(in, hdr, bufs, sizes, offset)
|
||||
}
|
||||
|
||||
func (tun *NativeTun) Read(buffs [][]byte, sizes []int, offset int) (int, error) {
|
||||
func (tun *NativeTun) Read(bufs [][]byte, sizes []int, offset int) (int, error) {
|
||||
tun.readOpMu.Lock()
|
||||
defer tun.readOpMu.Unlock()
|
||||
select {
|
||||
case err := <-tun.errors:
|
||||
return 0, err
|
||||
default:
|
||||
readInto := buffs[0][offset:]
|
||||
readInto := bufs[0][offset:]
|
||||
if tun.vnetHdr {
|
||||
readInto = tun.readBuff[:]
|
||||
}
|
||||
@@ -460,7 +460,7 @@ func (tun *NativeTun) Read(buffs [][]byte, sizes []int, offset int) (int, error)
|
||||
return 0, err
|
||||
}
|
||||
if tun.vnetHdr {
|
||||
return handleVirtioRead(readInto[:n], buffs, sizes, offset)
|
||||
return handleVirtioRead(readInto[:n], bufs, sizes, offset)
|
||||
} else {
|
||||
sizes[0] = n
|
||||
return 1, nil
|
||||
|
||||
@@ -204,13 +204,13 @@ func (tun *NativeTun) Events() <-chan Event {
|
||||
return tun.events
|
||||
}
|
||||
|
||||
func (tun *NativeTun) Read(buffs [][]byte, sizes []int, offset int) (int, error) {
|
||||
func (tun *NativeTun) Read(bufs [][]byte, sizes []int, offset int) (int, error) {
|
||||
select {
|
||||
case err := <-tun.errors:
|
||||
return 0, err
|
||||
default:
|
||||
buff := buffs[0][offset-4:]
|
||||
n, err := tun.tunFile.Read(buff[:])
|
||||
buf := bufs[0][offset-4:]
|
||||
n, err := tun.tunFile.Read(buf[:])
|
||||
if n < 4 {
|
||||
return 0, err
|
||||
}
|
||||
@@ -219,11 +219,11 @@ func (tun *NativeTun) Read(buffs [][]byte, sizes []int, offset int) (int, error)
|
||||
}
|
||||
}
|
||||
|
||||
func (tun *NativeTun) Write(buffs [][]byte, offset int) (int, error) {
|
||||
func (tun *NativeTun) Write(bufs [][]byte, offset int) (int, error) {
|
||||
if offset < 4 {
|
||||
return 0, io.ErrShortBuffer
|
||||
}
|
||||
for i, buf := range buffs {
|
||||
for i, buf := range bufs {
|
||||
buf = buf[offset-4:]
|
||||
buf[0] = 0x00
|
||||
buf[1] = 0x00
|
||||
@@ -240,7 +240,7 @@ func (tun *NativeTun) Write(buffs [][]byte, offset int) (int, error) {
|
||||
return i, err
|
||||
}
|
||||
}
|
||||
return len(buffs), nil
|
||||
return len(bufs), nil
|
||||
}
|
||||
|
||||
func (tun *NativeTun) Close() error {
|
||||
|
||||
@@ -141,7 +141,7 @@ func (tun *NativeTun) BatchSize() int {
|
||||
|
||||
// Note: Read() and Write() assume the caller comes only from a single thread; there's no locking.
|
||||
|
||||
func (tun *NativeTun) Read(buffs [][]byte, sizes []int, offset int) (int, error) {
|
||||
func (tun *NativeTun) Read(bufs [][]byte, sizes []int, offset int) (int, error) {
|
||||
tun.running.Add(1)
|
||||
defer tun.running.Done()
|
||||
retry:
|
||||
@@ -158,7 +158,7 @@ retry:
|
||||
switch err {
|
||||
case nil:
|
||||
packetSize := len(packet)
|
||||
copy(buffs[0][offset:], packet)
|
||||
copy(bufs[0][offset:], packet)
|
||||
sizes[0] = packetSize
|
||||
tun.session.ReleaseReceivePacket(packet)
|
||||
tun.rate.update(uint64(packetSize))
|
||||
@@ -179,22 +179,22 @@ retry:
|
||||
}
|
||||
}
|
||||
|
||||
func (tun *NativeTun) Write(buffs [][]byte, offset int) (int, error) {
|
||||
func (tun *NativeTun) Write(bufs [][]byte, offset int) (int, error) {
|
||||
tun.running.Add(1)
|
||||
defer tun.running.Done()
|
||||
if tun.close.Load() {
|
||||
return 0, os.ErrClosed
|
||||
}
|
||||
|
||||
for i, buff := range buffs {
|
||||
packetSize := len(buff) - offset
|
||||
for i, buf := range bufs {
|
||||
packetSize := len(buf) - offset
|
||||
tun.rate.update(uint64(packetSize))
|
||||
|
||||
packet, err := tun.session.AllocateSendPacket(packetSize)
|
||||
switch err {
|
||||
case nil:
|
||||
// TODO: Explore options to eliminate this copy.
|
||||
copy(packet, buff[offset:])
|
||||
copy(packet, buf[offset:])
|
||||
tun.session.SendPacket(packet)
|
||||
continue
|
||||
case windows.ERROR_HANDLE_EOF:
|
||||
@@ -205,7 +205,7 @@ func (tun *NativeTun) Write(buffs [][]byte, offset int) (int, error) {
|
||||
return i, fmt.Errorf("Write failed: %w", err)
|
||||
}
|
||||
}
|
||||
return len(buffs), nil
|
||||
return len(bufs), nil
|
||||
}
|
||||
|
||||
// LUID returns Windows interface instance ID.
|
||||
|
||||
Reference in New Issue
Block a user