1 /*
2 * Copyright 2006-2010, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 * Axel Dörfler, axeld@pinc-software.de
7 */
8 #ifndef BUFFER_QUEUE_H
9 #define BUFFER_QUEUE_H
10
11
12 #include "tcp.h"
13
14 #include <util/DoublyLinkedList.h>
15
16
17 typedef DoublyLinkedList<struct net_buffer,
18 DoublyLinkedListCLink<struct net_buffer> > SegmentList;
19
20 class BufferQueue {
21 public:
22 BufferQueue(size_t maxBytes);
23 ~BufferQueue();
24
25 void SetMaxBytes(size_t maxBytes);
26 void SetInitialSequence(tcp_sequence sequence);
27
28 void Add(net_buffer* buffer);
29 void Add(net_buffer* buffer, tcp_sequence sequence);
30 status_t RemoveUntil(tcp_sequence sequence);
31 status_t Get(net_buffer* buffer, tcp_sequence sequence,
32 size_t bytes);
33 status_t Get(size_t bytes, bool remove,
34 net_buffer** _buffer);
35
Available()36 size_t Available() const { return fContiguousBytes; }
37 size_t Available(tcp_sequence sequence) const;
38
39 inline size_t PushedData() const;
40 void SetPushPointer();
41 int PopulateSackInfo(tcp_sequence sequence, int maxSackCount, tcp_sack* sacks);
42
Used()43 size_t Used() const { return fNumBytes; }
44 inline size_t Free() const;
Size()45 size_t Size() const { return fMaxBytes; }
46
IsContiguous()47 bool IsContiguous() const
48 { return fNumBytes == fContiguousBytes; }
49
FirstSequence()50 tcp_sequence FirstSequence() const { return fFirstSequence; }
LastSequence()51 tcp_sequence LastSequence() const { return fLastSequence; }
NextSequence()52 tcp_sequence NextSequence() const
53 { return fFirstSequence + fContiguousBytes; }
54
55 #if DEBUG_TCP_BUFFER_QUEUE
56 void Verify() const;
57 void Dump() const;
58 #endif
59
60 private:
61 SegmentList fList;
62 size_t fMaxBytes;
63 size_t fNumBytes;
64 size_t fContiguousBytes;
65 tcp_sequence fFirstSequence;
66 tcp_sequence fLastSequence;
67 tcp_sequence fPushPointer;
68 };
69
70
71 size_t
PushedData()72 BufferQueue::PushedData() const
73 {
74 // We must check if fPushPointer is not 0 here due to
75 // tcp_sequence's special handling of >
76 return fPushPointer != 0 && fPushPointer > fFirstSequence
77 ? (fPushPointer - fFirstSequence).Number() : 0;
78 }
79
80
81 size_t
Free()82 BufferQueue::Free() const
83 {
84 // Max bytes is a soft limit, so it can be lower than the actual amount of
85 // data in the queue. TCP should never advertize a window outside the max
86 // buffer size, though.
87 if (fMaxBytes > fNumBytes)
88 return fMaxBytes - fNumBytes;
89
90 return 0;
91 }
92
93 #endif // BUFFER_QUEUE_H
94