diff --git a/http/httpraw/parse.go b/http/httpraw/parse.go index 6666e35..8e7817f 100644 --- a/http/httpraw/parse.go +++ b/http/httpraw/parse.go @@ -3,7 +3,6 @@ package httpraw import ( "bytes" "errors" - "log/slog" "slices" "unsafe" @@ -300,11 +299,13 @@ func (h *Header) appendHeader(key, value string) { if h.flags.hasAny(flagNoBufferGrow) { panic(errSmallBuffer) } + debuglog("http:appendhdr:grow-buf") hb.buf = slices.Grow(buf, len(key)+len(value)) } h.flags |= flagMangledBuffer k := hb.mustAppendSlice(key) v := hb.mustAppendSlice(value) + debuglog("http:appendhdr:grow-hdrs") hb.headers = append(hb.headers, argsKV{ key: k, value: v, @@ -426,10 +427,10 @@ func bytes2tok(buf, value []byte) headerSlice { } } -const enableDebug = false +const enableDebug = internal.HeapAllocDebugging func debuglog(msg string) { if enableDebug { - internal.LogAttrs(nil, slog.LevelDebug, msg) + internal.LogAllocs(msg) } } diff --git a/internet/pcap/capture.go b/internet/pcap/capture.go index cc75c06..4440d03 100644 --- a/internet/pcap/capture.go +++ b/internet/pcap/capture.go @@ -2,12 +2,12 @@ package pcap //go:generate stringer -type=FieldClass -linecomment -output stringers.go . import ( - "bytes" "encoding/binary" "errors" "fmt" - "log/slog" "math" + "strings" + "unsafe" "github.com/soypat/lneto" "github.com/soypat/lneto/arp" @@ -553,21 +553,21 @@ func (pc *PacketBreakdown) CaptureDHCPv4(dst []Frame, pkt []byte, bitOffset int) // based on the Content-Type header, falling back to byte inspection when Content-Type is absent. func httpBodyClass(contentType, body []byte) FieldClass { if len(contentType) > 0 { + // Use unsafe string conversion to avoid []byte("literal") heap allocations in TinyGo. + ct := unsafe.String(&contentType[0], len(contentType)) // Strip parameters (e.g. "; charset=utf-8") for media type matching. - mediaType := contentType - if i := bytes.IndexByte(contentType, ';'); i >= 0 { - mediaType = contentType[:i] + if i := strings.IndexByte(ct, ';'); i >= 0 { + ct = strings.TrimSpace(ct[:i]) } - mediaType = bytes.TrimSpace(mediaType) switch { - case bytes.HasPrefix(mediaType, []byte("text/")): + case strings.HasPrefix(ct, "text/"): return FieldClassText - case internal.BytesEqual(mediaType, []byte("application/json")), - internal.BytesEqual(mediaType, []byte("application/javascript")), - internal.BytesEqual(mediaType, []byte("application/xml")): + case ct == "application/json", + ct == "application/javascript", + ct == "application/xml": return FieldClassText - case bytes.HasSuffix(mediaType, []byte("+json")), - bytes.HasSuffix(mediaType, []byte("+xml")): + case strings.HasSuffix(ct, "+json"), + strings.HasSuffix(ct, "+xml"): return FieldClassText } return FieldClassPayload @@ -603,8 +603,11 @@ func (pc *PacketBreakdown) CaptureHTTP(dst []Frame, pkt []byte, bitOffset int) ( debuglog("pcap:http:parsed") hdrLen := pc.hdr.BufferParsed() body, _ := pc.hdr.Body() + debuglog("pcap:http:body") bodyClass := httpBodyClass(pc.hdr.Get("Content-Type"), body) + debuglog("pcap:http:bodyclass") finfo := reclaimFrame(&dst, httpProtocol, bitOffset, nil) + debuglog("pcap:http:reclaim") finfo.Fields = append(finfo.Fields, FrameField{ Name: "HTTP Header", @@ -1351,10 +1354,10 @@ func reclaimRemainingFrame(dst *[]Frame, proto string, class FieldClass, pktBitO }) } -const enableDebug = false +const enableDebug = internal.HeapAllocDebugging func debuglog(msg string) { if enableDebug { - internal.LogAttrs(nil, slog.LevelDebug, msg) + internal.LogAllocs(msg) } } diff --git a/internet/stack-ip.go b/internet/stack-ip.go index f41ff1d..3029d17 100644 --- a/internet/stack-ip.go +++ b/internet/stack-ip.go @@ -70,6 +70,7 @@ func (sb *StackIP) SetLogger(logger *slog.Logger) { } func (sb *StackIP) Demux(carrierData []byte, offset int) error { + debugLog("ip:demux") sb.handlers.info("StackIP.Demux:start") frame := carrierData[offset:] // we don't care about carrier data in IP. ifrm, err := ipv4.NewFrame(frame) @@ -232,7 +233,7 @@ func (l logger) trace(msg string, attrs ...slog.Attr) { internal.LogAttrs(l.log, internal.LevelTrace, msg, attrs...) } -const enableAllocLog = false +const enableAllocLog = internal.HeapAllocDebugging func debugLog(msg string) { if enableAllocLog { diff --git a/internet/tcplistener_test.go b/internet/tcplistener_test.go index 513ccff..ec26a53 100644 --- a/internet/tcplistener_test.go +++ b/internet/tcplistener_test.go @@ -411,10 +411,10 @@ func TestListener_RSTOnStalePacket(t *testing.T) { copy(rawBuf[12:16], clientIP[:]) copy(rawBuf[16:20], serverIP[:]) // TCP header at offset 20. - binary.BigEndian.PutUint16(rawBuf[20:], 1337) // src port + binary.BigEndian.PutUint16(rawBuf[20:], 1337) // src port binary.BigEndian.PutUint16(rawBuf[22:], serverPort) // dst port - binary.BigEndian.PutUint32(rawBuf[24:], 500) // SEQ - binary.BigEndian.PutUint32(rawBuf[28:], 200) // ACK + binary.BigEndian.PutUint32(rawBuf[24:], 500) // SEQ + binary.BigEndian.PutUint32(rawBuf[28:], 200) // ACK rawBuf[32] = 0x50 // offset=5 rawBuf[33] = 0x11 // flags = FIN|ACK (0x01|0x10) @@ -484,8 +484,8 @@ func TestStackPorts_RSTOnUnknownPort(t *testing.T) { binary.BigEndian.PutUint16(rawBuf[22:], 443) // dst port (no listener!) binary.BigEndian.PutUint32(rawBuf[24:], 700) // SEQ = 700 binary.BigEndian.PutUint32(rawBuf[28:], 0) // ACK = 0 - rawBuf[32] = 0x50 // offset=5 - rawBuf[33] = 0x02 // flags = SYN + rawBuf[32] = 0x50 // offset=5 + rawBuf[33] = 0x02 // flags = SYN err := sp.Demux(rawBuf[:40], 20) if err == nil { @@ -546,9 +546,9 @@ func TestListener_ECN_SYN(t *testing.T) { // TCP header at offset 20. binary.BigEndian.PutUint16(rawBuf[20:], 5000) // src port binary.BigEndian.PutUint16(rawBuf[22:], serverPort) - binary.BigEndian.PutUint32(rawBuf[24:], 300) // SEQ - binary.BigEndian.PutUint32(rawBuf[28:], 0) // ACK - rawBuf[32] = 0x50 // offset=5 + binary.BigEndian.PutUint32(rawBuf[24:], 300) // SEQ + binary.BigEndian.PutUint32(rawBuf[28:], 0) // ACK + rawBuf[32] = 0x50 // offset=5 rawBuf[33] = byte(tcp.FlagSYN | tcp.FlagECE | tcp.FlagCWR) // SYN+ECE+CWR // Should be accepted (create connection), not dropped. diff --git a/tcp/listener.go b/tcp/listener.go index 572d58a..1991918 100644 --- a/tcp/listener.go +++ b/tcp/listener.go @@ -241,6 +241,7 @@ func (listener *Listener) Demux(carrierData []byte, tcpFrameOffset int) error { listener.logerr("Listener:demux", slog.String("err", err.Error())) return lneto.ErrPacketDrop } + debuglog("tcplistener:demux-append") listener.incoming = append(listener.incoming, handler{ conn: conn, id: *conn.ConnectionID(), @@ -316,3 +317,11 @@ func (listener *Listener) returnIncoming(idx int) { listener.poolReturn(listener.incoming[idx].conn) listener.incoming[idx] = handler{} } + +const enableDebug = internal.HeapAllocDebugging + +func debuglog(msg string) { + if enableDebug { + internal.LogAllocs(msg) + } +}