/*
 * QEMU paravirtual RDMA - rdmacm-mux implementation
 *
 * Copyright (C) 2018 Oracle
 * Copyright (C) 2018 Red Hat Inc
 *
 * Authors:
 *     Yuval Shaia <yuval.shaia@oracle.com>
 *     Marcel Apfelbaum <marcel@redhat.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 *
 */

#include "qemu/osdep.h"
#include <sys/poll.h>
#include <sys/ioctl.h>
#include <pthread.h>
#include <syslog.h>

#include <infiniband/verbs.h>
#include <infiniband/umad.h>
#include <infiniband/umad_types.h>
#include <infiniband/umad_sa.h>
#include <infiniband/umad_cm.h>

#include "rdmacm-mux.h"

#define SCALE_US 1000
#define COMMID_TTL 2 /* How many SCALE_US a context of MAD session is saved */
#define SLEEP_SECS 5 /* This is used both in poll() and thread */
#define SERVER_LISTEN_BACKLOG 10
#define MAX_CLIENTS 4096
#define MAD_RMPP_VERSION 0
#define MAD_METHOD_MASK0 0x8

#define IB_USER_MAD_LONGS_PER_METHOD_MASK (128 / (8 * sizeof(long)))

#define CM_REQ_DGID_POS      80
#define CM_SIDR_REQ_DGID_POS 44

/* The below can be override by command line parameter */
#define UNIX_SOCKET_PATH "/var/run/rdmacm-mux"
/* Has format %s-%s-%d" <path>-<rdma-dev--name>-<port> */
#define SOCKET_PATH_MAX (PATH_MAX - NAME_MAX - sizeof(int) - 2)
#define RDMA_PORT_NUM 1

typedef struct RdmaCmServerArgs {
    char unix_socket_path[PATH_MAX];
    char rdma_dev_name[NAME_MAX];
    int rdma_port_num;
} RdmaCMServerArgs;

typedef struct CommId2FdEntry {
    int fd;
    int ttl; /* Initialized to 2, decrement each timeout, entry delete when 0 */
    __be64 gid_ifid;
} CommId2FdEntry;

typedef struct RdmaCmUMadAgent {
    int port_id;
    int agent_id;
    GHashTable *gid2fd; /* Used to find fd of a given gid */
    GHashTable *commid2fd; /* Used to find fd on of a given comm_id */
} RdmaCmUMadAgent;

typedef struct RdmaCmServer {
    bool run;
    RdmaCMServerArgs args;
    struct pollfd fds[MAX_CLIENTS];
    int nfds;
    RdmaCmUMadAgent umad_agent;
    pthread_t umad_recv_thread;
    pthread_rwlock_t lock;
} RdmaCMServer;

static RdmaCMServer server = {0};

static void usage(const char *progname)
{
    printf("Usage: %s [OPTION]...\n"
           "Start a RDMA-CM multiplexer\n"
           "\n"
           "\t-h                    Show this help\n"
           "\t-d rdma-device-name   Name of RDMA device to register with\n"
           "\t-s unix-socket-path   Path to unix socket to listen on (default %s)\n"
           "\t-p rdma-device-port   Port number of RDMA device to register with (default %d)\n",
           progname, UNIX_SOCKET_PATH, RDMA_PORT_NUM);
}

static void help(const char *progname)
{
    fprintf(stderr, "Try '%s -h' for more information.\n", progname);
}

static void parse_args(int argc, char *argv[])
{
    int c;
    char unix_socket_path[SOCKET_PATH_MAX];

    strcpy(server.args.rdma_dev_name, "");
    strcpy(unix_socket_path, UNIX_SOCKET_PATH);
    server.args.rdma_port_num = RDMA_PORT_NUM;

    while ((c = getopt(argc, argv, "hs:d:p:")) != -1) {
        switch (c) {
        case 'h':
            usage(argv[0]);
            exit(0);

        case 'd':
            strncpy(server.args.rdma_dev_name, optarg, NAME_MAX - 1);
            break;

        case 's':
            /* This is temporary, final name will build below */
            strncpy(unix_socket_path, optarg, SOCKET_PATH_MAX - 1);
            break;

        case 'p':
            server.args.rdma_port_num = atoi(optarg);
            break;

        default:
            help(argv[0]);
            exit(1);
        }
    }

    if (!strcmp(server.args.rdma_dev_name, "")) {
        fprintf(stderr, "Missing RDMA device name\n");
        help(argv[0]);
        exit(1);
    }

    /* Build unique unix-socket file name */
    snprintf(server.args.unix_socket_path, PATH_MAX, "%s-%s-%d",
             unix_socket_path, server.args.rdma_dev_name,
             server.args.rdma_port_num);

    syslog(LOG_INFO, "unix_socket_path=%s", server.args.unix_socket_path);
    syslog(LOG_INFO, "rdma-device-name=%s", server.args.rdma_dev_name);
    syslog(LOG_INFO, "rdma-device-port=%d", server.args.rdma_port_num);
}

