From 6432cead1941d5305bc2d7f22821ca8a98f43f78 Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Fri, 24 Nov 2017 18:54:03 +0000 Subject: Add skabus-rpc-daemon, skabus-rpcd and the skabus_rpc library --- src/libskabus/skabus_rpc_update.c | 120 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 src/libskabus/skabus_rpc_update.c (limited to 'src/libskabus/skabus_rpc_update.c') diff --git a/src/libskabus/skabus_rpc_update.c b/src/libskabus/skabus_rpc_update.c new file mode 100644 index 0000000..d727de1 --- /dev/null +++ b/src/libskabus/skabus_rpc_update.c @@ -0,0 +1,120 @@ +/* ISC license. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef int localhandler_func_t (skabus_rpc_t *, unixmessage_t *) ; +typedef localhandler_func_t *localhandler_func_t_ref ; + +static int skabus_rpc_serve (skabus_rpc_t *a, unixmessage_t *m) +{ + skabus_rpc_rinfo_t rinfo ; + uint32_t ifid ; + skabus_rpc_interface_t *p ; + if (m->len < 4 + SKABUS_RPC_RINFO_PACK) return (errno = EPROTO, 0) ; + uint32_unpack_big(m->s, &ifid) ; m->s += 4 ; m->len -= 4 ; + skabus_rpc_rinfo_unpack(m->s, &rinfo) ; + m->s += SKABUS_RPC_RINFO_PACK ; m->len -= SKABUS_RPC_RINFO_PACK ; + p = GENSETDYN_P(skabus_rpc_interface_t, &a->r, ifid) ; + if (!p) return (errno = ESRCH, 0) ; + return (*p->f)(a, &rinfo, m, p->data) ; +} + +static int skabus_rpc_cancelr (skabus_rpc_t *a, unixmessage_t *m) +{ + uint64_t serial ; + uint32_t ifid ; + skabus_rpc_interface_t *p ; + if (m->len != 13 || m->nfds) return (errno = EPROTO, 0) ; + uint32_unpack_big(m->s, &ifid) ; + uint64_unpack_big(m->s+4, &serial) ; + p = GENSETDYN_P(skabus_rpc_interface_t, &a->r, ifid) ; + if (!p) return (errno = ESRCH, 0) ; + return (*p->cancelf)(serial, m->s[12], p->data) ; +} + +static int skabus_rpc_handle_reply (skabus_rpc_t *a, unixmessage_t *m) +{ + skabus_rpc_qinfo_t *p ; + uint64_t serial ; + uint32_t id ; + if (m->len < 9) return (errno = EPROTO, 0) ; + uint64_unpack_big(m->s, &serial) ; + if (!avltree_search(&a->qmap, &serial, &id)) + { + unixmessage_drop(m) ; + return 1 ; + } + p = GENSETDYN_P(skabus_rpc_qinfo_t, &a->q, id) ; + if (!genalloc_readyplus(uint64_t, &a->qlist, 1)) return 0 ; + if (!m->s[8]) + { + if (m->len < 10) return (errno = EPROTO, 0) ; + p->message.s = alloc(m->len - 10) ; + if (!p->message.s) return 0 ; + p->message.fds = (int *)alloc(m->nfds * sizeof(int)) ; + if (!p->message.fds) + { + alloc_free(p->message.s) ; + p->message.s = 0 ; + return 0 ; + } + p->result = m->s[9] ; + p->message.len = m->len - 10 ; + p->message.nfds = m->nfds ; + memcpy(p->message.s, m->s + 10, p->message.len) ; + memcpy(p->message.fds, m->fds, p->message.nfds * sizeof(int)) ; + } + p->status = m->s[8] ; + genalloc_append(uint64_t, &a->qlist, &serial) ; + return 1 ; +} + +static int skabus_rpc_error (skabus_rpc_t *a, unixmessage_t *m) +{ + (void)a ; + (void)m ; + return (errno = EPROTO, 0) ; +} + +static int handler (unixmessage_t const *m, void *x) +{ + skabus_rpc_t *a = x ; + unixmessage_t mm = { .s = m->s + 1, .len = m->len - 1, .fds = m->fds, .nfds = m->nfds } ; + static localhandler_func_t_ref const f[4] = + { + &skabus_rpc_serve, + &skabus_rpc_handle_reply, + &skabus_rpc_cancelr, + &skabus_rpc_error + } ; + if (!m->len) + { + unixmessage_drop(m) ; + return (errno = EPROTO, 0) ; + } + if (!(*f[byte_chr("QRC", 3, m->s[0])])(a, &mm)) + { + unixmessage_drop(m) ; + return 0 ; + } + return 1 ; +} + +int skabus_rpc_update (skabus_rpc_t *a) +{ + genalloc_setlen(uint64_t, &a->qlist, 0) ; + return skaclient_update(&a->connection, &handler, a) ; +} -- cgit v1.3.1