libmessageserver(3)    FreeBSD Library Functions Manual    libmessageserver(3)

NAME
     libmessageserver - Message-Oriented Server Library

SYNOPSIS
     #include <messageserver.h>
     -I/usr/local/include -L/usr/local/lib -lmessageserver (or -lmessageserver_tls -lcrypto -lssl)

DESCRIPTION
     LibMessageServer implements generic, event-driven, message-oriented
     servers.  MessageServer performs network and concurrency tasks.  You
     supply code to produce and consume messages.

     LibMessageServer and LibMessageClient make it easy to write network
     clients and servers that exchange messages of arbitrary size, structure,
     and content.  MessageServer provides the framing mechanism.  You
     implement your application protocol on top of MessageServer.

     Frames consist of 2 bytes of length header followed by frame content.
     The most significant byte of the length occurs first in the header.  A 2
     byte length field limits the maximum frame size to 65535 bytes.  Messages
     of the maximum frame size or less are sent as single frames.  Messages
     greater than the maximum frame size are sent in fragments of the maximum
     frame size or less.  Fragmented messages are preceded and terminated by a
     frame of 0 length.  The limited size frame is to facilitate multiplexing
     in application protocols.

     Separate libraries service TLS encrypted and unencrypted connections. The
     libraries' interfaces are identical. The same code can be linked against
     either library.  The TLS configuration is provided by a file specified
     with the -t option.  To enable OCSP stapling, follow the instructions in
     the file message_ocsp.

     Example echo servers and clients are included in the LibMessage source
     distribution.

   USAGE
     The library provides your server's "main" function.  You define 6
     functions to match the following prototypes.

     void ms_init_func();
     void ms_exit_func();

     int ms_open_callback( void *, char * );
     void ms_read_callback( void *, int, int, unsigned char * );
     void ms_write_callback( void * );
     void ms_close_callback( void * );

     Do not define any other global symbol beginning with the 3 characters
     'ms_' because the library reserves that namespace.

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

     MessageServer calls ms_init_func():

     o   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
         ms_init_func(), executes as root.

     o   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.

   MS_EXIT_FUNC()
     If you have exit handlers you would like to register to run before the
     server exits, do not invoke atexit() from ms_init_func().  If you do so,
     your handlers are run when the server becomes a daemon.  The server forks
     to create a new session.  The dying parent process will call your
     handlers when it exits.  Instead, call your cleanup code from
     ms_exit_func().

   MS_SET_NAME()
     Call ms_set_name() inside ms_init_func() to set the server's name.

     void ms_set_name( char * );

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

     o   When the server is running, stderr is connected to /dev/null.  Errors
         must are reported with syslog(3).  MessageServer calls openlog() with
         the server's name as argument to ensure that log entries are
         identified by the server's name.

     o   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 MessageServer distribution.

     o   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 message.socket.  With the server's name
         explicitly set, the name is <name>.socket.

   MS_SET_PERIODIC()
     Install a function to be invoked periodically with:

     void ms_set_periodic( void (*)(), int );

     MessageServer calls the function pointed to by first argument 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.

   MS_OPEN_CALLBACK()
     MessageServer calls ms_open_callback() when a new connection is received.

     int ms_open_callback( void * );

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

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

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

   MS_SET_DATA()

   MS_GET_DATA()
     Use ms_set_data() to associate a void pointer with a connection.

     void ms_set_data( void *conn, void *data );

     The data argument is a pointer of any kind that you want to associate
     with the connection referenced by the conn argument.

     Use ms_get_data() to retrieve the stored pointer.

     void *ms_get_data( void *conn );

   MS_CLOSE_CALLBACK()
     MessageServer calls ms_close_callback() when a connection is closed.

     void ms_close_callback( void *data );

     The function's argument is the opaque pointer identifying the connection.
     MessageServer frees any outgoing queued data when ms_close_callback()
     returns.

   MS_READ_CALLBACK()
     MessageServer calls ms_read_callback() when a complete frame has been
     read from the client.

     void ms_read_callback( void *, unsigned int len, unsigned char *buffer );

     The second argument is the length of the frame. This is never greater
     than 65535, which is the maximum frame size.  If the length is the
     maximum frame size or less, the frame contains a complete message.  If
     the frame length is 0, this frame indicates that a fragmented message
     follows.  The succeeding frames carry message content in resource order.
     A final frame of length 0 terminates the fragmented message.

     The third argument is a character pointer to the frame content.  The
     third argument points into a buffer that will be subsequently freed.  If
     you want to preserve the frame when ms_read_callback returns, copy the
     content to another location.

   MS_QUEUE_MESSAGE()
     Queue an outgoing message for clients with ms_queue_message().

     int ms_queue_message( void **, int conns, unsigned int len, unsigned char *data );

     The first argument is a pointer to an array of opaque pointers
     representing the connections to which the data will be written.

     The second argument is the number of elements in the first argument.

     The third argument is the length of the message in bytes.

     The fourth argument is a character pointer to the message.

     ms_queue_message() queues the message for delivery for each connection in
     conns.  All queued data is reference counted to avoid unnecessary
     copying.

     Messages that fit within the maximum frame size are delivered in single
     frames.  Messages greater than the maximum frame size are delivered in
     multiple fragment frames.

     ms_queue_message() returns:

     o   -2 if the length is > 65535.

     o   -1 on allocation errors.

     o   0 on success.

   MS_QUEUE_FRAME()
     Queue an outgoing frame for clients with ms_queue_frame().

     int ms_queue_frame( void **, int conns, unsigned int, unsigned char *data );

     The first argument is a pointer to an array of opaque pointers
     representing the connections to which the data will be written.

     The second argument is the number of elements in the first argument.

     The third argument is the length of the message in bytes. The length must
     be <= 65535 bytes.

     The fourth argument is a character pointer to the frame data.

     ms_queue_frame() queues the frame for delivery for each connection in
     conns.  All queued data is reference counted to avoid unnecessary
     copying.

     You can explicitly send a 0 length frame. This enables you to manually
     fragment messages that you do not know the size of in advance.  The
     individual message fragments must have lengths in the range of 1 to
     65535.  The fragmented message must be preceded and terminated by 0
     length frames.

     You can avoid queueing an entire long message in memory by queueing the
     message in portions from ms_write_callback().

     ms_queue_frame() returns:

     o   -2 if the length is > 65535.

     o   -1 on allocation errors.

     o   0 on success.

   MS_WRITE_CALLBACK()
     ms_write_callback() is called when the outgoing queue of frames for a
     connection has been exhausted.

     void ms_write_callback( void * );

     The argument is the opaque pointer that identifies the connection.

   MS_CLOSE_CONN()
     To close a connection, invoke ms_close_conn().

     void ms_close_conn( void *, int force );

     ms_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.

   SIGNALS
     MessageServer needs to catch SIGTERM, so do not change the disposition of
     that signal.

     Upon receipt of SIGBUS or SIGSEGV, MessageServer 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.

     MessageServer 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).

   CONFIGURATION
     MessageServer 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 MessageServer distribution.  To use the script, you must replace
     all occurrences of "messageserver" with the value you pass to
     ms_set_name().  The script must be renamed as the value you passed to
     ms_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_enable="YES"
     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/messageserver start
     /usr/local/etc/rc.d/messageserver stop
     /usr/local/etc/rc.d/messageserver restart
     /usr/local/etc/rc.d/messageserver status

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

     messageserver_enable="NO"

     and use the following commands:

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

   COMMAND-LINE OPTIONS
     The following command line options are recognized by Message Servers.
     All of these are optional.

     -p  The -p option specifies the port to listen on.  This defaults to
         8000.  To bind to a port lower than 1024, the server must be started
         as root.

     -i  By default, MessageServer accepts connections on all interfaces it
         can find capable of IPv4 or IPv6.  The -i option limits dombey to
         accepting connections from a specified interface.  Pass the IP
         address of the desired interface as argument.

     -l  The -l option causes MessageServer to listen on a UNIX domain socket
         instead of the IP interfaces.  Specify the fully qualified name of
         the socket as argument.  To create the socket, MessageServer must
         start as root.

         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  By default, MessageServer maintains no more than 16384 simultaneous
         connections.  The -m option changes this value.

     -u

     -g  The -u and the -g options are used to specify the user and group for
         the server.  If the server starts as an unprivileged user and group,
         then these options must be set to the user and group.  For
         MessageServer to change to a different user and group, it must be
         started as root.  Both values default to "nobody".

         MessageServer 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.

         MessageServer 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 MessageServer from becoming a daemon and
         writing its pidfile to /var/run/.  MessageServer runs in the
         foreground.  Stderr is connected to the terminal so that diagnostic
         output can be sent there.  The option takes no argument.

     -f  The -f option takes a filename as argument.  MessageServer assigns
         the filename to the global character pointer ms_config_file.  This
         enables code in ms_init_func() and to access a configuration file.

     -o  The -o option is only understoood by -lmessageserver_tls. The option
         specifies the fully qualified path to a file containing an OCSP
         response to be stapled to the TLS handshake.

     -t  The -t option is only understood by -lmessageserver_tls.  The option
         specifies the fully qualified path to a TLS configuration file
         containing 3 lines of text.  The first line is the fully qualified
         path to the file holding the server key in PEM format. The second
         line is the the password for the key.  This line can be blank if
         there is no password.  The third line is the fully qualified path to
         the file containing the certificate chain in PEM format.

AUTHORS
     James Bailie <jimmy@mammothcheese.ca>
     http://www.mammothcheese.ca

                                Tue Dec 9, 2018