static void hash_tbl_alloc(void)
{

    server.umad_agent.gid2fd = g_hash_table_new_full(g_int64_hash,
                                                     g_int64_equal,
                                                     g_free, g_free);
    server.umad_agent.commid2fd = g_hash_table_new_full(g_int_hash,
                                                        g_int_equal,
                                                        g_free, g_free);
}

static void hash_tbl_free(void)
{
    if (server.umad_agent.commid2fd) {
        g_hash_table_destroy(server.umad_agent.commid2fd);
    }
    if (server.umad_agent.gid2fd) {
        g_hash_table_destroy(server.umad_agent.gid2fd);
    }
}


static int _hash_tbl_search_fd_by_ifid(__be64 *gid_ifid)
{
    int *fd;

    fd = g_hash_table_lookup(server.umad_agent.gid2fd, gid_ifid);
    if (!fd) {
        /* Let's try IPv4 */
        *gid_ifid |= 0x00000000ffff0000;
        fd = g_hash_table_lookup(server.umad_agent.gid2fd, gid_ifid);
    }

    return fd ? *fd : 0;
}

static int hash_tbl_search_fd_by_ifid(int *fd, __be64 *gid_ifid)
{
    pthread_rwlock_rdlock(&server.lock);
    *fd = _hash_tbl_search_fd_by_ifid(gid_ifid);
    pthread_rwlock_unlock(&server.lock);

    if (!*fd) {
        syslog(LOG_WARNING, "Can't find matching for ifid 0x%llx\n", *gid_ifid);
        return -ENOENT;
    }

    return 0;
}

static int hash_tbl_search_fd_by_comm_id(uint32_t comm_id, int *fd,
                                         __be64 *gid_idid)
{
    CommId2FdEntry *fde;

    pthread_rwlock_rdlock(&server.lock);
    fde = g_hash_table_lookup(server.umad_agent.commid2fd, &comm_id);
    pthread_rwlock_unlock(&server.lock);

    if (!fde) {
        syslog(LOG_WARNING, "Can't find matching for comm_id 0x%x\n", comm_id);
        return -ENOENT;
    }

    *fd = fde->fd;
    *gid_idid = fde->gid_ifid;

    return 0;
}

static RdmaCmMuxErrCode add_fd_ifid_pair(int fd, __be64 gid_ifid)
{
    int fd1;

    pthread_rwlock_wrlock(&server.lock);

    fd1 = _hash_tbl_search_fd_by_ifid(&gid_ifid);
    if (fd1) { /* record already exist - an error */
        pthread_rwlock_unlock(&server.lock);
        return fd == fd1 ? RDMACM_MUX_ERR_CODE_EEXIST :
                           RDMACM_MUX_ERR_CODE_EACCES;
    }

    g_hash_table_insert(server.umad_agent.gid2fd, g_memdup(&gid_ifid,
                        sizeof(gid_ifid)), g_memdup(&fd, sizeof(fd)));

    pthread_rwlock_unlock(&server.lock);

    syslog(LOG_INFO, "0x%lx registered on socket %d",
           be64toh((uint64_t)gid_ifid), fd);

    return RDMACM_MUX_ERR_CODE_OK;
}

static RdmaCmMuxErrCode delete_fd_ifid_pair(int fd, __be64 gid_ifid)
{
    int fd1;

    pthread_rwlock_wrlock(&server.lock);

    fd1 = _hash_tbl_search_fd_by_ifid(&gid_ifid);
    if (!fd1) { /* record not exist - an error */
        pthread_rwlock_unlock(&server.lock);
        return RDMACM_MUX_ERR_CODE_ENOTFOUND;
    }

    g_hash_table_remove(server.umad_agent.gid2fd, g_memdup(&gid_ifid,
                        sizeof(gid_ifid)));
    pthread_rwlock_unlock(&server.lock);

    syslog(LOG_INFO, "0x%lx unregistered on socket %d",
           be64toh((uint64_t)gid_ifid), fd);

    return RDMACM_MUX_ERR_CODE_OK;
}

