mirror of
https://github.com/soypat/lneto.git
synced 2026-08-07 08:23:42 +00:00
split out node callback between tinygo and go to avoid heap allocs
This commit is contained in:
+19
-17
@@ -40,12 +40,15 @@ type StackNode interface {
|
||||
|
||||
// node is a concrete StackNode as stored in Stacks. Methods are devirtualized for performance benefits, especially on TinyGo.
|
||||
type node struct {
|
||||
currConnID uint64
|
||||
connID *uint64
|
||||
demux func([]byte, int) error
|
||||
encapsulate func([]byte, int, int) (int, error)
|
||||
proto uint16
|
||||
port uint16
|
||||
currConnID uint64
|
||||
connID *uint64
|
||||
// cbnode has different definitions in tinygo and normal Go compiled programs
|
||||
// for performance and heap control reasons.
|
||||
callbacks cbnode
|
||||
// demux func([]byte, int) error
|
||||
// encapsulate func([]byte, int, int) (int, error)
|
||||
proto uint16
|
||||
port uint16
|
||||
// remoteAddr will be set on active(outbound) port connections
|
||||
// that require an ARP to set the remoteAddr beforehand.
|
||||
remoteAddr []byte
|
||||
@@ -152,7 +155,7 @@ func (h *handlers) demuxByProto(buf []byte, offset int, proto uint16) (*node, er
|
||||
if node == nil {
|
||||
return nil, lneto.ErrPacketDrop
|
||||
}
|
||||
err := node.demux(buf, offset)
|
||||
err := node.callbacks.Demux(buf, offset)
|
||||
if h.tryHandleError(node, err) {
|
||||
err = nil
|
||||
}
|
||||
@@ -165,7 +168,7 @@ func (h *handlers) demuxByPort(buf []byte, offset int, port uint16) (*node, erro
|
||||
if node == nil {
|
||||
return nil, lneto.ErrPacketDrop
|
||||
}
|
||||
err := node.demux(buf, offset)
|
||||
err := node.callbacks.Demux(buf, offset)
|
||||
if h.tryHandleError(node, err) {
|
||||
err = nil
|
||||
node = nil // Node is destroyed in tryHandleError and invalidated.
|
||||
@@ -181,7 +184,7 @@ func (h *handlers) encapsulateAny(buf []byte, offsetIP, offsetThisFrame int) (_
|
||||
if node.IsInvalid() {
|
||||
continue
|
||||
}
|
||||
n, err = node.encapsulate(buf, offsetIP, offsetThisFrame)
|
||||
n, err = node.callbacks.Encapsulate(buf, offsetIP, offsetThisFrame)
|
||||
if h.tryHandleError(node, err) {
|
||||
err = nil // CLOSE error handled gracefully by deleting node.
|
||||
node = nil // Node is destroyed in tryHandleError and invalidated.
|
||||
@@ -206,7 +209,7 @@ var (
|
||||
)
|
||||
|
||||
func (node *node) IsInvalid() bool {
|
||||
return node.demux == nil || node.encapsulate == nil || (node.connID != nil && node.currConnID != *node.connID)
|
||||
return node.callbacks.IsZeroed() || (node.connID != nil && node.currConnID != *node.connID)
|
||||
}
|
||||
|
||||
func checkNodeErr(node *node, err error) (discard bool) {
|
||||
@@ -223,13 +226,12 @@ func nodeFromStackNode(s StackNode, port uint16, protocol uint64, remoteAddr []b
|
||||
currConnID = *connIDPtr
|
||||
}
|
||||
return node{
|
||||
currConnID: currConnID,
|
||||
connID: connIDPtr,
|
||||
demux: s.Demux,
|
||||
encapsulate: s.Encapsulate,
|
||||
proto: uint16(protocol),
|
||||
port: port,
|
||||
remoteAddr: remoteAddr, // SHARED MEMORY- used to signal.
|
||||
currConnID: currConnID,
|
||||
connID: connIDPtr,
|
||||
callbacks: makecbnode(s),
|
||||
proto: uint16(protocol),
|
||||
port: port,
|
||||
remoteAddr: remoteAddr, // SHARED MEMORY- used to signal.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
//go:build !tinygo
|
||||
|
||||
package internet
|
||||
|
||||
func makecbnode(s StackNode) cbnode {
|
||||
return cbnode{
|
||||
_s: s,
|
||||
}
|
||||
}
|
||||
|
||||
type cbnode struct {
|
||||
// Do not access outside of handlers/node logic.
|
||||
_s StackNode
|
||||
}
|
||||
|
||||
func (s cbnode) Encapsulate(carrierData []byte, offsetToIP, offsetToFrame int) (int, error) {
|
||||
return s._s.Encapsulate(carrierData, offsetToIP, offsetToFrame)
|
||||
}
|
||||
|
||||
func (s cbnode) Demux(carrierData []byte, frameOffset int) error {
|
||||
return s._s.Demux(carrierData, frameOffset)
|
||||
}
|
||||
|
||||
func (s cbnode) IsZeroed() bool {
|
||||
return s._s == nil
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
//go:build tinygo
|
||||
|
||||
package internet
|
||||
|
||||
func makecbnode(s StackNode) cbnode {
|
||||
return cbnode{
|
||||
demux: s.Demux,
|
||||
encapsulate: s.Encapsulate,
|
||||
}
|
||||
}
|
||||
|
||||
type cbnode struct {
|
||||
// Do not access outside of handlers/node logic.
|
||||
demux func([]byte, int) error
|
||||
// Do not access outside of handlers/node logic.
|
||||
encapsulate func([]byte, int, int) (int, error)
|
||||
}
|
||||
|
||||
func (s *cbnode) Encapsulate(carrierData []byte, offsetToIP, offsetToFrame int) (int, error) {
|
||||
return s.encapsulate(carrierData, offsetToIP, offsetToFrame)
|
||||
}
|
||||
|
||||
func (s *cbnode) Demux(carrierData []byte, frameOffset int) error {
|
||||
return s.demux(carrierData, frameOffset)
|
||||
}
|
||||
|
||||
func (s cbnode) IsZeroed() bool {
|
||||
return s.demux == nil || s.encapsulate == nil
|
||||
}
|
||||
@@ -136,7 +136,7 @@ func (sb *StackIP) Demux(carrierData []byte, offset int) error {
|
||||
}
|
||||
}
|
||||
sb.handlers.info("ipDemux", slog.String("ipproto", proto.String()), slog.Int("plen", int(totalLen)))
|
||||
err = node.demux(frame[:totalLen], off)
|
||||
err = node.callbacks.Demux(frame[:totalLen], off)
|
||||
if sb.handlers.tryHandleError(node, err) {
|
||||
sb.handlers.info("ipclose", slog.String("proto", proto.String()))
|
||||
err = nil
|
||||
|
||||
@@ -134,7 +134,7 @@ func (ps *StackPortsMACFiltered) Encapsulate(carrierData []byte, offsetToIP, off
|
||||
if node.IsInvalid() || (len(node.remoteAddr) > 0 && internal.IsZeroed(node.remoteAddr...)) {
|
||||
continue
|
||||
}
|
||||
n, err = node.encapsulate(carrierData, offsetToIP, offsetToFrame)
|
||||
n, err = node.callbacks.Encapsulate(carrierData, offsetToIP, offsetToFrame)
|
||||
if h.tryHandleError(node, err) {
|
||||
err = nil // CLOSE error handled gracefully by deleting node.
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ func (sudp *StackUDPPort) Demux(carrierData []byte, frameOffset int) error {
|
||||
if sudp.rmport != 0 && src != sudp.rmport {
|
||||
return lneto.ErrPacketDrop // Not from our target remote port.
|
||||
}
|
||||
err = sudp.h.demux(carrierData, frameOffset+8)
|
||||
err = sudp.h.callbacks.Demux(carrierData, frameOffset+8)
|
||||
if err != nil {
|
||||
if checkNodeErr(&sudp.h, err) {
|
||||
sudp.h.destroy()
|
||||
@@ -79,7 +79,7 @@ func (sudp *StackUDPPort) Encapsulate(carrierData []byte, offsetToIP, offsetToFr
|
||||
}
|
||||
}
|
||||
// Child payload starts 8 bytes after UDP header start.
|
||||
n, err := sudp.h.encapsulate(carrierData, offsetToIP, offsetToFrame+8)
|
||||
n, err := sudp.h.callbacks.Encapsulate(carrierData, offsetToIP, offsetToFrame+8)
|
||||
if n == 0 {
|
||||
if err != nil {
|
||||
slog.Error("stackudp:encapsulate", slog.String("err", err.Error()))
|
||||
|
||||
Reference in New Issue
Block a user