Skip to main content

NAT transversal to RDV

14 replies [Last post]
xiptos
Offline
Joined: 2005-02-23
Points: 0

Hi all!

I tried to contact a RDV peer (with a public IPv4 address) from an EDGE peer with a NATed dynamic address. It succeeds in contacting, but the RDV peer gives the following message:

INFO: Line 136 net.jxta.impl.endpoint.netty.NettyTransportClient.getMessenger()
processing request to open connection to tcp://192.168.1.11:9710
Aug 12, 2010 11:10:05 PM net.jxta.impl.util.threads.LongTaskDetector run
WARNING: task of type [net.jxta.impl.endpoint.netty.NettyMessenger$1] still running after 1,001ms in thread JxtaWorker-4, current stack:
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:198)
java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedNanos(AbstractQueuedSynchronizer.java:947)
java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireSharedNanos(AbstractQueuedSynchronizer.java:1239)
java.util.concurrent.CountDownLatch.await(CountDownLatch.java:253)
net.jxta.endpoint.MessengerStateBarrier.awaitMatch(MessengerStateBarrier.java:59)
net.jxta.endpoint.AbstractMessenger.waitState(AbstractMessenger.java:245)
net.jxta.impl.endpoint.EndpointServiceImpl.getMessenger(EndpointServiceImpl.java:2044)
net.jxta.impl.rendezvous.PeerConnection.getCachedMessenger(PeerConnection.java:329)
net.jxta.impl.rendezvous.rdv.ClientConnection.connect(ClientConnection.java:98)
net.jxta.impl.rendezvous.rdv.RdvPeerRdvService.addClient(RdvPeerRdvService.java:507)
net.jxta.impl.rendezvous.rdv.RdvPeerRdvService.processLeaseRequest(RdvPeerRdvService.java:652)
net.jxta.impl.rendezvous.rdv.RdvPeerRdvService.access$200(RdvPeerRdvService.java:115)
net.jxta.impl.rendezvous.rdv.RdvPeerRdvService$StdRdvRdvProtocolListener.processIncomingMessage(RdvPeerRdvService.java:254)
net.jxta.impl.endpoint.EndpointServiceImpl.processIncomingMessage(EndpointServiceImpl.java:1027)
net.jxta.impl.endpoint.netty.NettyMessenger$1.run(NettyMessenger.java:148)
net.jxta.impl.util.threads.RunnableAsCallableWrapper.call(RunnableAsCallableWrapper.java:17)
net.jxta.impl.util.threads.RunMetricsWrapper.call(RunMetricsWrapper.java:50)
net.jxta.impl.util.threads.QueueTimeRunMetricsWrapper.call(QueueTimeRunMetricsWrapper.java:34)
net.jxta.impl.util.threads.RunMetricsWrapper.run(RunMetricsWrapper.java:93)
net.jxta.impl.util.threads.QueueTimeRunMetricsWrapper.run(QueueTimeRunMetricsWrapper.java:9)
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
java.lang.Thread.run(Thread.java:619)

As consequence, the EDGE peer does not get a confirmation of connection to the RDV...

It appears that the RDV peer cannot answer the EDGE peer initiated connection. Is this the expected behavior? Shouldn't both communicate giving that the initiator is the EDGE peer?
To solve this issue, it is necessary to use a RELAY?

Cheers,

/rp

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
xiptos
Offline
Joined: 2005-02-23
Points: 0

Hi again!

I captured packets from a session of an EDGE connecting to a RDV using wireshark (libpcap) in a NAT and in a LAN situation. I attach both files, for reference.
It seems that the RDV successfully contacts the EDGE in the LAN but not in a NAT scenario, although ACKs arrive just fine... could it be a bug?

Cheers,

/rp

adamman71
Offline
Joined: 2007-01-31
Points: 0

In the process of finding out whether an IP address is valid, the RDV tests it by trying to open a connection from the route advertisement it received from this edge. This route advertisement is created by the EDGE which does not know its public address.

