sendme.c 23.8 KB
Newer Older
1
2
3
4
5
6
7
8
9
/* Copyright (c) 2019, The Tor Project, Inc. */
/* See LICENSE for licensing information */

/**
 * \file sendme.c
 * \brief Code that is related to SENDME cells both in terms of
 *        creating/parsing cells and handling the content.
 */

10
11
#define SENDME_PRIVATE

12
13
#include "core/or/or.h"

14
#include "app/config/config.h"
15
#include "core/crypto/relay_crypto.h"
16
#include "core/mainloop/connection.h"
17
#include "core/or/cell_st.h"
18
#include "core/or/crypt_path.h"
19
#include "core/or/circuitlist.h"
20
#include "core/or/circuituse.h"
21
#include "core/or/or_circuit_st.h"
22
23
#include "core/or/relay.h"
#include "core/or/sendme.h"
24
#include "feature/nodelist/networkstatus.h"
25
#include "lib/ctime/di_ops.h"
26
#include "trunnel/sendme_cell.h"
27
28
29

/* Return the minimum version given by the consensus (if any) that should be
 * used when emitting a SENDME cell. */
30
STATIC int
31
32
33
34
35
36
37
38
39
40
get_emit_min_version(void)
{
  return networkstatus_get_param(NULL, "sendme_emit_min_version",
                                 SENDME_EMIT_MIN_VERSION_DEFAULT,
                                 SENDME_EMIT_MIN_VERSION_MIN,
                                 SENDME_EMIT_MIN_VERSION_MAX);
}

/* Return the minimum version given by the consensus (if any) that should be
 * accepted when receiving a SENDME cell. */
41
STATIC int
42
43
44
45
46
47
48
get_accept_min_version(void)
{
  return networkstatus_get_param(NULL, "sendme_accept_min_version",
                                 SENDME_ACCEPT_MIN_VERSION_DEFAULT,
                                 SENDME_ACCEPT_MIN_VERSION_MIN,
                                 SENDME_ACCEPT_MIN_VERSION_MAX);
}
49

50
51
52
53
54
55
56
/* Pop the first cell digset on the given circuit from the SENDME last digests
 * list. NULL is returned if the list is uninitialized or empty.
 *
 * The caller gets ownership of the returned digest thus is responsible for
 * freeing the memory. */
static uint8_t *
pop_first_cell_digest(const circuit_t *circ)
57
{
58
  uint8_t *circ_digest;
59

60
  tor_assert(circ);
61

62
63
  if (circ->sendme_last_digests == NULL ||
      smartlist_len(circ->sendme_last_digests) == 0) {
64
    return NULL;
65
66
  }

67
68
69
70
71
72
73
  /* More cell digest than the SENDME window is never suppose to happen. The
   * cell should have been rejected before reaching this point due to its
   * package_window down to 0 leading to a circuit close. Scream loudly but
   * still pop the element so we don't memory leak. */
  tor_assert_nonfatal(smartlist_len(circ->sendme_last_digests) <=
                      CIRCWINDOW_START_MAX / CIRCWINDOW_INCREMENT);

74
75
  circ_digest = smartlist_get(circ->sendme_last_digests, 0);
  smartlist_del_keeporder(circ->sendme_last_digests, 0);
76
77
78
79
80
81
82
83
84
85
  return circ_digest;
}

/* Return true iff the given cell digest matches the first digest in the
 * circuit sendme list. */
static bool
v1_digest_matches(const uint8_t *circ_digest, const uint8_t *cell_digest)
{
  tor_assert(circ_digest);
  tor_assert(cell_digest);
86
87
88
89
90
91

  /* Compare the digest with the one in the SENDME. This cell is invalid
   * without a perfect match. */
  if (tor_memneq(circ_digest, cell_digest, TRUNNEL_SENDME_V1_DIGEST_LEN)) {
    log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
           "SENDME v1 cell digest do not match.");
92
    return false;
93
  }
94

95
96
  /* Digests matches! */
  return true;
