/// <summary> /// Read any incoming TorReply instances. Will block if no data is currently available and 'blocking' is set to 'true' /// </summary> /// <param name="blocking">When set to true, will block when no data is available. When false, it'll return an empty array in when no data is available.</param> /// <returns>An array of TorReply instances.</returns> public TorReply[] Read(bool blocking) { if (_socket == null || !_socket.IsBound) { throw new InvalidOperationException("Not connected."); } if (!blocking && !_socket.IsDataAvailable()) { return new TorReply[0]; } var replies = new List<TorReply>(); while (true) { string line = _reader.ReadLine(); var torReply = new TorReply(line, replies.Count > 0 && replies[0].Type == CommandReplyType.MultiLineValue); // Notification - trigger the event if registered if (torReply.Type == CommandReplyType.Notification) { if (OnNotification != null) { OnNotification(this, torReply); } continue; } // Add the reply to the list replies.Add(torReply); // If we receive a 'Status' reply, we're done receiving if (torReply.Type == CommandReplyType.Status) { return replies.ToArray(); } } }
/// <summary> /// Connect and authenticate using the specified passwords. Throws if /// <remarks>Throws an exception if connecting or authentication failed.</remarks> /// </summary> /// <param name="password"></param> public bool Connect(string password) { try { if (_socket == null || !_socket.IsBound) { _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _socket.Connect(Address, Port); _socket.Send((byte[])new AuthenticateCommand(password)); _stream = new NetworkStream(_socket, FileAccess.ReadWrite, false); _reader = new StreamReader(_stream, Encoding.ASCII); var reply = new TorReply(_reader.ReadLine(), false); if (reply.Code != 250 && reply.Code != 251) // Not 'Ok' or 'Not Needed' { throw new ConnectFailedException(reply, "Unable to authenticate."); } // Success return true; } } catch { // If we have a socket if (_socket != null) { try { // Attempt to close it _socket.Close(); } catch { // Ignore any exception as it might already be closed } // Unset the field _socket = null; } throw; } return false; }
/// <summary> /// Initialize a new ConnectFailedException instance. /// </summary> public ConnectFailedException(TorReply reply, string message) : base(message) { Reply = reply; }
/// <summary> /// Initialize a new ConnectFailedException instance. /// </summary> public ConnectFailedException(TorReply reply, string message, Exception innerException) : base(message, innerException) { Reply = reply; }
/// <summary> /// Initialize a new ConnectFailedException instance. /// </summary> public ConnectFailedException(TorReply reply) { Reply = reply; }