[or-cvs] break part of circuit.c into relay.c

Roger Dingledine arma at seul.org
Wed May 12 19:49:51 UTC 2004


Update of /home/or/cvsroot/src/or
In directory moria.mit.edu:/home2/arma/work/onion/cvs/src/or

Modified Files:
	Makefile.am circuit.c connection.c directory.c or.h 
	routerlist.c 
Added Files:
	relay.c 
Log Message:
break part of circuit.c into relay.c


--- NEW FILE: relay.c ---
/* Copyright 2001 Matej Pfajfar, 2001-2004 Roger Dingledine. */
/* See LICENSE for licensing information */
/* $Id: relay.c,v 1.1 2004/05/12 19:49:48 arma Exp $ */

/**
 * \file relay.c
 * \brief Handle relay cell encryption/decryption.
 **/

#include "or.h"

static int relay_crypt(circuit_t *circ, cell_t *cell, int cell_direction,
                crypt_path_t **layer_hint, char *recognized);
static connection_t *relay_lookup_conn(circuit_t *circ, cell_t *cell, int cell_direction)
;

/** Stats: how many relay cells have originated at this hop, or have
 * been relayed onward (not recognized at this hop)?
 */
unsigned long stats_n_relay_cells_relayed = 0;
/** Stats: how many relay cells have been delivered to streams at this
 * hop?
 */
unsigned long stats_n_relay_cells_delivered = 0;

/** Update digest from the payload of cell. Assign integrity part to
 * cell.
 */
static void relay_set_digest(crypto_digest_env_t *digest, cell_t *cell) {
  char integrity[4];
  relay_header_t rh;

  crypto_digest_add_bytes(digest, cell->payload, CELL_PAYLOAD_SIZE);
  crypto_digest_get_digest(digest, integrity, 4);
//  log_fn(LOG_DEBUG,"Putting digest of %u %u %u %u into relay cell.",
//    integrity[0], integrity[1], integrity[2], integrity[3]);
  relay_header_unpack(&rh, cell->payload);
  memcpy(rh.integrity, integrity, 4);
  relay_header_pack(cell->payload, &rh);
}

/** Does the digest for this circuit indicate that this cell is for us?
 *
 * Update digest from the payload of cell (with the integrity part set
 * to 0). If the integrity part is valid, return 1, else restore digest
 * and cell to their original state and return 0.
 */
static int relay_digest_matches(crypto_digest_env_t *digest, cell_t *cell) {
  char received_integrity[4], calculated_integrity[4];
  relay_header_t rh;
  crypto_digest_env_t *backup_digest=NULL;

  backup_digest = crypto_digest_dup(digest);

  relay_header_unpack(&rh, cell->payload);
  memcpy(received_integrity, rh.integrity, 4);
  memset(rh.integrity, 0, 4);
  relay_header_pack(cell->payload, &rh);

//  log_fn(LOG_DEBUG,"Reading digest of %u %u %u %u from relay cell.",
//    received_integrity[0], received_integrity[1],
//    received_integrity[2], received_integrity[3]);

  crypto_digest_add_bytes(digest, cell->payload, CELL_PAYLOAD_SIZE);
  crypto_digest_get_digest(digest, calculated_integrity, 4);

  if(memcmp(received_integrity, calculated_integrity, 4)) {
//    log_fn(LOG_INFO,"Recognized=0 but bad digest. Not recognizing.");
// (%d vs %d).", received_integrity, calculated_integrity);
    /* restore digest to its old form */
    crypto_digest_assign(digest, backup_digest);
    /* restore the relay header */
    memcpy(rh.integrity, received_integrity, 4);
    relay_header_pack(cell->payload, &rh);
    crypto_free_digest_env(backup_digest);
    return 0;
  }
  crypto_free_digest_env(backup_digest);
  return 1;
}

/** Apply <b>cipher</b> to CELL_PAYLOAD_SIZE bytes of <b>in</b>
 * (in place).
 *
 * If <b>encrypt_mode</b> is 1 then encrypt, else decrypt.
 *
 * Return -1 if the crypto fails, else return 0.
 */
static int relay_crypt_one_payload(crypto_cipher_env_t *cipher, char *in,
                                   int encrypt_mode) {
  char out[CELL_PAYLOAD_SIZE]; /* 'in' must be this size too */
  relay_header_t rh;

  relay_header_unpack(&rh, in);
//  log_fn(LOG_DEBUG,"before crypt: %d",rh.recognized);
  if(( encrypt_mode && crypto_cipher_encrypt(cipher, in, CELL_PAYLOAD_SIZE, out)) ||
     (!encrypt_mode && crypto_cipher_decrypt(cipher, in, CELL_PAYLOAD_SIZE, out))) {
    log_fn(LOG_WARN,"Error during relay encryption");
    return -1;
  }
  memcpy(in,out,CELL_PAYLOAD_SIZE);
  relay_header_unpack(&rh, in);
//  log_fn(LOG_DEBUG,"after crypt: %d",rh.recognized);
  return 0;
}

/** Receive a relay cell:
 *  - Crypt it (encrypt APward, decrypt at AP, decrypt exitward).
 *  - Check if recognized (if exitward).
 *  - If recognized and the digest checks out, then find if there's
 *    a conn that the cell is intended for, and deliver it to·
 *    connection_edge.
 *  - Else connection_or_write_cell_to_buf to the conn on the other
 *    side of the circuit.
 */
