|
|
|
|
@ -191,6 +191,8 @@ static const struct mediaproxy_srtp __mps_null = {
|
|
|
|
|
|
|
|
|
|
static void call_destroy(struct call *);
|
|
|
|
|
static void unkernelize(struct peer *);
|
|
|
|
|
static void unconfirm(struct peer *);
|
|
|
|
|
static void unconfirm_cs(struct callstream *);
|
|
|
|
|
static void relays_cache_port_used(struct relays_cache *c);
|
|
|
|
|
static void ng_call_stats(struct call *call, const str *fromtag, const str *totag, bencode_item_t *output);
|
|
|
|
|
|
|
|
|
|
@ -1294,12 +1296,28 @@ fail:
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void setup_stream_families(struct callstream *cs, struct stream_input *s, int idx) {
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
|
|
|
switch (s->direction[i]) {
|
|
|
|
|
case DIR_INTERNAL:
|
|
|
|
|
cs->peers[i ^ idx].desired_family = AF_INET;
|
|
|
|
|
break;
|
|
|
|
|
case DIR_EXTERNAL:
|
|
|
|
|
cs->peers[i ^ idx].desired_family = AF_INET6;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* caller is responsible for appropriate locking */
|
|
|
|
|
static int setup_peer(struct peer *p, struct stream_input *s, const str *tag) {
|
|
|
|
|
struct streamrelay *a, *b;
|
|
|
|
|
struct callstream *cs;
|
|
|
|
|
struct call *ca;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
cs = p->up;
|
|
|
|
|
ca = cs->call;
|
|
|
|
|
@ -1307,12 +1325,8 @@ static int setup_peer(struct peer *p, struct stream_input *s, const str *tag) {
|
|
|
|
|
b = &p->rtps[1];
|
|
|
|
|
|
|
|
|
|
if (a->peer_advertised.port != s->stream.port
|
|
|
|
|
|| !IN6_ARE_ADDR_EQUAL(&a->peer_advertised.ip46, &s->stream.ip46)) {
|
|
|
|
|
cs->peers[0].confirmed = 0;
|
|
|
|
|
unkernelize(&cs->peers[0]);
|
|
|
|
|
cs->peers[1].confirmed = 0;
|
|
|
|
|
unkernelize(&cs->peers[1]);
|
|
|
|
|
}
|
|
|
|
|
|| !IN6_ARE_ADDR_EQUAL(&a->peer_advertised.ip46, &s->stream.ip46))
|
|
|
|
|
unconfirm_cs(cs);
|
|
|
|
|
|
|
|
|
|
a->peer = s->stream;
|
|
|
|
|
b->peer = s->stream;
|
|
|
|
|
@ -1326,18 +1340,7 @@ static int setup_peer(struct peer *p, struct stream_input *s, const str *tag) {
|
|
|
|
|
a->other->crypto.in = s->crypto;
|
|
|
|
|
b->other->crypto.in = s->crypto;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
|
|
|
switch (s->direction[i]) {
|
|
|
|
|
case DIR_INTERNAL:
|
|
|
|
|
cs->peers[i ^ p->idx].desired_family = AF_INET;
|
|
|
|
|
break;
|
|
|
|
|
case DIR_EXTERNAL:
|
|
|
|
|
cs->peers[i ^ p->idx].desired_family = AF_INET6;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
setup_stream_families(cs, s, p->idx);
|
|
|
|
|
|
|
|
|
|
call_str_cpy(ca, &p->tag, tag);
|
|
|
|
|
p->filled = 1;
|
|
|
|
|
@ -1364,10 +1367,8 @@ static void steal_peer(struct peer *dest, struct peer *src) {
|
|
|
|
|
mylog(LOG_DEBUG, LOG_PREFIX_CI "Re-using existing open RTP port %u",
|
|
|
|
|
LOG_PARAMS_CI(c), r->fd.localport);
|
|
|
|
|
|
|
|
|
|
dest->confirmed = 0;
|
|
|
|
|
unkernelize(dest);
|
|
|
|
|
src->confirmed = 0;
|
|
|
|
|
unkernelize(src);
|
|
|
|
|
unconfirm(dest);
|
|
|
|
|
unconfirm(src);
|
|
|
|
|
|
|
|
|
|
dest->filled = src->filled;
|
|
|
|
|
dest->tag = src->tag;
|
|
|
|
|
@ -1590,6 +1591,7 @@ static int call_streams(struct call *c, GQueue *s, const str *tag, enum call_opm
|
|
|
|
|
if (str_cmp_str0(&cs_o->peers[x].tag, tag))
|
|
|
|
|
continue;
|
|
|
|
|
DBG("found existing call stream to steal");
|
|
|
|
|
unconfirm_cs(cs_o);
|
|
|
|
|
goto found;
|
|
|
|
|
}
|
|
|
|
|
mutex_unlock(&cs_o->lock);
|
|
|
|
|
@ -1628,6 +1630,7 @@ found:
|
|
|
|
|
steal_peer(&cs->peers[0], &cs_o->peers[1]);
|
|
|
|
|
steal_peer(&cs->peers[1], &cs_o->peers[0]);
|
|
|
|
|
}
|
|
|
|
|
setup_stream_families(cs, t, 0);
|
|
|
|
|
mutex_unlock(&cs_o->lock);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -1658,6 +1661,7 @@ found:
|
|
|
|
|
got_cs:
|
|
|
|
|
/* cs and cs_o remain locked, and maybe cs == cs_o */
|
|
|
|
|
/* matched_relay == peer[x].rtp[0] of cs_o */
|
|
|
|
|
unconfirm_cs(cs);
|
|
|
|
|
g_queue_delete_link(c->callstreams, l); /* steal cs ref */
|
|
|
|
|
p = &cs->peers[1];
|
|
|
|
|
p2 = &cs->peers[0];
|
|
|
|
|
@ -1719,9 +1723,8 @@ got_cs:
|
|
|
|
|
g_queue_push_tail(c->callstreams, cs_o); /* hand over ref to original cs */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
time(&c->lookup_done);
|
|
|
|
|
|
|
|
|
|
skip:
|
|
|
|
|
time(&c->lookup_done);
|
|
|
|
|
g_queue_push_tail(q, p->up); /* hand over ref to cs */
|
|
|
|
|
mutex_unlock(&cs->lock);
|
|
|
|
|
if (cs_o && cs_o != cs)
|
|
|
|
|
@ -1752,6 +1755,15 @@ skip:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void unconfirm(struct peer *p) {
|
|
|
|
|
p->confirmed = 0;
|
|
|
|
|
unkernelize(p);
|
|
|
|
|
}
|
|
|
|
|
static void unconfirm_cs(struct callstream *cs) {
|
|
|
|
|
unconfirm(&cs->peers[0]);
|
|
|
|
|
unconfirm(&cs->peers[1]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void unkernelize(struct peer *p) {
|
|
|
|
|
struct streamrelay *r;
|
|
|
|
|
int i;
|
|
|
|
|
@ -1760,8 +1772,6 @@ static void unkernelize(struct peer *p) {
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
|
|
|
if (!p->kernelized)
|
|
|
|
|
continue;
|
|
|
|
|
r = &p->rtps[i];
|
|
|
|
|
if (r->no_kernel_support)
|
|
|
|
|
continue;
|
|
|
|
|
|