network-programmingrusttun

How does replying work on a TUN/TAP device?


I'm using the Rust tun crate to experiment with the tun device. I'm writing a simple client/server setup where the client sends the server a message, the server reads the request and responds and finally the client reads the server response.

On the client side, I spun up a generic UDP socket and I'm able to read the data correctly on the server side. However, I don't know how to write data from the server to the client. I'm confused because how would the tun socket even know how to write back to the client? There isn't a connection-based socket where I can call device.accept().

The crate I'm using as a write method on the device and I tried naively writing via device.write(&mut buf) but I don't get any data on the client side. Honestly, I'm not too surprised this isn't working because how could the device 'know' where to write to?


Solution

  • A tun device provides access to a stream of IP frames. When you read from it, you get a raw IP frame. You will need to parse the IP and TCP/UDP header to determine if the packet is for you, and then handle the payload as appropriate. If you are already doing this, then you already have the IP address and port the packet came from; the address would be in the IP header and the port in the UDP header.

    To reply, you need to construct a valid reply frame, including the IP and UDP headers. You cannot simply write your reply payload to the tun device. The OS kernel is going to look at the data and try to interpret it as an IP frame. Assuming it even gets sent anywhere, it's likely not being sent where you want it to go.