|
@@ -533,6 +533,10 @@ relay_command_to_string(uint8_t command)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ * payload. */
|
|
|
+#define CELL_PADDING_GAP 4
|
|
|
+
|
|
|
|
|
|
* the relay payload length expected to be put in the cell. It can not be
|
|
|
* bigger than RELAY_PAYLOAD_SIZE else this function assert().
|
|
@@ -556,7 +560,7 @@ get_pad_cell_offset(size_t data_len)
|
|
|
|
|
|
|
|
|
* of zero indicating that no padding needs to be added. */
|
|
|
- size_t offset = RELAY_HEADER_SIZE + data_len + 4;
|
|
|
+ size_t offset = RELAY_HEADER_SIZE + data_len + CELL_PADDING_GAP;
|
|
|
if (offset >= CELL_PAYLOAD_SIZE) {
|
|
|
return 0;
|
|
|
}
|
|
@@ -2027,27 +2031,82 @@ uint64_t stats_n_data_cells_received = 0;
|
|
|
* ever received were completely full of data. */
|
|
|
uint64_t stats_n_data_bytes_received = 0;
|
|
|
|
|
|
+
|
|
|
+ * Called when initializing a circuit, or when we have reached the end of the
|
|
|
+ * window in which we need to send some randomness so that incoming sendme
|
|
|
+ * cells will be unpredictable. Resets the flags and picks a new window.
|
|
|
+ */
|
|
|
+void
|
|
|
+circuit_reset_sendme_randomness(circuit_t *circ)
|
|
|
+{
|
|
|
+ circ->have_sent_sufficiently_random_cell = 0;
|
|
|
+ circ->send_randomness_after_n_cells = CIRCWINDOW_INCREMENT / 2 +
|
|
|
+ crypto_fast_rng_get_uint(get_thread_fast_rng(), CIRCWINDOW_INCREMENT / 2);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+ * Any relay data payload containing fewer than this many real bytes is
|
|
|
+ * considered to have enough randomness to.
|
|
|
+ **/
|
|
|
+#define RELAY_PAYLOAD_LENGTH_FOR_RANDOM_SENDMES \
|
|
|
+ (RELAY_PAYLOAD_SIZE - CELL_PADDING_GAP - 16)
|
|
|
+
|
|
|
|
|
|
* Helper. Return the number of bytes that should be put into a cell from a
|
|
|
* given edge connection on which <b>n_available</b> bytes are available.
|
|
|
*/
|
|
|
static size_t
|
|
|
connection_edge_get_inbuf_bytes_to_package(size_t n_available,
|
|
|
- int package_partial)
|
|
|
+ int package_partial,
|
|
|
+ circuit_t *on_circuit)
|
|
|
{
|
|
|
if (!n_available)
|
|
|
return 0;
|
|
|
|
|
|
- size_t length = RELAY_PAYLOAD_SIZE;
|
|
|
+
|
|
|
+ const bool force_random_bytes =
|
|
|
+ (on_circuit->send_randomness_after_n_cells == 0) &&
|
|
|
+ (! on_circuit->have_sent_sufficiently_random_cell);
|
|
|
|
|
|
- if (n_available < length) {
|
|
|
+
|
|
|
+ size_t target_length;
|
|
|
+ if (force_random_bytes) {
|
|
|
+ target_length = RELAY_PAYLOAD_LENGTH_FOR_RANDOM_SENDMES;
|
|
|
+ } else {
|
|
|
+ target_length = RELAY_PAYLOAD_SIZE;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ size_t package_length;
|
|
|
+ if (n_available >= target_length) {
|
|
|
+ package_length = target_length;
|
|
|
+ } else {
|
|
|
if (package_partial)
|
|
|
- length = n_available;
|
|
|
+ package_length = n_available;
|
|
|
else
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
- return length;
|
|
|
+
|
|
|
+ tor_assert_nonfatal(package_length > 0);
|
|
|
+
|
|
|
+ if (package_length <= RELAY_PAYLOAD_LENGTH_FOR_RANDOM_SENDMES) {
|
|
|
+
|
|
|
+ * sendme cell unpredictable. */
|
|
|
+ on_circuit->have_sent_sufficiently_random_cell = 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (on_circuit->send_randomness_after_n_cells == 0) {
|
|
|
+
|
|
|
+ * ensure sendme unpredictability. */
|
|
|
+ tor_assert_nonfatal(on_circuit->have_sent_sufficiently_random_cell);
|
|
|
+
|
|
|
+ circuit_reset_sendme_randomness(on_circuit);
|
|
|
+ }
|
|
|
+
|
|
|
+ --on_circuit->send_randomness_after_n_cells;
|
|
|
+
|
|
|
+ return package_length;
|
|
|
}
|
|
|
|
|
|
|
|
@@ -2123,10 +2182,13 @@ connection_edge_package_raw_inbuf(edge_connection_t *conn, int package_partial,
|
|
|
}
|
|
|
|
|
|
length = connection_edge_get_inbuf_bytes_to_package(bytes_to_process,
|
|
|
- package_partial);
|
|
|
+ package_partial, circ);
|
|
|
if (!length)
|
|
|
return 0;
|
|
|
|
|
|
+
|
|
|
+ * a cell. */
|
|
|
+
|
|
|
stats_n_data_bytes_packaged += length;
|
|
|
stats_n_data_cells_packaged += 1;
|
|
|
|