int circuit_receive_relay_cell(cell_t *cell, circuit_t *circ,
                               int cell_direction) {
  connection_t *conn=NULL;
  crypt_path_t *layer_hint=NULL;
  char recognized=0;

  tor_assert(cell && circ);
  tor_assert(cell_direction == CELL_DIRECTION_OUT || cell_direction == CELL_DIRECTION_IN);
  if (circ->marked_for_close)
    return 0;

  if(relay_crypt(circ, cell, cell_direction, &layer_hint, &recognized) < 0) {
    log_fn(LOG_WARN,"relay crypt failed. Dropping connection.");
    return -1;
  }

  if(recognized) {
    conn = relay_lookup_conn(circ, cell, cell_direction);
    if(cell_direction == CELL_DIRECTION_OUT) {
      ++stats_n_relay_cells_delivered;
      log_fn(LOG_DEBUG,"Sending away from origin.");
      if (connection_edge_process_relay_cell(cell, circ, conn, NULL) < 0) {
        log_fn(LOG_WARN,"connection_edge_process_relay_cell (away from origin) failed.");
        return -1;
      }
    }
    if(cell_direction == CELL_DIRECTION_IN) {
      ++stats_n_relay_cells_delivered;
      log_fn(LOG_DEBUG,"Sending to origin.");
      if (connection_edge_process_relay_cell(cell, circ, conn, layer_hint) < 0) {
        log_fn(LOG_WARN,"connection_edge_process_relay_cell (at origin) failed.");
        return -1;
      }
    }
    return 0;
  }

  /* not recognized. pass it on. */
  if(cell_direction == CELL_DIRECTION_OUT) {
    cell->circ_id = circ->n_circ_id; /* switch it */
    conn = circ->n_conn;
  } else {
    cell->circ_id = circ->p_circ_id; /* switch it */
    conn = circ->p_conn;
  }

  if(!conn) {
    if (circ->rend_splice && cell_direction == CELL_DIRECTION_OUT) {
      tor_assert(circ->purpose == CIRCUIT_PURPOSE_REND_ESTABLISHED);
      tor_assert(circ->rend_splice->purpose == CIRCUIT_PURPOSE_REND_ESTABLISHED);
      cell->circ_id = circ->rend_splice->p_circ_id;
      if (circuit_receive_relay_cell(cell, circ->rend_splice, CELL_DIRECTION_IN)<0) {
        log_fn(LOG_WARN, "Error relaying cell across rendezvous; closing circuits");
        circuit_mark_for_close(circ); /* XXXX Do this here, or just return -1? */
        return -1;
      }
      return 0;
    }
    log_fn(LOG_WARN,"Didn't recognize cell, but circ stops here! Closing circ.");
    return -1;
  }

  log_fn(LOG_DEBUG,"Passing on unrecognized cell.");
  ++stats_n_relay_cells_relayed;
  connection_or_write_cell_to_buf(cell, conn);
  return 0;
}

/** Do the appropriate en/decryptions for <b>cell</b> arriving on
 * <b>circ</b> in direction <b>cell_direction</b>.
 *
 * If cell_direction == CELL_DIRECTION_IN:
 *   - If we're at the origin (we're the OP), for hops 1..N,
 *     decrypt cell. If recognized, stop.
 *   - Else (we're not the OP), encrypt one hop. Cell is not recognized.
 *
 * If cell_direction == CELL_DIRECTION_OUT:
 *   - decrypt one hop. Check if recognized.
 *
 * If cell is recognized, set *recognized to 1, and set
 * *layer_hint to the hop that recognized it.
 *
 * Return -1 to indicate that we should mark the circuit for close,
 * else return 0.
 */
/* wrap this into receive_relay_cell one day */
static int relay_crypt(circuit_t *circ, cell_t *cell, int cell_direction,
                       crypt_path_t **layer_hint, char *recognized) {
  crypt_path_t *thishop;
  relay_header_t rh;

  tor_assert(circ && cell && recognized);
  tor_assert(cell_direction == CELL_DIRECTION_IN || cell_direction == CELL_DIRECTION_OUT); 

  if(cell_direction == CELL_DIRECTION_IN) {
    if(CIRCUIT_IS_ORIGIN(circ)) { /* We're at the beginning of the circuit.
                                     We'll want to do layered decrypts. */
      tor_assert(circ->cpath);
      thishop = circ->cpath;
      if(thishop->state != CPATH_STATE_OPEN) {
        log_fn(LOG_WARN,"Relay cell before first created cell? Closing.");
        return -1;
      }
      do { /* Remember: cpath is in forward order, that is, first hop first. */
        tor_assert(thishop);

        if(relay_crypt_one_payload(thishop->b_crypto, cell->payload, 0) < 0)
          return -1;

        relay_header_unpack(&rh, cell->payload);
        if(rh.recognized == 0) {
          /* it's possibly recognized. have to check digest to be sure. */
          if(relay_digest_matches(thishop->b_digest, cell)) {
            *recognized = 1;
            *layer_hint = thishop;
            return 0;
          }
        }

        thishop = thishop->next;
      } while(thishop != circ->cpath && thishop->state == CPATH_STATE_OPEN);
      log_fn(LOG_WARN,"in-cell at OP not recognized. Closing.");
      return -1;
    } else { /* we're in the middle. Just one crypt. */
      if(relay_crypt_one_payload(circ->p_crypto, cell->payload, 1) < 0)
        return -1;
//      log_fn(LOG_DEBUG,"Skipping recognized check, because we're not the OP.");
    }
  } else /* cell_direction == CELL_DIRECTION_OUT */ {
    /* we're in the middle. Just one crypt. */

    if(relay_crypt_one_payload(circ->n_crypto, cell->payload, 0) < 0)
      return -1;

    relay_header_unpack(&rh, cell->payload);
    if (rh.recognized == 0) {
      /* it's possibly recognized. have to check digest to be sure. */
      if(relay_digest_matches(circ->n_digest, cell)) {
        *recognized = 1;
        return 0;
      }
    }
  }
  return 0;
}

