if (relay_digest_matches(thishop->crypto.b_digest, cell)) {
*recognized = 1;
*layer_hint = thishop;
+ /* Keep current digest of this cell for the possible SENDME. */
+ if (thishop->crypto.sendme_digest) {
+ crypto_digest_free(thishop->crypto.sendme_digest);
+ }
+ thishop->crypto.sendme_digest =
+ crypto_digest_dup(thishop->crypto.b_digest);
+
return 0;
}
}
or_circuit_t *or_circ)
{
relay_set_digest(or_circ->crypto.b_digest, cell);
+ /* Keep a record of this cell, we might use it for validating the SENDME. */
+ if (or_circ->crypto.sendme_digest) {
+ crypto_digest_free(or_circ->crypto.sendme_digest);
+ }
+ or_circ->crypto.sendme_digest = crypto_digest_dup(or_circ->crypto.b_digest);
/* encrypt one layer */
relay_crypt_one_payload(or_circ->crypto.b_crypto, cell->payload);
}
crypto_cipher_free(crypto->b_crypto);
crypto_digest_free(crypto->f_digest);
crypto_digest_free(crypto->b_digest);
+ crypto_digest_free(crypto->sendme_digest);
}
/** Initialize <b>crypto</b> from the key material in key_data.
#include "core/or/cell_st.h"
#include "core/or/circuitlist.h"
#include "core/or/circuituse.h"
+#include "core/or/or_circuit_st.h"
#include "core/or/relay.h"
#include "core/or/sendme.h"
#include "feature/nodelist/networkstatus.h"
* more.
*/
void
-sendme_circuit_consider_sending(circuit_t *circ, crypt_path_t *layer_hint,
- crypto_digest_t *digest)
+sendme_circuit_consider_sending(circuit_t *circ, crypt_path_t *layer_hint)
{
- tor_assert(digest);
+ crypto_digest_t *digest;
while ((layer_hint ? layer_hint->deliver_window : circ->deliver_window) <=
CIRCWINDOW_START - CIRCWINDOW_INCREMENT) {
log_debug(LD_CIRC,"Queuing circuit sendme.");
- if (layer_hint)
+ if (layer_hint) {
layer_hint->deliver_window += CIRCWINDOW_INCREMENT;
- else
+ digest = layer_hint->crypto.sendme_digest;
+ } else {
circ->deliver_window += CIRCWINDOW_INCREMENT;
+ digest = TO_OR_CIRCUIT(circ)->crypto.sendme_digest;
+ }
if (send_circuit_level_sendme(circ, layer_hint, digest) < 0) {
return; /* The circuit's closed, don't continue */
}
return;
}
- digest = tor_malloc_zero(4);
- if (circ->sendme_last_digests == NULL) {
- circ->sendme_last_digests = smartlist_new();
+ /* Only note the digest if we actually have the digest of the previous cell
+ * recorded. It should never happen in theory as we always record the last
+ * digest for the v1 SENDME. */
+ if (TO_OR_CIRCUIT(circ)->crypto.sendme_digest) {
+ digest = tor_malloc_zero(4);
+ crypto_digest_get_digest(TO_OR_CIRCUIT(circ)->crypto.sendme_digest,
+ (char *) digest, 4);
+ if (circ->sendme_last_digests == NULL) {
+ circ->sendme_last_digests = smartlist_new();
+ }
+ smartlist_add(circ->sendme_last_digests, digest);
}
- smartlist_add(circ->sendme_last_digests, digest);
}
/* Sending SENDME cell. */
void sendme_connection_edge_consider_sending(edge_connection_t *edge_conn);
void sendme_circuit_consider_sending(circuit_t *circ,
- crypt_path_t *layer_hint,
- crypto_digest_t *digest);
+ crypt_path_t *layer_hint);
/* Processing SENDME cell. */
int sendme_process_circuit_level(crypt_path_t *layer_hint,