|
|
|
@ -1159,7 +1159,7 @@ static int call_streams(struct call *c, GQueue *s, const str *tag, enum call_opm |
|
|
|
GList *i, *l; |
|
|
|
struct stream_input *t; |
|
|
|
int x; |
|
|
|
struct streamrelay *r; |
|
|
|
struct streamrelay *matched_relay; |
|
|
|
struct callstream *cs, *cs_o; |
|
|
|
struct peer *p, *p2; |
|
|
|
int ret = 1; |
|
|
|
@ -1176,14 +1176,15 @@ static int call_streams(struct call *c, GQueue *s, const str *tag, enum call_opm |
|
|
|
cs_o = l->data; |
|
|
|
mutex_lock(&cs_o->lock); |
|
|
|
for (x = 0; x < 2; x++) { |
|
|
|
r = &cs_o->peers[x].rtps[0]; |
|
|
|
matched_relay = &cs_o->peers[x].rtps[0]; |
|
|
|
DBG("comparing new ["IP6F"]:%u/%.*s to old ["IP6F"]:%u/%.*s", |
|
|
|
IP6P(&t->stream.ip46), t->stream.port, STR_FMT(tag), |
|
|
|
IP6P(&r->peer_advertised.ip46), r->peer_advertised.port, STR_FMT(&cs_o->peers[x].tag)); |
|
|
|
IP6P(&matched_relay->peer_advertised.ip46), |
|
|
|
matched_relay->peer_advertised.port, STR_FMT(&cs_o->peers[x].tag)); |
|
|
|
|
|
|
|
if (!IN6_ARE_ADDR_EQUAL(&r->peer_advertised.ip46, &t->stream.ip46)) |
|
|
|
if (!IN6_ARE_ADDR_EQUAL(&matched_relay->peer_advertised.ip46, &t->stream.ip46)) |
|
|
|
continue; |
|
|
|
if (r->peer_advertised.port != t->stream.port) |
|
|
|
if (matched_relay->peer_advertised.port != t->stream.port) |
|
|
|
continue; |
|
|
|
if (str_cmp_str0(&cs_o->peers[x].tag, tag)) |
|
|
|
continue; |
|
|
|
@ -1194,7 +1195,7 @@ static int call_streams(struct call *c, GQueue *s, const str *tag, enum call_opm |
|
|
|
} |
|
|
|
|
|
|
|
/* not found */ |
|
|
|
r = NULL; |
|
|
|
matched_relay = NULL; |
|
|
|
cs_o = NULL; |
|
|
|
l = NULL; |
|
|
|
|
|
|
|
@ -1206,7 +1207,7 @@ found: |
|
|
|
cs = callstream_new(c, t->stream.num); |
|
|
|
mutex_lock(&cs->lock); |
|
|
|
|
|
|
|
if (!r) { |
|
|
|
if (!matched_relay) { |
|
|
|
/* nothing found to re-use, open new ports */ |
|
|
|
callstream_init(cs, 0, 0); |
|
|
|
p = &cs->peers[0]; |
|
|
|
@ -1215,7 +1216,7 @@ found: |
|
|
|
else { |
|
|
|
/* re-use, so don't open new ports */ |
|
|
|
callstream_init(cs, -1, -1); |
|
|
|
if (r->up->idx == 0) { |
|
|
|
if (matched_relay->up->idx == 0) { |
|
|
|
/* request/lookup came in the same order as before */ |
|
|
|
steal_peer(&cs->peers[0], &cs_o->peers[0]); |
|
|
|
steal_peer(&cs->peers[1], &cs_o->peers[1]); |
|
|
|
@ -1254,37 +1255,37 @@ found: |
|
|
|
|
|
|
|
got_cs: |
|
|
|
/* cs and cs_o remain locked, and maybe cs == cs_o */ |
|
|
|
/* r == peer[x].rtp[0] of cs_o */ |
|
|
|
/* matched_relay == peer[x].rtp[0] of cs_o */ |
|
|
|
g_queue_delete_link(c->callstreams, l); /* steal cs ref */ |
|
|
|
p = &cs->peers[1]; |
|
|
|
p2 = &cs->peers[0]; |
|
|
|
|
|
|
|
if (c->lookup_done && r) { |
|
|
|
if (c->lookup_done && matched_relay) { |
|
|
|
/* duplicate/stray lookup. don't do anything except replying with something |
|
|
|
we already have. check whether the direction is reversed or not and return |
|
|
|
the appropriate details. if no matching stream was found, results are |
|
|
|
undefined. */ |
|
|
|
DBG("double lookup"); |
|
|
|
if (p == r->up) |
|
|
|
if (p == matched_relay->up) |
|
|
|
goto skip; |
|
|
|
if (p2 == r->up) { |
|
|
|
if (p2 == matched_relay->up) { |
|
|
|
ret = -1; |
|
|
|
goto skip; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (r && p == r->up) { |
|
|
|
if (matched_relay && p == matched_relay->up) { |
|
|
|
/* best case, nothing to do */ |
|
|
|
DBG("case 1"); |
|
|
|
; |
|
|
|
} |
|
|
|
else if (r && cs_o != cs) { |
|
|
|
else if (matched_relay && cs_o != cs) { |
|
|
|
/* found something, but it's linked to a different stream */ |
|
|
|
DBG("case 2"); |
|
|
|
steal_peer(p, r->up); |
|
|
|
steal_peer(p, matched_relay->up); |
|
|
|
} |
|
|
|
else if (!r && !p->filled) { |
|
|
|
else if (!matched_relay && !p->filled) { |
|
|
|
/* nothing found to steal, but this end is open */ |
|
|
|
DBG("case 3"); |
|
|
|
setup_peer(p, t, tag); |
|
|
|
|