Example #1
0
 public UPnPManager(RouterContext context, TransportManager manager) {
     _context = context;
     _manager = manager;
     _log = _context.logManager().getLog(UPnPManager.class);
     // UPnP wants to bind to IPv6 link local interfaces by default, but what UPnP router
     // is going to want to talk IPv6 anyway? Just make it easy and force IPv4 only
     org.cybergarage.upnp.UPnP.setEnable(org.cybergarage.upnp.UPnP.USE_ONLY_IPV4_ADDR);
     // set up logging in the UPnP package
     Debug.initialize(context);
     _upnp = new UPnP(context);
     _upnp.setHTTPPort(_context.getProperty(PROP_HTTP_PORT, DEFAULT_HTTP_PORT));
     _upnp.setSSDPPort(_context.getProperty(PROP_SSDP_PORT, DEFAULT_SSDP_PORT));
     _upnpCallback = new UPnPCallback();
     _rescanner = new Rescanner();
 }
Example #2
0
    /**
     * Call when the ports might have changed
     * The transports can call this pretty quickly at startup,
     * which can have multiple UPnP threads running at once, but
     * that should be ok.
     */
    public void update(Set<TransportManager.Port> ports) {
        if (_log.shouldLog(Log.DEBUG))
            _log.debug("UPnP Update with " + ports.size() + " ports");

        //synchronized(this) {
            // TODO
            // called too often and may block for too long
            // may not have started if net was disconnected previously
            //if (!_isRunning && !ports.isEmpty())
            //    start();
            if (!_isRunning)
                return;
        //}

        Set<ForwardPort> forwards = new HashSet<ForwardPort>(ports.size());
        for (TransportManager.Port entry : ports) {
            String style = entry.style;
            int port = entry.port;
            int protocol = -1;
            if ("SSU".equals(style))
                protocol = ForwardPort.PROTOCOL_UDP_IPV4;
            else if ("NTCP".equals(style))
                protocol = ForwardPort.PROTOCOL_TCP_IPV4;
            else
                continue;
            if (_log.shouldLog(Log.DEBUG))
                _log.debug("Adding: " + style + " " + port);
            ForwardPort fp = new ForwardPort(style, false, protocol, port);
            forwards.add(fp);
        }
        // non-blocking
        _upnp.onChangePublicPorts(forwards, _upnpCallback);
    }
Example #3
0
 /** @since 1.8.0 */
 public boolean loadSCPD(InputStream input) throws ParserException {
   Parser parser = UPnP.getXMLParser();
   Node scpdNode = parser.parse(input);
   if (scpdNode == null) return false;
   ServiceData data = getServiceData();
   data.setSCPDNode(scpdNode);
   return true;
 }
Example #4
0
 public boolean loadSCPD(String scpdStr) throws InvalidDescriptionException {
   try {
     Parser parser = UPnP.getXMLParser();
     Node scpdNode = parser.parse(scpdStr);
     if (scpdNode == null) return false;
     ServiceData data = getServiceData();
     data.setSCPDNode(scpdNode);
   } catch (ParserException e) {
     throw new InvalidDescriptionException(e);
   }
   return true;
 }
Example #5
0
 /**
  *  Blocking, may take a while, up to 20 seconds
  */
 public synchronized void stop() {
     if (_log.shouldLog(Log.DEBUG))
         _log.debug("UPnP Stop");
     _shouldBeRunning = false;
     _rescanner.cancel();
     if (_isRunning)
         _upnp.terminate();
     _isRunning = false;
     _detectedAddress = null;
     if (_log.shouldLog(Log.DEBUG))
         _log.debug("UPnP Stop Done");
 }
