Advanced features of Grapple

This file contains some of the more obscure, less needed, yet more powerful
features of Grapple. Rather than clutter up the main README with stuff
most people will never need, they are here.

PACKET ORDERING IN UDP
----------------------
By default, a UDP connection processes packets in the order they are
transmitted, ensuring data ordering is correct.

In a situation where the order of data is unimportant, then UDP  sockets
can be told to process data in the order it is received. This will have
the effect of reducing latency at the cost of leaving the order of 
processing to be unsure.

grapple_client_sequential_set(grapple_client client,int value)

This will set sequential processing to on or off depending on the
value passed, either GRAPPLE_SEQUENTIAL or GRAPPLE_NONSEQUENTIAL

grapple_client_sequential_get(grapple_client client)

This will return the value currently set for sequential processing. 1 for
on and 0 for off.

The server has equivalent functions

grapple_server_sequential_set(grapple_server server,int value)
grapple_server_sequential_get(grapple_server server)

IMPORTANT NOTE:
Setting the sequential mode of a connection ONLY affects the receiving
end of the connection. If you want both ends to be sequential or not,
then you must set such a request at each end.

SIMPLE SERVER MODE
------------------
Sometimes you may just want to write an application using
grapple, where the clients are not allowed to know each others
identity.

grapple_server_notified_set(grapple_sever server,int state)

will stop the server notifying the clients of each others existance.

This will NOT prevent things like notifications of group joins or pretty much
anything else notifying clients of other clients existance, but it simply
prevents the notify messages being sent for connect/disconnect events.

The state can be
GRAPPLE_NOTIFY_STATE_ON
GRAPPLE_NOTIFY_STATE_OFF

The default state is GRAPPLE_NOTIFY_STATE_ON

SIMPLE CLIENT MODE
------------------
Sometimes you may just want to write a simple client server application using
grapple, that is not required to know all of the other users who are
connected. Using the function

grapple_client_notified_set(grapple_client client,int state)

will allow you to save the bandwidth and processing overhead of sending 
the client list

The state can be
GRAPPLE_NOTIFY_STATE_ON
GRAPPLE_NOTIFY_STATE_OFF

The default state is GRAPPLE_NOTIFY_STATE_ON

Name Policies
-------------
It is possible to restrict the use of names based on a policy. 

  grapple_server_namepolicy_set(grapple_server,grapple_namepolicy)

  The namepolicy should be set to one of either

     GRAPPLE_NAMEPOLICY_NONE
       There are no rules on which names are used, or even IF names are used
       This is the default state.

     GRAPPLE_NAMEPOLICY_REQUIRED
       A name is required but there is no restriction on what the name is

     GRAPPLE_NAMEPOLICY_UNIQUE
       A name is required and it must be unique


Protection Key Policies
-----------------------
It is possible to add a level of protection into Grapple products, ensuring
that each user connecting to a server has a unique key.

  grapple_server_protectionkeypolicy_set(grapple_server,
                                         grapple_protectionkeypolicy)

  The protectionkeypolicy should be set to one of either

     GRAPPLE_PROTECTIONKEYPOLICY_NONE
       There are no requirements for having a key.
       This is the default state.

     GRAPPLE_PROTECTIONKEYPOLICY_UNIQUE
       A key is required and it must be unique


The client, before connecting, must set a key, if the policy requires one.
This key must be set before grapple_client_start() is called, using.

  int grapple_client_protectionkey_set(grapple_client,const char *key)


If the key is not unique, then a connection failed message will be returned,
with the reason of GRAPPLE_NOCONN_PROTECTIONKEY_NOT_UNIQUE


Advanced Password Processing
----------------------------
If a simple password for the game is not enough, then grapple has the
facility to use complex password processing routines.

You can set a callback to use for the password processor, which will
hand the name and password to your callback function. From this function
simply return 1 for success, 0 for failure.

int grapple_server_passwordhandler_set(grapple_server server,
				       grapple_password_callback callback,
				       void *context);

The callback needs to be of the form
int callback(const char *login,const char *password, void *context)

The context passed into the callback is the same as the context passed into
the set function.