The warning message you get comes from 'monitoring' log information we have added in the code in 2.6 to find out about performance, thread idling, etc... Since the connection won't work (after 1 second), the system logs a false positive on a potential performance issue. It can be ignored.

The RDV must perform this test because it does not know whether the EDGE is on its LAN or not. It has to try all available options (i.e., all end point addresses in the route advertisement) to create Wisdom objects in the code.

If the EDGE has established a connection to the RDV, the RDV does not need to create a connection back to the RDV. It will use the existing one.

I believe that you are only seeing the result of the RDV doing its job in trying to find out which IP address to EDGE is valid or not. On top of my head, it will do that regardless of whether it already has an open connection to the RDV.

From what you have said so far, we can't conclude that the system does not work (and I would be really worried if it did not work). Several people have tested edges and rdv behind NATs successfully. I am not saying that there is no issue - we may have missed an angle - but I don't see an issue so far.

In your current configuration, you cannot expect the RDV to be able to connect to the EDGE. You would have to enable the RELAY mode for that.

I re-read your first post and notice you said:

"As consequence, the EDGE peer does not get a confirmation of connection to the RDV..."

No, the RDV does not need to open a connection to the EDGE to 'confirm' the connection. TCP is bidirectional, therefore, it is the TCP stack that will handle the ACK from the RDV. This is completely invisible from the JXTA/JXSE layer. We don't need to deal with that.

xiptos
Offline
Joined: 2005-02-23
Points: 0

Looking at the packet capture, I can summarise the connection as the following:

The EDGE sends to the RDV a message with the following message elements: Connect, EndpoitSourceAddress and EndpoitDestinationAddress.

In the LAN situation, the RDV sends to the EDGE a message with 5 Message Elements: RdvAdvReply, ConnectedPeer, ConnectedLease, EndpointRouterMsg, EndpoitSourceAddress, EndpoitDestinationAddress. Testing the isConnectedToRendezVous(), it returns 'true'.

In the NAT case, the message from the RDV does not get sent. Testing the isConnectedToRendezVous(), it returns 'false'.

Is there any test I can do to get some insight into what is happening?

Cheers,

/rp

adamman71
Offline
Joined: 2007-01-31
Points: 0

I am not an expert with wireshark, but I have opened both files you attached. I can't find any reference to 213.22.32.184 in these. It does not really make sense to me, because in the NAT configuration, the EDGE should fire some IP packets to that destination...

The obvious test is to open a pipe from EDGE to RDV in the NAT configuration and see if you can send a message and get it in the RDV.

I assume that in your NAT situation, you have set the RDV as a seed for the EDGE using 213.22.32.184? Correct?

xiptos
Offline
Joined: 2005-02-23
Points: 0

> I am not an expert with wireshark, but I have opened
> both files you attached. I can't find any reference
> to 213.22.32.184 in these. It does not really make
> sense to me, because in the NAT configuration, the
> EDGE should fire some IP packets to that
> destination...
Right!

>
> The obvious test is to open a pipe from EDGE to RDV
> in the NAT configuration and see if you can send a
> message and get it in the RDV.
Will do!

>
> I assume that in your NAT situation, you have set the
> RDV as a seed for the EDGE using 213.22.32.184?
> Correct?
I added the RDV public address as a seed in the EDGE. I also tried to add 213.22.32.184,false as the tcpPublicAddress in the EDGE, but did no good...

Cheers,

/rp

xiptos
Offline
Joined: 2005-02-23
Points: 0

I think I just solved it... probably the solution is documented, but I couldn't find it. I only needed to add:

networkConfigurator.addSeedRelay(new URI(s));

immediately after:

networkConfigurator.addSeedRendezvous(new URI(s));

