forked from I2P_Developers/i2p.i2p
UPnP: IPv6 part 2
Add support for storing multiple location URLs in DeviceData Add methods to prefer IPv6 for location URLs Prefer IPv6 for POST target to WANIPv6FirewallControl service Add method to bind local address for POST, needed for security checks when forwarding IPv6 Remove IPv6 checks from XML URL parser Remove unused call in QueryRequest
This commit is contained in:
@@ -388,6 +388,16 @@ public class HTTPRequest extends HTTPPacket
|
||||
|
||||
private Socket postSocket = null;
|
||||
|
||||
private String bindTo = null;
|
||||
|
||||
/**
|
||||
* I2P - bind HTTP socket to specified local host address
|
||||
*
|
||||
* @param fromHost null to not bind to a particlar local address
|
||||
* @since 0.9.50
|
||||
*/
|
||||
public void setBindHost(String host) { bindTo = host; }
|
||||
|
||||
public HTTPResponse post(String host, int port, boolean isKeepAlive)
|
||||
{
|
||||
HTTPResponse httpRes = new HTTPResponse();
|
||||
@@ -413,6 +423,8 @@ public class HTTPRequest extends HTTPPacket
|
||||
// And set the soTimeout to 2 second (for reads).
|
||||
//postSocket = new Socket(host, port);
|
||||
postSocket = new Socket();
|
||||
if (bindTo != null)
|
||||
postSocket.bind(new InetSocketAddress(bindTo, 0));
|
||||
postSocket.setSoTimeout(2000);
|
||||
SocketAddress sa = new InetSocketAddress(host, port);
|
||||
postSocket.connect(sa, 3000);
|
||||
|
||||
@@ -52,7 +52,7 @@ public class Action
|
||||
////////////////////////////////////////////////
|
||||
|
||||
private Node serviceNode;
|
||||
private Node actionNode;
|
||||
private final Node actionNode;
|
||||
|
||||
private Node getServiceNode()
|
||||
{
|
||||
@@ -369,12 +369,25 @@ public class Action
|
||||
////////////////////////////////////////////////
|
||||
|
||||
public boolean postControlAction()
|
||||
{
|
||||
return postControlAction(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* I2P - bind HTTP socket to specified local host address
|
||||
*
|
||||
* @param fromHost null to not bind to a particlar local address
|
||||
* @since 0.9.50
|
||||
*/
|
||||
public boolean postControlAction(String fromHost)
|
||||
{
|
||||
// Thanks for Giordano Sassaroli <sassarol@cefriel.it> (08/30/03)
|
||||
ArgumentList actionArgList = getArgumentList();
|
||||
ArgumentList actionInputArgList = getInputArgumentList();
|
||||
ActionRequest ctrlReq = new ActionRequest();
|
||||
ctrlReq.setRequest(this, actionInputArgList);
|
||||
if (fromHost != null)
|
||||
ctrlReq.setBindHost(fromHost);
|
||||
if (Debug.isOn() == true)
|
||||
ctrlReq.print();
|
||||
ActionResponse ctrlRes = ctrlReq.post();
|
||||
|
||||
@@ -108,6 +108,9 @@ public class ControlPoint implements HTTPRequestListener
|
||||
|
||||
private final static String DEFAULT_EVENTSUB_URI = "/evetSub";
|
||||
|
||||
// I2P
|
||||
private static final boolean ALLOW_IPV6_LOCATION = true;
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// Member
|
||||
////////////////////////////////////////////////
|
||||
@@ -277,15 +280,20 @@ public class ControlPoint implements HTTPRequestListener
|
||||
Debug.warning("Ignoring localhost device at " + location);
|
||||
return;
|
||||
}
|
||||
if (host.startsWith("[")) {
|
||||
Debug.warning("Ignoring IPv6 device at " + location);
|
||||
return;
|
||||
if (host.startsWith("[") && host.endsWith("]")) {
|
||||
if (!ALLOW_IPV6_LOCATION) {
|
||||
Debug.warning("Ignoring IPv6 device at " + location);
|
||||
return;
|
||||
}
|
||||
// fixup for valid checks below
|
||||
host = host.substring(1, host.length() - 1);
|
||||
}
|
||||
if (!"http".equals(locationUrl.getProtocol())) {
|
||||
Debug.warning("Ignoring non-http device at " + location);
|
||||
return;
|
||||
}
|
||||
if (!Addresses.isIPv4Address(host)) {
|
||||
if (!Addresses.isIPv4Address(host) &&
|
||||
(!ALLOW_IPV6_LOCATION || !Addresses.isIPv6Address(host))) {
|
||||
Debug.warning("Ignoring non-IPv4 address at " + location);
|
||||
return;
|
||||
}
|
||||
@@ -294,7 +302,7 @@ public class ControlPoint implements HTTPRequestListener
|
||||
Debug.warning("Ignoring bad IP at " + location);
|
||||
return;
|
||||
}
|
||||
if (TransportUtil.isPubliclyRoutable(ip, false)) {
|
||||
if (TransportUtil.isPubliclyRoutable(ip, ALLOW_IPV6_LOCATION)) {
|
||||
Debug.warning("Ignoring public address at " + location);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -731,9 +731,18 @@ public class Device implements org.cybergarage.http.HTTPRequestListener,
|
||||
}
|
||||
|
||||
public SSDPPacket getSSDPPacket() {
|
||||
return getSSDPPacket(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* I2P for multiple location support
|
||||
*
|
||||
* @since 0.9.50
|
||||
*/
|
||||
public SSDPPacket getSSDPPacket(boolean preferIPv6) {
|
||||
if (isRootDevice() == false)
|
||||
return null;
|
||||
return getDeviceData().getSSDPPacket();
|
||||
return getDeviceData().getSSDPPacket(preferIPv6);
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////
|
||||
@@ -745,10 +754,19 @@ public class Device implements org.cybergarage.http.HTTPRequestListener,
|
||||
}
|
||||
|
||||
public String getLocation() {
|
||||
SSDPPacket packet = getSSDPPacket();
|
||||
return getLocation(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* I2P for multiple location support
|
||||
*
|
||||
* @since 0.9.50
|
||||
*/
|
||||
public String getLocation(boolean preferIPv6) {
|
||||
SSDPPacket packet = getSSDPPacket(preferIPv6);
|
||||
if (packet != null)
|
||||
return packet.getLocation();
|
||||
return getDeviceData().getLocation();
|
||||
return getDeviceData().getLocation(preferIPv6);
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////
|
||||
|
||||
@@ -50,6 +50,9 @@ import org.cybergarage.upnp.*;
|
||||
|
||||
public class ControlRequest extends SOAPRequest
|
||||
{
|
||||
// I2P see setRequestHost();
|
||||
private static final String WAN_IPV6_CONNECTION = "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1";
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// Constructor
|
||||
////////////////////////////////////////////////
|
||||
@@ -114,8 +117,13 @@ public class ControlRequest extends SOAPRequest
|
||||
|
||||
// Thanks for Rob van den Boomen <rob.van.den.boomen@philips.com> (02/17/04)
|
||||
// BUGFIX, set urlbase from location string if not set in description.xml
|
||||
if (postURL == null || postURL.length() <= 0)
|
||||
postURL = service.getRootDevice().getLocation();
|
||||
if (postURL == null || postURL.length() <= 0) {
|
||||
// I2P
|
||||
// if service is ipv6 service...
|
||||
String type = service.getServiceType();
|
||||
boolean preferIPv6 = WAN_IPV6_CONNECTION.equals(type);
|
||||
postURL = service.getRootDevice().getLocation(preferIPv6);
|
||||
}
|
||||
|
||||
String reqHost = HTTP.getHost(postURL);
|
||||
int reqPort = HTTP.getPort(postURL);
|
||||
|
||||
@@ -74,7 +74,7 @@ public class QueryRequest extends ControlRequest
|
||||
{
|
||||
Service service = stateVar.getService();
|
||||
|
||||
String ctrlURL = service.getControlURL();
|
||||
//String ctrlURL = service.getControlURL();
|
||||
|
||||
setRequestHost(service);
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@ package org.cybergarage.upnp.xml;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.InetAddress;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
import org.cybergarage.util.*;
|
||||
import org.cybergarage.http.*;
|
||||
@@ -27,6 +29,11 @@ import org.cybergarage.upnp.*;
|
||||
import org.cybergarage.upnp.ssdp.*;
|
||||
import org.cybergarage.upnp.device.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* I2P added multiple location support
|
||||
*
|
||||
*/
|
||||
public class DeviceData extends NodeData
|
||||
{
|
||||
public DeviceData()
|
||||
@@ -61,12 +68,43 @@ public class DeviceData extends NodeData
|
||||
////////////////////////////////////////////////
|
||||
|
||||
private String location = "";
|
||||
private String location_ipv6 = "";
|
||||
|
||||
public String getLocation() {
|
||||
return location;
|
||||
return getLocation(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* I2P for multiple location support
|
||||
*
|
||||
* @since 0.9.50
|
||||
*/
|
||||
public String getLocation(boolean preferIPv6) {
|
||||
if (preferIPv6) {
|
||||
if (location_ipv6 != null && !location_ipv6.isEmpty())
|
||||
return location_ipv6;
|
||||
return location;
|
||||
} else {
|
||||
if (location != null && !location.isEmpty())
|
||||
return location;
|
||||
return location_ipv6;
|
||||
}
|
||||
}
|
||||
|
||||
public void setLocation(String location) {
|
||||
if (location != null) {
|
||||
try {
|
||||
URL url = new URL(location);
|
||||
String host = url.getHost();
|
||||
if (host != null && host.startsWith("[")) {
|
||||
location_ipv6 = location;
|
||||
return;
|
||||
}
|
||||
} catch (MalformedURLException me) {
|
||||
Debug.warning("Bad location: " + location, me);
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
@@ -241,12 +279,44 @@ public class DeviceData extends NodeData
|
||||
////////////////////////////////////////////////
|
||||
|
||||
private SSDPPacket ssdpPacket = null;
|
||||
private SSDPPacket ssdpPacket_ipv6 = null;
|
||||
|
||||
public SSDPPacket getSSDPPacket() {
|
||||
return ssdpPacket;
|
||||
return getSSDPPacket(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* I2P for multiple location support
|
||||
*
|
||||
* @since 0.9.50
|
||||
*/
|
||||
public SSDPPacket getSSDPPacket(boolean preferIPv6) {
|
||||
if (preferIPv6) {
|
||||
if (ssdpPacket_ipv6 != null)
|
||||
return ssdpPacket_ipv6;
|
||||
return ssdpPacket;
|
||||
} else {
|
||||
if (ssdpPacket != null)
|
||||
return ssdpPacket;
|
||||
return ssdpPacket_ipv6;
|
||||
}
|
||||
}
|
||||
|
||||
public void setSSDPPacket(SSDPPacket packet) {
|
||||
String location = packet.getLocation();
|
||||
if (location != null) {
|
||||
try {
|
||||
URL url = new URL(location);
|
||||
String host = url.getHost();
|
||||
if (host != null && host.startsWith("[")) {
|
||||
ssdpPacket_ipv6 = packet;
|
||||
return;
|
||||
}
|
||||
} catch (MalformedURLException me) {
|
||||
Debug.warning("Bad location: " + location, me);
|
||||
return;
|
||||
}
|
||||
}
|
||||
ssdpPacket = packet;
|
||||
}
|
||||
|
||||
|
||||
@@ -71,12 +71,13 @@ public abstract class Parser
|
||||
throw new ParserException("Not HTTP");
|
||||
String host = locationURL.getHost();
|
||||
if (host == null ||
|
||||
!Addresses.isIPv4Address(host) ||
|
||||
host.startsWith("127."))
|
||||
throw new ParserException("Bad host " + host);
|
||||
if (host.startsWith("[") && host.endsWith("]"))
|
||||
host = host.substring(1, host.length() - 1);
|
||||
byte[] ip = Addresses.getIP(host);
|
||||
if (ip == null ||
|
||||
TransportUtil.isPubliclyRoutable(ip, false))
|
||||
TransportUtil.isPubliclyRoutable(ip, true))
|
||||
throw new ParserException("Bad host " + host);
|
||||
|
||||
int port = locationURL.getPort();
|
||||
|
||||
Reference in New Issue
Block a user