⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 networkconfigurationdiscoveryprocess.java

📁 stun的java实现
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * Stun4j, the OpenSource Java Solution for NAT and Firewall Traversal.
 *
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */
package net.java.stun4j.client;

import java.net.*;

import net.java.stun4j.*;
import net.java.stun4j.attribute.*;
import net.java.stun4j.message.*;
import net.java.stun4j.stack.*;
import java.util.logging.*;

/**
 * <p>
 * This class implements the STUN Discovery Process as described by section 10.1
 * of rfc 3489.
 * </p><p>
 * 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.
 * </p><p>
 * 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.
 * </p><p>
 * 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.
 * </p><p>
 * 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.
 * </p><p>
 * 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.
 * </p><p>
 * 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).
 * </p><p>
 * <p>Organisation: <p> Louis Pasteur University, Strasbourg, France</p>
 * <p>Network Research Team (http://www-r2.u-strasbg.fr)</p></p>
 * @author Emil Ivov
 * @version 0.1
 */

public class NetworkConfigurationDiscoveryProcess
{
    private static final Logger logger =
        Logger.getLogger(NetworkConfigurationDiscoveryProcess.class.getName());
    /**
     * Indicates whether the underlying stack has been initialized and started
     * and that the discoverer is operational.
     */
    private boolean started = false;

    /**
     * The stack to use for STUN communication.
     */
    private StunStack                stunStack     = null;

    /**
     * The provider to send our messages through
     */
    private StunProvider             stunProvider  = null;

    /**
     * The point where we'll be listening.
     */
    private NetAccessPointDescriptor apDescriptor  = null;

    /**
     * The address of the stun server
     */
    private StunAddress              serverAddress = null;

    /**
     * A utility used to flatten the multithreaded architecture of the Stack
     * and execute the discovery process in a synchronized manner
     */
    private BlockingRequestSender    requestSender = null;

    /**
     * Creates a StunAddressDiscoverer. In order to use it one must start the
     * discoverer.
     * @param localAddress the address where the stach should bind.
     * @param serverAddress the address of the server to interrogate.
     */
    public NetworkConfigurationDiscoveryProcess(StunAddress localAddress,
                                 StunAddress serverAddress)
    {
        apDescriptor       = new NetAccessPointDescriptor(localAddress);
        this.serverAddress = serverAddress;
    }

    /**
     * Creates a StunAddressDiscoverer. In order to use it one must start the
     * discoverer.
     * @param apDescriptor the address where the stach should bind.
     * @param serverAddress the address of the server to interrogate.
     */
    public NetworkConfigurationDiscoveryProcess(NetAccessPointDescriptor apDescriptor,
                                 StunAddress serverAddress)
    {
        this.apDescriptor  = apDescriptor;
        this.serverAddress = serverAddress;

    }

    /**
     * Shuts down the underlying stack and prepares the object for garbage
     * collection.
     */
    public void shutDown()
    {
        stunStack.shutDown();
        stunStack     = null;
        stunProvider  = null;
        apDescriptor  = null;
        requestSender = null;

        this.started = false;

    }

    /**
     * Puts the discoverer into an operational state.
     * @throws StunException if we fail to bind or some other error occurs.
     */
    public void start()
        throws StunException
    {
        stunStack = StunStack.getInstance();
        stunStack.start();

        stunStack.installNetAccessPoint(apDescriptor);

        stunProvider = stunStack.getProvider();

        requestSender = new BlockingRequestSender(stunProvider, apDescriptor);

        started = true;
    }

    /**
     * Implements the discovery process itself (see class description).
     * @return a StunDiscoveryReport containing details about the network
     * configuration of the host where the class is executed.
     * @throws StunException ILLEGAL_STATE if the discoverer has not been started
     * NETWORK_ERROR or ILLEGAL_ARGUMENT if a failure occurs while executing
     * the discovery algorithm
     */
    public StunDiscoveryReport determineAddress()
        throws StunException
    {
        checkStarted();
        StunDiscoveryReport report = new StunDiscoveryReport();
        StunMessageEvent evt = doTestI(serverAddress);

        if(evt == null)
        {
            //UDP Blocked
            report.setNatType(StunDiscoveryReport.UDP_BLOCKING_FIREWALL);
            return report;
        }
        else
        {
            StunAddress mappedAddress =((MappedAddressAttribute)evt.getMessage().
                                            getAttribute(Attribute.MAPPED_ADDRESS)).getAddress();

            logger.info("mapped address is="+mappedAddress
                        +", name=" + mappedAddress.getHostName());

            StunAddress backupServerAddress =((ChangedAddressAttribute) evt.getMessage().
                                            getAttribute(Attribute.CHANGED_ADDRESS)).getAddress();

            logger.info("backup server address is="+backupServerAddress
                        + ", name=" + backupServerAddress.getHostName());

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -