Servers

#include <mailutils/server.h>

typedef void (*mu_conn_free_fp)(void *conn_data,void *server_data);
typedef int (*mu_conn_loop_fp)(int fd,void *conn_data,void *server_data);
typedef void (*mu_server_free_fp)(void *server_data);
typedef int (*mu_server_idle_fp)(void *server_data);

int mu_server_add_connection(mu_server_t t, int fd, void *data, mu_conn_loop_fp loop, mu_conn_free_fp free);
int mu_server_count(mu_server_t t, size_t *pcount);
int mu_server_create(mu_server_t *t);
int mu_server_destroy(mu_server_t *t);
int mu_server_run(mu_server_t t);
int mu_server_set_data(mu_server_t t,void *data,mu_server_free_fp fp);
int mu_server_set_idle(mu_server_t t, mu_server_idle_fp fp);
int mu_server_set_timeout(mu_server_t t,struct timeval *to);

typedef int (*mu_ip_server_conn_fp)(int fd,struct sockaddr *s,int len, void *server_data, void *call_data, mu_ip_server_t srv);
typedef int (*mu_ip_server_intr_fp)(void *data, void *call_data);
typedef void (*mu_ip_server_free_fp)(void *data);

int mu_ip_server_accept(mu_ip_server_t *srv, void *call_data);
int mu_ip_server_create(mu_ip_server_t *srv,struct sockaddr *addr, int addrlen, int type);
int mu_ip_server_destroy(mu_ip_server_t *srv);
int mu_ip_server_get_debug(mu_ip_server_t srv, mu_debug_t *debug);
int mu_ip_server_get_fd(mu_ip_server_t srv);
int mu_ip_server_get_sockaddr(mu_ip_server_t srv, struct sockaddr *s, int *size);
int mu_ip_server_get_type(mu_ip_server_t srv, int *ptype);
int mu_ip_server_loop(mu_ip_server_t srv, void *call_data);
int mu_ip_server_open(mu_ip_server_t srv);
int mu_ip_server_set_acl(mu_ip_server_t srv, mu_acl_t acl);
int mu_ip_server_set_conn(mu_ip_server_t srv, mu_ip_server_conn_fp conn);
int mu_ip_server_set_data(mu_ip_server_t srv, void *data, mu_ip_server_free_fp free);
int mu_ip_server_set_debug(mu_ip_server_t srv, mu_debug_t debug);
int mu_ip_server_set_ident(mu_ip_server_t srv, const char *ident);
int mu_ip_server_set_intr(mu_ip_server_t srv, mu_ip_server_intr_fp intr);
int mu_ip_server_shutdown(mu_ip_server_t srv);

int mu_tcp_server_set_backlog(mu_ip_server_t srv, int backlog);
int mu_udp_server_get_bufsize(mu_ip_server_t srv, size_t *size);
int mu_udp_server_get_rdata(mu_ip_server_t srv, char **pbuf, size_t *pbufsize);
int mu_udp_server_set_bufsize(mu_ip_server_t srv, size_t size);

typedef int (*mu_m_server_conn_fp)(int fd, struct sockaddr *sa, int salen, void *data, mu_ip_server_t srv, time_t timeout, int transcript);
typedef int (*mu_m_server_prefork_fp)(int fd, void *data, struct sockaddr *s, int size);

