Commit 05624b57 authored by David Goulet's avatar David Goulet 🐼
Browse files

Merge branch 'bug40566' into 'main'

Remove unused congestion control and BDP algs

See merge request tpo/core/tor!725
parents bcbc5b5b 5867ddef
Loading
Loading
Loading
Loading

changes/ticket40566

0 → 100644
+4 −0
Original line number Diff line number Diff line
  o Minor bugfix (congestion control):
    - Remove unused congestion control algorithms and BDP calculation
      code, now that we have settled on and fully tuned Vegas. Fixes
      bug 40566; bugfix on 0.4.7.4-alpha.
+25 −267
Original line number Diff line number Diff line
@@ -22,8 +22,6 @@
#include "core/or/congestion_control_st.h"
#include "core/or/congestion_control_common.h"
#include "core/or/congestion_control_vegas.h"
#include "core/or/congestion_control_nola.h"
#include "core/or/congestion_control_westwood.h"
#include "core/or/congestion_control_st.h"
#include "core/or/conflux.h"
#include "core/or/conflux_util.h"
@@ -88,8 +86,7 @@

static bool congestion_control_update_circuit_bdp(congestion_control_t *,
                                                  const circuit_t *,
                                                  const crypt_path_t *,
                                                  uint64_t, uint64_t);
                                                  uint64_t);
/* Number of times the RTT value was reset. For MetricsPort. */
static uint64_t num_rtt_reset;

@@ -216,6 +213,13 @@ congestion_control_new_consensus_params(const networkstatus_t *ns)
        CC_ALG_DFLT,
        CC_ALG_MIN,
        CC_ALG_MAX);
  if (cc_alg != CC_ALG_SENDME && cc_alg != CC_ALG_VEGAS) {
    // Does not need rate limiting because consensus updates
    // are at most 1x/hour
    log_warn(LD_BUG, "Unsupported congestion control algorithm %d",
               cc_alg);
    cc_alg = CC_ALG_DFLT;
  }

#define BWE_SENDME_MIN_MIN 2
#define BWE_SENDME_MIN_MAX (20)
@@ -316,37 +320,13 @@ congestion_control_init_params(congestion_control_t *cc,
    cc->cc_alg = cc_alg;
  }

  bdp_alg_t default_bdp_alg = 0;

  switch (cc->cc_alg) {
    case CC_ALG_WESTWOOD:
      default_bdp_alg = WESTWOOD_BDP_ALG;
      break;
    case CC_ALG_VEGAS:
      default_bdp_alg = VEGAS_BDP_MIX_ALG;
      break;
    case CC_ALG_NOLA:
      default_bdp_alg = NOLA_BDP_ALG;
      break;
    case CC_ALG_SENDME:
    default:
      tor_fragile_assert();
      return; // No alg-specific params
  }

  cc->bdp_alg =
    networkstatus_get_param(NULL, "cc_bdp_alg",
        default_bdp_alg,
        0,
        NUM_BDP_ALGS-1);

  /* Algorithm-specific parameters */
  if (cc->cc_alg == CC_ALG_WESTWOOD) {
    congestion_control_westwood_set_params(cc);
  } else if (cc->cc_alg == CC_ALG_VEGAS) {
  if (cc->cc_alg == CC_ALG_VEGAS) {
    congestion_control_vegas_set_params(cc, path);
  } else if (cc->cc_alg == CC_ALG_NOLA) {
    congestion_control_nola_set_params(cc);
  } else {
    // This should not happen anymore
    log_warn(LD_BUG, "Unknown congestion control algorithm %d",
             cc->cc_alg);
  }
}

@@ -420,7 +400,6 @@ congestion_control_init(congestion_control_t *cc,
                        cc_path_t path)
{
  cc->sendme_pending_timestamps = smartlist_new();
  cc->sendme_arrival_timestamps = smartlist_new();

  cc->in_slow_start = 1;
  congestion_control_init_params(cc, params, path);
@@ -451,9 +430,7 @@ congestion_control_free_(congestion_control_t *cc)
    return;

  SMARTLIST_FOREACH(cc->sendme_pending_timestamps, uint64_t *, t, tor_free(t));
  SMARTLIST_FOREACH(cc->sendme_arrival_timestamps, uint64_t *, t, tor_free(t));
  smartlist_free(cc->sendme_pending_timestamps);
  smartlist_free(cc->sendme_arrival_timestamps);

  tor_free(cc);
}
@@ -470,22 +447,6 @@ enqueue_timestamp(smartlist_t *timestamps_u64, uint64_t timestamp_usec)
  smartlist_add(timestamps_u64, timestamp_ptr);
}

