// getRingSlice returns a byte slice from the ring buffer given the head // and tail of the ring segment AND the slice indexes for head and tail. // That is, for head's byte slice, sliceStart is the a slice start index. // For tail's byte slice, sliceEnd is the slice end index. func getRingSlice(head, tail *types.Ring, sliceStart, sliceEnd int) []byte { var overlapBytes []byte if sliceStart < 0 || sliceEnd < 0 { log.Printf("sliceStart %d sliceEnd %d", sliceStart, sliceEnd) panic("getRingSlice: sliceStart < 0 || sliceEnd < 0") } if sliceStart >= len(head.Reassembly.Bytes) { panic(fmt.Sprintf("getRingSlice: sliceStart %d >= head len %d", sliceStart, len(head.Reassembly.Bytes))) } if sliceEnd > len(tail.Reassembly.Bytes) { panic("getRingSlice: impossible; sliceEnd is greater than ring segment") } if head == nil || tail == nil { panic("getRingSlice: head or tail is nil") } if head == tail { panic("getRingSlice: head == tail") } overlapBytes = append(overlapBytes, head.Reassembly.Bytes[sliceStart:]...) current := head.Next() for current.Reassembly.Seq != tail.Reassembly.Seq { overlapBytes = append(overlapBytes, current.Reassembly.Bytes...) current = current.Next() } overlapBytes = append(overlapBytes, tail.Reassembly.Bytes[:sliceEnd]...) return overlapBytes }
// getTailFromRing returns the oldest ring element that contains the beginning of // our sequence range (start - end) and whose range of ring segments all // have their Reassembly.Skip value set to 0 (zero). func getTailFromRing(head *types.Ring, end types.Sequence) *types.Ring { var ret *types.Ring for r := head; r != head.Prev(); r = r.Next() { if r.Reassembly == nil { ret = r.Prev() break } if len(r.Reassembly.Bytes) == 0 { log.Print("getTailFromRing: zero payload ring segment encountered.") ret = r.Prev() break } if r.Reassembly.Skip != 0 { log.Print("getTailFromRing: stream skip encountered.") ret = r.Prev() break } diff := r.Reassembly.Seq.Difference(end) if diff < 0 { return r.Prev() } } // XXX // prevent bug where the above sets ret to head.Prev() if ret == head.Prev() { return nil } else { return ret } return nil }
func displayRingSummary(ringHeadPtr *types.Ring) { log.Print("displayRingSummary:") i := 0 current := ringHeadPtr.Next() for current != ringHeadPtr { if current.Reassembly != nil { log.Printf("index: %d TCP.Seq %d Skip %d payload len %d\n", i, current.Reassembly.Seq, current.Reassembly.Skip, len(current.Reassembly.Bytes)) } else { log.Printf("index: %d nil\n", i) } current = current.Next() i += 1 } }
// getHeadFromRing returns a pointer to the oldest ring element that // contains the beginning of our sequence range (start - end) AND // whose Reassembly.Skip value is 0 (zero). func getHeadFromRing(ringPtr *types.Ring, start, end types.Sequence) *types.Ring { var head *types.Ring current := ringPtr.Prev() if current.Reassembly == nil { return nil } if start.Difference(current.Reassembly.Seq.Add(len(current.Reassembly.Bytes)-1)) < 0 { log.Printf("lastestSeq %d < newStartSeq %d\n", current.Reassembly.Seq.Add(len(current.Reassembly.Bytes)-1), start) return nil } head = nil var candidate *types.Ring = nil for current := ringPtr.Prev(); current != ringPtr && current.Reassembly != nil; current = current.Prev() { if len(current.Reassembly.Bytes) == 0 { continue } startDiff := current.Reassembly.Seq.Difference(start) if startDiff == 0 { return current } if startDiff < 0 { finishEndDiff := current.Reassembly.Seq.Difference(end) if finishEndDiff >= 0 { candidate = current } continue } else { endDiff := start.Difference(current.Reassembly.Seq.Add(len(current.Reassembly.Bytes) - 1)) if endDiff >= 0 { head = current break } } } if head == nil && candidate != nil { head = candidate } return head }
func TestGetStartSequence(t *testing.T) { var start types.Sequence = 4 var head *types.Ring = types.NewRing(10) head.Reassembly = &types.Reassembly{ Seq: 3, Bytes: []byte{1, 2, 3, 4, 5, 6, 7}, } startSeq := getStartSequence(head, start) if startSeq.Difference(start) != 0 { t.Errorf("startSeq %d != start %d\n", startSeq, start) t.Fail() } start = 2 startSeq = getStartSequence(head, start) if startSeq != start.Add(1) { t.Errorf("startSeq %d != start %d\n", startSeq, start.Add(1)) t.Fail() } }