mirror of
https://github.com/buger/goreplay.git
synced 2024-04-21 12:32:02 +00:00
Skip not complete HTTP messages (#953)
Added `--input-raw-allow-incomplete` if you really need it. Fixed Bug when outpuut binary response not tracked Additionally fixed bug which prevents Gor from exiting.
This commit is contained in:
+48
-12
@@ -42,7 +42,7 @@ type Listener struct {
|
|||||||
sync.Mutex
|
sync.Mutex
|
||||||
Transport string // transport layer default to tcp
|
Transport string // transport layer default to tcp
|
||||||
Activate func() error // function is used to activate the engine. it must be called before reading packets
|
Activate func() error // function is used to activate the engine. it must be called before reading packets
|
||||||
Handles map[string]gopacket.ZeroCopyPacketDataSource
|
Handles map[string]packetHandle
|
||||||
Interfaces []pcap.Interface
|
Interfaces []pcap.Interface
|
||||||
loopIndex int
|
loopIndex int
|
||||||
Reading chan bool // this channel is closed when the listener has started reading packets
|
Reading chan bool // this channel is closed when the listener has started reading packets
|
||||||
@@ -57,6 +57,11 @@ type Listener struct {
|
|||||||
quit chan struct{}
|
quit chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type packetHandle struct {
|
||||||
|
handler gopacket.ZeroCopyPacketDataSource
|
||||||
|
ips []net.IP
|
||||||
|
}
|
||||||
|
|
||||||
// EngineType ...
|
// EngineType ...
|
||||||
type EngineType uint8
|
type EngineType uint8
|
||||||
|
|
||||||
@@ -117,7 +122,7 @@ func NewListener(host string, ports []uint16, transport string, engine EngineTyp
|
|||||||
if transport != "" {
|
if transport != "" {
|
||||||
l.Transport = transport
|
l.Transport = transport
|
||||||
}
|
}
|
||||||
l.Handles = make(map[string]gopacket.ZeroCopyPacketDataSource)
|
l.Handles = make(map[string]packetHandle)
|
||||||
l.trackResponse = trackResponse
|
l.trackResponse = trackResponse
|
||||||
l.closeDone = make(chan struct{})
|
l.closeDone = make(chan struct{})
|
||||||
l.quit = make(chan struct{})
|
l.quit = make(chan struct{})
|
||||||
@@ -312,12 +317,12 @@ func (l *Listener) read(handler PacketHandler) {
|
|||||||
l.Lock()
|
l.Lock()
|
||||||
defer l.Unlock()
|
defer l.Unlock()
|
||||||
for key, handle := range l.Handles {
|
for key, handle := range l.Handles {
|
||||||
go func(key string, hndl gopacket.ZeroCopyPacketDataSource) {
|
go func(key string, hndl packetHandle) {
|
||||||
defer l.closeHandles(key)
|
defer l.closeHandles(key)
|
||||||
linkSize := 14
|
linkSize := 14
|
||||||
linkType := int(layers.LinkTypeEthernet)
|
linkType := int(layers.LinkTypeEthernet)
|
||||||
if _, ok := hndl.(*pcap.Handle); ok {
|
if _, ok := hndl.handler.(*pcap.Handle); ok {
|
||||||
linkType = int(hndl.(*pcap.Handle).LinkType())
|
linkType = int(hndl.handler.(*pcap.Handle).LinkType())
|
||||||
linkSize, ok = pcapLinkTypeLength(linkType)
|
linkSize, ok = pcapLinkTypeLength(linkType)
|
||||||
if !ok {
|
if !ok {
|
||||||
if os.Getenv("GORDEBUG") != "0" {
|
if os.Getenv("GORDEBUG") != "0" {
|
||||||
@@ -332,10 +337,22 @@ func (l *Listener) read(handler PacketHandler) {
|
|||||||
case <-l.quit:
|
case <-l.quit:
|
||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
data, ci, err := hndl.ZeroCopyReadPacketData()
|
data, ci, err := hndl.handler.ZeroCopyReadPacketData()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
pckt, err := tcp.ParsePacket(data, linkType, linkSize, &ci)
|
pckt, err := tcp.ParsePacket(data, linkType, linkSize, &ci, false)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
for _, p := range l.ports {
|
||||||
|
if pckt.DstPort == p {
|
||||||
|
for _, ip := range hndl.ips {
|
||||||
|
if pckt.DstIP.Equal(ip) {
|
||||||
|
pckt.Incoming = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
handler(pckt)
|
handler(pckt)
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
@@ -367,7 +384,7 @@ func (l *Listener) closeHandles(key string) {
|
|||||||
l.Lock()
|
l.Lock()
|
||||||
defer l.Unlock()
|
defer l.Unlock()
|
||||||
if handle, ok := l.Handles[key]; ok {
|
if handle, ok := l.Handles[key]; ok {
|
||||||
if c, ok := handle.(io.Closer); ok {
|
if c, ok := handle.handler.(io.Closer); ok {
|
||||||
c.Close()
|
c.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -388,7 +405,10 @@ func (l *Listener) activatePcap() error {
|
|||||||
msg += ("\n" + e.Error())
|
msg += ("\n" + e.Error())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
l.Handles[ifi.Name] = handle
|
l.Handles[ifi.Name] = packetHandle{
|
||||||
|
handler: handle,
|
||||||
|
ips: interfaceIPs(ifi),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if len(l.Handles) == 0 {
|
if len(l.Handles) == 0 {
|
||||||
return fmt.Errorf("pcap handles error:%s", msg)
|
return fmt.Errorf("pcap handles error:%s", msg)
|
||||||
@@ -409,7 +429,10 @@ func (l *Listener) activateRawSocket() error {
|
|||||||
msg += ("\n" + e.Error())
|
msg += ("\n" + e.Error())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
l.Handles[ifi.Name] = handle
|
l.Handles[ifi.Name] = packetHandle{
|
||||||
|
handler: handle,
|
||||||
|
ips: interfaceIPs(ifi),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if len(l.Handles) == 0 {
|
if len(l.Handles) == 0 {
|
||||||
return fmt.Errorf("raw socket handles error:%s", msg)
|
return fmt.Errorf("raw socket handles error:%s", msg)
|
||||||
@@ -433,7 +456,9 @@ func (l *Listener) activatePcapFile() (err error) {
|
|||||||
handle.Close()
|
handle.Close()
|
||||||
return fmt.Errorf("BPF filter error: %q, filter: %s", e, l.BPFFilter)
|
return fmt.Errorf("BPF filter error: %q, filter: %s", e, l.BPFFilter)
|
||||||
}
|
}
|
||||||
l.Handles["pcap_file"] = handle
|
l.Handles["pcap_file"] = packetHandle{
|
||||||
|
handler: handle,
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -456,7 +481,10 @@ func (l *Listener) activateAFPacket() error {
|
|||||||
fmt.Println("Interface:", ifi.Name, ". BPF Filter:", l.BPFFilter)
|
fmt.Println("Interface:", ifi.Name, ". BPF Filter:", l.BPFFilter)
|
||||||
handle.SetBPFFilter(l.BPFFilter, 64<<10)
|
handle.SetBPFFilter(l.BPFFilter, 64<<10)
|
||||||
|
|
||||||
l.Handles[ifi.Name] = handle
|
l.Handles[ifi.Name] = packetHandle{
|
||||||
|
handler: handle,
|
||||||
|
ips: interfaceIPs(ifi),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(l.Handles) == 0 {
|
if len(l.Handles) == 0 {
|
||||||
@@ -524,6 +552,14 @@ func interfaceAddresses(ifi pcap.Interface) []string {
|
|||||||
return hosts
|
return hosts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func interfaceIPs(ifi pcap.Interface) []net.IP {
|
||||||
|
var ips []net.IP
|
||||||
|
for _, addr := range ifi.Addresses {
|
||||||
|
ips = append(ips, addr.IP)
|
||||||
|
}
|
||||||
|
return ips
|
||||||
|
}
|
||||||
|
|
||||||
func listenAll(addr string) bool {
|
func listenAll(addr string) bool {
|
||||||
switch addr {
|
switch addr {
|
||||||
case "", "0.0.0.0", "[::]", "::":
|
case "", "0.0.0.0", "[::]", "::":
|
||||||
|
|||||||
+13
-13
@@ -53,16 +53,17 @@ func (protocol *TCPProtocol) String() string {
|
|||||||
// RAWInputConfig represents configuration that can be applied on raw input
|
// RAWInputConfig represents configuration that can be applied on raw input
|
||||||
type RAWInputConfig struct {
|
type RAWInputConfig struct {
|
||||||
capture.PcapOptions
|
capture.PcapOptions
|
||||||
Expire time.Duration `json:"input-raw-expire"`
|
Expire time.Duration `json:"input-raw-expire"`
|
||||||
CopyBufferSize size.Size `json:"copy-buffer-size"`
|
CopyBufferSize size.Size `json:"copy-buffer-size"`
|
||||||
Engine capture.EngineType `json:"input-raw-engine"`
|
Engine capture.EngineType `json:"input-raw-engine"`
|
||||||
TrackResponse bool `json:"input-raw-track-response"`
|
TrackResponse bool `json:"input-raw-track-response"`
|
||||||
Protocol TCPProtocol `json:"input-raw-protocol"`
|
Protocol TCPProtocol `json:"input-raw-protocol"`
|
||||||
RealIPHeader string `json:"input-raw-realip-header"`
|
RealIPHeader string `json:"input-raw-realip-header"`
|
||||||
Stats bool `json:"input-raw-stats"`
|
Stats bool `json:"input-raw-stats"`
|
||||||
quit chan bool // Channel used only to indicate goroutine should shutdown
|
AllowIncomplete bool `json:"input-raw-allow-incomplete"`
|
||||||
host string
|
quit chan bool // Channel used only to indicate goroutine should shutdown
|
||||||
ports []uint16
|
host string
|
||||||
|
ports []uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
// RAWInput used for intercepting traffic for given address
|
// RAWInput used for intercepting traffic for given address
|
||||||
@@ -116,8 +117,7 @@ func (i *RAWInput) PluginRead() (*Message, error) {
|
|||||||
select {
|
select {
|
||||||
case <-i.quit:
|
case <-i.quit:
|
||||||
return nil, ErrorStopped
|
return nil, ErrorStopped
|
||||||
default:
|
case msgTCP = <-i.messageParser.Messages():
|
||||||
msgTCP = i.messageParser.Read()
|
|
||||||
msg.Data = msgTCP.Data()
|
msg.Data = msgTCP.Data()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,7 +158,7 @@ func (i *RAWInput) listen(address string) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
i.messageParser = tcp.NewMessageParser(i.CopyBufferSize, i.Expire, Debug)
|
i.messageParser = tcp.NewMessageParser(i.CopyBufferSize, i.Expire, i.AllowIncomplete, Debug)
|
||||||
|
|
||||||
if i.Protocol == ProtocolHTTP {
|
if i.Protocol == ProtocolHTTP {
|
||||||
i.messageParser.Start = http1StartHint
|
i.messageParser.Start = http1StartHint
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ func TestRAWInputIPv4(t *testing.T) {
|
|||||||
} else {
|
} else {
|
||||||
respCounter++
|
respCounter++
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.Done()
|
wg.Done()
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -71,14 +72,18 @@ func TestRAWInputIPv4(t *testing.T) {
|
|||||||
emitter := NewEmitter()
|
emitter := NewEmitter()
|
||||||
defer emitter.Close()
|
defer emitter.Close()
|
||||||
go emitter.Start(plugins, Settings.Middleware)
|
go emitter.Start(plugins, Settings.Middleware)
|
||||||
|
|
||||||
|
// time.Sleep(time.Second)
|
||||||
for i := 0; i < 1; i++ {
|
for i := 0; i < 1; i++ {
|
||||||
wg.Add(2)
|
wg.Add(2)
|
||||||
_, err = http.Get(addr)
|
_, err = http.Get(addr)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
const want = 10
|
const want = 10
|
||||||
if reqCounter != respCounter && reqCounter != want {
|
if reqCounter != respCounter && reqCounter != want {
|
||||||
|
|||||||
@@ -141,6 +141,7 @@ func init() {
|
|||||||
flag.BoolVar(&Settings.Promiscuous, "input-raw-promisc", false, "enable promiscuous mode")
|
flag.BoolVar(&Settings.Promiscuous, "input-raw-promisc", false, "enable promiscuous mode")
|
||||||
flag.BoolVar(&Settings.Monitor, "input-raw-monitor", false, "enable RF monitor mode")
|
flag.BoolVar(&Settings.Monitor, "input-raw-monitor", false, "enable RF monitor mode")
|
||||||
flag.BoolVar(&Settings.Stats, "input-raw-stats", false, "enable stats generator on raw TCP messages")
|
flag.BoolVar(&Settings.Stats, "input-raw-stats", false, "enable stats generator on raw TCP messages")
|
||||||
|
flag.BoolVar(&Settings.AllowIncomplete, "input-raw-allow-incomplete", false, "If turned on Gor will record HTTP messages with missing packets")
|
||||||
|
|
||||||
flag.StringVar(&Settings.Middleware, "middleware", "", "Used for modifying traffic using external command")
|
flag.StringVar(&Settings.Middleware, "middleware", "", "Used for modifying traffic using external command")
|
||||||
|
|
||||||
|
|||||||
+37
-21
@@ -184,23 +184,27 @@ type MessageParser struct {
|
|||||||
maxSize size.Size // maximum message size, default 5mb
|
maxSize size.Size // maximum message size, default 5mb
|
||||||
m map[uint64]*Message
|
m map[uint64]*Message
|
||||||
|
|
||||||
messageExpire time.Duration // the maximum time to wait for the final packet, minimum is 100ms
|
messageExpire time.Duration // the maximum time to wait for the final packet, minimum is 100ms
|
||||||
End HintEnd
|
allowIncompete bool
|
||||||
Start HintStart
|
End HintEnd
|
||||||
ticker *time.Ticker
|
Start HintStart
|
||||||
messages chan *Message
|
ticker *time.Ticker
|
||||||
packets chan *Packet
|
messages chan *Message
|
||||||
close chan struct{} // to signal that we are able to close
|
packets chan *Packet
|
||||||
|
close chan struct{} // to signal that we are able to close
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewMessageParser returns a new instance of message parser
|
// NewMessageParser returns a new instance of message parser
|
||||||
func NewMessageParser(maxSize size.Size, messageExpire time.Duration, debugger Debugger) (parser *MessageParser) {
|
func NewMessageParser(maxSize size.Size, messageExpire time.Duration, allowIncompete bool, debugger Debugger) (parser *MessageParser) {
|
||||||
parser = new(MessageParser)
|
parser = new(MessageParser)
|
||||||
parser.debug = debugger
|
parser.debug = debugger
|
||||||
parser.messageExpire = time.Millisecond * 100
|
|
||||||
if parser.messageExpire < messageExpire {
|
parser.messageExpire = messageExpire
|
||||||
parser.messageExpire = messageExpire
|
if parser.messageExpire == 0 {
|
||||||
|
parser.messageExpire = time.Millisecond * 500
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parser.allowIncompete = allowIncompete
|
||||||
parser.maxSize = maxSize
|
parser.maxSize = maxSize
|
||||||
if parser.maxSize < 1 {
|
if parser.maxSize < 1 {
|
||||||
parser.maxSize = 5 << 20
|
parser.maxSize = 5 << 20
|
||||||
@@ -224,8 +228,6 @@ func (parser *MessageParser) PacketHandler(packet *Packet) {
|
|||||||
parser.packets <- packet
|
parser.packets <- packet
|
||||||
}
|
}
|
||||||
|
|
||||||
var processedPackets int
|
|
||||||
|
|
||||||
func (parser *MessageParser) wait() {
|
func (parser *MessageParser) wait() {
|
||||||
var (
|
var (
|
||||||
now time.Time
|
now time.Time
|
||||||
@@ -271,6 +273,8 @@ func (parser *MessageParser) processPacket(pckt *Packet) {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
in = pckt.Incoming
|
||||||
}
|
}
|
||||||
|
|
||||||
m = new(Message)
|
m = new(Message)
|
||||||
@@ -288,16 +292,18 @@ func (parser *MessageParser) addPacket(m *Message, pckt *Packet) {
|
|||||||
pckt.Payload = pckt.Payload[:int(parser.maxSize)-m.Length]
|
pckt.Payload = pckt.Payload[:int(parser.maxSize)-m.Length]
|
||||||
}
|
}
|
||||||
m.add(pckt)
|
m.add(pckt)
|
||||||
switch {
|
|
||||||
// if one of this cases matches, we dispatch the message
|
if trunc > 0 {
|
||||||
case trunc >= 0:
|
|
||||||
case parser.End != nil && parser.End(m):
|
|
||||||
default:
|
|
||||||
// continue to receive packets
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
parser.Emit(m)
|
// If we are using protocol parsing, like HTTP, depend on its parsing func.
|
||||||
|
// For the binary procols wait for message to expire
|
||||||
|
if parser.End != nil {
|
||||||
|
if parser.End(m) {
|
||||||
|
parser.Emit(m)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (parser *MessageParser) Read() *Message {
|
func (parser *MessageParser) Read() *Message {
|
||||||
@@ -305,6 +311,10 @@ func (parser *MessageParser) Read() *Message {
|
|||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (parser *MessageParser) Messages() chan *Message {
|
||||||
|
return parser.messages
|
||||||
|
}
|
||||||
|
|
||||||
func (parser *MessageParser) Emit(m *Message) {
|
func (parser *MessageParser) Emit(m *Message) {
|
||||||
delete(parser.m, m.packets[0].MessageID())
|
delete(parser.m, m.packets[0].MessageID())
|
||||||
|
|
||||||
@@ -321,7 +331,13 @@ func (parser *MessageParser) timer(now time.Time) {
|
|||||||
for _, m := range parser.m {
|
for _, m := range parser.m {
|
||||||
if now.Sub(m.End) > parser.messageExpire {
|
if now.Sub(m.End) > parser.messageExpire {
|
||||||
m.TimedOut = true
|
m.TimedOut = true
|
||||||
parser.Emit(m)
|
if parser.End == nil || parser.allowIncompete {
|
||||||
|
parser.Emit(m)
|
||||||
|
} else {
|
||||||
|
// Just remove
|
||||||
|
delete(parser.m, m.packets[0].MessageID())
|
||||||
|
m.Finalize()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-4
@@ -58,6 +58,7 @@ calllers must make sure that ParsePacket has'nt returned any error before callin
|
|||||||
function.
|
function.
|
||||||
*/
|
*/
|
||||||
type Packet struct {
|
type Packet struct {
|
||||||
|
Incoming bool
|
||||||
messageID uint64
|
messageID uint64
|
||||||
SrcIP, DstIP net.IP
|
SrcIP, DstIP net.IP
|
||||||
Version uint8
|
Version uint8
|
||||||
@@ -72,9 +73,9 @@ type Packet struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ParsePacket parse raw packets
|
// ParsePacket parse raw packets
|
||||||
func ParsePacket(data []byte, lType, lTypeLen int, cp *gopacket.CaptureInfo) (pckt *Packet, err error) {
|
func ParsePacket(data []byte, lType, lTypeLen int, cp *gopacket.CaptureInfo, allowEmpty bool) (pckt *Packet, err error) {
|
||||||
pckt = packetPool.Get()
|
pckt = packetPool.Get()
|
||||||
if err := pckt.parse(data, lType, lTypeLen, cp); err != nil {
|
if err := pckt.parse(data, lType, lTypeLen, cp, allowEmpty); err != nil {
|
||||||
packetPool.Put(pckt)
|
packetPool.Put(pckt)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -82,7 +83,7 @@ func ParsePacket(data []byte, lType, lTypeLen int, cp *gopacket.CaptureInfo) (pc
|
|||||||
return pckt, nil
|
return pckt, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pckt *Packet) parse(data []byte, lType, lTypeLen int, cp *gopacket.CaptureInfo) error {
|
func (pckt *Packet) parse(data []byte, lType, lTypeLen int, cp *gopacket.CaptureInfo, allowEmpty bool) error {
|
||||||
pckt.Retry = 0
|
pckt.Retry = 0
|
||||||
pckt.messageID = 0
|
pckt.messageID = 0
|
||||||
|
|
||||||
@@ -158,7 +159,7 @@ func (pckt *Packet) parse(data []byte, lType, lTypeLen int, cp *gopacket.Capture
|
|||||||
return ErrHdrLength("TCP opts")
|
return ErrHdrLength("TCP opts")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(ndata[dOf:]) == 0 {
|
if !allowEmpty && len(ndata[dOf:]) == 0 {
|
||||||
return EmptyPacket("")
|
return EmptyPacket("")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+19
-37
@@ -43,14 +43,15 @@ func generateHeader(request bool, seq uint32, length uint16) []byte {
|
|||||||
|
|
||||||
func GetPackets(request bool, start uint32, _len int, payload []byte) []*Packet {
|
func GetPackets(request bool, start uint32, _len int, payload []byte) []*Packet {
|
||||||
var packets = make([]*Packet, _len)
|
var packets = make([]*Packet, _len)
|
||||||
|
var err error
|
||||||
for i := start; i < start+uint32(_len); i++ {
|
for i := start; i < start+uint32(_len); i++ {
|
||||||
d := append(generateHeader(request, i, uint16(len(payload))), payload...)
|
d := append(generateHeader(request, i, uint16(len(payload))), payload...)
|
||||||
ci := &gopacket.CaptureInfo{Length: len(d), CaptureLength: len(d), Timestamp: time.Now()}
|
ci := &gopacket.CaptureInfo{Length: len(d), CaptureLength: len(d), Timestamp: time.Now()}
|
||||||
|
|
||||||
if len(payload) > 0 {
|
packets[i-start], err = ParsePacket(d, int(layers.LinkTypeLoop), 4, ci, true)
|
||||||
packets[i-start], _ = ParsePacket(d, int(layers.LinkTypeLoop), 4, ci)
|
packets[i-start].Incoming = request
|
||||||
} else {
|
if err != nil {
|
||||||
packets[i-start] = new(Packet)
|
panic(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return packets
|
return packets
|
||||||
@@ -74,7 +75,7 @@ func TestRequestResponseMapping(t *testing.T) {
|
|||||||
{SrcPort: 80, DstPort: 60000, Ack: 71, Seq: 56, Timestamp: time.Unix(8, 0), Payload: []byte("Content-Length: 0\r\n\r\n")},
|
{SrcPort: 80, DstPort: 60000, Ack: 71, Seq: 56, Timestamp: time.Unix(8, 0), Payload: []byte("Content-Length: 0\r\n\r\n")},
|
||||||
}
|
}
|
||||||
|
|
||||||
parser := NewMessageParser(1<<20, time.Second, nil)
|
parser := NewMessageParser(1<<20, time.Second, false, nil)
|
||||||
parser.Start = func(pckt *Packet) (bool, bool) {
|
parser.Start = func(pckt *Packet) (bool, bool) {
|
||||||
return proto.HasRequestTitle(pckt.Payload), proto.HasResponseTitle(pckt.Payload)
|
return proto.HasRequestTitle(pckt.Payload), proto.HasResponseTitle(pckt.Payload)
|
||||||
}
|
}
|
||||||
@@ -104,7 +105,7 @@ func TestRequestResponseMapping(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMessageParserWithHint(t *testing.T) {
|
func TestMessageParserWithHint(t *testing.T) {
|
||||||
parser := NewMessageParser(1<<20, time.Second, nil)
|
parser := NewMessageParser(1<<20, time.Second, false, nil)
|
||||||
parser.Start = func(pckt *Packet) (bool, bool) {
|
parser.Start = func(pckt *Packet) (bool, bool) {
|
||||||
return proto.HasRequestTitle(pckt.Payload), proto.HasResponseTitle(pckt.Payload)
|
return proto.HasRequestTitle(pckt.Payload), proto.HasResponseTitle(pckt.Payload)
|
||||||
}
|
}
|
||||||
@@ -144,7 +145,7 @@ func TestMessageParserWithHint(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMessageParserWrongOrder(t *testing.T) {
|
func TestMessageParserWrongOrder(t *testing.T) {
|
||||||
parser := NewMessageParser(1<<20, time.Second, nil)
|
parser := NewMessageParser(1<<20, time.Second, true, nil)
|
||||||
parser.Start = func(pckt *Packet) (bool, bool) {
|
parser.Start = func(pckt *Packet) (bool, bool) {
|
||||||
return proto.HasRequestTitle(pckt.Payload), proto.HasResponseTitle(pckt.Payload)
|
return proto.HasRequestTitle(pckt.Payload), proto.HasResponseTitle(pckt.Payload)
|
||||||
}
|
}
|
||||||
@@ -183,7 +184,7 @@ func TestMessageParserWithoutHint(t *testing.T) {
|
|||||||
var data [63 << 10]byte
|
var data [63 << 10]byte
|
||||||
packets := GetPackets(true, 1, 10, data[:])
|
packets := GetPackets(true, 1, 10, data[:])
|
||||||
|
|
||||||
p := NewMessageParser(63<<10*10, time.Second, nil)
|
p := NewMessageParser(63<<10*10, time.Second, false, nil)
|
||||||
for _, v := range packets {
|
for _, v := range packets {
|
||||||
p.PacketHandler(v)
|
p.PacketHandler(v)
|
||||||
}
|
}
|
||||||
@@ -197,12 +198,14 @@ func TestMessageParserWithoutHint(t *testing.T) {
|
|||||||
func TestMessageMaxSizeReached(t *testing.T) {
|
func TestMessageMaxSizeReached(t *testing.T) {
|
||||||
var data [63 << 10]byte
|
var data [63 << 10]byte
|
||||||
packets := GetPackets(true, 1, 2, data[:])
|
packets := GetPackets(true, 1, 2, data[:])
|
||||||
packets = append(packets, GetPackets(true, 1, 1, make([]byte, 63<<10+10))...)
|
packets = append(packets, GetPackets(false, 1, 1, make([]byte, 63<<10+10))...)
|
||||||
|
|
||||||
p := NewMessageParser(63<<10+10, time.Second, nil)
|
p := NewMessageParser(63<<10+10, time.Millisecond, false, nil)
|
||||||
for _, v := range packets {
|
for _, v := range packets {
|
||||||
p.PacketHandler(v)
|
p.PacketHandler(v)
|
||||||
}
|
}
|
||||||
|
time.Sleep(10 * time.Millisecond)
|
||||||
|
|
||||||
m := p.Read()
|
m := p.Read()
|
||||||
if m.Length != 63<<10+10 {
|
if m.Length != 63<<10+10 {
|
||||||
t.Errorf("expected %d to equal %d", m.Length, 63<<10+10)
|
t.Errorf("expected %d to equal %d", m.Length, 63<<10+10)
|
||||||
@@ -224,9 +227,9 @@ func TestMessageMaxSizeReached(t *testing.T) {
|
|||||||
func TestMessageTimeoutReached(t *testing.T) {
|
func TestMessageTimeoutReached(t *testing.T) {
|
||||||
var data [63 << 10]byte
|
var data [63 << 10]byte
|
||||||
packets := GetPackets(true, 1, 2, data[:])
|
packets := GetPackets(true, 1, 2, data[:])
|
||||||
p := NewMessageParser(1<<20, 0, nil)
|
p := NewMessageParser(1<<20, 10*time.Millisecond, true, nil)
|
||||||
p.PacketHandler(packets[0])
|
p.PacketHandler(packets[0])
|
||||||
time.Sleep(time.Millisecond * 400)
|
time.Sleep(time.Millisecond * 50)
|
||||||
p.PacketHandler(packets[1])
|
p.PacketHandler(packets[1])
|
||||||
m := p.Read()
|
m := p.Read()
|
||||||
if m.Length != 63<<10 {
|
if m.Length != 63<<10 {
|
||||||
@@ -237,32 +240,11 @@ func TestMessageTimeoutReached(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMessageUUID(t *testing.T) {
|
|
||||||
packets := GetPackets(true, 1, 10, nil)
|
|
||||||
|
|
||||||
var uuid, uuid1 []byte
|
|
||||||
parser := NewMessageParser(0, 0, nil)
|
|
||||||
|
|
||||||
for _, p := range packets {
|
|
||||||
parser.PacketHandler(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
m := parser.Read()
|
|
||||||
uuid = m.UUID()
|
|
||||||
|
|
||||||
m = parser.Read()
|
|
||||||
uuid1 = m.UUID()
|
|
||||||
|
|
||||||
if string(uuid) != string(uuid1) {
|
|
||||||
t.Errorf("expected %s, to equal %s", uuid, uuid1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkMessageUUID(b *testing.B) {
|
func BenchmarkMessageUUID(b *testing.B) {
|
||||||
packets := GetPackets(true, 1, 5, nil)
|
packets := GetPackets(true, 1, 5, nil)
|
||||||
|
|
||||||
var uuid []byte
|
var uuid []byte
|
||||||
parser := NewMessageParser(0, 0, nil)
|
parser := NewMessageParser(0, 0, false, nil)
|
||||||
for _, p := range packets {
|
for _, p := range packets {
|
||||||
parser.PacketHandler(p)
|
parser.PacketHandler(p)
|
||||||
}
|
}
|
||||||
@@ -291,7 +273,7 @@ func BenchmarkPacketParseAndSort(b *testing.B) {
|
|||||||
func BenchmarkMessageParserWithoutHint(b *testing.B) {
|
func BenchmarkMessageParserWithoutHint(b *testing.B) {
|
||||||
var chunk = []byte("111111111111111111111111111111")
|
var chunk = []byte("111111111111111111111111111111")
|
||||||
packets := GetPackets(true, 1, 1000, chunk)
|
packets := GetPackets(true, 1, 1000, chunk)
|
||||||
p := NewMessageParser(1<<20, time.Second*2, nil)
|
p := NewMessageParser(1<<20, time.Second*2, false, nil)
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
b.ReportMetric(float64(1000), "packets/op")
|
b.ReportMetric(float64(1000), "packets/op")
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
@@ -315,7 +297,7 @@ func BenchmarkMessageParserWithHint(b *testing.B) {
|
|||||||
packets[i] = GetPackets(false, 1, 1, buf[i])[0]
|
packets[i] = GetPackets(false, 1, 1, buf[i])[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
parser := NewMessageParser(1<<30, time.Second*10, nil)
|
parser := NewMessageParser(1<<30, time.Second*10, false, nil)
|
||||||
parser.Start = func(pckt *Packet) (bool, bool) {
|
parser.Start = func(pckt *Packet) (bool, bool) {
|
||||||
return false, proto.HasResponseTitle(pckt.Payload)
|
return false, proto.HasResponseTitle(pckt.Payload)
|
||||||
}
|
}
|
||||||
@@ -337,6 +319,6 @@ func BenchmarkNewAndParsePacket(b *testing.B) {
|
|||||||
data := append(generateHeader(true, 1024, 10), make([]byte, 10)...)
|
data := append(generateHeader(true, 1024, 10), make([]byte, 10)...)
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
ParsePacket(data, int(layers.LinkTypeLoop), 4, &gopacket.CaptureInfo{})
|
ParsePacket(data, int(layers.LinkTypeLoop), 4, &gopacket.CaptureInfo{}, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user