]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
cc: Consolidate trunnel code with ntorv3 trunnel file
authorDavid Goulet <dgoulet@torproject.org>
Mon, 22 Jan 2024 19:35:21 +0000 (14:35 -0500)
committerDavid Goulet <dgoulet@torproject.org>
Wed, 31 Jan 2024 15:15:07 +0000 (10:15 -0500)
Signed-off-by: David Goulet <dgoulet@torproject.org>
src/core/crypto/onion_crypto.c
src/core/or/circuitbuild.c
src/core/or/congestion_control_common.c
src/feature/hs/hs_cell.c
src/trunnel/congestion_control.c [deleted file]
src/trunnel/congestion_control.h [deleted file]
src/trunnel/congestion_control.trunnel [deleted file]
src/trunnel/include.am
src/trunnel/ntorv3.c
src/trunnel/ntorv3.h
src/trunnel/ntorv3.trunnel

index e89208411552ec3ec2fad38448a592a99f488b35..8c785a5c1a378afc1e89baf41785e8c2a32a1c7c 100644 (file)
@@ -49,7 +49,6 @@
 #include "core/or/crypt_path_st.h"
 #include "core/or/extend_info_st.h"
 
-#include "trunnel/congestion_control.h"
 #include "trunnel/extension.h"
 #include "trunnel/ntorv3.h"
 
