private TorStream CreateStream(string host, int port) { // tor-spec.txt // 6.2. // // ADDRPORT [nul-terminated string] // FLAGS[4 bytes] // // ADDRPORT is made of ADDRESS | ':' | PORT | [00] byte[] relay_data_bytes = new byte[100]; MemoryStream relay_data_stream = new MemoryStream(relay_data_bytes); StreamWrapper relay_data_buffer = new StreamWrapper(relay_data_stream, Endianness.big_endian); string ps = port.ToString(); string hp = host + ":" + ps; relay_data_buffer.Write(hp); // null terminator. relay_data_buffer.Write((byte)0); // flags. relay_data_buffer.Write((uint)(0)); // send RELAY_BEGIN cell. ushort stream_id = NextStreamId; TorStream stream = new TorStream(stream_id, this); _stream_map.Add(stream_id, stream); Logger.Debug("circuit::create_stream() [url: %s, stream: %u, status: creating]", hp, stream_id); this.State = CircuitState.connecting; SendRelayCell(stream_id, CellCommand.relay_begin, relay_data_bytes); WaitForState(CircuitState.ready); Logger.Debug("circuit::create_stream() [url: %s, stream: %u, status: created]", hp, stream_id); return(stream); }
private int FetchHiddenServiceDescriptor(int responsible_directory_index = 0) { for (int i = responsible_directory_index; i < _responsible_directory_list.Count; i++) { OnionRouter responsible_directory = _responsible_directory_list[i]; // create new circuit and extend it with responsible directory. Circuit directory_circuit = _socket.CreateCircuit(); directory_circuit.Extend(responsible_directory); byte replica = (byte)((i >= 3) ? 0 : 1); // create the directory stream on the directory circuit. TorStream directory_stream = directory_circuit.CreateDirStream(); // request the hidden service descriptor. Logger.Info( "hidden_service::fetch_hidden_service_descriptor() [path: {0}]", ("/tor/rendezvous2/" + Base32.encode(GetDescriptorId(replica)))); string request = "GET /tor/rendezvous2/" + Base32.encode(GetDescriptorId(replica)) + " HTTP/1.1\r\nHost: " + responsible_directory.IPAddress.ToString() + "\r\n\r\n"; directory_stream.Write(ASCIIEncoding.ASCII.GetBytes(request), 0, request.Length); StreamReader stream_reader = new StreamReader(directory_stream); string hidden_service_descriptor = stream_reader.ReadToEnd(); // parse hidden service descriptor. if (!hidden_service_descriptor.Contains("404 Not found")) { HiddenServiceDescriptorParser parser = new HiddenServiceDescriptorParser(); parser.parse(_owner, hidden_service_descriptor); _introduction_point_list = parser.introduction_point_list; parser.introduction_point_list = null; return(i); } } return(-1); }
private void HandleRelayConnectedCell(RelayCell cell) { TorStream stream = GetStreamById(cell.StreamId); if (null != stream) { stream.State = TorStream.StreamState.ready; } this.State = Circuit.CircuitState.ready; }
internal void SendRelayDataCell(TorStream stream, byte[] buffer) { for (int i = 0; i < Helpers.RoundUp(buffer.Length, max_data_size); i += max_data_size) { int data_size = Math.Min(buffer.Length - i, max_data_size); FinalCircuitNode.DecrementPackageWindow(); SendRelayCell(stream.StreamId, CellCommand.relay_data, buffer.Slice(i, i + data_size)); } }
private void HandleRelayEndCell(RelayCell cell) { TorStream stream = GetStreamById(cell.StreamId); if (null != stream) { Logger.Debug("circuit::handle_relay_end_cell() [stream: {0}, reason: {1}]", cell.StreamId, cell.RelayPayload[0]); stream.State = TorStream.StreamState.destroyed; _stream_map.Remove(cell.StreamId); } }
internal TorStream CreateDirStream() { ushort stream_id = NextStreamId; TorStream stream = new TorStream(stream_id, this); _stream_map.Add(stream_id, stream); Logger.Debug("circuit::create_dir_stream() [stream: %u, state: connecting]", stream_id); this.State = CircuitState.connecting; SendRelayCell(stream_id, CellCommand.relay_begin_dir); WaitForState(CircuitState.ready); Logger.Debug("circuit::create_dir_stream() [stream: %u, state: connected]", stream_id); return(stream); }
private void HandleRelaySendmeCell(RelayCell cell) { if (cell.StreamId == 0) { cell.CircuitNode.IncrementPackageWindow(); return; } TorStream stream = GetStreamById(cell.StreamId); if (null != stream) { stream.IncrementPackageWindows(); } }
private void HandleRelayDataCell(RelayCell cell) { // decrement deliver window on circuit node. cell.CircuitNode.DecrementDeliverWindow(); if (cell.CircuitNode.ConsiderSendingSendme()) { SendRelaySendmeCell(null); } TorStream stream = GetStreamById(cell.StreamId); if (null != stream) { stream.AppendToReceiveBuffer(cell.RelayPayload); // decrement window on stream. stream.DecrementDeliverWindows(); if (stream.ConsiderSendingSendme()) { SendRelaySendmeCell(stream); } } }
private void SendRelaySendmeCell(TorStream stream) { // if stream == nullptr, we're sending RELAY_SENDME // with stream_id = 0, which means circuit RELAY_SENDME SendRelayCell((ushort)((null == stream) ? 0 : stream.StreamId), CellCommand.relay_sendme, null); }
internal void SendRelayEndCell(TorStream stream) { SendRelayCell(stream.StreamId, CellCommand.relay_end, new byte[] { 6 }); // reason stream.State = TorStream.StreamState.destroyed; _stream_map.Remove(stream.StreamId); }