src/ws.c file

wsServer main routines.

Contents

Classes

struct ws_connection
Client socks.
struct ws_frame_data
WebSocket frame data.

Functions

static void close_socket(int fd)
Shutdown and close a given socket.
static auto get_client_state(ws_cli_conn_t* client) -> int
Returns the current client state for a given client client.
static auto set_client_state(ws_cli_conn_t* client, int state) -> int
Set a state state to the client index client.
static auto send_all(ws_cli_conn_t* client, const void* buf, size_t len, int flags) -> ssize_t
Send a given message buf on a socket sockfd.
static void close_client(ws_cli_conn_t* client)
Close client connection (no close handshake, this should be done earlier), set appropriate state and destroy mutexes.
static auto close_timeout(void* p) -> void*
Close time-out thread.
static auto start_close_timeout(ws_cli_conn_t* client) -> int
For a valid client index client, starts the timeout thread and set the current state to 'CLOSING'.
static void set_client_address(ws_cli_conn_t* client)
Sets the IP address relative to a client connection opened by the server and save inside the client structure.
auto ws_getaddress(ws_cli_conn_t* client) -> char*
Gets the IP address relative to a client connection opened by the server.
auto ws_sendframe(ws_cli_conn_t* client, const char* msg, uint64_t size, int type) -> int
Creates and send an WebSocket frame with some payload data.
auto ws_sendframe_txt(ws_cli_conn_t* client, const char* msg) -> int
Sends a WebSocket text frame.
auto ws_sendframe_bin(ws_cli_conn_t* client, const char* msg, uint64_t size) -> int
Sends a WebSocket binary frame.
auto ws_get_state(ws_cli_conn_t* client) -> int
For a given client, gets the current state for the connection, or -1 if invalid.
auto ws_close_client(ws_cli_conn_t* client) -> int
Close the client connection for the given client with normal close code (1000) and no reason string.
static auto is_control_frame(int frame) -> int
Checks is a given opcode frame belongs to a control frame or not.
static auto do_handshake(struct ws_frame_data* wfd) -> int
Do the handshake process.
static auto do_close(struct ws_frame_data* wfd, int close_code) -> int
Sends a close frame, accordingly with the close_code or the message inside wfd.
static auto do_pong(struct ws_frame_data* wfd, uint64_t frame_size) -> int
Send a pong frame in response to a ping frame.
static auto next_byte(struct ws_frame_data* wfd) -> int
Read a chunk of bytes and return the next byte belonging to the frame.
static auto skip_frame(struct ws_frame_data* wfd, uint64_t frame_size) -> int
Skips frame_size bytes of the current frame.
static auto read_frame(struct ws_frame_data* wfd, int opcode, unsigned char** buf, uint64_t* frame_length, uint64_t* frame_size, uint64_t* msg_idx, uint8_t* masks, int is_fin) -> int
Reads the current frame isolating data from control frames. The parameters are changed in order to reflect the current state.
static auto next_frame(struct ws_frame_data* wfd) -> int
Reads the next frame, whether if a TXT/BIN/CLOSE of arbitrary size.
static auto ws_establishconnection(void* vclient) -> void*
Establishes to connection with the client and trigger events when occurs one.
static auto ws_accept(void* data) -> void*
Main loop that keeps accepting new connections.
auto ws_socket(struct ws_events* evs, uint16_t port, int thread_loop) -> int
Main loop for the server.

Variables

static struct ws_events cli_events
Websocket events.
static struct ws_connection client_socks
Clients list.
static pthread_mutex_t mutex
Global mutex.

Defines

#define CLIENT_VALID(cli)
Client validity macro.
#define panic(s)
Issues an error message and aborts the program.

Function documentation

static void close_socket(int fd)

Shutdown and close a given socket.

Parameters
fd Socket file descriptor to be closed.

static int get_client_state(ws_cli_conn_t* client)

Returns the current client state for a given client client.

Parameters
client Client structure.
Returns Returns the client state, -1 otherwise.

static int set_client_state(ws_cli_conn_t* client, int state)

Set a state state to the client index client.

Parameters
client Client structure.
state State to be set.
Returns Returns 0 if success, -1 otherwise.

static ssize_t send_all(ws_cli_conn_t* client, const void* buf, size_t len, int flags)

Send a given message buf on a socket sockfd.

Parameters
client Target client.
buf Message to be sent.
len Message length.
flags Send flags.
Returns Returns 0 if success (i.e: all message was sent), -1 otherwise.

static void close_client(ws_cli_conn_t* client)

Close client connection (no close handshake, this should be done earlier), set appropriate state and destroy mutexes.

Parameters
client Client connection.

static void* close_timeout(void* p)

Close time-out thread.

Parameters
p ws_connection/ws_cli_conn_t Structure Pointer.
Returns Always NULL.

For a given client, this routine sleeps until TIMEOUT_MS and closes the connection or returns sooner if already closed connection.

static int start_close_timeout(ws_cli_conn_t* client)