/** Package a relay cell:
 *  - Encrypt it to the right layer
 *  - connection_or_write_cell_to_buf to the right conn
 */
int
circuit_package_relay_cell(cell_t *cell, circuit_t *circ,
                           int cell_direction,
                           crypt_path_t *layer_hint)
{ 
  connection_t *conn; /* where to send the cell */
  crypt_path_t *thishop; /* counter for repeated crypts */

  if(cell_direction == CELL_DIRECTION_OUT) {
    conn = circ->n_conn;
    if(!conn) {
      log_fn(LOG_WARN,"outgoing relay cell has n_conn==NULL. Dropping.");
      return 0; /* just drop it */
    }
    relay_set_digest(layer_hint->f_digest, cell);

    thishop = layer_hint;
    /* moving from farthest to nearest hop */
    do {
      tor_assert(thishop);

      log_fn(LOG_DEBUG,"crypting a layer of the relay cell.");
      if(relay_crypt_one_payload(thishop->f_crypto, cell->payload, 1) < 0) {
        return -1;
      }

      thishop = thishop->prev;
    } while (thishop != circ->cpath->prev);

  } else { /* incoming cell */
    conn = circ->p_conn;
    if(!conn) {
      log_fn(LOG_WARN,"incoming relay cell has p_conn==NULL. Dropping.");
      return 0; /* just drop it */
    }
    relay_set_digest(circ->p_digest, cell);
    if(relay_crypt_one_payload(circ->p_crypto, cell->payload, 1) < 0)
      return -1;
  }
  ++stats_n_relay_cells_relayed;
  connection_or_write_cell_to_buf(cell, conn);
  return 0;
}

/** If cell's stream_id matches the stream_id of any conn that's
 * attached to circ, return that conn, else return NULL.
 */
static connection_t *
relay_lookup_conn(circuit_t *circ, cell_t *cell, int cell_direction)
{
  connection_t *tmpconn;
  relay_header_t rh;

  relay_header_unpack(&rh, cell->payload);

  if(!rh.stream_id)
    return NULL;

  /* IN or OUT cells could have come from either direction, now
   * that we allow rendezvous *to* an OP.
   */

  for(tmpconn = circ->n_streams; tmpconn; tmpconn=tmpconn->next_stream) {
    if(rh.stream_id == tmpconn->stream_id) {
      log_fn(LOG_DEBUG,"found conn for stream %d.", rh.stream_id);
      if(cell_direction == CELL_DIRECTION_OUT ||
         connection_edge_is_rendezvous_stream(tmpconn))
        return tmpconn;
    }
  }
  for(tmpconn = circ->p_streams; tmpconn; tmpconn=tmpconn->next_stream) {
    if(rh.stream_id == tmpconn->stream_id) {
      log_fn(LOG_DEBUG,"found conn for stream %d.", rh.stream_id);
      return tmpconn;
    }
  }
  for(tmpconn = circ->resolving_streams; tmpconn; tmpconn=tmpconn->next_stream) {
    if(rh.stream_id == tmpconn->stream_id) {
      log_fn(LOG_DEBUG,"found conn for stream %d.", rh.stream_id);
      return tmpconn;
    }
  }
  return NULL; /* probably a begin relay cell */
}


Index: Makefile.am
===================================================================
RCS file: /home/or/cvsroot/src/or/Makefile.am,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -d -r1.32 -r1.33
--- Makefile.am	10 May 2004 17:30:51 -0000	1.32
+++ Makefile.am	12 May 2004 19:49:48 -0000	1.33
@@ -7,7 +7,7 @@
 tor_SOURCES = buffers.c circuit.c command.c config.c \
 	connection.c connection_edge.c connection_or.c \
 	cpuworker.c directory.c dirserv.c dns.c main.c \
-	onion.c rendcommon.c rendclient.c rendmid.c \
+	onion.c relay.c rendcommon.c rendclient.c rendmid.c \
 	rendservice.c rephist.c router.c routerlist.c routerparse.c \
 	tor_main.c
 
@@ -16,7 +16,7 @@
 test_SOURCES = buffers.c circuit.c command.c config.c \
 	connection.c connection_edge.c connection_or.c \
 	cpuworker.c directory.c dirserv.c dns.c main.c \
-	onion.c rendcommon.c rendclient.c rendmid.c \
+	onion.c relay.c rendcommon.c rendclient.c rendmid.c \
 	rendservice.c rephist.c router.c routerlist.c routerparse.c \
 	test.c
 
@@ -24,4 +24,3 @@
 
 noinst_HEADERS = or.h tree.h
 
-

Index: circuit.c
===================================================================
RCS file: /home/or/cvsroot/src/or/circuit.c,v
retrieving revision 1.232
retrieving revision 1.233
diff -u -d -r1.232 -r1.233
--- circuit.c	10 May 2004 07:02:58 -0000	1.232
+++ circuit.c	12 May 2004 19:49:48 -0000	1.233
@@ -4,17 +4,13 @@
 
 /**
  * \file circuit.c
- * \brief Manage circuits and the global circuit list. Also handle
- * relay cell encryption/decryption.
+ * \brief Manage circuits and the global circuit list.
  **/
 
 #include "or.h"
 
 extern or_options_t options; /* command-line and config-file options */
 
-static int relay_crypt(circuit_t *circ, cell_t *cell, int cell_direction,
-                crypt_path_t **layer_hint, char *recognized);
-static connection_t *relay_lookup_conn(circuit_t *circ, cell_t *cell, int cell_direction);
 static int circuit_resume_edge_reading_helper(connection_t *conn,
                                               circuit_t *circ,
                                               crypt_path_t *layer_hint);
