Quick Navigator

Search Site

Unix VPS
A - Starter
B - Basic
C - Preferred
D - Commercial
MPS - Dedicated
Previous VPSs
* Sign Up! *

Contact Us
Online Help
Domain Status
Man Pages

Virtual Servers

Topology Map

Server Agreement
Year 2038

USA Flag



Man Pages

Manual Reference Pages  -  LIBDORRIT (8)


libdorrit - UNIX-Domain WebSocket Server Library


     Command-line Options


#include <dorrit.h> -I/usr/local/include -L/usr/local/lib -ldorrit


Libdorrit implements a generic event-driven WebSocket server that works with the drood(8) or humdinger(8) web servers. The library performs network and concurrency tasks. You supply code to service connections.

Dorrit is intended for use in applications that exchange text messages.

  • Dorrit accepts only local UNIX-domain connections.
  • Dorrit automatically responds to pings with pongs.
  • Dorrit drops connections with clients that send:
    • binary messages.
    • Frames with payloads larger than a specified length, which can be no greater than 63535.

An Example echo server is included in the dorrit source distribution.


The libraries provide your server’s "main" function. You define 4 functions to match the following prototypes.
void ws_init_func();
int ws_open_callback( void *, char *, char *, char * );
void ws_read_callback( void *, int, char * );
void ws_close_callback( void * );

Do not define any other global symbol beginning with the five characters 'ws_’ because the library reserves that namespace.


In ws_init_func() perform the initialization tasks your server needs to do once at server start-up.

The library calls ws_init_func():

  • before attempting to change the server’s user and group to the values specified by the command line options. If the server starts as root ws_init_func(), executes as root.
  • before the server becomes a daemon and starts listening for connections. The standard streams are connected to the terminal from which the server was started. Error and informative messages should be sent to the terminal.


Call ws_set_name() inside ws_init_func() to set the server’s name.
void ws_set_name( char * );

If not set the server’s name defaults to "server". The server’s name is used in 3 ways:

  • When the server is running, stderr is connected to /dev/null. Errors must are reported with syslog(3). The library calls openlog() with the server’s name as argument to ensure that log entries are identified by the server’s name.
  • The server’s pidfile is written to /var/run/ if the server is started as root. The filename is the server’s name with ".pid" appended to it. This file is used by rc.d scripts to stop the server. A sample script is included in the dorrit distribution.
  • The server’s listening socket is created in /var/run/ unless you override this with the -l option. If you do not use the -l option, the name defaults to dorrit.socket. With the server’s name explicitly set, the name is <name>.socket.


You can install a function to be invoked periodically with:
void ws_set_periodic( void (*)(), int );

The function pointed to by first argument is called when the number of seconds specified by the second argument have elapsed and then again repeatedly when that number of seconds has elapsed since the last call.


ws_open_callback() is called when a new connection is received.
int ws_open_callback( void *, char *cookie, char *hostname, char *protocol );

Return 0 from ws_open_callback() to indicate that the connection should be accepted. Return a non-zero value to indicate that the connection should be dropped.

The first argument is an opaque pointer that uniquely identifies the connection. You pass the pointer to other library functions as necessary.

The second argument points to the value of the client’s HTTP Cookie header. The second argument points to the virtual host to which the client connected. The third argument points to the WebSocket sub-protocol negotiated with the client.

If the web server is drood, the cookie will always be the empty string. If the web server is humdinger, the hostname and protocol will always be the empty string. You cannot use the same dorrit server with both drood and humdinger. By default, dorrit assumes the web server is drood. If the web server is humdinger, you must specify this with the -h command line option.

If the web server is humdinger, the cookie header is that presented by the client in the WebSocket upgrade request. If you need to authenticate your humdinger clients, send them to an SCGI application server to login and receive a session cookie with a 303 response. In the response, use a Location header to redirect your clients to the page that accesses the WebSocket server. Validate the cookie in ws_open_callback().

If the protocol your server implements requires the server to speak first, send the initial data with ws_write_conn() in ws_open_callback().


ws_close_callback() is called when a connection is closed.
void ws_close_callback( void *data );

The function’s argument is the opaque pointer identifying the connection. The library frees any outgoing queued data when ws_close_callback() returns.


ws_read_callback() is called when a complete WebSocket message has been read from the client. Dorrit unframes and unmasks the payload and passes it to this function.
void ws_read_callback( void *, int len, char *buffer );

The second argument is the length of the payload data in bytes. The length will never be greater than the defined buffer size less 5 bytes (Defaults to 65535 bytes. See the description of the -b option). The third argument is a character pointer to the payload data. This data is always zero-terminated. The terminator is not part of the incoming message and is not counted in the length argument.

The data space pointed to by the third argument is associated with the current connection. The content of this space is overwritten by the payload of each incoming message.


Queue an outgoing message for the client with ws_write_conn().
int ws_write_conn( void *, int len, char *data );

The function’s second argument is the length of the payload data in bytes. The third argument is a character pointer to the payload data. The data is copied to an internal buffer and does not have to be zero-terminated.

ws_write_conn() does not write the data but queues it for delivery. When the socket is writeable, the library will send up to one complete frame to the client, in discrete writes, until the outgoing queue is consumed. Writes are multiplexed with other events. Payloads greater in size than the defined buffer size - 5 are broken into fragment frames to facilitate smoother multiplexing.

