> Rules are rather static, but your described scenario requires > rather dynamic changes. There is a much more targeted solution: > > Once your application decides it is time to switch, it needs to > change the conntrack entry for the UDP session. conntrack(8) > can be used, and there is also a C interface with > libnetfilter_conntrack. > > (With the conntrack command line utility, updating certain parameters is > not possible because of the program's way of option parsing. This > limitation may be gone in the C interface. With the command-line > utility, one could however recreate the entry, if the lack of atomicity > between the operations is bearable.) > > conntrack -D -p udp \ > --src client_addr --dst stun_addr \ > --sport client_port --dport stun_port > conntrack -I -p udp \ > --src client_addr --dst stun_addr \ > --sport client_port --dport stun_port \ > --reply-src real_server_addr --reply-dst client_addr \ > --reply-src-port real_server_port \ > --reply-dst-port client_port > > At least, that is the general idea.. whether it works, or if it needs > additional commands, I have not tried. This is indeed an exciting alternative! It might make it possible to avoid connection tracking for all other regular traffic through this box too so I am quite excited! However, I've tried to get it to work and must be missing something subtle. In my test I'm hosting my clients on 10.0.1.7:5000 (Alice) -> 10.0.1.8 (Relay Server) port 5001 relayed to Bob via 5002 -> 10.0.1.7:5003 (Bob) Using iptables (the old method) I create the NAT rules like this aAddr=10.0.1.7 aPort=5000 bAddr=10.0.1.7 bPort=5003 nAddr=10.0.1.8 anPort=5002 bnPort=5001 iptables -t nat -I PREROUTING -p udp -s $aAddr --sport $aPort -d $nAddr --dport $bnPort -j DNAT --to $bAddr:$bPort iptables -t nat -A POSTROUTING -p udp -d $bAddr --dport $bPort -j SNAT --to $nAddr:$anPort iptables -t nat -I OUTPUT -p udp -s $aAddr --sport $aPort -d $nAddr --dport $bnPort -j DNAT --to $bAddr:$bPort I can see the connection with conntrack -L -p udp udp 17 24 src=10.0.1.7 dst=10.0.1.8 sport=5000 dport=5001 [UNREPLIED] src=10.0.1.7 dst=10.0.1.8 sport=5003 dport=5002 mark=0 use=1 And Bob gets the packets and everything works. I tried repeating this experiment (without the complexity of the intermediate handshake, just by creating the connection manually: I cleared the nat rules from previous test with: iptables -t nat -F I flushed all udp tracked connections: conntrack -D -p udp Then I created the relay connection: conntrack -I -p udp \ --src $aAddr --sport $aPort \ --dst $nAddr --dport $bnPort \ --reply-src $bAddr --reply-port-src $bPort \ --reply-dst $nAddr --reply-port-dst $anPort \ --timeout 600 But my packets all bounce with ICMP Port Unreachable. I compared the conntrack -L -p udp output and it looked essentially the same. I also read the man page which suggested using this instead of --src/--dest --orig-src $aAddr --orig-port-src $aPort \ --orig-dst $nAddr --orig-port-dst $bnPort \ But the conntrack entry looks the same. It feels like some aspect of the firewall is not being informed of this state. I checked iptables -L, iptables -L -t nat, and -t raw and everything is empty. Can you think of something I've missed? -g -- To unsubscribe from this list: send the line "unsubscribe netfilter" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html