Fix responses when header end line separated by multiple packets

This commit is contained in:
Leonid Bugaev
2018-05-10 22:19:56 +03:00
parent c9fe4a11ad
commit fe6cfd90fe
3 changed files with 30 additions and 19 deletions
+2 -4
View File
@@ -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
+12 -12
View File
@@ -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
+16 -3
View File
@@ -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