mirror of
https://github.com/soypat/lneto.git
synced 2026-07-26 10:38:47 +00:00
heap: remove heap alloc in pcap of HTTP content type; more debugging logs
This commit is contained in:
+17
-14
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user