Пример #1
0
struct rtpp_pcount *
rtpp_pcount_ctor(void)
{
    struct rtpp_pcount_priv *pvt;
    struct rtpp_refcnt *rcnt;

    pvt = rtpp_rzmalloc(sizeof(struct rtpp_pcount_priv), &rcnt);
    if (pvt == NULL) {
        goto e0;
    }
    pvt->pub.rcnt = rcnt;
    if (pthread_mutex_init(&pvt->lock, NULL) != 0) {
        goto e1;
    }
    pvt->pub.reg_reld = &rtpp_pcount_reg_reld;
    pvt->pub.reg_drop = &rtpp_pcount_reg_drop;
    pvt->pub.reg_ignr = &rtpp_pcount_reg_ignr;
    pvt->pub.get_stats = &rtpp_pcount_get_stats;
    CALL_SMETHOD(pvt->pub.rcnt, attach, (rtpp_refcnt_dtor_t)&rtpp_pcount_dtor,
      pvt);
    return ((&pvt->pub));

e1:
    CALL_SMETHOD(pvt->pub.rcnt, decref);
    free(pvt);
e0:
    return (NULL);
}
Пример #2
0
void
rtpp_pcount_fintest()
{
    int naborts_s;

    struct {
        struct rtpp_pcount pub;
    } *tp;

    naborts_s = _naborts;
    tp = rtpp_rzmalloc(sizeof(*tp), offsetof(typeof(*tp), pub.rcnt));
    assert(tp != NULL);
    assert(tp->pub.rcnt != NULL);
    tp->pub.get_stats = (rtpp_pcount_get_stats_t)((void *)0x1);
    tp->pub.reg_drop = (rtpp_pcount_reg_drop_t)((void *)0x1);
    tp->pub.reg_ignr = (rtpp_pcount_reg_ignr_t)((void *)0x1);
    tp->pub.reg_reld = (rtpp_pcount_reg_reld_t)((void *)0x1);
    CALL_SMETHOD(tp->pub.rcnt, attach, (rtpp_refcnt_dtor_t)&rtpp_pcount_fin,
      &tp->pub);
    CALL_SMETHOD(tp->pub.rcnt, decref);
    CALL_TFIN(&tp->pub, get_stats);
    CALL_TFIN(&tp->pub, reg_drop);
    CALL_TFIN(&tp->pub, reg_ignr);
    CALL_TFIN(&tp->pub, reg_reld);
    assert((_naborts - naborts_s) == 4);
}
Пример #3
0
struct rtpp_acct_rtcp *
rtpp_acct_rtcp_ctor(const char *call_id, const struct rtp_packet *pp)
{
    struct rtpp_acct_rtcp_priv *pvt;

    pvt = rtpp_rzmalloc(sizeof(struct rtpp_acct_rtcp_priv), PVT_RCOFFS(pvt));
    if (pvt == NULL) {
        goto e0;
    }
    pvt->pub.pkt = rtp_packet_alloc();
    if (pvt->pub.pkt == NULL) {
        goto e1;
    }
    rtp_packet_dup(pvt->pub.pkt, pp, 0);
    pvt->pub.call_id = strdup(call_id);
    if (pvt->pub.call_id == NULL) {
        goto e2;
    }
    pvt->pub.jt = &pvt->_jt;
    CALL_SMETHOD(pvt->pub.rcnt, attach, (rtpp_refcnt_dtor_t)&rtpp_acct_rtcp_dtor,
      pvt);
    return ((&pvt->pub));

e2:
    rtp_packet_free(pvt->pub.pkt);
e1:
    CALL_SMETHOD(pvt->pub.rcnt, decref);
    free(pvt);
e0:
    return (NULL);
}
Пример #4
0
void
rtpp_wi_free(struct rtpp_wi *wi)
{

    if (wi->sock_rcnt != NULL) {
        CALL_SMETHOD(wi->sock_rcnt, decref);
    }
    if (wi->log != NULL) {
        CALL_SMETHOD(wi->log->rcnt, decref);
    }
    free(wi->free_ptr);
}
Пример #5
0
static int
rtpp_proc_ttl_foreach(void *dp, void *ap)
{
    struct foreach_args *fap;
    struct rtpp_session *sp;

    fap = (struct foreach_args *)ap;
    /*
     * This method does not need us to bump ref, since we are in the
     * locked context of the rtpp_hash_table, which holds its own ref.
     */
    sp = (struct rtpp_session *)dp;

    if (CALL_METHOD(sp->rtp, get_ttl) == 0) {
        RTPP_LOG(sp->log, RTPP_LOG_INFO, "session timeout");
        if (sp->timeout_data.notify_target != NULL) {
            CALL_METHOD(fap->rtpp_notify_cf, schedule,
              sp->timeout_data.notify_target, sp->timeout_data.notify_tag);
        }
        CALL_SMETHOD(fap->rtpp_stats, updatebyname, "nsess_timeout", 1);
        CALL_METHOD(fap->sessions_wrt, unreg, sp->seuid);
        return (RTPP_HT_MATCH_DEL);
    } else {
        CALL_METHOD(sp->rtp, decr_ttl);
    }
    return (RTPP_HT_MATCH_CONT);
}
Пример #6
0
void
rtpp_timed_task_fintest()
{
    int naborts_s;

    struct {
        struct rtpp_timed_task pub;
    } *tp;

    naborts_s = _naborts;
    tp = rtpp_rzmalloc(sizeof(*tp), offsetof(typeof(*tp), pub.rcnt));
    assert(tp != NULL);
    assert(tp->pub.rcnt != NULL);
    tp->pub.cancel = (rtpp_timed_task_cancel_t)((void *)0x1);
    CALL_SMETHOD(tp->pub.rcnt, attach, (rtpp_refcnt_dtor_t)&rtpp_timed_task_fin,
      &tp->pub);
    CALL_SMETHOD(tp->pub.rcnt, decref);
    CALL_TFIN(&tp->pub, cancel);
    assert((_naborts - naborts_s) == 1);
}
Пример #7
0
struct rtpp_socket *
rtpp_socket_ctor(int domain, int type)
{
    struct rtpp_socket_priv *pvt;

    pvt = rtpp_rzmalloc(sizeof(struct rtpp_socket_priv), PVT_RCOFFS(pvt));
    if (pvt == NULL) {
        goto e0;
    }
    pvt->fd = socket(domain, type, 0);
    if (pvt->fd < 0) {
        goto e1;
    }
    if (domain == AF_INET6) {
        /* Disable any automatic IPv4->IPv6 gatewaying */
        int yes = 1;

        setsockopt(pvt->fd, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof(yes));
    }
    pvt->pub.bind = &rtpp_socket_bind;
    pvt->pub.settos = &rtpp_socket_settos;
    pvt->pub.setrbuf = &rtpp_socket_setrbuf;
    pvt->pub.setnonblock = &rtpp_socket_setnonblock;
    pvt->pub.settimestamp = &rtpp_socket_settimestamp;
#if 0
    pvt->pub.send_pkt = &rtpp_socket_send_pkt;
#endif
    pvt->pub.send_pkt_na = &rtpp_socket_send_pkt_na;
    pvt->pub.rtp_recv = &rtpp_socket_rtp_recv_simple;
    pvt->pub.getfd = &rtpp_socket_getfd;
    CALL_SMETHOD(pvt->pub.rcnt, attach, (rtpp_refcnt_dtor_t)&rtpp_socket_dtor,
      pvt);
    return (&pvt->pub);
e1:
    CALL_SMETHOD(pvt->pub.rcnt, decref);
    free(pvt);
e0:
    return (NULL);
}
Пример #8
0
void
rtpp_netaddr_fintest()
{
    int naborts_s;

    struct {
        struct rtpp_netaddr pub;
    } *tp;

    naborts_s = _naborts;
    tp = rtpp_rzmalloc(sizeof(*tp), offsetof(typeof(*tp), pub.rcnt));
    assert(tp != NULL);
    assert(tp->pub.rcnt != NULL);
    static const struct rtpp_netaddr_smethods dummy = {
        .cmp = (rtpp_netaddr_cmp_t)((void *)0x1),
        .cmphost = (rtpp_netaddr_cmphost_t)((void *)0x1),
        .copy = (rtpp_netaddr_copy_t)((void *)0x1),
        .get = (rtpp_netaddr_get_t)((void *)0x1),
        .isaddrseq = (rtpp_netaddr_isaddrseq_t)((void *)0x1),
        .isempty = (rtpp_netaddr_isempty_t)((void *)0x1),
        .set = (rtpp_netaddr_set_t)((void *)0x1),
        .sip_print = (rtpp_netaddr_sip_print_t)((void *)0x1),
    };
    tp->pub.smethods = &dummy;
    CALL_SMETHOD(tp->pub.rcnt, attach, (rtpp_refcnt_dtor_t)&rtpp_netaddr_fin,
      &tp->pub);
    CALL_SMETHOD(tp->pub.rcnt, decref);
    CALL_TFIN(&tp->pub, cmp);
    CALL_TFIN(&tp->pub, cmphost);
    CALL_TFIN(&tp->pub, copy);
    CALL_TFIN(&tp->pub, get);
    CALL_TFIN(&tp->pub, isaddrseq);
    CALL_TFIN(&tp->pub, isempty);
    CALL_TFIN(&tp->pub, set);
    CALL_TFIN(&tp->pub, sip_print);
    assert((_naborts - naborts_s) == 8);
}
const static void *_rtpp_netaddr_ftp = (void *)&rtpp_netaddr_fintest;
DATA_SET(rtpp_fintests, _rtpp_netaddr_ftp);
Пример #9
0
static void
rtp_analyze_jt_destroy(struct rtp_analyze_jitter *jp)
{
    struct rtp_analyze_jdata *jdp, *jdp_next;

    for (jdp = jp->first; jdp != NULL; jdp = jdp_next) {
        jdp_next = jdp->next;
        CALL_SMETHOD(jdp->ts_dedup->rcnt, decref);
        free(jdp);
        jp->jdlen -= 1;
    }
    RTPP_DBG_ASSERT(jp->jdlen == 0);
    free(jp);
}
Пример #10
0
struct rtpp_wi *
rtpp_wi_malloc_pkt_na(int sock, struct rtp_packet *pkt,
  struct rtpp_netaddr *sendto, int nsend,
  struct rtpp_refcnt *sock_rcnt)
{
    struct rtpp_wi *wi;