97
98
99
100
101
102
103
104
105
}

/* Return true iff the given decoded SENDME version 1 cell is valid and
 * matches the expected digest on the circuit.
 *
 * Validation is done by comparing the digest in the cell from the previous
 * cell we saw which tells us that the other side has in fact seen that cell.
 * See proposal 289 for more details. */
static bool
106
cell_v1_is_valid(const sendme_cell_t *cell, const uint8_t *circ_digest)
107
108
{
  tor_assert(cell);
109
  tor_assert(circ_digest);
110

111
  const uint8_t *cell_digest = sendme_cell_getconstarray_data_v1_digest(cell);
112
  return v1_digest_matches(circ_digest, cell_digest);
113
114
115
116
}

/* Return true iff the given cell version can be handled or if the minimum
 * accepted version from the consensus is known to us. */
117
STATIC bool
118
cell_version_can_be_handled(uint8_t cell_version)
119
120
121
{
  int accept_version = get_accept_min_version();

122
123
124
  /* We will first check if the consensus minimum accepted version can be
   * handled by us and if not, regardless of the cell version we got, we can't
   * continue. */
125
126
  if (accept_version > SENDME_MAX_SUPPORTED_VERSION) {
    log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
127
           "Unable to accept SENDME version %u (from consensus). "
128
129
           "We only support <= %u. Probably your tor is too old?",
           accept_version, SENDME_MAX_SUPPORTED_VERSION);
130
131
132
    goto invalid;
  }

133
134
  /* Then, is this version below the accepted version from the consensus? If
   * yes, we must not handle it. */
135
  if (cell_version < accept_version) {
136
    log_info(LD_PROTOCOL, "Unacceptable SENDME version %u. Only "
137
                          "accepting %u (from consensus). Closing circuit.",
138
139
140
141
             cell_version, accept_version);
    goto invalid;
  }

142
143
144
145
146
147
148
149
150
  /* Is this cell version supported by us? */
  if (cell_version > SENDME_MAX_SUPPORTED_VERSION) {
    log_info(LD_PROTOCOL, "SENDME cell version %u is not supported by us. "
                          "We only support <= %u",
             cell_version, SENDME_MAX_SUPPORTED_VERSION);
    goto invalid;
  }

  return true;
151
 invalid:
152
  return false;
153
154
155
156
157
158
159
160
161
162
}

/* Return true iff the encoded SENDME cell in cell_payload of length
 * cell_payload_len is valid. For each version:
 *
 *  0: No validation
 *  1: Authenticated with last cell digest.
 *
 * This is the main critical function to make sure we can continue to
 * send/recv cells on a circuit. If the SENDME is invalid, the circuit should
163
 * be marked for close by the caller. */
164
STATIC bool
165
166
sendme_is_valid(const circuit_t *circ, const uint8_t *cell_payload,
                size_t cell_payload_len)
167
168
{
  uint8_t cell_version;
169
  uint8_t *circ_digest = NULL;
170
171
  sendme_cell_t *cell = NULL;

172
  tor_assert(circ);
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
  tor_assert(cell_payload);

  /* An empty payload means version 0 so skip trunnel parsing. We won't be
   * able to parse a 0 length buffer into a valid SENDME cell. */
  if (cell_payload_len == 0) {
    cell_version = 0;
  } else {
    /* First we'll decode the cell so we can get the version. */
    if (sendme_cell_parse(&cell, cell_payload, cell_payload_len) < 0) {
      log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
             "Unparseable SENDME cell received. Closing circuit.");
      goto invalid;
    }
    cell_version = sendme_cell_get_version(cell);
  }

  /* Validate that we can handle this cell version. */
190
  if (!cell_version_can_be_handled(cell_version)) {
191
192
193
    goto invalid;
  }

