A Transactional TCP/IP Stack Suitable for WCEC Analysis
- Introduction
- Platform is a highly resource-constrained embedded system with a persistent
memory device and hardware that implements a power-failure interrupt (PFI).
The system is intermittently powered by some form of locally generated
renewable energy, no battery is present because of the environmental
hazards. Capacitors are used instead.
- On these devices, the system must still achieve guaranteed forward-progress.
It must never waste any energy by starting some operation which can then not
be completed because power runs out before a new stable state is reached.
- To achieve this, we use worst-case energy-consumption (WCEC) analysis of the
software on the device. It is your goal to develop a transactional
networking stack (TCP/IP) to which WCEC analysis can be applied.
- The device must only turn itself off (persisting the applicaton, OS, and
network stack state to non-volatile memory) when it has reached a stable
state in which it can remain indefinately.
- The stack has a set of operations (e.g.,
advance_tcp_window()
) that
bring the device from one stable state to another. All these operations
must have a WCEC that can be statically analyzed in future work.
- Future work will attempt to prove properties like liveness and forward
progress based on your implementation (envisioned using Petri nets). Your
stack should be developed with this in mind.
- Background
- Related Work
- Design
- To simplify your stack, you must not have a clear separation of the OSI
layers in your implementation (e.g., transport, packet, and link layer).
- To implement your transaction, here’s an example of a few primitives that
will be needed. These will be the building blocks for going from one stable
state to another. To implement those, there are numerous resources online
(linked under implementation).
- MAC address lockup
- Prepare ARP request
- Could also be part of
send_arp_request()
but putting all the stuff
without side effects into a separate primitive will improve the WCEC of
the actual send/await-reply transaction.
- Send ARP request
- Await ARP reply
- Process ARP reply
- Send IP packet, has O(maxPacketSize)
- Can be split up similarily to the MAC address lookup.
- Example of stable states and associated transitions for your network stack
(per connection). It is part of your work to analyze whether these can be
split up further (goal is to reduce the maximum WCEC of the transitions):
closed
: Connection closed, initial state
- To get to
ip_ready
, three transactions can be used:
- Prepare ARP request
- Send ARP request and await ARP reply (see below for details)
- Process ARP reply
ip_ready
: Ready for sending IP packets (MAC address available)
tcp_transfer(TCP window state)
:
- Reached after TCP connection setup (handshake done)
- Challenge: Can the handshake be split up further to improve the WCEC?
- It is likely best to parameterize this state with the state of the TCP
window (send and ACKed bytes, not-yet sendable bytes). Will later be
transformed into one/many Petri net places.
- Repeated TCP send/ack pairs advance the window
- Use the “Send IP packet” primitive.
close()
brings us back to the initial state.
- Waiting for the response must (unfortunately) be included in the
transactions to make sure we reach a new stable state in which the device
can remain indefinately without secrificing guaranteed forward-progress.
- Otherwise, we open the door for infinite loops such as
- “I have a little energy”
- “I send ARP Request”
- “I turn myself off, missing the ARP response”
- “I have a little energy again, relize I missed the response and resend the ARP Request”
- For WCEC we assume some maximum network latency (e.g., one second).
- Forward progress can of course only be guaranteed if we do not have packet
loss.
- Can be done with TTEthernet or Time-Sensitive Networking, which is part
of the IEEE 802.1 (as mentioned in the tpIP paper).
- Implementation
- Hardware
- Both Zephyr and ESP-IDF use primitives from Espressif’s binary blobs to
interface with the network hardware. Thus, the most portable route is to
write a network stack that is OS-independent and only uses these interfaces.
- If possible, use the hardware directly instead of the binary blobs, see
https://esp32-open-mac.be/ (ESP32, ESP32-C3 is WIP)
- Existing network stacks from which code can be reused:
- Scientific Writing