wsServer main routines. More...
#include <errno.h>#include <fcntl.h>#include <pthread.h>#include <stdbool.h>#include <stddef.h>#include <stdint.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <sys/time.h>#include <unistd.h>#include <utf8.h>#include <ws.h>Classes | |
| struct | ws_cli_conn_t |
| Client socks. More... | |
| struct | ws_frame_data |
| WebSocket frame data. More... | |
| struct | frame_state_data |
| Frame state data. More... | |
| struct | ws_accept_params |
| Accept parameters. More... | |
Macros | |
| #define | _POSIX_C_SOURCE 200809L |
| #define | MSG_NOSIGNAL 0 |
| #define | CLIENT_VALID(cli) |
| Client validity macro. More... | |
| #define | panic(s) |
| Issues an error message and aborts the program. More... | |
Functions | |
| void * | ws_get_server_context (ws_cli_conn_t *cli) |
| Get server context. More... | |
| void | ws_set_connection_context (ws_cli_conn_t *cli, void *ptr) |
| Set connection context. More... | |
| void * | ws_get_connection_context (ws_cli_conn_t *cli) |
| Get connection context. More... | |
| static void | close_socket (int fd) |
| Shutdown and close a given socket. More... | |
| static int | get_client_state (ws_cli_conn_t *client) |
Returns the current client state for a given client client. More... | |
| static int | set_client_state (ws_cli_conn_t *client, int state) |
Set a state state to the client index client. More... | |
| 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. More... | |
| static void | close_client (ws_cli_conn_t *client, int lock) |
| Close client connection (no close handshake, this should be done earlier), set appropriate state and destroy mutexes. More... | |
| static void * | close_timeout (void *p) |
| Close time-out thread. More... | |
| 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'. More... | |
| 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. More... | |
| char * | ws_getaddress (ws_cli_conn_t *client) |
| Gets the IP address relative to a client connection opened by the server. More... | |
| char * | ws_getport (ws_cli_conn_t *client) |
| Gets the IP port relative to a client connection opened by the server. More... | |
| static int | ws_sendframe_internal (ws_cli_conn_t *client, const char *msg, uint64_t size, int type, uint16_t port) |
| Creates and send an WebSocket frame with some payload data. More... | |
| int | ws_sendframe (ws_cli_conn_t *client, const char *msg, uint64_t size, int type) |
| Send an WebSocket frame with some payload data. More... | |
| int | ws_sendframe_bcast (uint16_t port, const char *msg, uint64_t size, int type) |
| Send an WebSocket frame with some payload data to all clients connected into the same port. More... | |
| static int32_t | pong_msg_to_int32 (uint8_t *msg) |
| Given a PONG message, decodes the content as a int32_t number that corresponds to our PONG id. More... | |
| static void | int32_to_ping_msg (int32_t ping_id, uint8_t *msg) |
| Given a PING id, encodes the content to be sent as payload of a PING frame. More... | |
| static void | send_ping_close (ws_cli_conn_t *cli, int threshold, int lock) |
| Send a ping message and close if the client surpasses the threshold imposed. More... | |
| void | ws_ping (ws_cli_conn_t *cli, int threshold) |
Sends a PING frame to the client cli with threshold threshold. More... | |
| int | ws_sendframe_txt (ws_cli_conn_t *client, const char *msg) |
| Sends a WebSocket text frame. More... | |
| int | ws_sendframe_txt_bcast (uint16_t port, const char *msg) |
| Sends a broadcast WebSocket text frame. More... | |
| int | ws_sendframe_bin (ws_cli_conn_t *client, const char *msg, uint64_t size) |
| Sends a WebSocket binary frame. More... | |
| int | ws_sendframe_bin_bcast (uint16_t port, const char *msg, uint64_t size) |
| Sends a broadcast WebSocket binary frame. More... | |
| int | ws_get_state (ws_cli_conn_t *client) |
For a given client, gets the current state for the connection, or -1 if invalid. More... | |
| 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. More... | |
| static int | is_control_frame (int frame) |
Checks is a given opcode frame belongs to a control frame or not. More... | |
| static int | is_valid_frame (int opcode) |
Checks is a given opcode opcode is valid or not. More... | |
| static int | do_handshake (struct ws_frame_data *wfd) |
| Do the handshake process. More... | |
| 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. More... | |
| static int | do_pong (struct ws_frame_data *wfd, uint64_t frame_size) |
| Send a pong frame in response to a ping frame. More... | |
| static int | next_byte (struct ws_frame_data *wfd) |
| Read a chunk of bytes and return the next byte belonging to the frame. More... | |
| static int | skip_frame (struct ws_frame_data *wfd, uint64_t frame_size) |
Skips frame_size bytes of the current frame. More... | |
| static int | validate_utf8_txt (struct ws_frame_data *wfd, struct frame_state_data *fsd) |
| Validates TXT frames if UTF8 validation is enabled. More... | |
| static int | handle_pong_frame (struct ws_frame_data *wfd, struct frame_state_data *fsd) |
| Handle PONG frames in response to our PING (or not, unsolicited is possible too). More... | |
| static int | handle_ping_frame (struct ws_frame_data *wfd, struct frame_state_data *fsd) |
| Handle PING frames sending a PONG response. More... | |
| static int | handle_close_frame (struct ws_frame_data *wfd, struct frame_state_data *fsd) |
| Handle close frames while checking for UTF8 in the close reason. More... | |
| static int | read_single_frame (struct ws_frame_data *wfd, struct frame_state_data *fsd) |
| Reads the current frame isolating data from control frames. More... | |
| static int | next_complete_frame (struct ws_frame_data *wfd) |
| Reads the next frame, whether if a TXT/BIN/CLOSE of arbitrary size. More... | |
| static void * | ws_establishconnection (void *vclient) |
| Establishes to connection with the client and trigger events when occurs one. More... | |
| static void * | ws_accept (void *data) |
| Main loop that keeps accepting new connections. More... | |
| static int | do_bind_socket (struct ws_server *ws_srv) |
By using the server parameters provided in ws_srv, create a socket and bind it accordingly with the server configurations. More... | |
| int | ws_socket (struct ws_server *ws_srv) |
| Main loop for the server. More... | |
Variables | |
| static struct ws_connection | client_socks [MAX_CLIENTS] |
| Clients list. More... | |
| static uint32_t | timeout |
| Timeout to a single send(). More... | |
| static pthread_mutex_t | mutex = PTHREAD_MUTEX_INITIALIZER |
| Global mutex. More... | |
wsServer main routines.
| #define _POSIX_C_SOURCE 200809L |
| #define CLIENT_VALID | ( | cli | ) |
Client validity macro.
| #define MSG_NOSIGNAL 0 |
| #define panic | ( | s | ) |
Issues an error message and aborts the program.
| s | Error message. |
|
static |
Close client connection (no close handshake, this should be done earlier), set appropriate state and destroy mutexes.
| client | Client connection. |
| lock | Should lock the global mutex?. |
|
static |
Shutdown and close a given socket.
| fd | Socket file descriptor to be closed. |
|
static |
Close time-out thread.
For a given client, this routine sleeps until TIMEOUT_MS and closes the connection or returns sooner if already closed connection.
| p | ws_connection/ws_cli_conn_t Structure Pointer. |
|
static |
By using the server parameters provided in ws_srv, create a socket and bind it accordingly with the server configurations.
| ws_srv | Web Socket configurations. |
|
static |
Sends a close frame, accordingly with the close_code or the message inside wfd.
| wfd | Websocket Frame Data. |
| close_code | Websocket close code. |
|
static |
Do the handshake process.
| wfd | Websocket Frame Data. |
|
static |
Send a pong frame in response to a ping frame.
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.
| wfd | Websocket frame data. |
| frame_size | Pong frame size. |
|
static |
Returns the current client state for a given client client.
| client | Client structure. |
|
static |
Handle close frames while checking for UTF8 in the close reason.
| wfd | WebSocket frame data. |
| fsd | Frame state data. |
|
static |
Handle PING frames sending a PONG response.
| wfd | WebSocket frame data. |
| fsd | Frame state data. |
|
static |
Handle PONG frames in response to our PING (or not, unsolicited is possible too).
| wfd | WebSocket frame data. |
| fsd | Frame state data. |
|
inlinestatic |
Given a PING id, encodes the content to be sent as payload of a PING frame.
| ping_id | PING id to be encoded. |
| msg | Target buffer. |
|
inlinestatic |
Checks is a given opcode frame belongs to a control frame or not.
| frame | Frame opcode to be checked. |
|
inlinestatic |
Checks is a given opcode opcode is valid or not.
| opcode | Frame opcode to be checked. |
|
inlinestatic |
Read a chunk of bytes and return the next byte belonging to the frame.
| wfd | Websocket Frame Data. |
|
static |
Reads the next frame, whether if a TXT/BIN/CLOSE of arbitrary size.
| wfd | Websocket Frame Data. |
|
inlinestatic |
Given a PONG message, decodes the content as a int32_t number that corresponds to our PONG id.
| msg | Content to be decoded. |
|
static |
Reads the current frame isolating data from control frames.
The parameters are changed in order to reflect the current state.
| wfd | Websocket Frame Data. |
| fsd | Frame state data. |
|
static |
Send a given message buf on a socket sockfd.
| client | Target client. |
| buf | Message to be sent. |
| len | Message length. |
| flags | Send flags. |
|
static |
Send a ping message and close if the client surpasses the threshold imposed.
| cli | Client to be sent. |
| threshold | How many pings can miss?. |
| lock | Should lock global mutex or not?. |
|
static |
Sets the IP address relative to a client connection opened by the server and save inside the client structure.
| client | Client connection. |
|
static |
Set a state state to the client index client.
| client | Client structure. |
| state | State to be set. |
|
static |
Skips frame_size bytes of the current frame.
| wfd | Websocket Frame Data. |
| frame_size | Amount of bytes to be skipped. |
|
static |
For a valid client index client, starts the timeout thread and set the current state to 'CLOSING'.
| client | Client connection. |
|
static |
Validates TXT frames if UTF8 validation is enabled.
If the content is not valid, the connection is aborted.
| wfd | WebSocket frame data. |
| fsd | Frame state data. |
|
static |
Main loop that keeps accepting new connections.
| data | Server socket. |
data.| 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.
| client | Client connection. |
|
static |
Establishes to connection with the client and trigger events when occurs one.
| vclient | Client connection. |
vclient.| void* ws_get_connection_context | ( | ws_cli_conn_t * | cli | ) |
Get connection context.
| void* ws_get_server_context | ( | ws_cli_conn_t * | cli | ) |
Get server context.
Assumed to be set once, when initializing .context in struct ws_server.
| int ws_get_state | ( | ws_cli_conn_t * | client | ) |
For a given client, gets the current state for the connection, or -1 if invalid.
| client | Client connection. |
client.| char* ws_getaddress | ( | ws_cli_conn_t * | client | ) |
Gets the IP address relative to a client connection opened by the server.
| client | Client connection. |
| char* ws_getport | ( | ws_cli_conn_t * | client | ) |
Gets the IP port relative to a client connection opened by the server.
| client | Client connection. |
| void ws_ping | ( | ws_cli_conn_t * | cli, |
| int | threshold | ||
| ) |
Sends a PING frame to the client cli with threshold threshold.
This routine sends a PING to a single client pointed to by cli or a broadcast PING if cli is NULL. If the specified client does not respond up to threshold PINGs, the connection is aborted.
ws_ping() is not automatic: the user who wants to send keep-alive PINGs must call this routine in a timely manner, whether on a different thread or inside an event.
See examples/ping/ping.c for a minimal example usage.
| cli | Client to be sent, if NULL, broadcast. |
| threshold | How many ignored PINGs should tolerate? (should be positive and greater than 0). |
It is also important to note that for devices with unstable connections (such as a weak WiFi signal or 3/4/5G from a cell phone), a threshold greater than 1 is advisable.
| int ws_sendframe | ( | ws_cli_conn_t * | client, |
| const char * | msg, | ||
| uint64_t | size, | ||
| int | type | ||
| ) |
Send an WebSocket frame with some payload data.
| client | Target to be send. If NULL, broadcast the message. |
| msg | Message to be send. |
| size | Binary message size. |
| type | Frame type. |
size is -1, it is assumed that a text frame is being sent, otherwise, a binary frame. In the later case, the size is used. | int ws_sendframe_bcast | ( | uint16_t | port, |
| const char * | msg, | ||
| uint64_t | size, | ||
| int | type | ||
| ) |
Send an WebSocket frame with some payload data to all clients connected into the same port.
| port | Server listen port to broadcast message. |
| msg | Message to be send. |
| size | Binary message size. |
| type | Frame type. |
size is -1, it is assumed that a text frame is being sent, otherwise, a binary frame. In the later case, the size is used. | int ws_sendframe_bin | ( | ws_cli_conn_t * | client, |
| const char * | msg, | ||
| uint64_t | size | ||
| ) |
Sends a WebSocket binary frame.
| client | Target to be send. |
| msg | Message to be send. |
| size | Binary message size. |
| int ws_sendframe_bin_bcast | ( | uint16_t | port, |
| const char * | msg, | ||
| uint64_t | size | ||
| ) |
Sends a broadcast WebSocket binary frame.
| port | Server listen port to broadcast message. |
| msg | Message to be send. |
| size | Binary message size. |
|
static |
Creates and send an WebSocket frame with some payload data.
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.
| client | Target to be send. If NULL, broadcast the message. |
| msg | Message to be send. |
| size | Binary message size. |
| type | Frame type. |
| port | Server listen port to broadcast message (if any). |
size is -1, it is assumed that a text frame is being sent, otherwise, a binary frame. In the later case, the size is used.| int ws_sendframe_txt | ( | ws_cli_conn_t * | client, |
| const char * | msg | ||
| ) |
Sends a WebSocket text frame.
| client | Target to be send. |
| msg | Message to be send, null terminated. |
| int ws_sendframe_txt_bcast | ( | uint16_t | port, |
| const char * | msg | ||
| ) |
Sends a broadcast WebSocket text frame.
| port | Server listen port to broadcast message. |
| msg | Message to be send, null terminated. |
| void ws_set_connection_context | ( | ws_cli_conn_t * | cli, |
| void * | ptr | ||
| ) |
Set connection context.
| int ws_socket | ( | struct ws_server * | ws_srv | ) |
Main loop for the server.
| ws_srv | Web Socket server parameters. |
thread_loop != 0, returns 0. Otherwise, never returns.
|
static |
Clients list.
|
static |
Global mutex.
|
static |
Timeout to a single send().
1.8.17