[freenet-cvs] r13325 - trunk/plugins/UPnP
nextgens at freenetproject.org
nextgens at freenetproject.org
Wed May 23 00:08:07 UTC 2007
Author: nextgens
Date: 2007-05-23 00:08:07 +0000 (Wed, 23 May 2007)
New Revision: 13325
Modified:
trunk/plugins/UPnP/UPnP.java
Log:
UPnP: import some working code from Limewire (GPL too) ; now the plugin gets the external ip address \o/
Modified: trunk/plugins/UPnP/UPnP.java
===================================================================
--- trunk/plugins/UPnP/UPnP.java 2007-05-22 23:44:05 UTC (rev 13324)
+++ trunk/plugins/UPnP/UPnP.java 2007-05-23 00:08:07 UTC (rev 13325)
@@ -3,7 +3,7 @@
* http://www.gnu.org/ for further details of the GPL. */
package plugins.UPnP;
-import java.util.LinkedList;
+import java.util.Iterator;
import plugins.UPnP.org.cybergarage.upnp.Action;
import plugins.UPnP.org.cybergarage.upnp.ActionList;
@@ -16,7 +16,6 @@
import plugins.UPnP.org.cybergarage.upnp.ServiceList;
import plugins.UPnP.org.cybergarage.upnp.ServiceStateTable;
import plugins.UPnP.org.cybergarage.upnp.StateVariable;
-import plugins.UPnP.org.cybergarage.upnp.control.QueryRequest;
import plugins.UPnP.org.cybergarage.upnp.device.DeviceChangeListener;
import plugins.UPnP.org.cybergarage.upnp.xml.StateVariableData;
import freenet.pluginmanager.FredPlugin;
@@ -31,35 +30,104 @@
*
* @author Florent Daignière <nextgens at freenetproject.org>
*
+ *
+ * some code has been borrowed from Limewire : @see com.limegroup.gnutella.UPnPManager
+ *
* @see http://www.upnp.org/
* @see http://en.wikipedia.org/wiki/Universal_Plug_and_Play
*/
-public class UPnP implements FredPluginHTTP, FredPlugin, FredPluginThreadless, DeviceChangeListener {
- private ControlPoint upnpControlPoint;
- private final LinkedList igdList = new LinkedList();
+public class UPnP extends ControlPoint implements FredPluginHTTP, FredPlugin, FredPluginThreadless, DeviceChangeListener {
+
+ /** some schemas */
+ private static final String ROUTER_DEVICE = "urn:schemas-upnp-org:device:InternetGatewayDevice:1";
+ private static final String WAN_DEVICE = "urn:schemas-upnp-org:device:WANDevice:1";
+ private static final String WANCON_DEVICE = "urn:schemas-upnp-org:device:WANConnectionDevice:1";
+ private static final String WAN_IP_CONNECTION = "urn:schemas-upnp-org:service:WANIPConnection:1";
+ private volatile Device _router;
+ private volatile Service _service;
+ private final Object lock = new Object();
+
+ public UPnP() {
+ super();
+ addDeviceChangeListener(this);
+ }
+
public void runPlugin(PluginRespirator pr) {
- upnpControlPoint = new ControlPoint();
- upnpControlPoint.addDeviceChangeListener(this);
- upnpControlPoint.start();
+ start();
}
public void terminate() {
- upnpControlPoint.stop();
+ stop();
}
- public void deviceAdded(Device dev ){
- if(!"InternetGatewayDevice".equals(dev.getDeviceType()))
- return;
-
- System.out.println("##################Detected a new gateway ! "+dev.getFriendlyName());
- igdList.add(dev);
+ public void deviceAdded(Device dev ) {
+ synchronized (lock) {
+ if(isNATPresent())
+ return; // We don't handle more than one IGD.
+
+ if(!ROUTER_DEVICE.equals(dev.getDeviceType()) || !dev.isRootDevice())
+ return;
+ _router = dev;
+ discoverService();
+ }
}
+ /**
+ * Traverses the structure of the router device looking for the port mapping service.
+ */
+ private void discoverService() {
+ synchronized (lock) {
+ for (Iterator iter = _router.getDeviceList().iterator();iter.hasNext();) {
+ Device current = (Device)iter.next();
+ if (!current.getDeviceType().equals(WAN_DEVICE))
+ continue;
+
+ DeviceList l = current.getDeviceList();
+ for (int i=0;i<current.getDeviceList().size();i++) {
+ Device current2 = l.getDevice(i);
+
+ if (!current2.getDeviceType().equals(WANCON_DEVICE))
+ continue;
+
+ _service = current2.getService(WAN_IP_CONNECTION);
+ return;
+ }
+ }
+ }
+ }
+
public void deviceRemoved(Device dev ){
- igdList.remove(dev);
+ synchronized (lock) {
+ if(_router.equals(dev)) {
+ _router = null;
+ _service = null;
+ }
+ }
}
+ /**
+ * @return whether we are behind an UPnP-enabled NAT/router
+ */
+ public boolean isNATPresent() {
+ return _router != null && _service != null;
+ }
+
+ /**
+ * @return the external address the NAT thinks we have. Blocking.
+ * null if we can't find it.
+ */
+ public String getNATAddress() {
+ if (!isNATPresent())
+ return null;
+
+ Action getIP = _service.getAction("GetExternalIPAddress");
+ if(getIP == null || !getIP.postControlAction())
+ return null;
+
+ return ((Argument)getIP.getOutputArgumentList().getArgument("NewExternalIPAddress")).getValue();
+ }
+
private void listStateTable(Service serv, StringBuffer sb) {
ServiceStateTable table = serv.getServiceStateTable();
sb.append("<div><small>");
@@ -94,6 +162,15 @@
return (data == null ? "null" : data.getValue());
}
+ private String toString(String action, String Argument, Service serv) {
+ Action getIP = serv.getAction(action);
+ if(getIP == null || !getIP.postControlAction())
+ return null;
+
+ Argument ret = getIP.getOutputArgumentList().getArgument(Argument);
+ return ret.getValue();
+ }
+
private void listSubServices(Device dev, StringBuffer sb) {
ServiceList sl = dev.getServiceList();
for(int i=0; i<sl.size(); i++) {
@@ -134,15 +211,11 @@
StateVariable defaultConnectionService = serv.getStateVariable("DefaultConnectionService");
if(defaultConnectionService != null)
sb.append("DefaultConnectionService: " + toString(defaultConnectionService.getStateVariableData()));
- }else if("urn:schemas-upnp-org:service:WANIPConnection:1".equals(serv.getServiceType())){
- StateVariable linkStatus = serv.getStateVariable("ConnectionStatus");
- StateVariable externalIPAddress = serv.getStateVariable("ExternalIPAddress");
-
+ }else if(WAN_IP_CONNECTION.equals(serv.getServiceType())){
sb.append("WANIPConnection");
- if(linkStatus != null)
- sb.append(" status: " + toString(linkStatus.getStateVariableData()));
- if(externalIPAddress != null)
- sb.append(" external IP: " + toString(externalIPAddress.getStateVariableData()) + "<br>");
+ sb.append(" status: " + toString("GetStatusInfo", "NewConnectionStatus", serv));
+ sb.append(" type: " + toString("GetConnectionTypeInfo", "NewConnectionType", serv));
+ sb.append(" external IP: " + toString("GetExternalIPAddress", "NewExternalIPAddress", serv) + "<br>");
}else if("urn:schemas-upnp-org:service:WANEthernetLinkConfig:1".equals(serv.getServiceType())){
StateVariable linkStatus = serv.getStateVariable("EthernetLinkStatus");
@@ -185,14 +258,13 @@
public String handleHTTPGet(HTTPRequest request) throws PluginHTTPException {
StringBuffer sb = new StringBuffer();
sb.append("<html><body>");
- sb.append(igdList.size() + "<br>");
- DeviceList rootDevList = upnpControlPoint.getDeviceList();
- for(int i=0; i<rootDevList.size(); i++) {
- Device dev = rootDevList.getDevice(i);
- if(!"urn:schemas-upnp-org:device:InternetGatewayDevice:1".equals(dev.getDeviceType())) continue;
- listSubDev("WANDevice", dev, sb);
- }
+ sb.append("<h2>Our current ip address is : " + getNATAddress() + "</h2>");
+
+ if(_router != null)
+ listSubDev("WANDevice", _router, sb);
+ else
+ sb.append("No UPnP aware device has been found!");
sb.append("</body></html>");
return sb.toString();
@@ -208,4 +280,4 @@
// TODO Auto-generated method stub
return null;
}
-}
+}
\ No newline at end of file
More information about the cvs
mailing list