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.
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.
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.
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 - for more complex scenarios, my ‘poor-mans’ network emulator: enet (still at the very beginning, but it can already manipulate interface properties)