Commit d3292e48 authored by Roger Dingledine's avatar Roger Dingledine
Browse files

implement truncate and truncated (untested)

clean up circuit_deliver_relay_cell convention


svn:r312
parent 7137a578
Loading
Loading
Loading
Loading
+30 −27
Original line number Diff line number Diff line
@@ -225,30 +225,6 @@ circuit_t *circuit_get_newest_ap(void) {
  return bestcirc;
}

int circuit_deliver_relay_cell_from_edge(cell_t *cell, circuit_t *circ,
                                         char edge_type, crypt_path_t *layer_hint) {
  int cell_direction;
  static int numsent_ap=0, numsent_exit=0;

  log(LOG_DEBUG,"circuit_deliver_relay_cell_from_edge(): called, edge_type %d.", edge_type);

  if(edge_type == EDGE_AP) { /* i'm the AP */
    cell_direction = CELL_DIRECTION_OUT;
    numsent_ap++;
    log(LOG_DEBUG,"circuit_deliver_relay_cell_from_edge(): now sent %d relay cells from ap", numsent_ap);
  } else { /* i'm the exit */
    cell_direction = CELL_DIRECTION_IN;
    numsent_exit++;
    log(LOG_DEBUG,"circuit_deliver_relay_cell_from_edge(): now sent %d relay cells from exit", numsent_exit);
  }

  if(circuit_deliver_relay_cell(cell, circ, cell_direction, layer_hint) < 0) {
    return -1;
  }

  return 0;
}

