More fixes

This commit is contained in:
Leonid Bugaev
2016-05-11 13:16:05 +05:00
parent 7ee06e84f4
commit 2bc441e0be
6 changed files with 78 additions and 27 deletions
+1 -1
View File
@@ -29,7 +29,7 @@ test:
$(RUN) go test ./. -timeout 30s $(ARGS) -v
test_all:
$(RUN) go test ./... -timeout 30s $(ARGS) -v
$(RUN) go test ./... -timeout 60s $(ARGS) -v
testone:
$(RUN) go test ./... -timeout 4s -run $(TEST) $(ARGS) -v
+31 -20
View File
@@ -146,17 +146,28 @@ func (t *Listener) listen() {
}
}
func (t *Listener) deleteMessage(message *TCPMessage) {
delete(t.messages, message.ID())
delete(t.ackAliases, message.Ack)
if message.DataAck != 0 {
delete(t.ackAliases, message.DataAck)
}
if message.DataSeq != 0 {
delete(t.seqWithData, message.DataSeq)
}
delete(t.respAliases, message.ResponseAck)
}
func (t *Listener) dispatchMessage(message *TCPMessage) {
// If already dispatched
if _, ok := t.messages[message.ID()]; !ok {
return
}
delete(t.ackAliases, message.Ack)
delete(t.messages, message.ID())
delete(t.respAliases, message.ResponseAck)
t.deleteMessage(message)
// log.Println("Dispatching, message", message.Seq, message.Ack, string(message.Bytes()))
log.Println("Dispatching, message", message.Seq, message.Ack, message.RequestAck, string(message.Bytes()))
if message.IsIncoming {
// If there were response before request
@@ -375,7 +386,7 @@ func (t *Listener) processTCPPacket(packet *TCPPacket) {
}
}()
// log.Println("Processing packet:", packet.Ack, packet.Seq, string(packet.Data))
// log.Println("Processing packet:", packet.Ack, packet.Seq, packet.ID)
var message *TCPMessage
@@ -383,28 +394,26 @@ func (t *Listener) processTCPPacket(packet *TCPPacket) {
// Seek for 100-expect chunks
if parentAck, ok := t.seqWithData[packet.Seq]; ok {
// log.Println("Found data package with Ack:", packet.Ack)
// In case if non-first data chunks comes first
for _id, m := range t.messages {
// log.Println("Message ack:", m.Ack, m.packets[0].Addr, packet.Addr)
for _, m := range t.messages {
if m.Ack == packet.Ack && bytes.Equal(m.packets[0].Addr, packet.Addr) {
delete(t.messages, _id)
t.deleteMessage(m)
for _, pkt := range m.packets {
pkt.Ack = parentAck
// log.Println("Updating ack", parentAck, pkt.Ack)
pkt.UpdateAck(parentAck)
// Re-queue this packets
t.processTCPPacket(pkt)
}
}
}
delete(t.seqWithData, packet.Seq)
t.ackAliases[packet.Ack] = parentAck
packet.Ack = parentAck
packet.UpdateAck(parentAck)
}
if alias, ok := t.ackAliases[packet.Ack]; ok {
packet.Ack = alias
packet.UpdateAck(alias)
}
var responseRequest *request
@@ -430,25 +439,28 @@ func (t *Listener) processTCPPacket(packet *TCPPacket) {
}
}
// Adding packet to message
message.AddPacket(packet)
// Handling Expect: 100-continue requests
if len(packet.Data) > 4 && bytes.Equal(packet.Data[0:4], bPOST) {
// reading last 20 bytes (not counting CRLF): last header value (if no body presented)
if bytes.Equal(packet.Data[len(packet.Data)-24:len(packet.Data)-4], bExpect100ContinueCheck) {
seq := packet.Seq + uint32(len(packet.Data))
t.seqWithData[seq] = packet.Ack
message.DataSeq = seq
// In case if sequence packet came first
// log.Println("Looking for sequences:", seq, t.messages)
for _id, m := range t.messages {
// log.Println("SeqSEQ", m.Seq, len(m.packets))
for _, m := range t.messages {
if m.Seq == seq {
t.deleteMessage(m)
// log.Println("2: Adding ack alias:", m.Ack, packet.Ack)
t.ackAliases[m.Ack] = packet.Ack
for _, pkt := range m.packets {
pkt.UpdateAck(packet.Ack)
message.AddPacket(pkt)
}
delete(t.messages, _id)
}
}
@@ -459,8 +471,7 @@ func (t *Listener) processTCPPacket(packet *TCPPacket) {
}
}
// Adding packet to message
message.AddPacket(packet)
// log.Println("Received message:", string(message.Bytes()), message.ID(), t.messages)
if isIncoming {
// If message have multiple packets, delete previous alias
+26 -3
View File
@@ -203,7 +203,7 @@ func testChunkedSequence(t *testing.T, listener *Listener, packets ...*TCPPacket
var r, req, resp *TCPMessage
for _, p := range packets {
listener.processTCPPacket(p)
listener.packetsChan <- p.Dump()
}
select {
@@ -255,10 +255,26 @@ func testChunkedSequence(t *testing.T, listener *Listener, packets ...*TCPPacket
t.Error("Resp and Req UUID should be equal", string(resp.UUID()), string(req.UUID()))
}
time.Sleep(15 * time.Millisecond)
time.Sleep(20 * time.Millisecond)
if len(listener.messages) != 0 {
t.Error("Messages non empty:", listener.messages)
t.Fatal("Messages non empty:", listener.messages)
}
if len(listener.ackAliases) != 0 {
t.Fatal("ackAliases non empty:", listener.ackAliases)
}
if len(listener.seqWithData) != 0 {
t.Fatal("seqWithData non empty:", listener.seqWithData)
}
if len(listener.respAliases) != 0 {
t.Fatal("respAliases non empty:", listener.respAliases)
}
if len(listener.respWithoutReq) != 0 {
t.Fatal("respWithoutReq non empty:", listener.respWithoutReq)
}
}
@@ -295,7 +311,14 @@ func TestRawListenerChunkedWrongOrder(t *testing.T) {
// Should re-construct message from all possible combinations
for i := 0; i < 6*5*4*3*2*1; i++ {
if i != 87 {
continue
}
packets := permutation(i, []*TCPPacket{reqPacket1, reqPacket2, reqPacket3, reqPacket4, respPacket1, respPacket2})
t.Log("permutation:", i, packets)
testChunkedSequence(t, listener, packets...)
}
}
+6
View File
@@ -24,6 +24,8 @@ type TCPMessage struct {
Ack uint32
ResponseAck uint32
RequestStart time.Time
DataAck uint32
DataSeq uint32
RequestAck uint32
RequestID tcpID
ResponseID tcpID
@@ -114,6 +116,10 @@ func (t *TCPMessage) AddPacket(packet *TCPPacket) {
} else {
t.End = time.Now().Add(time.Millisecond)
}
if packet.OrigAck != 0 {
t.DataAck = packet.OrigAck
}
}
}
+1 -1
View File
@@ -25,7 +25,7 @@ func buildPacket(isIncoming bool, Ack, Seq uint32, Data []byte) (packet *TCPPack
buf[12] = 64
buf = append(buf, Data...)
packet = ParseTCPPacket([]byte(""), buf)
packet = ParseTCPPacket([]byte("123"), buf)
return packet
}
+13 -2
View File
@@ -28,6 +28,7 @@ type TCPPacket struct {
DestPort uint16
Seq uint32
Ack uint32
OrigAck uint32
DataOffset uint8
Raw []byte
@@ -41,13 +42,23 @@ func ParseTCPPacket(addr []byte, data []byte) (p *TCPPacket) {
p = &TCPPacket{Raw: data}
p.ParseBasic()
p.Addr = addr
p.GenID()
copy(p.ID[:4], addr)
return
}
func (p *TCPPacket) GenID() {
copy(p.ID[:4], p.Addr)
copy(p.ID[4:], p.Raw[0:2]) // Src port
copy(p.ID[6:], p.Raw[2:4]) // Dest port
copy(p.ID[8:], p.Raw[8:12]) // Ack
}
return
func (p *TCPPacket) UpdateAck(ack uint32) {
p.OrigAck = p.Ack
p.Ack = ack
binary.BigEndian.PutUint32(p.Raw[8:12], ack)
p.GenID()
}
// ParseBasic set of fields