where 's' is the seed address (tcp://public.ip.address:port).

No further changes were needed... is this the expected behavior?

Cheers,

/rp

adamman71
Offline
Joined: 2007-01-31
Points: 0

Ok, good to know.

If your RDV is not a RELAY, then adding

networkConfigurator.addSeedRelay(new URI(s));

should make no difference in your case. This is strange.

Can you share code for your EGDE and RELAY?

Thanks.

xiptos
Offline
Joined: 2005-02-23
Points: 0

Hi!

> If your RDV is not a RELAY, then adding
>
> networkConfigurator.addSeedRelay(new URI(s));
>
> should make no difference in your case. This is
> strange.
Right!

>
> Can you share code for your EGDE and RELAY?
Actually, it is your code. :)
I'm experimenting with RendezVous_Jack and Edge_Anna (from PracticalJXTA II).

I did no changes in RendezVous_Jack.

I added the following lines in Edge_Anna:
// Checking if RendezVous_Jack should be a seed
MyNetworkConfigurator.clearRendezvousSeeds();
String TheSeed = "tcp://public.ip.address:" + RendezVous_Jack.TcpPort;
Tools.CheckForRendezVousSeedAddition(Name, TheSeed, MyNetworkConfigurator);
// Without the following lines, it does not connect to the RDV (isConnectedToRdv is false)
// With them, it connects immediately
try {
MyNetworkConfigurator.addSeedRelay(new URI(TheSeed));
} catch (URISyntaxException e) {
e.printStackTrace();
}

If you need to check it online, let me know!

Cheers,

/rp

adamman71
Offline
Joined: 2007-01-31
Points: 0

I will take a look at this in more details.

xiptos
Offline
Joined: 2005-02-23
Points: 0

I also checked that it only works if HTTP is enabled. If it is disabled (confirmed with 'netstat -ntol'), it does not work.

Anything I can do to help, let me know!

/rp

galato
Offline
Joined: 2007-07-06
Points: 0

Hi guys,

any resolution on this yet?

Thanks

adamman71
Offline
Joined: 2007-01-31
Points: 0

I am working on another project, therefore, I don't have much to offer to JXTA right now.

There is a workaround for this issue. Moreover, enabling RDV service without RELAY service while using NAT-ed peer is pretty uncommon. I understand that the info received by xiptos is misleading, but not dramatic.

adamman71
Offline
Joined: 2007-01-31
Points: 0

i) What type of transportation are you enabling between your EDGE and your RDV?
ii) Do you encounter the same issue with the code example (delivered at www.practicaljxta.com for example)?
iii) Which version in JXTA/JXSE are you using? If it is 2.5 please try with 2.6, because 2.5 does not detect properly that tcp://192.168.1.11:9710 cannot be used from the WAN.

> It appears that the RDV peer cannot answer the EDGE peer initiated connection. Is this the expected behavior?
No (assuming TCP is enabled)

> Shouldn't both communicate giving that the initiator is the EDGE peer?
Yes

> To solve this issue, it is necessary to use a RELAY?
No. Since the RDV has a public IP Address, relay is not required.

xiptos
Offline
Joined: 2005-02-23
Points: 0

Hi!

Thanks for your quick response!

> i) What type of transportation are you enabling
> between your EDGE and your RDV?
TCP

> ii) Do you encounter the same issue with the code
> example (delivered at www.practicaljxta.com for
> example)?
Yes. I get this log message (I used RendezVous_Jack with public IP and Edge_Anna with private, dynamic IP):