@@ -138,7 +137,7 @@ parse_ntor3_server_ext(const uint8_t *data, size_t data_len,
     case TRUNNEL_NTORV3_EXT_TYPE_SUBPROTO_REQ:
       ret = parse_subproto_extension(field, params_out);
       break;
-    case TRUNNEL_EXT_TYPE_CC_FIELD_REQUEST:
+    case TRUNNEL_NTORV3_EXT_TYPE_CC_REQ:
       ret = congestion_control_ntor3_parse_ext_request(field, params_out);
       break;
     default:
index 1c3c7f832d5cc33dacbddea0c6b25749cbfc92aa..87dd81eae4d21fa57e71c6d2903fb62c21286376 100644 (file)
@@ -84,7 +84,6 @@
 #include "core/or/origin_circuit_st.h"
 
 #include "trunnel/extension.h"
-#include "trunnel/congestion_control.h"
 
 static int circuit_send_first_onion_skin(origin_circuit_t *circ);
 static int circuit_build_no_more_hops(origin_circuit_t *circ);
index 5a0285aaf8f35f8709339b3cdf19619b0d2cf30f..83a0afed301174a78fd5fee860fa8554d69d1591 100644 (file)
@@ -30,8 +30,8 @@
 #include "feature/nodelist/networkstatus.h"
 #include "app/config/config.h"
 
-#include "trunnel/congestion_control.h"
 #include "trunnel/extension.h"
+#include "trunnel/ntorv3.h"
 
 /* Consensus parameter defaults.
  *
@@ -1006,8 +1006,7 @@ congestion_control_build_ext_request(void)
 
   /* Build the extension field that will hold the CC field. */
   field = trn_extension_field_new();
-  trn_extension_field_set_field_type(field,
-                                     TRUNNEL_EXT_TYPE_CC_FIELD_REQUEST);
+  trn_extension_field_set_field_type(field, TRUNNEL_NTORV3_EXT_TYPE_CC_REQ);
 
   /* No payload indicating a request to use congestion control. */
   trn_extension_field_set_field_len(field, 0);
@@ -1029,7 +1028,7 @@ congestion_control_ntor3_parse_ext_request(const trn_extension_field_t *ext,
 {
   tor_assert(ext);
   tor_assert(trn_extension_field_get_field_type(ext) ==
-             TRUNNEL_EXT_TYPE_CC_FIELD_REQUEST);
+             TRUNNEL_NTORV3_EXT_TYPE_CC_REQ);
 
   /* The presence of the extension is enough to indicate we want it enabled. */
   params_out->cc_enabled = true;
@@ -1051,21 +1050,21 @@ congestion_control_ntor3_build_ext_response(const circuit_params_t *our_params)
 {
   ssize_t ret;
   trn_extension_field_t *field = NULL;
-  trn_extension_field_cc_t *cc_field = NULL;
+  trn_ntorv3_ext_cc_response_t *cc_field = NULL;
 
   tor_assert(our_params);
 
   /* Build the extension field that will hold the CC field. */
   field = trn_extension_field_new();
   trn_extension_field_set_field_type(field,
-                      TRUNNEL_EXT_TYPE_CC_FIELD_RESPONSE);
+                                     TRUNNEL_NTORV3_EXT_TYPE_CC_RESPONSE);
 
   /* Build the congestion control field response. */
-  cc_field = trn_extension_field_cc_new();
-  trn_extension_field_cc_set_sendme_inc(cc_field,
-                                        our_params->sendme_inc_cells);
+  cc_field = trn_ntorv3_ext_cc_response_new();
+  trn_ntorv3_ext_cc_response_set_sendme_inc(cc_field,
+                                            our_params->sendme_inc_cells);
 
-  ret = trn_extension_field_cc_encoded_len(cc_field);
+  ret = trn_ntorv3_ext_cc_response_encoded_len(cc_field);
   if (BUG(ret <= 0)) {
     trn_extension_field_free(field);
     field = NULL;
@@ -1076,7 +1075,7 @@ congestion_control_ntor3_build_ext_response(const circuit_params_t *our_params)
   trn_extension_field_setlen_field(field, field_len);
 
   uint8_t *field_array = trn_extension_field_getarray_field(field);
-  ret = trn_extension_field_cc_encode(field_array,
+  ret = trn_ntorv3_ext_cc_response_encode(field_array,
             trn_extension_field_getlen_field(field), cc_field);
   if (BUG(ret <= 0)) {
     trn_extension_field_free(field);
@@ -1085,7 +1084,7 @@ congestion_control_ntor3_build_ext_response(const circuit_params_t *our_params)
   }
 
  err:
-  trn_extension_field_cc_free(cc_field);
+  trn_ntorv3_ext_cc_response_free(cc_field);
   return field;
 }
 
@@ -1110,78 +1109,6 @@ congestion_control_validate_sendme_increment(uint8_t sendme_inc)
   return true;
 }
 
-/** Return 1 if CC is enabled which also will set the SENDME increment into our
- * params_out. Return 0 if CC is disabled. Else, return -1 on error. */
-int
-congestion_control_parse_ext_response(const uint8_t *msg,
-                                      const size_t msg_len,
-                                      circuit_params_t *params_out)
-{
-  ssize_t ret = 0;
-  size_t num_fields = 0;
-  trn_extension_t *ext = NULL;
-  trn_extension_field_cc_t *cc_field = NULL;
-
-  /* We will only accept this response (and this circuit) if sendme_inc
-   * is within a factor of 2 of our consensus value. We should not need
-   * to change cc_sendme_inc much, and if we do, we can spread out those
-   * changes over smaller increments once every 4 hours. Exits that
-   * violate this range should just not be used. */
-#define MAX_SENDME_INC_NEGOTIATE_FACTOR 2
-
-  /* Parse extension from payload. */
-  ret = trn_extension_parse(&ext, msg, msg_len);
-  if (ret < 0) {
-    goto end;
-  }
-
-  if ((num_fields = trn_extension_get_num(ext)) == 0) {
-    ret = 0;
-    goto end;
-  }
-
-  /* Go over all fields. If any field is TRUNNEL_EXT_TYPE_CC_FIELD_RESPONSE,
-   * then congestion control is enabled. Ignore unknown fields. */
-  for (size_t f = 0; f < num_fields; f++) {
-    const trn_extension_field_t *field = trn_extension_get_fields(ext, f);
-    if (field == NULL) {
-      ret = -1;
-      goto end;
-    }
-
-    /* Only examine TRUNNEL_EXT_TYPE_CC_FIELD_RESPONSE; ignore other fields */
-    if (trn_extension_field_get_field_type(field) ==
-        TRUNNEL_EXT_TYPE_CC_FIELD_RESPONSE) {
-
-      /* Parse the field into the congestion control field. */
-      ret = trn_extension_field_cc_parse(&cc_field,
-                trn_extension_field_getconstarray_field(field),
-                trn_extension_field_getlen_field(field));
-      if (ret < 0) {
-        goto end;
-      }
-
-      uint8_t sendme_inc_cells =
-              trn_extension_field_cc_get_sendme_inc(cc_field);
-      if (!congestion_control_validate_sendme_increment(sendme_inc_cells)) {
-        ret = -1;
-        goto end;
-      }
-
-      /* All good. Get value and break */
-      params_out->sendme_inc_cells = sendme_inc_cells;
-      ret = 1;
-      break;
-    }
-  }
-
- end:
-  trn_extension_free(ext);
-  trn_extension_field_cc_free(cc_field);
-
-  return (int)ret;
-}
-
 /**
  * Returns a formatted string of fields containing congestion
  * control information, for the CIRC_BW control port event.
index 0039825f3cb51abe5aed96587887b1d17357d6d1..a0a32d819b27260654de587163bfcae91c3dd55d 100644 (file)
@@ -19,9 +19,9 @@
 #include "core/or/origin_circuit_st.h"
 
 /* Trunnel. */
-#include "trunnel/congestion_control.h"
 #include "trunnel/ed25519_cert.h"
 #include "trunnel/extension.h"
+#include "trunnel/ntorv3.h"
 #include "trunnel/hs/cell_establish_intro.h"
 #include "trunnel/hs/cell_introduce1.h"
 #include "trunnel/hs/cell_rendezvous.h"
@@ -937,7 +937,6 @@ parse_introduce_cell_extension(const hs_service_t *service,
                                const trn_extension_field_t *field)
 {
   int ret = 0;
-  trn_extension_field_cc_t *cc_field = NULL;
 
   tor_assert(data);
   tor_assert(field);
@@ -961,7 +960,6 @@ parse_introduce_cell_extension(const hs_service_t *service,
     break;
   }
 
-  trn_extension_field_cc_free(cc_field);
   return ret;
 }
 
diff --git a/src/trunnel/congestion_control.c b/src/trunnel/congestion_control.c
deleted file mode 100644 (file)
index 371612b..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-/* congestion_control.c -- generated by Trunnel v1.5.3.
- * https://gitweb.torproject.org/trunnel.git
- * You probably shouldn't edit this file.
- */
-#include <stdlib.h>
-#include "trunnel-impl.h"
-
-#include "congestion_control.h"
-
-#define TRUNNEL_SET_ERROR_CODE(obj) \
-  do {                              \
-    (obj)->trunnel_error_code_ = 1; \
-  } while (0)
-
-#if defined(__COVERITY__) || defined(__clang_analyzer__)
-/* If we're running a static analysis tool, we don't want it to complain
- * that some of our remaining-bytes checks are dead-code. */
-int congestioncontrol_deadcode_dummy__ = 0;
-#define OR_DEADCODE_DUMMY || congestioncontrol_deadcode_dummy__
-#else
-#define OR_DEADCODE_DUMMY
-#endif
-
-#define CHECK_REMAINING(nbytes, label)                           \
-  do {                                                           \
-    if (remaining < (nbytes) OR_DEADCODE_DUMMY) {                \
-      goto label;                                                \
-    }                                                            \
-  } while (0)
-
-trn_extension_field_cc_t *
-trn_extension_field_cc_new(void)
-{
-  trn_extension_field_cc_t *val = trunnel_calloc(1, sizeof(trn_extension_field_cc_t));
-  if (NULL == val)
-    return NULL;
-  return val;
-}
-
-/** Release all storage held inside 'obj', but do not free 'obj'.
- */
-static void
-trn_extension_field_cc_clear(trn_extension_field_cc_t *obj)
-{
-  (void) obj;
-}
-
-void
-trn_extension_field_cc_free(trn_extension_field_cc_t *obj)
-{
-  if (obj == NULL)
-    return;
-  trn_extension_field_cc_clear(obj);
-  trunnel_memwipe(obj, sizeof(trn_extension_field_cc_t));
-  trunnel_free_(obj);
-}
-
-uint8_t
-trn_extension_field_cc_get_sendme_inc(const trn_extension_field_cc_t *inp)
-{
-  return inp->sendme_inc;
-}
-int
-trn_extension_field_cc_set_sendme_inc(trn_extension_field_cc_t *inp, uint8_t val)
-{
-  inp->sendme_inc = val;
-  return 0;
-}
-const char *
-trn_extension_field_cc_check(const trn_extension_field_cc_t *obj)
-{
-  if (obj == NULL)
-    return "Object was NULL";
-  if (obj->trunnel_error_code_)
-    return "A set function failed on this object";
-  return NULL;
-}
-
-ssize_t
-trn_extension_field_cc_encoded_len(const trn_extension_field_cc_t *obj)
-{
-  ssize_t result = 0;
-
-  if (NULL != trn_extension_field_cc_check(obj))
-     return -1;
-
-
-  /* Length of u8 sendme_inc */
-  result += 1;
-  return result;
-}
-int
-trn_extension_field_cc_clear_errors(trn_extension_field_cc_t *obj)
-{
-  int r = obj->trunnel_error_code_;
-  obj->trunnel_error_code_ = 0;
-  return r;
-}
-ssize_t
-trn_extension_field_cc_encode(uint8_t *output, const size_t avail, const trn_extension_field_cc_t *obj)
-{
-  ssize_t result = 0;
-  size_t written = 0;
-  uint8_t *ptr = output;
-  const char *msg;
-#ifdef TRUNNEL_CHECK_ENCODED_LEN
-  const ssize_t encoded_len = trn_extension_field_cc_encoded_len(obj);
-#endif
-
-  if (NULL != (msg = trn_extension_field_cc_check(obj)))
-    goto check_failed;
-
-#ifdef TRUNNEL_CHECK_ENCODED_LEN
-  trunnel_assert(encoded_len >= 0);
-#endif
-
-  /* Encode u8 sendme_inc */
-  trunnel_assert(written <= avail);
-  if (avail - written < 1)
-    goto truncated;
-  trunnel_set_uint8(ptr, (obj->sendme_inc));
-  written += 1; ptr += 1;
-
-
-  trunnel_assert(ptr == output + written);
-#ifdef TRUNNEL_CHECK_ENCODED_LEN
-  {
-    trunnel_assert(encoded_len >= 0);
-    trunnel_assert((size_t)encoded_len == written);
-  }
-
-#endif
-
-  return written;
-
- truncated:
-  result = -2;
-  goto fail;
- check_failed:
-  (void)msg;
-  result = -1;
-  goto fail;
- fail:
-  trunnel_assert(result < 0);
-  return result;
-}
-
-/** As trn_extension_field_cc_parse(), but do not allocate the output
- * object.
- */
-static ssize_t
-trn_extension_field_cc_parse_into(trn_extension_field_cc_t *obj, const uint8_t *input, const size_t len_in)
-{
-  const uint8_t *ptr = input;
-  size_t remaining = len_in;
-  ssize_t result = 0;
-  (void)result;
-
-  /* Parse u8 sendme_inc */
-  CHECK_REMAINING(1, truncated);
-  obj->sendme_inc = (trunnel_get_uint8(ptr));
-  remaining -= 1; ptr += 1;
-  trunnel_assert(ptr + remaining == input + len_in);
-  return len_in - remaining;
-
- truncated:
-  return -2;
-}
-
-ssize_t
-trn_extension_field_cc_parse(trn_extension_field_cc_t **output, const uint8_t *input, const size_t len_in)
-{
-  ssize_t result;
-  *output = trn_extension_field_cc_new();
-  if (NULL == *output)
-    return -1;
-  result = trn_extension_field_cc_parse_into(*output, input, len_in);
-  if (result < 0) {
-    trn_extension_field_cc_free(*output);
-    *output = NULL;
-  }
-  return result;
-}
diff --git a/src/trunnel/congestion_control.h b/src/trunnel/congestion_control.h
deleted file mode 100644 (file)
index 0cc21a1..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/* congestion_control.h -- generated by Trunnel v1.5.3.
- * https://gitweb.torproject.org/trunnel.git
- * You probably shouldn't edit this file.
- */
-#ifndef TRUNNEL_CONGESTION_CONTROL_H
-#define TRUNNEL_CONGESTION_CONTROL_H
-
-#include <stdint.h>
-#include "trunnel.h"
-
-#define TRUNNEL_EXT_TYPE_CC_FIELD_REQUEST 1
-#define TRUNNEL_EXT_TYPE_CC_FIELD_RESPONSE 2
-#if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_TRN_EXTENSION_FIELD_CC)
-struct trn_extension_field_cc_st {
-  uint8_t sendme_inc;
-  uint8_t trunnel_error_code_;
-};
-#endif
-typedef struct trn_extension_field_cc_st trn_extension_field_cc_t;
-/** Return a newly allocated trn_extension_field_cc with all elements
- * set to zero.
- */
-trn_extension_field_cc_t *trn_extension_field_cc_new(void);
-/** Release all storage held by the trn_extension_field_cc in
- * 'victim'. (Do nothing if 'victim' is NULL.)
- */
-void trn_extension_field_cc_free(trn_extension_field_cc_t *victim);
-/** Try to parse a trn_extension_field_cc from the buffer in 'input',
- * using up to 'len_in' bytes from the input buffer. On success,
- * return the number of bytes consumed and set *output to the newly
- * allocated trn_extension_field_cc_t. On failure, return -2 if the
- * input appears truncated, and -1 if the input is otherwise invalid.
- */
-ssize_t trn_extension_field_cc_parse(trn_extension_field_cc_t **output, const uint8_t *input, const size_t len_in);
-/** Return the number of bytes we expect to need to encode the
- * trn_extension_field_cc in 'obj'. On failure, return a negative
- * value. Note that this value may be an overestimate, and can even be
- * an underestimate for certain unencodeable objects.
- */
-ssize_t trn_extension_field_cc_encoded_len(const trn_extension_field_cc_t *obj);
-/** Try to encode the trn_extension_field_cc from 'input' into the
- * buffer at 'output', using up to 'avail' bytes of the output buffer.
- * On success, return the number of bytes used. On failure, return -2
- * if the buffer was not long enough, and -1 if the input was invalid.
- */
-ssize_t trn_extension_field_cc_encode(uint8_t *output, size_t avail, const trn_extension_field_cc_t *input);
-/** Check whether the internal state of the trn_extension_field_cc in
- * 'obj' is consistent. Return NULL if it is, and a short message if
- * it is not.
- */
-const char *trn_extension_field_cc_check(const trn_extension_field_cc_t *obj);
-/** Clear any errors that were set on the object 'obj' by its setter
- * functions. Return true iff errors were cleared.
- */
-int trn_extension_field_cc_clear_errors(trn_extension_field_cc_t *obj);
-/** Return the value of the sendme_inc field of the
- * trn_extension_field_cc_t in 'inp'
- */
-uint8_t trn_extension_field_cc_get_sendme_inc(const trn_extension_field_cc_t *inp);
-/** Set the value of the sendme_inc field of the
- * trn_extension_field_cc_t in 'inp' to 'val'. Return 0 on success;
- * return -1 and set the error code on 'inp' on failure.
- */
-int trn_extension_field_cc_set_sendme_inc(trn_extension_field_cc_t *inp, uint8_t val);
-
-
-#endif
diff --git a/src/trunnel/congestion_control.trunnel b/src/trunnel/congestion_control.trunnel
deleted file mode 100644 (file)
index 50697a0..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/* This file contains the definition for the encrypted payload of a circuit
- * parameter negotiation request/response portion of the trn_ntorv3 onionskin
- * handshake. Currently only supports congestion control params. */
-
-/* The following is encoded in the extension format. */
-
-/* Field types. */
-const TRUNNEL_EXT_TYPE_CC_FIELD_REQUEST  = 0x01;
-const TRUNNEL_EXT_TYPE_CC_FIELD_RESPONSE = 0x02;
-
-/*
- * "Request" is an empty payload signalling that CC is enabled.
- */
-
-/*
- * "Response" consists of 1 single byte:
- *    SENDME_INC -- Min: 0, Max: 255
- */
-
-struct trn_extension_field_cc {
-  u8 sendme_inc;
-};
index 3c20acecaade571b61c3f1fa6707fd6f90ce6019..e4d35038f61a4edf3f43fe8472a5f805796eb600 100644 (file)
@@ -14,7 +14,6 @@ TRUNNELINPUTS = \
        src/trunnel/channelpadding_negotiation.trunnel \
        src/trunnel/sendme_cell.trunnel \
        src/trunnel/flow_control_cells.trunnel \
-       src/trunnel/congestion_control.trunnel \
        src/trunnel/socks5.trunnel \
        src/trunnel/circpad_negotiation.trunnel \
        src/trunnel/conflux.trunnel \
@@ -32,7 +31,6 @@ TRUNNELSOURCES = \
        src/trunnel/channelpadding_negotiation.c \
        src/trunnel/sendme_cell.c                    \
        src/trunnel/flow_control_cells.c                    \
-       src/trunnel/congestion_control.c       \
        src/trunnel/socks5.c \
        src/trunnel/netinfo.c \
        src/trunnel/circpad_negotiation.c \
@@ -53,7 +51,6 @@ TRUNNELHEADERS = \
        src/trunnel/channelpadding_negotiation.h \
        src/trunnel/sendme_cell.h                    \
        src/trunnel/flow_control_cells.h                    \
-       src/trunnel/congestion_control.h    \
        src/trunnel/socks5.h                    \
        src/trunnel/netinfo.h \
        src/trunnel/circpad_negotiation.h \
index ff10fbff2951f57737bc78b1861b054ca8cc68da..8f223fb4857f3029a00e213f3f90970dd8acf1b6 100644 (file)
@@ -28,6 +28,159 @@ int ntorv_deadcode_dummy__ = 0;
     }                                                            \
   } while (0)
 
