Been working on a toy program that proxies a TCP connection. It was working fine for some and then would mysteriously corrupt others; I spent a long time looking and it finally hit me, painfully obvious.
I had threads going in each way doing this in a loop:
forward :: Socket -> Socket -> IO ByteString forward src dst = do buf <- recv src (16 * 2^10) send dst buf return bufNetwork.Socket.ByteString.send of course returns an integer of how many bytes were actually sent; you need to loop if you want to be sure to send it all. (I had imagined this higher-level API was handling this looping for me, but it makes more sense that it wouldn't. It does however handle
EINTR, so when I had glanced at the source in my desperation I did notice a loop, throwing me off the scent.) Sticking a loop around the send fixed everything.