/** * OnionCoffee - Anonymous Communication through TOR Network * Copyright (C) 2005-2007 RWTH Aachen University, Informatik IV * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ package TorJava; import java.io.IOException; import java.net.InetAddress; import TorJava.Common.Queue; import TorJava.Common.TorException; /** * used to anonymously resolve hostnames * * @author Lexi Pimenidis * @version unstable */ class ResolveStream extends TCPStream { int queue_timeout = TorConfig.queueTimeoutResolve; // wait x seconds for answer ResolveStream(Circuit c) { super(c); } /** * creates a new stream and does an anonymous DNS-Lookup. <br> * FIXME: RESOLVED-cells can transport an arbitrary amount of answer-records. currently only the first is returned * * @param hostname * 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) */ Object resolve(String hostname) throws TorException, IOException { ID = circ.assign_streamID(this); circ.streamHistory.add(hostname); // adds resolved hostname to the // history queue = new Queue(queue_timeout); closed = false; Logger.logStream(Logger.VERBOSE, "resolving hostname " + hostname + " on stream " + print()); // send RELAY-RESOLV send_cell(new CellRelayResolve(this, hostname)); // wait for RELAY_RESOLVED CellRelay relay = queue.receiveRelayCell(CellRelay.RELAY_RESOLVED); // read payload int len = ((int) (relay.data[1]) & 0xff); byte[] value = new byte[len]; System.arraycopy(relay.data, 2, value, 0, value.length); // check for error if (relay.data[0] == (byte) 0xf0) throw new TorException("transient error: " + new String(value)); if (relay.data[0] == (byte) 0xf1) throw new TorException("non transient error: " + new String(value)); // check return code if ((relay.data[0] != 0) && (relay.data[0] != 4) && (relay.data[0] != 6)) throw new TorException("can't handle answers of type " + relay.data[0]); // return payload if (relay.data[0] == 0) return new String(value); else return InetAddress.getByAddress(value); } }