WARNING: You should not make this callback too complex, as it blocks the
main data processing thread of Grapple until it is complete. 

Advanced User Handling
----------------------
If you need advanced processing to determind if a user is allowed to connect,
Grapple allows this using a callback which is called when a user has passed
all other connection criteria.

This will allow things like banning users by IP address, or other such
tests you may need to make. The callback should return 0 to block the
connection, or 1 to allow the connection.

int grapple_server_connectionhandler_set(grapple_server server,
	                                 grapple_connection_callback callback,
                                         void *context);

The callback needs to be of the form
int callback(grapple_user userid, void *context,void *data)

The context passed into the callback is the same as the context passed into
the set function.

The userid that is returned is the user ID that can be used to use grapple
functions to query information about a user.

WARNING: You should not make this callback too complex, as it blocks the
main data processing thread of Grapple until it is complete. 

Server Failover
---------------
If a host disconnects, then that is the end of the session, unless you
have server failover running. This system allows other hosts to take over
the task of being the server.

Some hosts cannot be the server, due to firewalls or other restrictions,
so server failover does 'the best it can'.

To turn on server failover simply use

grapple_server_failover_set(grapple_server server, int value)

  where value is 1 for on and 0 for off


Grapple will then sort itself out behind the scenes. The host will be notified
of its new status with the message

GRAPPLE_MSG_YOU_ARE_HOST

The other clients are never informed, as they do not need to know.

The server failover state can be obtained with the function

grapple_server_failover_get(grapple_server server)

which will return 0 or 1, depending on the failover state

NOTE: This system ONLY moves the control system of the multiplayer layer,
it does NOT handle all the things your game will need to do to take over the
hosting of the system. All messages will come to the new host, all player to
player messages will route through the new host, but there is no way for the
hew host to know how to restructure the internal GAME data.

IMPORTANT:
When the game is shutting down intentionally, you must turn off failover,
or clients will failover to the next server and so on.

Encryption
----------

Grapple supports SSL encryption over TCP connection

To enable encryption, the server must initialise this somewhere
between grapple_server_protocol_set and grapple_server_start

The function for enabling encryption is

grapple_server_encryption_enable(grapple_server,
                                 const char *private_key,
                                 const char *private_key_password,
                                 const char *public_key)

From this point on, all communication to and from the server will be
encryptyed. You cannot turn off encryption once it is turned on. The server
will not understand, and will drop connections from, any connection where
the client is not encrypted.

The values passed into the function are optional public and private key
strings. These are ascii keys.
These may be ignored and NULL be passed in, and the server will generate a
single-use key for this one instance. If you pass in a set of keys, this
can be used to tie in to the client side which may also define a
certificate authority, to verify the authenticity of the public key that
is sent to it.
The private_key_password is a password that may have been set into the private
key. If the key has no password, or you are generating a single use key,
you should set this to NULL.


From the client side, a client connecting to an encrypted server must
enable encryption somewhere between grapple_client_protocol_set and 
grapple_client_start

The function for enabling encryption is

grapple_client_encryption_enable(grapple_client,const char *cert_auth)

The cert_auth perameter is optional, and should only be used if the client
wishes to verify that the server is the correct server, and that the key
passed during the encryption startup is valid.
The cert_auth is the ascii public key of the certificate signer used to sign
the servers keys. If cert_auth is NULL, then no check for authenticity of
the servers key will be made, but the data stream will still be encrypted.

If the server is initialised with NULL keys, that is, it generates its key
itself, then passing a cert_auth into the client will always cause the 
connection to fail, as the key passed will not be valid for the cert_auth.

Once encryption is enabled, Grapple is used in the same ways as without
encryption. The only change is the underlying data stream.

NOTE: Encryption can ONLY be used with TCP as the protocol, UDP at this time
cannot be used in encrypted mode

----------------------------
VARIOUS USEFUL TOOLS

In the making of Grapple, some internal tools have been asked to be made 
part of the interface. These are as follows

const char **grapple_local_addresses_get()

This will return a NULL terminated array of char *'s containing the local
IP addresses of the machine.

This array is statically allocated memory and should not be free'd or written
to. It will not change