google / google/gopacket

High memory usage in reaseembly and tcpreassembly

Open
#444 8 comments 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
6.8k
Forks
1.2k
PR merge metrics
No merged PRs in 30d

Description

I wrote a small program for the tcpreassembly test and started traffic over FTP (ftp inside a gigabit LAN). On ftp uploaded 1 file (iso image 533 megabytes). As a result, the amount of memory used increased 78612 kb to 877 megabytes. If I upload iso a second time, then memory will grow to 1664 megabytes.

The test and reassembly package and the tcpreassembly package are the same result.

If you comment assembler.Assemble, the memory consumption becomes normal. Those. the problem is where it is in reassembly

Any idea why this happens?

```
package main

import (
"github.com/google/gopacket/reassembly"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"log"
"github.com/google/gopacket/afpacket"
)

type NullStream struct {
}

func (d *NullStream) Accept(tcp *layers.TCP, ci gopacket.CaptureInfo, dir reassembly.TCPFlowDirection, ackSeq reassembly.Sequence, start *bool, ac reassembly.AssemblerContext) bool {
return true
}

func (d *NullStream) ReassembledSG(sg reassembly.ScatterGather, ac reassembly.AssemblerContext) {
}

func (d *NullStream) ReassemblyComplete(ac reassembly.AssemblerContext) bool {
return true
}

type myFactory struct {
}

func (h *myFactory) New(netFlow, tcpFlow gopacket.Flow, tcp *layers.TCP, ac reassembly.AssemblerContext) reassembly.Stream {
return &NullStream{}
}

func main() {
inputAFpacket, err := afpacket.NewTPacket(afpacket.OptInterface("enp1s0"))
if err != nil {
log.Fatal(err)
}
defer inputAFpacket.Close()

streamFactory := &myFactory{}
streamPool := reassembly.NewStreamPool(streamFactory)
assembler := reassembly.NewAssembler(streamPool)

for {
pkt, _, err := inputAFpacket.ZeroCopyReadPacketData()
if err != nil {
log.Fatal(err)
}

packet := gopacket.NewPacket(pkt, layers.LayerTypeEthernet, gopacket.NoCopy)
if packet.NetworkLayer() == nil || packet.TransportLayer() == nil || packet.TransportLayer().LayerType() != layers.LayerTypeTCP {
continue
}

tcp, ok := packet.TransportLayer().(*layers.TCP)
if !ok {
continue
}

assembler.Assemble(packet.NetworkLayer().NetworkFlow(), tcp)
}
}
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.