Testing network fragmentation?

I’m writing a proxy for a network protocol. In normal operation, in my tests, packets turn up in one piece – i.e. {tcp, S, Packet} contains (at least) an entire packet.

I’d like to test my code in situations where this is not true.

If this were an integration test, I’d use GitHub - tylertreat/comcast: Simulating shitty network connections so you can build better systems. , but it’s a unit(-ish) test.

So: are there any good ways to subvert Erlang’s network stack, so that I can force it to deliver the network packets in smaller pieces, so that I can thoroughly test that I’m handling this properly?

Notes:

  • I don’t want to use {packet, 4}, because this is actually a proxy implementation, and some of these messages are huge, and I don’t want to hold them in memory.
  • Similarly, I don’t want to gather the entire message into a binary before processing – same reason.
  • I want to collect just enough of the header to figure out what to do with the message, and then stream the rest.
3 Likes

Edit: misread the question.

I’ve had similar requirements and if you don’t need to control the exact number of bytes sent each time then buffer option in gen_tcp:connect will do the job. I’m not exactly sure how system counts those bytes but setting that buffer to e.g. 200 will send packets fewer than 100 bytes (I think IP and TCP headers are counting here) which is pretty fragmented.

I’ve found lack of documentation for that option, but you I found use of it for that specific case.

Interested to find out how it worked for you.

1 Like

@rlipscombe We use throttle which works great.
Just run throttle --profile 3g to simulate poor network conditions that naturally cause fragmentation.

npm install @sitespeed.io/throttle -g

throttle --profile 3g
throttle --profile 4g
throttle --profile 2g
throttle stop

The available profiles include:

  • 2g: up:256 down:280 rtt:400
  • 3g: up:768 down:1600 rtt:150
  • 3gfast: up:768 down:1600 rtt:75
  • 3gslow: up:400 down:400 rtt:200
  • 4g: up:9000 down:9000
  • cable: up:1000 down:5000 rtt:14
  • dsl: up:384 down:1500 rtt:14

Be careful though, as throttle can really slow down everything on your machine!

1 Like

however slowing down an interface may not cause fragmentation. Maybe, setting MTU to some lower value could help to enforce fragmentation, see e.g., https://itslinuxfoss.com/change-mtu-size-linux/

Or - shameless self-advertisement :slight_smile: - for more complex scenarios, my ‘poor-mans’ network emulator: enet (still at the very beginning, but it can already manipulate interface properties)

1 Like