yimmo.h

Yimmo public API. Provides access to most commonly used types and routines.

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:

YIMMO_VERSION_MAJOR

Libyimmo package major version

Definition
#define YIMMO_VERSION_MAJOR   0
YIMMO_VERSION_MINOR

Libyimmo package minor version

Definition
#define YIMMO_VERSION_MINOR   2
YIMMO_VERSION_PATCH

Libyimmo patch level

Definition
#define YIMMO_VERSION_PATCH   4
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)

assert( ((YIMMO_VERSION >> 24) & 0xff) == YIMMO_VERSION_MAJOR );
assert( ((YIMMO_VERSION >> 16) & 0xff) == YIMMO_VERSION_MINOR );
assert( ((YIMMO_VERSION >>  8) & 0xff) == YIMMO_VERSION_PATCH );
Definition
#define YIMMO_VERSION         0x00020400
YMO_ABI_CURRENT

Libtool ABI “current”

Definition
#define YMO_ABI_CURRENT       1
YMO_ABI_AGE

Libtool ABI “age”.

Definition
#define YMO_ABI_AGE           1
YMO_ABI_REVISION

Libtool ABI “revision”.

Definition
#define YMO_ABI_REVISION      4

Types

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!).

Definition
typedef int ymo_status_t;
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:

Definition
#define YMO_OKAY 0
YMO_ERROR_SSIZE_T

Convenience macro for setting error condition from functions that return a size_t. The following are functionally equivalent:

ssize_t my_blocking_function()
{
   errno = EAGAIN;
   return -1;
}


ssize_t my_blocking_function()
{
   return YMO_ERROR_SSIZE_T(EAGAIN);
}
Definition
#define YMO_ERROR_SSIZE_T(x) (errno=x, -1)
YMO_ERROR_PTR

Convenience macro for setting error condition from functions that return a pointer. The following are functionally equivalent:

void* my_blocking_function()
{
   errno = EAGAIN;
   return NULL;
}


void* my_blocking_function()
{
   return YMO_ERROR_PTR(EAGAIN);
}
Definition
#define YMO_ERROR_PTR(x) (errno=x, NULL)
type ymo_server_t

Opaque struct used to represent a single server.

A yimmo “server” consists of a listener for a single port.

Info

For more detailed information, see the Server docs.

Definition
typedef struct ymo_server ymo_server_t;
type ymo_conn_t

Opaque struct used to represent a connection.

Info

For more detailed information, see the Connections docs.

Definition
typedef struct ymo_conn ymo_conn_t;
type ymo_proto_t

Opaque struct type used to represent a protocol.

Info

For more detailed information, see the Protocols docs.

Definition
typedef struct ymo_proto ymo_proto_t;
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 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

Definition
typedef void* (*ymo_user_conn_init_cb_t)(
        ymo_server_t* server,
        ymo_conn_t* conn);
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 ymo_user_conn_init_cb_t)

Param server

server object issuing the callback

Param conn

new connection object

Param user

data associated with connection

Definition
typedef void (*ymo_user_conn_cleanup_cb_t)(
        ymo_server_t* server,
        ymo_conn_t* conn,
        void* user);
type ymo_server_config_flags_t

Enumeration type used to pass server configuration flags.

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;
type ymo_server_config_t

Struct used to pass configuration information to ymo_server_create().

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;
type ymo_bucket_t

Apache-esque “bucket” type used to handle streams of data.

Definition
typedef struct ymo_bucket ymo_bucket_t;

Buckets

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.

Parameters
  • prev – a pointer to the previous bucket in the list (may be NULL)

  • next – a pointer to the next bucket in the list (may be NULL)

  • buf – an optional pointer to managed data to be freed on send (may be NULL)

  • buf_len – length of buf (must be specified if buf is non-NULL)

  • data – a pointer to the data to be sent

  • len – the length of the data to be sent

Returns

a new bucket created from the input parameters

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);
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.

Parameters
  • prev – a pointer to the previous bucket in the list (may be NULL)

  • next – a pointer to the next bucket in the list (may be NULL)

  • buf – a pointer to the data to be copied and sent

  • buf_len – the length of the data to be copied sent

Returns

a new bucket created from the input parameters

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!

Parameters
  • prev – a pointer to the previous bucket in the list (may be NULL)

  • next – a pointer to the next bucket in the list (may be NULL)

  • filepath – the filepath of the file data to be sent

  • prev – a pointer to the previous bucket in the list (may be NULL)

  • next – a pointer to the next bucket in the list (may be NULL)

  • filepath – the filepath of the file data to be sent

Returns

a new bucket created from the input parameters

Returns

a new bucket created from the input parameters

YMO_BUCKET_FROM_REF

Create a bucket which references static data (or data that is guaranteed to live longer than the bucket itself).