static void hash_tbl_save_fd_comm_id_pair(int fd, uint32_t comm_id,
                                          uint64_t gid_ifid)
{
    CommId2FdEntry fde = {fd, COMMID_TTL, gid_ifid};

    pthread_rwlock_wrlock(&server.lock);
    g_hash_table_insert(server.umad_agent.commid2fd,
                        g_memdup(&comm_id, sizeof(comm_id)),
                        g_memdup(&fde, sizeof(fde)));
    pthread_rwlock_unlock(&server.lock);
}

static gboolean remove_old_comm_ids(gpointer key, gpointer value,
                                    gpointer user_data)
{
    CommId2FdEntry *fde = (CommId2FdEntry *)value;

    return !fde->ttl--;
}

static gboolean remove_entry_from_gid2fd(gpointer key, gpointer value,
                                         gpointer user_data)
{
    if (*(int *)value == *(int *)user_data) {
        syslog(LOG_INFO, "0x%lx unregistered on socket %d",
               be64toh(*(uint64_t *)key), *(int *)value);
        return true;
    }

    return false;
}

static void hash_tbl_remove_fd_ifid_pair(int fd)
{
    pthread_rwlock_wrlock(&server.lock);
    g_hash_table_foreach_remove(server.umad_agent.gid2fd,
                                remove_entry_from_gid2fd, (gpointer)&fd);
    pthread_rwlock_unlock(&server.lock);
}

static int get_fd(const char *mad, int umad_len, int *fd, __be64 *gid_ifid)
{
    struct umad_hdr *hdr = (struct umad_hdr *)mad;
    char *data = (char *)hdr + sizeof(*hdr);
    int32_t comm_id = 0;
    uint16_t attr_id = be16toh(hdr->attr_id);
    int rc = 0;

    if (umad_len <= sizeof(*hdr)) {
        rc = -EINVAL;
        syslog(LOG_DEBUG, "Ignoring MAD packets with header only\n");
        goto out;
    }

    switch (attr_id) {
    case UMAD_CM_ATTR_REQ:
        if (unlikely(umad_len < sizeof(*hdr) + CM_REQ_DGID_POS +
            sizeof(*gid_ifid))) {
            rc = -EINVAL;
            syslog(LOG_WARNING,
                   "Invalid MAD packet size (%d) for attr_id 0x%x\n", umad_len,
                    attr_id);
            goto out;
        }
        memcpy(gid_ifid, data + CM_REQ_DGID_POS, sizeof(*gid_ifid));
        rc = hash_tbl_search_fd_by_ifid(fd, gid_ifid);
        break;

    case UMAD_CM_ATTR_SIDR_REQ:
        if (unlikely(umad_len < sizeof(*hdr) + CM_SIDR_REQ_DGID_POS +
            sizeof(*gid_ifid))) {
            rc = -EINVAL;
            syslog(LOG_WARNING,
                   "Invalid MAD packet size (%d) for attr_id 0x%x\n", umad_len,
                    attr_id);
            goto out;
        }
        memcpy(gid_ifid, data + CM_SIDR_REQ_DGID_POS, sizeof(*gid_ifid));
        rc = hash_tbl_search_fd_by_ifid(fd, gid_ifid);
        break;

    case UMAD_CM_ATTR_REP:
        /* Fall through */
    case UMAD_CM_ATTR_REJ:
        /* Fall through */
    case UMAD_CM_ATTR_DREQ:
        /* Fall through */
    case UMAD_CM_ATTR_DREP:
        /* Fall through */
    case UMAD_CM_ATTR_RTU:
        data += sizeof(comm_id);
        /* Fall through */
    case UMAD_CM_ATTR_SIDR_REP:
        if (unlikely(umad_len < sizeof(*hdr) + sizeof(comm_id))) {
            rc = -EINVAL;
            syslog(LOG_WARNING,
                   "Invalid MAD packet size (%d) for attr_id 0x%x\n", umad_len,
                   attr_id);
            goto out;
        }
        memcpy(&comm_id, data, sizeof(comm_id));
        if (comm_id) {
            rc = hash_tbl_search_fd_by_comm_id(comm_id, fd, gid_ifid);
        }
        break;

    default:
        rc = -EINVAL;
        syslog(LOG_WARNING, "Unsupported attr_id 0x%x\n", attr_id);
    }

    syslog(LOG_DEBUG, "mad_to_vm: %d 0x%x 0x%x\n", *fd, attr_id, comm_id);

out:
    return rc;
}

static void *umad_recv_thread_func(void *args)
{
    int rc;
    RdmaCmMuxMsg msg = {};
    int fd = -2;

    msg.hdr.msg_type = RDMACM_MUX_MSG_TYPE_REQ;
    msg.hdr.op_code = RDMACM_MUX_OP_CODE_MAD;

    while (server.run) {
        do {
            msg.umad_len = sizeof(msg.umad.mad);
            rc = umad_recv(server.umad_agent.port_id, &msg.umad, &msg.umad_len,
                           SLEEP_SECS * SCALE_US);
            if ((rc == -EIO) || (rc == -EINVAL)) {
                syslog(LOG_CRIT, "Fatal error while trying to read MAD");
            }

            if (rc == -ETIMEDOUT) {
                g_hash_table_foreach_remove(server.umad_agent.commid2fd,
                                            remove_old_comm_ids, NULL);
            }
        } while (rc && server.run);

        if (server.run) {
            rc = get_fd(msg.umad.mad, msg.umad_len, &fd,
                        &msg.hdr.sgid.global.interface_id);
            if (rc) {
                continue;
            }

            send(fd, &msg, sizeof(msg), 0);
        }
    }

    return NULL;
}

static int read_and_process(int fd)
{
    int rc;
    RdmaCmMuxMsg msg = {};
    struct umad_hdr *hdr;
    uint32_t *comm_id = 0;
    uint16_t attr_id;

    rc = recv(fd, &msg, sizeof(msg), 0);
    syslog(LOG_DEBUG, "Socket %d, recv %d\n", fd, rc);

    if (rc < 0 && errno != EWOULDBLOCK) {
        syslog(LOG_ERR, "Fail to read from socket %d\n", fd);
        return -EIO;
    }

    if (!rc) {
        syslog(LOG_ERR, "Fail to read from socket %d\n", fd);
        return -EPIPE;
    }

    if (msg.hdr.msg_type != RDMACM_MUX_MSG_TYPE_REQ) {
        syslog(LOG_WARNING, "Got non-request message (%d) from socket %d\n",
               msg.hdr.msg_type, fd);
        return -EPERM;
    }

    switch (msg.hdr.op_code) {
    case RDMACM_MUX_OP_CODE_REG:
        rc = add_fd_ifid_pair(fd, msg.hdr.sgid.global.interface_id);
        break;

    case RDMACM_MUX_OP_CODE_UNREG:
        rc = delete_fd_ifid_pair(fd, msg.hdr.sgid.global.interface_id);
        break;

    case RDMACM_MUX_OP_CODE_MAD:
        /* If this is REQ or REP then store the pair comm_id,fd to be later
         * used for other messages where gid is unknown */
        hdr = (struct umad_hdr *)msg.umad.mad;
        attr_id = be16toh(hdr->attr_id);
        if ((attr_id == UMAD_CM_ATTR_REQ) || (attr_id == UMAD_CM_ATTR_DREQ) ||
            (attr_id == UMAD_CM_ATTR_SIDR_REQ) ||
            (attr_id == UMAD_CM_ATTR_REP) || (attr_id == UMAD_CM_ATTR_DREP)) {
            comm_id = (uint32_t *)(msg.umad.mad + sizeof(*hdr));
            hash_tbl_save_fd_comm_id_pair(fd, *comm_id,
                                          msg.hdr.sgid.global.interface_id);
        }

        syslog(LOG_DEBUG, "vm_to_mad: %d 0x%x 0x%x\n", fd, attr_id,
               comm_id ? *comm_id : 0);
        rc = umad_send(server.umad_agent.port_id, server.umad_agent.agent_id,
                       &msg.umad, msg.umad_len, 1, 0);
        if (rc) {
            syslog(LOG_ERR,
                  "Fail to send MAD message (0x%x) from socket %d, err=%d",
                  attr_id, fd, rc);
        }
        break;

    default:
        syslog(LOG_ERR, "Got invalid op_code (%d) from socket %d",
               msg.hdr.msg_type, fd);
        rc = RDMACM_MUX_ERR_CODE_EINVAL;
    }

    msg.hdr.msg_type = RDMACM_MUX_MSG_TYPE_RESP;
    msg.hdr.err_code = rc;
    rc = send(fd, &msg, sizeof(msg), 0);

    return rc == sizeof(msg) ? 0 : -EPIPE;
}

