Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I am implementing a SIP Proxy that should be able to redirect all RTP traffic between two clients that can't reach each other. To implement that, I decided to manipulate the negotiated addresses in the SIP/SDP messages and use iptables rules to redirect the RTP traffic.

The problem happens if the source sending the RTP packets changes. In this case the iptables take 30 seconds to start redirecting the traffic from the new source.

To explain in details what I am trying to do, suppose I've got two SIP clients and my Proxy:

  • SIP client of Bob is running at
  • SIP client of Alice is running at
  • The Proxy is running at
  • Bob and Alice 's networks can't reach each other. The Proxy knows both Bob and Alice networks.

Bob call Alice, informing, in the its SIP/SDP message, that he will be listening to RTP traffic at The Proxy then changes this address to and forward the new SIP/SDP message to Alice. Now, all RTP traffic from Alice will be send to the Proxy. To redirect this traffic back to Bob, the Proxy add the following rules to iptables:

iptables -t nat -A OUTPUT      -d -p UDP --dport 15000 -j DNAT --to
iptables -t nat -A PREROUTING  -d -p UDP --dport 15000 -j DNAT --to
iptables -t nat -A POSTROUTING -d -p UDP --dport 8000  -j SNAT --to

Now, suppose that the source RTP stream changes. For some reason now the machine running the Proxy is generating the RTP traffic instead of Alice.

The iptables rules do not need to change. Iptables should be able to redirect this new RTP traffic using the OUTPUT rule above. But, it takes 30 seconds to iptables start redirecting the traffic to Bob.

After some research I've found that this problem might be caused by conntrack table, that must wait its entry "Alice->Bob" expire before add a new entry "Proxy->Bob". And I could confirm that when I looked at /proc/net/ip_conntrack.

My rules do not specify the source, because I not always have it and it could change dynamically without telling the Proxy. So, I can't delete conntrack entries manually using conntrack-tools as I read in other posts.

Any ideas on how to handle this problem?

share|improve this question

NAT'ing SIP+RTP is not an easy task. (doubly so when the source/dest IPs change) There is much more that needs to be tweaked than simply the source and destination address. In the actual SIP session itself, there are bits that also must be mangled (which is what the conntrack module does). SIP is used to negotiate the source and destination each peer must connect to in order to exchange RTP data. Since all the traffic is UDP (connection-less), the conntrack module must wait for a timeout or for the call to end before the connection to be considered dead, and removed from the table.

To fix your problem, you need a proper sip proxy... not iptables. In this case, the phones will connect to the proxy, the proxy will connect to the remote peer's proxy, and the remote proxy will connect to the remote peer. In this example, there will be 3 separate connections, and if one of the routers has an IP change, it simply reinvites the remote proxy, and the connection is restored. You would also no longer require iptables to mangle packets.

share|improve this answer
The SIP messages I am already handling in my proxy, that is in fact a B2B Server (I called it a Proxy to simplify the question). But, to avoid an extra effort implementing a RTP relay I am trying to use iptables to do this task. – krusty Apr 10 '13 at 18:22
My whole statement is based on the fact that IPTABLES does a poor job of handling RTP sessions negotiated by SIP. It makes several assumptions about the data stream (as it can't know every detail about everything) that can't be trusted 100%. Your example above is one perfect example of why the conntrack module isn't reliable. If the IP of the peer changes, there is no way for it to know that the peer changed. It simply assumes that it stopped receiving packets from that ip/port... and assumes the connection is dead (after 30-sec) – TheCompWiz Apr 10 '13 at 19:18

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.