public PluginInterface getLocalPluginInterface(Class plugin_class, String id)
      throws PluginException {
    try {
      Plugin p = (Plugin) plugin_class.newInstance();

      // Discard plugin.id from the properties, we want the
      // plugin ID we create to take priority - not a value
      // from the original plugin ID properties file.
      Properties local_props = new Properties(props);
      local_props.remove("plugin.id");

      if (id.endsWith("_v")) {

        throw (new Exception("Verified plugins must be loaded from a jar"));
      }

      PluginInterfaceImpl pi =
          new PluginInterfaceImpl(
              p,
              initialiser,
              initialiser_key,
              class_loader,
              null,
              key + "." + id,
              local_props,
              pluginDir,
              getPluginID() + "." + id,
              plugin_version);

      initialiser.fireCreated(pi);

      p.initialize(pi);

      children.add(pi);

      return (pi);

    } catch (Throwable e) {

      if (e instanceof PluginException) {

        throw ((PluginException) e);
      }

      throw (new PluginException("Local initialisation fails", e));
    }
  }
Exemplo n.º 2
0
  protected Map sendPunch(
      DHTTransportContact rendezvous,
      final DHTTransportUDPContact target,
      Map originator_client_data,
      boolean no_tunnel) {
    AESemaphore wait_sem = new AESemaphore("DHTNatPuncher::sendPunch");
    Object[] wait_data = new Object[] {target, wait_sem, new Integer(0)};

    try {

      try {
        punch_mon.enter();

        oustanding_punches.add(wait_data);

      } finally {

        punch_mon.exit();
      }

      Map request = new HashMap();

      request.put("type", new Long(RT_PUNCH_REQUEST));

      request.put("target", target.getAddress().toString().getBytes());

      if (originator_client_data != null) {

        if (no_tunnel) {

          originator_client_data.put("_notunnel", new Long(1));
        }

        request.put("client_data", originator_client_data);
      }

      // for a message payload (i.e. no_tunnel) we double the initiator timeout to give
      // more chance for reasonable size messages to get through as they have to go through
      // 2 xfer processes

      Map response =
          sendRequest(rendezvous, request, no_tunnel ? TRANSFER_TIMEOUT * 2 : TRANSFER_TIMEOUT);

      if (response == null) {

        return (null);
      }

      if (((Long) response.get("type")).intValue() == RT_PUNCH_REPLY) {

        int result = ((Long) response.get("ok")).intValue();

        trace(
            "received "
                + (no_tunnel ? "message" : "punch")
                + " reply: "
                + (result == 0 ? "failed" : "ok"));

        if (result == 1) {

          // pick up port changes from the rendezvous

          Long indirect_port = (Long) response.get("port");

          if (indirect_port != null) {

            int transport_port = indirect_port.intValue();

            if (transport_port != 0) {

              InetSocketAddress existing_address = target.getTransportAddress();

              if (transport_port != existing_address.getPort()) {

                target.setTransportAddress(
                    new InetSocketAddress(existing_address.getAddress(), transport_port));
              }
            }
          }

          if (!no_tunnel) {

            // ping the target a few times to try and establish a tunnel

            UTTimerEvent event =
                timer.addPeriodicEvent(
                    3000,
                    new UTTimerEventPerformer() {
                      private int pings = 1;

                      public void perform(UTTimerEvent event) {
                        if (pings > 3) {

                          event.cancel();

                          return;
                        }

                        pings++;

                        if (sendTunnelOutbound(target)) {

                          event.cancel();
                        }
                      }
                    });

            if (sendTunnelOutbound(target)) {

              event.cancel();
            }

            // give the other end a few seconds to kick off some tunnel events to us

            if (wait_sem.reserve(10000)) {

              event.cancel();
            }
          }

          // routers often fiddle with the port when not mapped so we need to grab the right one to
          // use
          // for direct communication

          // first priority goes to direct tunnel messages received

          int transport_port = 0;

          try {
            punch_mon.enter();

            transport_port = ((Integer) wait_data[2]).intValue();

          } finally {

            punch_mon.exit();
          }

          if (transport_port != 0) {

            InetSocketAddress existing_address = target.getTransportAddress();

            if (transport_port != existing_address.getPort()) {

              target.setTransportAddress(
                  new InetSocketAddress(existing_address.getAddress(), transport_port));
            }
          }

          Map target_client_data = (Map) response.get("client_data");

          if (target_client_data == null) {

            target_client_data = new HashMap();
          }

          return (target_client_data);
        }
      }

      return (null);

    } catch (Throwable e) {

      log(e);

      return (null);

    } finally {

      try {
        punch_mon.enter();

        oustanding_punches.remove(wait_data);

      } finally {

        punch_mon.exit();
      }
    }
  }