For a valid client index client, starts the timeout thread and set the current state to 'CLOSING'.

Parameters
client Client connection.
Returns Returns 0 if success, -1 otherwise.

static void set_client_address(ws_cli_conn_t* client)

Sets the IP address relative to a client connection opened by the server and save inside the client structure.

Parameters
client Client connection.

char* ws_getaddress(ws_cli_conn_t* client)

Gets the IP address relative to a client connection opened by the server.

Parameters
client Client connection.
Returns Pointer the ip address, or NULL if fails.

int ws_sendframe(ws_cli_conn_t* client, const char* msg, uint64_t size, int type)

Creates and send an WebSocket frame with some payload data.

Parameters
client Target to be send. If NULL, broadcast the message.
msg Message to be send.
size Binary message size.
type Frame type.
Returns Returns the number of bytes written, -1 if error.

This routine is intended to be used to create a websocket frame for a given type e sending to the client. For higher level routines, please check ws_sendframe_txt and ws_sendframe_bin.

int ws_sendframe_txt(ws_cli_conn_t* client, const char* msg)

Sends a WebSocket text frame.

Parameters
client Target to be send. If NULL, broadcast the message.
msg Message to be send, null terminated.
Returns Returns the number of bytes written, -1 if error.

int ws_sendframe_bin(ws_cli_conn_t* client, const char* msg, uint64_t size)

Sends a WebSocket binary frame.

Parameters
client Target to be send. If NULL, broadcast the message.
msg Message to be send.
size Binary message size.
Returns Returns the number of bytes written, -1 if error.

int ws_get_state(ws_cli_conn_t* client)

For a given client, gets the current state for the connection, or -1 if invalid.

Parameters
client Client connection.
Returns Returns the connection state or -1 if invalid client.

int ws_close_client(ws_cli_conn_t* client)

Close the client connection for the given client with normal close code (1000) and no reason string.

Parameters
client Client connection.
Returns Returns 0 on success, -1 otherwise.

static int is_control_frame(int frame)

Checks is a given opcode frame belongs to a control frame or not.

Parameters
frame Frame opcode to be checked.
Returns Returns 1 if is a control frame, 0 otherwise.

static int do_handshake(struct ws_frame_data* wfd)

Do the handshake process.

Parameters
wfd Websocket Frame Data.
Returns Returns 0 if success, a negative number otherwise.

static int do_close(struct ws_frame_data* wfd, int close_code)

Sends a close frame, accordingly with the close_code or the message inside wfd.

Parameters
wfd Websocket Frame Data.
close_code Websocket close code.
Returns Returns 0 if success, a negative number otherwise.

static int do_pong(struct ws_frame_data* wfd, uint64_t frame_size)

Send a pong frame in response to a ping frame.

Parameters
wfd Websocket frame data.
frame_size Pong frame size.
Returns Returns 0 if success and a negative number otherwise.

Accordingly to the RFC, a pong frame must have the same data payload as the ping frame, so we just send a ordinary frame with PONG opcode.

static int next_byte(struct ws_frame_data* wfd)

Read a chunk of bytes and return the next byte belonging to the frame.

Parameters
wfd Websocket Frame Data.
Returns Returns the byte read, or -1 if error.

static int skip_frame(struct ws_frame_data* wfd, uint64_t frame_size)

Skips frame_size bytes of the current frame.

Parameters
wfd Websocket Frame Data.
frame_size Amount of bytes to be skipped.
Returns Returns 0 if success, a negative number otherwise.

static int read_frame(struct ws_frame_data* wfd, int opcode, unsigned char** buf, uint64_t* frame_length, uint64_t* frame_size, uint64_t* msg_idx, uint8_t* masks, int is_fin)

Reads the current frame isolating data from control frames. The parameters are changed in order to reflect the current state.

Parameters
wfd Websocket Frame Data.
opcode Frame opcode.
buf Buffer to be written.
frame_length Length of the current frame.
frame_size Total size of the frame (considering CONT frames) read until the moment.
msg_idx Message index, reflects the current buffer pointer state.
masks Masks vector.
is_fin Is FIN frame indicator.
Returns Returns 0 if success, a negative number otherwise.

static int next_frame(struct ws_frame_data* wfd)

Reads the next frame, whether if a TXT/BIN/CLOSE of arbitrary size.

Parameters
wfd Websocket Frame Data.
Returns Returns 0 if success, a negative number otherwise.

static void* ws_establishconnection(void* vclient)

Establishes to connection with the client and trigger events when occurs one.

Parameters
vclient Client connection.
Returns Returns vclient.

static void* ws_accept(void* data)

Main loop that keeps accepting new connections.

Parameters
data Server socket.
Returns Returns data.

int ws_socket(struct ws_events* evs, uint16_t port, int thread_loop)

Main loop for the server.

Parameters
evs Events structure.
port Server port.
thread_loop If any value other than zero, runs the accept loop in another thread and immediately returns. If 0, runs in the same thread and blocks execution.
Returns If thread_loop != 0, returns 0. Otherwise, never returns.