Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

We need to consider a different type of network layer in the UDP design #435

Open
thirtytwobits opened this issue Feb 3, 2025 · 1 comment

Comments

@thirtytwobits
Copy link
Contributor

Our current media layer design builds abstract sockets where each multicast address subscribed to has a socket object. This is easy to implement on systems that have real sockets but almost impossible for systems that do not. Specifically, systems that have a simple queue of incoming ethernet frames will have difficulty handling calls to specific RX sockets that are scheduled above this layer. If the next frame on the queue for such a system is not sent to the multicast address of the RX socket for which receive is being called on then the media layer implementations must provide a complex set of behaviours. For some systems this will be out-of-order queue access but for others this will require popping off frames and caching them for later use until an appropriately addressed frame is found. Either approach leads to edge conditions where frames can be held and never used or lost without being accounted for or additional RAM and another layer of buffering.

Implementers are forced to either implement a full posix-like select behaviour or they have to accept that some amount of non-deterministic behaviour may be available in their system and implement ad-hoc work arounds.

We need to decide if libcyphal simply isn't for these systems or if we should modify the current design to accommodate them.

@pavel-kirienko
Copy link
Member

Indeed, for the socketless platforms we need a demultiplexer. This is normally done with a per-socket queue. The demultiplexer accepts every Ethernet frame, parses it, and for those that happen to be valid UDP datagrams it checks if there is a known libcyphal RX socket; otherwise, the frame is dropped. If a socket is found, the frame is enqueued, and the executor (its platform-specific implementation) is triggered to invoke the socket's callback asap. I think it's fairly straightforward but you do need to keep in mind that frames may be lost if libcyphal is too slow to read them from the per-socket queue. This is no different from the case of ordinary Berkeley sockets though.

Normally, demultiplexers would be highly platform-specific, but we could try and extract some commonalities and then ship them with libcyphal.

Overall I think it's fairly easy to do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants