Exemple #1
0
static void
do_timeout_notification(struct rtpp_notify_wi *wi, int retries,
  struct rtpp_log *log)
{
    int result;

    if (wi->rttp->connected == 0) {
        reconnect_timeout_handler(log, wi->rttp);

        /* If connect fails, no notification will be sent */
        if (wi->rttp->connected == 0) {
            RTPP_LOG(log, RTPP_LOG_ERR, "unable to send timeout notification");
            return;
        }
    }

    do {
        result = send(wi->rttp->fd, wi->notify_buf, wi->len - 1, 0);
    } while (result == -1 && errno == EINTR);

    if (result < 0) {
        wi->rttp->connected = 0;
        RTPP_ELOG(log, RTPP_LOG_ERR, "failed to send timeout notification");
        if (retries > 0)
            do_timeout_notification(wi, retries - 1, log);
    }
}
Exemple #2
0
int
set_rlimits(struct cfg *cf)
{
    struct rlimit rlp;

    if (getrlimit(RLIMIT_CORE, &rlp) < 0) {
        RTPP_ELOG(cf->stable->glog, RTPP_LOG_ERR, "getrlimit(RLIMIT_CORE)");
        return (-1);
    }
    rlp.rlim_cur = RLIM_INFINITY;
    rlp.rlim_max = RLIM_INFINITY;
    if (setrlimit(RLIMIT_CORE, &rlp) < 0) {
        RTPP_ELOG(cf->stable->glog, RTPP_LOG_ERR, "setrlimit(RLIMIT_CORE)");
        return (-1);
    }
    return (0);
}
Exemple #3
0
int
drop_privileges(const struct rtpp_cfg_stable *cfsp)
{

    if (cfsp->runcreds->gname != NULL) {
	if (setgid(cfsp->runcreds->gid) != 0) {
	    RTPP_ELOG(cfsp->glog, RTPP_LOG_ERR, "can't set current group ID: %d", cfsp->runcreds->gid);
	    return -1;
	}
    }
    if (cfsp->runcreds->uname == NULL)
	return 0;
    if (setuid(cfsp->runcreds->uid) != 0) {
	RTPP_ELOG(cfsp->glog, RTPP_LOG_ERR, "can't set current user ID: %d", cfsp->runcreds->uid);
	return -1;
    }
    return 0;
}
Exemple #4
0
static void
reconnect_timeout_handler(struct rtpp_log *log, struct rtpp_tnotify_target *rttp)
{

    assert (rttp->connected == 0);

    if (rttp->fd == -1) {
        RTPP_LOG(log, RTPP_LOG_DBUG, "connecting timeout socket");
    } else {
        RTPP_LOG(log, RTPP_LOG_DBUG, "reconnecting timeout socket");
        close(rttp->fd);
    }
    rttp->fd = socket(rttp->socket_type, SOCK_STREAM, 0);
    if (rttp->fd == -1) {
        RTPP_ELOG(log, RTPP_LOG_ERR, "can't create timeout socket");
        return;
    }
    if (rttp->local != NULL) {
        if (bind(rttp->fd, rttp->local, SA_LEN(rttp->local)) < 0) {
            RTPP_ELOG(log, RTPP_LOG_ERR, "can't bind timeout socket");
            goto e0;
        }
    }
    if (connect(rttp->fd, (struct sockaddr *)&(rttp->remote), rttp->remote_len) == -1) {
        RTPP_ELOG(log, RTPP_LOG_ERR, "can't connect to timeout socket");
        goto e0;
    } else {
        rttp->connected = 1;
    }
    return;

e0:
    close(rttp->fd);
    rttp->fd = -1;
    return;
}
Exemple #5
0
static int
controlfd_init_tcp(struct cfg *cf, struct rtpp_ctrl_sock *csp)
{
    struct sockaddr *ifsin;
    char *cp;
    int controlfd, so_rcvbuf, i;

    cp = strrchr(csp->cmd_sock, ':');
    if (cp != NULL) {
        *cp = '\0';
        cp++;
    }
    if (cp == NULL || *cp == '\0')
        cp = CPORT;
    csp->port_ctl = atoi(cp);
    i = (csp->type == RTPC_TCP6) ? AF_INET6 : AF_INET;
    ifsin = sstosa(&csp->bindaddr);
    if (setbindhost(ifsin, i, csp->cmd_sock, cp) != 0) {
        warnx("setbindhost failed");
        return (-1);
    }
    controlfd = socket(i, SOCK_STREAM, 0);
    if (controlfd == -1) {
        warn("can't create socket");
        return (-1);
    }
    so_rcvbuf = 16 * 1024;
    if (setsockopt(controlfd, SOL_SOCKET, SO_RCVBUF, &so_rcvbuf, sizeof(so_rcvbuf)) == -1)
        RTPP_ELOG(cf->stable->glog, RTPP_LOG_ERR, "unable to set 16K receive buffer size on controlfd");
    if (bind(controlfd, ifsin, SA_LEN(ifsin)) < 0) {
        warn("can't bind to a socket");
        goto e0;
    }
    if (listen(controlfd, 32) != 0) {
        warn("can't listen on a socket: %s", csp->cmd_sock);
        goto e0;
    }

    return (controlfd);
e0:
    close(controlfd);
    return (-1);
}
Exemple #6
0
int
rtpp_cfile_process(struct rtpp_cfg_stable *csp)
{
    struct ucl_parser *parser;
    ucl_object_t *conf_root;
    ucl_object_iter_t it_conf;
    const ucl_object_t *obj_file;
    const char *cf_key;
    int fd, ecode;

    ecode = 0;

    fd = open(csp->cfile, O_RDONLY);
    if (fd < 0) {
        RTPP_ELOG(csp->glog, RTPP_LOG_ERR, "open failed: %s", csp->cfile);
        ecode = -1;
        goto e0;
    }

    parser = ucl_parser_new(UCL_PARSER_NO_FILEVARS);
    if (parser == NULL) {
        RTPP_LOG(csp->glog, RTPP_LOG_ERR, "ucl_parser_new() failed");
        ecode = -1;
        goto e1;
    }

    ucl_parser_add_fd(parser, fd);
    conf_root = ucl_parser_get_object(parser);
    if (conf_root == NULL) {
        RTPP_LOG(csp->glog, RTPP_LOG_ERR, "ucl_parser_get_object() failed");
        ecode = -1;
        goto e2;
    }
    if (ucl_parser_get_error(parser)) {
        RTPP_LOG(csp->glog, RTPP_LOG_ERR, "Parse Error occured: %s", ucl_parser_get_error(parser));
        ecode = -1;
        goto e3;
    }

    it_conf = ucl_object_iterate_new(conf_root);
    if (it_conf == NULL) {
        RTPP_LOG(csp->glog, RTPP_LOG_ERR, "ucl_object_iterate_new() failed");
        ecode = -1;
        goto e3;
    }
    while ((obj_file = ucl_object_iterate_safe(it_conf, true)) != NULL) {
        cf_key = ucl_object_key(obj_file);
        RTPP_LOG(csp->glog, RTPP_LOG_DBUG, "Entry: %s", cf_key);
        if (strcasecmp(cf_key, "modules") == 0) {
            if (parse_modules(csp, obj_file) < 0) {
                RTPP_LOG(csp->glog, RTPP_LOG_ERR, "parse_modules() failed");
                ecode = -1;
                goto e4;
            }
        }
    }
    if (ucl_object_iter_chk_excpn(it_conf)) {
        ecode = -1;
    }
e4:
    ucl_object_iterate_free(it_conf);
e3:
    ucl_object_unref(conf_root);
e2:
    ucl_parser_free(parser);
e1:
    close(fd);
e0:
    return (ecode);
}
Exemple #7
0
static int
parse_modules(struct rtpp_cfg_stable *csp, const ucl_object_t *wop)
{
    ucl_object_iter_t it_conf;
    const ucl_object_t *obj_file;
    const char *cf_key;
    const ucl_object_t *obj_key;
    int ecode, success;
    void *confp;
    const conf_helper_map *fent, *map;
    struct rtpp_module_conf *mcp;
    char mpath[PATH_MAX + 1];
    const char *cp, *mp;
    struct rtpp_module_if *mif;

    it_conf = ucl_object_iterate_new(wop);
    if (it_conf == NULL)
        return (-1);
    ecode = 0;
    while ((obj_file = ucl_object_iterate_safe(it_conf, true)) != NULL) {
        cf_key = ucl_object_key(obj_file);
        RTPP_LOG(csp->glog, RTPP_LOG_DBUG, "\tmodule: %s", cf_key);
        obj_key = ucl_object_find_key(obj_file, "load");
        if (obj_key == NULL) {
            cp = rtpp_module_dsop_canonic(cf_key, mpath, sizeof(mpath));
            if (cp == NULL) {
                RTPP_LOG(csp->glog, RTPP_LOG_ERR, "Error: Unable to find load parameter in module: %s", cf_key);
                ecode = -1;
                goto e0;
            }
        } else {
            if (obj_key->type != UCL_STRING) {
                RTPP_LOG(csp->glog, RTPP_LOG_ERR, "Error: \"load\" parameter in %s has a wrong type, string is expected", cf_key);
                ecode = -1;
                goto e0;
            }
            mp = ucl_object_tostring(obj_key);
            cp = realpath(mp, mpath);
            if (cp == NULL) {
                RTPP_ELOG(csp->glog, RTPP_LOG_ERR, "realpath() failed: %s", mp);
                ecode = -1;
                goto e0;
            }
        }
        mif = rtpp_module_if_ctor(cp);
        if (mif == NULL) {
            RTPP_LOG(csp->glog, RTPP_LOG_ERR, "dymanic module constructor has failed: %s", cp);
            ecode = -1;
            goto e0;
        }
        if (CALL_METHOD(mif, load, csp, csp->glog) != 0) {
            RTPP_LOG(csp->glog, RTPP_LOG_ERR, "%p->load() method has failed: %s", mif, cp);
            goto e1;
        }
        if (CALL_METHOD(mif, get_mconf, &mcp) < 0) {
            RTPP_LOG(csp->glog, RTPP_LOG_ERR, "%p->get_mconf() method has failed: %s", mif, cp);
            goto e1;
        }
        fent = NULL;
        if (mcp != NULL) {
            map = mcp->conf_map;
            confp = mcp->conf_data;
        } else {
            map = default_module_map;
            confp = NULL;
        }
        success = conf_helper_mapper(csp->glog, obj_file, map, confp, &fent);
        if (!success) {
            RTPP_LOG(csp->glog, RTPP_LOG_ERR, "Config parsing issue in section %s",
              cf_key);
            if (fent != NULL && fent->conf_key != NULL) {
                RTPP_LOG(csp->glog, RTPP_LOG_ERR, "\tparameter %s", fent->conf_key);
            }
            goto e1;
        }
        if (CALL_METHOD(mif, config) < 0) {
            RTPP_LOG(csp->glog, RTPP_LOG_ERR, "%p->config() method has failed: %s", mif, cp);
            goto e1;
        }
        rtpp_list_append(csp->modules_cf, mif);
        continue;
e1:
        ecode = -1;
        CALL_SMETHOD(mif->rcnt, decref);
        goto e0;
    }
e0:
    if (ucl_object_iter_chk_excpn(it_conf)) {
        RTPP_LOG(csp->glog, RTPP_LOG_ERR, "UCL has failed with an internal error");
        ecode = -1;
    }
    ucl_object_iterate_free(it_conf);
    return (ecode);
}
Exemple #8
0
static void
rtpp_anetio_sthread(struct sthread_args *args)
{
    int n, nsend, i, send_errno, nretry;
    struct rtpp_wi *wi, *wis[100];
#if RTPP_DEBUG_timers
    double tp[3], runtime, sleeptime;
    long run_n;

    runtime = sleeptime = 0.0;
    run_n = 0;
    tp[0] = getdtime();
#endif
    for (;;) {
        nsend = rtpp_queue_get_items(args->out_q, wis, 100, 0);
#if RTPP_DEBUG_timers
        tp[1] = getdtime();
#endif

        for (i = 0; i < nsend; i++) {
	    wi = wis[i];
            if (wi->wi_type == RTPP_WI_TYPE_SGNL) {
                rtpp_wi_free(wi);
                goto out;
            }
            nretry = 0;
            do {
                n = sendto(wi->sock, wi->msg, wi->msg_len, wi->flags,
                  wi->sendto, wi->tolen);
                send_errno = (n < 0) ? errno : 0;
#if RTPP_DEBUG_netio >= 1
                if (wi->debug != 0) {
                    char daddr[MAX_AP_STRBUF];

                    addrport2char_r(wi->sendto, daddr, sizeof(daddr), ':');
                    if (n < 0) {
                        RTPP_ELOG(wi->log, RTPP_LOG_DBUG,
                          "sendto(%d, %p, %lld, %d, %p (%s), %d) = %d",
                          wi->sock, wi->msg, (long long)wi->msg_len, wi->flags,
                          wi->sendto, daddr, wi->tolen, n);
                    } else if (n < wi->msg_len) {
                        RTPP_LOG(wi->log, RTPP_LOG_DBUG,
                          "sendto(%d, %p, %lld, %d, %p (%s), %d) = %d: short write",
                          wi->sock, wi->msg, (long long)wi->msg_len, wi->flags,
                          wi->sendto, daddr, wi->tolen, n);
#if RTPP_DEBUG_netio >= 2
                    } else {
                        RTPP_LOG(wi->log, RTPP_LOG_DBUG,
                          "sendto(%d, %p, %d, %d, %p (%s), %d) = %d",
                          wi->sock, wi->msg, wi->msg_len, wi->flags, wi->sendto, daddr,
                          wi->tolen, n);
#endif
                    }
                }
#endif
                if (n >= 0) {
                    wi->nsend--;
                } else {
                    /* "EPERM" is Linux thing, yield and retry */
                    if ((send_errno == EPERM || send_errno == ENOBUFS)
                      && nretry < RTPP_ANETIO_MAX_RETRY) {
                        sched_yield();
                        nretry++;
                    } else {
                        break;
                    }
                }
            } while (wi->nsend > 0);
            rtpp_wi_free(wi);
        }
#if RTPP_DEBUG_timers
        sleeptime += tp[1] - tp[0];
        tp[0] = getdtime();
        runtime += tp[0] - tp[1];
        if ((run_n % 10000) == 0) {
            RTPP_LOG(args->glog, RTPP_LOG_DBUG, "rtpp_anetio_sthread(%p): run %ld aload = %f filtered = %f", \
              args, run_n, runtime / (runtime + sleeptime), args->average_load.lastval);
        }
        if (runtime + sleeptime > 1.0) {
            recfilter_apply(&args->average_load, runtime / (runtime + sleeptime));
            runtime = sleeptime = 0.0;
        }
        run_n += 1;
#endif
    }
out:
    return;
}