You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
245 lines
6.2 KiB
245 lines
6.2 KiB
16 years ago
|
// UPnP.java
|
||
|
// (C) 2009 by David Wieditz; d.wieditz@gmx.de
|
||
|
// first published 14.02.2009 on http://yacy.net
|
||
|
//
|
||
|
// This is a part of YaCy, a peer-to-peer based web search engine
|
||
|
//
|
||
|
// LICENSE
|
||
|
//
|
||
|
// This program is free software; you can redistribute it and/or modify
|
||
|
// it under the terms of the GNU General Public License as published by
|
||
|
// the Free Software Foundation; either version 2 of the License, or
|
||
|
// (at your option) any later version.
|
||
|
//
|
||
|
// This program is distributed in the hope that it will be useful,
|
||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
// GNU General Public License for more details.
|
||
|
//
|
||
|
// You should have received a copy of the GNU General Public License
|
||
|
// along with this program; if not, write to the Free Software
|
||
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||
|
|
||
11 years ago
|
package net.yacy.utils.upnp;
|
||
16 years ago
|
|
||
|
import java.io.IOException;
|
||
11 years ago
|
import java.net.InetAddress;
|
||
11 years ago
|
import java.util.EnumMap;
|
||
11 years ago
|
import java.util.Map;
|
||
11 years ago
|
import java.util.Map.Entry;
|
||
11 years ago
|
|
||
|
import javax.xml.parsers.ParserConfigurationException;
|
||
16 years ago
|
|
||
12 years ago
|
import net.yacy.cora.util.ConcurrentLog;
|
||
14 years ago
|
import net.yacy.search.Switchboard;
|
||
11 years ago
|
|
||
|
import org.bitlet.weupnp.GatewayDevice;
|
||
|
import org.bitlet.weupnp.GatewayDiscover;
|
||
|
import org.xml.sax.SAXException;
|
||
16 years ago
|
|
||
|
public class UPnP {
|
||
11 years ago
|
|
||
|
private static final ConcurrentLog LOG = new ConcurrentLog("UPNP");
|
||
|
private static final Switchboard SB = Switchboard.getSwitchboard();
|
||
|
|
||
|
private static Map<InetAddress, GatewayDevice> GATEWAY_DEVICES = null;
|
||
|
|
||
11 years ago
|
private static final Map<UPnPMappingType, UPnPMapping> MAPPINGS = new EnumMap<>(
|
||
|
UPnPMappingType.class);
|
||
|
static {
|
||
|
MAPPINGS.put(UPnPMappingType.HTTP, new UPnPMapping("port", null, "TCP",
|
||
|
"YaCy HTTP"));
|
||
|
MAPPINGS.put(UPnPMappingType.HTTPS, new UPnPMapping("port.ssl",
|
||
|
"server.https", "TCP", "YaCy HTTPS"));
|
||
|
}
|
||
11 years ago
|
|
||
16 years ago
|
private static boolean init() {
|
||
|
boolean init = true;
|
||
11 years ago
|
|
||
16 years ago
|
try {
|
||
11 years ago
|
if (GATEWAY_DEVICES == null) {
|
||
|
GATEWAY_DEVICES = new GatewayDiscover().discover();
|
||
|
}
|
||
|
} catch (IOException | SAXException | ParserConfigurationException e) {
|
||
16 years ago
|
init = false;
|
||
|
}
|
||
11 years ago
|
if (GATEWAY_DEVICES != null) {
|
||
|
for (final GatewayDevice gatewayDevice : GATEWAY_DEVICES.values()) {
|
||
|
LOG.info("found device: " + gatewayDevice.getFriendlyName());
|
||
16 years ago
|
}
|
||
|
} else {
|
||
11 years ago
|
LOG.info("no device found");
|
||
16 years ago
|
init = false;
|
||
|
}
|
||
11 years ago
|
|
||
16 years ago
|
return init;
|
||
|
}
|
||
11 years ago
|
|
||
16 years ago
|
/**
|
||
11 years ago
|
* Add port mappings for configured ports.
|
||
|
*/
|
||
|
public static void addPortMappings() {
|
||
|
if (SB == null) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
UPnPMapping mapping;
|
||
|
for (final Entry<UPnPMappingType, UPnPMapping> entry : MAPPINGS
|
||
|
.entrySet()) {
|
||
|
mapping = entry.getValue();
|
||
|
|
||
|
addPortMapping(entry.getKey(), mapping,
|
||
|
SB.getConfigInt(mapping.getConfigPortKey(), 0));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Remove all port mappings.
|
||
16 years ago
|
*/
|
||
11 years ago
|
public static void deletePortMappings() {
|
||
|
|
||
11 years ago
|
if (SB == null) {
|
||
|
return;
|
||
|
}
|
||
11 years ago
|
|
||
|
UPnPMapping mapping;
|
||
|
for (final Entry<UPnPMappingType, UPnPMapping> entry : MAPPINGS
|
||
|
.entrySet()) {
|
||
|
mapping = entry.getValue();
|
||
|
deletePortMapping(mapping);
|
||
|
}
|
||
16 years ago
|
}
|
||
11 years ago
|
|
||
16 years ago
|
/**
|
||
11 years ago
|
* Add port mapping to all gateway devices on the network.<br/>
|
||
11 years ago
|
* Latest port mapping will be removed.
|
||
|
*
|
||
11 years ago
|
* TODO: don't try to map already mapped port again, find alternative
|
||
|
*
|
||
|
* @param type
|
||
|
* mapping type
|
||
|
* @param mapping
|
||
|
* contains data about mapping
|
||
16 years ago
|
* @param port
|
||
11 years ago
|
* port number to map
|
||
16 years ago
|
*/
|
||
11 years ago
|
public static void addPortMapping(final UPnPMappingType type,
|
||
|
final UPnPMapping mapping, final int port) {
|
||
|
|
||
11 years ago
|
if (port < 1) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
11 years ago
|
if (mapping.getPort() > 0) {
|
||
|
deletePortMapping(mapping); // delete old mapping first
|
||
11 years ago
|
}
|
||
|
|
||
11 years ago
|
if ((mapping.isConfigEnabledKeyEmpty() || SB.getConfigBool(
|
||
|
mapping.getConfigEnabledKey(), false))
|
||
|
&& mapping.getPort() == 0
|
||
|
&& ((GATEWAY_DEVICES != null) || init())) {
|
||
11 years ago
|
|
||
|
String localHostIP;
|
||
|
boolean mapped;
|
||
|
String msg;
|
||
|
for (final GatewayDevice gatewayDevice : GATEWAY_DEVICES.values()) {
|
||
|
|
||
16 years ago
|
try {
|
||
11 years ago
|
localHostIP = toString(gatewayDevice.getLocalAddress());
|
||
|
|
||
|
mapped = gatewayDevice.addPortMapping(port, port,
|
||
11 years ago
|
localHostIP, mapping.getProtocol(),
|
||
|
mapping.getDescription());
|
||
11 years ago
|
|
||
|
msg = "port " + port + " on device "
|
||
|
+ gatewayDevice.getFriendlyName();
|
||
|
|
||
16 years ago
|
if (mapped) {
|
||
11 years ago
|
LOG.info("mapped " + msg);
|
||
11 years ago
|
mapping.setPort(port);
|
||
11 years ago
|
} else {
|
||
|
LOG.warn("could not map " + msg);
|
||
16 years ago
|
}
|
||
11 years ago
|
} catch (IOException | SAXException e) {
|
||
|
LOG.severe("mapping error: " + e.getMessage());
|
||
|
}
|
||
16 years ago
|
}
|
||
|
}
|
||
|
}
|
||
11 years ago
|
|
||
16 years ago
|
/**
|
||
11 years ago
|
* Delete current port mapping.
|
||
11 years ago
|
*
|
||
|
* @param mapping
|
||
|
* to delete
|
||
16 years ago
|
*/
|
||
11 years ago
|
public static void deletePortMapping(final UPnPMapping mapping) {
|
||
|
if (mapping.getPort() > 0 && GATEWAY_DEVICES != null) {
|
||
11 years ago
|
|
||
|
boolean unmapped;
|
||
|
String msg;
|
||
|
for (final GatewayDevice gatewayDevice : GATEWAY_DEVICES.values()) {
|
||
|
|
||
16 years ago
|
try {
|
||
11 years ago
|
unmapped = gatewayDevice.deletePortMapping(
|
||
|
mapping.getPort(), mapping.getProtocol());
|
||
11 years ago
|
|
||
11 years ago
|
msg = "port " + mapping.getPort() + " on device "
|
||
11 years ago
|
+ gatewayDevice.getFriendlyName();
|
||
|
|
||
|
if (unmapped) {
|
||
|
LOG.info("unmapped " + msg);
|
||
|
} else {
|
||
|
LOG.warn("could not unmap " + msg);
|
||
|
}
|
||
|
|
||
|
} catch (SAXException | IOException e) {
|
||
|
LOG.severe("unmapping error: " + e.getMessage());
|
||
|
}
|
||
16 years ago
|
}
|
||
11 years ago
|
|
||
11 years ago
|
mapping.setPort(0); // reset mapped port
|
||
16 years ago
|
}
|
||
|
}
|
||
11 years ago
|
|
||
16 years ago
|
/**
|
||
11 years ago
|
* Gets currently mapped port.
|
||
|
*
|
||
11 years ago
|
* @param type
|
||
|
* mapping type
|
||
|
*
|
||
11 years ago
|
* @return mapped port or 0 if no port is mapped
|
||
16 years ago
|
*/
|
||
11 years ago
|
public static int getMappedPort(final UPnPMappingType type) {
|
||
|
|
||
|
if (type == null) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
return MAPPINGS.get(type).getPort();
|
||
16 years ago
|
}
|
||
11 years ago
|
|
||
|
private static String toString(final InetAddress inetAddress) {
|
||
|
|
||
|
final String localHostIP;
|
||
|
|
||
|
if (inetAddress != null) {
|
||
|
|
||
|
localHostIP = inetAddress.getHostAddress();
|
||
|
|
||
|
if (!inetAddress.isSiteLocalAddress()
|
||
|
|| localHostIP.startsWith("127.")) {
|
||
|
LOG.warn("found odd local address: " + localHostIP
|
||
|
+ "; UPnP may fail");
|
||
16 years ago
|
}
|
||
11 years ago
|
} else {
|
||
|
|
||
|
localHostIP = "";
|
||
|
LOG.warn("unknown local address, UPnP may fail");
|
||
16 years ago
|
}
|
||
11 years ago
|
|
||
|
return localHostIP;
|
||
16 years ago
|
}
|
||
16 years ago
|
|
||
|
}
|