    wi = pkt->wi;
    wi->free_ptr = (struct rtpp_wi *)pkt;
    wi->wi_type = RTPP_WI_TYPE_OPKT;
    wi->sock = sock;
    if (sock_rcnt != NULL) {
        CALL_SMETHOD(sock_rcnt, incref);
    }
    wi->sock_rcnt = sock_rcnt;
    wi->flags = 0;
    wi->msg = pkt->data.buf;
    wi->msg_len = pkt->size;
    wi->sendto = sstosa(&pkt->sendto);
    wi->tolen = CALL_SMETHOD(sendto, get, wi->sendto, sizeof(pkt->raddr));
    wi->nsend = nsend;
    return (wi);
}
Пример #11
0
void
rtpp_netio_async_destroy(struct rtpp_anetio_cf *netio_cf)
{
    int i;

    for (i = 0; i < SEND_THREADS; i++) {
        rtpp_queue_put_item(netio_cf->args[i].sigterm, netio_cf->args[i].out_q);
    }
    for (i = 0; i < SEND_THREADS; i++) {
        pthread_join(netio_cf->thread_id[i], NULL);
        rtpp_queue_destroy(netio_cf->args[i].out_q);
        CALL_SMETHOD(netio_cf->args[i].glog->rcnt, decref);
    }
    free(netio_cf);
}
Пример #12
0
struct rtpp_log *
rtpp_log_ctor(struct rtpp_cfg_stable *cfs, const char *app,
  const char *call_id, int flags)
{
    struct rtpp_log_priv *pvt;
    struct rtpp_refcnt *rcnt;

    pvt = rtpp_rzmalloc(sizeof(struct rtpp_log_priv), &rcnt);
    if (pvt == NULL) {
        return (NULL);
    }
    pvt->pub.rcnt = rcnt;
    pvt->log = rtpp_log_open(cfs, app, call_id, flags);
    rtpp_gen_uid(&pvt->pub.lguid);
    pvt->pub.setlevel = &rtpp_log_obj_setlevel;
    pvt->pub.write = rtpp_log_obj_write;
    pvt->pub.ewrite = rtpp_log_obj_ewrite;
    CALL_SMETHOD(pvt->pub.rcnt, attach, (rtpp_refcnt_dtor_t)&rtpp_log_obj_dtor,
      pvt);
    return (&pvt->pub);
}
Пример #13
0
int
rtpp_anetio_sendto(struct rtpp_anetio_cf *netio_cf, int sock, const void *msg, \
  size_t msg_len, int flags, const struct sockaddr *sendto, socklen_t tolen)
{
    struct rtpp_wi *wi;

    wi = rtpp_wi_malloc(sock, msg, msg_len, flags, sendto, tolen);
    if (wi == NULL) {
        return (-1);
    }
#if RTPP_DEBUG_netio >= 1
    wi->debug = 1;
    wi->log = netio_cf->args[0].glog;
    CALL_SMETHOD(wi->log->rcnt, incref);
#if RTPP_DEBUG_netio >= 2
    RTPP_LOG(netio_cf->args[0].glog, RTPP_LOG_DBUG, "malloc(%d, %p, %d, %d, %p, %d) = %p",
      sock, msg, msg_len, flags, sendto, tolen, wi);
    RTPP_LOG(netio_cf->args[0].glog, RTPP_LOG_DBUG, "sendto(%d, %p, %d, %d, %p, %d)",
      wi->sock, wi->msg, wi->msg_len, wi->flags, wi->sendto, wi->tolen);
#endif
#endif
    rtpp_queue_put_item(wi, netio_cf->args[0].out_q);
    return (0);
}
Пример #14
0
struct rtpp_wi *
rtpp_wi_malloc_pkt(int sock, struct rtp_packet *pkt,
  const struct sockaddr *sendto, size_t tolen, int nsend,
  struct rtpp_refcnt *sock_rcnt)
{
    struct rtpp_wi *wi;

