SIP Communicator: the OpenSource Java VoIP and Instant Messaging client.

net.java.sip.communicator.impl.netaddr
Class StunClient

java.lang.Object
  extended by net.java.sip.communicator.impl.netaddr.StunClient

public class StunClient
extends Object

This class implements the STUN Discovery Process as described by section 10.1 of rfc 3489.

The flow makes use of three tests. In test I, the client sends a STUN Binding Request to a server, without any flags set in the CHANGE-REQUEST attribute, and without the RESPONSE-ADDRESS attribute. This causes the server to send the response back to the address and port that the request came from. In test II, the client sends a Binding Request with both the "change IP" and "change port" flags from the CHANGE-REQUEST attribute set. In test III, the client sends a Binding Request with only the "change port" flag set.

The client begins by initiating test I. If this test yields no response, the client knows right away that it is not capable of UDP connectivity. If the test produces a response, the client examines the MAPPED-ADDRESS attribute. If this address and port are the same as the local IP address and port of the socket used to send the request, the client knows that it is not natted. It executes test II.

If a response is received, the client knows that it has open access to the Internet (or, at least, its behind a firewall that behaves like a full-cone NAT, but without the translation). If no response is received, the client knows its behind a symmetric UDP firewall.

In the event that the IP address and port of the socket did not match the MAPPED-ADDRESS attribute in the response to test I, the client knows that it is behind a NAT. It performs test II. If a response is received, the client knows that it is behind a full-cone NAT. If no response is received, it performs test I again, but this time, does so to the address and port from the CHANGED-ADDRESS attribute from the response to test I. If the IP address and port returned in the MAPPED-ADDRESS attribute are not the same as the ones from the first test I, the client knows its behind a symmetric NAT. If the address and port are the same, the client is either behind a restricted or port restricted NAT. To make a determination about which one it is behind, the client initiates test III. If a response is received, its behind a restricted NAT, and if no response is received, its behind a port restricted NAT.

This procedure yields substantial information about the operating condition of the client application. In the event of multiple NATs between the client and the Internet, the type that is discovered will be the type of the most restrictive NAT between the client and the Internet. The types of NAT, in order of restrictiveness, from most to least, are symmetric, port restricted cone, restricted cone, and full cone.

Typically, a client will re-do this discovery process periodically to detect changes, or look for inconsistent results. It is important to note that when the discovery process is redone, it should not generally be done from the same local address and port used in the previous discovery process. If the same local address and port are reused, bindings from the previous test may still be in existence, and these will invalidate the results of the test. Using a different local address and port for subsequent tests resolves this problem. An alternative is to wait sufficiently long to be confident that the old bindings have expired (half an hour should more than suffice).

Organisation:

Louis Pasteur University, Strasbourg, France

Network Research Team (http://www-r2.u-strasbg.fr)

Version:
0.1
Author:
Emil Ivov

Constructor Summary
StunClient(net.java.stun4j.NetAccessPointDescriptor apDescriptor, net.java.stun4j.StunAddress serverAddress)
          Creates a StunAddressDiscoverer.
StunClient(net.java.stun4j.StunAddress localAddress)
          Creates a StunAddressDiscoverer.
 
Method Summary
 net.java.stun4j.StunMessageEvent doStunTestI(net.java.stun4j.StunAddress serverAddress)
          Sends a binding request to the specified server address.
 net.java.stun4j.StunMessageEvent doStunTestII(net.java.stun4j.StunAddress serverAddress)
          Sends a binding request to the specified server address with both change IP and change port flags are set to true.
 net.java.stun4j.StunMessageEvent doStunTestIII(net.java.stun4j.StunAddress serverAddress)
          Sends a binding request to the specified server address with only change port flag set to true and change IP flag - to false.
 void shutDown()
          Shuts down the underlying stack and prepares the object for garbage collection.
 void start()
          Puts the discoverer into an operational state.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

StunClient

public StunClient(net.java.stun4j.StunAddress localAddress)
Creates a StunAddressDiscoverer. In order to use it one must start the discoverer.

Parameters:
localAddress - the address where the stach should bind.

StunClient

public StunClient(net.java.stun4j.NetAccessPointDescriptor apDescriptor,
                  net.java.stun4j.StunAddress serverAddress)
Creates a StunAddressDiscoverer. In order to use it one must start the discoverer.

Parameters:
apDescriptor - the address where the stach should bind.
serverAddress - the address of the server to interrogate.
Method Detail

shutDown

public void shutDown()
Shuts down the underlying stack and prepares the object for garbage collection.


start

public void start()
           throws net.java.stun4j.StunException
Puts the discoverer into an operational state.

Throws:
net.java.stun4j.StunException - if we fail to bind or some other error occurs.

doStunTestI

public net.java.stun4j.StunMessageEvent doStunTestI(net.java.stun4j.StunAddress serverAddress)
                                             throws net.java.stun4j.StunException
Sends a binding request to the specified server address. Both change IP and change port flags are set to false.

Parameters:
serverAddress - the address where to send the bindingRequest.
Returns:
The returned message encapsulating event or null if no message was received.
Throws:
net.java.stun4j.StunException - if an exception occurs while sending the messge

doStunTestII

public net.java.stun4j.StunMessageEvent doStunTestII(net.java.stun4j.StunAddress serverAddress)
                                              throws net.java.stun4j.StunException
Sends a binding request to the specified server address with both change IP and change port flags are set to true.

Parameters:
serverAddress - the address where to send the bindingRequest.
Returns:
The returned message encapsulating event or null if no message was received.
Throws:
net.java.stun4j.StunException - if an exception occurs while sending the messge

doStunTestIII

public net.java.stun4j.StunMessageEvent doStunTestIII(net.java.stun4j.StunAddress serverAddress)
                                               throws net.java.stun4j.StunException
Sends a binding request to the specified server address with only change port flag set to true and change IP flag - to false.

Parameters:
serverAddress - the address where to send the bindingRequest.
Returns:
The returned message encapsulating event or null if no message was received.
Throws:
net.java.stun4j.StunException - if an exception occurs while sending the messge

SIP Communicator: the OpenSource Java VoIP and Instant Messaging client.

SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
Distributable under LGPL license.