TT#85701 improve branch handling with delete-delay=0

Initially created branches don't have a tag associated with them, so
they don't appear in `other_tags`. We need to keep track of which
branches were created from a single from-tag through their via-branch
values so we know when all branches have been deleted.

closes #1037

Change-Id: I4c6ce602b99a9104de98098cd06ca399eb28e1b2
changes/69/41669/1
Richard Fuchs 5 years ago
parent 18830a1a5d
commit 8e22c9a414

@ -2526,6 +2526,7 @@ static void __call_free(void *p) {
g_queue_clear(&m->medias);
g_hash_table_destroy(m->other_tags);
g_hash_table_destroy(m->branches);
g_hash_table_destroy(m->media_ids);
g_slice_free1(sizeof(*m), m);
}
@ -2673,6 +2674,7 @@ struct call_monologue *__monologue_create(struct call *call) {
ret->call = call;
ret->created = rtpe_now.tv_sec;
ret->other_tags = g_hash_table_new(str_hash, str_equal);
ret->branches = g_hash_table_new(str_hash, str_equal);
ret->media_ids = g_hash_table_new(str_hash, str_equal);
g_queue_init(&ret->medias);
@ -2693,15 +2695,21 @@ 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;
struct call_monologue *other = ml->active_dialogue;
if (!viabranch)
if (!viabranch || !viabranch->len)
return;
__C_DBG("tagging monologue with viabranch '"STR_FORMAT"'", STR_FMT(viabranch));
if (ml->viabranch.s)
if (ml->viabranch.s) {
g_hash_table_remove(call->viabranches, &ml->viabranch);
if (other)
g_hash_table_remove(other->branches, &ml->viabranch);
}
call_str_cpy(call, &ml->viabranch, viabranch);
g_hash_table_insert(call->viabranches, &ml->viabranch, ml);
if (other)
g_hash_table_insert(other->branches, &ml->viabranch, ml);
}
/* must be called with call->master_lock held in W */
@ -2750,6 +2758,10 @@ static void __monologue_destroy(struct call_monologue *monologue, int recurse) {
call = monologue->call;
ilog(LOG_DEBUG, "Destroying monologue '" STR_FORMAT "' (" STR_FORMAT ")",
STR_FMT(&monologue->tag),
STR_FMT0(&monologue->viabranch));
g_hash_table_remove(call->tags, &monologue->tag);
if (monologue->viabranch.s)
g_hash_table_remove(call->viabranches, &monologue->viabranch);
@ -2759,12 +2771,16 @@ static void __monologue_destroy(struct call_monologue *monologue, int recurse) {
if (dialogue == monologue)
continue;
if (dialogue->active_dialogue != monologue
if (monologue->tag.len
&& !g_hash_table_lookup(dialogue->other_tags, &monologue->tag))
continue;
if (monologue->viabranch.len
&& !g_hash_table_lookup(dialogue->branches, &monologue->viabranch))
continue;
g_hash_table_remove(dialogue->other_tags, &monologue->tag);
if (recurse && !g_hash_table_size(dialogue->other_tags))
g_hash_table_remove(dialogue->branches, &monologue->viabranch);
if (recurse && !g_hash_table_size(dialogue->other_tags) && !g_hash_table_size(dialogue->branches))
__monologue_destroy(dialogue, 0);
}

@ -1403,6 +1403,16 @@ static int json_link_tags(struct call *c, struct redis_list *tags, struct redis_
}
g_queue_clear(&q);
if (json_build_list(&q, c, "branches", &c->callid, i, tags, root_reader))
return -1;
for (l = q.head; l; l = l->next) {
other_ml = l->data;
if (!other_ml)
return -1;
g_hash_table_insert(ml->branches, &other_ml->viabranch, other_ml);
}
g_queue_clear(&q);
if (json_build_list(&ml->medias, c, "medias", &c->callid, i, medias, root_reader))
return -1;
}
@ -2026,6 +2036,18 @@ char* redis_encode_json(struct call *c) {
g_list_free(k);
k = g_hash_table_get_values(ml->branches);
snprintf(tmp, sizeof(tmp), "branches-%u", ml->unique_id);
json_builder_set_member_name(builder, tmp);
json_builder_begin_array (builder);
for (m = k; m; m = m->next) {
ml2 = m->data;
JSON_ADD_STRING("%u",ml2->unique_id);
}
json_builder_end_array (builder);
g_list_free(k);
snprintf(tmp, sizeof(tmp), "medias-%u", ml->unique_id);
json_builder_set_member_name(builder, tmp);
json_builder_begin_array (builder);

@ -357,6 +357,7 @@ struct call_monologue {
struct timeval terminated; /* for CDR */
enum termination_reason term_reason;
GHashTable *other_tags;
GHashTable *branches;
struct call_monologue *active_dialogue;
GQueue medias;
GHashTable *media_ids;

@ -120,6 +120,7 @@ sub offer_answer {
$regexp =~ s/CRYPTO192/([0-9a-zA-Z\/+]{51})/gs;
$regexp =~ s/CRYPTO256/([0-9a-zA-Z\/+]{62})/gs;
$regexp =~ s/LOOPER/([0-9a-f]{12})/gs;
$regexp =~ s/FINGERPRINT/([0-9a-fA-F:]{59})/gs;
my $crlf = crlf($resp->{sdp});
like $crlf, qr/$regexp/s, "$name - output '$cmd' SDP";
my @matches = $crlf =~ qr/$regexp/s;

@ -112,6 +112,244 @@ rcv($sock_d, -1, qr/^\x16\xfe\xff\x00\x00\x00\x00\x00\x00\x00/);
# GH 1037
new_call;
offer('rtcp-mux branched w delete-delay', {
ICE => 'remove',
SDES => 'off',
'via-branch' => 'foo.0',
'transport-protocol' => 'RTP/SAVPF',
'rtcp-mux' => ['offer'],
}, <<SDP);
v=0
o=root 1965229132 1965229132 IN IP4 172.31.30.143
s=Wildix 5.02.20200622.2~8ea32507
c=IN IP4 172.31.30.143
t=0 0
m=audio 35972 RTP/AVPF 8 0
a=rtpmap:8 PCMA/8000
a=rtpmap:0 PCMU/8000
a=ptime:20
a=sendrecv
----------------------------------
v=0
o=root 1965229132 1965229132 IN IP4 172.31.30.143
s=Wildix 5.02.20200622.2~8ea32507
c=IN IP4 203.0.113.1
t=0 0
m=audio PORT RTP/SAVPF 8 0
a=rtpmap:8 PCMA/8000
a=rtpmap:0 PCMU/8000
a=sendrecv
a=rtcp:PORT
a=rtcp-mux
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:CRYPTO128
a=crypto:2 AES_CM_128_HMAC_SHA1_32 inline:CRYPTO128
a=crypto:3 AES_192_CM_HMAC_SHA1_80 inline:CRYPTO192
a=crypto:4 AES_192_CM_HMAC_SHA1_32 inline:CRYPTO192
a=crypto:5 AES_256_CM_HMAC_SHA1_80 inline:CRYPTO256
a=crypto:6 AES_256_CM_HMAC_SHA1_32 inline:CRYPTO256
a=crypto:7 F8_128_HMAC_SHA1_80 inline:CRYPTO128
a=crypto:8 F8_128_HMAC_SHA1_32 inline:CRYPTO128
a=crypto:9 NULL_HMAC_SHA1_80 inline:CRYPTO128
a=crypto:10 NULL_HMAC_SHA1_32 inline:CRYPTO128
a=setup:actpass
a=fingerprint:sha-1 FINGERPRINT
a=ptime:20
SDP
offer('rtcp-mux branched w delete-delay', {
ICE => 'remove',
SDES => 'off',
'via-branch' => 'foo.1',
'transport-protocol' => 'RTP/AVP',
'rtcp-mux' => ['demux'],
}, <<SDP);
v=0
o=root 1965229132 1965229132 IN IP4 172.31.30.143
s=Wildix 5.02.20200622.2~8ea32507
c=IN IP4 172.31.30.143
t=0 0
m=audio 35972 RTP/AVPF 8 0
a=rtpmap:8 PCMA/8000
a=rtpmap:0 PCMU/8000
a=ptime:20
a=sendrecv
----------------------------------
v=0
o=root 1965229132 1965229132 IN IP4 172.31.30.143
s=Wildix 5.02.20200622.2~8ea32507
c=IN IP4 203.0.113.1
t=0 0
m=audio PORT RTP/AVP 8 0
a=rtpmap:8 PCMA/8000
a=rtpmap:0 PCMU/8000
a=sendrecv
a=rtcp:PORT
a=ptime:20
SDP
rtpe_req('delete', 'rtcp-mux branched w delete-delay', { 'from-tag' => ft(), 'via-branch' => 'foo.1' });
answer('rtcp-mux branched w delete-delay', {
ICE => 'remove',
SDES => 'off',
'via-branch' => 'foo.0',
'transport-protocol' => 'RTP/AVPF',
'rtcp-mux' => ['demux'],
}, <<SDP);
v=0
o=- 8520494338200249002 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE audio video
m=audio 63849 UDP/TLS/RTP/SAVPF 0
c=IN IP4 192.168.31.106
a=rtcp:9 IN IP4 0.0.0.0
a=fingerprint:sha-256 B5:CF:61:F3:C5:DF:F6:11:BF:B2:B5:1A:02:54:A1:2A:4A:B5:9E:1F:FF:C0:AA:96:16:9C:59:49:76:09:63:0B
a=setup:active
a=mid:audio
a=sendrecv
a=rtcp-mux
----------------------------------
v=0
o=- 8520494338200249002 2 IN IP4 127.0.0.1
s=-
t=0 0
m=audio PORT RTP/AVPF 0
c=IN IP4 203.0.113.1
a=rtpmap:0 PCMU/8000
a=sendrecv
a=rtcp:PORT
a=ptime:20
SDP
new_call;
offer('rtcp-mux branched delete-delay=0', {
ICE => 'remove',
SDES => 'off',
'via-branch' => 'foo.0',
'transport-protocol' => 'RTP/SAVPF',
'rtcp-mux' => ['offer'],
}, <<SDP);
v=0
o=root 1965229132 1965229132 IN IP4 172.31.30.143
s=Wildix 5.02.20200622.2~8ea32507
c=IN IP4 172.31.30.143
t=0 0
m=audio 35972 RTP/AVPF 8 0
a=rtpmap:8 PCMA/8000
a=rtpmap:0 PCMU/8000
a=ptime:20
a=sendrecv
----------------------------------
v=0
o=root 1965229132 1965229132 IN IP4 172.31.30.143
s=Wildix 5.02.20200622.2~8ea32507
c=IN IP4 203.0.113.1
t=0 0
m=audio PORT RTP/SAVPF 8 0
a=rtpmap:8 PCMA/8000
a=rtpmap:0 PCMU/8000
a=sendrecv
a=rtcp:PORT
a=rtcp-mux
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:CRYPTO128
a=crypto:2 AES_CM_128_HMAC_SHA1_32 inline:CRYPTO128
a=crypto:3 AES_192_CM_HMAC_SHA1_80 inline:CRYPTO192
a=crypto:4 AES_192_CM_HMAC_SHA1_32 inline:CRYPTO192
a=crypto:5 AES_256_CM_HMAC_SHA1_80 inline:CRYPTO256
a=crypto:6 AES_256_CM_HMAC_SHA1_32 inline:CRYPTO256
a=crypto:7 F8_128_HMAC_SHA1_80 inline:CRYPTO128
a=crypto:8 F8_128_HMAC_SHA1_32 inline:CRYPTO128
a=crypto:9 NULL_HMAC_SHA1_80 inline:CRYPTO128
a=crypto:10 NULL_HMAC_SHA1_32 inline:CRYPTO128
a=setup:actpass
a=fingerprint:sha-1 FINGERPRINT
a=ptime:20
SDP
offer('rtcp-mux branched delete-delay=0', {
ICE => 'remove',
SDES => 'off',
'via-branch' => 'foo.1',
'transport-protocol' => 'RTP/AVP',
'rtcp-mux' => ['demux'],
}, <<SDP);
v=0
o=root 1965229132 1965229132 IN IP4 172.31.30.143
s=Wildix 5.02.20200622.2~8ea32507
c=IN IP4 172.31.30.143
t=0 0
m=audio 35972 RTP/AVPF 8 0
a=rtpmap:8 PCMA/8000
a=rtpmap:0 PCMU/8000
a=ptime:20
a=sendrecv
----------------------------------
v=0
o=root 1965229132 1965229132 IN IP4 172.31.30.143
s=Wildix 5.02.20200622.2~8ea32507
c=IN IP4 203.0.113.1
t=0 0
m=audio PORT RTP/AVP 8 0
a=rtpmap:8 PCMA/8000
a=rtpmap:0 PCMU/8000
a=sendrecv
a=rtcp:PORT
a=ptime:20
SDP
rtpe_req('delete', 'rtcp-mux branched delete-delay=0', {
'from-tag' => ft(), 'via-branch' => 'foo.1',
'delete-delay' => 0,
});
answer('rtcp-mux branched delete-delay=0', {
ICE => 'remove',
SDES => 'off',
'via-branch' => 'foo.0',
'transport-protocol' => 'RTP/AVPF',
'rtcp-mux' => ['demux'],
}, <<SDP);
v=0
o=- 8520494338200249002 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE audio video
m=audio 63849 UDP/TLS/RTP/SAVPF 0
c=IN IP4 192.168.31.106
a=rtcp:9 IN IP4 0.0.0.0
a=fingerprint:sha-256 B5:CF:61:F3:C5:DF:F6:11:BF:B2:B5:1A:02:54:A1:2A:4A:B5:9E:1F:FF:C0:AA:96:16:9C:59:49:76:09:63:0B
a=setup:active
a=mid:audio
a=sendrecv
a=rtcp-mux
----------------------------------
v=0
o=- 8520494338200249002 2 IN IP4 127.0.0.1
s=-
t=0 0
m=audio PORT RTP/AVPF 0
c=IN IP4 203.0.113.1
a=rtpmap:0 PCMU/8000
a=sendrecv
a=rtcp:PORT
a=ptime:20
SDP
# RTP to SRTP switch (and SRTP re-invite) TT#81850
new_call;

Loading…
Cancel
Save