xref: /haiku/src/add-ons/kernel/network/protocols/tcp/BufferQueue.h (revision 45bd7bb3db9d9e4dcb02b89a3e7c2bf382c0a88c)
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 #ifndef DEBUG_BUFFER_QUEUE
17 #	define DEBUG_BUFFER_QUEUE 1
18 #endif
19 
20 
21 typedef DoublyLinkedList<struct net_buffer,
22 	DoublyLinkedListCLink<struct net_buffer> > SegmentList;
23 
24 class BufferQueue {
25 public:
26 								BufferQueue(size_t maxBytes);
27 								~BufferQueue();
28 
29 			void				SetMaxBytes(size_t maxBytes);
30 			void				SetInitialSequence(tcp_sequence sequence);
31 
32 			void				Add(net_buffer* buffer);
33 			void				Add(net_buffer* buffer, tcp_sequence sequence);
34 			status_t			RemoveUntil(tcp_sequence sequence);
35 			status_t			Get(net_buffer* buffer, tcp_sequence sequence,
36 									size_t bytes);
37 			status_t			Get(size_t bytes, bool remove,
38 									net_buffer** _buffer);
39 
40 			size_t				Available() const { return fContiguousBytes; }
41 			size_t				Available(tcp_sequence sequence) const;
42 
43 	inline	size_t				PushedData() const;
44 			void				SetPushPointer();
45 
46 			size_t				Used() const { return fNumBytes; }
47 	inline	size_t				Free() const;
48 			size_t				Size() const { return fMaxBytes; }
49 
50 			bool				IsContiguous() const
51 									{ return fNumBytes == fContiguousBytes; }
52 
53 			tcp_sequence		FirstSequence() const { return fFirstSequence; }
54 			tcp_sequence		LastSequence() const { return fLastSequence; }
55 			tcp_sequence		NextSequence() const
56 									{ return fFirstSequence + fContiguousBytes; }
57 
58 #if DEBUG_BUFFER_QUEUE
59 			void				Verify() const;
60 			void				Dump() const;
61 #endif
62 
63 private:
64 			SegmentList			fList;
65 			size_t				fMaxBytes;
66 			size_t				fNumBytes;
67 			size_t				fContiguousBytes;
68 			tcp_sequence		fFirstSequence;
69 			tcp_sequence		fLastSequence;
70 			tcp_sequence		fPushPointer;
71 };
72 
73 
74 size_t
75 BufferQueue::PushedData() const
76 {
77 	// We must check if fPushPointer is not 0 here due to
78 	// tcp_sequence's special handling of >
79 	return fPushPointer != 0 && fPushPointer > fFirstSequence
80 		? (fPushPointer - fFirstSequence).Number() : 0;
81 }
82 
83 
84 size_t
85 BufferQueue::Free() const
86 {
87 	// Max bytes is a soft limit, so it can be lower than the actual amount of
88 	// data in the queue. TCP should never advertize a window outside the max
89 	// buffer size, though.
90 	if (fMaxBytes > fNumBytes)
91 		return fMaxBytes - fNumBytes;
92 
93 	return 0;
94 }
95 
96 #endif	// BUFFER_QUEUE_H
97