    wi = pkt->wi;
    wi->free_ptr = (struct rtpp_wi *)pkt;
    wi->wi_type = RTPP_WI_TYPE_OPKT;
    wi->sock = sock;
    if (sock_rcnt != NULL) {
        CALL_SMETHOD(sock_rcnt, incref);
    }
    wi->sock_rcnt = sock_rcnt;
    wi->flags = 0;
    wi->msg = pkt->data.buf;
    wi->msg_len = pkt->size;
    wi->sendto = sstosa(&pkt->sendto);
    wi->tolen = tolen;
    memcpy(wi->sendto, sendto, tolen);
    wi->nsend = nsend;
    return (wi);
}
Пример #15
0
int
rtpp_anetio_send_pkt_na(struct sthread_args *sender, int sock, \
  struct rtpp_netaddr *sendto, struct rtp_packet *pkt,
  struct rtpp_refcnt *sock_rcnt, struct rtpp_log *plog)
{
    struct rtpp_wi *wi;
    int nsend;

    if (sender->dmode != 0 && pkt->size < LBR_THRS) {
        nsend = 2;
    } else {
        nsend = 1;
    }

    wi = rtpp_wi_malloc_pkt_na(sock, pkt, sendto, nsend, sock_rcnt);
    if (wi == NULL) {
        rtp_packet_free(pkt);
        return (-1);
    }
    /*
     * rtpp_wi_malloc_pkt() consumes pkt and returns wi, so no need to
     * call rtp_packet_free() here.
     */
#if RTPP_DEBUG_netio >= 2
    wi->debug = 1;
    if (plog == NULL) {
        plog = sender->glog;
    }
    CALL_SMETHOD(plog->rcnt, incref);
    wi->log = plog;
    RTPP_LOG(plog, RTPP_LOG_DBUG, "send_pkt(%d, %p, %d, %d, %p, %d)",
      wi->sock, wi->msg, wi->msg_len, wi->flags, wi->sendto, wi->tolen);
#endif
    rtpp_queue_put_item(wi, sender->out_q);
    return (0);
}
Пример #16
0
static int
process_rtp_servers_foreach(void *dp, void *ap)
{
    struct foreach_args *fap;
    struct rtpp_server *rsrv;
    struct rtp_packet *pkt;
    int len;
    struct rtpp_stream *rsop;

    fap = (struct foreach_args *)ap;
    /*
     * This method does not need us to bump ref, since we are in the
     * locked context of the rtpp_hash_table, which holds its own ref.
     */
    rsrv = (struct rtpp_server *)dp;
    rsop = CALL_METHOD(fap->rtp_streams_wrt, get_by_idx, rsrv->stuid);
    if (rsop == NULL) {
        return (RTPP_WR_MATCH_CONT);
    }
    for (;;) {
        pkt = CALL_SMETHOD(rsrv, get, fap->dtime, &len);
        if (pkt == NULL) {
            if (len == RTPS_EOF) {
                CALL_SMETHOD(rsop, finish_playback, rsrv->sruid);
                CALL_SMETHOD(rsop->rcnt, decref);
                return (RTPP_WR_MATCH_DEL);
            } else if (len != RTPS_LATER) {
                /* XXX some error, brag to logs */
            }
            break;
        }
        if (CALL_SMETHOD(rsop, issendable) == 0) {
            /* We have a packet, but nowhere to send it, drop */
            rtp_packet_free(pkt);
            continue;
        }
        CALL_SMETHOD(rsop, send_pkt, fap->sender, pkt);
        fap->rsp->npkts_played.cnt++;
    }
    CALL_SMETHOD(rsop->rcnt, decref);
    return (RTPP_WR_MATCH_CONT);
}
Пример #17
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);
}
Пример #18
0
static int 
fill_cmd_props(struct cfg *cf, struct rtpp_command *cmd,
  struct cmd_props *cpp)
{

