From fe6cfd90feb88199120a862046027fc36e4433ea Mon Sep 17 00:00:00 2001 From: Leonid Bugaev Date: Thu, 10 May 2018 22:19:56 +0300 Subject: [PATCH] Fix responses when header end line separated by multiple packets --- raw_socket_listener/listener.go | 6 ++---- raw_socket_listener/listener_test.go | 24 ++++++++++++------------ raw_socket_listener/tcp_message.go | 19 ++++++++++++++++--- 3 files changed, 30 insertions(+), 19 deletions(-) diff --git a/raw_socket_listener/listener.go b/raw_socket_listener/listener.go index 47a1aba..ad1e373 100644 --- a/raw_socket_listener/listener.go +++ b/raw_socket_listener/listener.go @@ -445,12 +445,12 @@ func (t *Listener) readPcap() { of = 4 case layers.LinkTypeLoop: of = 4 - case layers.LinkTypeRaw: + case layers.LinkTypeRaw, layers.LayerTypeIPv4: of = 0 case layers.LinkTypeLinuxSLL: of = 16 default: - log.Println("Unknown packet layer", packet) + log.Println("Unknown packet layer", decoder, packet) break } @@ -714,8 +714,6 @@ func (t *Listener) processTCPPacket(packet *TCPPacket) { } }() - // log.Println("PACKET:", packet, t.seqWithData) - var responseRequest *TCPMessage var message *TCPMessage diff --git a/raw_socket_listener/listener_test.go b/raw_socket_listener/listener_test.go index 988cd65..b606540 100644 --- a/raw_socket_listener/listener_test.go +++ b/raw_socket_listener/listener_test.go @@ -12,7 +12,7 @@ import ( func TestRawListenerInput(t *testing.T) { var req, resp *TCPMessage - listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "") + listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "", "") defer listener.Close() reqPacket := buildPacket(true, 1, 1, []byte("GET / HTTP/1.1\r\n\r\n"), time.Now()) @@ -77,7 +77,7 @@ func responsePacket(prev *TCPPacket, payload []byte) *TCPPacket { } func TestSingleAck100Continue(t *testing.T) { - listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "") + listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "", "") defer listener.Close() reqPacket1 := firstPacket([]byte("POST / HTTP/1.1\r\nExpect: 100-continue\r\nContent-Length: 4\r\n\r\n")) @@ -96,7 +96,7 @@ func TestSingleAck100Continue(t *testing.T) { } func Test100ContinueWithoutWaiting(t *testing.T) { - listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "") + listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "", "") defer listener.Close() req1 := firstPacket([]byte("POST / HTTP/1.1\r\nExpect: 100-continue\r\nContent-Length: 4\r\n\r\n")) @@ -112,7 +112,7 @@ func Test100ContinueWithoutWaiting(t *testing.T) { // Client first sends data without waiting 100-continue, but once response received, generate packets based on Ack payload func Test100ContinueMixed(t *testing.T) { - listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "") + listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "", "") defer listener.Close() req1 := firstPacket([]byte("POST / HTTP/1.1\r\nExpect: 100-continue\r\nContent-Length: 12\r\n\r\n")) @@ -130,7 +130,7 @@ func Test100ContinueMixed(t *testing.T) { } func TestDoubleAck100Continue(t *testing.T) { - listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "") + listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "", "") defer listener.Close() reqPacket1 := firstPacket([]byte("POST / HTTP/1.1\r\nExpect: 100-continue\r\nContent-Length: 4\r\n\r\n")) @@ -153,7 +153,7 @@ func TestDoubleAck100Continue(t *testing.T) { func TestRawListenerInputResponseByClose(t *testing.T) { var req, resp *TCPMessage - listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "") + listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "", "") defer listener.Close() reqPacket := buildPacket(true, 1, 1, []byte("GET / HTTP/1.1\r\n\r\n"), time.Now()) @@ -193,7 +193,7 @@ func TestRawListenerInputResponseByClose(t *testing.T) { func TestRawListenerInputWithoutResponse(t *testing.T) { var req *TCPMessage - listener := NewListener("", "0", EnginePcap, false, 10*time.Millisecond, "") + listener := NewListener("", "0", EnginePcap, false, 10*time.Millisecond, "", "") defer listener.Close() reqPacket := buildPacket(true, 1, 1, []byte("GET / HTTP/1.1\r\n\r\n"), time.Now()) @@ -215,7 +215,7 @@ func TestRawListenerInputWithoutResponse(t *testing.T) { func TestRawListenerResponse(t *testing.T) { var req, resp *TCPMessage - listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "") + listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "", "") defer listener.Close() reqPacket := firstPacket([]byte("GET / HTTP/1.1\r\n\r\n")) @@ -263,7 +263,7 @@ func get100ContinuePackets() (req []*TCPPacket, resp []*TCPPacket) { } func TestShort100Continue(t *testing.T) { - listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "") + listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "", "") defer listener.Close() req, resp := get100ContinuePackets() @@ -275,7 +275,7 @@ func TestShort100Continue(t *testing.T) { // Response comes before Request func Test100ContinueWrongOrder(t *testing.T) { - listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "") + listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "", "") defer listener.Close() req, resp := get100ContinuePackets() @@ -428,7 +428,7 @@ func permutation(n int, list []*TCPPacket) []*TCPPacket { // Response comes before Request func TestRawListenerChunkedWrongOrder(t *testing.T) { - listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "") + listener := NewListener("", "0", EnginePcap, true, 10*time.Millisecond, "", "") defer listener.Close() reqPacket1 := firstPacket([]byte("POST / HTTP/1.1\r\nTransfer-Encoding: chunked\r\nExpect: 100-continue\r\n\r\n")) @@ -498,7 +498,7 @@ func getMessage() []*TCPPacket { // Response comes before Request func TestRawListenerBench(t *testing.T) { - l := NewListener("", "0", EnginePcap, true, 200*time.Millisecond, "") + l := NewListener("", "0", EnginePcap, true, 200*time.Millisecond, "", "") defer l.Close() // Should re-construct message from all possible combinations diff --git a/raw_socket_listener/tcp_message.go b/raw_socket_listener/tcp_message.go index 440624c..18704bb 100644 --- a/raw_socket_listener/tcp_message.go +++ b/raw_socket_listener/tcp_message.go @@ -199,6 +199,7 @@ func (t *TCPMessage) checkSeqIntegrity() { } var bEmptyLine = []byte("\r\n\r\n") +var bBR = []byte("\r\n") var bChunkEnd = []byte("0\r\n\r\n") func (t *TCPMessage) updateHeadersPacket() { @@ -215,9 +216,16 @@ func (t *TCPMessage) updateHeadersPacket() { } for i, p := range t.packets { - if bytes.LastIndex(p.Data, bEmptyLine) != -1 { - t.headerPacket = i - return + if len(p.Data) >= len(bEmptyLine) { + if bytes.LastIndex(p.Data, bEmptyLine) != -1 { + t.headerPacket = i + return + } + } else if bytes.Equal(p.Data, bBR) { + if bytes.LastIndex(t.packets[i-1].Data, bBR) != -1 { + t.headerPacket = i + return + } } } @@ -227,18 +235,23 @@ func (t *TCPMessage) updateHeadersPacket() { // checkIfComplete returns true if all of the packets that compse the message arrived. func (t *TCPMessage) checkIfComplete() { if t.seqMissing || t.headerPacket == -1 { + // log.Println("Seq missing", t.seqMissing, t.packets) return } if t.methodType == httpMethodNotFound { + // log.Println("Method missing", t.methodType, t.packets) return } // Responses can be emitted only if we found request if !t.IsIncoming && t.AssocMessage == nil { + // log.Println("Assoc not found", t) return } + // log.Println("Found?", t) + switch t.bodyType { case httpBodyEmpty: t.complete = true