From TAP to curl: Building a Userspace TCP Stack in Go