Index: src/add-ons/kernel/network/protocols/tcp/BufferQueue.cpp
===================================================================
--- src/add-ons/kernel/network/protocols/tcp/BufferQueue.cpp	(revision 28859)
+++ src/add-ons/kernel/network/protocols/tcp/BufferQueue.cpp	(working copy)
@@ -100,9 +100,16 @@
 		fLastSequence = sequence + buffer->size;
 
 	if (fFirstSequence > sequence) {
+		ASSERT(fFirstSequence - sequence < buffer->size); // XXX
+		//XXX remove_header(), remove_trailer() do not remove any bytes from the buffer
+		//when passed with a byte count larger than the buffer size.
+
 		// this buffer contains data that is already long gone - trim it
 		gBufferModule->remove_header(buffer, fFirstSequence - sequence);
 		sequence = fFirstSequence;
+		buffer->sequence = fFirstSequence;
+		// XXX
+		// A similar line is near the top of this function.
 	}
 
 	// find the place where to insert the buffer into the queue
@@ -129,25 +136,35 @@
 				gBufferModule->free(buffer);
 				buffer = NULL;
 			} else {
+				fNumBytes -= previous->size;
 				fList.Remove(previous);
 				gBufferModule->free(previous);
+				//XXX fContiguousBytes will probably not be correctly maintained
+				//if we got here to remove the first buffer in the queue
 			}
 		} else if (tcp_sequence(previous->sequence + previous->size) > sequence) {
-			gBufferModule->remove_header(buffer,
-				previous->sequence + previous->size - sequence);
+			if (previous->sequence + previous->size - sequence >= buffer->size) {
+				gBufferModule->free(buffer);
+				buffer = NULL;
+			} else {
+				gBufferModule->remove_header(buffer,
+					previous->sequence + previous->size - sequence);
+			}
 		}
 	}
 
-	if (buffer != NULL && next != NULL
+	while (buffer != NULL && next != NULL
 		&& tcp_sequence(sequence + buffer->size) > next->sequence) {
 		// we already have at least part of this data
 		if (tcp_sequence(next->sequence + next->size) < sequence + buffer->size) {
 			net_buffer *remove = next;
 			next = (net_buffer *)next->link.next;
 
+			fNumBytes -= remove->size;
 			fList.Remove(remove);
 			gBufferModule->free(remove);
 		} else {
+			ASSERT(sequence + buffer->size - next->sequence < buffer->size);	//XXX
 			gBufferModule->remove_trailer(buffer,
 				sequence + buffer->size - next->sequence);
 		}
@@ -215,6 +232,8 @@
 		} else {
 			// remove the header as far as needed
 			size_t size = sequence - buffer->sequence;
+			//XXX
+			ASSERT(size <= sequence - buffer->sequence);
 			gBufferModule->remove_header(buffer, size);
 
 			buffer->sequence += size;
@@ -345,6 +364,8 @@
 			iterator.Remove();
 			gBufferModule->free(source);
 		} else {
+			//XXX remove_header does not remove anything when told to remove more bytes than the the buffer's size
+			ASSERT(size <= source->size);
 			gBufferModule->remove_header(source, size);
 			source->sequence += size;
 		}
@@ -377,6 +398,7 @@
 	return fContiguousBytes + fFirstSequence - sequence;
 }
 
+
 void
 BufferQueue::SetPushPointer()
 {
@@ -385,3 +407,39 @@
 	else
 		fPushPointer = fList.Tail()->sequence + fList.Tail()->size;
 }
+
+
+/*!	Sanity check
+*/
+void
+BufferQueue::Verify()
+{
+	ASSERT(Available() == 0 || fList.First() != NULL); 
+
+	if (fList.First() == NULL)
+		return;
+
+	SegmentList::Iterator it = fList.GetIterator();
+	net_buffer *nb;
+	size_t sum=0;
+	while ( (nb = it.Next()) != NULL )
+		sum += nb->size;
+
+	if (sum != fNumBytes)
+		TRACE(("BufferQueue@%p::Verify(): %d=sum != fNumBytes=%d\n", this, sum, fNumBytes));
+	ASSERT(sum == fNumBytes);
+}
+
+
+void
+BufferQueue::Dump()
+{
+	SegmentList::Iterator it = fList.GetIterator();
+	net_buffer *nb;	
+
+	TRACE(("BufferQueue@%p::Dump() >>>\n", this));
+	while ( (nb = it.Next()) != NULL )
+		TRACE(("BufferQueue@%p::Dump(): sequence 0x%x, size 0x%x\n", this, (uint32)nb->sequence, nb->size));
+	TRACE(("BufferQueue@%p::Dump() <<<\n", this));
+}
+
Index: src/add-ons/kernel/network/protocols/tcp/BufferQueue.h
===================================================================
--- src/add-ons/kernel/network/protocols/tcp/BufferQueue.h	(revision 28845)
+++ src/add-ons/kernel/network/protocols/tcp/BufferQueue.h	(working copy)
@@ -36,7 +36,7 @@
 			size_t			Available() const { return fContiguousBytes; }
 			size_t			Available(tcp_sequence sequence) const;
 
-	inline	size_t			PushedData() const;
+			inline	size_t			PushedData() const;
 			void			SetPushPointer();
 
 			size_t			Used() const { return fNumBytes; }
@@ -51,6 +51,9 @@
 			tcp_sequence	NextSequence() const
 								{ return fFirstSequence + fContiguousBytes; }
 
+			void			Verify();
+			void			Dump();
+
 private:
 	SegmentList				fList;
 	size_t					fMaxBytes;