/**
 * Peek at the head of a smartlist queue of u64 timestamps.
 */
static inline uint64_t
peek_timestamp(const smartlist_t *timestamps_u64_usecs)
{
  uint64_t *timestamp_ptr = smartlist_get(timestamps_u64_usecs, 0);

  if (BUG(!timestamp_ptr)) {
    log_err(LD_CIRC, "Congestion control timestamp list became empty!");
    return 0;
  }

  return *timestamp_ptr;
}

/**
 * Dequeue a u64 monotime usec timestamp from the front of a
 * smartlist of pointers to 64.
@@ -689,61 +650,6 @@ congestion_control_note_cell_sent(congestion_control_t *cc,
                    monotime_absolute_usec());
}

/**
 * Returns true if any edge connections are active.
 *
 * We need to know this so that we can stop computing BDP if the
 * edges are not sending on the circuit.
 */
static int
circuit_has_active_streams(const circuit_t *circ,
                           const crypt_path_t *layer_hint)
{
  const edge_connection_t *streams;

  if (CIRCUIT_IS_ORIGIN(circ)) {
    streams = CONST_TO_ORIGIN_CIRCUIT(circ)->p_streams;
  } else {
    streams = CONST_TO_OR_CIRCUIT(circ)->n_streams;
  }

  /* Check linked list of streams */
  for (const edge_connection_t *conn = streams; conn != NULL;
       conn = conn->next_stream) {
    if (conn->base_.marked_for_close)
      continue;

    if (edge_uses_cpath(conn, layer_hint)) {
      if (connection_get_inbuf_len(TO_CONN(conn)) > 0) {
        log_info(LD_CIRC, "CC: More in edge inbuf...");
        return 1;
      }

      /* If we did not reach EOF on this read, there's more */
      if (!TO_CONN(conn)->inbuf_reached_eof) {
        log_info(LD_CIRC, "CC: More on edge conn...");
        return 1;
      }

      if (TO_CONN(conn)->linked_conn) {
        if (connection_get_inbuf_len(TO_CONN(conn)->linked_conn) > 0) {
          log_info(LD_CIRC, "CC: More in linked inbuf...");
          return 1;
        }

        /* If there is a linked conn, and *it* did not each EOF,
         * there's more */
        if (!TO_CONN(conn)->linked_conn->inbuf_reached_eof) {
          log_info(LD_CIRC, "CC: More on linked conn...");
          return 1;
        }
      }
    }
  }

  return 0;
}

/**
 * Upon receipt of a SENDME, pop the oldest timestamp off the timestamp
 * list, and use this to update RTT.
@@ -753,15 +659,13 @@ circuit_has_active_streams(const circuit_t *circ,
 */
bool
congestion_control_update_circuit_estimates(congestion_control_t *cc,
                                            const circuit_t *circ,
                                            const crypt_path_t *layer_hint)
                                            const circuit_t *circ)
{
  uint64_t now_usec = monotime_absolute_usec();

  /* Update RTT first, then BDP. BDP needs fresh RTT */
  uint64_t curr_rtt_usec = congestion_control_update_circuit_rtt(cc, now_usec);
  return congestion_control_update_circuit_bdp(cc, circ, layer_hint, now_usec,
                                               curr_rtt_usec);
  return congestion_control_update_circuit_bdp(cc, circ, curr_rtt_usec);
}

