powered by Jive Software

Problems punching NAT holes with Jingle (Demo app)

Using the jingle demo app I am not able to establish a connection between two machines,

each residing behind NAT firewalls.

My configuration contains two machines “L” and “R”. Machine “L” is residing behind a

Restricted Cone NAT and machine R is resisting behind a Port Restricted Code NAT.

(I determined the NAT configuration using de.javawi.jstun.test.demo.DiscoveryTestDemo

found in smackx-jingle.jar).

On both machines “L” had “R” I am using the demo program from the Smack trunk revision

8549 with a minor modification to use a STUN server (built from code at

http://sourceforge.net/projects/stun/) located on a third machine “S” with a direct

Internet connection. I did this simply to help capture the STUN info.

After quite a bit of spec reading and digging in the Smack jingle extension code I have

concluded that either a) I completely confused as to how a UDP NAT hole should be punched

or b) the current jingle code is not doing the right operations to punch UDP NAT holes

given my configuration.


OK, here is what I see happening…

  1. Demo is started on machine “L” and gets a STUN MappedAddress:

From ethereal I know that the source port used to connect to the STUN server was port 37212.

  1. Demo is started on machine “R” and get MappedAddress: From ethereal

I know that the source port used to connect to the STUN server was port 42614.

  1. When I initialte the call from “L” to “R” I get the following candidates and listeners

on machine “L”

C: /|/ p:2195

Listening for ECHO:

C: /|/ p:1103

Listening for ECHO:

  1. on machine “R” I see its candidates and listeners

C: /|/ p:2195

Listening for ECHO:

Listening for ECHO:

C: /|/ p:1103

  1. Machine “R” get candiates at machine “L” (yes I did a little XML formatting to help readibility)


  1. Using ethereal I see machine “L” attempt to transmit (Echo) UDP packets to machine “R”

based upon the second candidate listed in step (6). Here is the first of 10 attempts…

No. Time Source Destination Protocol Info

3 19.295599 UDP Source port: 19974 Destination port: 12808

  1. Negotiation Closed.


If you are still with me here are my questions:

A) I am not sure how any packets can get across the NAT from an external host by using internal

port numbers. Shouldn’'t the external candidates exchanged between “L” and “R” provide and external port

(specifically the external port reported from the STUN server in steps (1) and (2))?

B) From what I understand from documents like http://www.brynosaurus.com/pub/net/p2pnat/ the key to

getting across a NAT to a known “internal” port is for a remote machine to transmit to known “external”

port from a previously established port mapping. Shouldn’'t the external candidates listed in steps 3 and

4 set up listeners with the same (internal) port used to communicate with the STUN server?


Thanks in advance for any information anyone can provide as to why I can not establish a successful

NAT hole punch with my configuration.

i don’‘T know if it’'s even possible to punch holes for udp … tcp yes … but udp ?!

anyway… i used spark (build on top of smack) to communicate through 2 nats:

spark <> nat <> i-net <> nat <> spark

at first it wouldn’'t work but i activated the media proxy on my openfire server and since this time i can call out

Thanks for the input.

That is interesting to learn that you were successful once activating the media proxy. I am trying hard to see if the jingle code is able to successfully punch UDP holes so that what I am working on does not have to pay the latency cost of using a media gateway (TURN) server. I realize that UDP NAT hole punching can not work for a symmetric NATs, but wherever possible I would like to be able to make p-2-p connections.

