mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-11 13:43:47 +01:00
prop289: Keep track of the last seen cell digests
This makes tor remember the last seen digest of a cell if that cell is the last one before a SENDME on the Exit side. Closes #26839 Signed-off-by: David Goulet <dgoulet@torproject.org>
This commit is contained in:
parent
81706d8427
commit
93f9fbbd34
@ -104,6 +104,12 @@ struct circuit_t {
|
|||||||
* circuit-level sendme cells to indicate that we're willing to accept
|
* circuit-level sendme cells to indicate that we're willing to accept
|
||||||
* more. */
|
* more. */
|
||||||
int deliver_window;
|
int deliver_window;
|
||||||
|
/** FIFO containing the digest of the cells that are just before a SENDME is
|
||||||
|
* sent by the client. It is done at the last cell before our package_window
|
||||||
|
* goes down to 0 which is when we expect a SENDME. The protocol doesn't
|
||||||
|
* allow more than 10 outstanding SENDMEs worth of data meaning this list
|
||||||
|
* should only contain at most 10 digests of 4 bytes each. */
|
||||||
|
smartlist_t *sendme_last_digests;
|
||||||
|
|
||||||
/** Temporary field used during circuits_handle_oom. */
|
/** Temporary field used during circuits_handle_oom. */
|
||||||
uint32_t age_tmp;
|
uint32_t age_tmp;
|
||||||
|
@ -1227,6 +1227,12 @@ circuit_free_(circuit_t *circ)
|
|||||||
* "active" checks will be violated. */
|
* "active" checks will be violated. */
|
||||||
cell_queue_clear(&circ->n_chan_cells);
|
cell_queue_clear(&circ->n_chan_cells);
|
||||||
|
|
||||||
|
/* Cleanup possible SENDME state. */
|
||||||
|
if (circ->sendme_last_digests) {
|
||||||
|
SMARTLIST_FOREACH(circ->sendme_last_digests, uint8_t *, d, tor_free(d));
|
||||||
|
smartlist_free(circ->sendme_last_digests);
|
||||||
|
}
|
||||||
|
|
||||||
log_info(LD_CIRC, "Circuit %u (id: %" PRIu32 ") has been freed.",
|
log_info(LD_CIRC, "Circuit %u (id: %" PRIu32 ") has been freed.",
|
||||||
n_circ_id,
|
n_circ_id,
|
||||||
CIRCUIT_IS_ORIGIN(circ) ?
|
CIRCUIT_IS_ORIGIN(circ) ?
|
||||||
|
@ -639,6 +639,14 @@ relay_send_command_from_edge_,(streamid_t stream_id, circuit_t *circ,
|
|||||||
circuit_mark_for_close(circ, END_CIRC_REASON_INTERNAL);
|
circuit_mark_for_close(circ, END_CIRC_REASON_INTERNAL);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If applicable, note the cell digest for the SENDME version 1 purpose if
|
||||||
|
* we need to. This call needs to be after the circuit_package_relay_cell()
|
||||||
|
* because the cell digest is set within that function. */
|
||||||
|
if (relay_command == RELAY_COMMAND_DATA) {
|
||||||
|
sendme_note_cell_digest(circ);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include "app/config/config.h"
|
#include "app/config/config.h"
|
||||||
#include "core/mainloop/connection.h"
|
#include "core/mainloop/connection.h"
|
||||||
|
#include "core/or/cell_st.h"
|
||||||
#include "core/or/circuitlist.h"
|
#include "core/or/circuitlist.h"
|
||||||
#include "core/or/circuituse.h"
|
#include "core/or/circuituse.h"
|
||||||
#include "core/or/relay.h"
|
#include "core/or/relay.h"
|
||||||
@ -507,3 +508,31 @@ sendme_stream_data_packaged(edge_connection_t *conn)
|
|||||||
tor_assert(conn);
|
tor_assert(conn);
|
||||||
return --conn->package_window;
|
return --conn->package_window;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Note the cell digest in the circuit sendme last digests FIFO if applicable.
|
||||||
|
* It is safe to pass a circuit that isn't meant to track those digests. */
|
||||||
|
void
|
||||||
|
sendme_note_cell_digest(circuit_t *circ)
|
||||||
|
{
|
||||||
|
uint8_t *digest;
|
||||||
|
|
||||||
|
tor_assert(circ);
|
||||||
|
|
||||||
|
/* We only keep the cell digest if we are the Exit on that circuit and if
|
||||||
|
* this cell is the last one before the client should send a SENDME. */
|
||||||
|
if (CIRCUIT_IS_ORIGIN(circ)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* Is this the last cell before a SENDME? The idea is that if the
|
||||||
|
* package_window reaches a multiple of the increment, after this cell, we
|
||||||
|
* should expect a SENDME. */
|
||||||
|
if (((circ->package_window - 1) % CIRCWINDOW_INCREMENT) != 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
digest = tor_malloc_zero(4);
|
||||||
|
if (circ->sendme_last_digests == NULL) {
|
||||||
|
circ->sendme_last_digests = smartlist_new();
|
||||||
|
}
|
||||||
|
smartlist_add(circ->sendme_last_digests, digest);
|
||||||
|
}
|
||||||
|
@ -34,4 +34,7 @@ int sendme_circuit_data_received(circuit_t *circ, crypt_path_t *layer_hint);
|
|||||||
int sendme_circuit_data_packaged(circuit_t *circ, crypt_path_t *layer_hint);
|
int sendme_circuit_data_packaged(circuit_t *circ, crypt_path_t *layer_hint);
|
||||||
int sendme_stream_data_packaged(edge_connection_t *conn);
|
int sendme_stream_data_packaged(edge_connection_t *conn);
|
||||||
|
|
||||||
|
/* Track cell digest. */
|
||||||
|
void sendme_note_cell_digest(circuit_t *circ);
|
||||||
|
|
||||||
#endif /* !defined(TOR_SENDME_H) */
|
#endif /* !defined(TOR_SENDME_H) */
|
||||||
|
Loading…
Reference in New Issue
Block a user