@@ -27,15 +23,6 @@
 static void circuit_build_failed(circuit_t *circ);
 static circuit_t *circuit_establish_circuit(uint8_t purpose, const char *exit_nickname);
 
-/** Stats: how many relay cells have originated at this hop, or have
- * been relayed onward (not recognized at this hop)?
- */
-unsigned long stats_n_relay_cells_relayed = 0;
-/** Stats: how many relay cells have been delivered to streams at this
- * hop?
- */
-unsigned long stats_n_relay_cells_delivered = 0;
-
 /********* START VARIABLES **********/
 
 /** A global (within this file) list of all circuits at this hop. */
@@ -675,331 +662,6 @@
   /* XXX count idle rendezvous circs and build more */
 }
 
-/** Update digest from the payload of cell. Assign integrity part to
- * cell.
- */
-static void relay_set_digest(crypto_digest_env_t *digest, cell_t *cell) {
-  char integrity[4];
-  relay_header_t rh;
-
-  crypto_digest_add_bytes(digest, cell->payload, CELL_PAYLOAD_SIZE);
-  crypto_digest_get_digest(digest, integrity, 4);
-//  log_fn(LOG_DEBUG,"Putting digest of %u %u %u %u into relay cell.",
-//    integrity[0], integrity[1], integrity[2], integrity[3]);
-  relay_header_unpack(&rh, cell->payload);
-  memcpy(rh.integrity, integrity, 4);
-  relay_header_pack(cell->payload, &rh);
-}
-
-/** Does the digest for this circuit indicate that this cell is for us?
- *
- * Update digest from the payload of cell (with the integrity part set
- * to 0). If the integrity part is valid, return 1, else restore digest
- * and cell to their original state and return 0.
- */
-static int relay_digest_matches(crypto_digest_env_t *digest, cell_t *cell) {
-  char received_integrity[4], calculated_integrity[4];
-  relay_header_t rh;
-  crypto_digest_env_t *backup_digest=NULL;
-
-  backup_digest = crypto_digest_dup(digest);
-
-  relay_header_unpack(&rh, cell->payload);
-  memcpy(received_integrity, rh.integrity, 4);
-  memset(rh.integrity, 0, 4);
-  relay_header_pack(cell->payload, &rh);
-
-//  log_fn(LOG_DEBUG,"Reading digest of %u %u %u %u from relay cell.",
-//    received_integrity[0], received_integrity[1],
-//    received_integrity[2], received_integrity[3]);
-
-  crypto_digest_add_bytes(digest, cell->payload, CELL_PAYLOAD_SIZE);
-  crypto_digest_get_digest(digest, calculated_integrity, 4);
-
-  if(memcmp(received_integrity, calculated_integrity, 4)) {
-//    log_fn(LOG_INFO,"Recognized=0 but bad digest. Not recognizing.");
-// (%d vs %d).", received_integrity, calculated_integrity);
-    /* restore digest to its old form */
-    crypto_digest_assign(digest, backup_digest);
-    /* restore the relay header */
-    memcpy(rh.integrity, received_integrity, 4);
-    relay_header_pack(cell->payload, &rh);
-    crypto_free_digest_env(backup_digest);
-    return 0;
-  }
-  crypto_free_digest_env(backup_digest);
-  return 1;
-}
-
-/** Apply <b>cipher</b> to CELL_PAYLOAD_SIZE bytes of <b>in</b>
- * (in place).
- *
- * If <b>encrypt_mode</b> is 1 then encrypt, else decrypt.
- *
- * Return -1 if the crypto fails, else return 0.
- */
-static int relay_crypt_one_payload(crypto_cipher_env_t *cipher, char *in,
-                                   int encrypt_mode) {
-  char out[CELL_PAYLOAD_SIZE]; /* 'in' must be this size too */
-  relay_header_t rh;
-
-  relay_header_unpack(&rh, in);
-//  log_fn(LOG_DEBUG,"before crypt: %d",rh.recognized);
-  if(( encrypt_mode && crypto_cipher_encrypt(cipher, in, CELL_PAYLOAD_SIZE, out)) ||
-     (!encrypt_mode && crypto_cipher_decrypt(cipher, in, CELL_PAYLOAD_SIZE, out))) {
-    log_fn(LOG_WARN,"Error during relay encryption");
-    return -1;
-  }
-  memcpy(in,out,CELL_PAYLOAD_SIZE);
-  relay_header_unpack(&rh, in);
-//  log_fn(LOG_DEBUG,"after crypt: %d",rh.recognized);
-  return 0;
-}
-
-/** Receive a relay cell:
- *  - Crypt it (encrypt APward, decrypt at AP, decrypt exitward).
- *  - Check if recognized (if exitward).
- *  - If recognized and the digest checks out, then find if there's
- *    a conn that the cell is intended for, and deliver it to 
- *    connection_edge.
- *  - Else connection_or_write_cell_to_buf to the conn on the other
- *    side of the circuit.
- */
-int circuit_receive_relay_cell(cell_t *cell, circuit_t *circ,
-                               int cell_direction) {
-  connection_t *conn=NULL;
-  crypt_path_t *layer_hint=NULL;
-  char recognized=0;
-
-  tor_assert(cell && circ);
-  tor_assert(cell_direction == CELL_DIRECTION_OUT || cell_direction == CELL_DIRECTION_IN);
-  if (circ->marked_for_close)
-    return 0;
-
-  if(relay_crypt(circ, cell, cell_direction, &layer_hint, &recognized) < 0) {
-    log_fn(LOG_WARN,"relay crypt failed. Dropping connection.");
-    return -1;
-  }
-
-  if(recognized) {
-    conn = relay_lookup_conn(circ, cell, cell_direction);
-    if(cell_direction == CELL_DIRECTION_OUT) {
-      ++stats_n_relay_cells_delivered;
-      log_fn(LOG_DEBUG,"Sending away from origin.");
-      if (connection_edge_process_relay_cell(cell, circ, conn, NULL) < 0) {
-        log_fn(LOG_WARN,"connection_edge_process_relay_cell (away from origin) failed.");
-        return -1;
-      }
-    }
-    if(cell_direction == CELL_DIRECTION_IN) {
-      ++stats_n_relay_cells_delivered;
-      log_fn(LOG_DEBUG,"Sending to origin.");
-      if (connection_edge_process_relay_cell(cell, circ, conn, layer_hint) < 0) {
-        log_fn(LOG_WARN,"connection_edge_process_relay_cell (at origin) failed.");
-        return -1;
-      }
-    }
-    return 0;
-  }
-
-  /* not recognized. pass it on. */
-  if(cell_direction == CELL_DIRECTION_OUT) {
-    cell->circ_id = circ->n_circ_id; /* switch it */
-    conn = circ->n_conn;
-  } else {
-    cell->circ_id = circ->p_circ_id; /* switch it */
-    conn = circ->p_conn;
-  }
-
-  if(!conn) {
-    if (circ->rend_splice && cell_direction == CELL_DIRECTION_OUT) {
-      tor_assert(circ->purpose == CIRCUIT_PURPOSE_REND_ESTABLISHED);
-      tor_assert(circ->rend_splice->purpose == CIRCUIT_PURPOSE_REND_ESTABLISHED);
-      cell->circ_id = circ->rend_splice->p_circ_id;
-      if (circuit_receive_relay_cell(cell, circ->rend_splice, CELL_DIRECTION_IN)<0) {
-        log_fn(LOG_WARN, "Error relaying cell across rendezvous; closing circuits");
-        circuit_mark_for_close(circ); /* XXXX Do this here, or just return -1? */
-        return -1;
-      }
-      return 0;
-    }
-    log_fn(LOG_WARN,"Didn't recognize cell, but circ stops here! Closing circ.");
-    return -1;
-  }
-
-  log_fn(LOG_DEBUG,"Passing on unrecognized cell.");
-  ++stats_n_relay_cells_relayed;
-  connection_or_write_cell_to_buf(cell, conn);
-  return 0;
-}
-
-/** Do the appropriate en/decryptions for <b>cell</b> arriving on
- * <b>circ</b> in direction <b>cell_direction</b>.
- *
- * If cell_direction == CELL_DIRECTION_IN:
- *   - If we're at the origin (we're the OP), for hops 1..N,
- *     decrypt cell. If recognized, stop.
- *   - Else (we're not the OP), encrypt one hop. Cell is not recognized.
- *
- * If cell_direction == CELL_DIRECTION_OUT:
- *   - decrypt one hop. Check if recognized.
- *
- * If cell is recognized, set *recognized to 1, and set
- * *layer_hint to the hop that recognized it.
- *
- * Return -1 to indicate that we should mark the circuit for close,
- * else return 0.
- */
-/* wrap this into receive_relay_cell one day */
-static int relay_crypt(circuit_t *circ, cell_t *cell, int cell_direction,
-                       crypt_path_t **layer_hint, char *recognized) {
-  crypt_path_t *thishop;
-  relay_header_t rh;
-
-  tor_assert(circ && cell && recognized);
-  tor_assert(cell_direction == CELL_DIRECTION_IN || cell_direction == CELL_DIRECTION_OUT);
-
-  if(cell_direction == CELL_DIRECTION_IN) {
-    if(CIRCUIT_IS_ORIGIN(circ)) { /* We're at the beginning of the circuit.
-                                     We'll want to do layered decrypts. */
-      tor_assert(circ->cpath);
-      thishop = circ->cpath;
-      if(thishop->state != CPATH_STATE_OPEN) {
-        log_fn(LOG_WARN,"Relay cell before first created cell? Closing.");
-        return -1;
-      }
-      do { /* Remember: cpath is in forward order, that is, first hop first. */
-        tor_assert(thishop);
-
-        if(relay_crypt_one_payload(thishop->b_crypto, cell->payload, 0) < 0)
-          return -1;
-
-        relay_header_unpack(&rh, cell->payload);
-        if(rh.recognized == 0) {
-          /* it's possibly recognized. have to check digest to be sure. */
-          if(relay_digest_matches(thishop->b_digest, cell)) {
-            *recognized = 1;
-            *layer_hint = thishop;
-            return 0;
-          }
-        }
-
-        thishop = thishop->next;
-      } while(thishop != circ->cpath && thishop->state == CPATH_STATE_OPEN);
-      log_fn(LOG_WARN,"in-cell at OP not recognized. Closing.");
-      return -1;
-    } else { /* we're in the middle. Just one crypt. */
-      if(relay_crypt_one_payload(circ->p_crypto, cell->payload, 1) < 0)
-        return -1;
-//      log_fn(LOG_DEBUG,"Skipping recognized check, because we're not the OP.");
-    }
-  } else /* cell_direction == CELL_DIRECTION_OUT */ {
-    /* we're in the middle. Just one crypt. */
-
-    if(relay_crypt_one_payload(circ->n_crypto, cell->payload, 0) < 0)
-      return -1;
-
-    relay_header_unpack(&rh, cell->payload);
-    if (rh.recognized == 0) {
-      /* it's possibly recognized. have to check digest to be sure. */
-      if(relay_digest_matches(circ->n_digest, cell)) {
-        *recognized = 1;
-        return 0;
-      }
-    }
-  }
-  return 0;
-}
-
-/** Package a relay cell:
- *  - Encrypt it to the right layer
- *  - connection_or_write_cell_to_buf to the right conn
- */
-int
-circuit_package_relay_cell(cell_t *cell, circuit_t *circ,
-                           int cell_direction,
-                           crypt_path_t *layer_hint)
-{
-  connection_t *conn; /* where to send the cell */
-  crypt_path_t *thishop; /* counter for repeated crypts */
-
-  if(cell_direction == CELL_DIRECTION_OUT) {
-    conn = circ->n_conn;
-    if(!conn) {
-      log_fn(LOG_WARN,"outgoing relay cell has n_conn==NULL. Dropping.");
-      return 0; /* just drop it */
-    }
-    relay_set_digest(layer_hint->f_digest, cell);
-
-    thishop = layer_hint;
-    /* moving from farthest to nearest hop */
-    do {
-      tor_assert(thishop);
-
-      log_fn(LOG_DEBUG,"crypting a layer of the relay cell.");
-      if(relay_crypt_one_payload(thishop->f_crypto, cell->payload, 1) < 0) {
-        return -1;
-      }
-
-      thishop = thishop->prev;
-    } while (thishop != circ->cpath->prev);
-
-  } else { /* incoming cell */
-    conn = circ->p_conn;
-    if(!conn) {
-      log_fn(LOG_WARN,"incoming relay cell has p_conn==NULL. Dropping.");
-      return 0; /* just drop it */
-    }
-    relay_set_digest(circ->p_digest, cell);
-    if(relay_crypt_one_payload(circ->p_crypto, cell->payload, 1) < 0)
-      return -1;
-  }
-  ++stats_n_relay_cells_relayed;
-  connection_or_write_cell_to_buf(cell, conn);
-  return 0;
-}
-
-/** If cell's stream_id matches the stream_id of any conn that's
- * attached to circ, return that conn, else return NULL.
- */
-static connection_t *
-relay_lookup_conn(circuit_t *circ, cell_t *cell, int cell_direction)
-{
-  connection_t *tmpconn;
-  relay_header_t rh;
-
-  relay_header_unpack(&rh, cell->payload);
-
-  if(!rh.stream_id)
-    return NULL;
-
-  /* IN or OUT cells could have come from either direction, now
-   * that we allow rendezvous *to* an OP.
-   */
-
-  for(tmpconn = circ->n_streams; tmpconn; tmpconn=tmpconn->next_stream) {
-    if(rh.stream_id == tmpconn->stream_id) {
-      log_fn(LOG_DEBUG,"found conn for stream %d.", rh.stream_id);
-      if(cell_direction == CELL_DIRECTION_OUT ||
-         connection_edge_is_rendezvous_stream(tmpconn))
-        return tmpconn;
-    }
-  }
-  for(tmpconn = circ->p_streams; tmpconn; tmpconn=tmpconn->next_stream) {
-    if(rh.stream_id == tmpconn->stream_id) {
-      log_fn(LOG_DEBUG,"found conn for stream %d.", rh.stream_id);
-      return tmpconn;
-    }
-  }
-  for(tmpconn = circ->resolving_streams; tmpconn; tmpconn=tmpconn->next_stream) {
-    if(rh.stream_id == tmpconn->stream_id) {
-      log_fn(LOG_DEBUG,"found conn for stream %d.", rh.stream_id);
-      return tmpconn;
-    }
-  }
-  return NULL; /* probably a begin relay cell */
-}
-
 /** The circuit <b>circ</b> has received a circuit-level sendme
  * (on hop <b>layer_hint</b>, if we're the OP). Go through all the
  * attached streams and let them resume reading and packaging, if

Index: connection.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection.c,v
retrieving revision 1.219
retrieving revision 1.220
diff -u -d -r1.219 -r1.220
--- connection.c	12 May 2004 19:17:09 -0000	1.219
+++ connection.c	12 May 2004 19:49:48 -0000	1.220
@@ -852,11 +852,12 @@
     }
   }
 
-  if(!connection_wants_to_flush(conn)) /* it's done flushing */
-    if(connection_finished_flushing(conn) < 0) { /* ...and get handled here. */
+  if(!connection_wants_to_flush(conn)) { /* it's done flushing */
+    if(connection_finished_flushing(conn) < 0) {
       /* already marked */
       return -1;
     }
+  }
 
   return 0;
 }
