roc-toolkit icon indicating copy to clipboard operation
roc-toolkit copied to clipboard

Add options to simulate packet losses and delays

Open gavv opened this issue 5 years ago • 6 comments

It would be very handy for debugging to be able to simulate packet losses on delays directly in roc-send and in roc-recv tools.

The following solution is suggested:

  • Create a new packet::IWriter implementation called packet::Jammer. It's write() method just passes packets to the nested IWriter, but sometimes it drops or delays some of the packets.

    • Jammer should be configurable with three parameters: probability of packet loss, probability of packet delay, and delay range (from - to). For each packet, jammer should decide, using core::random() function, whether to drop or delay the packet, based on the configured probability.

    • When jammer decides to delay a packet, it should not sleep, because IWriter shouldn't be blocking. Instead, Jammer should start storing packets in an internal queue (packet::Queue) instead of passing them to nested writer. Each time when write() is called, it should check whether packets are hanging in the queue long enough already; if they are, it should flush the queue to the nested writer, thus simulating the delivery of delayed packets.

  • Add unit tests for Jammer to roc_packet. Note that unit tests should not be tied to the real clock. Likely, in unit tests jammer should use mocked clock function.

  • Add jammer config to pipeline::SenderConfig and pipeline::ReceiverConfig. Conditionally insert packet::Jammer at the end of pipeline::SenderSink pipeline (just before packets are passed to netio) and at the beginning of pipeline::ReceiverSession pipeline (right after packets are received from netio).

  • Add command-line options to configure simulated packet loss and delay in roc-send and roc-recv tools. By default, jammer is disabled. If at least one of the options is given, jammer is enabled.

packet::Interleaver is an example of conditionally-enabled packet writer (in sender pipeline). audio::Watchdog is an example of a component with multiple parameters configured via command-line.

This documentation may be helpful: https://roc-streaming.org/toolkit/docs/internals/data_flow.html

gavv avatar Jan 21 '20 08:01 gavv

It Would be nice, I'd work on it !

unguest avatar Mar 22 '20 01:03 unguest

@unguest Great, thanks!

PS. I saw your question in IRC, but was away, sorry. Yes, you figured it out right. And also OFEncoder was renamed to OpenfecEncoder (same for decoder).

gavv avatar Mar 27 '20 16:03 gavv

@unguest Hi, do you still have plans on it?

gavv avatar Jun 05 '20 08:06 gavv

Unassigning this so that someone could pick it up. @unguest Feel free to ping me if you'll decide to work on it thought.

gavv avatar Jul 08 '20 14:07 gavv

Hi gavv, is anyone working on this? I'd be interested in giving it a go!

jatrindo avatar Jul 15 '21 04:07 jatrindo

You're welcome!

gavv avatar Jul 19 '21 07:07 gavv

Hey Gavv, new to the project but I'd like to take on this if there is still the need.

jm4l1 avatar Mar 09 '23 03:03 jm4l1

You're welcome, thanks! Yes, the issue is still relevant. Feel free to ask questions here on in chat, if you'll have any.

gavv avatar Mar 09 '23 07:03 gavv

@gavv Thanks. I have not had the time to dig in as yet but I will work on this. I have done similar features in other projects.

jm4l1 avatar Apr 24 '23 01:04 jm4l1

It make sense for this component to implement Gilber-Elliott channel model. It would let simulate bursty channel losses with some accountable statistical parameters.

In short, G.-E. channel model means that the component could be in one of two states: State1 and State2. Each state has its own packet loss probability PLoss1 and PLoss2. In addition there are probabilities of changing state from 1 to 2 and from 2 to 1. So, the model characterized by 4 values in range [0, 1].

And, the packet delay could be characterized by some distribution, e.g. gamma

A config could look as follows:

struct JammerConfig {
    float ploss1;
    float ploss2;
    float pswap12;
    float pswap21;

    float mean_delay;
    float jitter;
};

baranovmv avatar Sep 22 '23 13:09 baranovmv

Given this task second thought, it appears that it should be implemented separately from toolkit.

I think the best option would be a UDP proxy with configurable port mapping that will apply delays, reordering, and other modifications, as well as perform some measurements and report metrics.

For now there is no specific plan for developing it and I'm going to close the task. We will reevaluate it later.

gavv avatar Sep 25 '23 21:09 gavv

@baranovmv Thanks for your input BTW!

@jm4l1 You're welcome to check out other help wanted issues :)

gavv avatar Sep 25 '23 21:09 gavv