commit 0f2d45328dfcb16acb4a517711413a6f0386487a
Merge: 31eaa81f59 adb248b6d6
Author: Nick Mathewson <ni...@torproject.org>
Date:   Thu Jun 10 08:52:39 2021 -0400

    Merge branch 'maint-0.3.5' into maint-0.4.4
    
    Conflicts resolved:
            src/core/or/relay.c

 changes/ticket40389 |  3 +++
 src/core/or/relay.c | 39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 42 insertions(+)

diff --cc src/core/or/relay.c
index 75d2d479e7,00353f47a9..78fda99a45
--- a/src/core/or/relay.c
+++ b/src/core/or/relay.c
@@@ -1503,108 -1428,104 +1503,127 @@@ connection_edge_process_relay_cell_not_
  //  return -1;
  }
  
+ /**
+  * Return true iff our decryption layer_hint is from the last hop
+  * in a circuit.
+  */
+ static bool
+ relay_crypt_from_last_hop(origin_circuit_t *circ, crypt_path_t *layer_hint)
+ {
+   tor_assert(circ);
+   tor_assert(layer_hint);
+   tor_assert(circ->cpath);
+ 
+   if (layer_hint != circ->cpath->prev) {
+     log_fn(LOG_PROTOCOL_WARN, LD_CIRC,
+            "Got unexpected relay data from intermediate hop");
+     return false;
+   }
+   return true;
+ }
+ 
 -/** An incoming relay cell has arrived on circuit <b>circ</b>. If
 - * <b>conn</b> is NULL this is a control cell, else <b>cell</b> is
 - * destined for <b>conn</b>.
 +/** Process a SENDME cell that arrived on <b>circ</b>. If it is a stream level
 + * cell, it is destined for the given <b>conn</b>. If it is a circuit level
 + * cell, it is destined for the <b>layer_hint</b>. The <b>domain</b> is the
 + * logging domain that should be used.
   *
 - * If <b>layer_hint</b> is defined, then we're the origin of the
 - * circuit, and it specifies the hop that packaged <b>cell</b>.
 - *
 - * Return -reason if you want to warn and tear down the circuit, else 0.
 - */
 -STATIC int
 -connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
 -                                   edge_connection_t *conn,
 -                                   crypt_path_t *layer_hint)
 + * Return 0 if everything went well or a negative value representing a circuit
 + * end reason on error for which the caller is responsible for closing it. */
 +static int
 +process_sendme_cell(const relay_header_t *rh, const cell_t *cell,
 +                    circuit_t *circ, edge_connection_t *conn,
 +                    crypt_path_t *layer_hint, int domain)
  {
 -  static int num_seen=0;
 -  relay_header_t rh;
 -  unsigned domain = layer_hint?LD_APP:LD_EXIT;
 -  int reason;
 -  int optimistic_data = 0; /* Set to 1 if we receive data on a stream
 -                            * that's in the EXIT_CONN_STATE_RESOLVING
 -                            * or EXIT_CONN_STATE_CONNECTING states. */
 +  int ret;
  
 -  tor_assert(cell);
 -  tor_assert(circ);
 -
 -  relay_header_unpack(&rh, cell->payload);
 -//  log_fn(LOG_DEBUG,"command %d stream %d", rh.command, rh.stream_id);
 -  num_seen++;
 -  log_debug(domain, "Now seen %d relay cells here (command %d, stream %d).",
 -            num_seen, rh.command, rh.stream_id);
 +  tor_assert(rh);
  
 -  if (rh.length > RELAY_PAYLOAD_SIZE) {
 -    log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
 -           "Relay cell length field too long. Closing circuit.");
 -    return - END_CIRC_REASON_TORPROTOCOL;
 +  if (!rh->stream_id) {
 +    /* Circuit level SENDME cell. */
 +    ret = sendme_process_circuit_level(layer_hint, circ,
 +                                       cell->payload + RELAY_HEADER_SIZE,
 +                                       rh->length);
 +    if (ret < 0) {
 +      return ret;
 +    }
 +    /* Resume reading on any streams now that we've processed a valid
 +     * SENDME cell that updated our package window. */
 +    circuit_resume_edge_reading(circ, layer_hint);
 +    /* We are done, the rest of the code is for the stream level. */
 +    return 0;
    }
  
 -  if (rh.stream_id == 0) {
 -    switch (rh.command) {
 -      case RELAY_COMMAND_BEGIN:
 -      case RELAY_COMMAND_CONNECTED:
 -      case RELAY_COMMAND_END:
 -      case RELAY_COMMAND_RESOLVE:
 -      case RELAY_COMMAND_RESOLVED:
 -      case RELAY_COMMAND_BEGIN_DIR:
 -        log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, "Relay command %d with zero "
 -               "stream_id. Dropping.", (int)rh.command);
 -        return 0;
 -      default:
 -        ;
 +  /* No connection, might be half edge state. We are done if so. */
 +  if (!conn) {
 +    if (CIRCUIT_IS_ORIGIN(circ)) {
 +      origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
 +      if (connection_half_edge_is_valid_sendme(ocirc->half_streams,
 +                                               rh->stream_id)) {
 +        circuit_read_valid_data(ocirc, rh->length);
 +        log_info(domain, "Sendme cell on circ %u valid on half-closed "
 +                         "stream id %d",
 +                 ocirc->global_identifier, rh->stream_id);
 +      }
      }
 +
 +    log_info(domain, "SENDME cell dropped, unknown stream (streamid %d).",
 +             rh->stream_id);
 +    return 0;
    }
  
 -  /* either conn is NULL, in which case we've got a control cell, or else
 -   * conn points to the recognized stream. */
 +  /* Stream level SENDME cell. */
 +  ret = sendme_process_stream_level(conn, circ, rh->length);
 +  if (ret < 0) {
 +    /* Means we need to close the circuit with reason ret. */
 +    return ret;
 +  }
  
 -  if (conn && !connection_state_is_open(TO_CONN(conn))) {
 -    if (conn->base_.type == CONN_TYPE_EXIT &&
 -        (conn->base_.state == EXIT_CONN_STATE_CONNECTING ||
 -         conn->base_.state == EXIT_CONN_STATE_RESOLVING) &&
 -        rh.command == RELAY_COMMAND_DATA) {
 -      /* Allow DATA cells to be delivered to an exit node in state
 -       * EXIT_CONN_STATE_CONNECTING or EXIT_CONN_STATE_RESOLVING.
 -       * This speeds up HTTP, for example. */
 -      optimistic_data = 1;
 -    } else if (rh.stream_id == 0 && rh.command == RELAY_COMMAND_DATA) {
 -      log_warn(LD_BUG, "Somehow I had a connection that matched a "
 -               "data cell with stream ID 0.");
 -    } else {
 -      return connection_edge_process_relay_cell_not_open(
 -               &rh, cell, circ, conn, layer_hint);
 -    }
 +  /* We've now processed properly a SENDME cell, all windows have been
 +   * properly updated, we'll read on the edge connection to see if we can
 +   * get data out towards the end point (Exit or client) since we are now
 +   * allowed to deliver more cells. */
 +
 +  if (circuit_queue_streams_are_blocked(circ)) {
 +    /* Still waiting for queue to flush; don't touch conn */
 +    return 0;
    }
 +  connection_start_reading(TO_CONN(conn));
 +  /* handle whatever might still be on the inbuf */
 +  if (connection_edge_package_raw_inbuf(conn, 1, NULL) < 0) {
 +    /* (We already sent an end cell if possible) */
 +    connection_mark_for_close(TO_CONN(conn));
 +    return 0;
 +  }
 +  return 0;
 +}
  
 -  switch (rh.command) {
 -    case RELAY_COMMAND_DROP:
 -      rep_hist_padding_count_read(PADDING_TYPE_DROP);
 -//      log_info(domain,"Got a relay-level padding cell. Dropping.");
 -      return 0;
 +/** A helper for connection_edge_process_relay_cell(): Actually handles the
 + *  cell that we received on the connection.
 + *
 + *  The arguments are the same as in the parent function
 + *  connection_edge_process_relay_cell(), plus the relay header <b>rh</b> as
 + *  unpacked by the parent function, and <b>optimistic_data</b> as set by the
 + *  parent function.
 + */
 +STATIC int
 +handle_relay_cell_command(cell_t *cell, circuit_t *circ,
 +                     edge_connection_t *conn, crypt_path_t *layer_hint,
 +                     relay_header_t *rh, int optimistic_data)
 +{
 +  unsigned domain = layer_hint?LD_APP:LD_EXIT;
 +  int reason;
 +
 +  tor_assert(rh);
 +
 +  /* First pass the cell to the circuit padding subsystem, in case it's a
 +   * padding cell or circuit that should be handled there. */
 +  if (circpad_check_received_cell(cell, circ, layer_hint, rh) == 0) {
 +    log_debug(domain, "Cell handled as circuit padding");
 +    return 0;
 +  }
 +
 +  /* Now handle all the other commands */
 +  switch (rh->command) {
      case RELAY_COMMAND_BEGIN:
      case RELAY_COMMAND_BEGIN_DIR:
        if (layer_hint &&
@@@ -1716,10 -1635,11 +1735,19 @@@
        if (!conn) {
          if (CIRCUIT_IS_ORIGIN(circ)) {
            origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
++<<<<<<< HEAD
 +          if (connection_half_edge_is_valid_end(ocirc->half_streams,
 +                                                rh->stream_id)) {
++||||||| d71bf986b4faf7
++          if (connection_half_edge_is_valid_end(ocirc->half_streams,
++                                                rh.stream_id)) {
++=======
+           if (relay_crypt_from_last_hop(ocirc, layer_hint) &&
+               connection_half_edge_is_valid_end(ocirc->half_streams,
+                                                 rh.stream_id)) {
++>>>>>>> maint-0.3.5
  
 -            circuit_read_valid_data(ocirc, rh.length);
 +            circuit_read_valid_data(ocirc, rh->length);
              log_info(domain,
                       "end cell (%s) on circ %u valid on half-closed "
                       "stream id %d",
@@@ -1926,12 -1938,13 +1954,23 @@@
  
        if (CIRCUIT_IS_ORIGIN(circ)) {
          origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
++<<<<<<< HEAD
 +        if (connection_half_edge_is_valid_resolved(ocirc->half_streams,
 +                                                    rh->stream_id)) {
 +          circuit_read_valid_data(ocirc, rh->length);
++||||||| d71bf986b4faf7
++        if (connection_half_edge_is_valid_resolved(ocirc->half_streams,
++                                                    rh.stream_id)) {
++          circuit_read_valid_data(ocirc, rh.length);
++=======
+         if (relay_crypt_from_last_hop(ocirc, layer_hint) &&
+             connection_half_edge_is_valid_resolved(ocirc->half_streams,
+                                                     rh.stream_id)) {
+           circuit_read_valid_data(ocirc, rh.length);
++>>>>>>> maint-0.3.5
            log_info(domain,
                     "resolved cell on circ %u valid on half-closed "
 -                   "stream id %d", ocirc->global_identifier, rh.stream_id);
 +                   "stream id %d", ocirc->global_identifier, rh->stream_id);
            return 0;
          }
        }



_______________________________________________
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits

Reply via email to