Beispiel #1
0
 /**
  * internal function to use the tor-resolve-functionality
  *
  * @param query a hostname to be resolved, or for a reverse lookup: A.B.C.D.in-addr.arpa
  * @return either an InetAddress (normal query), or a String (reverse-DNS-lookup)
  */
 private Object resolve_internal(String query) throws IOException {
   try {
     // check, if tor is still in startup-phase
     checkStartup();
     // try to resolv query over all existing circuits
     // so iterate over all TLS-Connections
     Iterator<String> i = fnh.tls.keySet().iterator();
     while (i.hasNext()) {
       TLSConnection tls = fnh.tls.get(i.next());
       // and over all circuits in each TLS-Connection
       Iterator<Integer> i2 = tls.circuits.keySet().iterator();
       while (i2.hasNext()) {
         Circuit circuit = (Circuit) tls.circuits.get(i2.next());
         try {
           if (circuit.established) {
             // if an answer is given, we're satisfied
             ResolveStream rs = new ResolveStream(circuit);
             Object o = rs.resolve(query);
             rs.close();
             return o;
           }
           ;
         } catch (Exception e) {
           // in case of error, do nothing, but retry with the next
           // circuit
         }
       }
     }
     // if no circuit could give an answer (possibly there was no
     // established circuit?)
     // build a new circuit and ask this one to resolve the query
     ResolveStream rs = new ResolveStream(new Circuit(this, fnh, dir, new TCPStreamProperties()));
     Object o = rs.resolve(query);
     rs.close();
     return o;
   } catch (TorException e) {
     throw new IOException("Error in Tor: " + e.getMessage());
   } catch (InterruptedException e) {
     throw new IOException("Error in Tor: " + e.getMessage());
   }
 }
Beispiel #2
0
  /**
   * makes a connection to a remote service
   *
   * @param sp hostname, port to connect to and other stuff
   * @return some socket-thing
   */
  public TCPStream connect(TCPStreamProperties sp) throws IOException, TorResolveFailedException {
    // Tor.log.logGeneral(Logger.VERBOSE, "Tor: Trying to connect to " + sp.hostname);

    if (sp.hostname == null) throw new IOException("Tor: no hostname is provided");

    // check, if tor is still in startup-phase
    checkStartup();

    // check whether the address is hidden
    if (sp.hostname.endsWith(".onion")) return connectToHidden(sp);

    boolean resolveException = false;

    Circuit[] cs = fnh.provideSuitableCircuits(sp, false);
    if (TorConfig.veryAggressiveStreamBuilding) {

      for (int j = 0; j < cs.length; ++j) {
        // start N asynchronous stream building threads
        try {
          StreamThread[] streamThreads = new StreamThread[cs.length];
          for (int i = 0; i < cs.length; ++i) streamThreads[i] = new StreamThread(cs[i], sp);
          // wait for the first stream to return
          int chosenStream = -1;
          int waitingCounter = TorConfig.queueTimeoutStreamBuildup * 1000 / 10;
          while ((chosenStream < 0) && (waitingCounter >= 0)) {
            boolean atLeastOneAlive = false;
            for (int i = 0; (i < cs.length) && (chosenStream < 0); ++i)
              if (!streamThreads[i].isAlive()) {
                if ((streamThreads[i].stream != null) && (streamThreads[i].stream.established)) {
                  chosenStream = i;
                }
              } else {
                atLeastOneAlive = true;
              }
            if (!atLeastOneAlive) break;
            Common.sleep(10);
            --waitingCounter;
          }
          // return one and close others
          if (chosenStream >= 0) {
            TCPStream returnValue = streamThreads[chosenStream].stream;
            new ClosingThread(streamThreads, chosenStream);
            return returnValue;
          }
        } catch (Exception e) {
          Logger.logStream(Logger.WARNING, "Tor.connect(): " + e.getMessage());
          return null;
        }
      }

    } else {
      // build serial N streams, stop if successful
      for (int i = 0; i < cs.length; ++i) {
        try {
          return new TCPStream(cs[i], sp);
        } catch (TorResolveFailedException e) {
          Logger.logStream(Logger.WARNING, "Tor.connect: Resolve failed:" + e.getMessage());
          resolveException = true;
        } catch (TorNoAnswerException e) {
          Logger.logStream(Logger.WARNING, "Tor.connect: Timeout on circuit:" + e.getMessage());
        } catch (TorException e) {
          Logger.logStream(
              Logger.WARNING,
              "Tor.connect: TorException trying to reuse existing circuit:" + e.getMessage());
        } catch (IOException e) {
          Logger.logStream(Logger.WARNING, "Tor.connect: IOException " + e.getMessage());
        }
      }
    }

    if (resolveException) throw new TorResolveFailedException();

    throw new IOException(
        "Tor.connect: unable to connect to "
            + sp.hostname
            + ":"
            + sp.port
            + " after "
            + sp.connect_retries
            + " retries");
  }