示例#1
0
  protected void receiveTunnelInbound(DHTTransportUDPContact originator, Map data) {
    log("Received tunnel inbound message from " + originator.getString());

    try {
      punch_mon.enter();

      for (int i = 0; i < oustanding_punches.size(); i++) {

        Object[] wait_data = (Object[]) oustanding_punches.get(i);

        DHTTransportContact wait_contact = (DHTTransportContact) wait_data[0];

        if (originator.getAddress().getAddress().equals(wait_contact.getAddress().getAddress())) {

          wait_data[2] = new Integer(originator.getTransportAddress().getPort());

          ((AESemaphore) wait_data[1]).release();
        }
      }

    } finally {

      punch_mon.exit();
    }
  }
示例#2
0
  public void setRendezvous(DHTTransportContact target, DHTTransportContact rendezvous) {
    explicit_rendezvous_map.put(target.getAddress(), rendezvous);

    if (target.getAddress().equals(dht.getTransport().getLocalContact().getAddress())) {

      publish(true);
    }
  }
示例#3
0
  protected void rendezvousFailed(DHTTransportContact current_target, boolean tidy) {
    log("Rendezvous " + (tidy ? "closed" : "failed") + ": " + current_target.getString());

    try {
      pub_mon.enter();

      failed_rendezvous.put(current_target.getAddress(), "");

    } finally {

      pub_mon.exit();
    }

    publish(true);
  }
示例#4
0
 public static String getString(DHTTransportContact contact) {
   if (logging_on) {
     return (contact.getString());
   } else {
     return ("");
   }
 }
示例#5
0
  protected void receiveClose(DHTTransportUDPContact originator, Map request, Map response) {
    trace("received close request");

    final DHTTransportContact current_target = rendezvous_target;

    if (current_target != null && Arrays.equals(current_target.getID(), originator.getID())) {

      new AEThread2("DHTNATPuncher:close", true) {
        public void run() {
          rendezvousFailed(current_target, true);
        }
      }.start();
    }

    response.put("ok", new Long(1));
  }
示例#6
0
  protected byte[] getPublishKey(DHTTransportContact contact) {
    byte[] id = contact.getID();
    byte[] suffix = ":DHTNATPuncher".getBytes();

    byte[] res = new byte[id.length + suffix.length];

    System.arraycopy(id, 0, res, 0, id.length);
    System.arraycopy(suffix, 0, res, id.length, suffix.length);

    return (res);
  }
  protected void findContacts() {
    DHTTransportContact[] reachables = dht.getTransport().getReachableContacts();

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

      DHTTransportContact contact = reachables[i];

      byte[] address = contact.getAddress().getAddress().getAddress();

      if (tried_bloom == null || tried_bloom.getEntryCount() > 500) {

        tried_bloom = BloomFilterFactory.createAddOnly(4096);
      }

      if (!tried_bloom.contains(address)) {

        tried_bloom.add(address);

        synchronized (pending_contacts) {
          potentialPing ping =
              new potentialPing(
                  contact,
                  DHTNetworkPositionManager.estimateRTT(
                      contact.getNetworkPositions(),
                      dht.getTransport().getLocalContact().getNetworkPositions()));

          pending_contacts.add(0, ping);

          if (pending_contacts.size() > 60) {

            pending_contacts.removeLast();
          }
        }
      }
    }
  }
示例#8
0
  protected boolean sendTunnelOutbound(DHTTransportContact target) {
    log("Sending tunnel outbound message to " + target.getString());

    try {
      Map message = new HashMap();

      message.put("type", new Long(RT_TUNNEL_OUTBOUND));

      return (sendTunnelMessage(target, message));

    } catch (Throwable e) {

      log(e);

      return (false);
    }
  }
示例#9
0
  protected byte[] encodeContact(DHTTransportContact contact) {
    try {
      ByteArrayOutputStream baos = new ByteArrayOutputStream();

      DataOutputStream dos = new DataOutputStream(baos);

      contact.exportContact(dos);

      dos.close();

      return (baos.toByteArray());

    } catch (Throwable e) {

      log(e);

      return (null);
    }
  }