194
195
196
197
198
199
200
201
202
203
204
  /* Pop the first element that was added (FIFO). We do that regardless of the
   * version so we don't accumulate on the circuit if v0 is used by the other
   * end point. */
  circ_digest = pop_first_cell_digest(circ);
  if (circ_digest == NULL) {
    /* We shouldn't have received a SENDME if we have no digests. Log at
     * protocol warning because it can be tricked by sending many SENDMEs
     * without prior data cell. */
    log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
           "We received a SENDME but we have no cell digests to match. "
           "Closing circuit.");
205
206
207
208
209
210
    goto invalid;
  }

  /* Validate depending on the version now. */
  switch (cell_version) {
  case 0x01:
211
    if (!cell_v1_is_valid(cell, circ_digest)) {
212
213
214
215
      goto invalid;
    }
    break;
  case 0x00:
216
217
218
    /* Version 0, there is no work to be done on the payload so it is
     * necessarily valid if we pass the version validation. */
    break;
219
  default:
220
221
222
    log_warn(LD_PROTOCOL, "Unknown SENDME cell version %d received.",
             cell_version);
    tor_assert_nonfatal_unreached();
223
224
225
226
227
    break;
  }

  /* Valid cell. */
  sendme_cell_free(cell);
228
  tor_free(circ_digest);
229
  return true;
230
231
 invalid:
  sendme_cell_free(cell);
232
  tor_free(circ_digest);
233
  return false;
234
}
235
236
237
238
239
240

/* Build and encode a version 1 SENDME cell into payload, which must be at
 * least of RELAY_PAYLOAD_SIZE bytes, using the digest for the cell data.
 *
 * Return the size in bytes of the encoded cell in payload. A negative value
 * is returned on encoding failure. */
241
STATIC ssize_t
242
build_cell_payload_v1(const uint8_t *cell_digest, uint8_t *payload)
243
244
245
246
247
248
249
250
251
252
253
{
  ssize_t len = -1;
  sendme_cell_t *cell = NULL;

  tor_assert(cell_digest);
  tor_assert(payload);

  cell = sendme_cell_new();

  /* Building a payload for version 1. */
  sendme_cell_set_version(cell, 0x01);
254
255
  /* Set the data length field for v1. */
  sendme_cell_set_data_len(cell, TRUNNEL_SENDME_V1_DIGEST_LEN);
256
257

  /* Copy the digest into the data payload. */
258
259
  memcpy(sendme_cell_getarray_data_v1_digest(cell), cell_digest,
         sendme_cell_get_data_len(cell));
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274

  /* Finally, encode the cell into the payload. */
  len = sendme_cell_encode(payload, RELAY_PAYLOAD_SIZE, cell);

  sendme_cell_free(cell);
  return len;
}

/* Send a circuit-level SENDME on the given circuit using the layer_hint if
 * not NULL. The digest is only used for version 1.
 *
 * Return 0 on success else a negative value and the circuit will be closed
 * because we failed to send the cell on it. */
static int
send_circuit_level_sendme(circuit_t *circ, crypt_path_t *layer_hint,
275
                          const uint8_t *cell_digest)
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
{
  uint8_t emit_version;
  uint8_t payload[RELAY_PAYLOAD_SIZE];
  ssize_t payload_len;

  tor_assert(circ);
  tor_assert(cell_digest);

  emit_version = get_emit_min_version();
  switch (emit_version) {
  case 0x01:
    payload_len = build_cell_payload_v1(cell_digest, payload);
    if (BUG(payload_len < 0)) {
      /* Unable to encode the cell, abort. We can recover from this by closing
       * the circuit but in theory it should never happen. */
      return -1;
    }
    log_debug(LD_PROTOCOL, "Emitting SENDME version 1 cell.");
    break;
  case 0x00:
296
    FALLTHROUGH;
297
298
299
  default:
    /* Unknown version, fallback to version 0 meaning no payload. */
    payload_len = 0;
300
301
    log_debug(LD_PROTOCOL, "Emitting SENDME version 0 cell. "
                           "Consensus emit version is %d", emit_version);
302
303
304
305
306
307
308
309
310
311
312
313
    break;
  }

  if (relay_send_command_from_edge(0, circ, RELAY_COMMAND_SENDME,
                                   (char *) payload, payload_len,
                                   layer_hint) < 0) {
    log_warn(LD_CIRC,
             "SENDME relay_send_command_from_edge failed. Circuit's closed.");
    return -1; /* the circuit's closed, don't continue */
  }
  return 0;
}
314

