예제 #1
0
 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();
 }
예제 #2
0
 private Cell Encrypt(RelayCell cell)
 {
     for (int i = (int)_node_list.Count - 1; i >= 0; i--)
     {
         _node_list[i].EncryptForwardCell(cell);
     }
     return(cell);
 }
예제 #3
0
        private void HandleRelayConnectedCell(RelayCell cell)
        {
            TorStream stream = GetStreamById(cell.StreamId);

            if (null != stream)
            {
                stream.State = TorStream.StreamState.ready;
            }
            this.State = Circuit.CircuitState.ready;
        }
예제 #4
0
        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);
            }
        }
예제 #5
0
        private void HandleRelaySendmeCell(RelayCell cell)
        {
            if (cell.StreamId == 0)
            {
                cell.CircuitNode.IncrementPackageWindow();
                return;
            }
            TorStream stream = GetStreamById(cell.StreamId);

            if (null != stream)
            {
                stream.IncrementPackageWindows();
            }
        }
예제 #6
0
        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;
        }
예제 #7
0
        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);
                }
            }
        }
예제 #8
0
        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;
            }
        }