3. Embedding API
In this chapter the reader will find a short description of each function,
global variable and macro the core library of Serveez provides. The API can
either be used to implement a new server or coserver module for use with
Serveez or for supporting network and server functionality within your own
applications without caring about the details and system programming.
Most of the Serveez core library interface functionality should be
prefixed with svz_
. Small symbols will refer to functions and
variables in most cases and big letter symbols refer to macros.
3.1 Memory management
The core library of Serveez is able to keep track of the memory an
application or part of a program consumes and also controls itself in the
same manner. When you are using this memory allocator interface you can
determine and afterwards remove memory leaks. This is a very important
feature if you consider servers being long term programs.
The three allocator function pointers for malloc()
, realloc()
and free()
make it possible to instruct Serveez to use different
kinds of memory, which might be necessary if you want the library to work
with shared memory arenas or any other underlying memory API.
- Variable: svz_malloc_func_t svz_malloc_func
- Initial value: malloc
The svz_malloc_func variable is a function pointer for allocating
dynamic memory.
- Variable: svz_realloc_func_t svz_realloc_func
- Initial value: realloc
This function pointer is called whenever the core library needs to
reallocate (resize) a memory block.
- Variable: svz_free_func_t svz_free_func
- Initial value: free
In order to free a block of memory the core library calls this function
pointer.
- Function: void * svz_malloc (size_t size)
- Allocate size bytes of memory and return a pointer to this block.
- Function: void * svz_calloc (size_t size)
- Allocate size bytes of memory and return a pointer to this block.
The memory is cleared (filled with zeros).
- Function: void * svz_realloc (void * ptr, size_t size)
- Change the size of a
svz_malloc()
'ed block of memory. The size
argument is the new size of the block in bytes, The given variable
ptr must be a pointer previously returned by svz_malloc()
or
NULL
if you want to allocate a new block.
- Function: void svz_free (void * ptr)
- Free a block of
svz_malloc()
'ed or svz_realloc()
'ed memory
block. If ptr is a NULL
pointer, no operation is performed.
- Macro: svz_free_and_zero (var)
- Free the memory block pointed to by var and set it to
NULL
afterwards. The argument var is passed to svz_free()
.
- Function: char * svz_strdup (char * src)
- Duplicate the given string src if it is not
NULL
and has
got a valid length (greater than zero). Return the pointer to the
copied character string.
- Function: void * svz_pmalloc (size_t size)
- Allocate a block of memory with the size size permanently. Memory
allocated this way does not get into account of the libraries memory
tracking.
- Function: void * svz_prealloc (void * ptr, size_t size)
- Resize the memory block pointed to by ptr to size bytes. This
routine also allocates memory permanently.
- Function: char * svz_pstrdup (char * src)
- Duplicate the given character string src permanently.
- Variable: unsigned int svz_allocated_bytes
- Initial value: 0
The variable svz_allocated_bytes holds the overall number of bytes
allocated by the core library.
- Variable: unsigned int svz_allocated_blocks
- Initial value: 0
This variable holds the number of memory blocks reserved by the core
library.
- Function: void svz_heap (void)
- Print a list of non-released memory blocks. This is for debugging only
and should never occur in final software releases. The function goes
through the heap hash and states each blocks address, size and caller.
3.2 Data structures
Since most servers need to store information about its clients or want to
keep track of data during runtime we implemented some of the most useful
data pools. The actual aim was to provide higher level data structures which
the programming language C does not support. Some of the included servers
which come with Serveez make extensive use of them.
3.2.1 Array functions
The array data structure is a simple array implementation. Each array has got
a size and capacity. The array indices range from zero to the arrays size
minus one. You can put any kind of data into this array which fits into the
size of a pointer. The array automatically grows if necessary.
- Function: svz_array_t * svz_array_create (unsigned long capacity, svz_free_func_t destroy)
- Create a new array with the initial capacity capacity and return
a pointer to it. If capacity is zero it defaults to some value. The
destroy argument allows you to release dynamic allocated memory when
calling
svz_array_clear()
and svz_array_destroy()
. If the
array contains data allocated by svz_malloc()
you need to set
destroy to svz_free()
. For structured data you can pass a
user defined routine which recurses into the structure. If the array
contains data which should not be released you must set destroy
to NULL
.
- Function: void svz_array_clear (svz_array_t * array)
- Delete all values within the array array and set its size to zero.
The array array itself keeps valid. Do not perform any operation
if array is
NULL
. If you passed a destroy function to
svz_array_create()
the routine calls this function passing each
element of array to it.
- Function: void svz_array_destroy (svz_array_t * array)
- Completely destroy the array array. The array handle is
invalid afterwards. The routine runs the destroy callback for each
element of the array.
- Function: svz_array_t * svz_array_destroy_zero (svz_array_t * array)
- This function destroys the given array array if it holds no
elements and returns
NULL
in this case. Otherwise the
function returns the given array.
- Function: void * svz_array_get (svz_array_t * array, unsigned long index)
- Return the array element at the position index of the array
array if the index is within the array range. Return
NULL
if not.
- Function: void * svz_array_set (svz_array_t * array, unsigned long index, void * value)
- Replace the array element at the position index of the array
array with the value value and return the previous value
at this index. Returns
NULL
and does not perform any operation
if array is NULL
or the index is out of the array
range.
- Function: void svz_array_add (svz_array_t * array, void * value)
- Append the value value at the end of the array array. Does
not perform any operation if array is
NULL
.
- Function: void * svz_array_del (svz_array_t * array, unsigned long index)
- Remove the array element at the position index of the array
array. Return its previous value or
NULL
if the index
is out of the arrays range.
- Function: unsigned long svz_array_capacity (svz_array_t * array)
- Return the given arrays array current capacity.
- Function: unsigned long svz_array_size (svz_array_t * array)
- Return the given arrays array current size.
- Function: unsigned long svz_array_ins (svz_array_t * array, unsigned long index, void * value)
- This routine inserts the given value value at the position
index. The indices of all following values in the array array
and the size of the array get automatically incremented. Return the
values index or (-1) if the index is out of array bounds.
- Function: unsigned long svz_array_idx (svz_array_t * array, void * value)
- This function returns the index of the first occurrence of the value
value in the array array. It returns (-1) if there is no
such value stored within the array.
- Function: unsigned long svz_array_contains (svz_array_t * array, void * value)
- Returns how often the given value value is stored in the array
array. Return zero if there is no such value.
- Macro: svz_array_foreach (array, value, i)
- This is the iteration macro for the array implementation of the core
library. array specifies the array to iterate, value the
pointer each element of the array gets assigned and i is the
iteration variable.
- Function: svz_array_t * svz_array_strdup (svz_array_t * array)
- This function works something like
svz_array_dup()
but considers
the values within the array array to be zero-terminated character
strings and duplicates these via svz_strdup()
.
- Function: svz_array_t * svz_array_dup (svz_array_t * array)
- This function replicates the given array array. It returns
NULL
if there is nothing to do and an identical copy if the
array otherwise.
- Function: void ** svz_array_values (svz_array_t * array)
- Create a
NULL
terminated C array containing the values of the
given array. If the given array is NULL
then an empty
C array is returned. It is your responsibility to svz_free()
the
returned pointer.
3.2.2 Hashtable functions
A hashtable associates keys of arbitrary size and content with values.
This data structure is also called associative array sometimes because you
use keys in order to access values instead of numbers. You cannot store
two values associated with the same key. The values can have any simple
C types like integers or pointers.
- Function: svz_hash_t * svz_hash_create (int size, svz_free_func_t destroy)
- Create a new hash table with an initial capacity size. Return a
non-zero pointer to the newly created hash. The size is calculated down
to a binary value. The destroy callback allows you to pass a
element destruction callback called within
svz_hash_clear()
and
svz_hash_destroy()
for each value. If no such operation should be
performed the argument must be NULL
.
- Function: void svz_hash_destroy (svz_hash_t * hash)
- Destroy the existing hash table hash. Therefore we
svz_free()
all keys within the hash, the hash table and the hash itself. The values
in the hash keep untouched if the element destruction callback passed to
svz_hash_create()
was NULL
, otherwise it is called for each
value. If hash is NULL
no operation is performed.
- Function: void svz_hash_clear (svz_hash_t * hash)
- Clear the hash table of a given hash hash. Afterwards it does not
contains any key. In contradiction to
svz_hash_destroy()
this
functions does not destroy the hash itself, but shrinks it to a minimal
size.
- Function: void * svz_hash_delete (svz_hash_t * hash, char * key)
- Delete an existing hash entry accessed via a given key key form the
hash table hash. Return NULL if the key has not been found within
the hash, otherwise the previous value.
- Function: void * svz_hash_put (svz_hash_t * hash, char * key, void * value)
- This function adds a new element consisting of key and value
to an existing hash hash. If the hash is 75% filled it gets rehashed
(size will be doubled). When the key already exists then the value just
gets replaced dropping and returning the old value. Note: This is
sometimes the source of memory leaks.
- Function: void * svz_hash_get (svz_hash_t * hash, char * key)
- Hash table lookup. Find a value for a given key in the hash table
hash. Return NULL if the key has not been found within the hash
table.
- Function: void ** svz_hash_values (svz_hash_t * hash)
- This function delivers all values within a hash table hash. It
returns NULL if there were no values in the hash. You MUST
svz_hash_xfree()
a non-NULL return value in order to prevent
memory leaks.
- Function: char ** svz_hash_keys (svz_hash_t * hash)
- This function delivers all keys within a hash table hash. It
returns NULL if there were no keys in the hash. You MUST
svz_hash_xfree()
a non-NULL return value.
- Function: int svz_hash_size (svz_hash_t * hash)
- This routine delivers the number of keys in the hash table hash. If
the given hash is
NULL
it returns zero.
- Function: int svz_hash_capacity (svz_hash_t * hash)
- This function returns the current capacity of a given hash table hash.
- Function: char * svz_hash_contains (svz_hash_t * hash, void * value)
- This function can be used to determine if some key points to the value
argument in the hash table hash. Returns the appropriate key or NULL.
- Function: int svz_hash_exists (svz_hash_t * hash, char * key)
- Returns a non-zero value if the given
key
is stored within
the hash table hash
. Otherwise the function returns zero.
This function is useful when you cannot tell whether the return
value of svz_hash_get()
(== NULL
) indicates a real
value in the hash or a non-existing hash key.
- Macro: svz_hash_foreach_key (hash, iterarray, i)
- Iterator macro for walking over the keys of a hash. Use like:
| char **allkeys; int i;
svz_hash_foreach_key (hash, allkeys, i) {
printf ("%s => %p\n", allkeys[i], svz_hash_get (hash, allkeys[i]));
}
|
Be sure you pass real variables and no expressions to this macro !
Warning: Relatively slow implementation, builds up temporary array.
Do not break
or return
from inside the loop or your program
starts leaking memory ! Loop has to end normally.
- Macro: svz_hash_foreach_value (hash, iterarray, i)
- Iterator macro for walking over the values of a hash. Use like:
| type_t **values; int i;
svz_hash_foreach_value (hash, values, i) {
process_value (values[i]);
}
|
Be sure you pass real variables and no expressions to this macro !
Warning: Relatively slow implementation, builds up temporary array.
Do not break
or return
from inside the loop or your program
starts leaking memory ! Loop has to end normally.
3.2.3 Sparsevector functions
A sparse vector is a kind of data array which grows and shrinks on demand.
It unifies the advantages of chained lists (less memory usage than simple
arrays) and arrays (faster access to specific elements). This implementation
can handle gaps in between the array elements.
- Function: svz_spvec_t * svz_spvec_create (void)
- Construct an empty sparse vector without initial capacity. Return the
newly created sparse vector.
- Function: void svz_spvec_destroy (svz_spvec_t * spvec)
- Destroy the given sparse vector spvec completely. The argument
cannot be used afterwards because it is invalid.
- Function: void svz_spvec_add (svz_spvec_t * spvec, void * value)
- Appends the specified element value at the end of the sparse
vector spvec.
- Function: void svz_spvec_clear (svz_spvec_t * spvec)
- Removes all of the elements from the sparse vector spvec. The
sparse vector will be as clean as created with
svz_spvec_create()
then.
- Function: unsigned long svz_spvec_contains (svz_spvec_t * spvec, void * value)
- Returns non-zero if the sparse vector spvec contains the specified
element value.
- Function: void * svz_spvec_get (svz_spvec_t * spvec, unsigned long index)
- Returns the element at the specified position index in the sparse
vector spvec or
NULL
if there is no such element.
- Function: unsigned long svz_spvec_index (svz_spvec_t * spvec, void * value)
- Searches for the first occurrence of the given argument value.
Return -1 if the value value could not be found in the sparse
vector spvec.
- Function: void * svz_spvec_delete (svz_spvec_t * spvec, unsigned long index)
- Removes the element at the specified position index in the sparse
vector spvec and returns its previous value.
- Function: unsigned long svz_spvec_delete_range (svz_spvec_t * spvec, unsigned long from, unsigned long to)
- Removes all of the elements whose index is between from (inclusive)
and to (exclusive) from the sparse vector spvec. Returns the
amount of actually deleted elements.
- Function: void * svz_spvec_set (svz_spvec_t * spvec, unsigned long index, void * value)
- Replaces the element at the specified position index in the sparse
vector spvec by the specified element value and return its
previous value.
- Function: void * svz_spvec_unset (svz_spvec_t * spvec, unsigned long index)
- Delete the element at the given position index from the sparse
vector spvec but leave all following elements untouched
(unlike
svz_spvec_delete()
). Return its previous value if there
is one otherwise return NULL
.
- Function: unsigned long svz_spvec_size (svz_spvec_t * spvec)
- Returns the number of elements in the sparse vector spvec.
- Function: unsigned long svz_spvec_length (svz_spvec_t * spvec)
- Returns the index of the last element of the sparse vector spvec
plus one.
- Function: void svz_spvec_insert (svz_spvec_t * spvec, unsigned long index, void * value)
- Inserts the specified element value at the given position index
in the sparse vector spvec.
- Function: void ** svz_spvec_values (svz_spvec_t * spvec)
- Delivers all values within the given sparse vector spvec in a
single linear chunk. You have to
svz_free()
it after usage.
- Function: void svz_spvec_pack (svz_spvec_t * spvec)
- Rearranges the given sparse vector spvec. After that there are no
more gaps within the sparse vector. The index - value relationship gets
totally lost by this operation.
3.2.4 Vectorlist functions
A vector list is an array of memory chunks with a fixed size. It
holds copies of the values you added to the vector list. When deleting
or inserting an element the indices of the following elements get
either decremented or incremented. This data structure is especially useful
if you actually want to forget about the pointers you put into it for it
saves copies and not the pointers itself.
- Function: svz_vector_t * svz_vector_create (unsigned long size)
- Create a new vector list without elements. Each element will have
the given size size in bytes.
- Function: void svz_vector_destroy (svz_vector_t * vec)
- Destroy a given vector list vec. This pointer is invalid afterwards.
The routine
svz_free()
s all elements.
- Function: unsigned long svz_vector_clear (svz_vector_t * vec)
- Delete all elements of the given vector list vec. What you will
have then is an empty vector list. Returns the previous length.
- Function: unsigned long svz_vector_add (svz_vector_t * vec, void * value)
- Add an element to the end of the given vector list vec. Return the
position the element got. value is a pointer to a chunk of the
vector lists chunk size.
- Function: void * svz_vector_get (svz_vector_t * vec, unsigned long index)
- Get an vector list element of the vector list vec at the given
position index. Return
NULL
if the index is out of range.
- Function: void * svz_vector_set (svz_vector_t * vec, unsigned long index, void * value)
- Overwrite the element at index index in the vector list vec
with the given value value. Return
NULL
if the index is out
of range or the pointer to the new element.
- Function: unsigned long svz_vector_del (svz_vector_t * vec, unsigned long index)
- Delete the element of the vector vec at the position index.
Return -1 if the given index is out of range otherwise the new length
of the vector list.
- Function: unsigned long svz_vector_ins (svz_vector_t * vec, unsigned long index, void * value)
- Insert the given element value into the vector list vec at
the position index. Return the new length of the vector list or
-1 if the index is out of range.
- Function: unsigned long svz_vector_idx (svz_vector_t * vec, void * value)
- Find the given value value in the vector list vec. Return -1
if there is no such element or the index of the element.
- Function: unsigned long svz_vector_contains (svz_vector_t * vec, void * value)
- Return how often the vector list vec contains the element given
in value.
- Function: unsigned long svz_vector_length (svz_vector_t * vec)
- Return the current length of the vector list vec.
- Macro: svz_vector_foreach (vector, value, i)
- Iteration macro for the vector list vector. Each of its values
gets assigned to value. The iteration variable i runs from
0 to the size-1 of the vector list.
3.3 Utility functions
Within this section you will find some miscellaneous functionality and
left overs of the C API.
- Function: void svz_log (int level, const char * format, ...)
- Print a message to the log system. level specifies the prefix.
- Function: void svz_log_setfile (FILE * file)
- Set the file stream file to the log file all messages are printed
to. Could also be
stdout
or stderr
.
- Variable: int svz_os_version
- Initial value: 0
This variable contains the the runtime detected Win32 version. Its value
is setup in svz_version()
and can be Win32s
for Windows 3.x,
Win95
for Windows 95, Win98
for Windows 98, WinNT3x
for Windows NT 3.x, WinNT4x
for Windows NT 4.x, Win2k
for
Windows 2000, WinXP
for Windows XP and WinME
for Windows ME.
Please note:
This variable is only available on Windows version of this API.
- Variable: int svz_errno
- Initial value: 0
This variable contains the last system or network error occurred if
it was detected and printed. Needed for the "Resource unavailable" error
condition.
- Macro: SVZ_INT16 (p)
- Convert the byte array pointed to by p to a signed 16 bit integer.
- Macro: SVZ_INT32 (p)
- Convert the byte array pointed to by p to a signed 32 bit integer.
This is needed on aligned architectures where a plain type cast ends up
in a fatal bus error.
- Macro: SVZ_INT64 (p)
- Convert the byte array pointed to by p to a signed 64 bit integer.
- Macro: SVZ_UINT16 (p)
- Convert the byte array pointed to by p to an unsigned 16 bit integer.
- Macro: SVZ_UINT32 (p)
- Convert the byte array pointed to by p to an unsigned 32 bit integer.
- Macro: SVZ_UINT64 (p)
- Convert the byte array pointed to by p to an unsigned 64 bit integer.
- Macro: SVZ_NUM2PTR (n)
- Converts the integer value n into a pointer platform independently.
Both of the
SVZ_NUM2PTR()
and SVZ_PTR2NUM()
macros rely on
the (unsigned long)
having the same size as (void *)
.
- Macro: SVZ_PTR2NUM (p)
- Convert the pointer p into a integer value platform independently.
- Function: int svz_hexdump (FILE * out, char * action, int from, char * buffer, int len, int max)
- Dump a buffer with the length len to the file stream out.
You can specify a description in action. The hexadecimal text
representation of the given buffer will be either cut at len or
max. from is a numerical identifier of the buffers creator.
- Function: char * svz_itoa (unsigned int i)
- Converts an unsigned integer to its decimal string representation
returning a pointer to an internal buffer, so copy the result.
- Function: unsigned int svz_atoi (char * str)
- Converts a given string str in decimal format to an unsigned integer.
Stops conversion on any invalid characters.
- Function: char * svz_getcwd (void)
- Returns the current working directory. The returned pointer needs to be
svz_free()
'ed after usage.
- Function: int svz_strcasecmp (const char * str1, const char * str2)
- This is the system dependent case insensitive string compare. It
compares the strings str1 and str2 and returns zero if both
strings are equal.
- Function: int svz_strncasecmp (const char * str1, const char * str2, unsigned int n)
- The
svz_strncasecmp()
function compares the two strings str1
and str2, ignoring the case of the characters. It returns an
integer less than, equal to, or greater than zero if str1 is
found, respectively, to be less than, to match, or be greater than
str2. It only compares the first n characters of str1.
- Function: int svz_openfiles (int max_sockets)
- This routine checks for the current and maximum limit of open files
of the current process. The function heavily depends on the underlying
platform. It tries to set the limit to the given max_sockets
amount.
- Function: char * svz_time (long t)
- Transform the given binary data t (UTC time) to an ASCII time text
representation without any trailing characters.
- Function: char * svz_uptime (long diff)
- Create some kind of uptime string. It tells how long the core library
has been running.
- Function: char * svz_tolower (char * str)
- Convert the given string str to lower case text representation.
- Function: char * svz_sys_version (void)
- This routine is for detecting the operating system version of Win32
and all Unices at runtime. You should call it at least once at startup.
It saves its result in the variable
svz_os_version
and prints an
appropriate message.
- Function: char * svz_hstrerror (void)
- This is the
hstrerror()
wrapper function, depending on the
configuration file `config.h'.
- Function: char * svz_syserror (int nr)
- Routine which forms a valid error message under Win32. It might either
use the
GetLastError()
or WSAGetLastError()
in order to
get a valid error code.
- Function: int svz_snprintf (char * str, unsigned int n, const char * fmt, ...)
- Implementation of the
snprintf()
if it is not defined. It uses
the vsnprintf()
function therefore which will fall back to
vsprintf()
if vsnprintf()
does not exist.
- Function: int svz_asprintf (char ** str, const char * fmt, ...)
- Implementation of
asprintf()
. The function uses
svz_vasprintf()
. It can be used to format a character
string without knowing the actual length of it. The routine
dynamically allocates buffer space via svz_malloc()
and
returns the final length of the string. The calling function is
responsible to run svz_free()
on str.
3.4 Thread safety
The following macros and functions can be used to implement certain
thread safety functionality inside applications using the core library
(including Serveez itself). The user must explicitly enable this
functionality when configure'ing the Serveez package. Otherwise the
macros default to empty statements.
- Macro: svz_mutex_define (mutex)
- Defines a mutex object globally.
- Macro: svz_mutex_declare (mutex)
- Declares a mutex object externally. This is useful when the
mutex object is defined in another file.
- Macro: svz_mutex_create (mutex)
- Creates and initializes the given mutex object. The mutex is
in an unlocked state. The macro must be called before using
svz_mutex_lock()
or svz_mutex_unlock()
. The user
must call svz_mutex_destroy()
for each mutex created by this
function.
- Macro: svz_mutex_destroy (mutex)
- Destroys the given mutex object which has been created by
svz_mutex_create()
.
- Macro: svz_mutex_lock (mutex)
- Locks a mutex object and sets the current thread into an idle
state if the mutex object has been currently locked by another
thread.
- Macro: svz_mutex_unlock (mutex)
- Releases the given mutex object and thereby possibly resumes
a waiting thread calling
svz_mutex_lock()
.
3.5 Networking and other low level functions
The following chapter deals with the basic networking and file systems
functions. It encapsulates systems calls in a portable manner. These
functions should behave identical on Windows and Unices.
- Function: char * svz_inet_ntoa (unsigned long ip)
- Converts the given ip address ip to the dotted decimal
representation. The string is a statically allocated buffer, please
copy the result. The given ip address MUST be in network byte order.
- Function: int svz_inet_aton (char * str, struct sockaddr_in * addr)
- Converts the Internet host address str from the standard
numbers-and-dots notation into binary data and stores it in the
structure that addr points to.
svz_inet_aton()
returns
zero if the address is valid, nonzero if not.
This function handles an ip address of "*" special and sets
INADDR_ANY
for it.
- Function: int svz_socket_connect (SOCKET sockfd, unsigned long host, unsigned short port)
- Connect the given socket descriptor sockfd to the host host
at the network port port. Return non-zero on errors.
- Function: SOCKET svz_socket_create (int proto)
- Create a new non-blocking socket which does not get inherited on
exec()
. The protocol is specified by proto. Return the
socket descriptor or -1 on errors.
- Function: int svz_socket_create_pair (int proto, SOCKET desc [2])
- This function creates an unnamed pair of connected sockets with the
specified protocol proto. The descriptors used in referencing the
new sockets are returned in desc[0] and desc[1]. The two sockets are
indistinguishable. Also make both of them non-blocking and
non-inheritable. Returns -1 on failure, otherwise zero.
- Function: int svz_socket_type (SOCKET fd, int * type)
- Saves the socket type (like
SOCK_STREAM
, SOCK_DGRAM
, etc.)
of the socket fd in the buffer pointed to by type. Returns
zero on success.
- Function: int svz_fd_cloexec (int fd)
- Set the close-on-exec flag of the given file descriptor fd and
return zero on success. Otherwise return non-zero.
- Function: int svz_fd_nonblock (int fd)
- Set the given file descriptor to nonblocking I/O. This heavily differs
in Win32 and Unix. The given file descriptor fd must be a socket
descriptor under Win32, otherwise the function fails. Return zero on
success, otherwise non-zero.
- Function: int svz_fd_block (int fd)
- Set the given file descriptor to blocking I/O. This routine is the
counter part to
svz_fd_nonblock()
.
- Function: int svz_tcp_cork (SOCKET fd, int set)
- Enable or disable the
TCP_CORK
socket option of the given socket
descriptor fd. This is useful for performance reasons when using
sendfile()
with any prepending or trailing data not inside the
file to transmit. The function return zero on success, otherwise non-zero.
- Function: int svz_tcp_nodelay (SOCKET fd, int set, int * old)
- Enable or disable the
TCP_NODELAY
setting for the given socket
descriptor fd depending on the flag set. In fact its turns
the Nagle algorithm on or off. This means that packets are always sent
as soon as possible and no unnecessary delays are introduced. The
function saves the old setting if old is not NULL
. Returns
zero on success, otherwise non-zero.
- Function: int svz_sendfile (int out_fd, int in_fd, off_t * offset, unsigned int count)
- This function transmits data between one file descriptor and another
where in_fd is the source and out_fd the destination. The
offset argument is a pointer to a variable holding the input file
pointer position from which reading starts. When this routine returns,
the offset variable will be set to the offset of the byte following
the last byte that was read. count is the number of bytes to copy
between file descriptors. Returns the number of bytes actually
read/written or -1 on errors.
- Function: int svz_open (const char * file, int flags, unsigned int mode)
- Open the filename file and convert it into a file handle. The
given flags specify the access mode and the mode argument
the permissions if the
O_CREAT
flag is set.
- Function: int svz_close (int fd)
- Close the given file handle fd. Return -1 on errors.
- Function: int svz_fstat (int fd, struct stat * buf)
- Return information about the specified file associated with the file
descriptor fd returned by
svz_open()
. Stores available
information in the stat buffer buf.
- Function: FILE * svz_fopen (const char * file, const char * mode)
- Open the file whose name is the string pointed to by file and
associates a stream with it.
- Function: int svz_fclose (FILE * f)
- Dissociates the named stream f from its underlying file.
- Function: char * svz_file_path (char * path, char * file)
- Constructs a fully qualified file name form path and file.
If path is omitted (
NULL
) the function returns file
only. If file is NULL
a null pointer is returned.
Please remember to svz_free()
the returned pointer.
- Function: int svz_file_check (char * file)
- Checks for the existence of the given file system node file and
return zero on success. Otherwise the function returns non-zero.
3.6 Client connections
Serveez tries to handle all kinds of Internet protocols like TCP (connection
oriented), UDP, ICMP and RAW (packet oriented) and communication across
named pipes (also connection oriented) in the same way. Therefore it uses
a structure called svz_socket_t
which is the abstraction of any kind
of communication endpoint (can be client or server or both together).
3.6.1 TCP sockets
TCP sockets provide a reliable, stream oriented, full duplex connection
between two sockets on top of the Internet Protocol (IP). TCP guarantees
that the data arrives in order and retransmits lost packets. It generates
and checks a per packet checksum to catch transmission errors. TCP does
not preserve record boundaries.
- Function: svz_socket_t * svz_tcp_connect (unsigned long host, unsigned short port)
- Create a TCP connection to host host and set the socket descriptor
in structure sock to the resulting socket. Return a zero value on
errors.
- Function: int svz_tcp_default_connect (svz_socket_t * sock)
- The default routine for connecting a socket sock. When we get
select()
ed or poll()
ed via the WRITE_SET we simply
check for network errors,
- Function: int svz_tcp_read_socket (svz_socket_t * sock)
- Default function for reading from the socket sock. This function
only reads all data from the socket and calls the
check_request()
function for the socket, if set. Returns -1 if the socket has died,
returns zero otherwise.
- Function: int svz_tcp_write_socket (svz_socket_t * sock)
- Default function for writing to the socket sock. Simply flushes
the output buffer to the network. Write as much as possible into the
socket sock. Writing is performed non-blocking, so only as much
as fits into the network buffer will be written on each call.
- Function: int svz_tcp_recv_oob (svz_socket_t * sock)
- This function is the default
read_socket_oob()
callback for
TCP sockets. It stores the received out-of-band data (a single byte
only) in sock->oob
and runs the check_request_oob()
callback
if it is set properly. Returns -1 on failure and zero otherwise. The
function does not do anything if the underlying operating system does not
support urgent data and simply returns -1.
- Function: int svz_tcp_send_oob (svz_socket_t * sock)
- If the underlying operating system supports urgent data (out-of-band) in
TCP streams this function tries to send the byte in
sock->oob
through the socket structure sock as out-of-band data. The function
returns zero on success and -1 otherwise (also if urgent data is not
supported).
3.6.2 Pipe connections
The pipe implementations supports both named and anonymous pipes. Pipe
servers are implemented as listeners on a file system FIFO on Unices or
"Named Pipes" on Windows (can be shared over a Windows network).
A FIFO special file is similar to a pipe, except that it is created in a
different way. Instead of being an anonymous communications channel,
a FIFO special file is entered into the file system.
Once you have created a FIFO special file in this way, any process can open
it for reading or writing, in the same way as an ordinary file. However,
it has to be open at both ends simultaneously before you can proceed to do
any input or output operations on it.
- Function: int svz_pipe_startup (void)
- Startup the pipe interface of the core API of serveez. Returns zero on
success. Gets called from
svz_boot()
once. Do not use.
- Function: int svz_pipe_cleanup (void)
- Cleanup the pipe interface of the core API of serveez. Returns zero on
success. Gets called from
svz_halt()
once. Do not use.
- Function: svz_pipe_t * svz_pipe_alloc (void)
- Return a newly allocated and setup to some defaults pipe structure.
- Function: void svz_pipe_destroy (svz_pipe_t * pipe)
- Destroy the given pipe structure pipe.
- Function: int svz_pipe_valid (svz_socket_t * sock)
- This function is for checking if a given socket structure contains
a valid pipe socket (checking both pipes). Return non-zero on errors.
- Function: int svz_pipe_read_socket (svz_socket_t * sock)
- The
svz_pipe_read_socket()
function reads as much data as
available on a readable pipe descriptor or handle on Win32. Return
a non-zero value on errors.
- Function: int svz_pipe_write_socket (svz_socket_t * sock)
- This
svz_pipe_write_socket()
function writes as much data as
possible into a writable pipe descriptor. It returns a non-zero value
on errors.
- Function: int svz_pipe_disconnect (svz_socket_t * sock)
- This function is the default disconnection routine for pipe socket
structures. Return non-zero on errors.
- Function: svz_socket_t * svz_pipe_create (HANDLE recv_fd, HANDLE send_fd)
- Create a socket structure containing both the pipe descriptors
recv_fd and send_fd. Return
NULL
on errors.
- Function: int svz_pipe_create_pair (HANDLE pipe_desc [2])
- Create a (non blocking) pair of pipes. This differs in Win32 and
Unices. Return a non-zero value on errors.
- Function: svz_socket_t * svz_pipe_connect (svz_pipe_t * recv, svz_pipe_t * send)
- This routine creates a pipe connection socket structure to a pair of
named pipes. Return
NULL
on errors.
- Function: int svz_pipe_listener (svz_socket_t * sock, svz_pipe_t * recv, svz_pipe_t * send)
- Prepare the server socket structure sock for listening
on the receiving pipe of recv. Open the reading end of such a
connection. Return either zero or non-zero on errors.
- Function: int svz_pipe_check_user (svz_pipe_t * pipe)
- Check the consistency of the "user" - "user id" pair in the given pipe
structure pipe. Return zero if it is ok.
- Function: int svz_pipe_check_group (svz_pipe_t * pipe)
- Check the consistency of the "group" - "group id" pair in the structure
pipe. Return zero if it is valid.
3.6.3 UDP sockets
The UDP sockets implement a connectionless, unreliable datagram packet
service. Packets may be reordered or duplicated before they arrive. UDP
generates and checks checksums to catch transmission errors.
- Function: int svz_udp_read_socket (svz_socket_t * sock)
- This routine is the default reader for UDP sockets. Whenever the socket
descriptor is
select()
'ed for reading it is called by default and
reads as much data as possible (whole packets only) and saves the sender
into the sock->remote_addr
field. The packet load is written into
sock->recv_buffer
.
- Function: int svz_udp_lazy_read_socket (svz_socket_t * sock)
- This routine is the default reader for UDP server sockets. It allocates
necessary buffers (that's why it's called lazy) and reverts to the default
svz_udp_read_socket()
.
- Function: int svz_udp_write_socket (svz_socket_t * sock)
- The
svz_udp_write_socket()
callback should be called whenever
the UDP socket descriptor is ready for sending. It sends a single packet
within the sock->send_buffer
to the destination address specified
by sock->remote_addr
and sock->remote_port
.
- Function: int svz_udp_check_request (svz_socket_t * sock)
- This is the default
check_request()
routine for UDP servers.
Whenever new data arrived at an UDP server socket we call this function to
process the packet data. Any given handle_request()
callback MUST
return zero if it successfully processed the data and non-zero if it
could not.
- Function: svz_socket_t * svz_udp_connect (unsigned long host, unsigned short port)
- Create a UDP connection to host and set the socket descriptor in
structure sock to the resulting socket. Return a
NULL
value
on errors. This function can be used for port bouncing. If you assign the
handle_request
callback to something server specific and the
cfg field to the server's configuration to the returned socket
structure this socket is able to handle a dedicated UDP connection to
some other UDP server.
- Function: int svz_udp_write (svz_socket_t * sock, char * buf, int length)
- Write the given buf into the send queue of the UDP socket. If the
length argument supersedes the maximum length for UDP messages it
is split into smaller packets.
- Function: int svz_udp_printf (svz_socket_t * sock, const char * fmt, ...)
- Print a formatted string on the UDP socket sock. fmt is
the printf()-style format string, which describes how to format the
optional arguments. See the printf(3) manual page for details. The
destination address and port is saved for sending. This you might
specify them in
sock->remote_addr
and sock->remote_port
.
3.6.4 ICMP sockets
The ICMP socket implementation is currently used in the tunnel server which
comes with the Serveez package. It implements a user protocol receiving and
sending ICMP packets by opening a raw socket with the protocol IPPROTO_ICMP.
The types of ICMP packets passed to the socket can be filtered using the
ICMP_FILTER socket option (or by software as done here). ICMP packets are
always processed by the kernel too, even when passed to a user socket.
- Function: void svz_icmp_startup (void)
- Load the `ICMP.DLL' library into process address space and get all
necessary function pointers.
- Function: void svz_icmp_cleanup (void)
- Shutdown the ping service.
- Function: int svz_icmp_read_socket (svz_socket_t * sock)
- Default reader for ICMP sockets. The sender is stored within
sock->remote_addr
and sock->remote_port
afterwards.
- Function: int svz_icmp_lazy_read_socket (svz_socket_t * sock)
- Default reader for ICMP server sockets. Allocates necessary buffers and
reverts to
svz_icmp_read_socket()
.
- Function: int svz_icmp_write_socket (svz_socket_t * sock)
- The default ICMP write callback is called whenever the socket
descriptor has been
select()
'ed or poll()
'ed to be ready for
sending.
- Function: int svz_icmp_check_request (svz_socket_t * sock)
- Default
check_request()
callback for ICMP sockets.
- Function: svz_socket_t * svz_icmp_connect (unsigned long host, unsigned short port, unsigned char type)
- This function creates an ICMP socket for receiving and sending.
Return
NULL
on errors, otherwise an enqueued socket structure.
- Function: int svz_icmp_send_control (svz_socket_t * sock, svz_uint8_t type)
- If you are calling this function we will send an empty ICMP packet
signaling that this connection is going down soon.
- Function: int svz_icmp_write (svz_socket_t * sock, char * buf, int length)
- Send a given buffer buf with length length via this ICMP
socket. If the length argument supersedes the maximum ICMP message
size the buffer is split into smaller packets.
- Function: int svz_icmp_printf (svz_socket_t * sock, const char * fmt, ...)
- Put a formatted string to the icmp socket sock. Packet length and
destination address are additionally saved to the send buffer. The
destination is taken from
sock->remote_addr
. Furthermore a valid
icmp header is stored in front of the actual packet data.
3.6.5 Raw sockets
A raw socket receives or sends the raw datagram not including link
level headers. It is currently used by the ICMP socket implementation of
the core library. The IPv4 layer generates an IP header when sending a packet
unless the IP_HDRINCL socket option is enabled on the socket. When it is
enabled, the packet must contain an IP header. For receiving the IP header
is always included in the packet.
Only processes with an effective userid of 0 (Administrator or root) or the
CAP_NET_RAW capability are allowed to open raw sockets. All packets or errors
matching the protocol number specified for the raw socket are passed to
this socket. A protocol of IPPROTO_RAW implies enabled IP_HDRINCL and
receives all IP protocols. Sending is not allowed.
- Function: svz_ip_header_t * svz_raw_get_ip_header (svz_uint8_t * data)
- Get IP header from plain data.
- Function: svz_uint8_t * svz_raw_put_ip_header (svz_ip_header_t * hdr)
- Put IP header to plain data. This is currently not in use but can be
used when creating raw sockets with setsockopt (SOL_IP, IP_HDRINCL).
- Function: unsigned short svz_raw_ip_checksum (svz_uint8_t * data, int len)
- Recalculate any IP checksum.
- Function: int svz_raw_check_ip_header (svz_uint8_t * data, int len)
- Checking the IP header only. Return the length of the header if it
is valid, otherwise -1.
3.6.6 Passthrough connections
The function subset described in the following section allows the user to
passthrough client connections to the standard input (stdin) and standard
output (stdout) handles of external programs. Some of the routines deal
with the management of program environments. Basically there are two
methods how to passthrough a duplex connection: the Unix'ish fork()
and exec()
method and the shuffle method where the main process
keeps control over the communication on the original duplex connection and
passes this data through two pairs of pipes or yet another socket connection
to the child process. All of the three method are implemented calling them
SVZ_PROCESS_FORK
, SVZ_PROCESS_SHUFFLE_PIPE
and
SVZ_PROCESS_SHUFFLE_SOCK
.
- Function: int svz_sock_process (svz_socket_t * sock, char * bin, char * dir, char ** argv, svz_envblock_t * envp, int flag, char * user)
- This routine starts a new program specified by bin passing the
socket or pipe descriptor(s) in the socket structure sock to its
stdin and stdout.
The bin argument has to contain a fully qualified executable file
name and the dir argument contains the working directory of the
new process. The directory is not changed when this argument is
NULL
.
The program arguments and the environment of the new process can be
passed in argv and envp. Please note that argv[0]
has
to be set to the program's name, otherwise it defaults to bin if
it contains NULL
.
The flag argument specifies the method used to passthrough the
connection. It can be either SVZ_PROCESS_FORK
(in order to pass
the pipe descriptors or the socket descriptor directly through
fork()
and exec()
) or SVZ_PROCESS_SHUFFLE_PIPE
/
SVZ_PROCESS_SHUFFLE_SOCK
(in order to pass the socket transactions
via a pair of pipes or sockets).
You can pass the user and group identifications in the format
`user[.group]' (group is optional), as SVZ_PROCESS_NONE
or SVZ_PROCESS_OWNER
in the user argument. This specifies the
permissions of the new child process. If SVZ_PROCESS_OWNER
is
passed the permissions are set to the executable file bin owner;
SVZ_PROCESS_NONE
does not change user or group.
The function returns -1 on failure and otherwise the new process's pid.
- Function: int svz_process_disconnect (svz_socket_t * sock)
- Disconnection routine for the socket connection sock which is
connected with a process's stdin/stdout via the referring passthrough
socket structure which gets also scheduled for shutdown if possible.
- Function: int svz_process_disconnect_passthrough (svz_socket_t * sock)
- Disconnection routine for the passthrough socket structure sock
connected with a process's stdin/stdout. Schedules the referring socket
connection for shutdown if necessary and possible.
- Function: int svz_process_check_request (svz_socket_t * sock)
- Check request routine for the original passthrough connection sock.
Sets the send buffer fill counter of the referring socket structure which
is the passthrough connection in order to schedule it for sending.
- Function: int svz_process_idle (svz_socket_t * sock)
- Idle function for the passthrough shuffle connection sock. The
routine checks whether the spawned child process is still valid. If not
it schedules the connection for shutdown. The routine schedules itself
once a second.
- Function: int svz_process_send_pipe (svz_socket_t * sock)
- This is the shuffle pipe writer (reading end of a process's stdin). It
writes as much data as possible from the send buffer which is the receive
buffer of the referring socket structure. Returns non-zero on errors.
- Function: int svz_process_recv_pipe (svz_socket_t * sock)
- This is the shuffle pipe reader (writing end of a process's stdout). It
reads as much data as possible into its receive buffer which is the send
buffer of the connection this passthrough pipe socket structure stems
from.
- Function: int svz_process_send_socket (svz_socket_t * sock)
- This is the shuffle socket pair writer which is directly connected with
the reading end of the child process. It writes as much data as possible
from its send buffer which is the receive buffer of the original
passthrough connection.
- Function: int svz_process_recv_socket (svz_socket_t * sock)
- This is the shuffle socket pair reader which is directly connected
with the writing end of the child process. It reads as much data as
possible into its receive buffer which is the send buffer of the
original passthrough connection.
- Function: int svz_process_create_child (svz_process_t * proc)
- Spawns a new child process. The given proc argument contains all
information necessary to set a working directory, assign a new user
defined stdin and stdout of the new process, to set up a process
environment, pass a command line to the new process and to specify a
user and group identification the child process should have. The routine
returns -1 on failure, otherwise the new child program's process id.
Please note:
On M$-Windows platforms it is not possible to pass a socket connection
to a child process's stdin/stdout. That is why this function creates an
inheritable version of the socket and puts the socket handle number
into the environment variables SEND_HANDLE
and RECV_HANDLE
.
A spawned child process can use these handles as if these were created
by itself. After calling WSAStartup()
the child process can
send()
and recv()
as usual.
- Function: int svz_process_shuffle (svz_process_t * proc)
- Creates two pairs of pipes in order to passthrough the transactions of
the a socket structure. The function create a new socket structure and
sets it up for handling the transactions automatically. The given
argument proc contains the information inherited from
svz_sock_process()
. The function returns -1 on failure and the
new child's process id otherwise.
- Function: int svz_process_fork (svz_process_t * proc)
- Fork the current process and execute a new child program. The given
argument proc contains the information inherited from
svz_sock_process()
. The routine passes the socket or pipe
descriptors of the original passthrough socket structure to stdin and
stdout of the child. The caller is responsible for shutting down the
original socket structure. Returns -1 on errors and the child's
process id on success.
- Function: int svz_process_check_executable (char * file, char ** app)
- Check if the given file is an executable (script or binary
program). If it is script the routine returns an application able to
execute the script in app. Returns zero on success, non-zero
otherwise.
- Function: int svz_process_split_usergroup (char * str, char ** user, char ** group)
- Splits the given character string str in the format
`user[.group]' into a user name and a group name and stores
pointers to it in user and group. If the group has been
omitted in the format string then group is
NULL
afterwards. The function returns zero on success, or non-zero if the
given arguments have been invalid.
- Function: int svz_process_check_access (char * file, char * user)
- Try setting the user and group for the current process specified by the
given executable file file and the user argument. If user
equals
SVZ_PROCESS_NONE
no user or group is set. When you pass
SVZ_PROCESS_OWNER
in the user argument the file's owner
will be set. Otherwise user specifies the user and group
identification in the format `user[.group]'. If you omit the group
information the routine uses the primary group of the user. Returns zero
on success, non-zero otherwise.
- Function: svz_envblock_t * svz_envblock_create (void)
- Create a fresh environment block. The returned pointer can be used to pass
it to
svz_envblock_default()
and svz_envblock_add()
. Its
size is initially set to zero.
- Function: int svz_envblock_default (svz_envblock_t * env)
- Fill the given environment block env with the current process's
environment variables. If the environment env contained any
information before these will be overridden.
- Function: int svz_envblock_add (svz_envblock_t * env, char * format, ...)
- Insert a new environment variable into the given environment block
env. The format argument is a printf()-style format string
describing how to format the optional arguments. You specify environment
variables in the `VAR=VALUE' format.
- Function: int svz_envblock_free (svz_envblock_t * env)
- This function releases all environment variables currently stored in the
given environment block env. The block will be as clean as returned
by
svz_envblock_create()
afterwards.
- Function: void svz_envblock_destroy (svz_envblock_t * env)
- Destroys the given environment block env completely. The env
argument is invalid afterwards and should therefore not be referenced then.
- Function: svz_envp_t svz_envblock_get (svz_envblock_t * env)
- Unfortunately the layout of environment blocks in Unices and Windows
differ. On Unices you have a NULL terminated array of character strings
and on Windows systems you have a simple character string containing
the environment variables in the format VAR=VALUE each separated by a
zero byte. The end of the list is indicated by a further zero byte.
The following routine converts the given environment block env
into something which can be passed to
exeve()
(Unix) or
CreateProcess()
(Windows). The routine additionally sorts the
environment block on Windows systems since it is using sorted
environments.
- Macro: svz_envblock_setup ()
- This macro must be called once after
svz_boot()
for setting up the
svz_environ
variable. It simply passes the environ
variable
of the calling application to the underlying Serveez core API. This is
necessary to make the svz_envblock_default()
function working
correctly.
- Variable: char * * svz_environ
- Initial value: NULL
This variable is meant to hold the environ
variable of the
application using the Serveez core API. It must be setup via the macro
svz_envblock_setup()
.
3.7 Socket management
The function subset described in the following section deals with the
creation, destruction and other simple operations on socket structures
called svz_socket_t
. See for the details at the description of each
function which kind of socket it can handle and what they are for.
- Variable: int svz_sock_connections
- Initial value: 0
Count the number of currently connected sockets.
- Function: int svz_sock_valid (svz_socket_t * sock)
- Check if a given socket is still valid. Return non-zero if it is
not.
- Function: svz_socket_t * svz_sock_alloc (void)
- Allocate a structure of type
svz_socket_t
and initialize its data
fields. Assign some of the default callbacks for TCP connections.
- Function: int svz_sock_free (svz_socket_t * sock)
- Free the socket structure sock. Return a non-zero value on error.
- Function: svz_socket_t * svz_sock_create (int fd)
- Create a socket structure from the file descriptor fd. Set the
socket descriptor to non-blocking I/O. Return
NULL
on errors.
- Function: int svz_sock_disconnect (svz_socket_t * sock)
- Disconnect the socket sock from the network and calls the disconnect
function for the socket if set. Return a non-zero value on errors.
- Function: int svz_sock_write (svz_socket_t * sock, char * buf, int len)
- Write len bytes from the memory location pointed to by buf
to the output buffer of the socket sock. Also try to flush the
buffer to the socket of sock if possible. Return a non-zero value
on error, which normally means a buffer overflow.
- Function: int svz_sock_printf (svz_socket_t * sock, const char * fmt, ...)
- Print a formatted string on the socket sock. fmt is the
printf()-style format string, which describes how to format the optional
arguments. See the printf(3) manual page for details.
- Function: int svz_sock_resize_buffers (svz_socket_t * sock, int send_buf_size, int recv_buf_size)
- Resize the send and receive buffers for the socket sock.
send_buf_size is the new size for the send buffer,
recv_buf_size for the receive buffer. Note that data may be lost
when the buffers shrink. For a new buffer size of 0 the buffer is
freed and the pointer set to NULL.
- Function: int svz_sock_intern_connection_info (svz_socket_t * sock)
- Get local and remote addresses and ports of socket sock and save
them into the socket structure.
- Function: int svz_sock_local_info (svz_socket_t * sock, unsigned long * addr, unsigned short * port)
- This function returns the local network address and port for the given
client socket structure sock. It returns non-zero if there no
connection established.
- Function: int svz_sock_error_info (svz_socket_t * sock)
- Get and clear the pending socket error of a given socket. Print
the result to the log file.
- Function: int svz_sock_unique_id (svz_socket_t * sock)
- Calculate unique socket structure id and assign a version for a
given sock. The version is for validating socket structures. It is
currently used in the coserver callbacks.
- Function: int svz_sock_detect_proto (svz_socket_t * sock)
- This routine gets called whenever data is read from a client socket
accepted by any connection oriented protocol layer (TCP or PIPE). We
try to detect the data streams protocol here.
- Function: int svz_sock_check_request (svz_socket_t * sock)
- This function simply checks for the kind of packet delimiter within the
given socket structure and and assigns one of the default
check_request()
routines (one or more byte delimiters or a fixed
size). Afterwards this routine will never ever be called again because
the callback gets overwritten here.
- Function: int svz_sock_idle_protect (svz_socket_t * sock)
- Default idle function. This routine simply checks for "dead"
(non-receiving) sockets (connection oriented protocols only) and rejects
them by return a non-zero value.
- Function: int svz_sock_flood_protect (svz_socket_t * sock, int num_read)
- This routine can be called if flood protection is wished for
socket readers. Return non-zero if the socket should be kicked
because of flood.
- Macro: svz_sock_reduce_recv (sock, len)
- Shorten the receive buffer of sock by len bytes.
- Macro: svz_sock_reduce_send (sock, len)
- Reduce the send buffer of sock by len bytes.
3.8 Coserver functions
The following section describes the internal coserver interface of serveez.
Coservers are helper processes meant to perform blocking tasks. This is
going to be necessary because serveez itself is single threaded. Each
coserver is connected via a pair of pipes to the main thread of serveez
communicating over a simple text line protocol. Each request/response is
separated by a newline character.
If the user wants to use these processes you need to start the coserver
interface by calling svz_coserver_init()
once before entering the
main server loop and shut it down afterwards by calling
svz_coserver_finalize()
.
- Variable: svz_coservertype_t svz_coservertypes
- This static array contains the coserver structure for each type of
internal coserver the core library provides.
- Variable: svz_array_t * svz_coservers
- Initial value: NULL
Internal coserver instances.
- Function: void svz_coserver_check (void)
- Call this routine whenever there is time, e.g. within the timeout of
the
select()
statement. Indeed I built it in the
svz_periodic_tasks()
statement. Under Wind32 the routine checks
if there was any response from an active coserver. Moreover it keeps
the coserver threads/processes alive. If one of the coservers dies due
to buffer overrun or might be overloaded this function starts a new one.
- Function: int svz_coserver_init (void)
- Global coserver initialization. Here you should start all the internal
coservers you want to use later.
- Function: int svz_coserver_finalize (void)
- Global coserver finalization.
- Function: void svz_coserver_destroy (int type)
- Destroy specific coservers with the type type. This works for
Win32 and Unices. All instances of this coserver type will be stopped.
- Function: void svz_coserver_create (int type)
- Create a single coserver with the given type type.
- Function: void svz_coserver_send_request (int type, char * request, svz_coserver_handle_result_t handle_result, svz_coserver_args_t)
- Invoke a request for one of the running internal coservers
with type type. handle_result and arg specify what
should happen if the coserver delivers a result.
- Function: void svz_coserver_rdns_invoke (unsigned long ip, svz_coserver_handle_result_t cb, svz_coserver_args_t)
- This is a wrapper function for the reverse DNS lookup coserver.
- Macro: svz_coserver_rdns (ip, cb, arg0, arg1)
- This macro is considered to be the usual way to make a request to the
reverse DNS coserver. It calls
svz_coserver_rdns_invoke()
therefore.
If the given ip has been resolved by the coserver to a valid computer
name the callback cb gets invoked with the additional arguments
passed to this macro.
- Function: void svz_coserver_dns_invoke (char * host, svz_coserver_handle_result_t cb, svz_coserver_args_t)
- Wrapper for the DNS coserver.
- Macro: svz_coserver_dns (host, cb, arg0, arg1)
- This macro is the usual way to make use of the internal DNS coserver.
When the given computer name host has been resolved to a valid
ip address the function cb will be called with the additional
arguments arg0 and arg1.
- Function: void svz_coserver_ident_invoke (svz_socket_t * sock, svz_coserver_handle_result_t cb, svz_coserver_args_t)
- Wrapper for the ident coserver.
- Macro: svz_coserver_ident (sock, cb, arg0, arg1)
- This macro uses the internal ident coserver in order to identify the
connection of the given socket structure sock. The function cb
will be called when the coserver successfully delivers the identified
user on the other end of the connection. Both the arguments arg0
and arg1 are passed to cb.
3.9 Codec functions
The codec interface of the serveez core API supplies routines for setting up
socket structures to perform encoding or decoding of its receive or send
buffers. It is a transparent layer of buffer transition. The interface itself
tries to unify different types of codecs. In order to add a new codec the
programmer needs to write some wrapper functions around the actual
implementation to fulfil certain entry and exit semantics of this interface.
- Function: void svz_codec_list (void)
- Prints the text representation of the list of known codecs registered
within the core library. This includes all encoder and decoder once ran
through
svz_codec_register()
.
- Function: svz_codec_t * svz_codec_get (char * description, int type)
- Find an appropriate codec for the given description and type
which can be either
SVZ_CODEC_ENCODER
or SVZ_CODEC_DECODER
.
The function returns NULL
if there is no such codec registered.
- Function: int svz_codec_init (void)
- This routine is called by
svz_boot()
and registers the builtin
codecs.
- Function: int svz_codec_finalize (void)
- This routine is called by
svz_halt()
and destroys the list of
known codecs.
- Function: void svz_codec_ratio (svz_codec_t * codec, svz_codec_data_t * data)
- Print a text representation of a codec's current ratio in percent
if possible.
- Function: int svz_codec_register (svz_codec_t * codec)
- Register the given codec codec. Does not register invalid or
duplicate codecs. Returns zero on success, non-zero otherwise.
- Function: int svz_codec_unregister (svz_codec_t * codec)
- Removes the given codec codec from the list of known codecs. Returns
zero if the codec could be successfully removed, non-zero otherwise.
- Function: int svz_codec_sock_receive_setup (svz_socket_t * sock, svz_codec_t * codec)
- Setup the given socket structure sock to decode or encode its
receive data via the codec codec. Therefore you must have setup
the
check_request
method previously. The function returns zero
on success, non-zero otherwise.
- Function: int svz_codec_sock_receive (svz_socket_t * sock)
- This routine is the new
check_request
callback for reading codecs.
It is applied in the above svz_codec_sock_receive_setup()
function.
Usually it gets called whenever there is data in the receive buffer. It
lets the current receive buffer be the input of the codec. The output
buffer of the codec gets the new receive buffer buffer of the socket
structure sock. The old check_request
callback of sock
gets called afterwards. When leaving this functions the receive buffer
gets restored again with the bytes snipped consumed by the codec itself.
- Function: int svz_codec_sock_send_setup (svz_socket_t * sock, svz_codec_t * codec)
- Setup the socket structure sock for encoding or decoding its send
buffer via the given codec codec. Therefore you previously need to
assign the
write_socket
member of sock properly. The function
returns zero on success, non-zero otherwise.
- Function: int svz_codec_sock_send (svz_socket_t * sock)
- This is a codec socket structures sock new
write_socket
callback which is called whenever there is data within the send buffer
available and sock is scheduled for writing. It uses the current
send buffer as input buffer for the codec. The output buffer of the codec
is used to invoke the write_socket
callback saved within
svz_codec_sock_send_setup()
. After this the send buffer is
restored again without the bytes consumed by the codec.
- Function: int svz_codec_sock_disconnect (svz_socket_t * sock)
- This callback is used as the
disconnected_socket
callback of the
socket structure sock. It tries to release the resources of both
the receiving and sending codec of sock. The routine is called by
default if the codec socket structure sock gets disconnected for
some external reason.
- Function: svz_codec_t * svz_codec_sock_detect (svz_socket_t * sock)
- This routine can be used to detect a codec on the receive buffer of the
given socket structure sock. It returns a valid codec or
NULL
if no codec could be detected.
3.10 Server type functions
As already noted in the main serveez manual a server type is the
main specification of the abilities and configuration items of a server
which can be instantiated. It is represented by the C structure
svz_servertype_t
in serveez. It contains server specific members
like its name, different callbacks, a single default configuration and a
list of configuration items which determines what can be configured.
3.10.1 Macros for setting up a new server type
When specifying a server type you also need to define configuration items
for it. These items refer to addresses in the example configuration of the
server type. The following macros can be used to determine these items.
- Macro: SVZ_REGISTER_INT (name, item, defaultable)
- Register a simple integer. C-type:
int
. The given name
specifies the symbolic name of the integer and item the integer
itself (not its address). The defaultable argument can be either
SVZ_ITEM_DEFAULTABLE
or SVZ_ITEM_NOTDEFAULTABLE
.
- Macro: SVZ_REGISTER_BOOL (name, item, defaultable)
- Register a boolean value. C-type:
int
.
- Macro: SVZ_REGISTER_INTARRAY (name, item, defaultable)
- Register an array of integers. C-type:
svz_array_t *
.
- Macro: SVZ_REGISTER_STR (name, item, defaultable)
- Register a simple character string. C-type:
char *
.
- Macro: SVZ_REGISTER_STRARRAY (name, item, defaultable)
- Register a string array. C-type:
svz_array_t *
.
- Macro: SVZ_REGISTER_HASH (name, item, defaultable)
- Register a hash table associating strings with strings only. C-type:
svz_hash_t *
.
- Macro: SVZ_REGISTER_PORTCFG (name, item, defaultable)
- Register a port configuration. C-type:
svz_portcfg_t *
.
- Macro: SVZ_REGISTER_END ()
- This macro indicates the end of the list of configuration items. It is
the only mandatory item you need to specify in an example server type
configuration.
- Macro: SVZ_CONFIG_DEFINE (description, config, prototypes)
- Macro for defining the example configuration config (with the
name description and its configuration items prototypes
within a server type definition.
3.10.2 General server type functionality
The following set of functions are used to manage the list of known server
types in the serveez core library. Serveez itself uses some of these functions
to register its builtin server types.
- Variable: svz_array_t * svz_servertypes
- Initial value: NULL
The list of registered servers. Feel free to add yours.
- Function: void svz_servertype_add (svz_servertype_t * server)
- Add the server type server to the currently registered servers.
- Function: void svz_servertype_del (unsigned long index)
- Delete the server type with the index index from the list of
known server types and run its global finalizer if necessary. Moreover
we remove and finalize each server instance of this server type.
- Function: svz_servertype_t * svz_servertype_get (char * name, int dynamic)
- Find a servertype definition by its short name. If dynamic is set
to non-zero an attempt is made to load a shared library that provides
that servertype. Returns
NULL
if no server with the given variable
prefix name has been found.
- Function: svz_servertype_t * svz_servertype_find (svz_server_t * server)
- Find a given server instances server server type. Return
NULL
if there is no such server type (which should never occur since a server is
a child of an server type.
- Function: void svz_servertype_finalize (void)
- Run the global finalizers of each server type and delete all server
types.
- Function: void svz_servertype_print (void)
- Debug helper function to traverse all currently known server types.
3.10.3 Dynamic server loading
The core API of serveez is able to register server types dynamically at
runtime. It uses the dynamic linker capabilities of the underlying operating
system to load shared libraries (or DLLs on Win32). This has been
successfully tested on Windows and GNU/Linux. Other systems are supported
but yet untested. Please tell us if noticing any misbehaviour.
- Function: void svz_dynload_init (void)
- Initialize the shared library interface of the core library.
- Function: void svz_dynload_finalize (void)
- Finalize the shared library interface of the core library. Unload
all libraries no matter if referenced or not.
- Function: svz_servertype_t * svz_servertype_load (char * description)
- Load an additional server definition from a shared library. The given
descriptive name description must be part of the library's name.
- Function: int svz_servertype_unload (char * description)
- Unload a server definition from a shared library. The given
descriptive name description must be part of the library's name.
Return the remaining reference count or -1 on errors.
- Function: void svz_dynload_path_set (svz_array_t * paths)
- Set the additional search paths for the serveez library. The given array of
strings gets
svz_free()
d.
- Function: svz_array_t * svz_dynload_path_get (void)
- Create an array of strings containing each an additional search path.
The loadpath is hold in the environment variable `SERVEEZ_LOAD_PATH'
which can be set from outside the library or modified using
svz_dynload_path_set()
. The returned array needs to be destroyed
after usage.
3.11 Server functions
A server in serveez is an instantiated (configured) server type. It is
merely a copy of a specific server type with a unique server name. It is
represented by the C structure svz_server_t
in the core library.
3.11.1 General functionality
The following section contains functions dealing with the list of known
servers in the core library of serveez, also with the basics like creation
and destruction of such servers.
- Variable: svz_hash_t * svz_servers
- Initial value: NULL
This is the list of actually instantiated servers. The hash table
associates the servers' names with the server instances.
- Function: svz_server_t * svz_server_find (void * cfg)
- Find a server instance by the given configuration structure cfg.
Return
NULL
if there is no such configuration in any server
instance.
- Function: svz_array_t * svz_server_clients (svz_server_t * server)
- Returns a list of clients (socket structures) which are associated
with the given server instance server. If there is no such
socket
NULL
is returned. The calling routine is responsible
to svz_array_destroy()
the returned array.
- Function: svz_server_t * svz_server_add (svz_server_t * server)
- Add the server instance server to the list of instantiated
servers. Returns the previous value of that server if any or
NULL
otherwise.
- Function: svz_server_t * svz_server_get (char * name)
- Get the server instance with the given instance name name.
Return
NULL
if there is no such server yet.
- Function: void svz_server_del (char * name)
- Remove the server instance identified by the name name.
- Function: int svz_server_init (svz_server_t * server)
- This function runs the server initilizer of the given server instance
server and returns zero on success. Otherwise it emits an error
message and returns non-zero.
- Function: void svz_server_finalize (svz_server_t * server)
- This function runs the finalizer callback for the given server instance
server, removes all bindings and frees all resources allocated by
the server instance.
- Function: svz_server_t * svz_server_instantiate (svz_servertype_t * stype, char * name)
- Create a new server instance of the server type stype with the
instance name name.
- Function: void svz_server_notifiers (void)
- Run all the server instances's notify routines. This should be regularly
called within the
svz_periodic_tasks()
function.
- Function: void svz_server_reset (void)
- Runs each server instance's reset callback. The callbacks are run when
a
SIGHUP
signal has been detected by the internal signal handler
of the core library.
- Function: int svz_server_init_all (void)
- Run the initializers of all servers, return -1 if some server did not
think it is a good idea to run.
- Function: int svz_server_finalize_all (void)
- Run the local finalizers for all server instances.
- Function: void svz_server_free (svz_server_t * server)
- Completely destroy the given server instance server. This
especially means to go through each item of the server instances
configuration.
3.11.2 Configuration
These functions provide an interface for configuring a server. They are
used to create and modify the default configuration of a server type in
order to create a server configuration.
- Function: void * svz_server_configure (svz_servertype_t * server, char * name, void * arg, svz_config_accessor_t * configure)
- This function configures a server instance by modifying its default
configuration by the configure callbacks. Therefore you need
to pass the type of server in server, the name of the
server instance and the (optional) modifier callback structure
configure. The arg argument is passed to each of the
callbacks (e.g. specifying a scheme cell). The function returns
either a valid server instance configuration or
NULL
on
errors.
- Function: void svz_config_type_add (svz_config_type_t * type)
- Add the configurable type described by type to the list of
known configurable types.
- Function: int svz_config_type_instantiate (char * type, char * name, char * instance, void * options, svz_config_accessor_t * accessor, char ** error)
- Instantiate a configurable type. The type argument specifies
the configurable type name, name the name of the type (in the
domain of the configurable type) and instance the instance
name of the type. Returns zero on success, otherwise -1.
- Function: void svz_config_type_init (void)
- Adds the configurable types of Serveez. This function is called
from
svz_boot()
.
- Function: void svz_config_type_finalize (void)
- Removes the list of known configurable types and is called from
svz_halt()
.
- Function: void svz_config_prototype_print (svz_config_prototype_t * prototype)
- This function is a debug helper for checking the layout of the
configuration prototype prototype.
- Function: void svz_config_free (svz_config_prototype_t * prototype, void * cfg)
- Release the configuration cfg of the given configuration
prototype prototype. If the configuration equals
NULL
no operation is performed.
- Function: void * svz_config_instantiate (svz_config_prototype_t * prototype, char * name, void * arg, svz_config_accessor_t * accessor)
- This functions is used to instantiate the configuration prototype
prototype using the accessor callbacks accessor
depending on the type of items in the prototype. The
additional argument arg is passed to each of these callbacks.
The name argument should be used to pass the instance name of
the object which is going to be configured.
- Function: svz_array_t * svz_config_intarray_create (int * intarray)
- Create an array (
svz_array_t
) of integers. The given integer
array intarray is a list of integers where its first element which
is intarray[0]
contains the actual length of the given array.
- Function: void svz_config_intarray_destroy (svz_array_t * intarray)
- Destroy the given integer array intarray. This function is the
counter part of
svz_config_intarray_create()
.
- Function: svz_array_t * svz_config_intarray_dup (svz_array_t * intarray)
- Make a plain copy of the given integer array intarray. If this
value is
NULL
no operation is performed and the return value
is NULL
too.
- Function: svz_array_t * svz_config_strarray_create (char ** strarray)
- Create an array of strings. The given list of strings strarray
must be
NULL
terminated in order to indicate its end.
- Function: void svz_config_strarray_destroy (svz_array_t * strarray)
- Destroy the given string array strarray.
- Function: svz_array_t * svz_config_strarray_dup (svz_array_t * strarray)
- Duplicate the given array of strings strarray. Return
NULL
if strarray equals NULL
.
- Function: svz_hash_t * svz_config_hash_create (char ** strarray)
- Create a hash table from the given array of strings strarray which
must be
NULL
terminated in order to indicate the end of the list.
The array consists of pairs of strings where the first one specifies a
key and the following the associated string value. This function is
useful when creating default values for server type configurations.
- Function: void svz_config_hash_destroy (svz_hash_t * strhash)
- This function is the counter part of
svz_config_hash_create()
. It
destroys the given hash table strhash assuming it is a hash
associating strings with strings.
- Function: svz_hash_t * svz_config_hash_dup (svz_hash_t * strhash)
- Duplicate the given hash table strhash assuming it is a hash
associating strings with strings. Return
NULL
if strhash is
NULL
too.
3.11.3 Bindings
The following functionality represents the relationship between port
configurations as described in 3.12 Port configurations and server
instances. When binding a server to a specific port configuration the
core library creates listeners as needed by itself.
- Function: int svz_server_bind (svz_server_t * server, svz_portcfg_t * port)
- Bind the server instance server to the port configuration
port if possible. Return non-zero on errors otherwise zero. It
might occur that a single server is bound to more than one network port
if e.g. the TCP/IP address is specified by "*" since this gets expanded
to the known list of interfaces.
- Function: void svz_server_unbind (svz_server_t * server)
- Remove the given server instance server entirely from the list
of enqueued sockets. This means to delete it from each server socket on
the one hand and to shutdown every child client spawned from this server
on the other hand.
- Function: svz_array_t * svz_server_portcfgs (svz_server_t * server)
- Return an array of port configurations to which the given server instance
server is currently bound to or
NULL
if there is no such
binding. The caller is responsible for freeing the returned array by
running svz_array_destroy()
.
- Function: char * svz_server_bindings (svz_server_t * server)
- Return a static text representation of the server instance's server
current port configuration bindings.
- Function: svz_array_t * svz_server_listeners (svz_server_t * server)
- Return an array of listening socket structures to which the given server
instance server is currently bound to or
NULL
if there is
no such binding. The calling function is reponsible for destroying the
returned array via svz_array_destroy()
.
- Function: int svz_server_single_listener (svz_server_t * server, svz_socket_t * sock)
- This function checks if the given server instance server is
bound to the listening socket structure sock and returns non-zero
if it is the only server instance bound to this socket. Otherwise
the routine returns zero.
- Function: int svz_sock_add_server (svz_socket_t * sock, svz_server_t * server, svz_portcfg_t * port)
- This function attaches the given server instance server to the
listening socket structure sock. It returns zero on success and
non-zero if the server is already bound to the socket.
- Function: int svz_sock_del_server (svz_socket_t * sock, svz_server_t * server)
- Removes the server instance server from the listening socket
structure sock and returns the remaining number of servers bound
to the socket structure.
- Function: svz_socket_t * svz_sock_find_portcfg (svz_portcfg_t * port)
- Returns a socket structure representing a listening server socket with
the port configuration port. If there is no such socket with this
kind of port configuration yet then
NULL
is returned.
- Function: svz_array_t * svz_sock_find_portcfgs (svz_portcfg_t * port)
- This functions goes through the list of listening server socket
structures and returns an array of matching socket structures for the
given port configuration port. The caller is responsible for
freeing the array by running
svz_array_destroy()
. If there are
no such listening server socket structures NULL
is returned.
- Function: svz_socket_t * svz_sock_bind_port (svz_portcfg_t * port)
- Creates and returns a listening server socket structure. The kind of
listener which gets created depends on the given port configuration
port which must be a duplicated copy of one out of the list of
known port configurations. On success the function enqueues the
returned socket structure and assigns the port configuration. Initially
there are no bindings. In case of an error the given port configuration
is freed and
NULL
is returned.
- Function: svz_array_t * svz_sock_bindings (svz_socket_t * sock)
- Returns the binding array of the listening server socket structure
sock or
NULL
if there are no such bindings.
- Function: svz_array_t * svz_sock_servers (svz_socket_t * sock)
- Returns the array of server instances bound to the listening socket
structure sock or
NULL
if there are no bindings. The caller
is responsible for freeing the returned array by running
svz_array_destroy()
.
- Function: svz_binding_t * svz_binding_create (svz_server_t * server, svz_portcfg_t * port)
- Creates a bind structure. The binding contains the given server instance
server and the port configuration port. The caller is
responsible for freeing the returned pointer.
- Function: void svz_binding_destroy (svz_binding_t * binding)
- Destroys the given binding binding. This includes the explicit
destruction of the port configuration. If binding is
NULL
no operation is performed.
- Function: int svz_binding_contains (svz_array_t * bindings, svz_binding_t * binding)
- This function checks whether the server instance binding binding
is part of one of the bindings in the array bindings and returns
non-zero if so. Otherwise zero is returned.
- Function: svz_array_t * svz_binding_join (svz_array_t * bindings, svz_socket_t * sock)
- This function adds the bindings stored in the listening server socket
structure sock to the binding array bindings and returns the
resulting array. If bindings is
NULL
a new array is created.
If the socket structure sock is not a listening server socket
structure no operation is performed.
- Function: svz_binding_t * svz_binding_find (svz_socket_t * sock, svz_server_t * server, svz_portcfg_t * port)
- Goes through the listening server sockets sock bindings and checks
whether it contains the given binding consisting of server and
port. If there is no such binding yet
NULL
is returned
otherwise the appropriate binding.
- Function: svz_array_t * svz_binding_find_server (svz_socket_t * sock, svz_server_t * server)
- Searches through the bindings of the given listening server socket
structure sock and checks whether the server instance server
is bound to this socket structure. The function returns these binding and
returns
NULL
otherwise. The caller is responsible for freeing
the returned array.
- Function: int svz_binding_contains_server (svz_socket_t * sock, svz_server_t * server)
- This function checks whether the given server instance server is
bound to the server socket structure sock. Returns zero if not and
non-zero otherwise.
- Function: svz_array_t * svz_binding_filter_pipe (svz_socket_t * sock)
- This is the accept filter for the listening server socket structures
sock with pipe port configurations. It returns all bindings. The
caller is responsible for freeing the returned array by running
svz_array_destroy()
.
- Function: svz_array_t * svz_binding_filter_net (svz_socket_t * sock, unsigned long addr, unsigned short port)
- This is the accept filter for the listening server socket structures
sock with network port configurations. It returns the bindings
allowed to be accepted. The caller is responsible for freeing the returned
array by running
svz_array_destroy()
. Which of the bindings are
allowed depends on the network interface address addr and the
network port port.
- Function: svz_array_t * svz_binding_filter (svz_socket_t * sock)
- This is the main filter routine running either
svz_binding_filter_net()
or svz_binding_filter_pipe()
depending on the type of port configuration the given socket sock
contains.
3.11.4 Server core
- Variable: int svz_nuke_happened
- Initial value: 0
When svz_nuke_happened is set to a non-zero value, the server
will terminate its main loop.
- Variable: HANDLE svz_child_died
- svz_child_died is set to a non-zero value whenever the server
receives a SIGCHLD signal.
- Variable: long svz_notify
- This holds the time on which the next call to
svz_periodic_tasks()
should occur.
- Function: void svz_executable (char * file)
- Set the name of the executable file which uses the core library. This
is usually
argv[0]
.
- Function: int svz_periodic_tasks (void)
- This routine gets called once a second and is supposed to perform any
task that has to get scheduled periodically. It checks all sockets'
timers and calls their timer functions when necessary.
- Variable: svz_socket_t * svz_sock_root
- Initial value: NULL
svz_sock_root is the pointer to the head of the list of sockets,
which are handled by the server loop.
- Variable: svz_socket_t * svz_sock_last
- Initial value: NULL
svz_sock_last always points to the last structure in the socket queue
and is NULL when the queue is empty.
- Function: svz_socket_t * svz_sock_find (int id, int version)
- Return the socket structure for the socket id id and the version
version or
NULL
if no such socket exists. If version
is -1 it is not checked.
- Function: int svz_sock_schedule_for_shutdown (svz_socket_t * sock)
- Mark socket sock as killed. That means that no operations except
disconnecting and freeing are allowed anymore. All marked sockets
will be deleted once the server loop is through.
- Function: int svz_sock_enqueue (svz_socket_t * sock)
- Enqueue the socket sock into the list of sockets handled by
the server loop.
- Function: int svz_sock_dequeue (svz_socket_t * sock)
- Remove the socket sock from the list of sockets handled by
the server loop.
- Function: int svz_sock_shutdown (svz_socket_t * sock)
- Do everything to shut down the socket sock. The socket structure
gets removed from the socket queue, the file descriptor is closed
and all memory used by the socket gets freed. Note that this
function calls the sock's disconnect handler if defined.
- Function: void svz_sock_shutdown_all (void)
- Shutdown all sockets within the socket list no matter if it was
scheduled for shutdown or not.
- Function: void svz_sock_setparent (svz_socket_t * child, svz_socket_t * parent)
- Set the sockets child parent to the given socket structure
parent. This should be called whenever a listener accepts a
connection and creates a new child socket.
- Function: svz_socket_t * svz_sock_getparent (svz_socket_t * child)
- Return the sockets child parent socket structure or
NULL
if this socket does not exist anymore. This might happen if a listener
dies for some reason.
- Function: void svz_sock_setreferrer (svz_socket_t * sock, svz_socket_t * referrer)
- Set the referring socket structure of sock to the given socket
referrer. This can be used to create some relationship between
two socket structures. If referrer is
NULL
the reference
will be invalidated.
- Function: svz_socket_t * svz_sock_getreferrer (svz_socket_t * sock)
- Get the referrer of the socket structure sock. Return
NULL
if there is no such socket.
- Function: svz_portcfg_t * svz_sock_portcfg (svz_socket_t * sock)
- Return the parents port configuration of the socket structure sock
or
NULL
if the given socket has no parent, i.e. is a listener.
- Macro: svz_sock_foreach (sock)
- Go through each socket structure in the chained list.
- Macro: svz_sock_foreach_listener (sock)
- Goes through the chained list of socket structures and filters each
listener.
- Function: int svz_sock_check_frequency (svz_socket_t * parent, svz_socket_t * child)
- This routine checks the connection frequency of the socket structure
child for the port configuration of the listener socket structure
parent. Returns zero if the connection frequency is valid,
otherwise non-zero.
- Function: int svz_sock_check_access (svz_socket_t * parent, svz_socket_t * child)
- This function returns zero if the child socket is allowed to
connect to the port configuration of the parent socket structure
which needs to be a listener therefore.
- Function: void svz_sock_table_create (void)
- Create the socket lookup table initially. Must be called from
svz_boot()
.
- Function: void svz_sock_table_destroy (void)
- Destroy the socket lookup table finally. Must be called from
svz_halt()
.
- Function: void svz_sock_check_bogus (void)
- Goes through all socket and shuts invalid ones down.
- Function: void svz_sock_check_children (void)
- Goes through the list of socket structures and checks whether each
pid
stored in a socket structure has died. If so, the
child_died
callback is called. If this callback returned non-zero
the appropriate socket structure gets scheduled for shutdown.
- Function: int svz_sock_child_died (svz_socket_t * sock)
- This routine checks whether the child process specified by the
pid
handle stored in the socket structure sock is still alive. It
returns zero if so, otherwise (when the child process died) non-zero. This
routine is called from svz_sock_check_children()
.
- Function: void svz_signal_up (void)
- Setup signaling for the core library.
- Function: void svz_signal_dn (void)
- Deinstall signaling for the core library.
- Function: RETSIGTYPE svz_signal_handler (int sig)
- Handle some signals to handle server resets (SIGHUP), to ignore
broken pipes (SIGPIPE) and to exit gracefully if requested by the
user (SIGINT, SIGTERM).
- Function: void svz_strsignal_init (void)
- Prepare library so that
svz_strsignal()
works. Called
from svz_boot()
.
- Function: void svz_strsignal_destroy (void)
- The function
svz_strsignal()
does not work afterwards anymore.
Called from svz_halt()
.
- Function: char * svz_strsignal (int sig)
- Resolve the given signal number to form a describing string.
This function is reentrant, use it from the signal handler.
It does not return NULL. The returned pointer is shared amongst
all users. For unknown signals (which is not supposed to happen)
the returned string points to a statically allocated buffer (which
destroys the reentrance, of course) [who cares :-].
3.11.5 Server loop
This paragraph describes the main server loop functionality. There two modes
of operation. The default mode as used in serveez is to jump into the loop
and waiting until the core library drops out of it. The user can also tell
the serveez core library to pass its socket chain once and return
immediately. Thus you are able to issue additional functionality in between
each pass if you cannot handle this within the timers (notifiers) of servers
and sockets.
- Function: int svz_check_sockets (void)
- Check the server and client sockets for incoming connections
and data, and process outgoing data.
- Function: void svz_loop_pre (void)
- Call this function once before using
svz_loop_one()
.
- Function: void svz_loop_post (void)
- Call this function once after using
svz_loop_one()
.
- Function: void svz_loop (void)
- Main server loop. Handle all signals, incoming and outgoing connections
and listening server sockets.
- Function: void svz_loop_one (void)
- This routine handles all things once and is called regularly in the
below
svz_loop()
routine.
3.11.6 Server sockets
The next section deals with creating and handling listeners. The functions
below provide the default routines invoked when accepting a new connection
on a listener. This is necessary for connection oriented protocols (TCP and
named pipes) only.
- Function: svz_socket_t * svz_server_create (svz_portcfg_t * port)
- Create a listening server socket (network or pipe). port is the
port configuration to bind the server socket to. Return a
NULL
pointer on errors.
- Function: int svz_tcp_accept (svz_socket_t * server_sock)
- Something happened on the a server socket, most probably a client
connection which we will normally accept. This is the default callback
for
read_socket
for listening tcp sockets.
- Function: int svz_pipe_accept (svz_socket_t * server_sock)
- Check if client pipe is connected. This is the default callback for
idle_func
for listening pipe sockets.
3.12 Port configurations
A port configuration is a structure defining a network or file system
configuration. Depending on the type of a server it can be bound to one
or more port configurations. There are two major types of port
configurations: connection and packet oriented protocol port configurations.
TCP and PIPE configurations are connection oriented and ICMP, UDP and
RAW configurations are packet oriented.
Serveez holds a list of port configurations. Each configuration is
identified by its name. When you bind a server to a port configuration it
does not get bound to a certain name but to its content. If there are two
or more port configuration specifying the same network or file system
configuration just a single one gets actually used.
- Function: svz_portcfg_t * svz_portcfg_create (void)
- Create a new blank port configuration.
- Function: int svz_portcfg_equal (svz_portcfg_t * a, svz_portcfg_t * b)
- Check if two given port configurations structures are equal i.e.
specifying the same network port or pipe files. Returns
PORTCFG_EQUAL
if a and b are identical,
PORTCFG_MATCH
if the network address ofeither port
configurations contains the other (INADDR_ANY match) and otherwise
PORTCFG_NOMATCH
or possibly PORTCFG_CONFLICT
.
- Function: svz_portcfg_t * svz_portcfg_add (char * name, svz_portcfg_t * port)
- Add the given port configuration port associated with the name
name to the list of known port configurations. Return
NULL
on errors. If the return port configuration equals the given port
configuration the given one has been successfully added.
- Function: svz_portcfg_t * svz_portcfg_del (char * name)
- Remove the named port configuration identified by name from the
list of known port configurations. Return
NULL
on errors or
otherwise the port configuration associated with name.
- Function: svz_portcfg_t * svz_portcfg_get (char * name)
- Return the port configuration associated with the given name name.
This function returns
NULL
on errors.
- Function: void svz_portcfg_destroy (svz_portcfg_t * port)
- This function makes the given port configuration port completely
unusable. No operation is performed if port is
NULL
. If the
port configuration is part of the list of known port configurations it
it thrown out of them.
- Function: void svz_portcfg_free (svz_portcfg_t * port)
- This function frees all resources allocated by the given port
configuration port.
- Function: void svz_portcfg_finalize (void)
- Delete the list of known port configurations. This routine should
definitely called from the core library's finalizer.
- Function: int svz_portcfg_mkaddr (svz_portcfg_t * this)
- Construct the
sockaddr_in
fields from the ipaddr
field.
Returns zero if it worked. If it does not work the ipaddr
field
did not consist of an ip address in dotted decimal form.
- Function: void svz_portcfg_prepare (svz_portcfg_t * port)
- Prepare the given port configuration port. Fill in default values
for yet undefined variables.
- Function: void svz_portcfg_print (svz_portcfg_t * this, FILE * f)
- Debug helper: Emit a printable representation of the the given
port configuration to the given FILE stream f.
- Function: char * svz_portcfg_text (svz_portcfg_t * port)
- This function returns a simple text representation of the given port
configuration port. The returned character string is statically
allocated. Thus you cannot use it twice in argument lists.
- Function: svz_portcfg_t * svz_portcfg_dup (svz_portcfg_t * port)
- Make a copy of the given port configuration port. This function
is used in
svz_portcfg_expand()
.
- Function: svz_array_t * svz_portcfg_expand (svz_portcfg_t * this)
- Expand the given port configuration this if it is a network port
configuration and if the network ip address is
INADDR_ANY
. Return
an array of port configurations which are copies of the given.
- Macro: svz_portcfg_addr (port)
- Return the pointer of the
sockaddr_in
structure of the given
port configuration port if it is a network port configuration.
Otherwise return NULL
.
- Macro: svz_portcfg_port (port)
- Return the UDP or TCP port of the given port configuration or zero
if it neither TCP nor UDP.
- Macro: svz_portcfg_ipaddr (port)
- Return the pointer to the ip address
ipaddr
of the given
port configuration port if it is a network port configuration.
Otherwise return NULL
.
- Macro: svz_portcfg_device (port)
- This macro returns the network device name stored in the given port
configuration port if it is a network port configuration. The
returned pointer can be
NULL
if there is no such device set
or if the port configuration is not a network port configuration.
- Function: int svz_portcfg_set_ipaddr (svz_portcfg_t * this, char * ipaddr)
- This function can be used to set the character string representation
of a the port configuration this in dotted decimal form
(ipaddr). Returns zero on success, non-zero otherwise.
- Function: void svz_portcfg_destroy_accepted (svz_portcfg_t * port)
- Destroy the list of connections for each ip address ever connected to the
given port configuration port.
- Function: void svz_portcfg_destroy_access (svz_portcfg_t * port)
- Destroy the deny and allowed access list of the given port configuration
port.
3.13 Boot functions
This section contains the description of some runtime checkable flags
indicating the abilities of the running serveez core API and the underlying
operating system. It also describes the most important functions
svz_boot()
and svz_halt()
which must be the first and the last
call to the core API.
- Variable: svz_config_t svz_config
- Initial value: { NULL, 0, 0, 0 }
The configuration structure of the core library.
- Variable: char * svz_library
- Initial value: "serveez"
The symbolic name of the core library.
- Variable: char * svz_version
- Initial value: __serveez_version
The version of the core library.
- Variable: char * svz_build
- Initial value: __serveez_timestamp
Timestamp when core library has been build.
- Variable: int svz_have_debug
- Initial value: 1
Runtime flag if this is the debug version or not.
- Variable: int svz_have_Win32
- Initial value: 1
Runtime flag if this is Win32 or not.
- Variable: int svz_have_floodprotect
- Initial value: 1
Runtime checkable flags for configuration language and code if flood
protection has been enabled or not.
- Function: int svz_net_startup (void)
- This routine has to be called once before you could use any of the
serveez core library functions.
- Function: int svz_net_cleanup (void)
- Shutdown the serveez core library.
- Function: void svz_init_config (void)
- Initialization of the configuration.
- Function: void svz_boot (void)
- Initialization of the core library.
- Function: void svz_halt (void)
- Finalization of the core library.
3.14 Network interface functions
The network interface functions of the serveez core API allow the access
to the network devices on your system. The system administrator can setup
these devices to be bound to different Internet addresses and thereby split
the network configuration into different "domains". Thus the system is able
to separate traffic of different networks. If setup correctly serveez can
follow these rules.
- Variable: svz_vector_t * svz_interfaces
- Initial value: NULL
The available interface list.
- Function: void svz_interface_list (void)
- Print the text representation of all the network interfaces.
- Function: void svz_interface_collect (void)
- Collect all available network interfaces and put them into the list
svz_interfaces. This is useful in order to
bind()
server
sockets to specific network interfaces. Thus you can make certain
services accessible from "outside" or "inside" a network installation
only.
- Function: int svz_interface_free (void)
- Free the network interface list.
- Function: int svz_interface_add (int index, char * desc, unsigned long addr, int detected)
- Add a network interface to the current list of known interfaces. Drop
duplicate entries. The given arguments index specifies the network
interface index number, desc an interface desription, addr
the IP address in network byte order and the detected flag if
the given network interface has been detected by Serveez itself or not.
- Function: svz_interface_t * svz_interface_get (unsigned long addr)
- This function returns the interface structure for the given IP address
addr if any. Returns
NULL
otherwise.
- Function: svz_interface_t * svz_interface_search (char * desc)
- The following function returns a network interface structure for a given
interface name (e.g. eth0). If no such interface exists it returns
NULL
.
- Function: void svz_interface_check (void)
- This function checks for network interface changes. It emits messages for
new and removed interfaces. Software interfaces which have not been
detected by Serveez stay untouched. If Serveez receives a
SIGHUP
signal the signal handler runs it once.
- Macro: svz_interface_foreach (ifc, i)
- Iteration macro for the list of known network interfaces. If any
each interface gets assigned to ifc. The variable i is the
iteration variable.
3.15 Useful Windows functions
Serveez is meant to run on Windows systems as well (with some restrictions
of course). The following functions come up with the Windows implementation
of the serveez core API only. They allow access to the Windows registry
database and some other useful things.
- Function: int svz_windoze_start_daemon (char * prog)
- Start the windows daemon thread and detach from the current console.
- Function: int svz_windoze_stop_daemon (void)
- Stop the windows daemon thread.
- Function: WCHAR * svz_windoze_asc2uni (CHAR * asc)
- Convert an ASCII string into a UNICODE string.
- Function: CHAR * svz_windoze_uni2asc (WCHAR * unicode)
- Convert a UNICODE string into an ASCII string.
- Function: unsigned svz_windoze_get_reg_unsigned (HKEY key, char * subkey, char * subsubkey, unsigned def)
- Read an unsigned integer value from the Windows Registry Database.
- Function: void svz_windoze_set_reg_unsigned (HKEY key, char * subkey, char * subsubkey, unsigned value)
- Write an unsigned integer value to the Windows Registry Database.
- Function: char * svz_windoze_get_reg_string (HKEY key, char * subkey, char * subsubkey, char * def)
- Read a string value from the Windows Registry Database.
- Function: void svz_windoze_set_reg_string (HKEY key, char * subkey, char * subsubkey, char * value)
- Write a string value to the Windows Registry Database.
This document was generated
by Stefan Jahn on May, 31 2003
using texi2html