static int accept_all(void)
{
    int fd, rc = 0;

    pthread_rwlock_wrlock(&server.lock);

    do {
        if ((server.nfds + 1) > MAX_CLIENTS) {
            syslog(LOG_WARNING, "Too many clients (%d)", server.nfds);
            rc = -EIO;
            goto out;
        }

        fd = accept(server.fds[0].fd, NULL, NULL);
        if (fd < 0) {
            if (errno != EWOULDBLOCK) {
                syslog(LOG_WARNING, "accept() failed");
                rc = -EIO;
                goto out;
            }
            break;
        }

        syslog(LOG_INFO, "Client connected on socket %d\n", fd);
        server.fds[server.nfds].fd = fd;
        server.fds[server.nfds].events = POLLIN;
        server.nfds++;
    } while (fd != -1);

out:
    pthread_rwlock_unlock(&server.lock);
    return rc;
}

static void compress_fds(void)
{
    int i, j;
    int closed = 0;

    pthread_rwlock_wrlock(&server.lock);

    for (i = 1; i < server.nfds; i++) {
        if (!server.fds[i].fd) {
            closed++;
            for (j = i; j < server.nfds - 1; j++) {
                server.fds[j] = server.fds[j + 1];
            }
        }
    }

    server.nfds -= closed;

    pthread_rwlock_unlock(&server.lock);
}

static void close_fd(int idx)
{
    close(server.fds[idx].fd);
    syslog(LOG_INFO, "Socket %d closed\n", server.fds[idx].fd);
    hash_tbl_remove_fd_ifid_pair(server.fds[idx].fd);
    server.fds[idx].fd = 0;
}

static void run(void)
{
    int rc, nfds, i;
    bool compress = false;

    syslog(LOG_INFO, "Service started");

    while (server.run) {
        rc = poll(server.fds, server.nfds, SLEEP_SECS * SCALE_US);
        if (rc < 0) {
            if (errno != EINTR) {
                syslog(LOG_WARNING, "poll() failed");
            }
            continue;
        }

        if (rc == 0) {
            continue;
        }

        nfds = server.nfds;
        for (i = 0; i < nfds; i++) {
            syslog(LOG_DEBUG, "pollfd[%d]: revents 0x%x, events 0x%x\n", i,
                   server.fds[i].revents, server.fds[i].events);
            if (server.fds[i].revents == 0) {
                continue;
            }

            if (server.fds[i].revents != POLLIN) {
                if (i == 0) {
                    syslog(LOG_NOTICE, "Unexpected poll() event (0x%x)\n",
                           server.fds[i].revents);
                } else {
                    close_fd(i);
                    compress = true;
                }
                continue;
            }

            if (i == 0) {
                rc = accept_all();
                if (rc) {
                    continue;
                }
            } else {
                rc = read_and_process(server.fds[i].fd);
                if (rc) {
                    close_fd(i);
                    compress = true;
                }
            }
        }

        if (compress) {
            compress = false;
            compress_fds();
        }
    }
}

static void fini_listener(void)
{
    int i;

    if (server.fds[0].fd <= 0) {
        return;
    }

    for (i = server.nfds - 1; i >= 0; i--) {
        if (server.fds[i].fd) {
            close(server.fds[i].fd);
        }
    }

    unlink(server.args.unix_socket_path);
}

static void fini_umad(void)
{
    if (server.umad_agent.agent_id) {
        umad_unregister(server.umad_agent.port_id, server.umad_agent.agent_id);
    }

    if (server.umad_agent.port_id) {
        umad_close_port(server.umad_agent.port_id);
    }

    hash_tbl_free();
}

static void fini(void)
{
    if (server.umad_recv_thread) {
        pthread_join(server.umad_recv_thread, NULL);
        server.umad_recv_thread = 0;
    }
    fini_umad();
    fini_listener();
    pthread_rwlock_destroy(&server.lock);

    syslog(LOG_INFO, "Service going down");
}

