Latest commit: 24da343 by Karsten Pedersen on 2023-04-17
Message: Added --binary flag to support noVNC.
$ git clone https://www.thamessoftware.co.uk/git/wsstent.git
Many web browsers support persistent connections in the form of WebSockets. However, there is a protocol overhead in using these which means it is incompatible with existing TCP/IP daemons expecting a standard stream.
WsStent in essence, provides a proxy to bridge between these protocols and tunnel a connection to a standard network daemon. An overview of its features are as follows:
The ability of ANSI C to interact with raw memory is extremely important, however this can also lead to a wide range of memory errors which can be difficult to identify. The libstent library solves a number of these risks in a fairly innovative way and this project is entirely bound to it. As such, the code may look considerably different to idiomatic C. In the debug profile, the following benefits are provided:
The build system is intentionally kept very minimal. In general the following command should compile the wsstent binary, as well as creating a test certificate (and key) for SSL:
$ make
Various convenience rules are added to the Makefile:
$ make test_echo # Run the simple echo server on localhost
$ make test # Run a test TCP proxy server (ws:8080 -> tcp:8000)
$ make test_server # Run a simple TCP server via netcat (port 8000)
If you run the compiled wsstent binary with no arguments, you will be greeted with the usage instructions.
Note: You will notice that in the default build, these usage instructions are followed with many notifications detailing information about leaked memory. This demonstrates the leak checking done by libstent with the purposefully raw exit(0) of the application. This will be the only instance where the program should leak.
Generally there are two modes, the simple echo server and the TCP proxy. The echo server returns a copy of any message sent to it whereas the TCP server provides the main functionality of the proxy, forwarding communication between the browser and the TCP server.
Note: The echo server is intended only for debugging and as part of setting up your server. In particular, wsstent will cleanly exit when the message BYE is sent to it (to help with testing).
It is useful to first run the echo server to make sure things are working. To do this, run:
$ wsstent --port 8080 --webroot www --cert cert.pem --key key.pem
Because we have not specified the --tunnelport and --tunnelhost arguments, it will fall back to the echo server running on port 8080 and serving files from the www directory.
If you now navigate to https://localhost:8080, you should see the test page so you can use it to confirm that this part is working.
With that in place, the next step is to run it in TCP proxy mode. This is the following command:
$ wsstent --port 8080 --webroot www --cert cert.pem --key key.pem \
--tunnelhost localhost --tunnelport 8000
This will listen on port 8080 and forward traffic to TCP port 8000 on localhost.
If you attempt to connect using the test page, it should immediately disconnect. This is because it could not connect to the TCP end point. Lets run a quick test server via netcat.
$ nc -l 8000
With both wsstent and netcat running, you should now be able to connect via the test page and send data through to the netcat instance. Messages typed in netcat should also send back through to the test page and display in the log.
Perhaps have a look through the code to get a feel for how libstent works. For example, Client.c deals with the sending and receiving of buffers from the WebSocket client. This demonstrates the usage of the type-safe vector container rather than needing to deal with raw memory. There should actually be no memory unsafe code in this file. Also in this file you will notice that some variables get set to NULL once they are destroyed. Do take this opportunity to comment out these NULL assignments to see how libstent alerts you to dangling pointers.
There are some limitations to the software that you may be interested to know about. Though these should not affect its general purpose.