yimmo.h
=========
Yimmo public API. Provides access to most commonly used types and routines.
.. toctree::
:hidden:
:maxdepth: 3
.. contents:: Contents
:local:
:depth: 3
---------------------------------------------------------------
Version
---------------------------------------------------------------
Libyimmo uses `Semantic Versioning `_ for package
releases versions, and
`libtool versioning `_
for the library's ABI version.
The following macros can be used to determine version info at compile-time:
.. c:macro:: YIMMO_VERSION_MAJOR
Libyimmo package major version
.. code-block:: c
:caption: Definition
#define YIMMO_VERSION_MAJOR 0
.. c:macro:: YIMMO_VERSION_MINOR
Libyimmo package minor version
.. code-block:: c
:caption: Definition
#define YIMMO_VERSION_MINOR 2
.. c:macro:: YIMMO_VERSION_PATCH
Libyimmo patch level
.. code-block:: c
:caption: Definition
#define YIMMO_VERSION_PATCH 4
.. c:macro:: YIMMO_VERSION
Libyimmo *package* version (Semantic Versioning).
The version is encoded as a 32-bit unsigned integer. In most-to-least
significant byte order the bytes are ``major``, ``minor``, and ``patch``.
(The least significant byte is reserved for future use)
.. code-block:: c
assert( ((YIMMO_VERSION >> 24) & 0xff) == YIMMO_VERSION_MAJOR );
assert( ((YIMMO_VERSION >> 16) & 0xff) == YIMMO_VERSION_MINOR );
assert( ((YIMMO_VERSION >> 8) & 0xff) == YIMMO_VERSION_PATCH );
.. code-block:: c
:caption: Definition
#define YIMMO_VERSION 0x00020400
.. c:macro:: YMO_ABI_CURRENT
Libtool ABI "current"
.. code-block:: c
:caption: Definition
#define YMO_ABI_CURRENT 1
.. c:macro:: YMO_ABI_AGE
Libtool ABI "age".
.. code-block:: c
:caption: Definition
#define YMO_ABI_AGE 1
.. c:macro:: YMO_ABI_REVISION
Libtool ABI "revision".
.. code-block:: c
:caption: Definition
#define YMO_ABI_REVISION 4
---------------------------------------------------------------
Types
---------------------------------------------------------------
.. c:type:: ymo_status_t
Status code type used by the libyimmo API (generally follows errno.h).
.. note::
This is *just a typedef* for ``int``. It exists to make it easier for
library maintainers to identify status values in the code. It's not
necessary that you use ``ymo_status_t`` in your own code (though,
you are also welcome to!).
.. code-block:: c
:caption: Definition
typedef int ymo_status_t;
.. c:macro:: YMO_OKAY
Status code indicating everything went okay.
**Spoiler**: this is defined to be ``0`` and we use errno.h code values for
error conditions.
**Definition:**
.. code-block:: c
:caption: Definition
#define YMO_OKAY 0
.. c:macro:: YMO_ERROR_SSIZE_T
Convenience macro for setting error condition from functions
that return a ``size_t``. The following are functionally
equivalent:
.. code-block:: c
ssize_t my_blocking_function()
{
errno = EAGAIN;
return -1;
}
ssize_t my_blocking_function()
{
return YMO_ERROR_SSIZE_T(EAGAIN);
}
.. code-block:: c
:caption: Definition
#define YMO_ERROR_SSIZE_T(x) (errno=x, -1)
.. c:macro:: YMO_ERROR_PTR
Convenience macro for setting error condition from functions
that return a pointer. The following are functionally
equivalent:
.. code-block:: c
void* my_blocking_function()
{
errno = EAGAIN;
return NULL;
}
void* my_blocking_function()
{
return YMO_ERROR_PTR(EAGAIN);
}
.. code-block:: c
:caption: Definition
#define YMO_ERROR_PTR(x) (errno=x, NULL)
.. c:type:: ymo_server_t
Opaque struct used to represent a single server.
A yimmo "server" consists of a listener for a *single port*.
.. admonition:: Info
For more detailed information, see the :ref:`server` docs.
.. code-block:: c
:caption: Definition
typedef struct ymo_server ymo_server_t;
.. c:type:: ymo_conn_t
Opaque struct used to represent a connection.
.. admonition:: Info
For more detailed information, see the :ref:`connection` docs.
.. code-block:: c
:caption: Definition
typedef struct ymo_conn ymo_conn_t;
.. c:type:: ymo_proto_t
Opaque struct type used to represent a protocol.
.. admonition:: Info
For more detailed information, see the :ref:`protocols` docs.
.. code-block:: c
:caption: Definition
typedef struct ymo_proto ymo_proto_t;
.. c:type:: ymo_user_conn_init_cb_t
User-level connection init callback.
This function provides user-code with an opportunity to associate
application data with a newly initiated connection. The data associated
with the connection will also be passed to the user cleanup callback
just prior to final connection teardown.
(see also :c:type:`ymo_user_conn_cleanup_cb_t`)
:param server: server object issuing the callback
:param conn: new connection object
Returns user data to associate with the new connection
.. code-block:: c
:caption: Definition
typedef void* (*ymo_user_conn_init_cb_t)(
ymo_server_t* server,
ymo_conn_t* conn);
.. c:type:: ymo_user_conn_cleanup_cb_t
User-level connection cleanup callback.
This function provides user-code with an opportunity to perform some
cleanup on application data associated with the connection, just prior
to final teardown.
(see also :c:type:`ymo_user_conn_init_cb_t`)
:param server: server object issuing the callback
:param conn: new connection object
:param user: data associated with connection
.. code-block:: c
:caption: Definition
typedef void (*ymo_user_conn_cleanup_cb_t)(
ymo_server_t* server,
ymo_conn_t* conn,
void* user);
.. c:type:: ymo_server_config_flags_t
Enumeration type used to pass server configuration flags.
.. code-block:: c
:caption: Definition
typedef enum ymo_server_config_flags {
YMO_SERVER_REUSE_ADDR = 0x01, /* allow service to bind while socket in the WAIT state */
YMO_SERVER_REUSE_PORT = 0x02, /* allow multiple processes to bind to the listen port */
} ymo_server_config_flags_t;
.. c:type:: ymo_server_config_t
Struct used to pass configuration information to
:c:func:`ymo_server_create`.
.. code-block:: c
:caption: Definition
typedef struct ymo_server_config {
struct ev_loop* loop; /* I/O loop */
ymo_user_conn_init_cb_t user_init; /* user conn init callback */
ymo_user_conn_cleanup_cb_t user_cleanup; /* user conn cleanup callback */
in_port_t port; /* listen port */
ymo_server_config_flags_t flags; /* server settings */
int listen_backlog; /* TCP listen backlog */
int use_tls; /* 1: enabled; 0; disabled */
const char* cert_path; /* Optional TLS cert */
const char* key_path; /* Optional TLS private key*/
} ymo_server_config_t;
.. c:type:: ymo_bucket_t
Apache-esque "bucket" type used to handle streams of data.
.. code-block:: c
:caption: Definition
typedef struct ymo_bucket ymo_bucket_t;
.. _Yimmo Buckets:
---------------------------------------------------------------
Buckets
---------------------------------------------------------------
.. c:function:: ymo_bucket_t* ymo_bucket_create( ymo_bucket_t* restrict prev, ymo_bucket_t* restrict next, char* buf, size_t buf_len, const char* data, size_t len)
Create a "bucket" containing data to process.
A bucket has two pointer fields and two length fields. One points to the
data to be sent. The other is an optional pointer to the buffer containing
that data which is to freed on send.
:param prev: a pointer to the previous bucket in the list (may be NULL)
:param next: a pointer to the next bucket in the list (may be NULL)
:param buf: an optional pointer to managed data to be freed on send (may be NULL)
:param buf_len: length of buf (must be specified if buf is non-NULL)
:param data: a pointer to the data to be sent
:param len: the length of the data to be sent
:returns: a new bucket created from the input parameters
.. code-block:: c
:caption: Example
// hello is not freed after send, because we just provide "data":
ymo_bucket_t* hello = ymo_bucket_create(
NULL, NULL, // don't bother with next/prev for first item
NULL, 0, // no "buf" set here
"Hello, ", 7 // data to be sent is here
);
// world is freed after send because we provided the "data" (item to be
// sent), as well as "buf" (the underlying buffer):
char* world = strdup("World!");
ymo_bucket_t* world = ymo_bucket_create(
hello, NULL, // world is part of a chain; hello is before it
world, 7, // this is the buffer containing the payload
world, 6 // this is the payload
);
// send "Hello, world!" somewhere:
some_send_function(fd, hello);
.. c:function:: ymo_bucket_t* ymo_bucket_create_cpy( ymo_bucket_t* restrict prev, ymo_bucket_t* restrict next, const char* buf, size_t buf_len)
Create a "bucket" copying data to process.
:param prev: a pointer to the previous bucket in the list (may be NULL)
:param next: a pointer to the next bucket in the list (may be NULL)
:param buf: a pointer to the data to be copied and sent
:param buf_len: the length of the data to be copied sent
:returns: a new bucket created from the input parameters
.. c:function:: ymo_bucket_t* ymo_bucket_from_file( ymo_bucket_t* restrict prev, ymo_bucket_t* restrict next, const char* filepath)
Create a "bucket" from the file at `filepath`.
.. warning::
THIS IS A HACK!
:param prev: a pointer to the previous bucket in the list (may be NULL)
:param next: a pointer to the next bucket in the list (may be NULL)
:param filepath: the filepath of the file data to be sent
:returns: a new bucket created from the input parameters
:param prev: a pointer to the previous bucket in the list (may be NULL)
:param next: a pointer to the next bucket in the list (may be NULL)
:param filepath: the filepath of the file data to be sent
:returns: a new bucket created from the input parameters
.. c:macro:: YMO_BUCKET_FROM_REF
Create a bucket which references static data (or data that is
guaranteed to live longer than the bucket itself).
:param data: a pointer to the data to be sent
:param len: the length of the data to be sent
:returns: a new bucket created from the input parameters
.. code-block:: c
:caption: Definition
#define YMO_BUCKET_FROM_REF(data, len) \
ymo_bucket_create(NULL, NULL, NULL, 0, data, len)
.. c:macro:: YMO_BUCKET_FROM_CPY
Create a bucket by copying the given data and allowing yimmo
to manage the copy internally.
:param data: a pointer to the data to be copied and sent
:param len: the length of the data to be copied and sent
:returns: a new bucket created from the input parameters
.. code-block:: c
:caption: Definition
#define YMO_BUCKET_FROM_CPY(data, len) \
ymo_bucket_create_cpy(NULL, NULL, data, len)
.. c:function:: ymo_bucket_t* ymo_bucket_append( ymo_bucket_t* restrict dst, ymo_bucket_t* restrict src)
Append src onto dst, if it exists; else return src.
:param dst: Destination bucket.
:param src: Source bucket.
:returns: destination with src appended.
.. c:function:: size_t ymo_bucket_len_all(ymo_bucket_t* p)
Get the total length of a chain of buckets.
:param p: head of bucket chain
:returns: length of all content in the chain of buckets
.. c:function:: ymo_bucket_t* ymo_bucket_tail(ymo_bucket_t* p)
Get the last bucket in a chain of buckets.
:param p: a bucket in a chain of buckets
:returns: a pointers to the last bucket in the chain
.. c:function:: void ymo_bucket_free(ymo_bucket_t* bucket)
Free a bucket and - if managed - it's buffer.
:param bucket: the bucket to free.
.. c:function:: void ymo_bucket_free_all(ymo_bucket_t* bucket)
Free all buckets in a chain.
:param bucket: invoke :c:func:`ymo_bucket_free` on every bucket in a chain
---------------------------------------------------------------
Server Functions
---------------------------------------------------------------
.. c:type:: ymo_server_state_t
Enum used to indicate state for :c:type:`ymo_server_t`. Used primarily
to track termination state (graceful vs hard stop, etc).
.. code-block:: c
:caption: Definition
typedef enum ymo_server_state {
YMO_SERVER_CREATED,
YMO_SERVER_INITIALIZED,
YMO_SERVER_STARTED,
YMO_SERVER_STOP_GRACEFUL,
} ymo_server_state_t;
.. c:function:: ymo_server_t* ymo_server_create( ymo_server_config_t* svr_config, ymo_proto_t* proto)
Create a new server object.
:param svr_config: configurations struct for the new server
:param proto: pointer to a protocol created using the init function in
the appropriate module. (see also :c:type:`yimmo_modules`)
:returns: pointer to a new server instance or NULL on failure
.. c:function:: ymo_status_t ymo_server_init(ymo_server_t* server)
Bind the server to the configured port.
:param server: the server to start
:returns: YMO_OKAY on success; appropriate errno on failure
.. c:function:: ymo_status_t ymo_server_init_socket(ymo_server_t* server, int fd)
Initialize a server using a pre-configured socket.
:param server: the server to start
:param fd: the socket the server should listen on
:returns: YMO_OKAY on success; appropriate errno on failure
.. c:function:: ymo_status_t ymo_server_pre_fork(ymo_server_t* server)
Invoke *before forking* if forked processes will share a
common listen socket.
.. c:function:: ymo_status_t ymo_server_start(ymo_server_t* server, struct ev_loop* loop)
Create and start the ev_io watchers for the listen fd we invoke accept() on.
.. warning::
If you intend to **fork** and the forked processes will share a common
listen fd, you *must call* :c:func:`ymo_server_pre_fork` *before
starting the server!*
:param server: the server to start
:returns: YMO_OKAY on success; appropriate errno on failure
.. c:function:: ymo_server_state_t ymo_server_get_state(ymo_server_t* server)
.. c:function:: struct ev_loop* ymo_server_loop(ymo_server_t* server)
Get the ev loop used by a given server.
.. c:function:: ymo_status_t ymo_server_stop_graceful(ymo_server_t* server)
Gracefully shutdown a ymo_server.
:param server: the server to stop
:returns: YMO_OKAY on success; appropriate errno on failure
.. c:function:: void ymo_server_free(ymo_server_t* server)
Free a server object.
:param server: the server instance to free
---------------------------------------------------------------
Connection Functions
---------------------------------------------------------------
.. c:function:: ymo_server_t* ymo_conn_server(const ymo_conn_t* conn)
Given a connection, return a pointer to the owning server.
:param conn: valid ymo_conn_t
:returns: the ymo_server_t instance which owns the given connection
.. c:function:: struct ev_loop* ymo_conn_loop(const ymo_conn_t* conn)
Given a connection, return a pointer to the managing ev_loop.
:param conn: valid ymo_conn_t
:returns: the struct ev_loop* used to manage the connection I/O
.. c:function:: ymo_proto_t* ymo_conn_proto(const ymo_conn_t* conn)
Given a connection, return a pointer to the current protocol
:param conn: valid ymo_conn_t
:returns: the current protocol for this connection
.. c:function:: void ymo_conn_id(uuid_t dst, const ymo_conn_t* conn)
Given a connection, return its unique identifier.
:param dst: the destination uuid_t object into which we copy the id
:param conn: valid ymo_conn_t
.. c:function:: char* ymo_conn_id_str(const ymo_conn_t* conn)
Given a connection, return a pointer to the string representation of its
unique identifier.
:param conn: a valid ymo_conn_t
:returns: `const char*` to string representation of conn uuid.
.. warning:: This function is *not* thread-safe. The pointer returned is to
a static string buffer. For multi-threaded uses, best leverage
ymo_conn_id to copy the connection id into a local uuid_t and use
uuid_unparse.
.. c:function:: ymo_status_t ymo_conn_shutdown(ymo_conn_t* conn)
Start the shutdown sequence for a connection's underlying socket.
:param conn: The connection to close.
:returns: the connection state after invocation.
---------------------------------------------------------------
Protocol Functions
---------------------------------------------------------------
.. c:function:: const char* ymo_proto_name(ymo_proto_t* proto)
Given a protocol object, return the protocol name.
:param proto: The protocol object we wish to identify
:returns: string representation of the protocol name