lwIP was designed from the outset to have a low resource footprint. One of the
techniques it uses to achieve this goal is its high level of configurability.
lwIP allows both coarse- and fine-grained control of functionality. Large
sections of potentially unused functionality can be selected to be removed
by the user, including entire protocol stacks. Such examples of removable
coarse-grained functionality include UDP, TCP, SLIP, PPP stacks, ethernet/ARP
support, IP fragmentation and/or reassembly, or the sequential API.
It has a somewhat modular and layered design to assist with this. It is
intentionally only somewhat modular: other TCP/IP stacks have strictly
enforced interfaces and abstractions between protocol layers. These
abstractions are frequently cumbersome and can result in unnecessary
resource implications. lwIP deliberately violates some of these protocol
interface layering abstractions where doing so could improve resource
utilisation. An example is reserving an estimated appropriate amount of
space for protocol headers when constructing packets, where the choice
of protocol dictates the amount of space.
Where lwIP really stands out is in its fine-grained control over the
various pools of resources. Most resources are compartmentalised into
fixed size memory pools to allow sizes to be constrained deterministically.
The application designer will know, or can choose, the maximum number of
network connections which are to be supported depending on application
requirements. They also know the level of data throughput required for
transmission or reception and can control the levels of the necessary
resources appropriately, such as numbers of buffers (separately for
incoming or outgoing packet data) and their sizes, numbers of protocol
control blocks, TCP window sizes and more.
In this way, application designers can choose a configuration that
maximises performance within the limitations of available
memory. Clearly, the more constrained the memory, the greater the
potential for adverse consequences for performance, or the number of
supported connections. However, it should be realised that even with
copious quantities of memory resources available to lwIP, it cannot be
expected that a stack intentionally designed from the outset to be
sparing with memory will perform as well as a stack intentionally
designed from the outset for high performance. Nevertheless careful
tuning of lwIP almost always results in significant performance
improvements.