diff options
-rw-r--r-- | README.md | 27 | ||||
-rw-r--r-- | plugins/framing_fixedlength.c | 36 | ||||
-rw-r--r-- | plugins/framing_fixedlength.md | 9 | ||||
-rw-r--r-- | plugins/makefile | 5 | ||||
-rw-r--r-- | websocksy.c | 4 | ||||
-rw-r--r-- | websocksy.h | 1 |
6 files changed, 77 insertions, 5 deletions
@@ -3,7 +3,8 @@ `websocksy` is a highly configurable [WebSocket (RFC6455)](https://tools.ietf.org/html/rfc6455) to 'normal' networking transport (TCP/UDP/Unix sockets) bridge. It is written in C and supports pluggable modules for bridge peer selection modules (for dynamic bridging) and stream framing. -It can be used to connect a wide variety of existing applications directly to a website, or to implement new functionality in a way that maintains compatibility between traditional network transports and WebSockets. +It can be used to connect a wide variety of existing applications directly to a website, or to implement new functionality in a way that maintains compatibility +between traditional network transports and WebSockets. ## Table of contents @@ -15,6 +16,7 @@ It can be used to connect a wide variety of existing applications directly to a * [Command line arguments](#command-line-arguments) * [Configuration file](#configuration-file) * [Default backend](#default-backend) + * [Plugins](#plugins) * [Building](#building) * [Development](#development) * [Peer discovery backend API](#peer-discovery-backend-api) @@ -104,7 +106,7 @@ at the time. * `-p <port>`: Set the listen port for incoming WebSocket connections (Default: `8001`) * `-l <host>`: Set the host for listening for incoming WebSocket connections (Default: `::`) -* `-k <seconds>`: Set the inactivity timeout for sending WebSocket keep-alive pings +* `-k <seconds>`: Set the inactivity timeout for sending WebSocket keep-alive pings (Default: `30`) * `-b <backend>`: Select external backend * `-c <option>=<value>`: Pass configuration option to backend @@ -135,7 +137,15 @@ The integrated default backend takes the following configuration arguments: * `framing`: The name of a framing function to be used (`auto` is used when none is specified) * `protocol`: The subprotocol to negotiate with the WebSocket peer. If not set, only the empty protocol set is accepted, which fails clients indicating an explicitly supported subprotocol. The special value `*` matches the first available protocol. -* `framing-config`: Arguments to the framing function +* `framing-config`: Configuration data for the framing function + +## Plugins + +This repository comes with some plugins already included, in addition to the built-in backend and framing functions. +Documentation for these resides in the `plugins/` directory. + + * [backend\_file](plugins/backend_file.md) + * [framing\_fixedlength](plugins/framing_fixedlength.md) # Building @@ -174,6 +184,15 @@ From the backend shared object, `websocksy` tries to resolve the following symbo will be `free`'d by the core. * `cleanup` (`void cleanup()`): Release all allocated memory. Called in preparation to core shutdown. +The [`file` backend](plugins/backend_file.c) is provided as a reference backend implementation. + ## Peer stream framing API -TBD +At startup, `websocksy` tries to load all shared objects in the plugin path (`plugins/` by default) that have a file +name ending in `.so` and not starting with `backend_` (which is reserved for backend plugins, of which only one may be +loaded at run time). Plugins may declare their own initializer functions using e.g. the compiler's `__attribute__((constructor))` +syntax or the linker. To register a framing function with the framing function library, the initializer function should call the +function `core_register_framing(char* name, ws_framing func)`, exported by the core. + +An example plugin providing the [`fixedlength` framing function](plugins/framing_fixedlength.c) is provided in the repository. +Additions to the `websocksy` plugin library are welcome! diff --git a/plugins/framing_fixedlength.c b/plugins/framing_fixedlength.c new file mode 100644 index 0000000..1a66df4 --- /dev/null +++ b/plugins/framing_fixedlength.c @@ -0,0 +1,36 @@ +#include <stdio.h> + +#include "../websocksy.h" + +static int64_t framing_fixedlen(uint8_t* data, size_t length, size_t last_read, ws_operation* opcode, void** framing_data, const char* config){ + size_t* frame_size = framing_data ? (size_t*) (*framing_data) : NULL; + + if(data && !frame_size){ + frame_size = calloc(1, sizeof(size_t)); + if(!frame_size){ + fprintf(stderr, "Failed to allocate memory\n"); + return -1; + } + + *frame_size = strtoul(config, NULL, 0); + *framing_data = frame_size; + } + else if(!data && frame_size){ + free(*framing_data); + *framing_data = NULL; + } + + if(!(*frame_size)){ + return length; + } + + if(length >= *frame_size){ + return *frame_size; + } + + return 0; +} + +static void __attribute__((constructor)) init(){ + core_register_framing("fixedlength", framing_fixedlen); +} diff --git a/plugins/framing_fixedlength.md b/plugins/framing_fixedlength.md new file mode 100644 index 0000000..bd095c4 --- /dev/null +++ b/plugins/framing_fixedlength.md @@ -0,0 +1,9 @@ +# The `fixedlength` framing function + +The `fixedlength` peer stream framing function segments the peer stream into binary frames +at fixed byte boundaries (for example, aggregating and then sending 32-byte fragments from the +peer stream). + +## Configuration + +The framing configuration string is simply the length of the segments to transmit in bytes. diff --git a/plugins/makefile b/plugins/makefile index 1a6ef36..feab4cd 100644 --- a/plugins/makefile +++ b/plugins/makefile @@ -1,5 +1,5 @@ .PHONY: all clean -PLUGINS = backend_file.so +PLUGINS = backend_file.so framing_fixedlength.so CFLAGS += -fPIC -g -I../ LDFLAGS += -shared @@ -7,6 +7,9 @@ LDFLAGS += -shared %.so :: %.c %.h $(CC) $(CFLAGS) $(LDLIBS) $< -o $@ $(LDFLAGS) +%.so :: %.c + $(CC) $(CFLAGS) $(LDLIBS) $< -o $@ $(LDFLAGS) + all: $(PLUGINS) clean: diff --git a/websocksy.c b/websocksy.c index 8b37cec..5c29f8c 100644 --- a/websocksy.c +++ b/websocksy.c @@ -194,6 +194,10 @@ ws_framing core_framing(char* name){ return plugin_framing(name); } +int core_register_framing(char* name, ws_framing func){ + return plugin_register_framing(name, func); +} + /* Signal handler, attached to SIGINT */ static void signal_handler(int signum){ shutdown_requested = 1; diff --git a/websocksy.h b/websocksy.h index 6524977..a97784b 100644 --- a/websocksy.h +++ b/websocksy.h @@ -200,6 +200,7 @@ typedef struct /*_ws_backend*/ { /* Core API */ ws_framing core_framing(char* name); +int core_register_framing(char* name, ws_framing func); /* Internal helper functions */ char* xstr_lower(char* in); |