@@ -1053,6 +1054,7 @@
   return 0;
 }
 
+/** Return 1 if conn is in 'connecting' state, else return 0. */
 int connection_state_is_connecting(connection_t *conn) {
   tor_assert(conn);
 

Index: directory.c
===================================================================
RCS file: /home/or/cvsroot/src/or/directory.c,v
retrieving revision 1.102
retrieving revision 1.103
diff -u -d -r1.102 -r1.103
--- directory.c	12 May 2004 19:17:09 -0000	1.102
+++ directory.c	12 May 2004 19:49:48 -0000	1.103
@@ -527,7 +527,6 @@
  * appropriate.
  */
 int connection_dir_finished_flushing(connection_t *conn) {
-  int e, len=sizeof(e);
 
   tor_assert(conn && conn->type == CONN_TYPE_DIR);
 

Index: or.h
===================================================================
RCS file: /home/or/cvsroot/src/or/or.h,v
retrieving revision 1.341
retrieving revision 1.342
diff -u -d -r1.341 -r1.342
--- or.h	12 May 2004 19:17:09 -0000	1.341
+++ or.h	12 May 2004 19:49:48 -0000	1.342
@@ -897,11 +897,6 @@
 int circuit_stream_is_being_handled(connection_t *conn);
 void circuit_build_needed_circs(time_t now);
 
-int circuit_receive_relay_cell(cell_t *cell, circuit_t *circ,
-                               int cell_direction);
-int circuit_package_relay_cell(cell_t *cell, circuit_t *circ,
-                               int cell_direction, crypt_path_t *layer_hint);
-
 void circuit_resume_edge_reading(circuit_t *circ, crypt_path_t *layer_hint);
 int circuit_consider_stop_edge_reading(circuit_t *circ, crypt_path_t *layer_hint);
 void circuit_consider_sending_sendme(circuit_t *circ, crypt_path_t *layer_hint);
@@ -928,9 +923,6 @@
 void assert_cpath_layer_ok(const crypt_path_t *c);
 void assert_circuit_ok(const circuit_t *c);
 
-extern unsigned long stats_n_relay_cells_relayed;
-extern unsigned long stats_n_relay_cells_delivered;
-
 /********************************* command.c ***************************/
 
 void command_process_cell(cell_t *cell, connection_t *conn);
@@ -1090,6 +1082,20 @@
 int connection_dir_finished_flushing(connection_t *conn);
 int connection_dir_finished_connecting(connection_t *conn);
 
+/********************************* dirserv.c ***************************/
+int dirserv_add_own_fingerprint(const char *nickname, crypto_pk_env_t *pk);
+int dirserv_parse_fingerprint_file(const char *fname);
+int dirserv_router_fingerprint_is_known(const routerinfo_t *router);
+void dirserv_free_fingerprint_list();
+int dirserv_add_descriptor(const char **desc);
+int dirserv_init_from_directory_string(const char *dir);
+void dirserv_free_descriptors();
+int dirserv_dump_directory_to_string(char *s, unsigned int maxlen,
+                                     crypto_pk_env_t *private_key);
+void directory_set_dirty(void);
+size_t dirserv_get_directory(const char **cp);
+void dirserv_remove_old_servers(void);
+
 /********************************* dns.c ***************************/
 
 void dns_init(void);
@@ -1155,82 +1161,15 @@
 cpath_build_state_t *onion_new_cpath_build_state(uint8_t purpose,
                                                  const char *exit_nickname);
 
-/********************************* router.c ***************************/
-
-void set_onion_key(crypto_pk_env_t *k);
-crypto_pk_env_t *get_onion_key(void);
-crypto_pk_env_t *get_previous_onion_key(void);
-time_t get_onion_key_set_at(void);
-void set_identity_key(crypto_pk_env_t *k);
-crypto_pk_env_t *get_identity_key(void);
-int init_keys(void);
-crypto_pk_env_t *init_key_from_file(const char *fname);
-void rotate_onion_key(void);
-
-void router_retry_connections(void);
-void router_upload_dir_desc_to_dirservers(void);
-void router_post_to_dirservers(uint8_t purpose, const char *payload, int payload_len);
-int router_compare_to_my_exit_policy(connection_t *conn);
-routerinfo_t *router_get_my_routerinfo(void);
-const char *router_get_my_descriptor(void);
-int router_is_me(routerinfo_t *router);
-int router_rebuild_descriptor(void);
-int router_dump_router_to_string(char *s, int maxlen, routerinfo_t *router,
-                                 crypto_pk_env_t *ident_key);
-
-/********************************* routerlist.c ***************************/
-
-routerinfo_t *router_pick_directory_server(void);
-struct smartlist_t;
-routerinfo_t *router_choose_random_node(routerlist_t *dir,
-                                        char *preferred, char *excluded,
-                                        struct smartlist_t *excludedsmartlist);
-routerinfo_t *router_get_by_addr_port(uint32_t addr, uint16_t port);
-routerinfo_t *router_get_by_nickname(char *nickname);
-void router_get_routerlist(routerlist_t **prouterlist);
-void routerlist_free(routerlist_t *routerlist);
-void routerinfo_free(routerinfo_t *router);
-routerinfo_t *routerinfo_copy(const routerinfo_t *router);
-void router_mark_as_down(char *nickname);
-int router_set_routerlist_from_file(char *routerfile);
-int router_set_routerlist_from_string(const char *s);
-int router_set_routerlist_from_directory(const char *s, crypto_pk_env_t *pkey);
-int router_compare_addr_to_exit_policy(uint32_t addr, uint16_t port,
-                                       struct exit_policy_t *policy);
-#define ADDR_POLICY_ACCEPTED 0
-#define ADDR_POLICY_REJECTED -1
-#define ADDR_POLICY_UNKNOWN 1
-int router_exit_policy_all_routers_reject(uint32_t addr, uint16_t port);
-int router_exit_policy_rejects_all(routerinfo_t *router);
-
-/********************************* routerparse.c ************************/
-
-int router_get_router_hash(const char *s, char *digest);
-int router_get_dir_hash(const char *s, char *digest);
-int router_parse_list_from_string(const char **s,
-                                       routerlist_t **dest,
-                                       int n_good_nicknames,
-                                       const char **good_nickname_lst);
-int router_parse_routerlist_from_directory(const char *s,
-                                           routerlist_t **dest,
-                                           crypto_pk_env_t *pkey);
-routerinfo_t *router_parse_entry_from_string(const char *s, const char *end);
-int router_add_exit_policy_from_string(routerinfo_t *router, const char *s);
+/********************************* relay.c ***************************/
 
-/********************************* dirserv.c ***************************/
-int dirserv_add_own_fingerprint(const char *nickname, crypto_pk_env_t *pk);
-int dirserv_parse_fingerprint_file(const char *fname);
-int dirserv_router_fingerprint_is_known(const routerinfo_t *router);
-void dirserv_free_fingerprint_list();
-int dirserv_add_descriptor(const char **desc);
-int dirserv_init_from_directory_string(const char *dir);
-void dirserv_free_descriptors();
-int dirserv_dump_directory_to_string(char *s, unsigned int maxlen,
-                                     crypto_pk_env_t *private_key);
-void directory_set_dirty(void);
-size_t dirserv_get_directory(const char **cp);
-void dirserv_remove_old_servers(void);
+extern unsigned long stats_n_relay_cells_relayed;
+extern unsigned long stats_n_relay_cells_delivered;
 
+int circuit_receive_relay_cell(cell_t *cell, circuit_t *circ,
+                               int cell_direction);
+int circuit_package_relay_cell(cell_t *cell, circuit_t *circ,
+                               int cell_direction, crypt_path_t *layer_hint);
 
 /********************************* rephist.c ***************************/
 
@@ -1318,6 +1257,68 @@
 int rend_mid_establish_rendezvous(circuit_t *circ, const char *request, int request_len);
 int rend_mid_rendezvous(circuit_t *circ, const char *request, int request_len);
 
+/********************************* router.c ***************************/
+
+void set_onion_key(crypto_pk_env_t *k);
+crypto_pk_env_t *get_onion_key(void);
+crypto_pk_env_t *get_previous_onion_key(void);
+time_t get_onion_key_set_at(void);
+void set_identity_key(crypto_pk_env_t *k);
+crypto_pk_env_t *get_identity_key(void);
+int init_keys(void);
+crypto_pk_env_t *init_key_from_file(const char *fname);
+void rotate_onion_key(void);
+
+void router_retry_connections(void);
+void router_upload_dir_desc_to_dirservers(void);
+void router_post_to_dirservers(uint8_t purpose, const char *payload, int payload_len);
+int router_compare_to_my_exit_policy(connection_t *conn);
+routerinfo_t *router_get_my_routerinfo(void);
+const char *router_get_my_descriptor(void);
+int router_is_me(routerinfo_t *router);
+int router_rebuild_descriptor(void);
+int router_dump_router_to_string(char *s, int maxlen, routerinfo_t *router,
+                                 crypto_pk_env_t *ident_key);
+
+/********************************* routerlist.c ***************************/
+
+routerinfo_t *router_pick_directory_server(void);
+struct smartlist_t;
+routerinfo_t *router_choose_random_node(routerlist_t *dir,
+                                        char *preferred, char *excluded,
+                                        struct smartlist_t *excludedsmartlist);
+routerinfo_t *router_get_by_addr_port(uint32_t addr, uint16_t port);
+routerinfo_t *router_get_by_nickname(char *nickname);
+void router_get_routerlist(routerlist_t **prouterlist);
+void routerlist_free(routerlist_t *routerlist);
+void routerinfo_free(routerinfo_t *router);
+routerinfo_t *routerinfo_copy(const routerinfo_t *router);
+void router_mark_as_down(char *nickname);
+int router_set_routerlist_from_file(char *routerfile);
+int router_set_routerlist_from_string(const char *s);
+int router_set_routerlist_from_directory(const char *s, crypto_pk_env_t *pkey);
+int router_compare_addr_to_exit_policy(uint32_t addr, uint16_t port,
+                                       struct exit_policy_t *policy);
+#define ADDR_POLICY_ACCEPTED 0
+#define ADDR_POLICY_REJECTED -1
+#define ADDR_POLICY_UNKNOWN 1
+int router_exit_policy_all_routers_reject(uint32_t addr, uint16_t port);
+int router_exit_policy_rejects_all(routerinfo_t *router);
+
+/********************************* routerparse.c ************************/
+
+int router_get_router_hash(const char *s, char *digest);
+int router_get_dir_hash(const char *s, char *digest);
+int router_parse_list_from_string(const char **s,
+                                       routerlist_t **dest,
+                                       int n_good_nicknames,
+                                       const char **good_nickname_lst);
+int router_parse_routerlist_from_directory(const char *s,
+                                           routerlist_t **dest,
+                                           crypto_pk_env_t *pkey);
+routerinfo_t *router_parse_entry_from_string(const char *s, const char *end);
+int router_add_exit_policy_from_string(routerinfo_t *router, const char *s);
+
 #endif
 
 /*

Index: routerlist.c
===================================================================
RCS file: /home/or/cvsroot/src/or/routerlist.c,v
retrieving revision 1.74
retrieving revision 1.75
diff -u -d -r1.74 -r1.75
--- routerlist.c	10 May 2004 17:30:51 -0000	1.74
+++ routerlist.c	12 May 2004 19:49:48 -0000	1.75
@@ -211,6 +211,7 @@
   int i;
   routerinfo_t *router;
 
+  tor_assert(nickname);
   tor_assert(routerlist);
 
   for(i=0;i<smartlist_len(routerlist->routers);i++) {
@@ -290,7 +291,9 @@
 
 /** Mark the router named <b>nickname</b> as non-running in our routerlist. */
 void router_mark_as_down(char *nickname) {
-  routerinfo_t *router = router_get_by_nickname(nickname);
+  routerinfo_t *router;
+  tor_assert(nickname);
+  router = router_get_by_nickname(nickname);
   if(!router) /* we don't seem to know about him in the first place */
     return;
   log_fn(LOG_DEBUG,"Marking %s as down.",router->nickname);



More information about the tor-commits mailing list