as the name implies, alloc0 zeroed the chunk of memory requested, while alloc return raw memory block. when you free the memory, Nim internal allocator might reuse it at the next alloc call, if it thinks the previous block allocated could be reuse, hence the garbage.
if you think there is no need to do new allocation, you can keep the pointer around and reuse it, and call zeroMem if needed. isn't this scenario a common practice when using C language?(I really have no idea about your C skills) if you think alloc0 is slow because of the zeroMem overhead, you can put the zero terminator manually if you know the incoming packet length. (again, this is so common in C, no offense ) also I noticed that in line 67: if nread == 0: return, you don't free the buffer, doesn't it will leak?