On Thu, Jul 11, 2024 at 09:51:33AM -0300, K R wrote:
> >How-To-Repeat:
>
> On the server side:
>
> pass in quick inet6 proto udp to egress divert-to ::1 port 12345
>
> # nc -u -k -l ::1 12345
>
> On the client side:
>
> $ nc -u $server_ipv6 65000
>
> Anything typed in the client nc will appear on the server nc. Typing
> on the server nc won't show in the client one. This incoming/outgoing
> nc test works when using a TCP divert-to rule.
divert to TCP is easy, UDP is complicated, nc is not smart enough
My rule is
pass in on vio1 proto { tcp udp } to port 12345 divert-to 127.0.0.1 port 1234
When I tried it (with IPv4, but that does not matter) tcpdump showed:
12:51:42.844747 127.0.0.1.1234 > 10.188.234.17.39569: udp 3
A packet with 127.0.0.1 must not apear on the wire, it will be
dropped.
nc does a connect(2) so the packet is sent to correct destination.
But is still has its listen socket bound to 127.0.0.1. So the
packet source is wrong.
A UDP server that wants to use divert-to correctly has to do this:
- create socket
- setsockopt IP_RECVDSTADDR
- bind to 127.0.0.1
- use recvmsg to get soure and destination address of packet
- create new socket
- bind and connect new socket to port and addresses received earlier
- new socket can communicate bidirectional
With TCP the accept system call creates the new socket that is bound
and connected correctly. So it works out of the box.
bluhm