|
|
|
|
@ -76,13 +76,13 @@ unsigned int call_socket_cpu_affinity = 0;
|
|
|
|
|
static struct timeval add_ongoing_calls_dur_in_interval(struct timeval *interval_start,
|
|
|
|
|
struct timeval *interval_duration);
|
|
|
|
|
static void __call_free(void *p);
|
|
|
|
|
static void __call_cleanup(struct call *c);
|
|
|
|
|
static void __call_cleanup(call_t *c);
|
|
|
|
|
static void __monologue_stop(struct call_monologue *ml);
|
|
|
|
|
static void media_stop(struct call_media *m);
|
|
|
|
|
static void __subscribe_medias_both_ways(struct call_media * a, struct call_media * b);
|
|
|
|
|
|
|
|
|
|
/* called with call->master_lock held in R */
|
|
|
|
|
static int call_timer_delete_monologues(struct call *c) {
|
|
|
|
|
static int call_timer_delete_monologues(call_t *c) {
|
|
|
|
|
GList *i;
|
|
|
|
|
struct call_monologue *ml;
|
|
|
|
|
int ret = 0;
|
|
|
|
|
@ -121,7 +121,7 @@ static int call_timer_delete_monologues(struct call *c) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void call_make_own_foreign(struct call *c, bool foreign) {
|
|
|
|
|
void call_make_own_foreign(call_t *c, bool foreign) {
|
|
|
|
|
statistics_update_foreignown_dec(c);
|
|
|
|
|
bf_set_clear(&c->call_flags, CALL_FLAG_FOREIGN, foreign);
|
|
|
|
|
statistics_update_foreignown_inc(c);
|
|
|
|
|
@ -130,7 +130,7 @@ void call_make_own_foreign(struct call *c, bool foreign) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* called with hashlock held */
|
|
|
|
|
static void call_timer_iterator(struct call *c, struct iterator_helper *hlp) {
|
|
|
|
|
static void call_timer_iterator(call_t *c, struct iterator_helper *hlp) {
|
|
|
|
|
unsigned int check;
|
|
|
|
|
bool good = false;
|
|
|
|
|
struct packet_stream *ps;
|
|
|
|
|
@ -375,7 +375,7 @@ fault:
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void kill_calls_timer(GSList *list, const char *url) {
|
|
|
|
|
struct call *ca;
|
|
|
|
|
call_t *ca;
|
|
|
|
|
GList *csl;
|
|
|
|
|
struct call_monologue *cm;
|
|
|
|
|
char *url_prefix = NULL, *url_suffix = NULL;
|
|
|
|
|
@ -538,9 +538,9 @@ int call_init(void) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void __call_iterator_remove(struct call *c) {
|
|
|
|
|
static void __call_iterator_remove(call_t *c) {
|
|
|
|
|
for (unsigned int i = 0; i < NUM_CALL_ITERATORS; i++) {
|
|
|
|
|
struct call *prev_call, *next_call;
|
|
|
|
|
call_t *prev_call, *next_call;
|
|
|
|
|
while (1) {
|
|
|
|
|
mutex_lock(&rtpe_call_iterators[i].lock);
|
|
|
|
|
// lock this entry
|
|
|
|
|
@ -588,7 +588,7 @@ void call_free(void) {
|
|
|
|
|
mqtt_timer_stop(&global_mqtt_timer);
|
|
|
|
|
rtpe_calls_ht_iter iter;
|
|
|
|
|
t_hash_table_iter_init(&iter, rtpe_callhash);
|
|
|
|
|
struct call *c;
|
|
|
|
|
call_t *c;
|
|
|
|
|
while (t_hash_table_iter_next(&iter, NULL, &c)) {
|
|
|
|
|
__call_iterator_remove(c);
|
|
|
|
|
__call_cleanup(c);
|
|
|
|
|
@ -599,7 +599,7 @@ void call_free(void) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct call_media *call_media_new(struct call *call) {
|
|
|
|
|
struct call_media *call_media_new(call_t *call) {
|
|
|
|
|
struct call_media *med;
|
|
|
|
|
med = uid_slice_alloc0(med, &call->medias);
|
|
|
|
|
med->call = call;
|
|
|
|
|
@ -614,7 +614,7 @@ static struct call_media *__get_media(struct call_monologue *ml, const struct st
|
|
|
|
|
const sdp_ng_flags *flags, unsigned int index)
|
|
|
|
|
{
|
|
|
|
|
struct call_media *med;
|
|
|
|
|
struct call *call;
|
|
|
|
|
call_t *call;
|
|
|
|
|
|
|
|
|
|
// check for trickle ICE SDP fragment
|
|
|
|
|
if (flags && flags->fragment && sp->media_id.len) {
|
|
|
|
|
@ -891,7 +891,7 @@ static void __rtp_stats_free(void *p) {
|
|
|
|
|
g_slice_free1(sizeof(struct rtp_stats), p);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct packet_stream *__packet_stream_new(struct call *call) {
|
|
|
|
|
struct packet_stream *__packet_stream_new(call_t *call) {
|
|
|
|
|
struct packet_stream *stream;
|
|
|
|
|
|
|
|
|
|
stream = uid_slice_alloc0(stream, &call->streams.q);
|
|
|
|
|
@ -911,7 +911,7 @@ struct packet_stream *__packet_stream_new(struct call *call) {
|
|
|
|
|
|
|
|
|
|
static int __num_media_streams(struct call_media *media, unsigned int num_ports) {
|
|
|
|
|
struct packet_stream *stream;
|
|
|
|
|
struct call *call = media->call;
|
|
|
|
|
call_t *call = media->call;
|
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
|
|
// we need at least two, one for RTP and one for RTCP as they hold the crypto context
|
|
|
|
|
@ -1079,7 +1079,7 @@ void call_media_state_machine(struct call_media *m) {
|
|
|
|
|
|
|
|
|
|
int __init_stream(struct packet_stream *ps) {
|
|
|
|
|
struct call_media *media = ps->media;
|
|
|
|
|
struct call *call = ps->call;
|
|
|
|
|
call_t *call = ps->call;
|
|
|
|
|
int dtls_active = -1;
|
|
|
|
|
g_autoptr(char) paramsbuf = NULL;
|
|
|
|
|
struct dtls_connection *dtls_conn = NULL;
|
|
|
|
|
@ -2016,7 +2016,7 @@ static void __fingerprint_changed(struct call_media *m) {
|
|
|
|
|
__dtls_restart(m);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void __set_all_tos(struct call *c) {
|
|
|
|
|
static void __set_all_tos(call_t *c) {
|
|
|
|
|
for (__auto_type l = c->stream_fds.head; l; l = l->next) {
|
|
|
|
|
struct stream_fd *sfd = l->data;
|
|
|
|
|
if (sfd->socket.fd == -1)
|
|
|
|
|
@ -2025,7 +2025,7 @@ static void __set_all_tos(struct call *c) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void __tos_change(struct call *call, const sdp_ng_flags *flags) {
|
|
|
|
|
static void __tos_change(call_t *call, const sdp_ng_flags *flags) {
|
|
|
|
|
unsigned char new_tos;
|
|
|
|
|
|
|
|
|
|
/* Handle TOS= parameter. Negative value = no change, not present or too large =
|
|
|
|
|
@ -2088,7 +2088,7 @@ static void __dtls_logic(const sdp_ng_flags *flags,
|
|
|
|
|
struct call_media *other_media, struct stream_params *sp)
|
|
|
|
|
{
|
|
|
|
|
unsigned int tmp;
|
|
|
|
|
struct call *call = other_media->call;
|
|
|
|
|
call_t *call = other_media->call;
|
|
|
|
|
|
|
|
|
|
/* active and passive are from our POV */
|
|
|
|
|
tmp = other_media->media_flags;
|
|
|
|
|
@ -2187,7 +2187,7 @@ static void __update_media_id(struct call_media *media, struct call_media *other
|
|
|
|
|
if (!flags)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
struct call *call = other_media->call;
|
|
|
|
|
call_t *call = other_media->call;
|
|
|
|
|
struct call_monologue *ml = media ? media->monologue : NULL;
|
|
|
|
|
struct call_monologue *other_ml = other_media->monologue;
|
|
|
|
|
|
|
|
|
|
@ -2572,7 +2572,7 @@ void update_init_subscribers(struct call_monologue *ml, enum call_opmode opmode)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void __call_monologue_init_from_flags(struct call_monologue *ml, sdp_ng_flags *flags) {
|
|
|
|
|
struct call *call = ml->call;
|
|
|
|
|
call_t *call = ml->call;
|
|
|
|
|
|
|
|
|
|
call->last_signal = rtpe_now.tv_sec;
|
|
|
|
|
call->deleted = 0;
|
|
|
|
|
@ -2607,7 +2607,7 @@ static void __update_media_label(struct call_media *media, struct call_media *ot
|
|
|
|
|
if (!flags)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
struct call *call = media->call;
|
|
|
|
|
call_t *call = media->call;
|
|
|
|
|
|
|
|
|
|
if (flags->siprec && flags->opmode == OP_REQUEST) {
|
|
|
|
|
if (!media->label.len) {
|
|
|
|
|
@ -2625,7 +2625,7 @@ static void __update_media_label(struct call_media *media, struct call_media *ot
|
|
|
|
|
static void __media_init_from_flags(struct call_media *other_media, struct call_media *media,
|
|
|
|
|
struct stream_params *sp, sdp_ng_flags *flags)
|
|
|
|
|
{
|
|
|
|
|
struct call *call = other_media->call;
|
|
|
|
|
call_t *call = other_media->call;
|
|
|
|
|
str_q *additional_attributes = &sp->attributes; /* attributes in str format */
|
|
|
|
|
|
|
|
|
|
if (flags && flags->opmode == OP_OFFER && flags->reset) {
|
|
|
|
|
@ -3550,7 +3550,7 @@ next:
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void __call_cleanup(struct call *c) {
|
|
|
|
|
static void __call_cleanup(call_t *c) {
|
|
|
|
|
for (__auto_type l = c->streams.head; l; l = l->next) {
|
|
|
|
|
struct packet_stream *ps = l->data;
|
|
|
|
|
|
|
|
|
|
@ -3596,7 +3596,7 @@ static void __call_cleanup(struct call *c) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* called lock-free, but must hold a reference to the call */
|
|
|
|
|
void call_destroy(struct call *c) {
|
|
|
|
|
void call_destroy(call_t *c) {
|
|
|
|
|
struct packet_stream *ps=0;
|
|
|
|
|
GList *l, *ll;
|
|
|
|
|
struct call_monologue *ml;
|
|
|
|
|
@ -3609,7 +3609,7 @@ void call_destroy(struct call *c) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rwlock_lock_w(&rtpe_callhash_lock);
|
|
|
|
|
struct call *call_ht = NULL;
|
|
|
|
|
call_t *call_ht = NULL;
|
|
|
|
|
t_hash_table_steal_extended(rtpe_callhash, &c->callid, NULL, &call_ht);
|
|
|
|
|
if (call_ht) {
|
|
|
|
|
if (call_ht != c) {
|
|
|
|
|
@ -3881,7 +3881,7 @@ void __monologue_free(struct call_monologue *m) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void __call_free(void *p) {
|
|
|
|
|
struct call *c = p;
|
|
|
|
|
call_t *c = p;
|
|
|
|
|
struct call_monologue *m;
|
|
|
|
|
struct call_media *md;
|
|
|
|
|
struct packet_stream *ps;
|
|
|
|
|
@ -3933,8 +3933,8 @@ static void __call_free(void *p) {
|
|
|
|
|
assert(c->stream_fds.head == NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct call *call_create(const str *callid) {
|
|
|
|
|
struct call *c;
|
|
|
|
|
static call_t *call_create(const str *callid) {
|
|
|
|
|
call_t *c;
|
|
|
|
|
|
|
|
|
|
ilog(LOG_NOTICE, "Creating new call");
|
|
|
|
|
c = obj_alloc0("call", sizeof(*c), __call_free);
|
|
|
|
|
@ -3962,8 +3962,8 @@ static struct call *call_create(const str *callid) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* returns call with master_lock held in W */
|
|
|
|
|
struct call *call_get_or_create(const str *callid, bool exclusive) {
|
|
|
|
|
struct call *c;
|
|
|
|
|
call_t *call_get_or_create(const str *callid, bool exclusive) {
|
|
|
|
|
call_t *c;
|
|
|
|
|
|
|
|
|
|
restart:
|
|
|
|
|
rwlock_lock_r(&rtpe_callhash_lock);
|
|
|
|
|
@ -3987,7 +3987,7 @@ restart:
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < NUM_CALL_ITERATORS; i++) {
|
|
|
|
|
c->iterator[i].link.data = obj_get(c);
|
|
|
|
|
struct call *first_call;
|
|
|
|
|
call_t *first_call;
|
|
|
|
|
while (1) {
|
|
|
|
|
// lock the list
|
|
|
|
|
mutex_lock(&rtpe_call_iterators[i].lock);
|
|
|
|
|
@ -4039,8 +4039,8 @@ restart:
|
|
|
|
|
* Therefore the code must use obj_put() on the call after call_get()
|
|
|
|
|
* and after it's done operating on the object.
|
|
|
|
|
*/
|
|
|
|
|
struct call *call_get(const str *callid) {
|
|
|
|
|
struct call *ret;
|
|
|
|
|
call_t *call_get(const str *callid) {
|
|
|
|
|
call_t *ret;
|
|
|
|
|
|
|
|
|
|
rwlock_lock_r(&rtpe_callhash_lock);
|
|
|
|
|
ret = t_hash_table_lookup(rtpe_callhash, callid);
|
|
|
|
|
@ -4058,7 +4058,7 @@ struct call *call_get(const str *callid) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* returns call with master_lock held in W, or possibly NULL iff opmode == OP_ANSWER */
|
|
|
|
|
struct call *call_get_opmode(const str *callid, enum call_opmode opmode) {
|
|
|
|
|
call_t *call_get_opmode(const str *callid, enum call_opmode opmode) {
|
|
|
|
|
if (opmode == OP_OFFER)
|
|
|
|
|
return call_get_or_create(callid, false);
|
|
|
|
|
return call_get(callid);
|
|
|
|
|
@ -4072,7 +4072,7 @@ struct call *call_get_opmode(const str *callid, enum call_opmode opmode) {
|
|
|
|
|
*
|
|
|
|
|
* Must be called with call->master_lock held in W.
|
|
|
|
|
*/
|
|
|
|
|
struct call_monologue *__monologue_create(struct call *call) {
|
|
|
|
|
struct call_monologue *__monologue_create(call_t *call) {
|
|
|
|
|
struct call_monologue *ret;
|
|
|
|
|
|
|
|
|
|
__C_DBG("creating new monologue");
|
|
|
|
|
@ -4098,7 +4098,7 @@ struct call_monologue *__monologue_create(struct call *call) {
|
|
|
|
|
* Must be called with call->master_lock held in W.
|
|
|
|
|
*/
|
|
|
|
|
void __monologue_tag(struct call_monologue *ml, const str *tag) {
|
|
|
|
|
struct call *call = ml->call;
|
|
|
|
|
call_t *call = ml->call;
|
|
|
|
|
|
|
|
|
|
__C_DBG("tagging monologue with '"STR_FORMAT"'", STR_FMT(tag));
|
|
|
|
|
if (ml->tag.s)
|
|
|
|
|
@ -4108,7 +4108,7 @@ void __monologue_tag(struct call_monologue *ml, const str *tag) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void __monologue_viabranch(struct call_monologue *ml, const str *viabranch) {
|
|
|
|
|
struct call *call = ml->call;
|
|
|
|
|
call_t *call = ml->call;
|
|
|
|
|
|
|
|
|
|
if (!viabranch || !viabranch->len)
|
|
|
|
|
return;
|
|
|
|
|
@ -4221,7 +4221,7 @@ static void __tags_unassociate_all(struct call_monologue *a) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void monologue_destroy(struct call_monologue *monologue) {
|
|
|
|
|
struct call *call;
|
|
|
|
|
call_t *call;
|
|
|
|
|
|
|
|
|
|
call = monologue->call;
|
|
|
|
|
|
|
|
|
|
@ -4269,7 +4269,7 @@ static void __tags_unassociate(struct call_monologue *a, struct call_monologue *
|
|
|
|
|
* Returns `true`, if we need to update Redis.
|
|
|
|
|
*/
|
|
|
|
|
static bool monologue_delete_iter(struct call_monologue *a, int delete_delay) {
|
|
|
|
|
struct call *call = a->call;
|
|
|
|
|
call_t *call = a->call;
|
|
|
|
|
if (!call)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
@ -4311,7 +4311,7 @@ static bool monologue_delete_iter(struct call_monologue *a, int delete_delay) {
|
|
|
|
|
*
|
|
|
|
|
* Must be called with call->master_lock held in W.
|
|
|
|
|
*/
|
|
|
|
|
struct call_monologue *call_get_monologue(struct call *call, const str *fromtag) {
|
|
|
|
|
struct call_monologue *call_get_monologue(call_t *call, const str *fromtag) {
|
|
|
|
|
return g_hash_table_lookup(call->tags, fromtag);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -4321,7 +4321,7 @@ struct call_monologue *call_get_monologue(struct call *call, const str *fromtag)
|
|
|
|
|
*
|
|
|
|
|
* Must be called with call->master_lock held in W.
|
|
|
|
|
*/
|
|
|
|
|
struct call_monologue *call_get_or_create_monologue(struct call *call, const str *fromtag) {
|
|
|
|
|
struct call_monologue *call_get_or_create_monologue(call_t *call, const str *fromtag) {
|
|
|
|
|
struct call_monologue *ret = call_get_monologue(call, fromtag);
|
|
|
|
|
if (!ret) {
|
|
|
|
|
ret = __monologue_create(call);
|
|
|
|
|
@ -4348,7 +4348,7 @@ static void __tags_associate(struct call_monologue *a, struct call_monologue *b)
|
|
|
|
|
/**
|
|
|
|
|
* Check whether the call object contains some other monologues, which can have own associations.
|
|
|
|
|
*/
|
|
|
|
|
static bool call_monologues_associations_left(struct call * c) {
|
|
|
|
|
static bool call_monologues_associations_left(call_t * c) {
|
|
|
|
|
for (GList * l = c->monologues.head; l; l = l->next)
|
|
|
|
|
{
|
|
|
|
|
struct call_monologue * ml = l->data;
|
|
|
|
|
@ -4464,7 +4464,7 @@ static bool call_viabranch_intact_monologue(const str * viabranch, struct call_m
|
|
|
|
|
*
|
|
|
|
|
* `dialogue` must be initialised to zero.
|
|
|
|
|
*/
|
|
|
|
|
static int call_get_monologue_new(struct call_monologue *monologues[2], struct call *call,
|
|
|
|
|
static int call_get_monologue_new(struct call_monologue *monologues[2], call_t *call,
|
|
|
|
|
const str *fromtag,
|
|
|
|
|
const str *totag,
|
|
|
|
|
const str *viabranch)
|
|
|
|
|
@ -4568,7 +4568,7 @@ monologues_intact_finalize:
|
|
|
|
|
*
|
|
|
|
|
* `dialogue` must be initialised to zero.
|
|
|
|
|
*/
|
|
|
|
|
static int call_get_dialogue(struct call_monologue *monologues[2], struct call *call,
|
|
|
|
|
static int call_get_dialogue(struct call_monologue *monologues[2], call_t *call,
|
|
|
|
|
const str *fromtag,
|
|
|
|
|
const str *totag,
|
|
|
|
|
const str *viabranch)
|
|
|
|
|
@ -4657,7 +4657,7 @@ done:
|
|
|
|
|
/* fromtag and totag strictly correspond to the directionality of the message, not to the actual
|
|
|
|
|
* SIP headers. IOW, the fromtag corresponds to the monologue sending this message, even if the
|
|
|
|
|
* tag is actually from the TO header of the SIP message (as it would be in a 200 OK) */
|
|
|
|
|
int call_get_mono_dialogue(struct call_monologue *monologues[2], struct call *call,
|
|
|
|
|
int call_get_mono_dialogue(struct call_monologue *monologues[2], call_t *call,
|
|
|
|
|
const str *fromtag,
|
|
|
|
|
const str *totag,
|
|
|
|
|
const str *viabranch)
|
|
|
|
|
@ -4719,7 +4719,7 @@ static void monologue_stop(struct call_monologue *ml, bool stop_media_subsribers
|
|
|
|
|
|
|
|
|
|
// call must be locked in W.
|
|
|
|
|
// unlocks the call and releases the reference prior to returning, even on error.
|
|
|
|
|
int call_delete_branch(struct call *c, const str *branch,
|
|
|
|
|
int call_delete_branch(call_t *c, const str *branch,
|
|
|
|
|
const str *fromtag, const str *totag, bencode_item_t *output, int delete_delay)
|
|
|
|
|
{
|
|
|
|
|
struct call_monologue *ml;
|
|
|
|
|
@ -4851,7 +4851,7 @@ out:
|
|
|
|
|
int call_delete_branch_by_id(const str *callid, const str *branch,
|
|
|
|
|
const str *fromtag, const str *totag, bencode_item_t *output, int delete_delay)
|
|
|
|
|
{
|
|
|
|
|
struct call *c = call_get(callid);
|
|
|
|
|
call_t *c = call_get(callid);
|
|
|
|
|
if (!c) {
|
|
|
|
|
ilog(LOG_INFO, "Call-ID to delete not found");
|
|
|
|
|
return -1;
|
|
|
|
|
|