From c0b6f577cb6866a8bfce22acbcec6983d5f610f6 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 29 Dec 2021 18:22:37 +0100 Subject: -updating block plugins to new API --- src/block/plugin_block_template.c | 83 +++++++++- src/block/plugin_block_test.c | 109 ++++++++++++- src/dht/plugin_block_dht.c | 144 ++++++++++++++++- src/dns/plugin_block_dns.c | 140 ++++++++++++++++- src/identity/identity_api.c | 15 +- src/include/gnunet_identity_service.h | 2 + src/regex/plugin_block_regex.c | 228 ++++++++++++++++++++++++++- src/revocation/gnunet-service-revocation.c | 33 ++-- src/revocation/plugin_block_revocation.c | 242 +++++++++++++++++++---------- src/set/plugin_block_set_test.c | 88 ++++++++++- src/seti/plugin_block_seti_test.c | 86 +++++++++- src/setu/plugin_block_setu_test.c | 86 +++++++++- 12 files changed, 1134 insertions(+), 122 deletions(-) (limited to 'src') diff --git a/src/block/plugin_block_template.c b/src/block/plugin_block_template.c index ecd46e364..13d9adfda 100644 --- a/src/block/plugin_block_template.c +++ b/src/block/plugin_block_template.c @@ -134,6 +134,80 @@ block_plugin_template_evaluate (void *cls, } +/** + * Function called to validate a query. + * + * @param cls closure + * @param ctx block context + * @param type block type + * @param query original query (hash) + * @param xquery extrended query data (can be NULL, depending on type) + * @param xquery_size number of bytes in @a xquery + * @return #GNUNET_OK if the query is fine, #GNUNET_NO if not + */ +static enum GNUNET_GenericReturnValue +block_plugin_template_check_query (void *cls, + enum GNUNET_BLOCK_Type type, + const struct GNUNET_HashCode *query, + const void *xquery, + size_t xquery_size) +{ + return GNUNET_OK; +} + + +/** + * Function called to validate a block for storage. + * + * @param cls closure + * @param type block type + * @param query key for the block (hash), must match exactly + * @param block block data to validate + * @param block_size number of bytes in @a block + * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not + */ +static enum GNUNET_GenericReturnValue +block_plugin_template_check_block (void *cls, + enum GNUNET_BLOCK_Type type, + const struct GNUNET_HashCode *query, + const void *block, + size_t block_size) +{ + return GNUNET_OK; +} + + +/** + * Function called to validate a reply to a request. Note that it is assumed + * that the reply has already been matched to the key (and signatures checked) + * as it would be done with the GetKeyFunction and the + * BlockEvaluationFunction. + * + * @param cls closure + * @param type block type + * @param group which block group to use for evaluation + * @param query original query (hash) + * @param xquery extrended query data (can be NULL, depending on type) + * @param xquery_size number of bytes in @a xquery + * @param reply_block response to validate + * @param reply_block_size number of bytes in @a reply_block + * @return characterization of result + */ +static enum GNUNET_BLOCK_ReplyEvaluationResult +block_plugin_template_check_reply ( + void *cls, + enum GNUNET_BLOCK_Type type, + struct GNUNET_BLOCK_Group *group, + const struct GNUNET_HashCode *query, + const void *xquery, + size_t xquery_size, + const void *reply_block, + size_t reply_block_size) +{ + return GNUNET_BLOCK_REPLY_OK_MORE; +} + + /** * Function called to obtain the key for a block. * @@ -145,7 +219,7 @@ block_plugin_template_evaluate (void *cls, * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported * (or if extracting a key from a block of this type does not work) */ -static int +static enum GNUNET_GenericReturnValue block_plugin_template_get_key (void *cls, enum GNUNET_BLOCK_Type type, const void *block, @@ -164,8 +238,8 @@ block_plugin_template_get_key (void *cls, void * libgnunet_plugin_block_template_init (void *cls) { - static enum GNUNET_BLOCK_Type types[] = { - /* FIXME: insert supported block types here */ + static const enum GNUNET_BLOCK_Type types[] = { + /* NOTE: insert supported block types here */ GNUNET_BLOCK_TYPE_ANY /* end of list */ }; struct GNUNET_BLOCK_PluginFunctions *api; @@ -173,6 +247,9 @@ libgnunet_plugin_block_template_init (void *cls) api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); api->evaluate = &block_plugin_template_evaluate; api->get_key = &block_plugin_template_get_key; + api->check_query = &block_plugin_template_check_query; + api->check_block = &block_plugin_template_check_block; + api->check_reply = &block_plugin_template_check_reply; api->create_group = &block_plugin_template_create_group; api->types = types; return api; diff --git a/src/block/plugin_block_test.c b/src/block/plugin_block_test.c index 45d54d339..fd643c4dc 100644 --- a/src/block/plugin_block_test.c +++ b/src/block/plugin_block_test.c @@ -142,6 +142,108 @@ block_plugin_test_evaluate (void *cls, } +/** + * Function called to validate a query. + * + * @param cls closure + * @param ctx block context + * @param type block type + * @param query original query (hash) + * @param xquery extrended query data (can be NULL, depending on type) + * @param xquery_size number of bytes in @a xquery + * @return #GNUNET_OK if the query is fine, #GNUNET_NO if not + */ +static enum GNUNET_GenericReturnValue +block_plugin_test_check_query (void *cls, + enum GNUNET_BLOCK_Type type, + const struct GNUNET_HashCode *query, + const void *xquery, + size_t xquery_size) +{ + if (GNUNET_BLOCK_TYPE_TEST != type) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + if (0 != xquery_size) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; +} + + +/** + * Function called to validate a block for storage. + * + * @param cls closure + * @param type block type + * @param query key for the block (hash), must match exactly + * @param block block data to validate + * @param block_size number of bytes in @a block + * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not + */ +static enum GNUNET_GenericReturnValue +block_plugin_test_check_block (void *cls, + enum GNUNET_BLOCK_Type type, + const struct GNUNET_HashCode *query, + const void *block, + size_t block_size) +{ + if (GNUNET_BLOCK_TYPE_TEST != type) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + + +/** + * Function called to validate a reply to a request. Note that it is assumed + * that the reply has already been matched to the key (and signatures checked) + * as it would be done with the GetKeyFunction and the + * BlockEvaluationFunction. + * + * @param cls closure + * @param type block type + * @param group which block group to use for evaluation + * @param query original query (hash) + * @param xquery extrended query data (can be NULL, depending on type) + * @param xquery_size number of bytes in @a xquery + * @param reply_block response to validate + * @param reply_block_size number of bytes in @a reply_block + * @return characterization of result + */ +static enum GNUNET_BLOCK_ReplyEvaluationResult +block_plugin_test_check_reply (void *cls, + enum GNUNET_BLOCK_Type type, + struct GNUNET_BLOCK_Group *group, + const struct GNUNET_HashCode *query, + const void *xquery, + size_t xquery_size, + const void *reply_block, + size_t reply_block_size) +{ + struct GNUNET_HashCode chash; + + if (GNUNET_BLOCK_TYPE_TEST != type) + { + GNUNET_break (0); + return GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED; + } + GNUNET_CRYPTO_hash (reply_block, + reply_block_size, + &chash); + if (GNUNET_YES == + GNUNET_BLOCK_GROUP_bf_test_and_set (group, + &chash)) + return GNUNET_BLOCK_REPLY_OK_DUPLICATE; + return GNUNET_BLOCK_REPLY_OK_MORE; +} + + /** * Function called to obtain the key for a block. * @@ -153,7 +255,7 @@ block_plugin_test_evaluate (void *cls, * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported * (or if extracting a key from a block of this type does not work) */ -static int +static enum GNUNET_GenericReturnValue block_plugin_test_get_key (void *cls, enum GNUNET_BLOCK_Type type, const void *block, @@ -175,7 +277,7 @@ block_plugin_test_get_key (void *cls, void * libgnunet_plugin_block_test_init (void *cls) { - static enum GNUNET_BLOCK_Type types[] = { + static const enum GNUNET_BLOCK_Type types[] = { GNUNET_BLOCK_TYPE_TEST, GNUNET_BLOCK_TYPE_ANY /* end of list */ }; @@ -184,6 +286,9 @@ libgnunet_plugin_block_test_init (void *cls) api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); api->evaluate = &block_plugin_test_evaluate; api->get_key = &block_plugin_test_get_key; + api->check_query = &block_plugin_test_check_query; + api->check_block = &block_plugin_test_check_block; + api->check_reply = &block_plugin_test_check_reply; api->create_group = &block_plugin_test_create_group; api->types = types; return api; diff --git a/src/dht/plugin_block_dht.c b/src/dht/plugin_block_dht.c index a9f336240..7c6fb9ed6 100644 --- a/src/dht/plugin_block_dht.c +++ b/src/dht/plugin_block_dht.c @@ -158,6 +158,145 @@ block_plugin_dht_evaluate (void *cls, } +/** + * Function called to validate a query. + * + * @param cls closure + * @param ctx block context + * @param type block type + * @param query original query (hash) + * @param xquery extrended query data (can be NULL, depending on type) + * @param xquery_size number of bytes in @a xquery + * @return #GNUNET_OK if the query is fine, #GNUNET_NO if not + */ +static enum GNUNET_GenericReturnValue +block_plugin_dht_check_query (void *cls, + enum GNUNET_BLOCK_Type type, + const struct GNUNET_HashCode *query, + const void *xquery, + size_t xquery_size) +{ + if (type != GNUNET_BLOCK_TYPE_DHT_HELLO) + return GNUNET_SYSERR; + if (0 != xquery_size) + { + GNUNET_break_op (0); + return GNUNET_NO; + } + return GNUNET_OK; +} + + +/** + * Function called to validate a block for storage. + * + * @param cls closure + * @param type block type + * @param query key for the block (hash), must match exactly + * @param block block data to validate + * @param block_size number of bytes in @a block + * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not + */ +static enum GNUNET_GenericReturnValue +block_plugin_dht_check_block (void *cls, + enum GNUNET_BLOCK_Type type, + const struct GNUNET_HashCode *query, + const void *block, + size_t block_size) +{ + const struct GNUNET_HELLO_Message *hello; + struct GNUNET_PeerIdentity pid; + const struct GNUNET_MessageHeader *msg; + + if (type != GNUNET_BLOCK_TYPE_DHT_HELLO) + return GNUNET_SYSERR; + if (block_size < sizeof(struct GNUNET_MessageHeader)) + { + GNUNET_break_op (0); + return GNUNET_NO; + } + msg = block; + if (block_size != ntohs (msg->size)) + { + GNUNET_break_op (0); + return GNUNET_NO; + } + hello = block; + if (GNUNET_OK != + GNUNET_HELLO_get_id (hello, + &pid)) + { + GNUNET_break_op (0); + return GNUNET_NO; + } + return GNUNET_OK; +} + + +/** + * Function called to validate a reply to a request. Note that it is assumed + * that the reply has already been matched to the key (and signatures checked) + * as it would be done with the GetKeyFunction and the + * BlockEvaluationFunction. + * + * @param cls closure + * @param type block type + * @param group which block group to use for evaluation + * @param query original query (hash) + * @param xquery extrended query data (can be NULL, depending on type) + * @param xquery_size number of bytes in @a xquery + * @param reply_block response to validate + * @param reply_block_size number of bytes in @a reply_block + * @return characterization of result + */ +static enum GNUNET_BLOCK_ReplyEvaluationResult +block_plugin_dht_check_reply ( + void *cls, + enum GNUNET_BLOCK_Type type, + struct GNUNET_BLOCK_Group *group, + const struct GNUNET_HashCode *query, + const void *xquery, + size_t xquery_size, + const void *reply_block, + size_t reply_block_size) +{ + const struct GNUNET_HELLO_Message *hello; + struct GNUNET_PeerIdentity pid; + const struct GNUNET_MessageHeader *msg; + struct GNUNET_HashCode phash; + + if (type != GNUNET_BLOCK_TYPE_DHT_HELLO) + return GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED; + if (reply_block_size < sizeof(struct GNUNET_MessageHeader)) + { + GNUNET_break_op (0); + return GNUNET_BLOCK_REPLY_INVALID; + } + msg = reply_block; + if (reply_block_size != ntohs (msg->size)) + { + GNUNET_break_op (0); + return GNUNET_BLOCK_REPLY_INVALID; + } + hello = reply_block; + if (GNUNET_OK != + GNUNET_HELLO_get_id (hello, + &pid)) + { + GNUNET_break_op (0); + return GNUNET_BLOCK_REPLY_INVALID; + } + GNUNET_CRYPTO_hash (&pid, + sizeof(pid), + &phash); + if (GNUNET_YES == + GNUNET_BLOCK_GROUP_bf_test_and_set (group, + &phash)) + return GNUNET_BLOCK_REPLY_OK_DUPLICATE; + return GNUNET_BLOCK_REPLY_OK_MORE; +} + + /** * Function called to obtain the key for a block. * @@ -169,7 +308,7 @@ block_plugin_dht_evaluate (void *cls, * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported * (or if extracting a key from a block of this type does not work) */ -static int +static enum GNUNET_GenericReturnValue block_plugin_dht_get_key (void *cls, enum GNUNET_BLOCK_Type type, const void *block, @@ -229,6 +368,9 @@ libgnunet_plugin_block_dht_init (void *cls) api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); api->evaluate = &block_plugin_dht_evaluate; api->get_key = &block_plugin_dht_get_key; + api->check_query = &block_plugin_dht_check_query; + api->check_block = &block_plugin_dht_check_block; + api->check_reply = &block_plugin_dht_check_reply; api->create_group = &block_plugin_dht_create_group; api->types = types; return api; diff --git a/src/dns/plugin_block_dns.c b/src/dns/plugin_block_dns.c index e0beccb52..d3eb7d2b9 100644 --- a/src/dns/plugin_block_dns.c +++ b/src/dns/plugin_block_dns.c @@ -176,6 +176,141 @@ block_plugin_dns_evaluate (void *cls, } +/** + * Function called to validate a query. + * + * @param cls closure + * @param ctx block context + * @param type block type + * @param query original query (hash) + * @param xquery extrended query data (can be NULL, depending on type) + * @param xquery_size number of bytes in @a xquery + * @return #GNUNET_OK if the query is fine, #GNUNET_NO if not + */ +static enum GNUNET_GenericReturnValue +block_plugin_dns_check_query (void *cls, + enum GNUNET_BLOCK_Type type, + const struct GNUNET_HashCode *query, + const void *xquery, + size_t xquery_size) +{ + switch (type) + { + case GNUNET_BLOCK_TYPE_DNS: + if (0 != xquery_size) + return GNUNET_NO; + return GNUNET_OK; + default: + return GNUNET_SYSERR; + } +} + + +/** + * Function called to validate a block for storage. + * + * @param cls closure + * @param type block type + * @param query key for the block (hash), must match exactly + * @param block block data to validate + * @param block_size number of bytes in @a block + * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not + */ +static enum GNUNET_GenericReturnValue +block_plugin_dns_check_block (void *cls, + enum GNUNET_BLOCK_Type type, + const struct GNUNET_HashCode *query, + const void *block, + size_t block_size) +{ + const struct GNUNET_DNS_Advertisement *ad; + + switch (type) + { + case GNUNET_BLOCK_TYPE_DNS: + if (sizeof(struct GNUNET_DNS_Advertisement) != block_size) + { + GNUNET_break_op (0); + return GNUNET_NO; + } + ad = block; + + if (ntohl (ad->purpose.size) != + sizeof(struct GNUNET_DNS_Advertisement) + - sizeof(struct GNUNET_CRYPTO_EddsaSignature)) + { + GNUNET_break_op (0); + return GNUNET_NO; + } + if (GNUNET_TIME_absolute_is_past ( + GNUNET_TIME_absolute_ntoh (ad->expiration_time))) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "DNS advertisement has expired\n"); + return GNUNET_NO; + } + if (GNUNET_OK != + GNUNET_CRYPTO_eddsa_verify_ (GNUNET_SIGNATURE_PURPOSE_DNS_RECORD, + &ad->purpose, + &ad->signature, + &ad->peer.public_key)) + { + GNUNET_break_op (0); + return GNUNET_NO; + } + return GNUNET_OK; + default: + return GNUNET_SYSERR; + } +} + + +/** + * Function called to validate a reply to a request. Note that it is assumed + * that the reply has already been matched to the key (and signatures checked) + * as it would be done with the GetKeyFunction and the + * BlockEvaluationFunction. + * + * @param cls closure + * @param type block type + * @param group which block group to use for evaluation + * @param query original query (hash) + * @param xquery extrended query data (can be NULL, depending on type) + * @param xquery_size number of bytes in @a xquery + * @param reply_block response to validate + * @param reply_block_size number of bytes in @a reply_block + * @return characterization of result + */ +static enum GNUNET_BLOCK_ReplyEvaluationResult +block_plugin_dns_check_reply ( + void *cls, + enum GNUNET_BLOCK_Type type, + struct GNUNET_BLOCK_Group *group, + const struct GNUNET_HashCode *query, + const void *xquery, + size_t xquery_size, + const void *reply_block, + size_t reply_block_size) +{ + struct GNUNET_HashCode phash; + + switch (type) + { + case GNUNET_BLOCK_TYPE_DNS: + GNUNET_CRYPTO_hash (reply_block, + reply_block_size, + &phash); + if (GNUNET_YES == + GNUNET_BLOCK_GROUP_bf_test_and_set (group, + &phash)) + return GNUNET_BLOCK_REPLY_OK_DUPLICATE; + return GNUNET_BLOCK_REPLY_OK_MORE; + default: + return GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED; + } +} + + /** * Function called to obtain the key for a block. * @@ -187,7 +322,7 @@ block_plugin_dns_evaluate (void *cls, * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported * (or if extracting a key from a block of this type does not work) */ -static int +static enum GNUNET_GenericReturnValue block_plugin_dns_get_key (void *cls, enum GNUNET_BLOCK_Type type, const void *block, @@ -214,6 +349,9 @@ libgnunet_plugin_block_dns_init (void *cls) api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); api->evaluate = &block_plugin_dns_evaluate; api->get_key = &block_plugin_dns_get_key; + api->check_query = &block_plugin_dns_check_query; + api->check_block = &block_plugin_dns_check_block; + api->check_reply = &block_plugin_dns_check_reply; api->create_group = &block_plugin_dns_create_group; api->types = types; return api; diff --git a/src/identity/identity_api.c b/src/identity/identity_api.c index 08a975e65..01f36b840 100644 --- a/src/identity/identity_api.c +++ b/src/identity/identity_api.c @@ -979,10 +979,8 @@ GNUNET_IDENTITY_key_get_length (const struct GNUNET_IDENTITY_PublicKey *key) { case GNUNET_IDENTITY_TYPE_ECDSA: return sizeof (key->type) + sizeof (key->ecdsa_key); - break; case GNUNET_IDENTITY_TYPE_EDDSA: return sizeof (key->type) + sizeof (key->eddsa_key); - break; default: GNUNET_break (0); } @@ -992,19 +990,22 @@ GNUNET_IDENTITY_key_get_length (const struct GNUNET_IDENTITY_PublicKey *key) ssize_t GNUNET_IDENTITY_read_key_from_buffer (struct GNUNET_IDENTITY_PublicKey *key, - const void*buffer, + const void *buffer, size_t len) { if (len < sizeof (key->type)) return -1; - GNUNET_memcpy (&(key->type), buffer, sizeof (key->type)); - const ssize_t length = GNUNET_IDENTITY_key_get_length (key); + GNUNET_memcpy (&key->type, + buffer, + sizeof (key->type)); + ssize_t length = GNUNET_IDENTITY_key_get_length (key); if (len < length) return -1; if (length < 0) return -2; - GNUNET_memcpy (&(key->ecdsa_key), buffer + sizeof (key->type), length - - sizeof (key->type)); + GNUNET_memcpy (&key->ecdsa_key, + buffer + sizeof (key->type), + length - sizeof (key->type)); return length; } diff --git a/src/include/gnunet_identity_service.h b/src/include/gnunet_identity_service.h index c123983e2..e40a741bf 100644 --- a/src/include/gnunet_identity_service.h +++ b/src/include/gnunet_identity_service.h @@ -82,6 +82,8 @@ struct GNUNET_IDENTITY_Handle; */ struct GNUNET_IDENTITY_Ego; +// FIXME: these types are NOT packed, +// NOT 64-bit aligned, but used in messages!!?? /** * A private key for an identity as per LSD0001. diff --git a/src/regex/plugin_block_regex.c b/src/regex/plugin_block_regex.c index ad897493f..0953830ab 100644 --- a/src/regex/plugin_block_regex.c +++ b/src/regex/plugin_block_regex.c @@ -328,6 +328,222 @@ block_plugin_regex_evaluate (void *cls, } +/** + * Function called to validate a query. + * + * @param cls closure + * @param ctx block context + * @param type block type + * @param query original query (hash) + * @param xquery extrended query data (can be NULL, depending on type) + * @param xquery_size number of bytes in @a xquery + * @return #GNUNET_OK if the query is fine, #GNUNET_NO if not + */ +static enum GNUNET_GenericReturnValue +block_plugin_regex_check_query (void *cls, + enum GNUNET_BLOCK_Type type, + const struct GNUNET_HashCode *query, + const void *xquery, + size_t xquery_size) +{ + switch (type) + { + case GNUNET_BLOCK_TYPE_REGEX: + if (0 != xquery_size) + { + const char *s; + + s = (const char *) xquery; + if ('\0' != s[xquery_size - 1]) /* must be valid 0-terminated string */ + { + GNUNET_break_op (0); + return GNUNET_NO; + } + } + return GNUNET_OK; + case GNUNET_BLOCK_TYPE_REGEX_ACCEPT: + if (0 != xquery_size) + { + GNUNET_break_op (0); + return GNUNET_NO; + } + return GNUNET_OK; + default: + GNUNET_break (0); + return GNUNET_SYSERR; + } +} + + +/** + * Function called to validate a block for storage. + * + * @param cls closure + * @param type block type + * @param query key for the block (hash), must match exactly + * @param block block data to validate + * @param block_size number of bytes in @a block + * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not + */ +static enum GNUNET_GenericReturnValue +block_plugin_regex_check_block (void *cls, + enum GNUNET_BLOCK_Type type, + const struct GNUNET_HashCode *query, + const void *block, + size_t block_size) +{ + switch (type) + { + case GNUNET_BLOCK_TYPE_REGEX: + if (GNUNET_SYSERR == + REGEX_BLOCK_check (block, + block_size, + query, + NULL)) + return GNUNET_NO; + return GNUNET_OK; + case GNUNET_BLOCK_TYPE_REGEX_ACCEPT: + { + const struct RegexAcceptBlock *rba; + + if (sizeof(struct RegexAcceptBlock) != block_size) + { + GNUNET_break_op (0); + return GNUNET_NO; + } + rba = block; + if (ntohl (rba->purpose.size) != + sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) + + sizeof(struct GNUNET_TIME_AbsoluteNBO) + + sizeof(struct GNUNET_HashCode)) + { + GNUNET_break_op (0); + return GNUNET_NO; + } + if (GNUNET_TIME_absolute_is_past (GNUNET_TIME_absolute_ntoh ( + rba->expiration_time))) + { + return GNUNET_NO; + } + if (GNUNET_OK != + GNUNET_CRYPTO_eddsa_verify_ (GNUNET_SIGNATURE_PURPOSE_REGEX_ACCEPT, + &rba->purpose, + &rba->signature, + &rba->peer.public_key)) + { + GNUNET_break_op (0); + return GNUNET_NO; + } + return GNUNET_OK; + } + default: + GNUNET_break (0); + return GNUNET_SYSERR; + } +} + + +/** + * Function called to validate a reply to a request. Note that it is assumed + * that the reply has already been matched to the key (and signatures checked) + * as it would be done with the GetKeyFunction and the + * BlockEvaluationFunction. + * + * @param cls closure + * @param type block type + * @param group which block group to use for evaluation + * @param query original query (hash) + * @param xquery extrended query data (can be NULL, depending on type) + * @param xquery_size number of bytes in @a xquery + * @param reply_block response to validate + * @param reply_block_size number of bytes in @a reply_block + * @return characterization of result + */ +static enum GNUNET_BLOCK_ReplyEvaluationResult +block_plugin_regex_check_reply ( + void *cls, + enum GNUNET_BLOCK_Type type, + struct GNUNET_BLOCK_Group *group, + const struct GNUNET_HashCode *query, + const void *xquery, + size_t xquery_size, + const void *reply_block, + size_t reply_block_size) +{ + struct GNUNET_HashCode chash; + + switch (type) + { + case GNUNET_BLOCK_TYPE_REGEX: + if (0 != xquery_size) + { + const char *s; + + s = (const char *) xquery; + if ('\0' != s[xquery_size - 1]) /* must be valid 0-terminated string */ + { + /* Technically, the query is invalid ... */ + GNUNET_break (0); + return GNUNET_BLOCK_REPLY_INVALID; + } + } + switch (REGEX_BLOCK_check (reply_block, + reply_block_size, + query, + xquery)) + { + case GNUNET_SYSERR: + GNUNET_break_op (0); + return GNUNET_BLOCK_REPLY_INVALID; + case GNUNET_NO: + /* xquery mismatch, can happen */ + return GNUNET_BLOCK_REPLY_IRRELEVANT; + default: + break; + } + GNUNET_CRYPTO_hash (reply_block, + reply_block_size, + &chash); + if (GNUNET_YES == + GNUNET_BLOCK_GROUP_bf_test_and_set (group, + &chash)) + return GNUNET_BLOCK_REPLY_OK_DUPLICATE; + return GNUNET_BLOCK_REPLY_OK_MORE; + case GNUNET_BLOCK_TYPE_REGEX_ACCEPT: + { + const struct RegexAcceptBlock *rba; + + if (sizeof(struct RegexAcceptBlock) != reply_block_size) + { + GNUNET_break_op (0); + return GNUNET_BLOCK_REPLY_INVALID; + } + rba = reply_block; + if (ntohl (rba->purpose.size) != + sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) + + sizeof(struct GNUNET_TIME_AbsoluteNBO) + + sizeof(struct GNUNET_HashCode)) + { + GNUNET_break_op (0); + return GNUNET_BLOCK_REPLY_INVALID; + } + GNUNET_CRYPTO_hash (reply_block, + reply_block_size, + &chash); + if (GNUNET_YES == + GNUNET_BLOCK_GROUP_bf_test_and_set (group, + &chash)) + return GNUNET_BLOCK_REPLY_OK_DUPLICATE; + return GNUNET_BLOCK_REPLY_OK_MORE; + } + default: + GNUNET_break (0); + return GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED; + } + return GNUNET_BLOCK_REPLY_OK_MORE; +} + + /** * Function called to obtain the key for a block. * @@ -339,7 +555,7 @@ block_plugin_regex_evaluate (void *cls, * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported * (or if extracting a key from a block of this type does not work) */ -static int +static enum GNUNET_GenericReturnValue block_plugin_regex_get_key (void *cls, enum GNUNET_BLOCK_Type type, const void *block, @@ -350,14 +566,14 @@ block_plugin_regex_get_key (void *cls, { case GNUNET_BLOCK_TYPE_REGEX: if (GNUNET_OK != - REGEX_BLOCK_get_key (block, block_size, + REGEX_BLOCK_get_key (block, + block_size, key)) { GNUNET_break_op (0); return GNUNET_NO; } return GNUNET_OK; - case GNUNET_BLOCK_TYPE_REGEX_ACCEPT: if (sizeof(struct RegexAcceptBlock) != block_size) { @@ -366,7 +582,6 @@ block_plugin_regex_get_key (void *cls, } *key = ((struct RegexAcceptBlock *) block)->key; return GNUNET_OK; - default: GNUNET_break (0); return GNUNET_SYSERR; @@ -380,7 +595,7 @@ block_plugin_regex_get_key (void *cls, void * libgnunet_plugin_block_regex_init (void *cls) { - static enum GNUNET_BLOCK_Type types[] = { + static const enum GNUNET_BLOCK_Type types[] = { GNUNET_BLOCK_TYPE_REGEX, GNUNET_BLOCK_TYPE_REGEX_ACCEPT, GNUNET_BLOCK_TYPE_ANY /* end of list */ @@ -390,6 +605,9 @@ libgnunet_plugin_block_regex_init (void *cls) api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); api->evaluate = &block_plugin_regex_evaluate; api->get_key = &block_plugin_regex_get_key; + api->check_query = &block_plugin_regex_check_query; + api->check_block = &block_plugin_regex_check_block; + api->check_reply = &block_plugin_regex_check_reply; api->create_group = &block_plugin_regex_create_group; api->types = types; return api; diff --git a/src/revocation/gnunet-service-revocation.c b/src/revocation/gnunet-service-revocation.c index 5fe0ade98..4494ade83 100644 --- a/src/revocation/gnunet-service-revocation.c +++ b/src/revocation/gnunet-service-revocation.c @@ -169,14 +169,16 @@ new_peer_entry (const struct GNUNET_PeerIdentity *peer) * @return #GNUNET_YES if the message is verified * #GNUNET_NO if the key/signature don't verify */ -static int +static enum GNUNET_GenericReturnValue verify_revoke_message (const struct RevokeMessage *rm) { - struct GNUNET_REVOCATION_PowP *pow = (struct GNUNET_REVOCATION_PowP *) &rm[1]; - if (GNUNET_YES != GNUNET_REVOCATION_check_pow (pow, - (unsigned - int) revocation_work_required, - epoch_duration)) + const struct GNUNET_REVOCATION_PowP *pow + = (const struct GNUNET_REVOCATION_PowP *) &rm[1]; + + if (GNUNET_YES != + GNUNET_REVOCATION_check_pow (pow, + (unsigned int) revocation_work_required, + epoch_duration)) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Proof of work invalid!\n"); @@ -263,7 +265,7 @@ handle_query_message (void *cls, * @param value our `struct PeerEntry` for the neighbour * @return #GNUNET_OK (continue to iterate) */ -static int +static enum GNUNET_GenericReturnValue do_flood (void *cls, const struct GNUNET_PeerIdentity *target, void *value) @@ -278,10 +280,12 @@ do_flood (void *cls, but we have no direct CORE connection for flooding */ e = GNUNET_MQ_msg_extra (cp, - htonl (rm->pow_size), - GNUNET_MESSAGE_TYPE_REVOCATION_REVOKE); + htonl (rm->pow_size), + GNUNET_MESSAGE_TYPE_REVOCATION_REVOKE); *cp = *rm; - memcpy (&cp[1], &rm[1], htonl (rm->pow_size)); + memcpy (&cp[1], + &rm[1], + htonl (rm->pow_size)); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Flooding revocation to `%s'\n", GNUNET_i2s (target)); @@ -300,17 +304,18 @@ do_flood (void *cls, * @return #GNUNET_OK on success, #GNUNET_NO if we encountered an error, * #GNUNET_SYSERR if the message was malformed */ -static int +static enum GNUNET_GenericReturnValue publicize_rm (const struct RevokeMessage *rm) { struct RevokeMessage *cp; struct GNUNET_HashCode hc; struct GNUNET_SETU_Element e; ssize_t pklen; - const struct GNUNET_IDENTITY_PublicKey *pk; + const struct GNUNET_REVOCATION_PowP *pow + = (const struct GNUNET_REVOCATION_PowP *) &rm[1]; + const struct GNUNET_IDENTITY_PublicKey *pk + = (const struct GNUNET_IDENTITY_PublicKey *) &pow[1]; - struct GNUNET_REVOCATION_PowP *pow = (struct GNUNET_REVOCATION_PowP *) &rm[1]; - pk = (const struct GNUNET_IDENTITY_PublicKey *) &pow[1]; pklen = GNUNET_IDENTITY_key_get_length (pk); if (0 > pklen) { diff --git a/src/revocation/plugin_block_revocation.c b/src/revocation/plugin_block_revocation.c index da5882d59..3beae60bb 100644 --- a/src/revocation/plugin_block_revocation.c +++ b/src/revocation/plugin_block_revocation.c @@ -33,19 +33,6 @@ #define DEBUG_REVOCATION GNUNET_EXTRA_LOGGING -/** - * Number of bits we set per entry in the bloomfilter. - * Do not change! - */ -#define BLOOMFILTER_K 16 - - -/** - * How big is the BF we use for DHT blocks? - */ -#define REVOCATION_BF_SIZE 8 - - /** * Context used inside the plugin. */ @@ -56,54 +43,6 @@ struct InternalContext }; -/** - * Create a new block group. - * - * @param ctx block context in which the block group is created - * @param type type of the block for which we are creating the group - * @param nonce random value used to seed the group creation - * @param raw_data optional serialized prior state of the group, NULL if unavailable/fresh - * @param raw_data_size number of bytes in @a raw_data, 0 if unavailable/fresh - * @param va variable arguments specific to @a type - * @return block group handle, NULL if block groups are not supported - * by this @a type of block (this is not an error) - */ -static struct GNUNET_BLOCK_Group * -block_plugin_revocation_create_group (void *cls, - enum GNUNET_BLOCK_Type type, - uint32_t nonce, - const void *raw_data, - size_t raw_data_size, - va_list va) -{ - unsigned int bf_size; - const char *guard; - - guard = va_arg (va, const char *); - if (0 == strcmp (guard, - "seen-set-size")) - bf_size = GNUNET_BLOCK_GROUP_compute_bloomfilter_size (va_arg (va, unsigned - int), - BLOOMFILTER_K); - else if (0 == strcmp (guard, - "filter-size")) - bf_size = va_arg (va, unsigned int); - else - { - GNUNET_break (0); - bf_size = REVOCATION_BF_SIZE; - } - GNUNET_break (NULL == va_arg (va, const char *)); - return GNUNET_BLOCK_GROUP_bf_create (cls, - bf_size, - BLOOMFILTER_K, - type, - nonce, - raw_data, - raw_data_size); -} - - /** * Function called to validate a reply or a request. For * request evaluation, simply pass "NULL" for the reply_block. @@ -133,7 +72,6 @@ block_plugin_revocation_evaluate (void *cls, size_t reply_block_size) { struct InternalContext *ic = cls; - struct GNUNET_HashCode chash; ssize_t pklen; const struct RevokeMessage *rm = reply_block; @@ -160,14 +98,134 @@ block_plugin_revocation_evaluate (void *cls, GNUNET_break_op (0); return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; } - GNUNET_CRYPTO_hash (pk, - pklen, - &chash); - if (GNUNET_YES == - GNUNET_BLOCK_GROUP_bf_test_and_set (group, - &chash)) - return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE; - return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; + return GNUNET_BLOCK_EVALUATION_OK_LAST; +} + + +/** + * Function called to validate a query. + * + * @param cls closure + * @param ctx block context + * @param type block type + * @param query original query (hash) + * @param xquery extrended query data (can be NULL, depending on type) + * @param xquery_size number of bytes in @a xquery + * @return #GNUNET_OK if the query is fine, #GNUNET_NO if not + */ +static enum GNUNET_GenericReturnValue +block_plugin_revocation_check_query (void *cls, + enum GNUNET_BLOCK_Type type, + const struct GNUNET_HashCode *query, + const void *xquery, + size_t xquery_size) +{ + (void) cls; + (void) query; + (void) xquery; + if (GNUNET_BLOCK_TYPE_REVOCATION != type) + return GNUNET_SYSERR; + if (0 != xquery_size) + return GNUNET_NO; + return GNUNET_OK; +} + + +/** + * Function called to validate a block for storage. + * + * @param cls closure + * @param type block type + * @param query key for the block (hash), must match exactly + * @param block block data to validate + * @param block_size number of bytes in @a block + * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not + */ +static enum GNUNET_GenericReturnValue +block_plugin_revocation_check_block (void *cls, + enum GNUNET_BLOCK_Type type, + const struct GNUNET_HashCode *query, + const void *block, + size_t block_size) +{ + struct InternalContext *ic = cls; + const struct RevokeMessage *rm = block; + const struct GNUNET_REVOCATION_PowP *pow + = (const struct GNUNET_REVOCATION_PowP *) &rm[1]; + struct GNUNET_IDENTITY_PublicKey pk; + ssize_t pklen; + size_t left; + + if (GNUNET_BLOCK_TYPE_REVOCATION != type) + return GNUNET_SYSERR; + if (block_size < sizeof(*rm) + sizeof(*pow)) + { + GNUNET_break_op (0); + return GNUNET_NO; + } + if (block_size != sizeof(*rm) + ntohl (rm->pow_size)) + { + GNUNET_break_op (0); + return GNUNET_NO; + } + left = block_size - sizeof (*rm) - sizeof (*pow); + pklen = GNUNET_IDENTITY_read_key_from_buffer (&pk, + &pow[1], + left); + if (0 > pklen) + { + GNUNET_break_op (0); + return GNUNET_NO; + } + if (GNUNET_YES != + GNUNET_REVOCATION_check_pow (pow, + ic->matching_bits, + ic->epoch_duration)) + { + GNUNET_break_op (0); + return GNUNET_NO; + } + return GNUNET_OK; +} + + +/** + * Function called to validate a reply to a request. Note that it is assumed + * that the reply has already been matched to the key (and signatures checked) + * as it would be done with the GetKeyFunction and the + * BlockEvaluationFunction. + * + * @param cls closure + * @param type block type + * @param group which block group to use for evaluation + * @param query original query (hash) + * @param xquery extrended query data (can be NULL, depending on type) + * @param xquery_size number of bytes in @a xquery + * @param reply_block response to validate + * @param reply_block_size number of bytes in @a reply_block + * @return characterization of result + */ +static enum GNUNET_BLOCK_ReplyEvaluationResult +block_plugin_revocation_check_reply ( + void *cls, + enum GNUNET_BLOCK_Type type, + struct GNUNET_BLOCK_Group *group, + const struct GNUNET_HashCode *query, + const void *xquery, + size_t xquery_size, + const void *reply_block, + size_t reply_block_size) +{ + (void) cls; + (void) group; + (void) query; + (void) xquery; + (void) xquery_size; + (void) reply_block; + (void) reply_block_size; + if (GNUNET_BLOCK_TYPE_REVOCATION != type) + return GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED; + return GNUNET_BLOCK_REPLY_OK_LAST; } @@ -182,7 +240,7 @@ block_plugin_revocation_evaluate (void *cls, * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported * (or if extracting a key from a block of this type does not work) */ -static int +static enum GNUNET_GenericReturnValue block_plugin_revocation_get_key (void *cls, enum GNUNET_BLOCK_Type type, const void *block, @@ -190,24 +248,35 @@ block_plugin_revocation_get_key (void *cls, struct GNUNET_HashCode *key) { const struct RevokeMessage *rm = block; - ssize_t ksize; + const struct GNUNET_REVOCATION_PowP *pow + = (const struct GNUNET_REVOCATION_PowP *) &rm[1]; + struct GNUNET_IDENTITY_PublicKey pk; + ssize_t pklen; + size_t left; - if (block_size <= sizeof(*rm)) + if (GNUNET_BLOCK_TYPE_REVOCATION != type) + return GNUNET_SYSERR; + if (block_size < sizeof(*rm) + sizeof(*pow)) { GNUNET_break_op (0); - return GNUNET_SYSERR; + return GNUNET_NO; } - struct GNUNET_REVOCATION_PowP *pow = (struct GNUNET_REVOCATION_PowP *) &rm[1]; - const struct GNUNET_IDENTITY_PublicKey *pk; - pk = (const struct GNUNET_IDENTITY_PublicKey *) &pow[1]; - ksize = GNUNET_IDENTITY_key_get_length (pk); - if (0 > ksize) + if (block_size != sizeof(*rm) + ntohl (rm->pow_size)) { GNUNET_break_op (0); - return GNUNET_SYSERR; + return GNUNET_NO; } - GNUNET_CRYPTO_hash (pk, - ksize, + left = block_size - sizeof (*rm) - sizeof (*pow); + pklen = GNUNET_IDENTITY_read_key_from_buffer (&pk, + &pow[1], + left); + if (0 > pklen) + { + GNUNET_break_op (0); + return GNUNET_NO; + } + GNUNET_CRYPTO_hash (&pow[1], + pklen, key); return GNUNET_OK; } @@ -221,8 +290,8 @@ block_plugin_revocation_get_key (void *cls, void * libgnunet_plugin_block_revocation_init (void *cls) { - static enum GNUNET_BLOCK_Type types[] = { - GNUNET_BLOCK_TYPE_REVOCATION, + static const enum GNUNET_BLOCK_Type types[] = { + GNUNET_BLOCK_TYPE_REVOCATION, GNUNET_BLOCK_TYPE_ANY /* end of list */ }; const struct GNUNET_CONFIGURATION_Handle *cfg = cls; @@ -247,7 +316,10 @@ libgnunet_plugin_block_revocation_init (void *cls) api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); api->evaluate = &block_plugin_revocation_evaluate; api->get_key = &block_plugin_revocation_get_key; - api->create_group = &block_plugin_revocation_create_group; + api->check_query = &block_plugin_revocation_check_query; + api->check_block = &block_plugin_revocation_check_block; + api->check_reply = &block_plugin_revocation_check_reply; + api->create_group = NULL; api->types = types; ic = GNUNET_new (struct InternalContext); ic->matching_bits = (unsigned int) matching_bits; diff --git a/src/set/plugin_block_set_test.c b/src/set/plugin_block_set_test.c index 1de086092..3d66831bb 100644 --- a/src/set/plugin_block_set_test.c +++ b/src/set/plugin_block_set_test.c @@ -65,6 +65,87 @@ block_plugin_set_test_evaluate (void *cls, } +/** + * Function called to validate a query. + * + * @param cls closure + * @param ctx block context + * @param type block type + * @param query original query (hash) + * @param xquery extrended query data (can be NULL, depending on type) + * @param xquery_size number of bytes in @a xquery + * @return #GNUNET_OK if the query is fine, #GNUNET_NO if not + */ +static enum GNUNET_GenericReturnValue +block_plugin_set_test_check_query (void *cls, + enum GNUNET_BLOCK_Type type, + const struct GNUNET_HashCode *query, + const void *xquery, + size_t xquery_size) +{ + return GNUNET_OK; +} + + +/** + * Function called to validate a block for storage. + * + * @param cls closure + * @param type block type + * @param query key for the block (hash), must match exactly + * @param block block data to validate + * @param block_size number of bytes in @a block + * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not + */ +static enum GNUNET_GenericReturnValue +block_plugin_set_test_check_block (void *cls, + enum GNUNET_BLOCK_Type type, + const struct GNUNET_HashCode *query, + const void *block, + size_t block_size) +{ + if ((NULL == block) || + (0 == block_size) || + (0 != ((char *) block)[0])) + return GNUNET_SYSERR; + return GNUNET_OK; +} + + +/** + * Function called to validate a reply to a request. Note that it is assumed + * that the reply has already been matched to the key (and signatures checked) + * as it would be done with the GetKeyFunction and the + * BlockEvaluationFunction. + * + * @param cls closure + * @param type block type + * @param group which block group to use for evaluation + * @param query original query (hash) + * @param xquery extrended query data (can be NULL, depending on type) + * @param xquery_size number of bytes in @a xquery + * @param reply_block response to validate + * @param reply_block_size number of bytes in @a reply_block + * @return characterization of result + */ +static enum GNUNET_BLOCK_ReplyEvaluationResult +block_plugin_set_test_check_reply (void *cls, + enum GNUNET_BLOCK_Type type, + struct GNUNET_BLOCK_Group *group, + const struct GNUNET_HashCode *query, + const void *xquery, + size_t xquery_size, + const void *reply_block, + size_t reply_block_size) +{ + if ((NULL == reply_block) || + (0 == reply_block_size) || + (0 != ((char *) reply_block)[0])) + return GNUNET_BLOCK_REPLY_INVALID; + return GNUNET_BLOCK_REPLY_OK_MORE; +} + + /** * Function called to obtain the key for a block. * @@ -76,7 +157,7 @@ block_plugin_set_test_evaluate (void *cls, * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported * (or if extracting a key from a block of this type does not work) */ -static int +static enum GNUNET_GenericReturnValue block_plugin_set_test_get_key (void *cls, enum GNUNET_BLOCK_Type type, const void *block, @@ -93,7 +174,7 @@ block_plugin_set_test_get_key (void *cls, void * libgnunet_plugin_block_set_test_init (void *cls) { - static enum GNUNET_BLOCK_Type types[] = { + static const enum GNUNET_BLOCK_Type types[] = { GNUNET_BLOCK_TYPE_SET_TEST, GNUNET_BLOCK_TYPE_ANY /* end of list */ }; @@ -102,6 +183,9 @@ libgnunet_plugin_block_set_test_init (void *cls) api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); api->evaluate = &block_plugin_set_test_evaluate; api->get_key = &block_plugin_set_test_get_key; + api->check_query = &block_plugin_set_test_check_query; + api->check_block = &block_plugin_set_test_check_block; + api->check_reply = &block_plugin_set_test_check_reply; api->types = types; return api; } diff --git a/src/seti/plugin_block_seti_test.c b/src/seti/plugin_block_seti_test.c index 55cf31bea..af86e1af6 100644 --- a/src/seti/plugin_block_seti_test.c +++ b/src/seti/plugin_block_seti_test.c @@ -65,6 +65,87 @@ block_plugin_seti_test_evaluate (void *cls, } +/** + * Function called to validate a query. + * + * @param cls closure + * @param ctx block context + * @param type block type + * @param query original query (hash) + * @param xquery extrended query data (can be NULL, depending on type) + * @param xquery_size number of bytes in @a xquery + * @return #GNUNET_OK if the query is fine, #GNUNET_NO if not + */ +static enum GNUNET_GenericReturnValue +block_plugin_seti_test_check_query (void *cls, + enum GNUNET_BLOCK_Type type, + const struct GNUNET_HashCode *query, + const void *xquery, + size_t xquery_size) +{ + return GNUNET_OK; +} + + +/** + * Function called to validate a block for storage. + * + * @param cls closure + * @param type block type + * @param query key for the block (hash), must match exactly + * @param block block data to validate + * @param block_size number of bytes in @a block + * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not + */ +static enum GNUNET_GenericReturnValue +block_plugin_seti_test_check_block (void *cls, + enum GNUNET_BLOCK_Type type, + const struct GNUNET_HashCode *query, + const void *block, + size_t block_size) +{ + if ((NULL == block) || + (0 == block_size) || + (0 != ((char *) block)[0])) + return GNUNET_SYSERR; + return GNUNET_OK; +} + + +/** + * Function called to validate a reply to a request. Note that it is assumed + * that the reply has already been matched to the key (and signatures checked) + * as it would be done with the GetKeyFunction and the + * BlockEvaluationFunction. + * + * @param cls closure + * @param type block type + * @param group which block group to use for evaluation + * @param query original query (hash) + * @param xquery extrended query data (can be NULL, depending on type) + * @param xquery_size number of bytes in @a xquery + * @param reply_block response to validate + * @param reply_block_size number of bytes in @a reply_block + * @return characterization of result + */ +static enum GNUNET_BLOCK_ReplyEvaluationResult +block_plugin_seti_test_check_reply (void *cls, + enum GNUNET_BLOCK_Type type, + struct GNUNET_BLOCK_Group *group, + const struct GNUNET_HashCode *query, + const void *xquery, + size_t xquery_size, + const void *reply_block, + size_t reply_block_size) +{ + if ( (NULL == reply_block) || + (0 == reply_block_size) || + (0 != ((char *) reply_block)[0]) ) + return GNUNET_BLOCK_REPLY_INVALID; + return GNUNET_BLOCK_REPLY_OK_MORE; +} + + /** * Function called to obtain the key for a block. * @@ -76,7 +157,7 @@ block_plugin_seti_test_evaluate (void *cls, * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported * (or if extracting a key from a block of this type does not work) */ -static int +static enum GNUNET_GenericReturnValue block_plugin_seti_test_get_key (void *cls, enum GNUNET_BLOCK_Type type, const void *block, @@ -102,6 +183,9 @@ libgnunet_plugin_block_seti_test_init (void *cls) api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); api->evaluate = &block_plugin_seti_test_evaluate; api->get_key = &block_plugin_seti_test_get_key; + api->check_query = &block_plugin_seti_test_check_query; + api->check_block = &block_plugin_seti_test_check_block; + api->check_reply = &block_plugin_seti_test_check_reply; api->types = types; return api; } diff --git a/src/setu/plugin_block_setu_test.c b/src/setu/plugin_block_setu_test.c index fd0c8a680..9872bba39 100644 --- a/src/setu/plugin_block_setu_test.c +++ b/src/setu/plugin_block_setu_test.c @@ -65,6 +65,87 @@ block_plugin_setu_test_evaluate (void *cls, } +/** + * Function called to validate a query. + * + * @param cls closure + * @param ctx block context + * @param type block type + * @param query original query (hash) + * @param xquery extrended query data (can be NULL, depending on type) + * @param xquery_size number of bytes in @a xquery + * @return #GNUNET_OK if the query is fine, #GNUNET_NO if not + */ +static enum GNUNET_GenericReturnValue +block_plugin_setu_test_check_query (void *cls, + enum GNUNET_BLOCK_Type type, + const struct GNUNET_HashCode *query, + const void *xquery, + size_t xquery_size) +{ + return GNUNET_OK; +} + + +/** + * Function called to validate a block for storage. + * + * @param cls closure + * @param type block type + * @param query key for the block (hash), must match exactly + * @param block block data to validate + * @param block_size number of bytes in @a block + * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not + */ +static enum GNUNET_GenericReturnValue +block_plugin_setu_test_check_block (void *cls, + enum GNUNET_BLOCK_Type type, + const struct GNUNET_HashCode *query, + const void *block, + size_t block_size) +{ + if ( (NULL == block) || + (0 == block_size) || + (0 != ((char *) block)[0]) ) + return GNUNET_SYSERR; + return GNUNET_OK; +} + + +/** + * Function called to validate a reply to a request. Note that it is assumed + * that the reply has already been matched to the key (and signatures checked) + * as it would be done with the GetKeyFunction and the + * BlockEvaluationFunction. + * + * @param cls closure + * @param type block type + * @param group which block group to use for evaluation + * @param query original query (hash) + * @param xquery extrended query data (can be NULL, depending on type) + * @param xquery_size number of bytes in @a xquery + * @param reply_block response to validate + * @param reply_block_size number of bytes in @a reply_block + * @return characterization of result + */ +static enum GNUNET_BLOCK_ReplyEvaluationResult +block_plugin_setu_test_check_reply (void *cls, + enum GNUNET_BLOCK_Type type, + struct GNUNET_BLOCK_Group *group, + const struct GNUNET_HashCode *query, + const void *xquery, + size_t xquery_size, + const void *reply_block, + size_t reply_block_size) +{ + if ( (NULL == reply_block) || + (0 == reply_block_size) || + (0 != ((char *) reply_block)[0]) ) + return GNUNET_BLOCK_REPLY_INVALID; + return GNUNET_BLOCK_REPLY_OK_MORE; +} + + /** * Function called to obtain the key for a block. * @@ -76,7 +157,7 @@ block_plugin_setu_test_evaluate (void *cls, * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported * (or if extracting a key from a block of this type does not work) */ -static int +static enum GNUNET_GenericReturnValue block_plugin_setu_test_get_key (void *cls, enum GNUNET_BLOCK_Type type, const void *block, @@ -102,6 +183,9 @@ libgnunet_plugin_block_setu_test_init (void *cls) api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); api->evaluate = &block_plugin_setu_test_evaluate; api->get_key = &block_plugin_setu_test_get_key; + api->check_query = &block_plugin_setu_test_check_query; + api->check_block = &block_plugin_setu_test_check_block; + api->check_reply = &block_plugin_setu_test_check_reply; api->types = types; return api; } -- cgit v1.2.3