315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
/* Record the cell digest only if the next cell is expected to be a SENDME. */
static void
record_cell_digest_on_circ(circuit_t *circ, const uint8_t *sendme_digest)
{
  tor_assert(circ);
  tor_assert(sendme_digest);

  /* Add the digest to the last seen list in the circuit. */
  if (circ->sendme_last_digests == NULL) {
    circ->sendme_last_digests = smartlist_new();
  }
  smartlist_add(circ->sendme_last_digests,
                tor_memdup(sendme_digest, DIGEST_LEN));
}

330
331
332
333
334
335
336
337
338
339
/*
 * Public API
 */

/** Return true iff the next cell for the given cell window is expected to be
 * a SENDME.
 *
 * We are able to know that because the package or deliver window value minus
 * one cell (the possible SENDME cell) should be a multiple of the increment
 * window value. */
340
341
static bool
circuit_sendme_cell_is_next(int window)
342
{
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
  /* At the start of the window, no SENDME will be expected. */
  if (window == CIRCWINDOW_START) {
    return false;
  }

  /* Are we at the limit of the increment and if not, we don't expect next
   * cell is a SENDME.
   *
   * We test against the window minus 1 because when we are looking if the
   * next cell is a SENDME, the window (either package or deliver) hasn't been
   * decremented just yet so when this is called, we are currently processing
   * the "window - 1" cell.
   *
   * This function is used when recording a cell digest and this is done quite
   * low in the stack when decrypting or encrypting a cell. The window is only
   * updated once the cell is actually put in the outbuf. */
359
360
361
  if (((window - 1) % CIRCWINDOW_INCREMENT) != 0) {
    return false;
  }
362

363
364
365
366
  /* Next cell is expected to be a SENDME. */
  return true;
}

367
368
369
/** Called when we've just received a relay data cell, when we've just
 * finished flushing all bytes to stream <b>conn</b>, or when we've flushed
 * *some* bytes to the stream <b>conn</b>.
370
 *
371
372
 * If conn->outbuf is not too full, and our deliver window is low, send back a
 * suitable number of stream-level sendme cells.
373
374
375
376
 */
void
sendme_connection_edge_consider_sending(edge_connection_t *conn)
{
377
  tor_assert(conn);
378

379
  int log_domain = TO_CONN(conn)->type == CONN_TYPE_AP ? LD_APP : LD_EXIT;
380

381
382
383
  /* Don't send it if we still have data to deliver. */
  if (connection_outbuf_too_full(TO_CONN(conn))) {
    goto end;
384
385
  }

386
387
388
389
390
391
392
393
394
395
396
397
  if (circuit_get_by_edge_conn(conn) == NULL) {
    /* This can legitimately happen if the destroy has already arrived and
     * torn down the circuit. */
    log_info(log_domain, "No circuit associated with edge connection. "
                         "Skipping sending SENDME.");
    goto end;
  }

  while (conn->deliver_window <=
         (STREAMWINDOW_START - STREAMWINDOW_INCREMENT)) {
    log_debug(log_domain, "Outbuf %" TOR_PRIuSZ ", queuing stream SENDME.",
              TO_CONN(conn)->outbuf_flushlen);
398
399
400
    conn->deliver_window += STREAMWINDOW_INCREMENT;
    if (connection_edge_send_command(conn, RELAY_COMMAND_SENDME,
                                     NULL, 0) < 0) {
401
402
403
      log_warn(LD_BUG, "connection_edge_send_command failed while sending "
                       "a SENDME. Circuit probably closed, skipping.");
      goto end; /* The circuit's closed, don't continue */
404
405
    }
  }
406
407
408

 end:
  return;
409
410
411
412
413
414
415
416
417
}