void mu_m_server_begin(mu_m_server_t srv);
void mu_m_server_cfg_init(void);
void mu_m_server_create(mu_m_server_t *srv,char *ident);
void mu_m_server_destroy(mu_m_server_t *srv);
void mu_m_server_end(mu_m_server_t srv);
int mu_m_server_foreground(mu_m_server_t srv);
int mu_m_server_get_default_address(mu_m_server_t srv,struct sockaddr *sa, int *salen);
void mu_m_server_get_sigset(mu_m_server_t srv,  sigset_t *sigset);
void mu_m_server_get_type(mu_m_server_t srv,int *type);
int mu_m_server_run(mu_m_server_t srv);
const char *mu_m_server_pidfile(mu_m_server_t srv);
void mu_m_server_set_conn(mu_m_server_t srv, mu_m_server_conn_fp f);
void mu_m_server_set_data(mu_m_server_t srv, void *data);
void mu_m_server_set_default_address(mu_m_server_t srv, struct sockaddr *sa, int salen);
void mu_m_server_set_default_port(mu_m_server_t srv, int port);
int mu_m_server_set_foreground(mu_m_server_t srv, int enable);
void mu_m_server_set_max_children(mu_m_server_t srv, size_t num);
int mu_m_server_set_pidfile(mu_m_server_t srv, const char *pidfile);
void mu_m_server_set_prefork(mu_m_server_t srv, mu_m_server_prefork_fp f);
void mu_m_server_set_sigset(mu_m_server_t srv,  sigset_t *sigset);
void mu_m_server_set_strexit(mu_m_server_t srv,const char* (*fun)(int));
void mu_m_server_set_timeout(mu_m_server_t srv, time_t timeout);
void mu_m_server_set_type(mu_m_server_t srv,int type);
void mu_m_server_stop(int code);
time_t mu_m_server_timeout(mu_m_server_t srv);

The core of the server system is the mu_server_t object. This object can monitor any number of file descriptors for activity calling user-defined routines to process the incoming data.

Servers based on socket communications can be created and managed using the mu_ip_server_t. These can be used either as standalone servers or as a connection to a mu_server_t object, in which case the mu_ip_server_t object is passed as the data argument of the mu_server_add_connection.

Severs based on the mu_server_t and mu_ip_server_t objects can only process one client session at a time. The mu_m_server object can process multiple sessions by fork'ing sub-processes to handle each connection.

To access the configuration file options for configuring an mu_m_server object, the following code is needed:

#include <mailutils/acl.h>
#include <mailutils/server.h>

struct mu_cfg_param param[]={
.....
{".server",mu_cfg_section,NULL,0,NULL,"Server Configuration"},
.....
NULL};

struct argp argp={ ..... };
static const char *capa[]={.....};

int main(int argc, char *argv[])
{
   mu_m_server_t srv=NULL;

   mu_acl_cfg_init();
   mu_m_server_cfg_init();

   mu_argp_init(NULL,NULL);

   mu_m_server_create(&srv,"ident");

   if(mu_app_init(&app,capa,param,argc,argv,0,NULL,srv))
     exit(1);

   ........
}

mu_ip_server_t

typedef struct _mu_ip_server *mu_ip_server_t

This is an opaque data structure used to control IP servers. None of the fields in the structure should be accessed by a user program.

mu_m_server_t

typedef struct _mu_m_server *mu_m_server_t

This is an opaque data structure used to control multi-servers. None of the fields in the structure should be accessed by a user program.

mu_server_t

typedef struct _mu_server *mu_server_t;

This is an opaque data structure used to control the server. None of the fields in the structure should be accessed by a user program.

mu_ip_server_accept

int mu_ip_server_accept(mu_ip_server_t *srv, void *call_data);

Once called this function waits for an incoming connection from a client. When a connection is made, any acl(s) are checked and the connection function is called to handle the session. The function will return 0 if successful or an error code. In the event of an error, the listening socket will also be closed terminating the server.

mu_ip_server_create

int mu_ip_server_create(mu_ip_server_t *srv,struct sockaddr *addr, int addrlen, int type);

This create a new instance of an IP server. The IP address and port for the server to listen on are passed in the addr argument, the size of which is passed in addrlen. The type argument is either MU_IP_TCP or MU_IP_UDP. The function returns 0 if successful or an error code.

mu_ip_server_destroy

int mu_ip_server_destroy(mu_ip_server_t *srv);

Releases all the resources allocated to the IP server. The function returns 0 if successful or an error code.

mu_ip_server_get_debug

int mu_ip_server_get_debug(mu_ip_server_t srv, mu_debug_t *debug);

The IP server maintains in internal debug object. This function returns this object. Returns 0 if successful or an error code.

mu_ip_server_get_fd

