Fix transmission tracking

Delayed packets weren't handled properly and when a transmission timed
out, RTP sequence numbers were re-used and therefore rejected by the SRTP layer.
This commit is contained in:
Jonas Herzig 2018-12-15 19:15:34 +01:00
parent 83773f0a1d
commit 3f079c4153

View file

@ -46,6 +46,12 @@ impl User {
if self.active { if self.active {
self.active = false; self.active = false;
self.rtp_seq_num_offset = self
.rtp_seq_num_offset
.wrapping_add((self.highest_voice_seq_num - self.start_voice_seq_num) as u32 + 1);
self.start_voice_seq_num = 0;
self.highest_voice_seq_num = 0;
let mut msg = Mumble::TalkingState::new(); let mut msg = Mumble::TalkingState::new();
msg.set_session(self.session); msg.set_session(self.session);
EitherS::A(stream::once(Ok(Frame::Client(MumbleFrame { EitherS::A(stream::once(Ok(Frame::Client(MumbleFrame {
@ -250,7 +256,7 @@ impl Connection {
Some(t) => t, Some(t) => t,
None => return EitherS::B(stream::empty()), None => return EitherS::B(stream::empty()),
}; };
let (sequence_id, buf) = match read_varint(buf) { let (seq_num, buf) = match read_varint(buf) {
Some(t) => t, Some(t) => t,
None => return EitherS::B(stream::empty()), None => return EitherS::B(stream::empty()),
}; };
@ -277,59 +283,63 @@ impl Connection {
}; };
let rtp_ssrc = user.ssrc; let rtp_ssrc = user.ssrc;
let mut rtp_marker = if user.active { let mut first_in_transmission = if user.active {
false false
} else { } else {
user.start_voice_seq_num = sequence_id; user.start_voice_seq_num = seq_num;
user.highest_voice_seq_num = sequence_id; user.highest_voice_seq_num = seq_num;
true true
}; };
let activity_stream = if last_bit && sequence_id > user.start_voice_seq_num { let offset = seq_num - user.start_voice_seq_num;
let mut rtp_seq_num = user.rtp_seq_num_offset + offset as u32;
let activity_stream = if last_bit {
if seq_num <= user.highest_voice_seq_num {
// Horribly delayed end packet from a previous stream, just drop it
// (or single packet stream which would be inaudible anyway)
return EitherS::B(stream::empty());
}
// this is the last packet of this voice transmission -> reset counters // this is the last packet of this voice transmission -> reset counters
// doing that will effectively trash any delayed packets but that's just // doing that will effectively trash any delayed packets but that's just
// a flaw in the mumble protocol and there's nothing we can do about it. // a flaw in the mumble protocol and there's nothing we can do about it.
EitherS::B(user.set_inactive()) EitherS::B(user.set_inactive())
} else if sequence_id >= user.highest_voice_seq_num } else {
&& sequence_id + 100 < user.highest_voice_seq_num EitherS::A(
if seq_num == user.highest_voice_seq_num && seq_num != user.start_voice_seq_num {
// re-transmission, drop it
return EitherS::B(stream::empty());
} else if seq_num >= user.highest_voice_seq_num
&& seq_num < user.highest_voice_seq_num + 100
{ {
// probably same voice transmission (also not too far in the future) // probably same voice transmission (also not too far in the future)
user.highest_voice_seq_num = sequence_id; user.highest_voice_seq_num = seq_num;
EitherS::A(user.set_active(target)) EitherS::A(user.set_active(target))
} else if user.highest_voice_seq_num > sequence_id + 100 { } else if seq_num < user.highest_voice_seq_num
&& seq_num + 100 > user.highest_voice_seq_num
{
// slightly delayed but probably same voice transmission
EitherS::A(user.set_active(target))
} else {
// Either significant jitter (>2s) or we missed the end of the last // Either significant jitter (>2s) or we missed the end of the last
// transmission. Since >2s jitter will break opus horribly anyway, // transmission. Since >2s jitter will break opus horribly anyway,
// we assume the latter and start a new transmission // we assume the latter and start a new transmission
user.rtp_seq_num_offset = user let stream = user.set_inactive();
.rtp_seq_num_offset first_in_transmission = true;
.wrapping_add((user.highest_voice_seq_num - user.start_voice_seq_num) as u32) user.start_voice_seq_num = seq_num;
.wrapping_add(1); user.highest_voice_seq_num = seq_num;
user.start_voice_seq_num = sequence_id; rtp_seq_num = user.rtp_seq_num_offset;
user.highest_voice_seq_num = sequence_id; EitherS::B(stream.chain(user.set_active(target)))
rtp_marker = true; },
EitherS::A(user.set_active(target)) )
} else {
EitherS::A(user.set_active(target))
}; };
let offset = sequence_id - user.start_voice_seq_num;
let rtp_seq_num = user.rtp_seq_num_offset + offset as u32;
if !user.active {
user.rtp_seq_num_offset = user
.rtp_seq_num_offset
.wrapping_add((sequence_id - user.start_voice_seq_num) as u32)
.wrapping_add(1);
user.start_voice_seq_num = 0;
user.highest_voice_seq_num = 0;
}
let rtp_time = 480 * rtp_seq_num; let rtp_time = 480 * rtp_seq_num;
let rtp = RtpPacket { let rtp = RtpPacket {
header: RtpFixedHeader { header: RtpFixedHeader {
padding: false, padding: false,
marker: rtp_marker, marker: first_in_transmission,
payload_type: 97, payload_type: 97,
seq_num: rtp_seq_num as u16, seq_num: rtp_seq_num as u16,
timestamp: rtp_time as u32, timestamp: rtp_time as u32,