Actually UDP is the commonly implemented protocol on which NAT hole punching can be done whereas TCP hole punching does not yet seem to be ready for prime time (http://www.brynosaurus.com/pub/net/p2pnat/ has an excellent description of UDP hole punching and http://nutss.gforge.cis.cornell.edu/stunt.php seem to be on the forefront of getting a TCP hole puncher ready for prime time).

Any thoughts on my original comments/questions from a Smack/Jingle developer?


Can you please make sure that you are loading JMF native libs and has your firewalls opened for UDP packets?

According to tyour log it seems not a NAT punch problem.

Can you please check these details, and if it is possible try to use spark Jingle plug to test your NAT issues.

Best Regards,


After being pulled away on other stuff for a bit I was finally able to spend some time testing my hypothesis for why the NAT punching was not working for my configuration.

The first thing that I noticed is that the mapped address port reported back from the STUN server for one of the firewalls (home netgear router) was almost always identical to the internal port. The other “corporate” firewall never had identical port mappings. So if someone was running the current jingle code with two firewalls that always had direct internal/external port mappings, then the current code would successfully punch holes. Unfortunately this was not my configuration.

I was able to successfully have the jingle code punch NAT holes for my configuration by modifying the JSTUN code to capture and provide access to the mapped address external port (as returned by the STUN serer) and then modifying the jingle code to use that external port number when offering up candidates to the other peers.

My question now is how to help out the community with what I have found. Specifically, is there a process for submitting patches upstream to Jive engineering?

Did you modify JSTUN or Smack or both?

Call me silly, but I really hope somebody on here would email you to ask for your code, but barring that, you could certainly ping one of the jive people through this forum.

And barring that, could you share your code with me?

Sorry for the delayed response, I just got back from vacation.

I modified both the JSTUN code and the jingle (smack) code.

Since the code in jstun.jar in jingle/extension/build/merge appears to be ahead of the released JSTUN source code, I had to make my changes to decompiled source code. I have subsequently received access to the JSTUN cvs repo and am going to be feeding a patch back to Thomas King for my changes (they are pretty minor).

I still have a bit of cleanup to do on the jingle code before creating a patch. Since there was not overwhelming interest (despite your post) for my changes, the cleanup and patch creation have been bumped down on my to-do list. I still should be able to get to the cleanup in the next week or so.

I was really hoping to be able to push the changes to a jingle maintainer for approval and integration (or disapproval), but if there continues to be little interest in a patch I will have no problem sending the changes directly to you.

Hi Yakkleman,

I am working on a project which has a requirement for P2P connections for Voice/Video data. Can you share your modifcation to the Smack’s jingle library with me (or in general with the community)? Also, can you provide your feedback on the experience you have had so far on P2P with jingle? I would be highly obliged if yous share this information with me as I need to make a decsision between SIP or XMPP (Jingle) for my applicaton and i am finding it hard as both these protocols have some positives and negatives.

Thanks & Best Regards,

Nitin Gupta

Hi Yakkleman

I know that this is an old post, but we are having the same problem a year latter. What happened to your modifications to the Smack’s jingle library? Are you still working with Jingle? Did you share them with the community? If yes, how can we get them and if not, is it possible to share them with us? We will appreciate it a lot.


I am building a Screen Share application with Smack_3_1_0.

when I run the Demo App with jstun.javawi.de as STUN server, I am getting the following error.

java.net.BindException: Cannot assign requested address
at java.net.PlainDatagramSocketImpl.bind0(Native Method)
at java.net.PlainDatagramSocketImpl.bind(PlainDatagramSocketImpl.java:82)
at java.net.DatagramSocket.bind(DatagramSocket.java:368)
at java.net.DatagramSocket.(DatagramSocket.java:210)
at java.net.DatagramSocket.(DatagramSocket.java:261)
at de.javawi.jstun.test.demo.ice.Candidate.(Candidate.java:44)
at de.javawi.jstun.test.demo.ice.ICENegociator.gatherCandidateAddresses(ICENegocia tor.java:87)
at org.jivesoftware.smackx.jingle.nat.ICEResolver.initialize(ICEResolver.java:82)
at org.jivesoftware.smackx.jingle.nat.TransportResolver.initializeAndWait(Transpor tResolver.java:387)
at org.jivesoftware.smackx.jingle.nat.ICETransportManager.(ICETransportManag er.java:36)
at Demo.initialize(Demo.java:84)
at Demo.(Demo.java:76)
at Demo.main(Demo.java:176)

This is because we are trying to bind public IP of whichever we got through STUN resolver.

1.Here my question is, why we are binding to the public IP?

I download jstun-0.7.3 and made changes in src/de/javawi/jstun/test/demo/ice/Candidate.java, instead of binding public IP I used local IP, then

this case I am not getting the above error. so please confirm which way of doing is correct.

My actual problem is same as mentioned in this Thread.

I am using jstun.javawi.de and running Demo app from two different public IPs which are behind Port Restricted Cone NAT and Restricted cone NAT.

Once I built jar files from jstun-0.7.3 separately, I am using these jar files in running Demo app.

Here I am able to get the public IP through STUN, but after this the negotiation is not happening.

I am getting error

Terminate Unable to negotiate session. This may be caused by firewall configuration problems.
Session state change: JingleSessionStatePending->JingleSessionStateEnded
Session Ended

Please suggest me a solution for this problem.

even if we have patch for this problem as mentioned in http://www.igniterealtime.org/community/thread/27051

that would be great help to all.




You MUST bind to local IP and send in the candidate the public one discovered by STUN.