Skip to content
Malachi edited this page Nov 12, 2019 · 10 revisions

Inspiration

Netbuf architecture is inspired by LwIP netbuf and pbuf as well as general DMA architecture.

Overview

A netbuf is one or more raw buffers organized in a sequential manner. One can think of it as a linked list of buffer pointers, though underlying implementation can differ.

Netbuf use template metaprogramming so that they may compile-time optimize down to the same footprint as the native code in which they wrap.

Terminology

One netbuf is comprised of a chain of many buffers. TBD what each buffer is called, either chunk or chain-buffer.

API calls

Referred to as netbuf mk2

Since C++ concepts are still relatively new, it's important to specify the calling surface:

bool next()

Moves to next already-allocated buffer in netbuf chain, if one is available. Returns whether this actually happened

ExpandResult expand(size_type by_amount, bool move_to_next)

Attempts to allocate a new buffer in the next position, sizing by the specified by_amount

void* data()

Acquire pointer to current buffer in netbuf chain

void reset()

Reposition netbuf chain to the very first buffer

bool last()

Queries whether this is the last allocated chain buffer in the netbuf

size_type size() const

Returns the size in bytes of the current buffer

size_type total_size() const

Returnsthe size in bytes of the entire netbuf, ultimately the same as totaling every size() call for each chained buffer

shrink(size_type to_size) (optional and experimental)

This experimental call mirrors what PBUF shrink does - specifically it reduces the memory allocation of the netbuf to precisely to_size. This includes, if necessary, iterating over any chain of buffers and potentially deallocating trailing ones completely.

This is useful for protocols like CoAP who derive the message size by the size of the buffer itself

Earlier versions

Referred to as netbuf mk1

Prototype versions of netbuf also included a pos index in which a position within the current netbuf was tracked. This duty has been moved out to classes like NetBufReader/NetBufWriter and streambuf wrappers

The tracking of pos also necessitated the notions of unprocessed and processed calls which made the pos + data() interact

Lastly, an advance mechanism existed to move that pos forward

Current state of things

Unfortunately, there are 3 different buffer mechanisms to content with:

  1. Legacy/earlier netbufs
  2. New-style netbufs
  3. streambuf

For the transition from 1 to 2, internal::NetBufWrapper appears to wrap up a new-style to operate as a legacy netbuf. Not so bad, but the name could be more clear

Clone this wiki locally