Example #6
0
  public void announce(String bindAddr) {
    // uuid:device-UUID::urn:schemas-upnp-org:service:serviceType:v
    Device rootDev = getRootDevice();
    String devLocation = rootDev.getLocationURL(bindAddr);
    String serviceNT = getNotifyServiceTypeNT();
    String serviceUSN = getNotifyServiceTypeUSN();

    Device dev = getDevice();

    SSDPNotifyRequest ssdpReq = new SSDPNotifyRequest();
    ssdpReq.setServer(UPnP.getServerName());
    ssdpReq.setLeaseTime(dev.getLeaseTime());
    ssdpReq.setLocation(devLocation);
    ssdpReq.setNTS(NTS.ALIVE);
    ssdpReq.setNT(serviceNT);
    ssdpReq.setUSN(serviceUSN);

    SSDPNotifySocket ssdpSock = new SSDPNotifySocket(bindAddr);
    Device.notifyWait();
    ssdpSock.post(ssdpReq);
  }
Example #7
0
 /**
  *  Call when IP or network connectivity might have changed.
  *  Starts UPnP if previous start failed, else starts a search.
  *  Must have called start() first, and not called stop().
  *
  *  Should be fast. This only starts the search, the responses
  *  will come in over the MX time (3 seconds).
  *
  *  @since 0.9.18
  */
 public synchronized void rescan() {
     if (!_shouldBeRunning)
         return;
     if (_context.router().gracefulShutdownInProgress())
         return;
     long now = System.currentTimeMillis();
     if (_lastRescan + RESCAN_MIN_DELAY > now)
         return;
     _lastRescan = now;
     if (_log.shouldLog(Log.DEBUG))
         _log.debug("UPnP Rescan Start");
     if (_isRunning) {
         // TODO default search MX (jitter) is 3 seconds... reduce?
         // See also:
         // Adaptive Jitter Control for UPnP M-Search
         // Kevin Mills and Christopher Dabrowski
         _upnp.search();
     } else {
         start();
     }
 }
Example #8
0
 /**
  *  Blocking, may take a while
  */
 public synchronized void start() {
     if (_log.shouldLog(Log.DEBUG))
         _log.debug("UPnP Start");
     _shouldBeRunning = true;
     if (!_isRunning) {
         long b = _context.clock().now();
         try {
             _isRunning = _upnp.runPlugin();
             if (_log.shouldLog(Log.INFO))
                 _log.info("UPnP runPlugin took " + (_context.clock().now() - b));
         } catch (Exception e) {
             // NPE in UPnP (ticket #728), can't let it bring us down
             if (!_errorLogged) {
                 _log.error("UPnP error, please report", e);
                 _errorLogged = true;
             }
         }
     }
     if (_isRunning) {
         _rescanner.schedule(RESCAN_LONG_DELAY);
         if (_log.shouldLog(Log.DEBUG))
             _log.debug("UPnP Start Done");
     } else {
         _rescanner.schedule(RESCAN_SHORT_DELAY);
         // Do we have a non-loopback, non-broadcast address?
         // If not, that's why it failed (HTTPServer won't start)
         if (!Addresses.isConnected()) {
             if (!_disconLogged) {
                 _log.logAlways(Log.WARN, "UPnP start failed - no network connection?");
                 _disconLogged = true;
             }
         } else {
             _log.error("UPnP start failed - port conflict?");
         }
     }
 }
Example #9
0
 private Node getSCPDNode(File scpdFile) throws ParserException {
   Parser parser = UPnP.getXMLParser();
   return parser.parse(scpdFile);
 }
Example #10
0
 private Node getSCPDNode(URL scpdUrl) throws ParserException {
   Parser parser = UPnP.getXMLParser();
   return parser.parse(scpdUrl);
 }