ws_write_conn() will not queue more than 200 frames for any connection.

ws_write_conn() returns:

  • -1 if the queue could not be enlarged.
  • -2 if len is less than 1.
  • 0 on success.

If the function returns -1, the server cannot allocate memory. There is no point continuing to service this connection. Perform any clean up operations necessary, and call ws_close_conn() to drop the connection.


To close a connection, invoke ws_close_conn().
void ws_close_conn( int fd, int force );

ws_close_conn() closes a connection immediately if the second "force" argument is non-zero. If "force" is zero, the connection is closed when the outgoing queue has been written to the client. In that situation, further incoming data is not read from the client.

If a client closes its connection, the library calls ws_close_callback().


The library needs to catch SIGTERM, so do not change the disposition of that signal.

Upon receipt of SIGBUS or SIGSEGV, dorrit restarts servers with a call to execv(3). If you want to do something else, install your own handler.

If your server starts as root and changes user and group, the library will be unable to restart if your server is not executable by the user or group.

The library will be unable to perform the operations that require root privileges after restart unless you turn on the setuid bit of the server (chmod u=+s).


Dorrit writes its pidfile into /var/run/ if is started as root. The library is stopped with SIGTERM. A sample control script is provided in the dorrit distribution. To use the script, you must replace all occurrences of "dorrit" with the value you pass to ws_set_name(). The script must be renamed as the value you passed to ws_set_name() and installed in /usr/local/etc/rc.d.

Two variables must be added to /etc/rc.conf to use the script. Substitute your server’s name for "server":

server_flags="-u www -g www

If the "enable" variable is set to "YES", the server is started at system start. Use the following rc commands:

/usr/local/etc/rc.d/dorrit start
/usr/local/etc/rc.d/dorrit stop
/usr/local/etc/rc.d/dorrit restart
/usr/local/etc/rc.d/dorrit status

If you do not want the server started on system start, then set


and use the following commands:

/usr/local/etc/rc.d/dorrit forcestart
/usr/local/etc/rc.d/dorrit forcestop
/usr/local/etc/rc.d/dorrit forcerestart
/usr/local/etc/rc.d/dorrit forcestatus


The following command line options are recognized by dorrit servers. All of these are optional.
-b <number> By default, dorrit uses buffers of 65540 bytes to contain incoming WebSocket frames. 65535 is the largest size that can be specified in 16 bits. Dorrit does not support incoming WebSocket frames with larger payloads. 4 bytes are added to the buffer size for the WebSocket header. 1 byte is added for a zero terminator. 65535 + 4 + 1 = 65540. The mask for incoming frames is stored elsewhere.

Each incoming connection has a buffer allocated to hold incoming frames and two queues of buffers to hold incoming fragment frames and outgoing frames. To reduce memory consumption, you can specify a smaller buffer size with the -b option, but you cannot set the buffer size to less than 10 bytes or to more than 65540 bytes.

Dorrit will drop connections on which frames arrive with payloads greater than the buffer size less 5 bytes. If fragment frames arrive on a connection, each fragment’s payload must fit into the defined buffer size less 5 bytes, and the complete coelesced message must also fit into the defined buffer size less 5 bytes.

Support for incoming fragments is so limited because although browsers do not fragment outgoing frames, RFC6455 specifies that intermediaries can change the fragmentation of messages. If your clients do not send messages larger than those that will fit into the buffer size less 5 bytes, any fragments created by intermediaries will fit into the buffer size, and the reconstituted message will also fit into the buffer size.

You can queue outgoing messages of any size, but they will be broken into fragments of the defined buffer size or less.

-h By default, dorrit assumes the web server is drood. The -h option specifies that the web server is humdinger. This option must be set correctly for dorrit to function correctly. The option is either present or absent on the command line. The option takes no argument.
-l <path/to/socket>
  By default, dorrit listens on /var/run/dorrit.socket. If you set the server’s name with ws_set_name(), then "dorrit" in the preceding path is replaced with the name you set. To create the socket, dorrit must start as root. The -l option instructs the library to listen on another socket instead. Specify the full path to the socket as argument.

The server creates the listening socket when it starts, unlinking it first if it already exists in the filesystem. The owner and group of the socket are changed to the values of the -u and -g options. The permisssions of the socket are set to srwxrwx---.

-m <number> The -m option specifies the maximum number of connections which may be active at any time. The value defaults to 2000.
-u <string>
-g <string>
  The -u and the -g options are used to specify the user and group for the server. Both values default to "nobody". For dorrit to change user, it must be started as root.

Dorrit restarts servers on receipt of SIGSEGV or SIGBUS.

If your server starts as root and changes user and group, the library will be unable to restart if your server is not executable by the user or group.

The library will be unable to perform the operations that require root privileges after restart unless you turn on the setuid bit of the server (chmod +s).

-x The -x option prevents Dorrit from becoming a daemon and writing its pidfile to /var/run/. Dorrit runs in the foreground. Stderr is connected to the terminal so that diagnostic output can be sent there. The option takes no argument.
-f <path/to/file> The -f option takes a filename as argument. Dorrit assigns the filename to the global character pointer ws_config_file. This enables code in ws_init_func() and to access a configuration file.


.An James Bailie Aq
Search for    or go to Top of page |  Section 8 |  Main Index

Powered by GSP Visit the GSP FreeBSD Man Page Interface.
Output converted with manServer 1.07.