Skip to content

S13.11: Introduce opaque SolidSyslogAddress to hide sockaddr_in #142

Description

@DavidCozens

Parent epic: #40 (E13 Cross-Platform CI and Windows)

Goal

Replace the leaked struct sockaddr_in* in the Resolver/Datagram/Stream interfaces with an opaque SolidSyslogAddress type. The concrete address type (sockaddr_in, or a Winsock equivalent) stays inside the platform source; senders and other platform-agnostic code only see a forward declaration and an opaquely-sized storage buffer. Public API stops including <netinet/in.h>.

Outcomes

  • Platform-agnostic code (senders, dispatch) no longer includes POSIX socket headers.
  • A sender holds an address inside its own storage via the storage pattern; it can pass a pointer to the address to Stream/Datagram without knowing the layout.
  • Switching between POSIX and Winsock builds does not require any source change in senders or dispatch code — the platform-specific address header is selected by the include path.
  • Alignment is preserved so platform code can safely cast the storage to the underlying address struct.

Scope

  • New platform-specific header Platform/<OS>/Interface/SolidSyslogAddress.h:
    • Forward declaration of struct SolidSyslogAddress.
    • Platform-sized SolidSyslogAddressStorage typedef — an array of void* to guarantee alignment (MISRA-compliant; no unions).
    • SolidSyslogAddress_FromStorage(SolidSyslogAddressStorage*) accessor.
  • New platform source Platform/<OS>/Source/SolidSyslogAddress.c providing the concrete struct and the FromStorage implementation.
  • Resolver vtable signature: struct SolidSyslogAddress* replaces struct sockaddr_in*.
  • Datagram vtable signature: const struct SolidSyslogAddress* replaces const struct sockaddr_in* in SendTo.
  • Stream vtable signature: const struct SolidSyslogAddress* replaces const struct sockaddr_in* in Open.
  • Sender structs switch from struct sockaddr_in addr to SolidSyslogAddressStorage addrStorage + SolidSyslogAddress* obtained via FromStorage.
  • Platform implementations of Resolver/Datagram/Stream cast internally to the concrete type, via a uint8_t* view for strict-aliasing safety.

Out of scope

  • IPv6 support — the storage is sized to hold the widest concrete address struct (struct sockaddr_storage worth of bytes) so IPv6 will fit without future API churn, but activating IPv6 resolution is a separate story.
  • Non-IP transports (Unix sockets, etc.) — not on the roadmap.

Design notes

  • No unions — MISRA 19.2 flags unions as problematic. Storage is an array of void* whose count is sized to cover the concrete address struct on both 32-bit and 64-bit targets (e.g. 32 pointers = 128 bytes on 32-bit, 256 bytes on 64-bit; always ≥ sizeof(struct sockaddr_storage)).
  • Alignment by construction — the pointer-array storage inherits alignof(void*), which meets or exceeds the alignment requirement of any sockaddr_* struct on supported platforms.
  • Aliasing — platform code casts SolidSyslogAddressStorage* to uint8_t* (a character type, permitted to alias any object under C99 strict aliasing), then to the concrete struct type, or uses memcpy for in/out copies when that is clearer.
  • Because each build targets exactly one platform, there is no multi-platform ABI concern — the SolidSyslogAddress shape is fixed at build time by the active Platform/<OS>/ include path.
  • Depends on the platform folder reorganisation being in place first (otherwise the address header has no natural home).

Context

Pairs with S12.11 (honest error reporting) at the same interface boundary — both touch Resolver.Resolve, Datagram.Open, Stream.Open signatures, so doing them in sequence avoids churning the same signatures twice. Unblocks the Winsock stories (S13.04, S13.09) by removing the POSIX type leak from their public contract.

Metadata

Metadata

Assignees

No one assigned

    Labels

    storyStory issue

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions