private void HandleRelayTruncatedCell(RelayCell cell) { // tor-spec.txt // 5.4. // // To tear down part of a circuit, the OP may send a RELAY_TRUNCATE cell // signaling a given OR (Stream ID zero). That OR sends a DESTROY // cell to the next node in the circuit, and replies to the OP with a // RELAY_TRUNCATED cell. // // [Note: If an OR receives a TRUNCATE cell and it has any RELAY cells // still queued on the circuit for the next node it will drop them // without sending them. This is not considered conformant behavior, // but it probably won't get fixed until a later version of Tor. Thus, // clients SHOULD NOT send a TRUNCATE cell to a node running any current // version of Tor if a) they have sent relay cells through that node, // and b) they aren't sure whether those cells have been sent on yet.] // // When an unrecoverable error occurs along one connection in a // circuit, the nodes on either side of the connection should, if they // are able, act as follows: the node closer to the OP should send a // RELAY_TRUNCATED cell towards the OP; the node farther from the OP // should send a DESTROY cell down the circuit. // Logger.Warning("circuit::handle_relay_truncated_cell() destroying circuit"); Destroy(); }
private Cell Encrypt(RelayCell cell) { for (int i = (int)_node_list.Count - 1; i >= 0; i--) { _node_list[i].EncryptForwardCell(cell); } return(cell); }
private void HandleRelayConnectedCell(RelayCell cell) { TorStream stream = GetStreamById(cell.StreamId); if (null != stream) { stream.State = TorStream.StreamState.ready; } this.State = Circuit.CircuitState.ready; }
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); } }
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 HandleRelayExtendedCell(RelayCell cell) { // finish the handshake. _extend_node.SetSharedSecret(BigInteger.FromBytes(cell.RelayPayload.Slice(0, Constants.DH_LEN)), cell.RelayPayload.Slice(Constants.DH_LEN, Constants.DH_LEN + Constants.HASH_LEN)); if (_extend_node.HasValidCryptoState) { _node_list.Add(_extend_node); } else { Logger.Warning( "circuit::handle_relay_extended_cell() extend node [ {0} ] has invalid crypto state", _extend_node.OnionRouter.Name); } // we're ready here. _extend_node = null; this.State = Circuit.CircuitState.ready; }
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); } } }
internal void HandleCell(Cell cell) { if (CellCommand.relay != cell.Command) { Logger.Debug("tor_socket::recv_cell() [circuit: {0}{1}, command: {2}]", cell.CircuitId & 0x7FFFFFFF, ((0 != (cell.CircuitId & 0x80000000)) ? " (MSB set)" : ""), cell.Command); } switch (cell.Command) { case CellCommand.created: HandleCreatedCell(cell); break; case CellCommand.destroy: HandleDestroyedCell(cell); break; case CellCommand.relay: RelayCell decrypted_relay_cell = Decrypt(cell); if (!decrypted_relay_cell.IsRelayCellValid) { Logger.Warning("circuit::handle_cell() cannot decrypt relay cell, destroying circuit"); Destroy(); break; } Logger.Debug("tor_socket::recv_cell() [circuit: %i%s, stream: %u, command: %u, relay_command: %u, payload_size: %u]", decrypted_relay_cell.CircuitId & 0x7FFFFFFF, ((0 != (decrypted_relay_cell.CircuitId & 0x80000000)) ? " (MSB set)" : ""), decrypted_relay_cell.StreamId, decrypted_relay_cell.Command, decrypted_relay_cell.RelayCommand, decrypted_relay_cell.RelayPayload.Length); switch (decrypted_relay_cell.RelayCommand) { case CellCommand.relay_truncated: HandleRelayTruncatedCell(decrypted_relay_cell); break; case CellCommand.relay_end: HandleRelayEndCell(decrypted_relay_cell); break; case CellCommand.relay_connected: HandleRelayConnectedCell(decrypted_relay_cell); break; case CellCommand.relay_extended: HandleRelayExtendedCell(decrypted_relay_cell); break; case CellCommand.relay_data: HandleRelayDataCell(decrypted_relay_cell); break; case CellCommand.relay_sendme: HandleRelaySendmeCell(decrypted_relay_cell); break; case CellCommand.relay_command_rendezvous2: HandleRelayExtendedCell(decrypted_relay_cell); this.State = Circuit.CircuitState.rendezvous_completed; break; case CellCommand.relay_command_rendezvous_established: this.State = Circuit.CircuitState.rendezvous_established; break; case CellCommand.relay_command_introduce_ack: this.State = Circuit.CircuitState.rendezvous_introduced; break; default: Logger.Warning("tor_socket::recv_cell() !! unhandled relay cell [ relay_command: %u ]", decrypted_relay_cell.RelayCommand); break; } break; default: break; } }