/**
@@ -777,13 +681,6 @@ time_delta_should_use_heuristics(const congestion_control_t *cc)
    return true;
  }

  /* If we managed to get enough acks to estimate a SENDME BDP, then
   * we have enough to estimate clock jumps relative to a baseline,
   * too. (This is at least 'cc_bwe_min' acks). */
  if (cc->bdp[BDP_ALG_SENDME_RATE]) {
    return true;
  }

  /* Not enough data to estimate clock jumps */
  return false;
}
@@ -950,14 +847,10 @@ congestion_control_update_circuit_rtt(congestion_control_t *cc,
static bool
congestion_control_update_circuit_bdp(congestion_control_t *cc,
                                      const circuit_t *circ,
                                      const crypt_path_t *layer_hint,
                                      uint64_t now_usec,
                                      uint64_t curr_rtt_usec)
{
  int chan_q = 0;
  unsigned int blocked_on_chan = 0;
  uint64_t timestamp_usec;
  uint64_t sendme_rate_bdp = 0;

  tor_assert(cc);

@@ -995,10 +888,7 @@ congestion_control_update_circuit_bdp(congestion_control_t *cc,
       cc->blocked_chan = 0;
     }

     cc->bdp[BDP_ALG_CWND_RTT] = cwnd;
     cc->bdp[BDP_ALG_INFLIGHT_RTT] = cwnd;
     cc->bdp[BDP_ALG_SENDME_RATE] = cwnd;
     cc->bdp[BDP_ALG_PIECEWISE] = cwnd;
     cc->bdp = cwnd;

     static ratelim_t dec_notice_limit = RATELIM_INIT(300);
     log_fn_ratelim(&dec_notice_limit, LOG_NOTICE, LD_CIRC,
@@ -1017,84 +907,7 @@ congestion_control_update_circuit_bdp(congestion_control_t *cc,
   * close to ewma RTT. Since all fields are u64, there is plenty of
   * room here to multiply first.
   */
  cc->bdp[BDP_ALG_CWND_RTT] = cc->cwnd*cc->min_rtt_usec/cc->ewma_rtt_usec;

  /*
   * If we have no pending streams, we do not have enough data to fill
   * the BDP, so preserve our old estimates but do not make any more.
   */
  if (!blocked_on_chan && !circuit_has_active_streams(circ, layer_hint)) {
    log_info(LD_CIRC,
               "CC: Streams drained. Spare package window: %"PRIu64
               ", no BDP update", cc->cwnd - cc->inflight);

    /* Clear SENDME timestamps; they will be wrong with intermittent data */
    SMARTLIST_FOREACH(cc->sendme_arrival_timestamps, uint64_t *, t,
                      tor_free(t));
    smartlist_clear(cc->sendme_arrival_timestamps);
  } else if (curr_rtt_usec && is_monotime_clock_reliable()) {
    /* Sendme-based BDP will quickly measure BDP in much less than
     * a cwnd worth of data when in use (in 2-10 SENDMEs).
     *
     * But if the link goes idle, it will be vastly lower than true BDP. Hence
     * we only compute it if we have either pending stream data, or streams
     * are still blocked on the channel queued data.
     *
     * We also do not compute it if we do not have a current RTT passed in,
     * because that means that monotime is currently stalled or just jumped.
     */
    enqueue_timestamp(cc->sendme_arrival_timestamps, now_usec);

    if (smartlist_len(cc->sendme_arrival_timestamps) >= bwe_sendme_min) {
      /* If we have more sendmes than fit in a cwnd, trim the list.
       * Those are not acurrately measuring throughput, if cwnd is
       * currently smaller than BDP */
      while (smartlist_len(cc->sendme_arrival_timestamps) >
             bwe_sendme_min &&
             (uint64_t)smartlist_len(cc->sendme_arrival_timestamps) >
                       n_ewma_count(cc)) {
        (void)dequeue_timestamp(cc->sendme_arrival_timestamps);
      }
      int sendme_cnt = smartlist_len(cc->sendme_arrival_timestamps);

      /* Calculate SENDME_BWE_COUNT pure average */
      timestamp_usec = peek_timestamp(cc->sendme_arrival_timestamps);
      uint64_t delta = now_usec - timestamp_usec;

      /* In Shadow, the time delta between acks can be 0 if there is no
       * network activity between them. Only update BDP if the delta is
       * non-zero. */
      if (delta > 0) {
        /* The acked data is in sendme_cnt-1 chunks, because we are counting
         * the data that is processed by the other endpoint *between* all of
         * these sendmes. There's one less gap between the sendmes than the
         * number of sendmes. */
        uint64_t cells = (sendme_cnt-1)*cc->sendme_inc;

        /* The bandwidth estimate is cells/delta, which when multiplied
         * by min RTT obtains the BDP. However, we multiply first to
         * avoid precision issues with the RTT being close to delta in size. */
        sendme_rate_bdp = cells*cc->min_rtt_usec/delta;

        /* Calculate BDP_EWMA_COUNT N-EWMA */
        cc->bdp[BDP_ALG_SENDME_RATE] =
                   n_count_ewma(sendme_rate_bdp, cc->bdp[BDP_ALG_SENDME_RATE],
                                n_ewma_count(cc));
      }
    }

    /* In-flight BDP will cause the cwnd to drift down when underutilized.
     * It is most useful when the local OR conn is blocked, so we only
     * compute it if we're utilized. */
    cc->bdp[BDP_ALG_INFLIGHT_RTT] =
        (cc->inflight - chan_q)*cc->min_rtt_usec/
                              MAX(cc->ewma_rtt_usec, curr_rtt_usec);
  } else {
    /* We can still update inflight with just an EWMA RTT, but only
     * if there is data flowing */
    cc->bdp[BDP_ALG_INFLIGHT_RTT] =
        (cc->inflight - chan_q)*cc->min_rtt_usec/cc->ewma_rtt_usec;
  }
  cc->bdp = cc->cwnd*cc->min_rtt_usec/cc->ewma_rtt_usec;

  /* The orconn is blocked; use smaller of inflight vs SENDME */
  if (blocked_on_chan) {
@@ -1107,13 +920,6 @@ congestion_control_update_circuit_bdp(congestion_control_t *cc,
      cc->next_cc_event = 0;
      cc->blocked_chan = 1;
    }

    if (cc->bdp[BDP_ALG_SENDME_RATE]) {
      cc->bdp[BDP_ALG_PIECEWISE] = MIN(cc->bdp[BDP_ALG_INFLIGHT_RTT],
                                      cc->bdp[BDP_ALG_SENDME_RATE]);
    } else {
      cc->bdp[BDP_ALG_PIECEWISE] = cc->bdp[BDP_ALG_INFLIGHT_RTT];
    }
  } else {
    /* If we were previously blocked, emit a new congestion event
     * now that we are unblocked, to re-evaluate cwnd */
@@ -1123,19 +929,6 @@ congestion_control_update_circuit_bdp(congestion_control_t *cc,
      log_info(LD_CIRC, "CC: Streams un-blocked on circ channel. Chanq: %d",
               chan_q);
    }

    cc->bdp[BDP_ALG_PIECEWISE] = MAX(cc->bdp[BDP_ALG_SENDME_RATE],
                                     cc->bdp[BDP_ALG_CWND_RTT]);
  }

  /* We can end up with no piecewise value if we didn't have either
   * a SENDME estimate or enough data for an inflight estimate.
   * It also happens on the very first sendme, since we need two
   * to get a BDP. In these cases, use the cwnd method. */
  if (!cc->bdp[BDP_ALG_PIECEWISE]) {
    cc->bdp[BDP_ALG_PIECEWISE] = cc->bdp[BDP_ALG_CWND_RTT];
    log_info(LD_CIRC, "CC: No piecewise BDP. Using %"PRIu64,
             cc->bdp[BDP_ALG_PIECEWISE]);
  }

  if (cc->next_cc_event == 0) {
@@ -1143,44 +936,25 @@ congestion_control_update_circuit_bdp(congestion_control_t *cc,
      log_info(LD_CIRC,
                 "CC: Circuit %d "
                 "SENDME RTT: %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64", "
                 "BDP estimates: "
                 "%"PRIu64", "
                 "%"PRIu64", "
                 "%"PRIu64", "
                 "%"PRIu64", "
                 "%"PRIu64". ",
                 "BDP estimate: %"PRIu64,
               CONST_TO_ORIGIN_CIRCUIT(circ)->global_identifier,
               cc->min_rtt_usec/1000,
               curr_rtt_usec/1000,
               cc->ewma_rtt_usec/1000,
               cc->max_rtt_usec/1000,
               cc->bdp[BDP_ALG_INFLIGHT_RTT],
               cc->bdp[BDP_ALG_CWND_RTT],
               sendme_rate_bdp,
               cc->bdp[BDP_ALG_SENDME_RATE],
               cc->bdp[BDP_ALG_PIECEWISE]
               );
               cc->bdp);
    } else {
      log_info(LD_CIRC,
                 "CC: Circuit %"PRIu64":%d "
                 "SENDME RTT: %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64", "
                 "%"PRIu64", "
                 "%"PRIu64", "
                 "%"PRIu64", "
                 "%"PRIu64", "
                 "%"PRIu64". ",
                 "%"PRIu64,
                 CONST_TO_OR_CIRCUIT(circ)->p_chan->global_identifier,
                 CONST_TO_OR_CIRCUIT(circ)->p_circ_id,
                 cc->min_rtt_usec/1000,
                 curr_rtt_usec/1000,
                 cc->ewma_rtt_usec/1000,
                 cc->max_rtt_usec/1000,
                 cc->bdp[BDP_ALG_INFLIGHT_RTT],
                 cc->bdp[BDP_ALG_CWND_RTT],
                 sendme_rate_bdp,
                 cc->bdp[BDP_ALG_SENDME_RATE],
                 cc->bdp[BDP_ALG_PIECEWISE]
                 );
                 cc->bdp);
    }
  }

@@ -1188,8 +962,7 @@ congestion_control_update_circuit_bdp(congestion_control_t *cc,
   * the curr_rtt_usec was not 0. */
  bool ret = (blocked_on_chan || curr_rtt_usec != 0);
  if (ret) {
    tor_trace(TR_SUBSYS(cc), TR_EV(bdp_update), circ, cc, curr_rtt_usec,
              sendme_rate_bdp);
    tor_trace(TR_SUBSYS(cc), TR_EV(bdp_update), circ, cc, curr_rtt_usec);
  }
  return ret;
}
@@ -1199,27 +972,12 @@ congestion_control_update_circuit_bdp(congestion_control_t *cc,
 */
int
congestion_control_dispatch_cc_alg(congestion_control_t *cc,
                                   circuit_t *circ,
                                   const crypt_path_t *layer_hint)
                                   circuit_t *circ)
{
  int ret = -END_CIRC_REASON_INTERNAL;
  switch (cc->cc_alg) {
    case CC_ALG_WESTWOOD:
      ret = congestion_control_westwood_process_sendme(cc, circ, layer_hint);
      break;

    case CC_ALG_VEGAS:
      ret = congestion_control_vegas_process_sendme(cc, circ, layer_hint);
      break;

    case CC_ALG_NOLA:
      ret = congestion_control_nola_process_sendme(cc, circ, layer_hint);
      break;

    case CC_ALG_SENDME:
    default:
      tor_assert(0);
  }
  tor_assert_nonfatal_once(cc->cc_alg == CC_ALG_VEGAS);
  ret = congestion_control_vegas_process_sendme(cc, circ);

  if (cc->cwnd > cwnd_max) {
    static ratelim_t cwnd_limit = RATELIM_INIT(60);
+2 −4
Original line number Diff line number Diff line
@@ -46,16 +46,14 @@ congestion_control_t *congestion_control_new(
                                    cc_path_t path);

int congestion_control_dispatch_cc_alg(congestion_control_t *cc,
                                       circuit_t *circ,
                                       const crypt_path_t *layer_hint);
                                       circuit_t *circ);

void congestion_control_note_cell_sent(congestion_control_t *cc,
                                       const circuit_t *circ,
                                       const crypt_path_t *cpath);

bool congestion_control_update_circuit_estimates(congestion_control_t *,
                                                 const circuit_t *,
                                                 const crypt_path_t *);
                                                 const circuit_t *);

int congestion_control_get_package_window(const circuit_t *,
                                          const crypt_path_t *);
+0 −139
Original line number Diff line number Diff line
/* Copyright (c) 2019-2021, The Tor Project, Inc. */
/* See LICENSE for licensing information */

/**
 * \file congestion_control_nola.c
 * \brief Code that implements the TOR_NOLA congestion control algorithm
 *        from Proposal #324.
 */

#define TOR_CONGESTION_CONTROL_NOLA_PRIVATE

#include "core/or/or.h"

#include "core/or/crypt_path.h"
#include "core/or/or_circuit_st.h"
#include "core/or/sendme.h"
#include "core/or/congestion_control_st.h"
#include "core/or/congestion_control_common.h"
#include "core/or/congestion_control_nola.h"
#include "core/or/circuituse.h"
#include "core/or/circuitlist.h"
#include "core/or/origin_circuit_st.h"
#include "core/or/channel.h"
#include "feature/nodelist/networkstatus.h"
#include "feature/control/control_events.h"

#define NOLA_BDP_OVERSHOOT    100

/**
 * Cache NOLA consensus parameters.
 */
void
congestion_control_nola_set_params(congestion_control_t *cc)
{
  tor_assert(cc->cc_alg == CC_ALG_NOLA);

  cc->nola_params.bdp_overshoot =
      networkstatus_get_param(NULL, "cc_nola_overshoot",
              NOLA_BDP_OVERSHOOT,
              0,
              1000);
}

/**
* Process a SENDME and update the congestion window according to the
* rules specified in TOR_NOLA of Proposal #324.
*
* TOR_NOLA updates the congestion window to match the current
* BDP estimate, every sendme. Because this can result in downward
* drift, a fixed overhead is added to the BDP estimate. This will
* cause some queuing, but ensures that the algorithm always uses
* the full BDP.
*
* To handle the case where the local orconn blocks, TOR_NOLA uses
* the 'piecewise' BDP estimate, which uses more a conservative BDP
* estimate method when blocking occurs, but a more aggressive BDP
* estimate when there is no local blocking. This minimizes local
* client queues.
*/
int
congestion_control_nola_process_sendme(congestion_control_t *cc,
                                       const circuit_t *circ,
                                       const crypt_path_t *layer_hint)
{
  tor_assert(cc && cc->cc_alg == CC_ALG_NOLA);
  tor_assert(circ);

  if (cc->next_cc_event)
    cc->next_cc_event--;

  /* If we get a congestion event, the only thing NOLA
   * does is note this as if we exited slow-start
   * (which for NOLA just means we finished our ICW). */
  if (cc->next_cc_event == 0) {
    if (cc->in_slow_start) {
      cc->in_slow_start = 0;

      /* We need to report that slow start has exited ASAP,
       * for sbws bandwidth measurement. */
      if (CIRCUIT_IS_ORIGIN(circ)) {
        /* We must discard const here because the event modifies fields :/ */
        control_event_circ_bandwidth_used_for_circ(
                TO_ORIGIN_CIRCUIT((circuit_t*)circ));
      }
    }
  }

  /* If we did not successfully update BDP, we must return. Otherwise,
   * NOLA can drift downwards */
  if (!congestion_control_update_circuit_estimates(cc, circ, layer_hint)) {
    cc->inflight = cc->inflight - cc->sendme_inc;
    return 0;
  }

  /* We overshoot the BDP by the cwnd_inc param amount, because BDP
   * may otherwise drift down. This helps us probe for more capacity.
   * But there is no sense to do it if the local channel is blocked. */
  if (cc->blocked_chan)
    cc->cwnd = cc->bdp[cc->bdp_alg];
  else
    cc->cwnd = cc->bdp[cc->bdp_alg] + cc->nola_params.bdp_overshoot;

  /* cwnd can never fall below 1 increment */
  cc->cwnd = MAX(cc->cwnd, cc->cwnd_min);

  if (CIRCUIT_IS_ORIGIN(circ)) {
    log_info(LD_CIRC,
               "CC TOR_NOLA: Circuit %d "
               "CWND: %"PRIu64", "
               "INFL: %"PRIu64", "
               "NCCE: %"PRIu16", "
               "SS: %d",
             CONST_TO_ORIGIN_CIRCUIT(circ)->global_identifier,
             cc->cwnd,
             cc->inflight,
             cc->next_cc_event,
             cc->in_slow_start
             );
  } else {
    log_info(LD_CIRC,
               "CC TOR_NOLA: Circuit %"PRIu64":%d "
               "CWND: %"PRIu64", "
               "INFL: %"PRIu64", "
               "NCCE: %"PRIu16", "
               "SS: %d",
             CONST_TO_OR_CIRCUIT(circ)->p_chan->global_identifier,
             CONST_TO_OR_CIRCUIT(circ)->p_circ_id,
             cc->cwnd,
             cc->inflight,
             cc->next_cc_event,
             cc->in_slow_start
             );
  }

  /* Update inflight with ack */
  cc->inflight = cc->inflight - cc->sendme_inc;

  return 0;
}
+0 −33
Original line number Diff line number Diff line
/* Copyright (c) 2019-2021, The Tor Project, Inc. */
/* See LICENSE for licensing information */

/**
 * \file congestion_control_nola.h
 * \brief Private-ish APIs for the TOR_NOLA congestion control algorithm
 **/

#ifndef TOR_CONGESTION_CONTROL_NOLA_H
#define TOR_CONGESTION_CONTROL_NOLA_H

#include "core/or/crypt_path_st.h"
#include "core/or/circuit_st.h"

/* Processing SENDME cell. */
int congestion_control_nola_process_sendme(struct congestion_control_t *cc,
                                           const circuit_t *circ,
                                           const crypt_path_t *layer_hint);
void congestion_control_nola_set_params(struct congestion_control_t *cc);

/* Private section starts. */
#ifdef TOR_CONGESTION_CONTROL_NOLA_PRIVATE

/*
 * Unit tests declaractions.
 */
#ifdef TOR_UNIT_TESTS

#endif /* defined(TOR_UNIT_TESTS) */

#endif /* defined(TOR_CONGESTION_CONTROL_NOLA_PRIVATE) */

#endif /* !defined(TOR_CONGESTION_CONTROL_NOLA_H) */
Loading