示例#10
0
  protected byte[] encodePublishValue(DHTTransportContact contact) {
    try {
      ByteArrayOutputStream baos = new ByteArrayOutputStream();

      DataOutputStream dos = new DataOutputStream(baos);

      dos.writeByte(0); // version

      contact.exportContact(dos);

      dos.close();

      return (baos.toByteArray());

    } catch (Throwable e) {

      log(e);

      return (new byte[0]);
    }
  }
  protected void updateRegistrationData(Map<String, Object> payload) {
    int puncher_num = 0;

    int num_registered = 0;

    for (DHTNATPuncher nat_ipv4 : nat_punchers_ipv4) {

      DHTTransportContact rend = nat_ipv4.getRendezvous();
      DHTTransportContact lc = nat_ipv4.getLocalContact();

      if (rend != null && lc != null) {

        puncher_num++;

        InetSocketAddress rend_address = rend.getTransportAddress();

        num_registered++;

        payload.put(
            "rc_v4-" + puncher_num,
            rend_address.getAddress().getHostAddress() + ":" + rend_address.getPort());

        if (puncher_num == 1) {

          payload.put(
              "rl_v4",
              lc.getExternalAddress().getAddress().getHostAddress()
                  + ":"
                  + lc.getAddress().getPort());
        }
      }
    }

    puncher_num = 0;

    for (DHTNATPuncher nat_ipv6 : nat_punchers_ipv6) {

      DHTTransportContact rend = nat_ipv6.getRendezvous();
      DHTTransportContact lc = nat_ipv6.getLocalContact();

      if (rend != null && lc != null) {

        puncher_num++;

        InetSocketAddress rend_address = rend.getTransportAddress();

        num_registered++;

        payload.put(
            "rc_v6-" + puncher_num,
            rend_address.getAddress().getHostAddress() + ":" + rend_address.getPort());

        if (puncher_num == 1) {

          payload.put(
              "rl_v6",
              lc.getExternalAddress().getAddress().getHostAddress()
                  + ":"
                  + lc.getAddress().getPort());
        }
      }
    }

    if (num_registered != last_punchers_registered) {

      last_punchers_registered = num_registered;

      manager.updateSRPState();
    }
  }
    protected void ping(pingInstanceSet ping_set, DHTTransportContact contact) {
      final pingInstance pi = new pingInstance(ping_set);

      outstanding++;

      try {
        contact.sendImmediatePing(
            new DHTTransportReplyHandlerAdapter() {
              public void pingReply(DHTTransportContact contact) {
                int rtt = getElapsed();

                try {
                  synchronized (activePing.this) {
                    outstanding--;

                    if (!running) {

                      if (rtt < best_ping) {

                        best_pingee = contact;
                        best_ping = rtt;
                      }

                      if (outstanding == 0) {

                        running = true;
                      }
                    } else {

                      total_ok++;

                      consec_fails = 0;
                    }
                  }

                  Iterator it = listeners.iterator();

                  while (it.hasNext()) {

                    try {
                      ((DHTSpeedTesterContactListener) it.next())
                          .ping(activePing.this, getElapsed());

                    } catch (Throwable e) {

                      Debug.printStackTrace(e);
                    }
                  }
                } finally {

                  pi.setResult(activePing.this, rtt);
                }
                // System.out.println( "    " + contact.getString() + ": " + getElapsed() + ", " +
                // contact.getVivaldiPosition().estimateRTT(
                // dht.getTransport().getLocalContact().getVivaldiPosition().getCoordinates()));
              }

              public void failed(DHTTransportContact contact, Throwable error) {
                try {
                  synchronized (activePing.this) {
                    outstanding--;

                    if (!running) {

                      if (outstanding == 0) {

                        running = true;
                      }
                    } else {

                      consec_fails++;
                      total_fails++;

                      if (consec_fails == 3) {

                        dead = true;

                      } else if (total_ok > 10 && total_fails > 0 && total_ok / total_fails < 1) {

                        // failing too often

                        dead = true;

                      } else if (total_ok > 100) {

                        total_ok = 0;
                        total_fails = 0;
                      }
                    }
                  }

                  if (!dead) {

                    Iterator it = listeners.iterator();

                    while (it.hasNext()) {

                      try {
                        ((DHTSpeedTesterContactListener) it.next()).pingFailed(activePing.this);

                      } catch (Throwable e) {

                        Debug.printStackTrace(e);
                      }
                    }
                  }
                  // System.out.println( "    " + contact.getString() + ": failed" );
                } finally {

                  pi.setResult(activePing.this, -1);
                }
              }
            },
            PING_TIMEOUT);

      } catch (Throwable e) {

        pi.setResult(this, -1);

        dead = true;

        outstanding--;

        Debug.printStackTrace(e);
      }
    }
