Buffers are statically allocated kernel memory so that storing received TPDUs can be done quickly.
If the network layer is reliable the transport layer need not buffer transmitted data, since it relies on the network layer to get the data through.
If the network layer is unreliable, then the sending transport entity has to buffer all TPDUs until they are acknowledged. This gives the receiving transport entity the choice of buffering. If it does not, it knows the sender will eventually resend, though the time spent transmitting and receiving the TPDU has been wasted. Why might the receiver not buffer? It might not have a buffer to put the received TPDU in. Remember that the transport entities handle many connections simultaneously. The buffer pool available to the transport entity may be exhausted by other connections.
Several possible means of managing buffers exists.
If all TPDUs are the same size, then a pool of same-size buffers can be maintained, and each connection has a linked list corresponding to its received TPDUs. This is not a good scheme if TPDUs vary in size, since you'd have to make your buffers as big as the largest possible TPDU, so small packets would waste buffer space.You could have a pool of varying sized buffers, then pick one that fits as well as possible, maintaining the same sort of linked list per connection. This is a little more complicated to manage, since you can't just grab any free buffer.
The other possibility is to assign a block of memory to each connection, then manage it as a circular buffer. But how big should the circular buffer block be? If the connection is busy, large, but if it is a slow connection, a large block wastes memory.Buffering isn't the only thing that limits the flow control in the transport layer. Suppose the receiver had an infinite supply of memory to dedicate to buffers. You still have the limit of the subnet's carrying capacity. This is the issue of congestion control.
One scheme is to have the sender monitor the carrying capacity of the
network by measuring the time required for sending and receiving an ack
for a TPDU. Then, with a capacity of C TPDUs/second, and a round trip time
of r seconds per TPDU, the sender should be allowed a window of C * r bytes.
This keeps the pipe full. Since the network capacity may change rapidly
due to congestion, the estimates of C and r must be continually updated.