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 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 43 size_t Used() const { return fNumBytes; } 44 inline size_t Free() const; 45 size_t Size() const { return fMaxBytes; } 46 47 bool IsContiguous() const 48 { return fNumBytes == fContiguousBytes; } 49 50 tcp_sequence FirstSequence() const { return fFirstSequence; } 51 tcp_sequence LastSequence() const { return fLastSequence; } 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 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 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