mirror of
https://github.com/soypat/lneto.git
synced 2026-08-20 06:29:03 +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.
|
// node is a concrete StackNode as stored in Stacks. Methods are devirtualized for performance benefits, especially on TinyGo.
|
||||||
type node struct {
|
type node struct {
|
||||||
currConnID uint64
|
currConnID uint64
|
||||||
connID *uint64
|
connID *uint64
|
||||||
demux func([]byte, int) error
|
// cbnode has different definitions in tinygo and normal Go compiled programs
|
||||||
encapsulate func([]byte, int, int) (int, error)
|
// for performance and heap control reasons.
|
||||||
proto uint16
|
callbacks cbnode
|
||||||
port uint16
|
// 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
|
// remoteAddr will be set on active(outbound) port connections
|
||||||
// that require an ARP to set the remoteAddr beforehand.
|
// that require an ARP to set the remoteAddr beforehand.
|
||||||
remoteAddr []byte
|
remoteAddr []byte
|
||||||
@@ -152,7 +155,7 @@ func (h *handlers) demuxByProto(buf []byte, offset int, proto uint16) (*node, er
|
|||||||
if node == nil {
|
if node == nil {
|
||||||
return nil, lneto.ErrPacketDrop
|
return nil, lneto.ErrPacketDrop
|
||||||
}
|
}
|
||||||
err := node.demux(buf, offset)
|
err := node.callbacks.Demux(buf, offset)
|
||||||
if h.tryHandleError(node, err) {
|
if h.tryHandleError(node, err) {
|
||||||
err = nil
|
err = nil
|
||||||
}
|
}
|
||||||
@@ -165,7 +168,7 @@ func (h *handlers) demuxByPort(buf []byte, offset int, port uint16) (*node, erro
|
|||||||
if node == nil {
|
if node == nil {
|
||||||
return nil, lneto.ErrPacketDrop
|
return nil, lneto.ErrPacketDrop
|
||||||
}
|
}
|
||||||
err := node.demux(buf, offset)
|
err := node.callbacks.Demux(buf, offset)
|
||||||
if h.tryHandleError(node, err) {
|
if h.tryHandleError(node, err) {
|
||||||
err = nil
|
err = nil
|
||||||
node = nil // Node is destroyed in tryHandleError and invalidated.
|
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() {
|
if node.IsInvalid() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
n, err = node.encapsulate(buf, offsetIP, offsetThisFrame)
|
n, err = node.callbacks.Encapsulate(buf, offsetIP, offsetThisFrame)
|
||||||
if h.tryHandleError(node, err) {
|
if h.tryHandleError(node, err) {
|
||||||
err = nil // CLOSE error handled gracefully by deleting node.
|
err = nil // CLOSE error handled gracefully by deleting node.
|
||||||
node = nil // Node is destroyed in tryHandleError and invalidated.
|
node = nil // Node is destroyed in tryHandleError and invalidated.
|
||||||
@@ -206,7 +209,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (node *node) IsInvalid() bool {
|
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) {
|
func checkNodeErr(node *node, err error) (discard bool) {
|
||||||
@@ -223,13 +226,12 @@ func nodeFromStackNode(s StackNode, port uint16, protocol uint64, remoteAddr []b
|
|||||||
currConnID = *connIDPtr
|
currConnID = *connIDPtr
|
||||||
}
|
}
|
||||||
return node{
|
return node{
|
||||||
currConnID: currConnID,
|
currConnID: currConnID,
|
||||||
connID: connIDPtr,
|
connID: connIDPtr,
|
||||||
demux: s.Demux,
|
callbacks: makecbnode(s),
|
||||||
encapsulate: s.Encapsulate,
|
proto: uint16(protocol),
|
||||||
proto: uint16(protocol),
|
port: port,
|
||||||
port: port,
|
remoteAddr: remoteAddr, // SHARED MEMORY- used to signal.
|
||||||
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)))
|
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) {
|
if sb.handlers.tryHandleError(node, err) {
|
||||||
sb.handlers.info("ipclose", slog.String("proto", proto.String()))
|
sb.handlers.info("ipclose", slog.String("proto", proto.String()))
|
||||||
err = nil
|
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...)) {
|
if node.IsInvalid() || (len(node.remoteAddr) > 0 && internal.IsZeroed(node.remoteAddr...)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
n, err = node.encapsulate(carrierData, offsetToIP, offsetToFrame)
|
n, err = node.callbacks.Encapsulate(carrierData, offsetToIP, offsetToFrame)
|
||||||
if h.tryHandleError(node, err) {
|
if h.tryHandleError(node, err) {
|
||||||
err = nil // CLOSE error handled gracefully by deleting node.
|
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 {
|
if sudp.rmport != 0 && src != sudp.rmport {
|
||||||
return lneto.ErrPacketDrop // Not from our target remote port.
|
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 err != nil {
|
||||||
if checkNodeErr(&sudp.h, err) {
|
if checkNodeErr(&sudp.h, err) {
|
||||||
sudp.h.destroy()
|
sudp.h.destroy()
|
||||||
@@ -79,7 +79,7 @@ func (sudp *StackUDPPort) Encapsulate(carrierData []byte, offsetToIP, offsetToFr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Child payload starts 8 bytes after UDP header start.
|
// 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 n == 0 {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("stackudp:encapsulate", slog.String("err", err.Error()))
|
slog.Error("stackudp:encapsulate", slog.String("err", err.Error()))
|
||||||
|
|||||||
Reference in New Issue
Block a user