How do I make NAT table work reliably?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Greetings - 

I am developing some telephony server and - obviously - have lots of 
RTP/UDP audio traffic going on through my server. 

Currently, when the server is bridging two SIP telephones "T1" and "T2" 
into a call, it has telephone "T1" send audio to a UDP socket "S1" 
opened on the server, reads data from this socket and writes it to another 
socket "S2" opened for the outgoing audio to telephone "T2" (for a reason 
I cannot send RE-INVITE to the telephones and have them talk directly). 
Here's a picture: 

T1@xxxxxxxxxxxxxx --udp audio--> S1-server@xxxxxxxxxxxxxxxxxx --udp audio--> T2@xxxxxxxxxxxx 

The server does not do anything with the packets coming from "S1" - 
just copies them directly to "S2". The problem with this setup is that 
each packet form "T1" hits the interface on server, goes into kernel, 
from there it is copied to the user space on the server application, 
from there back to the kernel space for the outgoing socket "S2" and 
then leaves the server. That's a lot of memory copying without real need. 

What I'd like to happen is setup NAT with iptables so that all UDP packets 
from "T1" hitting the network interface on server go through DNAT and SNAT 
to be sent directly to "T2", without being copied into the user space. 
Here's the setup of my nat table (204.147.182.200 is server's IP): 

[root@ast-mv ~/Work/AsteriskPilot/asterisk/cpp]# /sbin/iptables-save -c -t nat 
# Generated by iptables-save v1.3.5 on Fri Aug 18 12:43:28 2006 
*nat 
:PREROUTING ACCEPT [62131:9673404] 
:POSTROUTING ACCEPT [12841:1191046] 
:OUTPUT ACCEPT [18958:2414567] 
[0:0] -A PREROUTING -s 204.147.182.21 -d 204.147.182.200 -p udp -m udp --sport 8000 --dport 23330 -j DNAT --to-destination 207.5.64.156:25590 
[0:0] -A PREROUTING -s 207.5.64.156 -d 204.147.182.200 -p udp -m udp --sport 25590 --dport 21226 -j DNAT --to-destination 204.147.182.21:8000 
[0:0] -A PREROUTING -s 204.147.182.21 -d 204.147.182.200 -p udp -m udp --sport 8001 --dport 23331 -j DNAT --to-destination 207.5.64.156:25591 
[0:0] -A PREROUTING -s 207.5.64.156 -d 204.147.182.200 -p udp -m udp --sport 25591 --dport 21227 -j DNAT --to-destination 204.147.182.21:8001 
[0:0] -A POSTROUTING -d 207.5.64.156 -p udp -m udp --dport 25590 -j SNAT --to-source 204.147.182.200:21226 
[844:168800] -A POSTROUTING -d 204.147.182.21 -p udp -m udp --dport 8000 -j SNAT --to-source 204.147.182.200:23330 
[0:0] -A POSTROUTING -d 207.5.64.156 -p udp -m udp --dport 25591 -j SNAT --to-source 204.147.182.200:21227 
[0:0] -A POSTROUTING -d 204.147.182.21 -p udp -m udp --dport 8001 -j SNAT --to-source 204.147.182.200:23331 
COMMIT 
# Completed on Fri Aug 18 12:43:28 2006 

This routing is established dynamically by writing commands to STDIN 
of "/sbin/iptables-restore --noflush -t nat". Server writes these commands 
after "T1" has already began sending packet to "T2" and therefore the server 
also resets conntrack cache using libnetfilter_conntrack library nfct_delete_conntrack() 
function after issuing the commands. 

The problem is that this setup works unreliably and this can be seen 
from 2 things: 

1) 0 counters of NATed packets and bytes, 
2) No audio on "T2". 

It appears that nat table is simply not seeing the packets it has to NAT 
(although tcpdump shows that the do come to the server). I've tried everything 
I could think of - including automated resets of conntrack entries every 
few seconds by server. 

Does anybody have ideas what else can be done to nat table reliably see the 
packets it has to NAT? 

Respectfully 

Constantine


[Index of Archives]     [Linux Netfilter Development]     [Linux Kernel Networking Development]     [Netem]     [Berkeley Packet Filter]     [Linux Kernel Development]     [Advanced Routing & Traffice Control]     [Bugtraq]

  Powered by Linux