Ticket #7912: 223690

File 223690, 2.0 KB (added by asn, 6 years ago)
Line 
1static cell_queue_t destroy_queue;
2
3int
4connection_or_flush_from_destroy_queue(or_connection_t *conn, int max)
5{
6  int n_flushed;
7  cell_queue_t *queue = &destroy_queue;
8  if (!queue->head)
9    return 0;
10  for (n_flushed = 0; n_flushed < max; ) {
11    packed_cell_t *cell = cell_queue_pop(queue);
12
13    connection_write_to_buf(cell->body, CELL_NETWORK_SIZE, TO_CONN(conn));
14
15    packed_cell_free_unchecked(cell);
16    ++n_flushed;
17  }
18
19  if (n_flushed)
20    conn->timestamp_last_added_nonpadding = now;
21  return n_flushed;
22}
23
24void
25append_cell_to_destroy_queue(or_connection_t *orconn,
26                             cell_t *cell)
27{
28  cell_queue_append_packed_copy(destroy_queue, cell);
29
30  if (! connection_get_outbuf_len(TO_CONN(orconn))) {
31    /* There is no data at all waiting to be sent on the outbuf.  Add a
32     * cell, so that we can notice when it gets flushed, flushed_some can
33     * get called, and we can start putting more data onto the buffer then.
34     */
35    log_debug(LD_GENERAL, "Primed a buffer.");
36    connection_or_flush_from_destroy_queue(orconn, 1);
37  }
38}
39
40int
41connection_or_send_destroy(circid_t circ_id, or_connection_t *conn, int reason)
42{
43  cell_t cell;
44
45  memset(&cell, 0, sizeof(cell_t));
46  cell.circ_id = circ_id;
47  cell.command = CELL_DESTROY;
48  cell.payload[0] = (uint8_t) reason;
49  log_debug(LD_OR,"Sending destroy (circID %d).", circ_id);
50  append_cell_to_destroy_queue(conn, &cell)
51  return 0;
52}
53
54int
55connection_or_flushed_some(or_connection_t *conn)
56{
57  size_t datalen = connection_get_outbuf_len(TO_CONN(conn));
58  int flushed;
59  /* If we're under the low water mark, add cells until we're just over the
60   * high water mark. */
61  if (datalen < OR_CONN_LOWWATER) {
62    ssize_t n = CEIL_DIV(OR_CONN_HIGHWATER - datalen, CELL_NETWORK_SIZE);
63    time_t now = approx_time();
64    flushed = connection_or_flush_from_destroy_queue(conn, 1);
65    n -= flushed;
66   /* (64)32:1 destroy cell fair enough? */
67    while (conn->active_circuits && n > 0) {
68      flushed = connection_or_flush_from_first_active_circuit(conn, 1, now);
69      n -= flushed;
70    }
71  }
72  return 0;
73}