    cpp->has_call_id = 1;
    cpp->fpos = -1;
    cpp->tpos = -1;
    cpp->cmods = &(cmd->argv[0][1]);
    switch (cmd->argv[0][0]) {
    case 'u':
    case 'U':
        cmd->cca.op = UPDATE;
        cmd->cca.rname = "update/create";
        cmd->cca.hint = "U[opts] callid remote_ip remote_port from_tag [to_tag] [notify_socket notify_tag]";
        cpp->max_argc = 8;
        cpp->min_argc = 5;
        cpp->has_cmods = 1;
        cpp->fpos = 4;
        cpp->tpos = 5;
        break;

    case 'l':
    case 'L':
        cmd->cca.op = LOOKUP;
        cmd->cca.rname = "lookup";
        cmd->cca.hint = "L[opts] callid remote_ip remote_port from_tag [to_tag]";
        cpp->max_argc = 6;
        cpp->min_argc = 5;
        cpp->has_cmods = 1;
        cpp->fpos = 4;
        cpp->tpos = 5;
        break;

    case 'd':
    case 'D':
        cmd->cca.op = DELETE;
        cmd->cca.rname = "delete";
        cmd->cca.hint = "D[w] callid from_tag [to_tag]";
        cpp->max_argc = 4;
        cpp->min_argc = 3;
        cpp->has_cmods = 1;
        cpp->fpos = 2;
        cpp->tpos = 3;
        break;

    case 'p':
    case 'P':
        cmd->cca.op = PLAY;
        cmd->cca.rname = "play";
        cmd->cca.hint = "P[n] callid pname codecs from_tag [to_tag]";
        cpp->max_argc = 6;
        cpp->min_argc = 5;
        cpp->has_cmods = 1;
        cpp->fpos = 4;
        cpp->tpos = 5;
        break;

    case 'r':
    case 'R':
        cmd->cca.op = RECORD;
        cmd->cca.rname = "record";
        if (cf->stable->record_pcap != 0) {
            cmd->cca.hint = "R[s] call_id from_tag [to_tag]";
        } else {
            cmd->cca.hint = "R call_id from_tag [to_tag]";
        }
        cpp->max_argc = 4;
        cpp->min_argc = 3;
        cpp->has_cmods = 1;
        cpp->fpos = 2;
        cpp->tpos = 3;
        break;

    case 'c':
    case 'C':
        cmd->cca.op = COPY;
        cmd->cca.rname = "copy";
        cmd->cca.hint = "C[-xxx-] call_id -XXX- from_tag [to_tag]";
        cpp->max_argc = 5;
        cpp->min_argc = 4;
        cpp->has_cmods = 1;
        cpp->fpos = 3;
        cpp->tpos = 4;
        break;

    case 's':
    case 'S':
        cmd->cca.op = NOPLAY;
        cmd->cca.rname = "noplay";
        cmd->cca.hint = "S call_id from_tag [to_tag]";
        cpp->max_argc = 4;
        cpp->min_argc = 3;
        cpp->has_cmods = 0;
        cpp->fpos = 2;
        cpp->tpos = 3;
        break;

    case 'v':
    case 'V':
        if (cpp->cmods[0] == 'F' || cpp->cmods[0] == 'f') {
            cpp->cmods += 1;
            cmd->cca.op = VER_FEATURE;
            cmd->cca.rname = "feature_check";
            cmd->cca.hint = "VF feature_num";
            cmd->no_glock = 1;
            cpp->max_argc = 2;
            cpp->min_argc = 2;
            cpp->has_cmods = 0;
            cpp->has_call_id = 0;
            break;
        }
        cmd->cca.op = GET_VER;
        cmd->cca.rname = "get_version";
        cmd->cca.hint = "V";
        cmd->no_glock = 1;
        cpp->max_argc = 1;
        cpp->min_argc = 1;
        cpp->has_cmods = 0;
        cpp->has_call_id = 0;
        break;

    case 'i':
    case 'I':
        cmd->cca.op = INFO;
        cmd->cca.rname = "get_info";
        cmd->cca.hint = "I[b]";
        cpp->max_argc = 1;
        cpp->min_argc = 1;
        cpp->has_cmods = 1;
        cpp->has_call_id = 0;
        break;

    case 'q':
    case 'Q':
        cmd->cca.op = QUERY;
        cmd->cca.rname = "query";
        cmd->cca.hint = "Q[v] call_id from_tag [to_tag [stat_name1 ...[stat_nameN]]]";
        cpp->max_argc = 4 + RTPP_QUERY_NSTATS;
        cpp->min_argc = 3;
        cpp->has_cmods = 1;
        cpp->fpos = 2;
        cpp->tpos = 3;
        break;

    case 'x':
    case 'X':
        cmd->cca.op = DELETE_ALL;
        cmd->cca.rname = "delete_all";
        cmd->cca.hint = "X";
        cpp->max_argc = 1;
        cpp->min_argc = 1;
        cpp->has_cmods = 0;
        cpp->has_call_id = 0;
        break;

    case 'g':
    case 'G':
        cmd->cca.op = GET_STATS;
        cmd->cca.rname = "get_stats";
        cmd->cca.hint = "G[v] [stat_name1 [stat_name2 [stat_name3 ...[stat_nameN]]]]";
        cmd->no_glock = 1;
        cpp->max_argc = CALL_SMETHOD(cf->stable->rtpp_stats, getnstats) + 1;
        cpp->min_argc = 1;
        cpp->has_cmods = 1;
        cpp->has_call_id = 0;
        break;

    default:
        return (-1);
    }
    return (0);
}
Пример #19
0
struct rtpp_anetio_cf *
rtpp_netio_async_init(struct cfg *cf, int qlen)
{
    struct rtpp_anetio_cf *netio_cf;
    int i, ri;

    netio_cf = rtpp_zmalloc(sizeof(*netio_cf));
    if (netio_cf == NULL)
        return (NULL);

    for (i = 0; i < SEND_THREADS; i++) {
        netio_cf->args[i].out_q = rtpp_queue_init(qlen, "RTPP->NET%.2d", i);
        if (netio_cf->args[i].out_q == NULL) {
            for (ri = i - 1; ri >= 0; ri--) {
                rtpp_queue_destroy(netio_cf->args[ri].out_q);
                CALL_SMETHOD(netio_cf->args[ri].glog->rcnt, decref);
            }
            goto e0;
        }
        CALL_SMETHOD(cf->stable->glog->rcnt, incref);
        netio_cf->args[i].glog = cf->stable->glog;
        netio_cf->args[i].dmode = cf->stable->dmode;
#if RTPP_DEBUG_timers
        recfilter_init(&netio_cf->args[i].average_load, 0.9, 0.0, 0);
#endif
    }

    for (i = 0; i < SEND_THREADS; i++) {
        netio_cf->args[i].sigterm = rtpp_wi_malloc_sgnl(SIGTERM, NULL, 0);
        if (netio_cf->args[i].sigterm == NULL) {
            for (ri = i - 1; ri >= 0; ri--) {
                rtpp_wi_free(netio_cf->args[ri].sigterm);
            }
            goto e1;
        }
    }

    cf->stable->rtpp_netio_cf = netio_cf;
    for (i = 0; i < SEND_THREADS; i++) {
        if (pthread_create(&(netio_cf->thread_id[i]), NULL, (void *(*)(void *))&rtpp_anetio_sthread, &netio_cf->args[i]) != 0) {
             for (ri = i - 1; ri >= 0; ri--) {
                 rtpp_queue_put_item(netio_cf->args[ri].sigterm, netio_cf->args[ri].out_q);
                 pthread_join(netio_cf->thread_id[ri], NULL);
             }
             for (ri = i; ri < SEND_THREADS; ri++) {
                 rtpp_wi_free(netio_cf->args[ri].sigterm);
             }
             goto e1;
        }
    }

    return (netio_cf);

#if 0
e2:
    for (i = 0; i < SEND_THREADS; i++) {
        rtpp_wi_free(netio_cf->args[i].sigterm);
    }
#endif
e1:
    for (i = 0; i < SEND_THREADS; i++) {
        rtpp_queue_destroy(netio_cf->args[i].out_q);
        CALL_SMETHOD(netio_cf->args[i].glog->rcnt, decref);
    }
e0:
    free(netio_cf);
    return (NULL);
}