using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Tor.Controller { /// /// A class containing methods for performing control operations against the tor application. /// public sealed class Control : MarshalByRefObject { private readonly Client client; /// /// Initializes a new instance of the class. /// /// The client for which this object instance belongs. internal Control(Client client) { this.client = client; } /// /// Cleans the current circuits in the tor application by requesting new circuits be generated. /// public bool CleanCircuits() { return Command.DispatchAndReturn(client); } /// /// Clears the client-side cache of IP addresses for hostnames. /// /// public bool ClearDNSCache() { return Command.DispatchAndReturn(client); } /// /// Closes an existing circuit within the tor service. /// /// The circuit which should be closed. /// true if the circuit was closed successfully; otherwise, false. public bool CloseCircuit(Circuit circuit) { if (circuit == null) throw new ArgumentNullException("circuit"); if (circuit.ID == 0) throw new ArgumentException("The circuit has an invalid ID", "circuit"); CloseCircuitCommand command = new CloseCircuitCommand(circuit); Response response = command.Dispatch(client); return response.Success; } /// /// Closes an existing stream within the tor service. /// /// The stream which should be closed. /// The reason for the stream being closed. /// true if the stream was closed successfully; otherwise, false. public bool CloseStream(Stream stream, StreamReason reason) { if (stream == null) throw new ArgumentNullException("stream"); if (stream.ID == 0) throw new ArgumentException("The stream has an invalid ID", "stream"); if (reason == StreamReason.None || reason == StreamReason.End || reason == StreamReason.PrivateAddr) throw new ArgumentOutOfRangeException("reason", "The reason for closure cannot be None, End or PrivateAddr"); CloseStreamCommand command = new CloseStreamCommand(stream, reason); Response response = command.Dispatch(client); return response.Success; } /// /// Creates a new circuit within the tor service, and allow tor to select the routers. /// /// true if the circuit is created successfully; otherwise, false. public bool CreateCircuit() { CreateCircuitCommand command = new CreateCircuitCommand(); CreateCircuitResponse response = command.Dispatch(client); return response.Success && response.CircuitID >= 0; } /// /// Creates a new circuit within the tor service comprised of a series of specified routers. /// /// true if the circuit is created successfully; otherwise, false. public bool CreateCircuit(params string[] routers) { CreateCircuitCommand command = new CreateCircuitCommand(routers); CreateCircuitResponse response = command.Dispatch(client); return response.Success && response.CircuitID >= 0; } /// /// Extends an existing circuit by attaching a new router onto the path. /// /// The circuit which should be extended. /// The list of router identities or nicknames to extend onto the circuit. /// true if the circuit was extended successfully; otherwise, false. public bool ExtendCircuit(Circuit circuit, params string[] routers) { if (circuit == null) throw new ArgumentNullException("circuit"); if (circuit.ID == 0) throw new ArgumentException("The circuit has an invalid ID", "circuit"); if (routers.Length == 0) throw new ArgumentOutOfRangeException("routers", "At least one router should be supplied with the extend"); ExtendCircuitCommand command = new ExtendCircuitCommand(circuit); command.Routers.AddRange(routers); Response response = command.Dispatch(client); return response.Success; } } }