int mu_ip_server_get_fd(mu_ip_server_t srv);

This function returns the file descriptor associated with the listening socket.

mu_ip_server_get_sockaddr

int mu_ip_server_get_sockaddr(mu_ip_server_t srv, struct sockaddr *s, int *size);

This function returns in s a copy of the listening socket descriptor. The argument size holds the size of s and is updated on exit to reflect the actual size of the listening socket descriptor. The function returns 0 if successful or an error code.

mu_ip_server_get_type

int mu_ip_server_get_type(mu_ip_server_t srv, int *ptype);

This function returns the type (TCP or UDP) of the server in ptype. Returns 0 if successful or an error code.

mu_ip_server_loop

int mu_ip_server_loop(mu_ip_server_t srv, void *call_data);

This function enters a loop which calls mu_ip_server_accept to accept and process client sessions. The loop remains active for as long as the socket is open and the mu_ip_server_accept function returns 0. The function returns 0 if the loop is properly exited or the error code.

mu_ip_server_open

int mu_ip_server_open(mu_ip_server_t srv);

This function opens the socket associated with the server. It returns 0 if successful or an error code.

mu_ip_server_set_acl

int mu_ip_server_set_acl(mu_ip_server_t srv, mu_acl_t acl);

This function sets the access control list which controls access to the server to the acl argument. Returns 0 if successful or an error code.

mu_ip_server_set_conn

int mu_ip_server_set_conn(mu_ip_server_t srv, mu_ip_server_conn_fp conn);

This function sets the function called by the mu_ip_server_accept function when a connection from a client is made. The function return 0 if successful or an error code.

The parameters passed to the connection function is the file descriptor associated with the connection, a socket structure identifying the source of the incoming connection, the size of this structure, the call_data and srv arguments of the calling mu_ip_tcp_accept function. The function should return a non-zero value in the event of an error which will terminate the server.

mu_ip_server_set_data

int mu_ip_server_set_data(mu_ip_server_t srv, void *data, mu_ip_server_free_fp free);

This function sets a pointer to a block of memory that is passed to the function set by a call to mu_ip_server_set_intr. The free argument is a function that releases this block of data when the server object is destroyed.

mu_ip_server_set_debug

int mu_ip_server_set_debug(mu_ip_server_t srv, mu_debug_t debug);

This function replaces the internal debug object with the one passed in debug. Returns 0 if successful or an error code.

mu_ip_server_set_ident

int mu_ip_server_set_ident(mu_ip_server_t srv, const char *ident);

This set an identity string for the server object. Returns 0 if successful or an error code.

mu_ip_server_set_intr

int mu_ip_server_set_intr(mu_ip_server_t srv, mu_ip_server_intr_fp intr);

This function is used to define the function called from mu_ip_server_tcp_accept if a signal is caught while it is waiting for a connection. Returns 0 if successful or an error code.

The arguments for the interrupt function are the pointer set by the most recent call to mu_ip_server_set_data and the call_data argument passed to the mu_ip_server_tcp_accept function. If this function returns a non-zero value then the connection is terminated.

mu_ip_server_shutdown

int mu_ip_server_shutdown(mu_ip_server_t srv);

This function closes the listening socket so terminating the server. The function returns 0 if successful or an error code.

mu_m_server_begin

void mu_m_server_begin(mu_m_server_t srv);

This routine is called to start the server process. If necessary, the process is daemonised, the pidfile is created, any existing signal handlers are stored and signal handlers for the signals being trapped by the server are defined.

mu_m_server_cfg_init

void mu_m_server_cfg_init(void);

This routine is called to enable the server options in the configuration file.

mu_m_server_create

void mu_m_server_create(mu_m_server_t *srv,char *ident);

This function creates a new mu_m_server_t object. The ident argument is used to prefix messages.

mu_m_server_destroy

void mu_m_server_destroy(mu_m_server_t *srv);

Releases the resources allocated to the object.

mu_m_server_end

void mu_m_server_end(mu_m_server_t srv);

This routine is called when the main server control loop is completed to restore the old signal handlers.

mu_m_server_foreground

