A from-scratch RFC 6455 WebSocket frame protocol implementation in C.
Handles the wire-level details of WebSocket communication: frame parsing, frame construction, and payload masking/unmasking. Built as a static library (C11, CMake) for embedding in applications that need direct control over WebSocket framing without pulling in a full-stack library.
| Component | File | RFC 6455 Section |
|---|---|---|
| Frame parsing | parseframe.c |
5.2 — Base Framing Protocol |
| Frame construction | wsframe.c |
5.2 — Base Framing Protocol |
| Payload masking | wsmask.c |
5.3 — Client-to-Server Masking |
Parses incoming WebSocket frames from a byte buffer. Extracts payload boundaries, handles all three payload length encodings (7-bit, 16-bit extended, 64-bit extended), detects control frames (ping, close), and applies XOR unmasking when the MASK bit is set. Uses bitfield unions to map directly onto the RFC 6455 frame header layout.
Builds outgoing WebSocket frames. Populates the header (FIN, RSV, OPCODE, payload length), selects the correct length encoding based on message size, writes the optional masking key, and applies XOR masking to the payload.
XOR mask/unmask operation per RFC 6455 Section 5.3. Symmetric — same function masks and unmasks.
Errors are reported via a bitfield struct (parseframe_err), allowing callers to check multiple error conditions from a single return value:
typedef struct parseframe_err_t {
unsigned payload_over_buffer: 1;
unsigned ping: 1;
unsigned closed_connection_frame: 1;
unsigned nothing_to_parse: 1;
unsigned payload_size_not_implemented: 1;
} parseframe_err;See Bitfield Error Handling in C for the design rationale behind this pattern.
Requires CMake 3.15+ and a C11 compiler.
mkdir build && cd build
cmake ..
cmake --build .Produces a static library (libwsmessage.a / wsmessage.lib) with a single public header at include/kwebsocket/wsmessage.h.
#include "kwebsocket/wsmessage.h"
// Parse a WebSocket frame from a byte buffer
int wsmessage__parseframe(
uint8_t *beg, uint8_t *end,
uint8_t **payload, uint8_t **frame_end,
uint32_t *maskingkey
);
// Construct a WebSocket frame for an outgoing message
void wsmessage__frame_msg(
WSFRAMEHEADER *f, char const *msg,
const K1MAXINT_T len, uint32_t * const maskingkey
);
// XOR mask/unmask a payload (symmetric operation)
void wsmessage__mask_flip(
const uint32_t masking_key,
unsigned char * const payload,
const K1MAXUINT_T len
);This is the wire protocol layer only — frame encoding/decoding and masking. It does not handle TCP connections, HTTP upgrade handshakes, or higher-level WebSocket session management. Designed to be embedded in applications that manage their own transport.
GPL-3.0