Package de.anomic.net

Source Code of de.anomic.net.UPnP$Listener$Handler

// 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
//
// $LastChangedDate: 2011-03-08 02:51:51 +0100 (Di, 08. Mär 2011) $
// $LastChangedRevision: 7567 $
// $LastChangedBy: low012 $
//
// 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

package de.anomic.net;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import net.yacy.cora.protocol.Domains;
import net.yacy.kelondro.logging.Log;
import net.yacy.upnp.DiscoveryAdvertisement;
import net.yacy.upnp.DiscoveryEventHandler;
import net.yacy.upnp.devices.UPNPRootDevice;
import net.yacy.upnp.impls.InternetGatewayDevice;
import net.yacy.upnp.messages.UPNPResponseException;
import de.anomic.search.Switchboard;
import de.anomic.search.SwitchboardConstants;

public class UPnP {
 
  public final static Log log = new Log("UPNP");
  private static Switchboard sb = Switchboard.getSwitchboard();
 
  private final static int discoveryTimeout = 5000; // seconds to receive a response from devices
  private static InternetGatewayDevice[] IGDs = null;
 
  // mapping variables
  private final static String mappedName = "YaCy";
  private final static String mappedProtocol = "TCP";
  private static int mappedPort = 0;
  private static String localHostIP = null;;
 
  /* Discovery message sender IP /10.100.100.2 does not match device description IP /192.168.1.254 skipping message,
  set the net.yacy.upnp.ddos.matchip system property to false to avoid this check
  static {
    System.setProperty("net.yacy.upnp.ddos.matchip", "false");
  } */
 
  public static boolean setIGDs(InternetGatewayDevice[] igds) {
    if(IGDs == null) {
      IGDs = igds; // set only once to prevent many same devices by advertisement events
      return true;
    }
    return false;
  }
 
  private static boolean init() {
    boolean init = true;
    try {
      if (IGDs == null) IGDs = InternetGatewayDevice.getDevices(discoveryTimeout);
      localHostIP = Domains.myPublicLocalIP().getHostAddress();
      if (localHostIP.startsWith("127.")) log.logWarning("found odd local address: " + localHostIP + "; UPnP may fail");
    } catch (IOException e) {
      init = false;
    }
    if (IGDs != null) {
      for (InternetGatewayDevice IGD : IGDs) {
        log.logInfo("found device: " + IGD.getIGDRootDevice().getFriendlyName());
      }
    } else {
      log.logInfo("no device found");
      init = false;
      log.logInfo("listening for device");
      Listener.register();
    }
   
    return init;
  }
 
  private static String getRemoteHost() {
    if (sb == null) return null;
    return sb.getConfig(SwitchboardConstants.UPNP_REMOTEHOST, "");
  }
 
  /**
   * add port mapping for configured port
   */
  public static void addPortMapping() {
    if (sb == null) return;
    addPortMapping(Integer.parseInt(sb.getConfig("port", "0")));
  }
 
  /**
   * add TCP port mapping to all IGDs on the network<br/>
   * latest port mapping will be removed
   * @param port
   */
  public static void addPortMapping(final int port) { //TODO: don't map already mapped port again
    if (port < 1) return;
    if (mappedPort > 0) deletePortMapping(); // delete old mapping first
    if (mappedPort == 0 && ((IGDs != null && localHostIP != null) || init())) {
      for (InternetGatewayDevice IGD : IGDs) {
        try {
          boolean mapped = IGD.addPortMapping(mappedName, getRemoteHost(), port, port, localHostIP, 0, mappedProtocol);
          String msg = "port " + port + " on device "+ IGD.getIGDRootDevice().getFriendlyName();
          if (mapped) {
            log.logInfo("mapped " + msg);
            mappedPort = port;
          }
          else log.logWarning("could not map " + msg);
        } catch (IOException e) {} catch (UPNPResponseException e) { log.logSevere("mapping error: " + e.getMessage()); }
      }
    }
  }
 
  /**
   * delete current port mapping
   */
  public static void deletePortMapping() {
    if (mappedPort > 0 && IGDs != null && localHostIP != null) {
      for (InternetGatewayDevice IGD : IGDs) {
        try {
          boolean unmapped = IGD.deletePortMapping(getRemoteHost(), mappedPort, mappedProtocol);
          String msg = "port " + mappedPort + " on device "+ IGD.getIGDRootDevice().getFriendlyName();
          if (unmapped) log.logInfo("unmapped " + msg);
          else log.logWarning("could not unmap " + msg);
        } catch (IOException e) {} catch (UPNPResponseException e) { log.logSevere("unmapping error: " + e.getMessage()); }
      }
      mappedPort = 0; // reset mapped port
    }
  }
 
  /**
   * @return mapped port or 0
   */
  public static int getMappedPort() {
    return mappedPort;
  }
     
  public static void main(String[] args) {
    deletePortMapping(); // nothing
    addPortMapping(40000); // map
    addPortMapping(40000); // unmap, map
    deletePortMapping(); // unmap
    deletePortMapping(); // nothing
  }
 
  /**
   * register devices that do not respond to discovery but advertise themselves
   */
  public static class Listener {
   
    private final static Handler handler = new Handler();
    private final static String devicetype = "urn:schemas-upnp-org:device:InternetGatewayDevice:1";
   
    public static void register() {
      try {
        DiscoveryAdvertisement.getInstance().registerEvent(DiscoveryAdvertisement.EVENT_SSDP_ALIVE, devicetype, handler);
//        DiscoveryAdvertisement.getInstance().registerEvent(DiscoveryAdvertisement.EVENT_SSDP_BYE_BYE, devicetype, handler);
      } catch (IOException e) {}
    }
   
    public static void unregister() {
      DiscoveryAdvertisement.getInstance().unRegisterEvent(DiscoveryAdvertisement.EVENT_SSDP_ALIVE, devicetype, handler);
//      DiscoveryAdvertisement.getInstance().unRegisterEvent(DiscoveryAdvertisement.EVENT_SSDP_BYE_BYE, devicetype, handler);
    }
   
    protected static class Handler implements DiscoveryEventHandler {
   
      public void eventSSDPAlive(String usn, String udn, String nt, String maxAge, URL location) {
        InternetGatewayDevice[] newIGD = { null };
        boolean error = false;
        String errorMsg = null;
        try {
          newIGD[0] = new InternetGatewayDevice(new UPNPRootDevice(location, maxAge, "", usn, udn));
        } catch (UnsupportedOperationException e) {
          error = true;
          errorMsg = e.getMessage();
        } catch (MalformedURLException e) {
          error = true;
          errorMsg = e.getMessage();
        } catch (IllegalStateException e) {
          error = true;
          errorMsg = e.getMessage();
        }
        if (error && errorMsg != null)
          log.logSevere("eventSSDPAlive: " + errorMsg);
        if (newIGD[0] == null) return;
        log.logInfo("discovered device: " + newIGD[0].getIGDRootDevice().getFriendlyName());
        if (UPnP.setIGDs(newIGD) &&
          Switchboard.getSwitchboard().getConfigBool(SwitchboardConstants.UPNP_ENABLED, false))
            UPnP.addPortMapping();
        Listener.unregister();
      }
   
      public void eventSSDPByeBye(String usn, String udn, String nt) {}
     
    }
   
  }

}
TOP

Related Classes of de.anomic.net.UPnP$Listener$Handler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.