+trn_ntorv3_ext_cc_response_t *
+trn_ntorv3_ext_cc_response_new(void)
+{
+  trn_ntorv3_ext_cc_response_t *val = trunnel_calloc(1, sizeof(trn_ntorv3_ext_cc_response_t));
+  if (NULL == val)
+    return NULL;
+  return val;
+}
+
+/** Release all storage held inside 'obj', but do not free 'obj'.
+ */
+static void
+trn_ntorv3_ext_cc_response_clear(trn_ntorv3_ext_cc_response_t *obj)
+{
+  (void) obj;
+}
+
+void
+trn_ntorv3_ext_cc_response_free(trn_ntorv3_ext_cc_response_t *obj)
+{
+  if (obj == NULL)
+    return;
+  trn_ntorv3_ext_cc_response_clear(obj);
+  trunnel_memwipe(obj, sizeof(trn_ntorv3_ext_cc_response_t));
+  trunnel_free_(obj);
+}
+
+uint8_t
+trn_ntorv3_ext_cc_response_get_sendme_inc(const trn_ntorv3_ext_cc_response_t *inp)
+{
+  return inp->sendme_inc;
+}
+int
+trn_ntorv3_ext_cc_response_set_sendme_inc(trn_ntorv3_ext_cc_response_t *inp, uint8_t val)
+{
+  inp->sendme_inc = val;
+  return 0;
+}
+const char *
+trn_ntorv3_ext_cc_response_check(const trn_ntorv3_ext_cc_response_t *obj)
+{
+  if (obj == NULL)
+    return "Object was NULL";
+  if (obj->trunnel_error_code_)
+    return "A set function failed on this object";
+  return NULL;
+}
+
+ssize_t
+trn_ntorv3_ext_cc_response_encoded_len(const trn_ntorv3_ext_cc_response_t *obj)
+{
+  ssize_t result = 0;
+
+  if (NULL != trn_ntorv3_ext_cc_response_check(obj))
+     return -1;
+
+
+  /* Length of u8 sendme_inc */
+  result += 1;
+  return result;
+}
+int
+trn_ntorv3_ext_cc_response_clear_errors(trn_ntorv3_ext_cc_response_t *obj)
+{
+  int r = obj->trunnel_error_code_;
+  obj->trunnel_error_code_ = 0;
+  return r;
+}
+ssize_t
+trn_ntorv3_ext_cc_response_encode(uint8_t *output, const size_t avail, const trn_ntorv3_ext_cc_response_t *obj)
+{
+  ssize_t result = 0;
+  size_t written = 0;
+  uint8_t *ptr = output;
+  const char *msg;
+#ifdef TRUNNEL_CHECK_ENCODED_LEN
+  const ssize_t encoded_len = trn_ntorv3_ext_cc_response_encoded_len(obj);
+#endif
+
+  if (NULL != (msg = trn_ntorv3_ext_cc_response_check(obj)))
+    goto check_failed;
+
+#ifdef TRUNNEL_CHECK_ENCODED_LEN
+  trunnel_assert(encoded_len >= 0);
+#endif
+
+  /* Encode u8 sendme_inc */
+  trunnel_assert(written <= avail);
+  if (avail - written < 1)
+    goto truncated;
+  trunnel_set_uint8(ptr, (obj->sendme_inc));
+  written += 1; ptr += 1;
+
+
+  trunnel_assert(ptr == output + written);
+#ifdef TRUNNEL_CHECK_ENCODED_LEN
+  {
+    trunnel_assert(encoded_len >= 0);
+    trunnel_assert((size_t)encoded_len == written);
+  }
+
+#endif
+
+  return written;
+
+ truncated:
+  result = -2;
+  goto fail;
+ check_failed:
+  (void)msg;
+  result = -1;
+  goto fail;
+ fail:
+  trunnel_assert(result < 0);
+  return result;
+}
+
+/** As trn_ntorv3_ext_cc_response_parse(), but do not allocate the
+ * output object.
+ */
+static ssize_t
+trn_ntorv3_ext_cc_response_parse_into(trn_ntorv3_ext_cc_response_t *obj, const uint8_t *input, const size_t len_in)
+{
+  const uint8_t *ptr = input;
+  size_t remaining = len_in;
+  ssize_t result = 0;
+  (void)result;
+
+  /* Parse u8 sendme_inc */
+  CHECK_REMAINING(1, truncated);
+  obj->sendme_inc = (trunnel_get_uint8(ptr));
+  remaining -= 1; ptr += 1;
+  trunnel_assert(ptr + remaining == input + len_in);
+  return len_in - remaining;
+
+ truncated:
+  return -2;
+}
+
+ssize_t
+trn_ntorv3_ext_cc_response_parse(trn_ntorv3_ext_cc_response_t **output, const uint8_t *input, const size_t len_in)
+{
+  ssize_t result;
+  *output = trn_ntorv3_ext_cc_response_new();
+  if (NULL == *output)
+    return -1;
+  result = trn_ntorv3_ext_cc_response_parse_into(*output, input, len_in);
+  if (result < 0) {
+    trn_ntorv3_ext_cc_response_free(*output);
+    *output = NULL;
+  }
+  return result;
+}
 trn_ntorv3_ext_subproto_req_t *
 trn_ntorv3_ext_subproto_req_new(void)
 {
index dfa4bac6dcda6e455ff67d448d675bab30913be9..9ed5138a1bb4e2ffaf2396e8fb113d6c82a7c280 100644 (file)
@@ -8,7 +8,16 @@
 #include <stdint.h>
 #include "trunnel.h"
 
-#define TRUNNEL_EXT_TYPE_SUBPROTO_REQ 3
+#define TRUNNEL_NTORV3_EXT_TYPE_CC_REQ 1
+#define TRUNNEL_NTORV3_EXT_TYPE_CC_RESPONSE 2
+#define TRUNNEL_NTORV3_EXT_TYPE_SUBPROTO_REQ 3
+#if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_TRN_NTORV3_EXT_CC_RESPONSE)
+struct trn_ntorv3_ext_cc_response_st {
+  uint8_t sendme_inc;
+  uint8_t trunnel_error_code_;
+};
+#endif
+typedef struct trn_ntorv3_ext_cc_response_st trn_ntorv3_ext_cc_response_t;
 #if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_TRN_NTORV3_EXT_SUBPROTO_REQ)
 struct trn_ntorv3_ext_subproto_req_st {
   uint8_t proto_id;
@@ -24,6 +33,52 @@ struct trn_ntorv3_ext_subproto_st {
 };
 #endif
 typedef struct trn_ntorv3_ext_subproto_st trn_ntorv3_ext_subproto_t;
+/** Return a newly allocated trn_ntorv3_ext_cc_response with all
+ * elements set to zero.
+ */
+trn_ntorv3_ext_cc_response_t *trn_ntorv3_ext_cc_response_new(void);
+/** Release all storage held by the trn_ntorv3_ext_cc_response in
+ * 'victim'. (Do nothing if 'victim' is NULL.)
+ */
+void trn_ntorv3_ext_cc_response_free(trn_ntorv3_ext_cc_response_t *victim);
+/** Try to parse a trn_ntorv3_ext_cc_response from the buffer in
+ * 'input', using up to 'len_in' bytes from the input buffer. On
+ * success, return the number of bytes consumed and set *output to the
+ * newly allocated trn_ntorv3_ext_cc_response_t. On failure, return -2
+ * if the input appears truncated, and -1 if the input is otherwise
+ * invalid.
+ */
+ssize_t trn_ntorv3_ext_cc_response_parse(trn_ntorv3_ext_cc_response_t **output, const uint8_t *input, const size_t len_in);
+/** Return the number of bytes we expect to need to encode the
+ * trn_ntorv3_ext_cc_response in 'obj'. On failure, return a negative
+ * value. Note that this value may be an overestimate, and can even be
+ * an underestimate for certain unencodeable objects.
+ */
+ssize_t trn_ntorv3_ext_cc_response_encoded_len(const trn_ntorv3_ext_cc_response_t *obj);
+/** Try to encode the trn_ntorv3_ext_cc_response from 'input' into the
+ * buffer at 'output', using up to 'avail' bytes of the output buffer.
+ * On success, return the number of bytes used. On failure, return -2
+ * if the buffer was not long enough, and -1 if the input was invalid.
+ */
+ssize_t trn_ntorv3_ext_cc_response_encode(uint8_t *output, size_t avail, const trn_ntorv3_ext_cc_response_t *input);
+/** Check whether the internal state of the trn_ntorv3_ext_cc_response
+ * in 'obj' is consistent. Return NULL if it is, and a short message
+ * if it is not.
+ */
+const char *trn_ntorv3_ext_cc_response_check(const trn_ntorv3_ext_cc_response_t *obj);
+/** Clear any errors that were set on the object 'obj' by its setter
+ * functions. Return true iff errors were cleared.
+ */
+int trn_ntorv3_ext_cc_response_clear_errors(trn_ntorv3_ext_cc_response_t *obj);
+/** Return the value of the sendme_inc field of the
+ * trn_ntorv3_ext_cc_response_t in 'inp'
+ */
+uint8_t trn_ntorv3_ext_cc_response_get_sendme_inc(const trn_ntorv3_ext_cc_response_t *inp);
+/** Set the value of the sendme_inc field of the
+ * trn_ntorv3_ext_cc_response_t in 'inp' to 'val'. Return 0 on
+ * success; return -1 and set the error code on 'inp' on failure.
+ */
+int trn_ntorv3_ext_cc_response_set_sendme_inc(trn_ntorv3_ext_cc_response_t *inp, uint8_t val);
 /** Return a newly allocated trn_ntorv3_ext_subproto_req with all
  * elements set to zero.
  */
index fee756af390148cbc67b778be8cf032cd9e8be99..80d25fac59a2141f0f3e98253ea4b371bd316255 100644 (file)
@@ -1,8 +1,13 @@
+/* This file contains the definition for the encrypted payload of a circuit
+ * parameter negotiation request/response portion of the trn_ntorv3 onionskin
+ * handshake. */
+
 /*
- * The ntorv3 extension type value in order to recognize the subproto
- * extension.
+ * The ntorv3 extension type value.
  */
-const TRUNNEL_EXT_TYPE_SUBPROTO_REQ = 0x03;
+const TRUNNEL_NTORV3_EXT_TYPE_CC_REQ       = 0x01;
+const TRUNNEL_NTORV3_EXT_TYPE_CC_RESPONSE  = 0x02;
+const TRUNNEL_NTORV3_EXT_TYPE_SUBPROTO_REQ = 0x03;
 
 /*
  * Extension used to negotiate subprotocol versions detailed in proposal 346.
@@ -20,3 +25,17 @@ struct trn_ntorv3_ext_subproto_req {
   /* Protocol version being requested. */
   u8 proto_version;
 }
+
+/*
+ * Congestion Control
+ */
+
+/* "Request" is an empty payload signalling that CC is enabled. */
+
+/*
+ * "Response" consists of 1 single byte:
+ *    SENDME_INC -- Min: 0, Max: 255
+ */
+struct trn_ntorv3_ext_cc_response {
+  u8 sendme_inc;
+};