From 803e203dcccdb6ade9ccc64b691d9106f233fbba Mon Sep 17 00:00:00 2001
From: Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
Date: Sun, 23 Aug 2020 11:08:30 +0900
Subject: [PATCH] Add repurposed ngtcp2_rand_ctx

---
 examples/client.cc           |  3 ++-
 examples/h09client.cc        |  3 ++-
 examples/h09server.cc        |  3 ++-
 examples/server.cc           |  3 ++-
 lib/includes/ngtcp2/ngtcp2.h | 18 ++++++++++++++++++
 lib/ngtcp2_conn.c            |  6 +++---
 tests/ngtcp2_conn_test.c     |  4 +++-
 7 files changed, 32 insertions(+), 8 deletions(-)

diff --git a/examples/client.cc b/examples/client.cc
index 5eafef1d..4a111232 100644
--- a/examples/client.cc
+++ b/examples/client.cc
@@ -621,7 +621,8 @@ int extend_max_streams_bidi(ngtcp2_conn *conn, uint64_t max_streams,
 } // namespace
 
 namespace {
-int rand(uint8_t *dest, size_t destlen, ngtcp2_rand_usage usage) {
+int rand(uint8_t *dest, size_t destlen, const ngtcp2_rand_ctx *rand_ctx,
+         ngtcp2_rand_usage usage) {
   auto dis = std::uniform_int_distribution<uint8_t>(0, 255);
   std::generate(dest, dest + destlen, [&dis]() { return dis(randgen); });
   return 0;
diff --git a/examples/h09client.cc b/examples/h09client.cc
index b8484316..02c40d38 100644
--- a/examples/h09client.cc
+++ b/examples/h09client.cc
@@ -597,7 +597,8 @@ int extend_max_streams_bidi(ngtcp2_conn *conn, uint64_t max_streams,
 } // namespace
 
 namespace {
-int rand(uint8_t *dest, size_t destlen, ngtcp2_rand_usage usage) {
+int rand(uint8_t *dest, size_t destlen, const ngtcp2_rand_ctx *rand_ctx,
+         ngtcp2_rand_usage usage) {
   auto dis = std::uniform_int_distribution<uint8_t>(0, 255);
   std::generate(dest, dest + destlen, [&dis]() { return dis(randgen); });
   return 0;
diff --git a/examples/h09server.cc b/examples/h09server.cc
index 8e49c9a3..684a49d5 100644
--- a/examples/h09server.cc
+++ b/examples/h09server.cc
@@ -704,7 +704,8 @@ int stream_close(ngtcp2_conn *conn, int64_t stream_id, uint64_t app_error_code,
 } // namespace
 
 namespace {
-int rand(uint8_t *dest, size_t destlen, ngtcp2_rand_usage usage) {
+int rand(uint8_t *dest, size_t destlen, const ngtcp2_rand_ctx *rand_ctx,
+         ngtcp2_rand_usage usage) {
   auto dis = std::uniform_int_distribution<uint8_t>(0, 255);
   std::generate(dest, dest + destlen, [&dis]() { return dis(randgen); });
   return 0;
diff --git a/examples/server.cc b/examples/server.cc
index 427c5786..cb2e1e3c 100644
--- a/examples/server.cc
+++ b/examples/server.cc
@@ -1064,7 +1064,8 @@ int Handler::on_stream_reset(int64_t stream_id) {
 }
 
 namespace {
-int rand(uint8_t *dest, size_t destlen, ngtcp2_rand_usage usage) {
+int rand(uint8_t *dest, size_t destlen, const ngtcp2_rand_ctx *rand_ctx,
+         ngtcp2_rand_usage usage) {
   auto dis = std::uniform_int_distribution<uint8_t>(0, 255);
   std::generate(dest, dest + destlen, [&dis]() { return dis(randgen); });
   return 0;
diff --git a/lib/includes/ngtcp2/ngtcp2.h b/lib/includes/ngtcp2/ngtcp2.h
index 88d781b2..11f49659 100644
--- a/lib/includes/ngtcp2/ngtcp2.h
+++ b/lib/includes/ngtcp2/ngtcp2.h
@@ -711,6 +711,18 @@ typedef enum ngtcp2_qlog_write_flag {
   NGTCP2_QLOG_WRITE_FLAG_FIN = 0x01
 } ngtcp2_qlog_write_flag;
 
+/**
+ * @struct
+ *
+ * `ngtcp2_rand_ctx` is a wrapper around native random number
+ * generator.  It is opaque to the ngtcp2 library.  This might be
+ * useful if application needs to specify random number generator per
+ * thread or per connection.
+ */
+typedef struct ngtcp2_rand_ctx {
+  void *native_handle;
+} ngtcp2_rand_ctx;
+
 /**
  * @functypedef
  *
@@ -762,6 +774,11 @@ typedef struct ngtcp2_settings {
    * of token.
    */
   ngtcp2_vec token;
+  /**
+   * rand_ctx is an optional random number generator to be passed to
+   * :type:`ngtcp2_rand` callback.
+   */
+  ngtcp2_rand_ctx rand_ctx;
 } ngtcp2_settings;
 
 /**
@@ -1531,6 +1548,7 @@ typedef int (*ngtcp2_extend_max_stream_data)(ngtcp2_conn *conn,
  * immediately.
  */
 typedef int (*ngtcp2_rand)(uint8_t *dest, size_t destlen,
+                           const ngtcp2_rand_ctx *rand_ctx,
                            ngtcp2_rand_usage usage);
 
 /**
diff --git a/lib/ngtcp2_conn.c b/lib/ngtcp2_conn.c
index 7f30cdad..6855544e 100644
--- a/lib/ngtcp2_conn.c
+++ b/lib/ngtcp2_conn.c
@@ -3616,9 +3616,9 @@ static ngtcp2_ssize conn_write_path_challenge(ngtcp2_conn *conn,
   }
 
   assert(conn->callbacks.rand);
-  rv = conn->callbacks.rand(lfr.path_challenge.data,
-                            sizeof(lfr.path_challenge.data),
-                            NGTCP2_RAND_USAGE_PATH_CHALLENGE);
+  rv = conn->callbacks.rand(
+      lfr.path_challenge.data, sizeof(lfr.path_challenge.data),
+      &conn->local.settings.rand_ctx, NGTCP2_RAND_USAGE_PATH_CHALLENGE);
   if (rv != 0) {
     return NGTCP2_ERR_CALLBACK_FAILURE;
   }
diff --git a/tests/ngtcp2_conn_test.c b/tests/ngtcp2_conn_test.c
index f1758456..1fa0b9e1 100644
--- a/tests/ngtcp2_conn_test.c
+++ b/tests/ngtcp2_conn_test.c
@@ -341,7 +341,9 @@ static int recv_retry(ngtcp2_conn *conn, const ngtcp2_pkt_hd *hd,
   return 0;
 }
 
-static int genrand(uint8_t *dest, size_t destlen, ngtcp2_rand_usage usage) {
+static int genrand(uint8_t *dest, size_t destlen,
+                   const ngtcp2_rand_ctx *rand_ctx, ngtcp2_rand_usage usage) {
+  (void)rand_ctx;
   (void)usage;
 
   memset(dest, 0, destlen);
-- 
GitLab