Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions containers/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,18 @@ func (c *Container) onL7Request(pid uint32, fd uint64, timestamp uint64, r *l7.R
if timestamp != 0 && conn.Timestamp != timestamp {
return nil
}
if conn.dstWorkload.Namespace == "external" && (r.Protocol == l7.ProtocolHTTP || r.Protocol == l7.ProtocolHTTP2) {
if host, ok := iqfqdn[conn.DestinationKey.ActualDestination().IP()]; ok {
log.Printf("Setting external host %s", host)
conn.dstWorkload.Name = host
} else {
host, error := l7.ParseHostFromHttpRequest(string(r.Payload))
if error == nil {
conn.dstWorkload.Name = host
}
}
}

stats := c.l7Stats.get(r.Protocol, conn.DestinationKey, r, conn.srcWorkload, conn.DestinationKey.GetDestinationWorkload(), conn.DestinationKey.GetActualDestinationWorkload())

trace := c.tracer.NewTrace(conn.DestinationKey.ActualDestinationIfKnown(), conn.srcWorkload, conn.DestinationKey.GetDestinationWorkload(), conn.DestinationKey.GetActualDestinationWorkload())
Expand All @@ -747,13 +759,12 @@ func (c *Container) onL7Request(pid uint32, fd uint64, timestamp uint64, r *l7.R
method := ""
uri := ""
response := ""
host := ""
host := conn.dstWorkload.Name
headers := http.Header{}
req, err := l7.ParseHTTPRequest(r.Payload)
if err != nil {
log.Printf("Failed to parse payload %s, %q", err, string(r.Payload))
method, uri = l7.ParseHttp(r.Payload)
host, _ = l7.ParseHostFromHttpRequest(string(r.Payload))
} else {
if req != nil && req.Body != nil {
body, _ := io.ReadAll(req.Body)
Expand All @@ -768,7 +779,6 @@ func (c *Container) onL7Request(pid uint32, fd uint64, timestamp uint64, r *l7.R
klog.Warningf("Non-utf8 characters in uri %q", req.URL.Path)
uri = string([]rune(req.URL.Path))
}
host = req.Host
if req.Header != nil {
headers = req.Header
}
Expand Down
8 changes: 0 additions & 8 deletions containers/l7.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,6 @@ func (s L7Stats) get(protocol l7.Protocol, key common.DestinationKey, r *l7.Requ
log.Printf("Failed to parse path %s", path)
}
constLabels["method"] = method
if dstWorkload.Namespace == "external" {
host, err := l7.ParseHostFromHttpRequest(string(r.Payload))
if host != "" {
constLabels["destination_workload_name"] = host
} else {
log.Printf("Failed to parse host %s , %v", string(r.Payload), err)
}
}
hOpts := L7Latency[protocol]
m.Latency = prometheus.NewHistogram(
prometheus.HistogramOpts{Name: hOpts.Name, Help: hOpts.Help, ConstLabels: constLabels},
Expand Down
45 changes: 30 additions & 15 deletions ebpftracer/tracer.go
Original file line number Diff line number Diff line change
Expand Up @@ -388,11 +388,32 @@ func runEventsReader(name string, r *perf.Reader, ch chan<- Event, typ perfMapTy
v := &l7Event{}
data := rec.RawSample
reader := bytes.NewBuffer(data)

// Ensure binary.Read does not fail before proceeding
if err := binary.Read(reader, binary.LittleEndian, v); err != nil {
klog.Warningln("failed to read msg:", err)
continue
}

payload := reader.Bytes()
expectedSize := int(v.PayloadSize) + int(v.ResponseSize)

// If the actual payload is smaller than expected, we log a warning and adjust
if len(payload) < expectedSize {
klog.Warningf("Payload too small (got %d bytes, expected %d), adjusting sizes", len(payload), expectedSize)
}

// Compute safe slicing limits
payloadEnd := min(int(v.PayloadSize), len(payload))
responseEnd := min(payloadEnd+int(v.ResponseSize), len(payload))

// Always copy to prevent garbage data from reused buffers
payloadData := make([]byte, payloadEnd)
copy(payloadData, payload[:payloadEnd])

responseData := make([]byte, responseEnd-payloadEnd)
copy(responseData, payload[payloadEnd:responseEnd])

req := &l7.RequestData{
Protocol: l7.Protocol(v.Protocol),
Status: l7.Status(v.Status),
Expand All @@ -401,23 +422,17 @@ func runEventsReader(name string, r *perf.Reader, ch chan<- Event, typ perfMapTy
StatementId: v.StatementId,
PayloadSize: v.PayloadSize,
ResponseSize: v.ResponseSize,
Payload: payloadData,
Response: responseData,
}
switch {
case v.PayloadSize == 0:
case v.PayloadSize > MaxPayloadSize && v.ResponseSize > MaxPayloadSize:
req.Payload = payload[:MaxPayloadSize]
req.Response = payload[MaxPayloadSize:]
case v.PayloadSize > MaxPayloadSize:
req.Payload = payload[:MaxPayloadSize]
req.Response = payload[MaxPayloadSize : MaxPayloadSize+v.ResponseSize]
case v.ResponseSize > MaxPayloadSize:
req.Payload = payload[:v.PayloadSize]
req.Response = payload[MaxPayloadSize:]
default:
req.Payload = payload[:v.PayloadSize]
req.Response = payload[MaxPayloadSize : MaxPayloadSize+v.ResponseSize]

event = Event{
Type: EventTypeL7Request,
Pid: v.Pid,
Fd: v.Fd,
Timestamp: v.ConnectionTimestamp,
L7Request: req,
}
event = Event{Type: EventTypeL7Request, Pid: v.Pid, Fd: v.Fd, Timestamp: v.ConnectionTimestamp, L7Request: req}
case perfMapTypeFileEvents:
v := &fileEvent{}
if err := binary.Read(bytes.NewBuffer(rec.RawSample), binary.LittleEndian, v); err != nil {
Expand Down