diff --git a/internet/definitions.go b/internet/definitions.go index 583cfd3..8467f9a 100644 --- a/internet/definitions.go +++ b/internet/definitions.go @@ -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. } } diff --git a/internet/definitions_go.go b/internet/definitions_go.go new file mode 100644 index 0000000..f84e843 --- /dev/null +++ b/internet/definitions_go.go @@ -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 +} diff --git a/internet/definitions_tinygo.go b/internet/definitions_tinygo.go new file mode 100644 index 0000000..3ffa59f --- /dev/null +++ b/internet/definitions_tinygo.go @@ -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 +} diff --git a/internet/stack-ip.go b/internet/stack-ip.go index 5e465ab..9b69a3d 100644 --- a/internet/stack-ip.go +++ b/internet/stack-ip.go @@ -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 diff --git a/internet/stack-ports.go b/internet/stack-ports.go index 413cc09..e70c0e2 100644 --- a/internet/stack-ports.go +++ b/internet/stack-ports.go @@ -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. } diff --git a/internet/stack-udpport.go b/internet/stack-udpport.go index ad60790..761ca3e 100644 --- a/internet/stack-udpport.go +++ b/internet/stack-udpport.go @@ -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()))