int mu_m_server_foreground(mu_m_server_t srv);

Returns 0 if the server is configured to run as a daemon process or a non-zero value if it is configured to run in the foreground.

mu_m_server_get_default_address

int mu_m_server_get_default_address(mu_m_server_t srv,struct sockaddr *sa, int *salen);

This function returns in sa a copy of the default address' socket descriptor. The argument salen holds the size of sa and is updated on exit to reflect the actual size of the socket descriptor. The function returns 0 if successful or an error code.

mu_m_server_get_sigset

void mu_m_server_get_sigset(mu_m_server_t srv,  sigset_t *sigset);

This function returns the current signal mask in sigset.

mu_m_server_get_type

void mu_m_server_get_type(mu_m_server_t srv,int *type);

Returns the connection mode of the server in type.

mu_m_server_pidfile

const char *mu_m_server_pidfile(mu_m_server_t srv);

Returns the filename of the pidfile.

mu_m_server_run

int mu_m_server_run(mu_m_server_t srv);

This is the main control loop of the server. The function returns 0 if the main loop is terminated correctly or an error code.

mu_m_server_set_conn

void mu_m_server_set_conn(mu_m_server_t srv, mu_m_server_conn_fp f);

Sets the connection function for the server.

The connection function is called by the sub-process after it has been created. The arguments to this routine are the file descriptor associated with the connection, the socket describing the incoming connection and its size, a pointer to the block of memory set by the last call to mu_m_server_set_data, the mu_ip_server_t object associated with the server, the timeout value and the transcript flag.

mu_m_server_set_data

void mu_m_server_set_data(mu_m_server_t srv, void *data);

Sets a pointer to a memory block which is passed to the connection and prefork functions. The resources allocated to this block are NOT released when the object is destroyed.

mu_m_server_set_default_address

void mu_m_server_set_default_address(mu_m_server_t srv, struct sockaddr *sa, int salen);

This function sets the default address the server listens on.

mu_m_server_set_default_port

void mu_m_server_set_default_port(mu_m_server_t srv, int port);

This sets the default port that the server listens on. The server will listen on all interfaces.

mu_m_server_set_foreground

int mu_m_server_set_foreground(mu_m_server_t srv, int enable);

This function controls whether or not the server is to run daemonised or not. If enable is 1 then the server runs in the foreground.

mu_m_server_set_max_children

void mu_m_server_set_max_children(mu_m_server_t srv, size_t num);

This sets the maximum number of sub-processes created by the server to num.

mu_m_server_set_pidfile

int mu_m_server_set_pidfile(mu_m_server_t srv, const char *pidfile);

This sets name of the pidfile. This function returns 0 if it is successful or an error code.

mu_m_server_set_prefork

void mu_m_server_set_prefork(mu_m_server_t srv, mu_m_server_prefork_fp f);

Sets the prefork function for the server.

The prefork function is called when a valid session has been established but before the sub-process which handles the session is created. The arguments to this routine are: the file descriptor associated with the session, a pointer to the memory block set by the last call to mu_m_server_set_data, a socket describing the incoming connection and the size of the socket. If this function returns a non-zero value then the session is abandoned.

mu_m_server_set_strexit

void mu_m_server_set_strexit(mu_m_server_t srv,const char* (*fun)(int));

This function sets the function called to convert the exit code of a sub-process to human readable text.

mu_m_server_set_sigset

void mu_m_server_set_sigset(mu_m_server_t srv,  sigset_t *sigset);

By default, the server traps and handles the SIGCHLD, SIGINT, SIGTERM, SIGQUIT and SIGHUP signals. This function can be used to modify the signals that are handled by the server.

mu_m_server_set_timeout

void mu_m_server_set_timeout(mu_m_server_t srv, time_t timeout);

This function sets the value which is passed to the connection function as a timeout value.

mu_m_server_set_type

void mu_m_server_set_type(mu_m_server_t srv,int type);

Sets the connection mode of the server, either MU_IP_TCP or MU_IP_UDP.

mu_m_server_stop