Example #11
0
  protected void startUp() {
    if (upnp != null) {

      // already started up, must have been re-enabled

      refreshMappings();

      return;
    }

    final LoggerChannel core_log = plugin_interface.getLogger().getChannel("UPnP Core");

    try {
      upnp =
          UPnPFactory.getSingleton(
              new UPnPAdapter() {
                Set exception_traces = new HashSet();

                public SimpleXMLParserDocument parseXML(String data)
                    throws SimpleXMLParserDocumentException {
                  return (plugin_interface
                      .getUtilities()
                      .getSimpleXMLParserDocumentFactory()
                      .create(data));
                }

                public ResourceDownloaderFactory getResourceDownloaderFactory() {
                  return (plugin_interface.getUtilities().getResourceDownloaderFactory());
                }

                public UTTimer createTimer(String name) {
                  return (plugin_interface.getUtilities().createTimer(name, true));
                }

                public void createThread(String name, Runnable runnable) {
                  plugin_interface.getUtilities().createThread(name, runnable);
                }

                public Comparator getAlphanumericComparator() {
                  return (plugin_interface
                      .getUtilities()
                      .getFormatters()
                      .getAlphanumericComparator(true));
                }

                public void trace(String str) {
                  core_log.log(str);
                  if (trace_to_log.getValue()) {
                    upnp_log_listener.log(str);
                  }
                }

                public void log(Throwable e) {
                  String nested = Debug.getNestedExceptionMessage(e);

                  if (!exception_traces.contains(nested)) {

                    exception_traces.add(nested);

                    if (exception_traces.size() > 128) {

                      exception_traces.clear();
                    }

                    core_log.log(e);

                  } else {

                    core_log.log(nested);
                  }
                }

                public void log(String str) {
                  log.log(str);
                }

                public String getTraceDir() {
                  return (plugin_interface.getUtilities().getAzureusUserDir());
                }
              },
              getSelectedInterfaces());

      upnp.addRootDeviceListener(this);

      upnp_log_listener =
          new UPnPLogListener() {
            public void log(String str) {
              log.log(str);
            }

            public void logAlert(String str, boolean error, int type) {
              boolean logged = false;

              if (alert_device_probs_param.getValue()) {

                if (type == UPnPLogListener.TYPE_ALWAYS) {

                  log.logAlertRepeatable(
                      error ? LoggerChannel.LT_ERROR : LoggerChannel.LT_WARNING, str);

                  logged = true;

                } else {

                  boolean do_it = false;

                  if (type == UPnPLogListener.TYPE_ONCE_EVER) {

                    byte[] fp =
                        plugin_interface
                            .getUtilities()
                            .getSecurityManager()
                            .calculateSHA1(str.getBytes());

                    String key =
                        "upnp.alert.fp."
                            + plugin_interface
                                .getUtilities()
                                .getFormatters()
                                .encodeBytesToString(fp);

                    PluginConfig pc = plugin_interface.getPluginconfig();

                    if (!pc.getPluginBooleanParameter(key, false)) {

                      pc.setPluginParameter(key, true);

                      do_it = true;
                    }
                  } else {

                    do_it = true;
                  }

                  if (do_it) {

                    log.logAlert(error ? LoggerChannel.LT_ERROR : LoggerChannel.LT_WARNING, str);

                    logged = true;
                  }
                }
              }

              if (!logged) {

                log.log(str);
              }
            }
          };

      upnp.addLogListener(upnp_log_listener);

      mapping_manager.addListener(
          new UPnPMappingManagerListener() {
            public void mappingAdded(UPnPMapping mapping) {
              addMapping(mapping);
            }
          });

      UPnPMapping[] upnp_mappings = mapping_manager.getMappings();

      for (int i = 0; i < upnp_mappings.length; i++) {

        addMapping(upnp_mappings[i]);
      }

      setNATPMPEnableState();

    } catch (Throwable e) {

      log.log(e);
    }
  }
Example #12
0
 /**
  *  Warning - blocking, very slow, queries the active router,
  *  will take many seconds if it has vanished.
  */
 public String renderStatusHTML() {
     if (!_isRunning)
         return "<h3><a name=\"upnp\"></a>" + _("UPnP is not enabled") + "</h3>\n";
     return _upnp.renderStatusHTML();
 }
 ////////////////////////////////////////////////
 // Constructor
 ////////////////////////////////////////////////
 public ControlResponse() {
   setServer(UPnP.getServerName());
 }