/** Check if the deliver_window for circuit <b>circ</b> (at hop
 * <b>layer_hint</b> if it's defined) is low enough that we should
 * send a circuit-level sendme back down the circuit. If so, send
 * enough sendmes that the window would be overfull if we sent any
 * more.
 */
void
418
sendme_circuit_consider_sending(circuit_t *circ, crypt_path_t *layer_hint)
419
{
420
  bool sent_one_sendme = false;
421
  const uint8_t *digest;
422

423
424
425
  while ((layer_hint ? layer_hint->deliver_window : circ->deliver_window) <=
          CIRCWINDOW_START - CIRCWINDOW_INCREMENT) {
    log_debug(LD_CIRC,"Queuing circuit sendme.");
426
    if (layer_hint) {
427
      layer_hint->deliver_window += CIRCWINDOW_INCREMENT;
428
      digest = cpath_get_sendme_digest(layer_hint);
429
    } else {
430
      circ->deliver_window += CIRCWINDOW_INCREMENT;
431
      digest = relay_crypto_get_sendme_digest(&TO_OR_CIRCUIT(circ)->crypto);
432
    }
433
434
    if (send_circuit_level_sendme(circ, layer_hint, digest) < 0) {
      return; /* The circuit's closed, don't continue */
435
    }
436
437
438
439
440
441
    /* Current implementation is not suppose to send multiple SENDME at once
     * because this means we would use the same relay crypto digest for each
     * SENDME leading to a mismatch on the other side and the circuit to
     * collapse. Scream loudly if it ever happens so we can address it. */
    tor_assert_nonfatal(!sent_one_sendme);
    sent_one_sendme = true;
442
443
  }
}
444
445
446
447

/* Process a circuit-level SENDME cell that we just received. The layer_hint,
 * if not NULL, is the Exit hop of the connection which means that we are a
 * client. In that case, circ must be an origin circuit. The cell_body_len is
448
449
 * the length of the SENDME cell payload (excluding the header). The
 * cell_payload is the payload.
450
 *
451
452
 * Return 0 on success (the SENDME is valid and the package window has
 * been updated properly).
453
 *
454
455
 * On error, a negative value is returned, which indicates that the
 * circuit must be closed using the value as the reason for it. */
456
457
int
sendme_process_circuit_level(crypt_path_t *layer_hint,
458
459
                             circuit_t *circ, const uint8_t *cell_payload,
                             uint16_t cell_payload_len)
460
461
{
  tor_assert(circ);
462
  tor_assert(cell_payload);
463

464
465
466
467
468
469
  /* Validate the SENDME cell. Depending on the version, different validation
   * can be done. An invalid SENDME requires us to close the circuit. */
  if (!sendme_is_valid(circ, cell_payload, cell_payload_len)) {
    return -END_CIRC_REASON_TORPROTOCOL;
  }

470
471
472
  /* If we are the origin of the circuit, we are the Client so we use the
   * layer hint (the Exit hop) for the package window tracking. */
  if (CIRCUIT_IS_ORIGIN(circ)) {
473
474
475
476
477
    /* If we are the origin of the circuit, it is impossible to not have a
     * cpath. Just in case, bug on it and close the circuit. */
    if (BUG(layer_hint == NULL)) {
      return -END_CIRC_REASON_TORPROTOCOL;
    }
478
479
480
481
482
483
484
485
486
487
488
489
490
491
    if ((layer_hint->package_window + CIRCWINDOW_INCREMENT) >
        CIRCWINDOW_START_MAX) {
      static struct ratelim_t exit_warn_ratelim = RATELIM_INIT(600);
      log_fn_ratelim(&exit_warn_ratelim, LOG_WARN, LD_PROTOCOL,
                     "Unexpected sendme cell from exit relay. "
                     "Closing circ.");
      return -END_CIRC_REASON_TORPROTOCOL;
    }
    layer_hint->package_window += CIRCWINDOW_INCREMENT;
    log_debug(LD_APP, "circ-level sendme at origin, packagewindow %d.",
              layer_hint->package_window);

    /* We count circuit-level sendme's as valid delivered data because they
     * are rate limited. */
492
    circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), cell_payload_len);
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
  } else {
    /* We aren't the origin of this circuit so we are the Exit and thus we
     * track the package window with the circuit object. */
    if ((circ->package_window + CIRCWINDOW_INCREMENT) >
        CIRCWINDOW_START_MAX) {
      static struct ratelim_t client_warn_ratelim = RATELIM_INIT(600);
      log_fn_ratelim(&client_warn_ratelim, LOG_PROTOCOL_WARN, LD_PROTOCOL,
                     "Unexpected sendme cell from client. "
                     "Closing circ (window %d).", circ->package_window);
      return -END_CIRC_REASON_TORPROTOCOL;
    }
    circ->package_window += CIRCWINDOW_INCREMENT;
    log_debug(LD_EXIT, "circ-level sendme at non-origin, packagewindow %d.",
              circ->package_window);
  }

  return 0;
}

