MT#55283 decouple SDP origin settings

Move o= replacement logic into sdp_out_add_origin. Copy fields from
input source ML if present, or keep unchanged. Generate if not present.

Change-Id: Ieea5abea05bf076262248639118e9e9192f77e1c
pull/2056/head
Richard Fuchs 2 months ago
parent e948e5a976
commit 52b19f400b

@ -1589,8 +1589,6 @@ static int redis_tags(call_t *c, struct redis_list *tags, parser_arg arg) {
ml->sdp_orig_in.username = call_str_cpy(&s);
if (!redis_hash_get_str(&s, rh, "sdp_orig_session_id"))
ml->sdp_orig_in.session_id = call_str_cpy(&s);
if (!redis_hash_get_str(&s, rh, "sdp_orig_version_str"))
ml->sdp_orig_in.version_str = call_str_cpy(&s);
if (!redis_hash_get_str(&s, rh, "sdp_orig_address_network_type"))
ml->sdp_orig_in.address.network_type = call_str_cpy(&s);
if (!redis_hash_get_str(&s, rh, "sdp_orig_address_address_type"))
@ -1606,8 +1604,6 @@ static int redis_tags(call_t *c, struct redis_list *tags, parser_arg arg) {
ml->sdp_orig_out.username = call_str_cpy(&s);
if (!redis_hash_get_str(&s, rh, "last_sdp_orig_session_id"))
ml->sdp_orig_out.session_id = call_str_cpy(&s);
if (!redis_hash_get_str(&s, rh, "last_sdp_orig_version_str"))
ml->sdp_orig_out.version_str = call_str_cpy(&s);
if (!redis_hash_get_str(&s, rh, "last_sdp_orig_address_network_type"))
ml->sdp_orig_out.address.network_type = call_str_cpy(&s);
if (!redis_hash_get_str(&s, rh, "last_sdp_orig_address_address_type"))
@ -2652,7 +2648,6 @@ static str redis_encode_json(ng_parser_ctx_t *ctx, call_t *c, void **to_free) {
if (ml->sdp_orig_in.parsed) {
JSON_SET_SIMPLE_STR("sdp_orig_username", &ml->sdp_orig_in.username);
JSON_SET_SIMPLE_STR("sdp_orig_session_id", &ml->sdp_orig_in.session_id);
JSON_SET_SIMPLE_STR("sdp_orig_version_str", &ml->sdp_orig_in.version_str);
JSON_SET_SIMPLE("sdp_orig_version_num", "%llu", ml->sdp_orig_in.version_num);
JSON_SET_SIMPLE("sdp_orig_parsed", "%u", ml->sdp_orig_in.parsed);
JSON_SET_SIMPLE_STR("sdp_orig_address_network_type", &ml->sdp_orig_in.address.network_type);
@ -2662,7 +2657,6 @@ static str redis_encode_json(ng_parser_ctx_t *ctx, call_t *c, void **to_free) {
if (ml->sdp_orig_out.parsed) {
JSON_SET_SIMPLE_STR("last_sdp_orig_username", &ml->sdp_orig_out.username);
JSON_SET_SIMPLE_STR("last_sdp_orig_session_id", &ml->sdp_orig_out.session_id);
JSON_SET_SIMPLE_STR("last_sdp_orig_version_str", &ml->sdp_orig_out.version_str);
JSON_SET_SIMPLE("last_sdp_orig_version_num", "%llu", ml->sdp_orig_out.version_num);
JSON_SET_SIMPLE("last_sdp_orig_parsed", "%u", ml->sdp_orig_out.parsed);
JSON_SET_SIMPLE_STR("last_sdp_orig_address_network_type", &ml->sdp_orig_out.address.network_type);

@ -1905,7 +1905,6 @@ sdp_origin sdp_orig_dup(const sdp_origin *orig) {
sdp_origin copy = {};
copy.username = call_str_cpy(&orig->username);
copy.session_id = call_str_cpy(&orig->session_id);
copy.version_str = call_str_cpy(&orig->version_str);
copy.version_num = orig->version_num;
copy.version_output_pos = orig->version_output_pos;
copy.parsed = orig->parsed;
@ -2706,29 +2705,28 @@ static void insert_rtcp_attr(GString *s, struct packet_stream *ps, const sdp_ng_
/**
* Handle sdp version replacements.
*/
static void sdp_version_replace(GString *s, sdp_origin *src_orig, sdp_origin *other_orig)
static void sdp_version_increase(GString *s, sdp_origin *origin)
{
char version_str[64];
snprintf(version_str, sizeof(version_str), "%llu", src_orig->version_num);
size_t version_len = strlen(version_str);
snprintf(version_str, sizeof(version_str), "%llu", origin->version_num);
size_t old_version_len = strlen(version_str);
if (!other_orig)
return;
origin->version_num++;
snprintf(version_str, sizeof(version_str), "%llu", origin->version_num);
size_t version_len = strlen(version_str);
other_orig->version_num = src_orig->version_num;
/* is our new value longer? */
if (version_len > other_orig->version_str.len) {
if (version_len > old_version_len) {
/* overwrite + insert */
g_string_overwrite_len(s, other_orig->version_output_pos, version_str, other_orig->version_str.len);
g_string_insert(s, other_orig->version_output_pos + other_orig->version_str.len, version_str + other_orig->version_str.len);
other_orig->version_str.len = version_len;
g_string_overwrite_len(s, origin->version_output_pos, version_str, old_version_len);
g_string_insert(s, origin->version_output_pos + old_version_len, version_str + old_version_len);
}
else {
/* overwrite + optional erase */
g_string_overwrite(s, other_orig->version_output_pos, version_str);
if (version_len < other_orig->version_str.len) {
g_string_erase(s, other_orig->version_output_pos + version_len, other_orig->version_str.len - version_len);
other_orig->version_str.len = version_len;
g_string_overwrite(s, origin->version_output_pos, version_str);
if (version_len < old_version_len) {
g_string_erase(s, origin->version_output_pos + version_len, old_version_len - version_len);
}
}
}
@ -2736,40 +2734,19 @@ static void sdp_version_replace(GString *s, sdp_origin *src_orig, sdp_origin *ot
/**
* SDP session version manipulations.
*/
static void sdp_version_check(GString *s, struct call_monologue *monologue,
struct call_monologue *source_ml,
bool force_increase)
{
static void sdp_version_check(GString *s, struct call_monologue *monologue) {
if (!monologue->sdp_orig_out.parsed)
return;
sdp_origin *origin = &monologue->sdp_orig_out;
sdp_origin *other_origin = NULL;
if (source_ml && source_ml->sdp_orig_in.parsed)
other_origin = &source_ml->sdp_orig_in;
/* We really expect only a single session here, but we treat all the same regardless,
* and use the same version number on all of them */
/* First update all versions to match our single version */
sdp_version_replace(s, origin, other_origin);
/* Now check if we need to change the version actually.
* The version change will be forced with the 'force_increase',
* and it gets incremented, regardless whether:
* - we have no previously stored SDP,
* - we have previous SDP and it's equal to the current one */
if (!force_increase) {
if (!monologue->last_out_sdp)
goto dup;
if (g_string_equal(monologue->last_out_sdp, s))
return;
}
if (!monologue->last_out_sdp)
goto dup;
if (g_string_equal(monologue->last_out_sdp, s))
return;
/* mismatch detected. increment version, update again, and store copy */
origin->version_num++;
sdp_version_replace(s, origin, other_origin);
sdp_version_increase(s, origin);
if (monologue->last_out_sdp)
g_string_free(monologue->last_out_sdp, TRUE);
dup:
@ -3006,56 +2983,81 @@ static void sdp_out_add_origin(GString *out, struct call_monologue *monologue,
struct call_monologue *source_ml,
struct packet_stream *first_ps, sdp_ng_flags *flags)
{
__auto_type ml = source_ml;
if (!ml)
ml = monologue;
/* orig username
* session_last_sdp_orig is stored on the other media always,
* so if origin is meant for the A media, then it is stored on the B one */
str * orig_username = (monologue->sdp_orig_out.parsed &&
(flags->replace_username || flags->replace_origin_full)) ?
&monologue->sdp_orig_out.username : &ml->sdp_orig_in.username;
/* orig session id */
str * orig_session_id = (monologue->sdp_orig_out.parsed && flags->replace_origin_full) ?
&monologue->sdp_orig_out.session_id : &ml->sdp_orig_in.session_id;
/* orig session ver
* replacement is handled later in sdp_create() based on SDP changes */
unsigned long long orig_session_version = ml->sdp_orig_in.version_num;
/* origin username */
str username = STR_NULL;
if (source_ml && !(flags->replace_username || flags->replace_origin_full))
username = source_ml->sdp_orig_in.username;
if (!username.len && monologue->sdp_orig_out.parsed)
username = monologue->sdp_orig_out.username;
if (!username.len && source_ml)
username = source_ml->sdp_orig_in.username;
if (!username.len)
username = STR("-");
/* origin session id */
str session_id = STR_NULL;
char id_buf[64];
if (source_ml && !flags->replace_origin_full)
session_id = source_ml->sdp_orig_in.session_id;
if (!session_id.len && monologue->sdp_orig_out.parsed)
session_id = monologue->sdp_orig_out.session_id;
if (!session_id.len && source_ml)
session_id = source_ml->sdp_orig_in.session_id;
if (!session_id.len) {
snprintf(id_buf, sizeof(id_buf), "%" PRId64, (rtpe_now & 0xfffffffL) + 1);
session_id = STR(id_buf);
}
/* origin session ver */
unsigned long long session_version;
if (monologue->sdp_orig_out.parsed && flags->force_inc_sdp_ver)
session_version = monologue->sdp_orig_out.version_num + 1;
else if (monologue->sdp_orig_out.parsed
&& (flags->replace_sdp_version || flags->replace_origin_full))
session_version = monologue->sdp_orig_out.version_num;
else if (source_ml)
session_version = source_ml->sdp_orig_in.version_num;
else if (monologue->sdp_orig_out.parsed)
session_version = monologue->sdp_orig_out.version_num;
else
session_version = (ssl_random() & 0xfffffffL) + 1;
/* record origin version position for replacements
* + 4 - means: `o=` + 2 spaces between username and version / version and id */
ml->sdp_orig_in.version_output_pos = out->len + orig_username->len + orig_session_id->len + 4;
size_t version_output_pos = out->len + username.len + session_id.len + 4;
/* orig IP family and address */
str orig_address_type;
str orig_address;
if (!source_ml || flags->replace_origin || flags->replace_origin_full) {
/* replacing flags or PUBLISH */
if (source_ml && !(flags->replace_origin || flags->replace_origin_full)) {
orig_address_type = source_ml->sdp_orig_in.address.address_type;
orig_address = source_ml->sdp_orig_in.address.address;
}
else if (monologue->sdp_orig_out.parsed) {
orig_address_type = monologue->sdp_orig_out.address.address_type;
orig_address = monologue->sdp_orig_out.address.address;
}
else {
orig_address_type = STR(first_ps->selected_sfd->local_intf->advertised_address.addr.family->rfc_name);
orig_address = STR(sockaddr_print_buf(&first_ps->selected_sfd->local_intf->advertised_address.addr));
} else {
orig_address_type = ml->sdp_orig_in.address.address_type;
orig_address = ml->sdp_orig_in.address.address;
}
if (!monologue->sdp_orig_out.parsed)
monologue->sdp_orig_out = sdp_orig_dup(&(sdp_origin) {
.username = *orig_username,
.session_id = *orig_session_id,
.version_num = orig_session_version,
.address.address_type = orig_address_type,
.address.address = orig_address,
.parsed = 1,
});
monologue->sdp_orig_out = sdp_orig_dup(&(sdp_origin) {
.username = username,
.session_id = session_id,
.version_num = session_version,
.address.address_type = orig_address_type,
.address.address = orig_address,
.version_output_pos = version_output_pos,
.parsed = 1,
});
/* print it to the output sdp */
g_string_append_printf(out,
"o="STR_FORMAT" "STR_FORMAT" %llu IN "STR_FORMAT" "STR_FORMAT"\r\n",
STR_FMT(orig_username),
STR_FMT(orig_session_id),
orig_session_version,
STR_FMT(&username),
STR_FMT(&session_id),
session_version,
STR_FMT(&orig_address_type),
STR_FMT(&orig_address));
}
@ -3551,13 +3553,8 @@ bool sdp_create(str *out, struct call_monologue *monologue, sdp_ng_flags *flags)
sdp_manipulations_add(s, sdp_manipulations);
}
/* The SDP version gets increased in case:
* - if replace_sdp_version (sdp-version) or replace_origin_full flag is set and SDP information has been updated, or
* - if the force_inc_sdp_ver (force-increment-sdp-ver) flag is set additionally to replace_sdp_version,
* which forces version increase regardless changes in the SDP information.
*/
if (flags->force_inc_sdp_ver || flags->replace_sdp_version || flags->replace_origin_full)
sdp_version_check(s, monologue, source_ml, !!flags->force_inc_sdp_ver);
if (flags->replace_sdp_version || flags->replace_origin_full)
sdp_version_check(s, monologue);
out->len = s->len;
out->s = g_string_free(s, FALSE);

@ -119,7 +119,7 @@ t=0 0
m=audio 6000 RTP/AVP 0 8
----------------------------------
v=0
o=- 1545997027 1 IN IP4 203.0.113.6
o=- SDP_VERSION IN IP4 203.0.113.6
s=RTPE_VERSION
t=0 0
m=audio PORT RTP/AVP 0
@ -147,7 +147,7 @@ t=0 0
m=audio 6000 RTP/AVP 0 8
----------------------------------
v=0
o=- 1545997027 1 IN IP4 203.0.113.6
o=- SDP_VERSION IN IP4 203.0.113.6
s=RTPE_VERSION
t=0 0
m=audio PORT RTP/AVP 0
@ -176,7 +176,7 @@ t=0 0
m=audio 6000 RTP/AVP 0 8
----------------------------------
v=0
o=- 1545997027 1 IN IP4 203.0.113.6
o=- SDP_VERSION IN IP4 203.0.113.6
s=RTPE_VERSION
t=0 0
m=audio PORT RTP/AVP 0
@ -206,7 +206,7 @@ t=0 0
m=audio 6000 RTP/AVP 0 8
----------------------------------
v=0
o=- 1545997027 1 IN IP4 203.0.113.6
o=- SDP_VERSION IN IP4 203.0.113.6
s=RTPE_VERSION
t=0 0
m=audio PORT RTP/AVP 0

@ -137,7 +137,6 @@ SDP
new_call;
# there is no 'monologue->last_out_sdp', but the version still gets increased
offer('SDP version force increase', { replace => ['force-increment-sdp-ver'] }, <<SDP);
v=0
o=- 1545997027 1 IN IP4 198.51.100.1
@ -147,7 +146,7 @@ m=audio 2000 RTP/AVP 0
c=IN IP4 198.51.100.1
----------------------------
v=0
o=- 1545997027 2 IN IP4 198.51.100.1
o=- 1545997027 1 IN IP4 198.51.100.1
s=tester
t=0 0
m=audio PORT RTP/AVP 0
@ -157,8 +156,6 @@ a=sendrecv
a=rtcp:PORT
SDP
# there is 'monologue->last_out_sdp' and it's equal to the newly given SDP,
# but the version still gets increased
offer('SDP version force increase', { replace => ['force-increment-sdp-ver'] }, <<SDP);
v=0
o=- 1545997027 2 IN IP4 198.51.100.1
@ -168,6 +165,25 @@ m=audio 2000 RTP/AVP 0
c=IN IP4 198.51.100.1
----------------------------
v=0
o=- 1545997027 2 IN IP4 198.51.100.1
s=tester
t=0 0
m=audio PORT RTP/AVP 0
c=IN IP4 203.0.113.1
a=rtpmap:0 PCMU/8000
a=sendrecv
a=rtcp:PORT
SDP
offer('SDP version force increase', { replace => ['force-increment-sdp-ver'] }, <<SDP);
v=0
o=- 1545997027 3 IN IP4 198.51.100.1
s=tester
t=0 0
m=audio 2002 RTP/AVP 0
c=IN IP4 198.51.100.1
----------------------------
v=0
o=- 1545997027 3 IN IP4 198.51.100.1
s=tester
t=0 0
@ -178,8 +194,6 @@ a=sendrecv
a=rtcp:PORT
SDP
# there is 'monologue->last_out_sdp' and it's not equal to the newly given SDP,
# and the version gets increased, as if that would be increased with 'sdp-version'.
offer('SDP version force increase', { replace => ['force-increment-sdp-ver'] }, <<SDP);
v=0
o=- 1545997027 3 IN IP4 198.51.100.1

@ -589,7 +589,7 @@ class TestVideoroom(unittest.TestCase):
sdp,
re.compile(
"^v=0\r\n"
"o=x \\d+ \\d+ IN IP4 203.0.113.1\r\n"
"o=- \\d+ \\d+ IN IP4 203.0.113.1\r\n"
"s=rtpengine.*?\r\n"
"t=0 0\r\n"
"m=audio \\d+ RTP/AVP 8\r\n"
@ -875,7 +875,7 @@ class TestVideoroom(unittest.TestCase):
sdp,
re.compile(
"^v=0\r\n"
"o=x \\d+ \\d+ IN IP4 203.0.113.1\r\n"
"o=- \\d+ \\d+ IN IP4 203.0.113.1\r\n"
"s=rtpengine.*?\r\n"
"t=0 0\r\n"
"m=audio \\d+ RTP/AVP 8\r\n"
@ -1143,7 +1143,7 @@ class TestVideoroom(unittest.TestCase):
sdp,
re.compile(
"^v=0\r\n"
"o=x \\d+ \\d+ IN IP4 203.0.113.1\r\n"
"o=- \\d+ \\d+ IN IP4 203.0.113.1\r\n"
"s=rtpengine.*?\r\n"
"t=0 0\r\n"
"m=audio \\d+ RTP/SAVP 8\r\n"
@ -1242,7 +1242,7 @@ class TestVideoroom(unittest.TestCase):
sdp,
re.compile(
"^v=0\r\n"
"o=x \\d+ \\d+ IN IP4 203.0.113.1\r\n"
"o=- \\d+ \\d+ IN IP4 203.0.113.1\r\n"
"s=rtpengine.*?\r\n"
"t=0 0\r\n"
"m=audio \\d+ RTP/SAVP 8\r\n"
@ -1338,7 +1338,7 @@ class TestVideoroom(unittest.TestCase):
sdp,
re.compile(
"^v=0\r\n"
"o=x \\d+ \\d+ IN IP4 203.0.113.1\r\n"
"o=- \\d+ \\d+ IN IP4 203.0.113.1\r\n"
"s=rtpengine.*?\r\n"
"t=0 0\r\n"
"m=audio \\d+ UDP/TLS/RTP/SAVPF 8\r\n"
@ -1433,7 +1433,7 @@ class TestVideoroom(unittest.TestCase):
self.assertIsInstance(sdp, str)
match_re = re.compile(
"^v=0\r\n"
"o=x \\d+ \\d+ IN IP4 203.0.113.1\r\n"
"o=- \\d+ \\d+ IN IP4 203.0.113.1\r\n"
"s=rtpengine.*?\r\n"
"t=0 0\r\n"
"m=audio (\\d+) RTP/AVP 8\r\n"
@ -1983,7 +1983,7 @@ class TestVideoroom(unittest.TestCase):
sdp,
re.compile(
"^v=0\r\n"
"o=x \\d+ \\d+ IN IP4 203.0.113.1\r\n"
"o=- \\d+ \\d+ IN IP4 203.0.113.1\r\n"
"s=rtpengine.*?\r\n"
"t=0 0\r\n"
"m=audio \\d+ RTP/AVP 8\r\n"
@ -2728,7 +2728,7 @@ class TestVideoroom(unittest.TestCase):
self.assertIsInstance(sdp, str)
match_re = re.compile(
"^v=0\r\n"
"o=x \\d+ \\d+ IN IP4 203.0.113.1\r\n"
"o=- \\d+ \\d+ IN IP4 203.0.113.1\r\n"
"s=rtpengine.*?\r\n"
"t=0 0\r\n"
"m=audio (\\d+) RTP/AVP 96\r\n"
@ -2852,7 +2852,7 @@ class TestVideoroom(unittest.TestCase):
match_re = re.compile(
"^v=0\r\n"
"o=x \\d+ \\d+ IN IP4 203.0.113.1\r\n"
"o=- \\d+ \\d+ IN IP4 203.0.113.1\r\n"
"s=rtpengine.*?\r\n"
"t=0 0\r\n"
"m=audio (\\d+) RTP/AVP 96\r\n"
@ -3103,7 +3103,7 @@ class TestVideoroom(unittest.TestCase):
match_re = re.compile(
"^v=0\r\n"
"o=x \\d+ \\d+ IN IP4 203.0.113.1\r\n"
"o=- \\d+ \\d+ IN IP4 203.0.113.1\r\n"
"s=rtpengine.*?\r\n"
"t=0 0\r\n"
"m=audio (\\d+) RTP/AVP 96\r\n"

Loading…
Cancel
Save