We’ve just released a new version of WASP, our pluggable application server platform. This release is built with release 6.5.2 of The Server Framework and includes support for secure TCP connections using SSL/TLS via our SChannel Option pack.
Setting up a secure TCP endpoint with WASP is easy, simply add the Secure configuration option to the <EndPoint> node like this:
<?xml version="1.0" encoding="Windows-1252"?> <Configuration> <WASP> <TCP> <Endpoints> <EndPoint Name="Echo Server" Port="5050" HandlerDLL="[CONFIG]\EchoServer.
As you’ve seen from some of the earlier tutorials, WASP has quite a few command line parameters that can change how it runs. You can run WASP as a normal executable or install it as a Windows Service. The complete set of command line options are displayed if you run WASP with /help or with an option that it doesn’t understand but I thought I’d list them all here for completeness and so that I can explain in a little more detail what each one does.
So far the tutorials have focused on a simple length prefixed message type. This is probably the easiest message in the world to process, the message framing is very simple and there’s hardly anything to do in your message framing DLL. Unfortunately not all protocols are this simple to parse. Another common real-world protocol is a line based protocol that is delimited by a terminating character, or characters. One such protocol is the POP3 protocol which works in terms of commands which are delimited by the CR LF sequence.
As you have discovered if you’ve been following the tutorials, WASP is configured using an XML file.
This file can either live in the same directory as the WASP executable or, for when you’re running WASP as a Windows Service, it can live in a place that is configured in the registry.
The file is pretty simple and we’ve covered most of the options in the various tutorials but there are some configuration options that we haven’t touched on yet and it seems sensible to have one place to look for details of all of the options that you can configure in the config file.
By now you’ve probably taken a look inside of the WASP SDK header, WASPDLLEntryPoints.h and seen all of the various plugin entry points that you can export from your plugin. This tutorial will explain what each of them is for and how you use them and will present a simple plugin which uses all of the entry points and logs its actions to WASP’s debug log.
As you’ve seen from the previous tutorials, a WASP plugin can be either a message framing DLL or a message handling DLL or both depending on the entry points that it exports.
A single WASP plugin can be loaded by multiple end points to provide the same server on multiple ports. A plugin could, for example, be configured on one end point to provide services to the internal network and on another end point to provide services to the internet. Alternatively, in later WASP releases, a single plugin may be used to provide services over an insecure link on one end point and via an SSL protected link on another.
So far our simple example WASP plugins have all used OnReadCompletedEx() which gives you both an input and an output buffer and assumes that you generate a single response to each inbound message. It also assumes that you wont write more data than will fit in a single I/O buffer. Whilst this is suitable for some server designs it’s quite restrictive. Most plugins will probably use a combination of OnReadCompleted() and the WASP callback function writeToConnection().
Way back in 2002 when I was developing ISO8583 servers for PayPoint I put together a two thread pool server design that has worked so well that many of the servers that I develop today still use variations on the original design. The main idea behind the design was that the threads that do the network I/O should never block and the threads that do the user work can block if they like.
The simple echo server plugin that we developed in the earlier tutorial was easy to test using telnet as it simply echoed all data back to the client. The plugin which used simple message framing was less easy to test using telnet as you first needed to enter the correct bytes to specify a message length as an int in network byte order.
Neither plugin was easy to stress test using telnet as you’d need lots of monkeys and lots of machines to simulate lots of users.
Most TCP servers deal with distinct messages whereas TCP itself deals in terms of a stream bytes. By default a single read from a TCP stream can return any number of bytes from 1 to the size of the buffer that you supplied. TCP knows nothing about your message structure. This is where message framing comes in. If the protocol that you are supporting has a concept of what constitutes a “message” then your protocol requires message framing.