From 30c0a10e8a68850d0f76f4653f102b096ebd86ec Mon Sep 17 00:00:00 2001
From: Emmanuel Hocdet <manu@gandi.net>
Date: Wed, 21 Mar 2018 11:19:01 +0100
Subject: [PATCH] MINOR: samples: add crc32c function

This patch adds the support of CRC32c (rfc4960).
---
 doc/configuration.txt | 10 ++++++++++
 src/sample.c          | 11 +++++++++++
 2 files changed, 21 insertions(+)

diff --git a/doc/configuration.txt b/doc/configuration.txt
index fc8304c8f..53f73db63 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -12849,6 +12849,16 @@ crc32([<avalanche>])
   not be used for security purposes as a 32-bit hash is trivial to break. See
   also "djb2", "sdbm", "wt6" and the "hash-type" directive.
 
+crc32c([<avalanche>])
+  Hashes a binary input sample into an unsigned 32-bit quantity using the CRC32C
+  hash function. Optionally, it is possible to apply a full avalanche hash
+  function to the output if the optional <avalanche> argument equals 1. This
+  converter uses the same functions as described in RFC4960, Appendix B [8].
+  It is provided for compatibility with other software which want a CRC32C to be
+  computed on some input keys. It is slower than the other algorithms and it must
+  not be used for security purposes as a 32-bit hash is trivial to break. See
+  also "djb2", "sdbm", "wt6" and the "hash-type" directive.
+
 da-csv-conv(<prop>[,<prop>*])
   Asks the DeviceAtlas converter to identify the User Agent string passed on
   input, and to emit a string made of the concatenation of the properties
diff --git a/src/sample.c b/src/sample.c
index 3e1a156f0..71ee59f0b 100644
--- a/src/sample.c
+++ b/src/sample.c
@@ -1743,6 +1743,16 @@ static int sample_conv_crc32(const struct arg *arg_p, struct sample *smp, void *
 	return 1;
 }
 
+/* hashes the binary input into crc32c (RFC4960, Appendix B [8].) */
+static int sample_conv_crc32c(const struct arg *arg_p, struct sample *smp, void *private)
+{
+	smp->data.u.sint = hash_crc32c(smp->data.u.str.str, smp->data.u.str.len);
+	if (arg_p && arg_p->data.sint)
+		smp->data.u.sint = full_hash(smp->data.u.sint);
+	smp->data.type = SMP_T_SINT;
+	return 1;
+}
+
 /* This function escape special json characters. The returned string can be
  * safely set between two '"' and used as json string. The json string is
  * defined like this:
@@ -2910,6 +2920,7 @@ static struct sample_conv_kw_list sample_conv_kws = {ILH, {
 	{ "ltime",  sample_conv_ltime,     ARG2(1,STR,SINT), NULL, SMP_T_SINT, SMP_T_STR },
 	{ "utime",  sample_conv_utime,     ARG2(1,STR,SINT), NULL, SMP_T_SINT, SMP_T_STR },
 	{ "crc32",  sample_conv_crc32,     ARG1(0,SINT), NULL, SMP_T_BIN,  SMP_T_SINT  },
+	{ "crc32c", sample_conv_crc32c,    ARG1(0,SINT), NULL, SMP_T_BIN,  SMP_T_SINT  },
 	{ "djb2",   sample_conv_djb2,      ARG1(0,SINT), NULL, SMP_T_BIN,  SMP_T_SINT  },
 	{ "sdbm",   sample_conv_sdbm,      ARG1(0,SINT), NULL, SMP_T_BIN,  SMP_T_SINT  },
 	{ "wt6",    sample_conv_wt6,       ARG1(0,SINT), NULL, SMP_T_BIN,  SMP_T_SINT  },
-- 
2.11.0

