/* File: transport.h * Author: Ed Griffiths (edgrif@sanger.ac.uk) * Copyright (c) J Thierry-Mieg and R Durbin, 2000 *------------------------------------------------------------------- * This file is part of the ACEDB genome database package, written by * Richard Durbin (Sanger Centre, UK) rd@sanger.ac.uk, and * Jean Thierry-Mieg (CRBM du CNRS, France) mieg@kaa.crbm.cnrs-mop.fr * * Description: This header defines the interface that a transport layer * must provide for the acedb server code. The transport * layer might be sockets, RPC or whatever, but it must * provide certain services for the server. * HISTORY: * Last edited: Oct 18 14:14 2002 (edgrif) * Created: Fri Feb 11 09:59:06 2000 (edgrif) * CVS info: $Id: servertransport.h,v 1.9 2002/10/18 13:45:29 edgrif Exp $ *------------------------------------------------------------------- */ #ifndef DEF_TRANSPORT_H #define DEF_TRANSPORT_H /* It's assumed in the protocol that ints are 4 bytes, this will stop the */ /* code from compiling, but we also do a run time check (although I can't */ /* imagine that a 32-bit binary can really be run with ints that aren't 4 */ /* bytes...). */ /* n.b. solaris seems unable to cope with this test. */ /* */ #ifndef SOLARIS #if (UINT_MAX != 4294967295U) #error "WARNING !! You cannot compile this program, it requires 4 byte integers and this machine does not have them." #endif #endif /* MESSAGE DEFINITION: */ /* */ /* Messages are passed between client and server, each message has a header */ /* and a body. The header contains fields that show whether the header needs */ /* swopping, what sort of message it is and the length of the body of the */ /* message. */ /* serverVersion in the message header is set by the server to this number */ /* to indicate the level of the protocol used. We may or may not use this */ /* to modify the protocol at a later date. */ enum {ACESERV_CURRENT_SERVER_VERSION = 1} ; /* The client sets swapMagic to OK_MAGIC if on the server side it appears as SWAP_MAGIC then the server will swap bytes in the headers in both directions, so the client never needs to swap */ #define OK_MAGIC 0x12345678 #define SWAP_MAGIC 0x78563412 /* We strings rather than enums, easier for others to interface to... */ /* No ACESERV_MSGnnn string should be longer than */ /* (ACESERV_MSGTYPE_BUFLEN - 1) */ /* you must not lightly change this length, this is the size clients will */ /* be expecting, to change it means changing all clients. */ /* */ enum {ACESERV_MSGTYPE_BUFLEN = 30} ; /* Client only, its messages are either normal requests (commands) or are */ /* ace data that needs to be parsed in. */ #define ACESERV_MSGREQ "ACESERV_MSGREQ" #define ACESERV_MSGDATA "ACESERV_MSGDATA" /* Server only, it may just be sending or a reply or it may be sending an */ /* instruction, such as "operation refused". */ #define ACESERV_MSGOK "ACESERV_MSGOK" #define ACESERV_MSGENCORE "ACESERV_MSGENCORE" #define ACESERV_MSGFAIL "ACESERV_MSGFAIL" #define ACESERV_MSGKILL "ACESERV_MSGKILL" /* The message header struct, this has to be packed into the the first */ /* ACE_HEADER_BYTES of a message sent between client & server. */ /* ATTENTION if you modify this struct, modify also headerPack, headerUnpack */ /* and the two constants below. */ /* Number of fields in the header that may need to be byte swopped. */ enum {ACE_HEADER_SWAPFIELDS = 5} ; /* Because we want a CONSTANT size for the buffer, we define this very */ /* tediously...we have 6 ints of 4 bytes each and a char buffer to hold the */ /* message type which is ACESERV_MSGTYPE_MAXLEN long. */ enum {ACE_HEADER_BYTES = ((4 * ACE_HEADER_SWAPFIELDS) + ACESERV_MSGTYPE_BUFLEN)} ; typedef struct _ACE_HEADER { int swapMagic ; /* Shows if header needs swapping */ int length ; /* Length of data being sent in bytes. */ int serverVersion ; /* not used ?? */ int clientId ; /* Unique client identifier. */ int maxBytes ; /* Maximum request size. */ char msgType[ACESERV_MSGTYPE_BUFLEN] ; /* See the msgs defined above. */ } *ACE_HEADER ; /* SERVER <-> TRANSPORT LAYER DEFINITION: */ /* */ /* The acedb server code communicates with the tranport layer via this */ /* interface. */ /* */ /* Opaque pointer to client connection details, needed here because acedb */ /* server layer needs sometimes to call the transport layer and pass in */ /* details of client connection. */ /* */ typedef struct _ClientConnectStruct *ClientConnect ; /* Type defines an id for a connection, typically this will be an int for a */ /* file descriptor. It needs to be something that can be used in a simple */ /* comparision. The acedb layers needs to check (for security reasons) that */ /* this connection id remains the same for a particular client id throughout */ /* the connection. Otherwise someone could start faking client ids in order */ /* to gain admin access. */ typedef int ClientConnectionID ; /* These types are to implement communication between the socket layer and */ /* the server. This communication all passes back and forth between */ /* the two via a single function call/return. What this all says is that */ /* each request has a target (either a single client or the whole server), */ /* and it also has an operation which needs to be performed. */ /* Some operations are specific to a client or a socket/server. */ /* */ /* A request can be for action on a client or server. */ typedef enum _AceSocketRequestTarget { ACESOCK_NONE, ACESOCK_SERVER, ACESOCK_CLIENT } AceSocketRequestTarget ; typedef enum _AceSocketRequestType { /* Initial invalid request. */ ACESOCK_NULL, /* Server/socket specific */ ACESOCK_SHUTQUIESCE, ACESOCK_SHUTFORCE, ACESOCK_EXIT, ACESOCK_TERM, /* Client specific */ ACESOCK_REQ, ACESOCK_KILL, /* common to both */ ACESOCK_TIMEDOUT } AceSocketRequestType ; /* The definition of the acedb server callback routine, this is the routine */ /* that the transport layer calls each time it receives a request from the */ /* network. */ typedef Stack (*AceSocketServerRequestRoutine)(void *serverData, ClientConnect client, ClientConnectionID connection_id, AceSocketRequestTarget *type_inout, AceSocketRequestType *req_inout, ACE_HEADER ah, char *request) ; /* When the server is first started, it will initialise and then call this */ /* routine which never returns (like the X Windows style of program). */ /* This routine in the transport layer loops listening for requests which it */ /* then passes on to the acedb server. The server passes in time outs and */ /* a callback function pointer and a pointer to some data that the server */ /* wants passed to its callback routine, again all very X like. */ void aceSocketListen (int port, int serverTimeOut, int clientTimeOut, AceSocketServerRequestRoutine processRequestFunc, void *serverData) ; /* We may receive a signal in the acedb layer, this routine can be called * to tell the transport layer to call acedb back next time round the * "wait for client loop" to shutdown in an orderly way. This avoids * getting caught in the transport layer or the acedb layer calling * signal unsafe routines. */ void aceTransportRequestShutdown(void) ; /* Were we started by inetd ? For lots of reasons acedb needs to know this. */ /* If port_out is non-NULL then the listening port number will be returned. */ BOOL isInetdDaemon(int *port_out) ; /* If we are controlled by inetd and crash on startup without clearing the */ /* listening socket, inetd will immediately try to restart us, which is */ /* very bad news, this routine must clear up the listening socket for acedb */ /* so that this does not happen. */ void aceSocketInetdCleanup(void) ; /* Returns the dotted decimal and human readable forms of the clients host */ /* name. This is just a service routine really, but its all network stuff */ /* so it goes here. */ BOOL getClientInetAddressInfo(ClientConnect connect_struct, char **dotted_name, char **host_name) ; /* Turn debugging output on/off. */ void aceSocketDebug(BOOL debug_on) ; /* SERVER <-> TRANSPORT MESSAGE DEFINITIONS: */ /* */ /* The server expects various messages during logging on, not strictly */ /* necessary, but it all helps. */ /* */ /* On connection to the server, the client must send this text. */ #define ACESERV_CLIENT_HELLO "bonjour" /* The server will reply with this string when password verification is */ /* complete. */ #define ACESERV_SERVER_HELLO "et bonjour a vous" /* SERVER <-> TRANSPORT GENERAL DEFINITIONS: */ /* */ /* Timeouts, setting a time out of zero means that client and/or server will */ /* never be timedout by the server. Timeouts must be a positive integer */ /* number of seconds. */ enum {ACESERV_MIN_TIMEOUT = 0, ACESERV_INFINITE_TIMEOUT = 0} ; #define ACESERV_INFINITE_TIMEOUT_STR "infinite" #endif /* DEF_TRANSPORT_H */