示例#13
0
  protected void publishSupport() {
    DHTTransport transport = dht.getTransport();

    if (TESTING || !transport.isReachable()) {

      DHTTransportContact local_contact = transport.getLocalContact();

      // see if the rendezvous has failed and therefore we are required to find a new one

      boolean force =
          rendezvous_target != null
              && failed_rendezvous.containsKey(rendezvous_target.getAddress());

      if (rendezvous_local_contact != null && !force) {

        if (local_contact.getAddress().equals(rendezvous_local_contact.getAddress())) {

          // already running for the current local contact

          return;
        }
      }

      DHTTransportContact explicit =
          (DHTTransportContact) explicit_rendezvous_map.get(local_contact.getAddress());

      if (explicit != null) {

        try {
          pub_mon.enter();

          rendezvous_local_contact = local_contact;
          rendezvous_target = explicit;

          runRendezvous();

        } finally {

          pub_mon.exit();
        }
      } else {

        final DHTTransportContact[] new_rendezvous_target = {null};

        DHTTransportContact[] reachables = dht.getTransport().getReachableContacts();

        int reachables_tried = 0;
        int reachables_skipped = 0;

        final Semaphore sem = plugin_interface.getUtilities().getSemaphore();

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

          DHTTransportContact contact = reachables[i];

          try {
            pub_mon.enter();

            // see if we've found a good one yet

            if (new_rendezvous_target[0] != null) {

              break;
            }

            // skip any known bad ones

            if (failed_rendezvous.containsKey(contact.getAddress())) {

              reachables_skipped++;

              sem.release();

              continue;
            }
          } finally {

            pub_mon.exit();
          }

          if (i > 0) {

            try {
              Thread.sleep(1000);

            } catch (Throwable e) {

            }
          }

          reachables_tried++;

          contact.sendPing(
              new DHTTransportReplyHandlerAdapter() {
                public void pingReply(DHTTransportContact ok_contact) {
                  trace("Punch:" + ok_contact.getString() + " OK");

                  try {
                    pub_mon.enter();

                    if (new_rendezvous_target[0] == null) {

                      new_rendezvous_target[0] = ok_contact;
                    }
                  } finally {

                    pub_mon.exit();

                    sem.release();
                  }
                }

                public void failed(DHTTransportContact failed_contact, Throwable e) {
                  try {
                    trace("Punch:" + failed_contact.getString() + " Failed");

                  } finally {

                    sem.release();
                  }
                }
              });
        }

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

          sem.reserve();

          try {
            pub_mon.enter();

            if (new_rendezvous_target[0] != null) {

              rendezvous_target = new_rendezvous_target[0];
              rendezvous_local_contact = local_contact;

              log(
                  "Rendezvous found: "
                      + rendezvous_local_contact.getString()
                      + " -> "
                      + rendezvous_target.getString());

              runRendezvous();

              break;
            }
          } finally {

            pub_mon.exit();
          }
        }

        if (new_rendezvous_target[0] == null) {

          log(
              "No rendezvous found: candidates="
                  + reachables.length
                  + ",tried="
                  + reachables_tried
                  + ",skipped="
                  + reachables_skipped);

          try {
            pub_mon.enter();

            rendezvous_local_contact = null;
            rendezvous_target = null;

          } finally {

            pub_mon.exit();
          }
        }
      }
    } else {

      try {
        pub_mon.enter();

        rendezvous_local_contact = null;
        rendezvous_target = null;

      } finally {

        pub_mon.exit();
      }
    }
  }
