WolfIP Doesn’t Allocate

For some types of embedded systems — especially those that are safety-critical — it’s considered bad form to dynamically allocate memory during operation. While you can usually arrange for your own code to behave, it’s the libraries that get you. In particular, it is hard to find a TCP/IP stack that doesn’t allocate and free memory all over the place. Unless you’ve found wolfIP.

The library supports a BSD-like non-blocking socket API. It can act as an endpoint, but can also support multiple interfaces and forwarding if you were building something like a router. It doesn’t appear to be bare-bones either. In addition to the normal things you’d expect for IPv4, there’s also ICMP, IPSEC, ARP, DHCP, DNS, and HTTP with or without SSL TLS. There is also a FIPS-compliant implementation of WireGuard for VPN, although it is not directly compatible with standard WireGuard, only with other instances of itself (known as wolfGuard). There is a Linux kernel module for WolfGuard, though.

The code should be fairly easy to port, and it includes a binding for FreeRTOS already. If you’ve used wolfIP, let us know in the comments.

If you want to really get down to the low-level, try this project. Of, if you want a refresher on basics, we can help with that, too.

28 thoughts on “WolfIP Doesn’t Allocate

      1. https://en.wikipedia.org/wiki/Fieldbus

        Modbus TCP and modern x.509 secured variants with static host IP on air-gapped networks are still very common, galvanically isolated. and a highly interoperable ISO/OSI. Note, the industrial certification on this type of equipment often far exceeds consumer equipment.

        CAN bus is like UDP, and heavily loaded with countless closed format pseudo-standards people just make up. The only reason it is in cars was the Laws mandating ODBII ports in anything post 1996 for emissions control. Some undocumented CANt bus versions are even booby-trapped, so you poke your nose in there to repair something, than you will be paying for a factory service tech. The other 97% of the time, it is just some wonk ripping off consumers.

        Finally, don’t assume the industrial connectors will look like consumer cables in either case, and note airplanes have their own proprietary standards with several redundancies.

        Best of luck kid. =3

    1. Good safety design requires that you compensate for the weaknesses of your tools. It doesn’t tell you what tools to use. The first step is accepting that everything is inherently unreliable, so determining that TCP/IP is inherently unreliable doesn’t automatically disqualify it. In fact, if you disqualify TCP/IP because it’s inherently unreliable, and accept something else instead because you view it as inherently reliable, then you just made a severe error that makes safety impossible.

      It really depends what you’re trying to accomplish but the idea that something is unsuitable just because it has weaknesses is only going to lead you down a bad path. We are always designing around weaknesses, not looking for things that aren’t weak!

  1. LWIP is pretty rock stable, I like using it. It lets me write socket level code on ESP32 and similar SoCs. The best part, I can run the same-ish code on my PC, that runs on ESP32. At least the socket part of it

    Raw socket features I haven’t used though.

      1. Not FUD. If you include GPLv3 in an application, then GPLv3 extends itself to the whole application. And as this targets embedded systems, most likely microcontrollers, it highly limits the usability in commercial settings. I found it strange that wolfSSL doesn’t offer a commercial license on this page. As this is something we would definitely pay for in certain projects that we do.

        The github summary on GPLv3 is pretty clear on this:

        Permissions of this strong copyleft license are conditioned on making available complete source code of licensed works and modifications, which include larger works using a licensed work, under the same license.

      2. to expand on what Daid said…the GPLv2 had a companion “LGPL” (Lesser GPL / Library GPL) that allowed some flexbility when linking LGPL components into a larger project. There is some debate (and possible FUD) around whether the LGPL restricts what kind of linker you can use. The LGPL may not allow the kind of linking needed for many embedded environments (though my personal belief is that it does).

        One of the controversies about GPLv3 is that it came out at the same time as the FSF (or RMS, i don’t know) made disparaging comments about the LGPL. Which is a shame, IMO, but that’s why GPLv3 is viewed in this way. There is no LGPL variant of the GPLv3. GPLv3 is a true parasitic license.

        1. LGPL also becomes a contaminating license when statically linked.

          The wxwidgets libraries removed that clause in a more permissive license, to encourage more cross platforms builds.

          1. Yep, except, that they added an exception in LGPLv3 that allows it to be statically linked in non-consumer products. Which makes things even more complicated. The clause that mentions this isn’t the most obvious as it refers to GPLv3.

  2. The problem is not dynamic allocation, but dynamic allocation/free. It is fine to allocate resources in the heap at start up, as long as those are fixed in size and remain static. In fact if you want your system to be configurable, it is probably necessary. The risk comes from a) loss of resources due to allocating memory then not deallocating it and b) heap fragmentation.

    1. I think they are pitching this mostly from the perspective of determinism. I am not a real time expert but allocating, freeing, etc on the heap leads to nondeterminism.

      For a lot of projects this doesn’t matter at all, but for safety critical ones it is a consideration. I am not sure how they are entirely avoiding heap here but it sounds like a cool project and if I had the time I’d be curious how they are doing it.

      1. It can do, but we make systems with a high level of jitter intollerance and stack allocation is generally not the issue. There are of course may allocation/deallocation schemes each with its own caveats. For example our stack uses SLAB https://en.wikipedia.org/wiki/Slab_allocation and is highly determistic. While there are risks on allocation/deallocation there are also good reasons to have it. For example you may want to allocate more resources during high network loads

        1. “highly determistic” ? Either you are deterministic or you aren’t. There’s no level here, no grayness. If allocating (or freeing) doesn’t take the exact same time each time, it’s not deterministic. If all you can ensure is that this process will run within some delay statistically, it’s not deterministic, but it might be enough for your need.

    2. I think you’re going too deep on the semantics of “dynamic”. No matter how it’s allocated (heap, stack, RAII, new, malloc), if it’s all done at the start and remains static, it’s still deterministic and I think most people wouldn’t call it “dynamic memory usage”

  3. I believe the print function, also used by logging code, will allocate memory. You’d have to rewrite quite a bit of the standard library. How many bugs did that create?

  4. Just an aside about allocators…modern malloc on PCs is mostly very good. Like, one of my favorite things is deleting “stupid hacks” from my predecessors who had to do battle with a much less capable malloc. People used to really bend over backwards to deal with abysmal malloc performance.

    But i still run into environments where it isn’t, which is kind of disappointing. And on those environments, I have taken to wrapping the host malloc in dlmalloc (Doug Lea), which is free and fast and easy to use in this way. So i am successful even so at using malloc/free as much as i want without concern.

    But it is possible, through pathological or unlucky patterns, to fragment memory in such a way that you effectively waste it and can’t return it from a future malloc() call. I’d say, it’s vanishingly rare, especially if your program tends to malloc/free the same sizes (like 1500 byte MTU) over and over. And on a full-sized PC with gigabytes of RAM, it would be very hard to even detect the failure even if you composed a pathological example. But on embedded where 128kB RAM is “kind of a lot”, yeah, it’s a valid concern. Even if you don’t need to prove deterministic behavior, you still have a pretty high chance of running into trouble if you’re careless.

Leave a Reply to ChristianCancel reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.