Aug 14, 2010 1:35:32 PM net.jxta.logging.Logging logCheckedInfo
INFO: Line 136 net.jxta.impl.endpoint.netty.NettyTransportClient.getMessenger()
processing request to open connection to tcp://192.168.1.11:9712
Aug 14, 2010 1:35:33 PM net.jxta.impl.util.threads.LongTaskDetector run
WARNING: task of type [net.jxta.impl.endpoint.netty.NettyMessenger$1] still running after 1,002ms in thread JxtaWorker-4, current stack:
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:198)
java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedNanos(AbstractQueuedSynchronizer.java:947)
java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireSharedNanos(AbstractQueuedSynchronizer.java:1239)
java.util.concurrent.CountDownLatch.await(CountDownLatch.java:253)
net.jxta.endpoint.MessengerStateBarrier.awaitMatch(MessengerStateBarrier.java:59)
net.jxta.endpoint.AbstractMessenger.waitState(AbstractMessenger.java:245)
net.jxta.impl.endpoint.EndpointServiceImpl.getMessenger(EndpointServiceImpl.java:2044)
net.jxta.impl.rendezvous.PeerConnection.getCachedMessenger(PeerConnection.java:329)
net.jxta.impl.rendezvous.rdv.ClientConnection.connect(ClientConnection.java:98)
net.jxta.impl.rendezvous.rdv.RdvPeerRdvService.addClient(RdvPeerRdvService.java:507)
net.jxta.impl.rendezvous.rdv.RdvPeerRdvService.processLeaseRequest(RdvPeerRdvService.java:652)
net.jxta.impl.rendezvous.rdv.RdvPeerRdvService.access$200(RdvPeerRdvService.java:115)
net.jxta.impl.rendezvous.rdv.RdvPeerRdvService$StdRdvRdvProtocolListener.processIncomingMessage(RdvPeerRdvService.java:254)
net.jxta.impl.endpoint.EndpointServiceImpl.processIncomingMessage(EndpointServiceImpl.java:1027)
net.jxta.impl.endpoint.netty.NettyMessenger$1.run(NettyMessenger.java:148)
net.jxta.impl.util.threads.RunnableAsCallableWrapper.call(RunnableAsCallableWrapper.java:17)
net.jxta.impl.util.threads.RunMetricsWrapper.call(RunMetricsWrapper.java:50)
net.jxta.impl.util.threads.QueueTimeRunMetricsWrapper.call(QueueTimeRunMetricsWrapper.java:34)
net.jxta.impl.util.threads.RunMetricsWrapper.run(RunMetricsWrapper.java:93)
net.jxta.impl.util.threads.QueueTimeRunMetricsWrapper.run(QueueTimeRunMetricsWrapper.java:9)
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
java.lang.Thread.run(Thread.java:619)

I also saw some messages with different private IP addresses... where does this come from?
Aug 14, 2010 1:35:35 PM net.jxta.logging.Logging logCheckedInfo
INFO: Line 136 net.jxta.impl.endpoint.netty.NettyTransportClient.getMessenger()
processing request to open connection to tcp://192.168.164.1:9712
Aug 14, 2010 1:35:37 PM net.jxta.impl.endpoint.netty.NettyTransportClient getMessenger
INFO: Netty transport for protocol tcp failed to connect to tcp://192.168.1.11:9712 within acceptable time
Aug 14, 2010 1:35:37 PM net.jxta.logging.Logging logCheckedWarning
WARNING: Line 449 net.jxta.impl.endpoint.router.EndpointRouter$EndpointGetMessengerAsyncListener.messengerReady()
null messenger for dest :jxta://uuid-59616261646162614E504720503250334564676520414E6EA1008003
Aug 14, 2010 1:35:38 PM net.jxta.logging.Logging logCheckedInfo
INFO: Line 136 net.jxta.impl.endpoint.netty.NettyTransportClient.getMessenger()
processing request to open connection to tcp://192.168.58.1:9712
Aug 14, 2010 1:35:40 PM net.jxta.impl.endpoint.netty.NettyTransportClient getMessenger
INFO: Netty transport for protocol tcp failed to connect to tcp://192.168.164.1:9712 within acceptable time
Aug 14, 2010 1:35:40 PM net.jxta.logging.Logging logCheckedWarning

> iii) Which version in JXTA/JXSE are you using? If it
> is 2.5 please try with 2.6, because 2.5 does not
> detect properly that tcp://192.168.1.11:9710 cannot
> be used from the WAN.
2.6

I checked the NATed IP address with 'w' and I got "213.22.32.184", so NAT is really working as expected...

Cheers,

/rp