struct rtpp_ttl * rtpp_ttl_ctor(int max_ttl) { struct rtpp_ttl_priv *pvt; struct rtpp_refcnt *rcnt; pvt = rtpp_rzmalloc(sizeof(struct rtpp_ttl_priv), &rcnt); if (pvt == NULL) { goto e0; } pvt->pub.rcnt = rcnt; if (pthread_mutex_init(&pvt->lock, NULL) != 0) { goto e1; } pvt->pub.reset = &rtpp_ttl_reset; pvt->pub.reset_with = &rtpp_ttl_reset_with; pvt->pub.get_remaining = &rtpp_ttl_get_remaining; pvt->pub.decr = &rtpp_ttl_decr; pvt->ttl = pvt->max_ttl = max_ttl; CALL_METHOD(pvt->pub.rcnt, attach, (rtpp_refcnt_dtor_t)&rtpp_ttl_dtor, pvt); return ((&pvt->pub)); e1: CALL_METHOD(pvt->pub.rcnt, decref); free(pvt); e0: return (NULL); }
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); }
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); }
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); }
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); }
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); }
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);
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); }
struct rtpp_module_if * rtpp_module_if_ctor(struct rtpp_cfg_stable *cfsp, struct rtpp_log *log, const char *mpath) { struct rtpp_refcnt *rcnt; struct rtpp_module_if_priv *pvt; const char *derr; pvt = rtpp_rzmalloc(sizeof(struct rtpp_module_if_priv), &rcnt); if (pvt == NULL) { goto e0; } pvt->pub.rcnt = rcnt; pvt->dmp = dlopen(mpath, RTLD_NOW); if (pvt->dmp == NULL) { derr = dlerror(); if (strstr(derr, mpath) == NULL) { RTPP_LOG(log, RTPP_LOG_ERR, "can't dlopen(%s): %s", mpath, derr); } else { RTPP_LOG(log, RTPP_LOG_ERR, "can't dlopen() module: %s", derr); } goto e1; } pvt->mip = dlsym(pvt->dmp, "rtpp_module"); if (pvt->mip == NULL) { derr = dlerror(); if (strstr(derr, mpath) == NULL) { RTPP_LOG(log, RTPP_LOG_ERR, "can't find 'rtpp_module' symbol in the %s" ": %s", mpath, derr); } else { RTPP_LOG(log, RTPP_LOG_ERR, "can't find 'rtpp_module' symbol: %s", derr); } goto e2; } if (!MI_VER_CHCK(pvt->mip)) { RTPP_LOG(log, RTPP_LOG_ERR, "incompatible API version in the %s, " "consider recompiling the module", mpath); goto e2; } #if RTPP_CHECK_LEAKS pvt->mip->_malloc = &rtpp_memdeb_malloc; pvt->mip->_zmalloc = &rtpp_zmalloc_memdeb; pvt->mip->_free = &rtpp_memdeb_free; pvt->mip->_realloc = &rtpp_memdeb_realloc; pvt->mip->_strdup = &rtpp_memdeb_strdup; pvt->mip->_asprintf = &rtpp_memdeb_asprintf; pvt->mip->_vasprintf = &rtpp_memdeb_vasprintf; pvt->memdeb_p = rtpp_memdeb_init(); rtpp_memdeb_setlog(pvt->memdeb_p, log); #else pvt->mip->_malloc = (rtpp_module_malloc_t)&malloc; pvt->mip->_zmalloc = (rtpp_module_zmalloc_t)&rtpp_zmalloc; pvt->mip->_free = (rtpp_module_free_t)&free; pvt->mip->_realloc = (rtpp_module_realloc_t)&realloc; pvt->mip->_strdup = (rtpp_module_strdup_t)&strdup; pvt->mip->_asprintf = rtpp_module_asprintf; pvt->mip->_vasprintf = rtpp_module_vasprintf; #endif if (pvt->memdeb_p == NULL) { goto e2; } /* We make a copy, so that the module cannot screw us up */ pvt->mip->memdeb_p = pvt->memdeb_p; pvt->sigterm = rtpp_wi_malloc_sgnl(SIGTERM, NULL, 0); if (pvt->sigterm == NULL) { goto e3; } pvt->req_q = rtpp_queue_init(1, "rtpp_module_if(%s)", pvt->mip->name); if (pvt->req_q == NULL) { goto e4; } if (pvt->mip->ctor != NULL) { pvt->mpvt = pvt->mip->ctor(cfsp); if (pvt->mpvt == NULL) { RTPP_LOG(log, RTPP_LOG_ERR, "module '%s' failed to initialize", pvt->mip->name); goto e5; } } if (pvt->mip->on_session_end.argsize != rtpp_acct_OSIZE()) { RTPP_LOG(log, RTPP_LOG_ERR, "incompatible API version in the %s, " "consider recompiling the module", mpath); goto e6; } if (pthread_create(&pvt->thread_id, NULL, (void *(*)(void *))&rtpp_mif_run, pvt) != 0) { goto e6; } CALL_METHOD(log->rcnt, incref); pvt->log = log; pvt->pub.do_acct = &rtpp_mif_do_acct; CALL_METHOD(pvt->pub.rcnt, attach, (rtpp_refcnt_dtor_t)&rtpp_mif_dtor, pvt); return ((&pvt->pub)); e6: if (pvt->mip->dtor != NULL) { pvt->mip->dtor(pvt->mpvt); } e5: rtpp_queue_destroy(pvt->req_q); #if RTPP_CHECK_LEAKS if (rtpp_memdeb_dumpstats(pvt->memdeb_p, 1) != 0) { RTPP_LOG(log, RTPP_LOG_ERR, "module '%s' leaked memory in the failed " "constructor", pvt->mip->name); } #endif e4: rtpp_wi_free(pvt->sigterm); e3: #if RTPP_CHECK_LEAKS rtpp_memdeb_dtor(pvt->memdeb_p); #endif e2: dlclose(pvt->dmp); e1: CALL_METHOD(rcnt, decref); free(pvt); e0: return (NULL); }
struct rtpp_stream * rtpp_stream_ctor(struct rtpp_log *log, struct rtpp_weakref_obj *servers_wrt, struct rtpp_stats *rtpp_stats, enum rtpp_stream_side side, int session_type, uint64_t seuid) { struct rtpp_stream_priv *pvt; struct rtpp_refcnt *rcnt; pvt = rtpp_rzmalloc(sizeof(struct rtpp_stream_priv), &rcnt); if (pvt == NULL) { goto e0; } pvt->pub.rcnt = rcnt; if (pthread_mutex_init(&pvt->lock, NULL) != 0) { goto e1; } if (session_type == SESS_RTP) { pvt->pub.analyzer = rtpp_analyzer_ctor(log); if (pvt->pub.analyzer == NULL) { goto e3; } } pvt->pub.pcnt_strm = rtpp_pcnt_strm_ctor(); if (pvt->pub.pcnt_strm == NULL) { goto e4; } pvt->servers_wrt = servers_wrt; pvt->rtpp_stats = rtpp_stats; pvt->pub.log = log; CALL_METHOD(log->rcnt, incref); pvt->side = side; pvt->pub.session_type = session_type; pvt->pub.handle_play = &rtpp_stream_handle_play; pvt->pub.handle_noplay = &rtpp_stream_handle_noplay; pvt->pub.isplayer_active = &rtpp_stream_isplayer_active; pvt->pub.finish_playback = &rtpp_stream_finish_playback; pvt->pub.get_actor = &rtpp_stream_get_actor; pvt->pub.get_proto = &rtpp_stream_get_proto; pvt->pub.latch = &rtpp_stream_latch; pvt->pub.check_latch_override = &rtpp_stream_check_latch_override; pvt->pub.fill_addr = &rtpp_stream_fill_addr; pvt->pub.prefill_addr = &rtpp_stream_prefill_addr; pvt->pub.get_rtps = &rtpp_stream_get_rtps; pvt->pub.replace_rtps = &rtpp_stream_replace_rtps; if (session_type == SESS_RTCP) { pvt->pub.guess_addr = &rtpp_stream_guess_addr; } rtpp_gen_uid(&pvt->pub.stuid); pvt->pub.seuid = seuid; CALL_METHOD(pvt->pub.rcnt, attach, (rtpp_refcnt_dtor_t)&rtpp_stream_dtor, pvt); return (&pvt->pub); e4: if (session_type == SESS_RTP) { CALL_METHOD(pvt->pub.analyzer->rcnt, decref); } e3: pthread_mutex_destroy(&pvt->lock); e1: CALL_METHOD(pvt->pub.rcnt, decref); free(pvt); e0: return (NULL); }