/* Process a stream-level SENDME cell that we just received. The conn is the
 * edge connection (stream) that the circuit circ is associated with. The
 * cell_body_len is the length of the payload (excluding the header).
 *
516
517
 * Return 0 on success (the SENDME is valid and the package window has
 * been updated properly).
518
 *
519
520
 * On error, a negative value is returned, which indicates that the
 * circuit must be closed using the value as the reason for it. */
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
int
sendme_process_stream_level(edge_connection_t *conn, circuit_t *circ,
                            uint16_t cell_body_len)
{
  tor_assert(conn);
  tor_assert(circ);

  /* Don't allow the other endpoint to request more than our maximum (i.e.
   * initial) stream SENDME window worth of data. Well-behaved stock clients
   * will not request more than this max (as per the check in the while loop
   * of sendme_connection_edge_consider_sending()). */
  if ((conn->package_window + STREAMWINDOW_INCREMENT) >
      STREAMWINDOW_START_MAX) {
    static struct ratelim_t stream_warn_ratelim = RATELIM_INIT(600);
    log_fn_ratelim(&stream_warn_ratelim, LOG_PROTOCOL_WARN, LD_PROTOCOL,
                   "Unexpected stream sendme cell. Closing circ (window %d).",
                   conn->package_window);
    return -END_CIRC_REASON_TORPROTOCOL;
  }
  /* At this point, the stream sendme is valid */
  conn->package_window += STREAMWINDOW_INCREMENT;

  /* We count circuit-level sendme's as valid delivered data because they are
   * rate limited. */
  if (CIRCUIT_IS_ORIGIN(circ)) {
    circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), cell_body_len);
  }

  log_debug(CIRCUIT_IS_ORIGIN(circ) ? LD_APP : LD_EXIT,
            "stream-level sendme, package_window now %d.",
            conn->package_window);
  return 0;
}
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586

/* Called when a relay DATA cell is received on the given circuit. If
 * layer_hint is NULL, this means we are the Exit end point else we are the
 * Client. Update the deliver window and return its new value. */
int
sendme_circuit_data_received(circuit_t *circ, crypt_path_t *layer_hint)
{
  int deliver_window, domain;

  if (CIRCUIT_IS_ORIGIN(circ)) {
    tor_assert(layer_hint);
    --layer_hint->deliver_window;
    deliver_window = layer_hint->deliver_window;
    domain = LD_APP;
  } else {
    tor_assert(!layer_hint);
    --circ->deliver_window;
    deliver_window = circ->deliver_window;
    domain = LD_EXIT;
  }

  log_debug(domain, "Circuit deliver_window now %d.", deliver_window);
  return deliver_window;
}

/* Called when a relay DATA cell is received for the given edge connection
 * conn. Update the deliver window and return its new value. */
int
sendme_stream_data_received(edge_connection_t *conn)
{
  tor_assert(conn);
  return --conn->deliver_window;
}
587
588
589
590
591

/* Called when a relay DATA cell is packaged on the given circuit. If
 * layer_hint is NULL, this means we are the Exit end point else we are the
 * Client. Update the package window and return its new value. */