Parameters
  • data – a pointer to the data to be sent

  • len – the length of the data to be sent

Returns

a new bucket created from the input parameters

Definition
#define YMO_BUCKET_FROM_REF(data, len) \
    ymo_bucket_create(NULL, NULL, NULL, 0, data, len)
YMO_BUCKET_FROM_CPY

Create a bucket by copying the given data and allowing yimmo to manage the copy internally.

Parameters
  • data – a pointer to the data to be copied and sent

  • len – the length of the data to be copied and sent

Returns

a new bucket created from the input parameters

Definition
#define YMO_BUCKET_FROM_CPY(data, len) \
    ymo_bucket_create_cpy(NULL, NULL, data, len)
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.

Parameters
  • dst – Destination bucket.

  • src – Source bucket.

Returns

destination with src appended.

size_t ymo_bucket_len_all(ymo_bucket_t *p)

Get the total length of a chain of buckets.

Parameters
  • p – head of bucket chain

Returns

length of all content in the chain of buckets

ymo_bucket_t *ymo_bucket_tail(ymo_bucket_t *p)

Get the last bucket in a chain of buckets.

Parameters
  • p – a bucket in a chain of buckets

Returns

a pointers to the last bucket in the chain

void ymo_bucket_free(ymo_bucket_t *bucket)

Free a bucket and - if managed - it’s buffer.

Parameters
  • bucket – the bucket to free.

void ymo_bucket_free_all(ymo_bucket_t *bucket)

Free all buckets in a chain.

Parameters

Server Functions

type ymo_server_state_t

Enum used to indicate state for ymo_server_t. Used primarily to track termination state (graceful vs hard stop, etc).

Definition
typedef enum ymo_server_state {
    YMO_SERVER_CREATED,
    YMO_SERVER_INITIALIZED,
    YMO_SERVER_STARTED,
    YMO_SERVER_STOP_GRACEFUL,
} ymo_server_state_t;
ymo_server_t *ymo_server_create(ymo_server_config_t *svr_config, ymo_proto_t *proto)

Create a new server object.

Parameters
  • svr_config – configurations struct for the new server

  • proto – pointer to a protocol created using the init function in the appropriate module. (see also yimmo_modules)

Returns

pointer to a new server instance or NULL on failure

ymo_status_t ymo_server_init(ymo_server_t *server)

Bind the server to the configured port.

Parameters
  • server – the server to start

Returns

YMO_OKAY on success; appropriate errno on failure

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

ymo_status_t ymo_server_pre_fork(ymo_server_t *server)

Invoke before forking if forked processes will share a common listen socket.

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 ymo_server_pre_fork() before starting the server!

Parameters
  • server – the server to start

Returns

YMO_OKAY on success; appropriate errno on failure

ymo_server_state_t ymo_server_get_state(ymo_server_t *server)
struct ev_loop *ymo_server_loop(ymo_server_t *server)

Get the ev loop used by a given server.

ymo_status_t ymo_server_stop_graceful(ymo_server_t *server)

Gracefully shutdown a ymo_server.

Parameters
  • server – the server to stop

Returns

YMO_OKAY on success; appropriate errno on failure

void ymo_server_free(ymo_server_t *server)

Free a server object.

Parameters
  • server – the server instance to free

Connection Functions

ymo_server_t *ymo_conn_server(const ymo_conn_t *conn)

Given a connection, return a pointer to the owning server.

Parameters
  • conn – valid ymo_conn_t

Returns

the ymo_server_t instance which owns the given connection

struct ev_loop *ymo_conn_loop(const ymo_conn_t *conn)

Given a connection, return a pointer to the managing ev_loop.

Parameters
  • conn – valid ymo_conn_t

Returns

the struct ev_loop* used to manage the connection I/O

ymo_proto_t *ymo_conn_proto(const ymo_conn_t *conn)

Given a connection, return a pointer to the current protocol

Parameters
  • conn – valid ymo_conn_t

Returns

the current protocol for this connection

void ymo_conn_id(uuid_t dst, const ymo_conn_t *conn)

Given a connection, return its unique identifier.

Parameters
  • dst – the destination uuid_t object into which we copy the id

  • conn – valid ymo_conn_t

char *ymo_conn_id_str(const ymo_conn_t *conn)

Given a connection, return a pointer to the string representation of its unique identifier.

Parameters
  • 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.

ymo_status_t ymo_conn_shutdown(ymo_conn_t *conn)

Start the shutdown sequence for a connection’s underlying socket.

Parameters
  • conn – The connection to close.

Returns

the connection state after invocation.

Protocol Functions

const char *ymo_proto_name(ymo_proto_t *proto)

Given a protocol object, return the protocol name.

Parameters
  • proto – The protocol object we wish to identify

Returns

string representation of the protocol name