/****************************************************************************** * Copyright © 2013-2016 The Nxt Core Developers. * * * * See the AUTHORS.txt, DEVELOPER-AGREEMENT.txt and LICENSE.txt files at * * the top-level directory of this distribution for the individual copyright * * holder information and the developer policies on copyright and licensing. * * * * Unless otherwise agreed in a custom licensing agreement, no part of the * * Nxt software, including this file, may be copied, modified, propagated, * * or distributed except according to the terms contained in the LICENSE.txt * * file. * * * * Removal or modification of this copyright notice is prohibited. * * * ******************************************************************************/ package nxt.util; import nxt.Nxt; import org.bitlet.weupnp.GatewayDevice; import org.bitlet.weupnp.GatewayDiscover; import java.net.InetAddress; import java.util.Map; /** * Forward ports using the UPnP protocol. */ public class UPnP { /** Initialization done */ private static boolean initDone = false; /** UPnP gateway device */ private static GatewayDevice gateway = null; /** Local address */ private static InetAddress localAddress; /** External address */ private static InetAddress externalAddress; /** * Add a port to the UPnP mapping * * @param port Port to add */ public static synchronized void addPort(int port) { if (!initDone) init(); // // Ignore the request if we didn't find a gateway device // if (gateway == null) return; // // Forward the port // try { if (gateway.addPortMapping(port, port, localAddress.getHostAddress(), "TCP", Nxt.APPLICATION + " " + Nxt.VERSION)) { Logger.logDebugMessage("Mapped port [" + externalAddress.getHostAddress() + "]:" + port); } else { Logger.logDebugMessage("Unable to map port " + port); } } catch (Exception exc) { Logger.logErrorMessage("Unable to map port " + port + ": " + exc.toString()); } } /** * Delete a port from the UPnP mapping * * @param port Port to delete */ public static synchronized void deletePort(int port) { if (!initDone || gateway == null) return; // // Delete the port // try { if (gateway.deletePortMapping(port, "TCP")) { Logger.logDebugMessage("Mapping deleted for port " + port); } else { Logger.logDebugMessage("Unable to delete mapping for port " + port); } } catch (Exception exc) { Logger.logErrorMessage("Unable to delete mapping for port " + port + ": " + exc.toString()); } } /** * Return the local address * * @return Local address or null if the address is not available */ public static synchronized InetAddress getLocalAddress() { if (!initDone) init(); return localAddress; } /** * Return the external address * * @return External address or null if the address is not available */ public static synchronized InetAddress getExternalAddress() { if (!initDone) init(); return externalAddress; } /** * Initialize the UPnP support */ private static void init() { initDone = true; // // Discover the gateway devices on the local network // try { Logger.logInfoMessage("Looking for UPnP gateway device..."); GatewayDevice.setHttpReadTimeout(Nxt.getIntProperty("nxt.upnpGatewayTimeout", GatewayDevice.getHttpReadTimeout())); GatewayDiscover discover = new GatewayDiscover(); discover.setTimeout(Nxt.getIntProperty("nxt.upnpDiscoverTimeout", discover.getTimeout())); Map<InetAddress, GatewayDevice> gatewayMap = discover.discover(); if (gatewayMap == null || gatewayMap.isEmpty()) { Logger.logDebugMessage("There are no UPnP gateway devices"); } else { gatewayMap.forEach((addr, device) -> Logger.logDebugMessage("UPnP gateway device found on " + addr.getHostAddress())); gateway = discover.getValidGateway(); if (gateway == null) { Logger.logDebugMessage("There is no connected UPnP gateway device"); } else { localAddress = gateway.getLocalAddress(); externalAddress = InetAddress.getByName(gateway.getExternalIPAddress()); Logger.logDebugMessage("Using UPnP gateway device on " + localAddress.getHostAddress()); Logger.logInfoMessage("External IP address is " + externalAddress.getHostAddress()); } } } catch (Exception exc) { Logger.logErrorMessage("Unable to discover UPnP gateway devices: " + exc.toString()); } } }