diff --git a/router/java/src/org/cybergarage/upnp/ControlPoint.java b/router/java/src/org/cybergarage/upnp/ControlPoint.java index 00638a119..fa5b0874b 100644 --- a/router/java/src/org/cybergarage/upnp/ControlPoint.java +++ b/router/java/src/org/cybergarage/upnp/ControlPoint.java @@ -97,6 +97,9 @@ import org.cybergarage.xml.NodeList; import org.cybergarage.xml.Parser; import org.cybergarage.xml.ParserException; +import net.i2p.util.Addresses; +import net.i2p.router.transport.TransportUtil; + public class ControlPoint implements HTTPRequestListener { private final static int DEFAULT_EVENTSUB_PORT = 8058; @@ -242,15 +245,9 @@ public class ControlPoint implements HTTPRequestListener { if (ssdpPacket.isRootDevice() == false) return; - + String usn = ssdpPacket.getUSN(); - String udn = USN.getUDN(usn); - Device dev = getDevice(udn); - if (dev != null) { - dev.setSSDPPacket(ssdpPacket); - return; - } - + String location = ssdpPacket.getLocation(); try { URL locationUrl = new URL(location); @@ -263,13 +260,59 @@ public class ControlPoint implements HTTPRequestListener return; } } + // I2P + // We duplicate all the checks in Parser.parse() because they + // are bypassed for a known device. + // Devices may send two SSDP responses, one with an IPv4 location + // and one with an IPv6 location. + // Do these check BEFORE we call dev.setSSDPPacket() so we don't + // overwrite the SSDPPacket in DeviceData. + // TODO handle multiple locations in DeviceData. + String host = locationUrl.getHost(); + if (host == null) { + Debug.warning("Ignoring device with bad URL at " + location); + return; + } + if (host.startsWith("127.")) { + Debug.warning("Ignoring localhost device at " + location); + return; + } + if (host.startsWith("[")) { + Debug.warning("Ignoring IPv6 device at " + location); + return; + } + if (!"http".equals(locationUrl.getProtocol())) { + Debug.warning("Ignoring non-http device at " + location); + return; + } + if (!Addresses.isIPv4Address(host)) { + Debug.warning("Ignoring non-IPv4 address at " + location); + return; + } + byte[] ip = Addresses.getIP(host); + if (ip == null) { + Debug.warning("Ignoring bad IP at " + location); + return; + } + if (TransportUtil.isPubliclyRoutable(ip, false)) { + Debug.warning("Ignoring public address at " + location); + return; + } + String udn = USN.getUDN(usn); + Device dev = getDevice(udn); + if (dev != null) { + Debug.warning("Additional SSDP for " + udn + " at " + location); + dev.setSSDPPacket(ssdpPacket); + return; + } + Parser parser = UPnP.getXMLParser(); Node rootNode = parser.parse(locationUrl); Device rootDev = getDevice(rootNode); if (rootDev == null) return; rootDev.setSSDPPacket(ssdpPacket); - Debug.warning("Add root device", new Exception("received on " + ssdpPacket.getLocalAddress())); + Debug.warning("Add root device at " + location, new Exception("received on " + ssdpPacket.getLocalAddress())); addDevice(rootNode); // Thanks for Oliver Newell (2004/10/16)