Skip to content

Latest commit

 

History

History
97 lines (64 loc) · 3.31 KB

File metadata and controls

97 lines (64 loc) · 3.31 KB

Solution

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 ;-)

AI Use

Manual setup of protocol and abstractions in header files and CMake Model: claude-4.6-opus-high

Assumptions

Consumer and Producer running on a single machine and environment

  • 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

Abstraction for the transport layer

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.

Protocol

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.

Events and Threading

Support signals and timeouts using epoll

The event loop is a single-threaded, blocking dispatch loop through epoll

Errors

throwing std::runtime_error. Terminates (possible core dump).

Code Structure

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

transport.hpp

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.

event_loop.hpp

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.

endpoint.hpp

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.