int
592
sendme_note_circuit_data_packaged(circuit_t *circ, crypt_path_t *layer_hint)
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
{
  int package_window, domain;

  tor_assert(circ);

  if (CIRCUIT_IS_ORIGIN(circ)) {
    /* Client side. */
    tor_assert(layer_hint);
    --layer_hint->package_window;
    package_window = layer_hint->package_window;
    domain = LD_APP;
  } else {
    /* Exit side. */
    tor_assert(!layer_hint);
    --circ->package_window;
    package_window = circ->package_window;
    domain = LD_EXIT;
  }

  log_debug(domain, "Circuit package_window now %d.", package_window);
  return package_window;
}

/* Called when a relay DATA cell is packaged for the given edge connection
 * conn. Update the package window and return its new value. */
int
619
sendme_note_stream_data_packaged(edge_connection_t *conn)
620
621
{
  tor_assert(conn);
622
623
624

  --conn->package_window;
  log_debug(LD_APP, "Stream package_window now %d.", conn->package_window);
625
  return conn->package_window;
626
}
627

628
629
630
/* Record the cell digest into the circuit sendme digest list depending on
 * which edge we are. The digest is recorded only if we expect the next cell
 * that we will receive is a SENDME so we can match the digest. */
631
void
632
sendme_record_cell_digest_on_circ(circuit_t *circ, crypt_path_t *cpath)
633
{
634
635
  int package_window;
  uint8_t *sendme_digest;
636
637
638

  tor_assert(circ);

639
640
641
  package_window = circ->package_window;
  if (cpath) {
    package_window = cpath->package_window;
642
  }
643

644
645
646
  /* 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. */
647
  if (!circuit_sendme_cell_is_next(package_window)) {
648
649
650
    return;
  }

651
652
653
654
655
656
657
  /* Getting the digest is expensive so we only do it once we are certain to
   * record it on the circuit. */
  if (cpath) {
    sendme_digest = cpath_get_sendme_digest(cpath);
  } else {
    sendme_digest =
      relay_crypto_get_sendme_digest(&TO_OR_CIRCUIT(circ)->crypto);
658
  }
659
660

  record_cell_digest_on_circ(circ, sendme_digest);
661
}
662
663
664
665
666
667
668
669
670
671

/* Called once we decrypted a cell and recognized it. Record the cell digest
 * as the next sendme digest only if the next cell we'll send on the circuit
 * is expected to be a SENDME. */
void
sendme_record_received_cell_digest(circuit_t *circ, crypt_path_t *cpath)
{
  tor_assert(circ);

  /* Only record if the next cell is expected to be a SENDME. */
672
  if (!circuit_sendme_cell_is_next(cpath ? cpath->deliver_window :
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
                                           circ->deliver_window)) {
    return;
  }

  if (cpath) {
    /* Record incoming digest. */
    cpath_sendme_record_cell_digest(cpath, false);
  } else {
    /* Record foward digest. */
    relay_crypto_record_sendme_digest(&TO_OR_CIRCUIT(circ)->crypto, true);
  }
}

/* Called once we encrypted a cell. Record the cell digest as the next sendme
 * digest only if the next cell we expect to receive is a SENDME so we can
 * match the digests. */
void
sendme_record_sending_cell_digest(circuit_t *circ, crypt_path_t *cpath)
{
  tor_assert(circ);

  /* Only record if the next cell is expected to be a SENDME. */
695
  if (!circuit_sendme_cell_is_next(cpath ? cpath->package_window :
696
697
698
699
700
701
702
703
704
705
706
707
708
709
                                           circ->package_window)) {
    goto end;
  }

  if (cpath) {
    /* Record the forward digest. */
    cpath_sendme_record_cell_digest(cpath, true);
  } else {
    /* Record the incoming digest. */
    relay_crypto_record_sendme_digest(&TO_OR_CIRCUIT(circ)->crypto, false);
  }

 end:
  return;
710
}