示例#14
0
  protected DHTTransportContact getRendezvous(String reason, DHTTransportContact target) {
    DHTTransportContact explicit =
        (DHTTransportContact) explicit_rendezvous_map.get(target.getAddress());

    if (explicit != null) {

      return (explicit);
    }

    byte[] key = getPublishKey(target);

    final DHTTransportValue[] result_value = {null};

    final Semaphore sem = plugin_interface.getUtilities().getSemaphore();

    dht.get(
        key,
        reason + ": lookup for '" + target.getString() + "'",
        (byte) 0,
        1,
        RENDEZVOUS_LOOKUP_TIMEOUT,
        false,
        true,
        new DHTOperationAdapter() {
          public void read(DHTTransportContact contact, DHTTransportValue value) {
            result_value[0] = value;

            sem.release();
          }

          public void complete(boolean timeout) {
            sem.release();
          }
        });

    sem.reserve();

    DHTTransportContact result = null;

    if (result_value[0] != null) {

      byte[] bytes = result_value[0].getValue();

      try {
        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);

        DataInputStream dis = new DataInputStream(bais);

        byte version = dis.readByte();

        if (version != 0) {

          throw (new Exception("Unsupported rendezvous version '" + version + "'"));
        }

        result = dht.getTransport().importContact(dis);

      } catch (Throwable e) {

        log(e);
      }
    }

    log(
        "Lookup of rendezvous for "
            + target.getString()
            + " -> "
            + (result == null ? "None" : result.getString()));

    return (result);
  }
示例#15
0
 protected void receiveTunnelOutbound(DHTTransportContact originator, Map data) {
   log("Received tunnel outbound message from " + originator.getString());
 }
示例#16
0
  protected void receiveConnect(DHTTransportContact rendezvous, Map request, Map response) {
    trace("received connect request");

    boolean ok = false;

    // ensure that we've received this from our current rendezvous node

    DHTTransportContact rt = rendezvous_target;

    if (rt != null && rt.getAddress().equals(rendezvous.getAddress())) {

      final DHTTransportUDPContact target = decodeContact((byte[]) request.get("origin"));

      if (target != null) {

        int transport_port = 0;

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

        if (indirect_port != null) {

          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));
          }
        }

        Map originator_client_data = (Map) request.get("client_data");

        boolean no_tunnel = false;

        if (originator_client_data == null) {

          originator_client_data = new HashMap();

        } else {

          no_tunnel = originator_client_data.get("_notunnel") != null;
        }

        if (no_tunnel) {

          log("Received message from " + target.getString());

        } else {

          log("Received connect request from " + target.getString());

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

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

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

                        ev.cancel();

                        return;
                      }

                      pings++;

                      if (sendTunnelInbound(target)) {

                        ev.cancel();
                      }
                    }
                  });

          if (sendTunnelInbound(target)) {

            event.cancel();
          }
        }

        Map client_data =
            adapter.getClientData(target.getTransportAddress(), originator_client_data);

        if (client_data == null) {

          client_data = new HashMap();
        }

        response.put("client_data", client_data);

        ok = true;

      } else {

        log("Connect request: failed to decode target");
      }
    } else {

      log("Connect request from invalid rendezvous: " + rendezvous.getString());
    }

    response.put("ok", new Long(ok ? 1 : 0));
  }