Start out defining the wire protocol, add a transport abstraction. Determine signals/timeouts needed for the event mechanism.
As a bonus a compatible Rust async version is provided (mostly by Claude ;-)
Manual setup of protocol and abstractions in header files and CMake Model: claude-4.6-opus-high
- Both are built from identical versions of the source code repository
- Deployment using packaging (Deb/RPM) are controlled and reflects this
No need for a versioned platform agnostic protocol ala Protobuf
Make a transport abstraction and a specific implementation for Linux AF sockets. Due to the listen/accept mechanism in sockets, a split into two classes should be used.
Use a Transport class object acting as a factory for a connection class object. The abstact base classes may include file descriptor references as this would be common for Linux operations
The consumer Transport needs a setup method to facilitate listen and a wait_for_connection method to mirror accept. The producer can just connect.
filesize (uint64_t) filenamesize (uint32_t) filename (string) file (bytes)
Simple memcpy on parameters will do given the same ABI/endianess on the target platform. The filename parameter must be sanitized on the consumer side to avoid path manipulations. A limit on file size should also be in place.
Support signals and timeouts using epoll
The event loop is a single-threaded, blocking dispatch loop through epoll
throwing std::runtime_error. Terminates (possible core dump).
All library code lives in the fc namespace.
include/
transport.hpp Transport and Connection abstract interfaces
UnixTransport / UnixConnection (AF_UNIX impl)
event_loop.hpp EventLoop (epoll + signalfd + timerfd)
endpoint.hpp Producer / Consumer file-transfer state machines
src/
transport.cpp UnixTransport / UnixConnection implementation
event_loop.cpp EventLoop implementation
endpoint.cpp Producer / Consumer implementation
apps/
producer.cpp CLI: connect and send a file
consumer.cpp CLI: listen, accept, and receive a file
Connection — abstract data channel with send/recv/fd/close.
Transport — factory that produces Connection objects. A single class
covers both roles: call setup + wait_for_connection on the consumer
side, or connect on the producer side.
UnixConnection / UnixTransport — AF_UNIX SOCK_STREAM implementation.
Non-blocking, CLOEXEC. Sends with MSG_NOSIGNAL.
EventLoop — single-threaded epoll loop.
add_fd/modify_fd/remove_fd— register fd callbacks with epoll event masks.add_signal/remove_signal— signals delivered via signalfd through epoll.add_timer/remove_timer— one-shot or recurring timers via timerfd.run/stop— blocking dispatch loop, tolerates EINTR.
Producer — async state machine driven by EPOLLOUT. Streams a file as
header + 64 KB chunks over any Connection.
Consumer — async state machine driven by EPOLLIN. Reassembles the
header, creates the output file, and writes the payload.