summaryrefslogtreecommitdiff
path: root/docs/common/lib_server
diff options
context:
space:
mode:
Diffstat (limited to 'docs/common/lib_server')
-rw-r--r--docs/common/lib_server/Daemon.txt96
-rw-r--r--docs/common/lib_server/Protocol.txt120
-rw-r--r--docs/common/lib_server/ServerStream.txt29
-rw-r--r--docs/common/lib_server/ServerTLS.txt6
-rw-r--r--docs/common/lib_server/SocketStream.txt8
-rw-r--r--docs/common/lib_server/SocketStreamTLS.txt11
-rw-r--r--docs/common/lib_server/TLSContext.txt16
7 files changed, 286 insertions, 0 deletions
diff --git a/docs/common/lib_server/Daemon.txt b/docs/common/lib_server/Daemon.txt
new file mode 100644
index 00000000..6956ec2b
--- /dev/null
+++ b/docs/common/lib_server/Daemon.txt
@@ -0,0 +1,96 @@
+CLASS Daemon
+
+Implement a UNIX daemon which
+
+* Daemonises (detach from console, etc)
+* Sets up signal handlers, and does useful things with them
+* Reads configuration files
+* Writes PID file
+* Opens syslog
+
+all the usual UNIX basic daemon behaviour.
+
+The daemon exe takes optional arguments: The first is a configuration file filename which overrides the default. If the second argument is 'SINGLEPROCESS' the daemon will not daemonise.
+
+The configuration file must have a section like this
+
+Server
+{
+ PidFile = /var/run/daemon.pid
+ User = username
+}
+
+Use DAEMON_VERIFY_SERVER_KEYS (defined in Daemon.h) to include the necessary keys in your configuration file's verify structure.
+
+The "User" line is optional, and if it is present the Daemon will change user to this username just before it daemonises. Note that unless the directory the PID file is written to has write permission for this user, the PID file will not be deleted on exit.
+
+
+To implement a daemon, derive a class from Daemon, and override Run().
+
+Then in your main file, do something like
+
+int main(int argc, const char *argv[])
+{
+ MAINHELPER_START
+
+ BackupDaemon daemon;
+ return daemon.Main(BOX_FILE_BBACKUPD_DEFAULT_CONFIG, argc, argv);
+
+ MAINHELPER_END
+}
+
+and that's it. Obviously it's worth doing a few more things as well, but that's it.
+
+
+FUNCTION Daemon::Run()
+
+Override with the main daemon code. It should behave like this
+
+void SomethingDaemon::Run()
+{
+ // Read configuration file
+
+ // Do lots of work until StopRun() returns true
+ while(!StopRun())
+ {
+ ::sleep(10);
+ }
+
+ // Clean up nicely
+}
+
+which allows the base class to implement the standard start, terminate and -HUP behaviours correctly.
+
+
+FUNCTION Daemon::DaemonName()
+
+Returns the name of the daemon, for use in syslog.
+
+
+FUNCTION Daemon::DaemonBanner()
+
+Returns the banner to be displayed on startup, or 0 for no banner.
+
+
+FUNCTION Daemon::GetConfigVerify()
+
+Returns a configuration verify structure for verifying the config file. Note that this configuration structure should include a sub-configuration called "Server, and have entries defined by DAEMON_VERIFY_SERVER_KEYS. See one of the bin/bbackupd for an example.
+
+
+FUNCTION Daemon::StopRun()
+
+Returns true when the daemon needs to be terminated or restarted. Use IsReloadConfigWanted() and IsTerminateWanted() to find out which one, if you need to know.
+
+
+FUNCTION Daemon::SetupInInitialProcess()
+
+Override to perform additional functions in the initial process, before forking and detachment happens.
+
+
+FUNCTION Daemon::EnterChild()
+
+Called when a child is entered. If you override it, remember to call the base class.
+
+
+
+
diff --git a/docs/common/lib_server/Protocol.txt b/docs/common/lib_server/Protocol.txt
new file mode 100644
index 00000000..09d3c1f1
--- /dev/null
+++ b/docs/common/lib_server/Protocol.txt
@@ -0,0 +1,120 @@
+CLASS Protocol
+
+Protocol
+
+* serialises and deserialises data objects
+* sends arbitary streams
+
+through a bi-directional IOStream object, usually a socket.
+
+These data objects are auto-generated by a perl script, along with the logic to implement a simple protocol where one end is a client, and the other a server. The client sends a command object (and optional streams) and the server returns a reply object (and optional streams).
+
+The perl script uses a description file which specifies the data inside these objects (which can be extended to include any type which implements the standard serialisation functions), the required responses to the commands, and whether streams are involved.
+
+It then implements a server object, which given a stream and a user defined context object, waits for commands, processes them, and sends the results back. All you need to do is implement a DoCommand() function for each command object you define.
+
+On the client side, a Query() function is implemented which takes objects as parameters, and returns the right type of reply object (or throws an exception if it doesn't get it.) Short cut Query<CommandName>() functions are also implemented which don't require objects to be created manually.
+
+Thus, implementing a server is as simple as deriving a daemon off ServerStream or ServerTLS, and implementing the Connection() function as
+
+ void TestProtocolServer::Connection(SocketStream &rStream)
+ {
+ TestProtocolServer server(rStream);
+ TestContext context;
+ server.DoServer(context);
+ }
+
+and that's it. TestContext is a user defined class which keeps track of all the state of the connection, and is passed to all the DoCommand() functions, which look like this:
+
+ std::auto_ptr<ProtocolObject>
+ TestProtocolServerSimple::DoCommand(TestProtocolServer &rProtocol,
+ TestContext &rContext)
+ {
+ return std::auto_ptr<ProtocolObject>
+ (new TestProtocolServerSimpleReply(mValue+1));
+ }
+
+(taken from test/basicserver)
+
+The client code looks like this
+
+ SocketStream conn;
+ conn.Open(Socket::TypeUNIX, "testfiles/srv4.sock");
+
+ TestProtocolClient protocol(conn);
+
+ // Query
+ {
+ std::auto_ptr<TestProtocolClientSimpleReply>
+ reply(protocol.QuerySimple(41));
+ TEST_THAT(reply->GetValuePlusOne() == 42);
+ }
+
+
+Finally, debug logging can be generated which allows a list of all commands and their parameters to be logged to syslog or a file.
+
+
+SUBTITLE Protocol Description File
+
+This file is passed to the lib/server/makeprotocol.pl script, which generates a h and cpp file to implement the protocol.
+
+It is in two sections, separated by a 'BEGIN_OBJECTS' on a line of it's own.
+
+In the top half, the following statements must be made.
+
+Name <name>
+ The name of the protocol, used in naming classes.
+
+IdentString <string>
+ The idenfitifaction string sent over the IOStream to confirm it it
+ is talking to another Protocol object speaking the same Protocol.
+
+ServerContextClass <class-name> <header-file>
+ The user defined context class used for the server, and the header
+ file it is defined in.
+
+Additionally, the following optional commands can be made.
+
+ClientType <description-typename> <C++ typename> <headerfile>
+ServerType (similarly)
+ Extends the types used in the objects below. Server and client
+ can use different types for the same object type.
+
+ImplementLog (Client|Server) (syslog|file)
+ Implement command logging for client or server into syslog or a file.
+
+LogTypeToText (Client|Server) <description-typename> <printf-element>
+ <evaluate>
+ For extended types, optionally define how to convert them into printf
+ elements and the code to run to get the argument. Within the evaluate
+ parameter, VAR is replaced by the name of the variable to display.
+ If this is not specified for a given type, OPAQUE is output instead.
+
+
+In the object section, an object is defined by a line
+
+<name> <id number> <attributes>
+
+followed by lines beginning with whitespace defining the data transmitted in the object. The type may be list<type>, which specifies a list (implemented as a std::vector) of entries of that type.
+
+The attributes specify exactly how that object is used in the defined protocol.
+
+Reply
+ The object is a reply object, sent from the server to the client.
+
+Command(Reply-Type)
+ The object is a command, send from the client to the server, and the server
+ will send back an object of type Reply-Type.
+
+IsError(Type-Field,SubType-Field)
+ The command is an error object, and the two files specify the data member
+ which describes the error type and sub type.
+
+EndsConversation
+ When this command is received, the connection is to be terminated.
+ (ie a logout command)
+
+StreamWithCommand
+ When this command is sent as a command, a stream follows it.
+
+
diff --git a/docs/common/lib_server/ServerStream.txt b/docs/common/lib_server/ServerStream.txt
new file mode 100644
index 00000000..6c5932a0
--- /dev/null
+++ b/docs/common/lib_server/ServerStream.txt
@@ -0,0 +1,29 @@
+CLASS ServerStream
+
+ServerStream implementes a Daemon which accepts stream connections over sockets, and forks into a child process to handle them.
+
+To implement a daemon, derive from
+
+ ServerStream<SocketStream, SERVER_LISTEN_PORT>
+
+The type SocketStream specifies that incoming connections should be treated as normal sockets, and SERVER_LISTEN_PORT is the port to listen to (if it's a inet socket, and if not overridden in the config file). The actual addresses (or names) to bind to are specified in the configuration file by the user.
+
+Make sure SERVERSTREAM_VERIFY_SERVER_KEYS(0) is included in the configuration verification structure in the "Server" sub configuration. 0 could be replaced with a default address, for example "unix:/var/run/server.sock" to specific a default UNIX socket in the filesystem.
+
+See test/basicserver for a simple example.
+
+The ListenAddresses key in the Server subconfiguration is a comma separated list of addresses, specified as family:name. Internet sockets are family 'inet', for example 'inet:localhost' (or 'inet:localhost:1080' to specify a port number as well), and unix domain sockets are 'unix', example above.
+
+
+Override Connection to handle the connection.
+
+Remember to override Daemon functions like the server name, and start it up, just like a generic Daemon.
+
+
+FUNCTION ServerStream::Connection
+
+This function takes a connected stream as it's argument. It should then proceed to do whatever it needs to do to talk to the client.
+
+Using IOStreamGetLine or a Protocol class to communicate may be quick ways of implementing this functionality.
+
+
diff --git a/docs/common/lib_server/ServerTLS.txt b/docs/common/lib_server/ServerTLS.txt
new file mode 100644
index 00000000..dbde500f
--- /dev/null
+++ b/docs/common/lib_server/ServerTLS.txt
@@ -0,0 +1,6 @@
+CLASS ServerTLS
+
+Implements a server which uses TLS (SSL) to encrypt and authenticate connections.
+
+Very similar to ServerStream, except it reads the certificate files for the TLSContext out of the Server sub-configuration to set up a TLSContext ("CertificateFile", "PrivateKeyFile" and "TrustedCAsFile"). Otherwise works exactly the same.
+
diff --git a/docs/common/lib_server/SocketStream.txt b/docs/common/lib_server/SocketStream.txt
new file mode 100644
index 00000000..82813279
--- /dev/null
+++ b/docs/common/lib_server/SocketStream.txt
@@ -0,0 +1,8 @@
+CLASS SocketStream
+
+A implementation of IOStream which wraps a socket connection.
+
+It can either be created by attaching to an existing object, or use the Open() function to open a connection to a named host on a specific port (or a local UNIX socket in the filesystem).
+
+Follows stream interface.
+
diff --git a/docs/common/lib_server/SocketStreamTLS.txt b/docs/common/lib_server/SocketStreamTLS.txt
new file mode 100644
index 00000000..ebb3f233
--- /dev/null
+++ b/docs/common/lib_server/SocketStreamTLS.txt
@@ -0,0 +1,11 @@
+CLASS SocketStreamTLS
+
+An implementation of IOStream which wraps a TLS (SSL) connection over a socket.
+
+The Open function takes a TLSContext reference which specifies the parameters for the connection.
+
+
+FUNCTION GetPeerCommonName()
+
+Returns the common name of the certificate presented by the remote end.
+
diff --git a/docs/common/lib_server/TLSContext.txt b/docs/common/lib_server/TLSContext.txt
new file mode 100644
index 00000000..ff50d3e6
--- /dev/null
+++ b/docs/common/lib_server/TLSContext.txt
@@ -0,0 +1,16 @@
+CLASS TLSContext
+
+A wrapper over the OpenSSL context object.
+
+Note: you need to call SSLLib::Initialise at the beginning of your program to use these functions.
+
+
+SUBTITLE Construction
+
+The constuctor takes the following parameters
+
+* Boolean for whether this is acting as a server or a client
+* The .pem file containing the certificate which will be used
+* The .pem file containing the private key for this certificate
+* The .pem file containing the certificates which will certify the other end of the connection.
+