static int init_listener(void)
{
    struct sockaddr_un sun;
    int rc, on = 1;

    server.fds[0].fd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (server.fds[0].fd < 0) {
        syslog(LOG_ALERT, "socket() failed");
        return -EIO;
    }

    rc = setsockopt(server.fds[0].fd, SOL_SOCKET, SO_REUSEADDR, (char *)&on,
                    sizeof(on));
    if (rc < 0) {
        syslog(LOG_ALERT, "setsockopt() failed");
        rc = -EIO;
        goto err;
    }

    rc = ioctl(server.fds[0].fd, FIONBIO, (char *)&on);
    if (rc < 0) {
        syslog(LOG_ALERT, "ioctl() failed");
        rc = -EIO;
        goto err;
    }

    if (strlen(server.args.unix_socket_path) >= sizeof(sun.sun_path)) {
        syslog(LOG_ALERT,
               "Invalid unix_socket_path, size must be less than %ld\n",
               sizeof(sun.sun_path));
        rc = -EINVAL;
        goto err;
    }

    sun.sun_family = AF_UNIX;
    rc = snprintf(sun.sun_path, sizeof(sun.sun_path), "%s",
                  server.args.unix_socket_path);
    if (rc < 0 || rc >= sizeof(sun.sun_path)) {
        syslog(LOG_ALERT, "Could not copy unix socket path\n");
        rc = -EINVAL;
        goto err;
    }

    rc = bind(server.fds[0].fd, (struct sockaddr *)&sun, sizeof(sun));
    if (rc < 0) {
        syslog(LOG_ALERT, "bind() failed");
        rc = -EIO;
        goto err;
    }

    rc = listen(server.fds[0].fd, SERVER_LISTEN_BACKLOG);
    if (rc < 0) {
        syslog(LOG_ALERT, "listen() failed");
        rc = -EIO;
        goto err;
    }

    server.fds[0].events = POLLIN;
    server.nfds = 1;
    server.run = true;

    return 0;

err:
    close(server.fds[0].fd);
    return rc;
}

static int init_umad(void)
{
    long method_mask[IB_USER_MAD_LONGS_PER_METHOD_MASK];

    server.umad_agent.port_id = umad_open_port(server.args.rdma_dev_name,
                                               server.args.rdma_port_num);

    if (server.umad_agent.port_id < 0) {
        syslog(LOG_WARNING, "umad_open_port() failed");
        return -EIO;
    }

    memset(&method_mask, 0, sizeof(method_mask));
    method_mask[0] = MAD_METHOD_MASK0;
    server.umad_agent.agent_id = umad_register(server.umad_agent.port_id,
                                               UMAD_CLASS_CM,
                                               UMAD_SA_CLASS_VERSION,
                                               MAD_RMPP_VERSION, method_mask);
    if (server.umad_agent.agent_id < 0) {
        syslog(LOG_WARNING, "umad_register() failed");
        return -EIO;
    }

    hash_tbl_alloc();

    return 0;
}

static void signal_handler(int sig, siginfo_t *siginfo, void *context)
{
    static bool warned;

    /* Prevent stop if clients are connected */
    if (server.nfds != 1) {
        if (!warned) {
            syslog(LOG_WARNING,
                   "Can't stop while active client exist, resend SIGINT to overid");
            warned = true;
            return;
        }
    }

    if (sig == SIGINT) {
        server.run = false;
        fini();
    }

    exit(0);
}

static int init(void)
{
    int rc;
    struct sigaction sig = {};

    rc = init_listener();
    if (rc) {
        return rc;
    }

    rc = init_umad();
    if (rc) {
        return rc;
    }

    pthread_rwlock_init(&server.lock, 0);

    rc = pthread_create(&server.umad_recv_thread, NULL, umad_recv_thread_func,
                        NULL);
    if (rc) {
        syslog(LOG_ERR, "Fail to create UMAD receiver thread (%d)\n", rc);
        return rc;
    }

    sig.sa_sigaction = &signal_handler;
    sig.sa_flags = SA_SIGINFO;
    rc = sigaction(SIGINT, &sig, NULL);
    if (rc < 0) {
        syslog(LOG_ERR, "Fail to install SIGINT handler (%d)\n", errno);
        return rc;
    }

    return 0;
}

int main(int argc, char *argv[])
{
    int rc;

    memset(&server, 0, sizeof(server));

    parse_args(argc, argv);

    rc = init();
    if (rc) {
        syslog(LOG_ERR, "Fail to initialize server (%d)\n", rc);
        rc = -EAGAIN;
        goto out;
    }

    run();

out:
    fini();

    return rc;
}