void mu_m_server_stop(int code);

If this function is called with a non-zero value for code the control loop will be terminated.

mu_m_server_timeout

time_t mu_m_server_timeout(mu_m_server_t srv);

Returns the currently set timeout value.

mu_server_add_connection

int mu_server_add_connection(mu_server_t t, int fd, void *data, mu_conn_loop_fp loop, mu_conn_free_fp free);

This function adds the file descriptor fd to the list of those being monitored by the server. The data argument is a pointer to a structure which is used to manage the underlying connection, e.g. in the case of an IP server, it will be the address of the mu_ip_server_t structure. This function will return 0 if successful or an error code.

The loop function is called from the main control loop when activity is detected on the file descriptor. The three arguments passed to this function are the fd and data arguments and the current pointer set by the mu_server_set_data function. This function should return MU_SERVER_SUCCESS if there is no error, MU_SERVER_CLOSE_CONN to stop the server monitoring that connection or MU_SERVER_SHUTDOWN to terminate the control loop altogether.

The free function is called from mu_server_destroy to release all resources associated with the connection. The two arguments pass to this function are the data argument and the current pointer set by the mu_server_set_data function.

mu_server_count

int mu_server_count(mu_server_t t, size_t *pcount);

This function returns in pcount the number of connections currently being monitored. This function will return 0 if successful or an error code.

mu_server_create

int mu_server_create(mu_server_t *t);

This function creates a new server. Returns 0 if successful or an error code.

mu_server_destroy

int mu_server_destroy(mu_server_t *t);

Releases all the resources allocated to the server. Returns 0 if successful or an error code.

mu_server_run

int mu_server_run(mu_server_t t);

This enters the main control loop of the server. Once in this loop, the server waits for some activity on any of the connections it is monitoring. If there is activity on the connection then that connection's loop function is called. If the monitoring is interrupted by a signal then the idle function is called. Any error in either the monitoring or processing of the data results in the control loop being terminated and the error code being returned to the caller.

mu_server_set_data

int mu_server_set_data(mu_server_t t,void *data,mu_server_free_fp fp);

This function stores the pointer to a user provided block of data which is passed as an additional argument to various functions called during the operation of the server. The function fp, if it is provided, is used to release this data block during the call to mu_server_destroy.

mu_server_set_idle

int mu_server_set_idle(mu_server_t t, mu_server_idle_fp fp);

This function sets the function called when the main control loop is interrupted by a signal.

When the fp function is called, the argument passed to it is the pointer set by the most recent call to mu_server_set_data. If this function returns a non-zero value then the main control loop will be terminated.

mu_server_set_timeout

int mu_server_set_timeout(mu_server_t t,struct timeval *to);

This function sets the timeout value used by the main control loop when monitoring for activity. If no timeout is specified then the server will block indefinitly. The function returns 0 if successful or an error code.

mu_tcp_server_set_backlog

int mu_tcp_server_set_backlog(mu_ip_server_t srv, int backlog);

This function is used to set the size of the incoming connection queue for TCP sockets. The function returns 0 if successful or an error code.

The default value is 4.

mu_udp_server_get_bufsize

int mu_udp_server_get_bufsize(mu_ip_server_t srv, size_t *size);

This function returns in size the size of the data buffer used for UDP communications. The function returns 0 if successful or an error code.

mu_udp_server_get_rdata

int mu_udp_server_get_rdata(mu_ip_server_t srv, char **pbuf, size_t *pbufsize);

This function returns a pointer to the UDP data buffer in pbuf and its size in pbufsize. It returns 0 if successful or an error code.

mu_udp_server_set_bufsize

int mu_udp_server_set_bufsize(mu_ip_server_t srv, size_t size);

This function is used to set the size of the buffer used to hold incoming UDP messages. The function returns 0 if successful or an error code.

The default is 4096 bytes.

 
servers.txt · Last modified: 2009/06/24 17:18 by admin
 
Except where otherwise noted, content on this wiki is licensed under the following license:CC Attribution-Noncommercial-Share Alike 3.0 Unported
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki