---
# System prepended metadata

title: Implementation Goals

---

# Implementation Goals
From a working Transport Layer (TL + Socket) implementation, wrap/decorate to add an disruption layer, to simulate various network incidents:
- Delay (fixed, random, ...)
- Reordering packets
- Packet injection (duplication, fake packets,...)
- Packet loss
- Buffer/Jam behavior (blocking packets until threshold on time/#packets/...)
- other behaviors

Suggested implementation direction:
- focus on sender-side: trigger new behaviors on calling Send()
- implement a new Socket type (leveraging the existing interface), wrapping another socket

# Implementation

## Design choices

- Buffer Jam: we realized that taking into account the number of packets to be buffered will introduce sequentiality. It might be better to simulate the jam using sinusoidal (or similar, having a stateful filter) delays 

- Injection: Beyond randomizing the payload, we also thought about spoofing (changing the source address for example).
But:
    - too 'random' packets -> trigger early drops, more useful as unit tests rather than stress-test
    - crafting precise packets: hard to define, + risk of implementing an actual attack (overkill given the threat model considered?)

- Reordering: To avoid sequentiality issues (and +-converting a packet-based system to a stream-based system) we implicitly implemented it through delays only

## New Transport Layer - DisruptedLayer

```
type DisruptedTransport struct {
	transport.Transport
	filters []Filter
}
```
Wrapper for a 'normal TL'. Needed as Sockets are instantiated by call to the TL.  
Contains the 'normal TL', and a list of filters (uninitialized) to be copied and launched for every instantiated disrupted socket.

On socket creation, a 'normal socket' is created through the wrapped TL, then wrapped in a DisruptedSocket, for which filters are copied and `Start()`-ed, then an 'end-of-line' listening goroutine is launched (see further).

## New Socket - DisruptedSocket
```
type Socket struct {
	transport.ClosableSocket
	filters []Filter
}
```
Wrapper for a 'normal Socket'.  
Contains an ordered list of autonomous filters, sequentially connected by channels transmitting `SendingTriplet`s (decorated packets with destination and timeout to use on the actual normalSocket `Send()`).
```
type SendingTriplet struct {
	dest    string
	pkt     transport.Packet
	timeout time.Duration
}
```


An incoming packet is transferred to the first Filter of the list through its input channel (non-blocking `In()` call), which will act on it and transmit to the next filter, etc.

The DisruptedSocket has a goroutine listening on the last channel, and calling the normalSocket `Send()` as soon as a SendingTriplet is available.

Due to the asynchronous nature of this implementation, DisruptedSocket's `Send()` is non-blocking (always returning nil).

## Filters (old version)
Spec: one op only, `Pass(pkt transport.Packet) ([]transport.Packet)`, called concurrently (slice to handle packet injection)

Issues: 
- apply filter n+1 on all filters outputted by filter n ?
- delays: blocking on a packet blocks all the slice
- privileges: trying to send duplicates directly means the Filter has sending privileges (-> access to the socket ?)


## Filters (new version)
```
type Filter interface {
	Start()                                         // Launch Filter listener
	Stop()                                          // Stop Filter listener
	Copy() Filter                                   // Copy Filter
	pass(tripl SendingTriplet)                      // Internal, compute the filter function on an augmented packet
	SetIO(chan SendingTriplet, chan SendingTriplet) // Used to initialize channels
	In(SendingTriplet)                              // (blocking) To feed a packet into the filter
}
```

Autonomous item with in/out channels.

Once `Start()`-ed, waits on input packets, processes (non-blocking) them using `pass()` and transmits to `out` channel. Also waits on a quit channel, triggered by `Stop()`. `Copy()` needed to instantiate all sockets.

`SetIO()` and `In()` needed at TL-level to resp. initialize all filters for a new socket, and feed a packet into the first filter when calling `Send()`.


- Injection:
    - Pseudo-random:
        - [ ] unmarshable (sanity check)
        - [ ] marshable w/ random packet ID
        - [ ] marshable w/ random source (spoof)
    - [x] Duplication: poisson distribution for #packets added
- Delay:
    - [x] Exponential (HW transfer time)
    - [x] Stateful (pseudo-atomic op needed, at least monotonic inc) ~periodic for jam simulation w/ non-0 mean
    - [x] Fixed
- Loss:
    - [x] Probabilistic drops of packets

---
---
# Draft

## Issues - various
(Filter design) Issue: need for interface (~virtual class), so that `Start()` launches listener on in/out and calls `pass()`. Pb: `pass()` needs out channel, ended up with cyclic dependancy design. (lack of virtual classes/inheritance in Golang?)

**Solved** by accepting redundant code (every Filter has its own Start(), Stop(), SetIO(), In() implementations even if identical)


## How to test filters
- integrate them into some tests
- 

# Discussions
- Ref implem => 100% tests ?
- Adapt all tests, only integration ?
- filters implement Socket (ClosableSocket)
- Send direct
- go routine en continue + delais

# Réu 02/08
- recv side
- filter -> interface Socket (truc récursif)
- integrate filters into tests
- func option pattern pr init
- implementation with a queue
![](https://hackmd.io/_uploads/r1IPQb_ih.png)