int circuit_deliver_relay_cell(cell_t *cell, circuit_t *circ,
                               int cell_direction, crypt_path_t *layer_hint) {
  connection_t *conn=NULL;
@@ -483,7 +459,7 @@ int circuit_consider_sending_sendme(circuit_t *circ, int edge_type, crypt_path_t
    while(layer_hint->deliver_window < CIRCWINDOW_START-CIRCWINDOW_INCREMENT) {
      log(LOG_DEBUG,"circuit_consider_sending_sendme(): deliver_window %d, Queueing sendme forward.", layer_hint->deliver_window);
      layer_hint->deliver_window += CIRCWINDOW_INCREMENT;
      if(circuit_deliver_relay_cell_from_edge(&cell, circ, edge_type, layer_hint) < 0) {
      if(circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION_OUT, layer_hint) < 0) {
        return -1;
      }
    }
@@ -492,7 +468,7 @@ int circuit_consider_sending_sendme(circuit_t *circ, int edge_type, crypt_path_t
    while(circ->deliver_window < CIRCWINDOW_START-CIRCWINDOW_INCREMENT) {
      log(LOG_DEBUG,"circuit_consider_sending_sendme(): deliver_window %d, Queueing sendme back.", circ->deliver_window);
      circ->deliver_window += CIRCWINDOW_INCREMENT;
      if(circuit_deliver_relay_cell_from_edge(&cell, circ, edge_type, layer_hint) < 0) {
      if(circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION_IN, layer_hint) < 0) {
        return -1;
      }
    }
@@ -801,7 +777,7 @@ int circuit_send_next_onion_skin(circuit_t *circ) {

    log(LOG_DEBUG,"circuit_send_next_onion_skin(): Sending extend relay cell.");
    /* send it to hop->prev, because it will transfer it to a create cell and then send to hop */
    if(circuit_deliver_relay_cell_from_edge(&cell, circ, EDGE_AP, hop->prev) < 0) {
    if(circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION_OUT, hop->prev) < 0) {
      log(LOG_DEBUG,"circuit_send_next_onion_skin(): failed to deliver extend cell. Closing.");
      return -1;
    }
@@ -921,6 +897,33 @@ int circuit_finish_handshake(circuit_t *circ, char *reply) {
  return 0;
}

int circuit_truncated(circuit_t *circ, crypt_path_t *layer) {
  crypt_path_t *victim;
  connection_t *stream;

  assert(circ);
  assert(layer);

  while(layer->next != circ->cpath) {
    /* we need to clear out layer->next */
    victim = layer->next;
    log(LOG_DEBUG, "circuit_truncated(): Killing a layer of the cpath.");

    for(stream = circ->p_streams; stream; stream=stream->next_stream) {
      if(stream->cpath_layer == victim) {
        log(LOG_DEBUG, "circuit_truncated(): Marking stream %d for close.", *(int*)stream->stream_id);
        stream->marked_for_close = 1;
      }
    }

    layer->next = victim->next;
    circuit_free_cpath_node(victim);
  }

  log(LOG_DEBUG, "circuit_truncated(): Complete.");
  return 0;
}

/*
  Local Variables:
  mode:c
+1 −1
Original line number Diff line number Diff line
@@ -147,7 +147,7 @@ void command_process_created_cell(cell_t *cell, connection_t *conn) {
    memcpy(newcell.payload+RELAY_HEADER_SIZE, cell->payload, DH_KEY_LEN);

    log(LOG_DEBUG,"command_process_created_cell(): Sending extended relay cell.");
    if(circuit_deliver_relay_cell_from_edge(&newcell, circ, EDGE_EXIT, NULL) < 0) {
    if(circuit_deliver_relay_cell(&newcell, circ, CELL_DIRECTION_IN, NULL) < 0) {
      log(LOG_DEBUG,"command_process_created_cell(): failed to deliver extended cell. Closing.");
      circuit_close(circ);
      return;
+6 −6
Original line number Diff line number Diff line
@@ -685,8 +685,8 @@ repeat_connection_package_raw_inbuf:

  if(conn->type == CONN_TYPE_EXIT) {
    cell.aci = circ->p_aci;
    if(circuit_deliver_relay_cell_from_edge(&cell, circ, EDGE_EXIT, NULL) < 0) {
      log(LOG_DEBUG,"connection_package_raw_inbuf(): circuit_deliver_relay_cell_from_edge (backward) failed. Closing.");
    if(circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION_IN, NULL) < 0) {
      log(LOG_DEBUG,"connection_package_raw_inbuf(): circuit_deliver_relay_cell (backward) failed. Closing.");
      circuit_close(circ);
      return 0;
    }
@@ -695,8 +695,8 @@ repeat_connection_package_raw_inbuf:
  } else { /* send it forward. we're an AP */
    assert(conn->type == CONN_TYPE_AP);
    cell.aci = circ->n_aci;
    if(circuit_deliver_relay_cell_from_edge(&cell, circ, EDGE_AP, conn->cpath_layer) < 0) {
      log(LOG_DEBUG,"connection_package_raw_inbuf(): circuit_deliver_relay_cell_from_edge (forward) failed. Closing.");
    if(circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION_OUT, conn->cpath_layer) < 0) {
      log(LOG_DEBUG,"connection_package_raw_inbuf(): circuit_deliver_relay_cell (forward) failed. Closing.");
      circuit_close(circ);
      return 0;
    }
@@ -749,8 +749,8 @@ int connection_consider_sending_sendme(connection_t *conn, int edge_type) {
  while(conn->deliver_window < STREAMWINDOW_START - STREAMWINDOW_INCREMENT) {
    log(LOG_DEBUG,"connection_consider_sending_sendme(): Outbuf %d, Queueing stream sendme.", conn->outbuf_flushlen);
    conn->deliver_window += STREAMWINDOW_INCREMENT;
    if(circuit_deliver_relay_cell_from_edge(&cell, circ, edge_type, conn->cpath_layer) < 0) {
      log(LOG_DEBUG,"connection_consider_sending_sendme(): circuit_deliver_relay_cell_from_edge failed. Closing.");
    if(circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION(edge_type), conn->cpath_layer) < 0) {
      log(LOG_DEBUG,"connection_consider_sending_sendme(): circuit_deliver_relay_cell failed. Closing.");
      circuit_close(circ);
      return 0;
    }
+1 −1
Original line number Diff line number Diff line
@@ -136,7 +136,7 @@ int ap_handshake_send_begin(connection_t *ap_conn, circuit_t *circ) {
             "%s:%d", ap_conn->dest_addr, ap_conn->dest_port) + 
    1 + STREAM_ID_SIZE + RELAY_HEADER_SIZE;
  log(LOG_DEBUG,"ap_handshake_send_begin(): Sending relay cell (id %d) to begin stream %d.", *(int *)(cell.payload+1),*(int *)ap_conn->stream_id);
  if(circuit_deliver_relay_cell_from_edge(&cell, circ, EDGE_AP, ap_conn->cpath_layer) < 0) {
  if(circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION_OUT, ap_conn->cpath_layer) < 0) {
    log(LOG_DEBUG,"ap_handshake_send_begin(): failed to deliver begin cell. Closing.");
    return -1;
  }
+36 −12
Original line number Diff line number Diff line
@@ -31,8 +31,8 @@ int connection_edge_process_inbuf(connection_t *conn) {
    SET_CELL_STREAM_ID(cell, conn->stream_id);
    cell.aci = circ->n_aci;

    if (circuit_deliver_relay_cell_from_edge(&cell, circ, conn->type, conn->cpath_layer) < 0) {
      log(LOG_DEBUG,"connection_edge_process_inbuf: circuit_deliver_relay_cell_from_edge failed.  Closing");
    if (circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION(conn->type), conn->cpath_layer) < 0) {
      log(LOG_DEBUG,"connection_edge_process_inbuf: circuit_deliver_relay_cell failed. Closing.");
      circuit_close(circ);
    }
    return 0;
@@ -60,30 +60,37 @@ int connection_edge_process_inbuf(connection_t *conn) {
  return 0;
}

int connection_edge_send_command(connection_t *conn, circuit_t *circ, int relay_command) {
int connection_edge_send_command(connection_t *fromconn, circuit_t *circ, int relay_command) {
  cell_t cell;

  assert(conn);
  int cell_direction;

  if(!circ) {
    log(LOG_DEBUG,"connection_edge_send_command(): conn has no circ. Closing.");
    log(LOG_DEBUG,"connection_edge_send_command(): no circ. Closing.");
    return -1;
  }

  memset(&cell, 0, sizeof(cell_t));
  if(conn->type == CONN_TYPE_AP)
  if(fromconn && fromconn->type == CONN_TYPE_AP) {
    cell.aci = circ->n_aci;
  else
    cell_direction = CELL_DIRECTION_OUT;
  } else {
    /* NOTE: if !fromconn, we assume that it's heading towards the OP */
    cell.aci = circ->p_aci;
    cell_direction = CELL_DIRECTION_IN;
  }

  cell.command = CELL_RELAY;
  SET_CELL_RELAY_COMMAND(cell, relay_command);
  SET_CELL_STREAM_ID(cell, conn->stream_id);
  if(fromconn)
    SET_CELL_STREAM_ID(cell, fromconn->stream_id);
  else
    SET_CELL_STREAM_ID(cell, ZERO_STREAM);

  cell.length = RELAY_HEADER_SIZE;
  log(LOG_INFO,"connection_edge_send_command(): delivering %d cell %s.", relay_command, conn->type == CONN_TYPE_AP ? "forward" : "backward");
  log(LOG_INFO,"connection_edge_send_command(): delivering %d cell %s.", relay_command, cell_direction == CELL_DIRECTION_OUT ? "forward" : "backward");

  if(circuit_deliver_relay_cell_from_edge(&cell, circ, conn->type, conn->cpath_layer) < 0) {
    log(LOG_DEBUG,"connection_edge_send_command(): circuit_deliver_relay_cell_from_edge failed. Closing.");
  if(circuit_deliver_relay_cell(&cell, circ, cell_direction, fromconn ? fromconn->cpath_layer : NULL) < 0) {
    log(LOG_DEBUG,"connection_edge_send_command(): circuit_deliver_relay_cell failed. Closing.");
    circuit_close(circ);
    return 0;
  }
@@ -199,6 +206,23 @@ int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, connection
        return -1;
      }
      return circuit_send_next_onion_skin(circ);
    case RELAY_COMMAND_TRUNCATE:
      if(edge_type == EDGE_AP) {
        log(LOG_INFO,"connection_edge_process_relay_cell(): 'truncate' unsupported at AP. Dropping.");
        return 0;
      }
      if(circ->n_conn) {
        connection_send_destroy(circ->n_aci, circ->n_conn);
        circ->n_conn = NULL;
      }
      log(LOG_DEBUG, "connection_edge_process_relay_cell(): Processed 'truncate', replying.");
      return connection_edge_send_command(NULL, circ, RELAY_COMMAND_TRUNCATED);
    case RELAY_COMMAND_TRUNCATED:
      if(edge_type == EDGE_EXIT) {
        log(LOG_INFO,"connection_edge_process_relay_cell(): 'truncated' unsupported at exit. Dropping.");
        return 0;
      }
      return circuit_truncated(circ, layer_hint);
    case RELAY_COMMAND_CONNECTED:
      if(edge_type == EDGE_EXIT) {
        log(LOG_INFO,"connection_edge_process_relay_cell(): 'connected' unsupported at exit. Dropping.");
Loading