diff --git a/src/Tor/Circuits/Circuit.cs b/src/Tor/Circuits/Circuit.cs index 490542e..df1e681 100644 --- a/src/Tor/Circuits/Circuit.cs +++ b/src/Tor/Circuits/Circuit.cs @@ -46,6 +46,85 @@ internal Circuit(Client client, int id) this.timeCreated = DateTime.MinValue; } + /// + /// Creates a new instance of the class from respone line. + /// + /// The client for which the circuit belongs. + /// The line which was received from the control connection. + /// + /// Circuit a new instance. + /// + public static Circuit FromLine(Client client, string line) + { + int index = 0; + int circuitID = 0; + string[] parts = StringHelper.GetAll(line, ' '); + Circuit circuit = null; + List routers = new List(); + + if (parts == null || parts.Length < 2) + return null; + + if (!int.TryParse(parts[0], out circuitID)) + return null; + + circuit = new Circuit(client, circuitID); + circuit.Status = ReflectionHelper.GetEnumerator(attr => parts[1].Equals(attr.Description, StringComparison.CurrentCultureIgnoreCase)); + + for (int i = 2, length = parts.Length; i < length; i++) + { + string data = parts[i]; + + index += data.Length + 1; + data = data.Trim(); + + if (!data.Contains("=")) + { + routers.AddRange(data.Split(',')); + continue; + } + + string[] values = data.Split(new[] { '=' }, 2); + string name = values[0].Trim(); + string value = values[1].Trim(); + + if (name.Equals("BUILD_FLAGS")) + { + string[] flags = value.Split(','); + + foreach (string flag in flags) + circuit.BuildFlags |= ReflectionHelper.GetEnumerator(attr => flag.Equals(attr.Description, StringComparison.CurrentCultureIgnoreCase)); + } + else + { + switch (name) + { + case "HS_STATE": + circuit.HSState = ReflectionHelper.GetEnumerator(attr => value.Equals(attr.Description, StringComparison.CurrentCultureIgnoreCase)); + break; + case "PURPOSE": + circuit.Purpose = ReflectionHelper.GetEnumerator(attr => value.Equals(attr.Description, StringComparison.CurrentCultureIgnoreCase)); + break; + case "REASON": + circuit.Reason = ReflectionHelper.GetEnumerator(attr => value.Equals(attr.Description, StringComparison.CurrentCultureIgnoreCase)); + break; + case "TIME_CREATED": + DateTime timeCreated; + if (DateTime.TryParse(value, out timeCreated)) + circuit.TimeCreated = timeCreated; + else + circuit.TimeCreated = DateTime.MinValue; + break; + } + } + } + + circuit.Paths = routers; + circuit.GetRouters(); + + return circuit; + } + #region Properties /// diff --git a/src/Tor/Events/Dispatchers/CircuitDispatcher.cs b/src/Tor/Events/Dispatchers/CircuitDispatcher.cs index ca7389b..e3403f8 100644 --- a/src/Tor/Events/Dispatchers/CircuitDispatcher.cs +++ b/src/Tor/Events/Dispatchers/CircuitDispatcher.cs @@ -2,8 +2,6 @@ using System.Collections.Generic; using System.Linq; using System.Text; -using Tor.Helpers; -using System.ComponentModel; namespace Tor.Events { @@ -24,70 +22,9 @@ internal sealed class CircuitDispatcher : Dispatcher /// public override bool Dispatch(string line) { - int index = 0; - int circuitID = 0; - string[] parts = StringHelper.GetAll(line, ' '); - Circuit circuit = null; - List routers = new List(); - - if (parts == null || parts.Length < 2) - return false; - - if (!int.TryParse(parts[0], out circuitID)) + Circuit circuit = Circuit.FromLine(Client, line); + if (circuit == null) return false; - - circuit = new Circuit(Client, circuitID); - circuit.Status = ReflectionHelper.GetEnumerator(attr => parts[1].Equals(attr.Description, StringComparison.CurrentCultureIgnoreCase)); - - for (int i = 2, length = parts.Length; i < length; i++) - { - string data = parts[i]; - - index += data.Length + 1; - data = data.Trim(); - - if (!data.Contains("=")) - { - routers.AddRange(data.Split(',')); - continue; - } - - string[] values = data.Split(new[] { '=' }, 2); - string name = values[0].Trim(); - string value = values[1].Trim(); - - if (name.Equals("BUILD_FLAGS")) - { - string[] flags = value.Split(','); - - foreach (string flag in flags) - circuit.BuildFlags |= ReflectionHelper.GetEnumerator(attr => flag.Equals(attr.Description, StringComparison.CurrentCultureIgnoreCase)); - } - else - { - switch (name) - { - case "HS_STATE": - circuit.HSState = ReflectionHelper.GetEnumerator(attr => value.Equals(attr.Description, StringComparison.CurrentCultureIgnoreCase)); - break; - case "PURPOSE": - circuit.Purpose = ReflectionHelper.GetEnumerator(attr => value.Equals(attr.Description, StringComparison.CurrentCultureIgnoreCase)); - break; - case "REASON": - circuit.Reason = ReflectionHelper.GetEnumerator(attr => value.Equals(attr.Description, StringComparison.CurrentCultureIgnoreCase)); - break; - case "TIME_CREATED": - DateTime timeCreated; - if (DateTime.TryParse(value, out timeCreated)) - circuit.TimeCreated = timeCreated; - else - circuit.TimeCreated = DateTime.MinValue; - break; - } - } - } - - circuit.Paths = routers; Events.OnCircuitChanged(new CircuitEventArgs(circuit)); diff --git a/src/Tor/Events/Dispatchers/ORConnectionDispatcher.cs b/src/Tor/Events/Dispatchers/ORConnectionDispatcher.cs index 345d7c9..9f022dc 100644 --- a/src/Tor/Events/Dispatchers/ORConnectionDispatcher.cs +++ b/src/Tor/Events/Dispatchers/ORConnectionDispatcher.cs @@ -2,8 +2,6 @@ using System.Collections.Generic; using System.Linq; using System.Text; -using Tor.Helpers; -using System.ComponentModel; namespace Tor.Events { @@ -24,62 +22,11 @@ internal sealed class ORConnectionDispatcher : Dispatcher /// public override bool Dispatch(string line) { - string target; - ORStatus status; - string[] parts = StringHelper.GetAll(line, ' '); + ORConnection connection = ORConnection.FromLine(line); - if (parts.Length < 2) + if (connection == null) return false; - target = parts[0]; - status = ReflectionHelper.GetEnumerator(attr => parts[1].Equals(attr.Description, StringComparison.CurrentCultureIgnoreCase)); - - ORConnection connection = new ORConnection(); - connection.Status = status; - connection.Target = target; - - for (int i = 2; i < parts.Length; i++) - { - string data = parts[i].Trim(); - - if (!data.Contains("=")) - continue; - - string[] values = data.Split(new[] { '=' }, 2); - - if (values.Length < 2) - continue; - - string name = values[0].Trim(); - string value = values[1].Trim(); - - if ("REASON".Equals(name, StringComparison.CurrentCultureIgnoreCase)) - { - connection.Reason = ReflectionHelper.GetEnumerator(attr => value.Equals(attr.Description, StringComparison.CurrentCultureIgnoreCase)); - continue; - } - - if ("NCIRCS".Equals(name, StringComparison.CurrentCultureIgnoreCase)) - { - int circuits; - - if (int.TryParse(value, out circuits)) - connection.CircuitCount = circuits; - - continue; - } - - if ("ID".Equals(name, StringComparison.CurrentCultureIgnoreCase)) - { - int id; - - if (int.TryParse(value, out id)) - connection.ID = id; - - continue; - } - } - Client.Events.OnORConnectionChanged(new ORConnectionEventArgs(connection)); return true; } diff --git a/src/Tor/Events/Dispatchers/StreamDispatcher.cs b/src/Tor/Events/Dispatchers/StreamDispatcher.cs index 2fa04a4..8327dcd 100644 --- a/src/Tor/Events/Dispatchers/StreamDispatcher.cs +++ b/src/Tor/Events/Dispatchers/StreamDispatcher.cs @@ -2,8 +2,6 @@ using System.Collections.Generic; using System.Linq; using System.Text; -using Tor.Helpers; -using System.ComponentModel; namespace Tor.Events { @@ -24,68 +22,11 @@ internal sealed class StreamDispatcher : Dispatcher /// public override bool Dispatch(string line) { - int streamID; - int circuitID; - int port; - StreamStatus status; - Host target; - string[] parts = StringHelper.GetAll(line, ' '); + Stream stream = Stream.FromLine(Client, line); - if (parts.Length < 4) + if (stream == null) return false; - if ("Tor_internal".Equals(parts[3], StringComparison.CurrentCultureIgnoreCase)) - return false; - - if (!int.TryParse(parts[0], out streamID)) - return false; - - if (!int.TryParse(parts[2], out circuitID)) - return false; - - string[] targetParts = parts[3].Split(new[] { ':' }, 2); - - if (targetParts.Length < 2) - return false; - - if (!int.TryParse(targetParts[1], out port)) - return false; - - status = ReflectionHelper.GetEnumerator(attr => parts[1].Equals(attr.Description, StringComparison.CurrentCultureIgnoreCase)); - target = new Host(targetParts[0], port); - - Stream stream = new Stream(Client, streamID, target); - stream.CircuitID = circuitID; - stream.Status = status; - - for (int i = 4; i < parts.Length; i++) - { - string data = parts[i].Trim(); - - if (!data.Contains("=")) - continue; - - string[] values = data.Split(new[] { '=' }, 2); - - if (values.Length < 2) - continue; - - string name = values[0].Trim(); - string value = values[1].Trim(); - - if ("REASON".Equals(name, StringComparison.CurrentCultureIgnoreCase)) - { - stream.Reason = ReflectionHelper.GetEnumerator(attr => value.Equals(attr.Description, StringComparison.CurrentCultureIgnoreCase)); - continue; - } - - if ("PURPOSE".Equals(name, StringComparison.CurrentCultureIgnoreCase)) - { - stream.Purpose = ReflectionHelper.GetEnumerator(attr => value.Equals(attr.Description, StringComparison.CurrentCultureIgnoreCase)); - continue; - } - } - Events.OnStreamChanged(new StreamEventArgs(stream)); return true; } diff --git a/src/Tor/ORConnections/ORConnection.cs b/src/Tor/ORConnections/ORConnection.cs index 955a848..04d1501 100644 --- a/src/Tor/ORConnections/ORConnection.cs +++ b/src/Tor/ORConnections/ORConnection.cs @@ -3,6 +3,8 @@ using System.Linq; using System.Text; using System.Collections.ObjectModel; +using Tor.Helpers; +using System.ComponentModel; namespace Tor { @@ -30,6 +32,73 @@ internal ORConnection() this.target = ""; } + /// + /// Creates a new instance of the class. + /// + /// The line which was received from the control connection. + /// + /// ORConnection the new instance. + /// + public static ORConnection FromLine(string line) + { + string target; + ORStatus status; + string[] parts = StringHelper.GetAll(line, ' '); + + if (parts.Length < 2) + return null; + + target = parts[0]; + status = ReflectionHelper.GetEnumerator(attr => parts[1].Equals(attr.Description, StringComparison.CurrentCultureIgnoreCase)); + + ORConnection connection = new ORConnection(); + connection.Status = status; + connection.Target = target; + + for (int i = 2; i < parts.Length; i++) + { + string data = parts[i].Trim(); + + if (!data.Contains("=")) + continue; + + string[] values = data.Split(new[] { '=' }, 2); + + if (values.Length < 2) + continue; + + string name = values[0].Trim(); + string value = values[1].Trim(); + + if ("REASON".Equals(name, StringComparison.CurrentCultureIgnoreCase)) + { + connection.Reason = ReflectionHelper.GetEnumerator(attr => value.Equals(attr.Description, StringComparison.CurrentCultureIgnoreCase)); + continue; + } + + if ("NCIRCS".Equals(name, StringComparison.CurrentCultureIgnoreCase)) + { + int circuits; + + if (int.TryParse(value, out circuits)) + connection.CircuitCount = circuits; + + continue; + } + + if ("ID".Equals(name, StringComparison.CurrentCultureIgnoreCase)) + { + int id; + + if (int.TryParse(value, out id)) + connection.ID = id; + + continue; + } + } + return connection; + } + #region Properties /// @@ -78,6 +147,7 @@ public string Target } #endregion + } /// diff --git a/src/Tor/Streams/Stream.cs b/src/Tor/Streams/Stream.cs index 2f8d190..0cc11f0 100644 --- a/src/Tor/Streams/Stream.cs +++ b/src/Tor/Streams/Stream.cs @@ -3,6 +3,8 @@ using System.Linq; using System.Text; using System.Collections.ObjectModel; +using Tor.Helpers; +using System.ComponentModel; namespace Tor { @@ -37,6 +39,81 @@ internal Stream(Client client, int id, Host target) this.target = target; } + /// + /// Creates a new instance of the class. + /// + /// The client for which the stream belongs. + /// The line which was received from the control connection. + /// + /// Stream the new instance. + /// + public static Stream FromLine(Client client, string line) + { + int streamID; + int circuitID; + int port; + StreamStatus status; + Host target; + string[] parts = StringHelper.GetAll(line, ' '); + + if (parts.Length < 4) + return null; + + if ("Tor_internal".Equals(parts[3], StringComparison.CurrentCultureIgnoreCase)) + return null; + + if (!int.TryParse(parts[0], out streamID)) + return null; + + if (!int.TryParse(parts[2], out circuitID)) + return null; + + string[] targetParts = parts[3].Split(new[] { ':' }, 2); + + if (targetParts.Length < 2) + return null; + + if (!int.TryParse(targetParts[1], out port)) + return null; + + status = ReflectionHelper.GetEnumerator(attr => parts[1].Equals(attr.Description, StringComparison.CurrentCultureIgnoreCase)); + target = new Host(targetParts[0], port); + + Stream stream = new Stream(client, streamID, target); + stream.CircuitID = circuitID; + stream.Status = status; + + for (int i = 4; i < parts.Length; i++) + { + string data = parts[i].Trim(); + + if (!data.Contains("=")) + continue; + + string[] values = data.Split(new[] { '=' }, 2); + + if (values.Length < 2) + continue; + + string name = values[0].Trim(); + string value = values[1].Trim(); + + if ("REASON".Equals(name, StringComparison.CurrentCultureIgnoreCase)) + { + stream.Reason = ReflectionHelper.GetEnumerator(attr => value.Equals(attr.Description, StringComparison.CurrentCultureIgnoreCase)); + continue; + } + + if ("PURPOSE".Equals(name, StringComparison.CurrentCultureIgnoreCase)) + { + stream.Purpose = ReflectionHelper.GetEnumerator(attr => value.Equals(attr.Description, StringComparison.CurrentCultureIgnoreCase)); + continue; + } + } + + return stream; + } + #region Properties ///