diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-08-13 16:40:41 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-08-13 16:40:41 +0000 |
commit | ee32003b7e606767f9b89715cb956d863fe067d9 (patch) | |
tree | eca3af3ac8a6c0852352861a69ea9e919343b03c /src/gns/plugin_block_gns.c | |
parent | 597dc76d129d291cd9dbe2fbd6914e54ae0ef118 (diff) | |
download | gnunet-ee32003b7e606767f9b89715cb956d863fe067d9.tar.gz gnunet-ee32003b7e606767f9b89715cb956d863fe067d9.zip |
-working on new, simplified GNS API
Diffstat (limited to 'src/gns/plugin_block_gns.c')
-rw-r--r-- | src/gns/plugin_block_gns.c | 201 |
1 files changed, 57 insertions, 144 deletions
diff --git a/src/gns/plugin_block_gns.c b/src/gns/plugin_block_gns.c index 4d12f02df..22e3d61fd 100644 --- a/src/gns/plugin_block_gns.c +++ b/src/gns/plugin_block_gns.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet | 2 | This file is part of GNUnet |
3 | (C) 2010, 2012 Christian Grothoff (and other contributing authors) | 3 | (C) 2010-2013 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -27,7 +27,6 @@ | |||
27 | #include "platform.h" | 27 | #include "platform.h" |
28 | #include "gnunet_block_plugin.h" | 28 | #include "gnunet_block_plugin.h" |
29 | #include "gnunet_namestore_service.h" | 29 | #include "gnunet_namestore_service.h" |
30 | #include "block_gns.h" | ||
31 | #include "gnunet_signatures.h" | 30 | #include "gnunet_signatures.h" |
32 | #include "gns_common.h" | 31 | #include "gns_common.h" |
33 | 32 | ||
@@ -47,49 +46,32 @@ | |||
47 | * @param cls closure | 46 | * @param cls closure |
48 | * @param type block type | 47 | * @param type block type |
49 | * @param query original query (hash) | 48 | * @param query original query (hash) |
50 | * @param bf pointer to bloom filter associated with query; possibly updated (!) | 49 | * @param bf pointer to bloom filter associated with @a query; possibly updated (!) |
51 | * @param bf_mutator mutation value for bf | 50 | * @param bf_mutator mutation value for @a bf |
52 | * @param xquery extrended query data (can be NULL, depending on type) | 51 | * @param xquery extrended query data (can be NULL, depending on @a type) |
53 | * @param xquery_size number of bytes in xquery | 52 | * @param xquery_size number of bytes in @a xquery |
54 | * @param reply_block response to validate | 53 | * @param reply_block response to validate |
55 | * @param reply_block_size number of bytes in reply block | 54 | * @param reply_block_size number of bytes in @a reply_block |
56 | * @return characterization of result | 55 | * @return characterization of result |
57 | */ | 56 | */ |
58 | static enum GNUNET_BLOCK_EvaluationResult | 57 | static enum GNUNET_BLOCK_EvaluationResult |
59 | block_plugin_gns_evaluate (void *cls, enum GNUNET_BLOCK_Type type, | 58 | block_plugin_gns_evaluate (void *cls, enum GNUNET_BLOCK_Type type, |
60 | const struct GNUNET_HashCode * query, | 59 | const struct GNUNET_HashCode *query, |
61 | struct GNUNET_CONTAINER_BloomFilter **bf, | 60 | struct GNUNET_CONTAINER_BloomFilter **bf, |
62 | int32_t bf_mutator, const void *xquery, | 61 | int32_t bf_mutator, const void *xquery, |
63 | size_t xquery_size, const void *reply_block, | 62 | size_t xquery_size, const void *reply_block, |
64 | size_t reply_block_size) | 63 | size_t reply_block_size) |
65 | { | 64 | { |
66 | const struct GNSNameRecordBlock *nrb; | 65 | const struct GNUNET_NAMESTORE_Block *block; |
67 | const char* name; | 66 | struct GNUNET_HashCode h; |
68 | const char *name_end; | ||
69 | const char *rd_data; | ||
70 | struct GNUNET_HashCode query_key; | ||
71 | struct GNUNET_HashCode mhash; | ||
72 | struct GNUNET_HashCode chash; | 67 | struct GNUNET_HashCode chash; |
73 | struct GNUNET_CRYPTO_ShortHashCode pkey_hash; | 68 | struct GNUNET_HashCode mhash; |
74 | struct GNUNET_CRYPTO_HashAsciiEncoded xor_exp; | ||
75 | struct GNUNET_CRYPTO_HashAsciiEncoded xor_got; | ||
76 | uint32_t rd_count; | ||
77 | size_t rd_len; | ||
78 | size_t name_len; | ||
79 | uint32_t record_xquery; | ||
80 | unsigned int record_match; | ||
81 | |||
82 | //GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "RB SIZE %d\n", reply_block_size); | ||
83 | 69 | ||
84 | if (type != GNUNET_BLOCK_TYPE_GNS_NAMERECORD) | 70 | if (type != GNUNET_BLOCK_TYPE_GNS_NAMERECORD) |
85 | return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; | 71 | return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; |
86 | if (reply_block == NULL) | 72 | if (NULL == reply_block) |
87 | { | 73 | { |
88 | /** | 74 | if (0 != xquery_size) |
89 | * check if request is valid | ||
90 | * FIXME we could check for the record types here | ||
91 | **/ | ||
92 | if (xquery_size < sizeof(uint32_t)) | ||
93 | { | 75 | { |
94 | GNUNET_break_op (0); | 76 | GNUNET_break_op (0); |
95 | return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID; | 77 | return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID; |
@@ -98,111 +80,47 @@ block_plugin_gns_evaluate (void *cls, enum GNUNET_BLOCK_Type type, | |||
98 | } | 80 | } |
99 | 81 | ||
100 | /* this is a reply */ | 82 | /* this is a reply */ |
101 | 83 | if (reply_block_size < sizeof (struct GNUNET_NAMESTORE_Block)) | |
102 | nrb = (const struct GNSNameRecordBlock *)reply_block; | ||
103 | name = (const char*) &nrb[1]; | ||
104 | name_end = memchr (name, 0, reply_block_size - sizeof (struct GNSNameRecordBlock)); | ||
105 | if (NULL == name_end) | ||
106 | { | ||
107 | GNUNET_break_op (0); | ||
108 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
109 | } | ||
110 | name_len = (name_end - name) + 1; | ||
111 | GNUNET_CRYPTO_short_hash (&nrb->public_key, | ||
112 | sizeof(nrb->public_key), | ||
113 | &pkey_hash); | ||
114 | GNUNET_GNS_get_key_for_record (name, &pkey_hash, &query_key); | ||
115 | |||
116 | GNUNET_CRYPTO_hash_to_enc (&query_key, &xor_exp); | ||
117 | GNUNET_CRYPTO_hash_to_enc (query, &xor_got); | ||
118 | |||
119 | //GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
120 | // "BLOCK_TEST for %s got %s expected %s\n", | ||
121 | // name, (char*) &xor_got, (char*) &xor_exp); | ||
122 | |||
123 | /* Check query key against public key */ | ||
124 | if (0 != GNUNET_CRYPTO_hash_cmp(query, &query_key)) | ||
125 | { | ||
126 | GNUNET_break_op (0); | ||
127 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
128 | } | ||
129 | |||
130 | record_match = 0; | ||
131 | rd_count = ntohl(nrb->rd_count); | ||
132 | rd_data = &name[name_len]; | ||
133 | rd_len = reply_block_size - (name_len | ||
134 | + sizeof(struct GNSNameRecordBlock)); | ||
135 | { | ||
136 | struct GNUNET_NAMESTORE_RecordData rd[rd_count]; | ||
137 | unsigned int i; | ||
138 | uint64_t exp = UINT64_MAX; | ||
139 | struct GNUNET_TIME_Absolute et = GNUNET_TIME_UNIT_FOREVER_ABS; | ||
140 | |||
141 | if (GNUNET_SYSERR == GNUNET_NAMESTORE_records_deserialize (rd_len, | ||
142 | rd_data, | ||
143 | rd_count, | ||
144 | rd)) | ||
145 | { | 84 | { |
146 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 85 | GNUNET_break_op (0); |
147 | "Data invalid (%d bytes, %d records)\n", rd_len, rd_count); | ||
148 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | 86 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; |
149 | } | 87 | } |
150 | 88 | block = reply_block; | |
151 | if (xquery_size < sizeof(uint32_t)) | 89 | if (ntohs (block->purpose.size) + sizeof (struct GNUNET_CRYPTO_EccSignature) + sizeof (struct GNUNET_CRYPTO_EccPublicKey) != |
152 | record_xquery = 0; | 90 | reply_block_size) |
153 | else | 91 | { |
154 | record_xquery = ntohl(*((uint32_t*)xquery)); | 92 | GNUNET_break_op (0); |
155 | 93 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | |
156 | for (i=0; i<rd_count; i++) | ||
157 | { | ||
158 | GNUNET_break (0 == (rd[i].flags & GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION)); | ||
159 | exp = GNUNET_MIN (exp, rd[i].expiration_time); | ||
160 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
161 | "Got record of size %d expiration %u\n", | ||
162 | rd[i].data_size, rd[i].expiration_time); | ||
163 | if ((record_xquery != 0) | ||
164 | && (rd[i].record_type == record_xquery)) | ||
165 | { | ||
166 | record_match++; | ||
167 | } | ||
168 | } | 94 | } |
169 | et.abs_value_us = exp; | 95 | GNUNET_CRYPTO_hash (&block->derived_key, |
170 | 96 | sizeof (block->derived_key), | |
171 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 97 | &h); |
172 | "Verifying signature of %d records for name %s with expiration of %s\n", | 98 | if (0 != memcmp (&h, query, sizeof (struct GNUNET_HashCode))) |
173 | rd_count, name, | ||
174 | GNUNET_STRINGS_absolute_time_to_string (et)); | ||
175 | |||
176 | if (GNUNET_OK != | ||
177 | GNUNET_NAMESTORE_verify_signature (&nrb->public_key, | ||
178 | et, | ||
179 | name, | ||
180 | rd_count, | ||
181 | rd, | ||
182 | &nrb->signature)) | ||
183 | { | 99 | { |
184 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
185 | "Signature invalid for %s\n", name); | ||
186 | GNUNET_break_op (0); | 100 | GNUNET_break_op (0); |
187 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | 101 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; |
188 | } | 102 | } |
189 | } | 103 | if (GNUNET_OK != |
190 | 104 | GNUNET_NAMESTORE_block_verify (block)) | |
191 | if (NULL != bf) | ||
192 | { | ||
193 | GNUNET_CRYPTO_hash (reply_block, reply_block_size, &chash); | ||
194 | GNUNET_BLOCK_mingle_hash (&chash, bf_mutator, &mhash); | ||
195 | if (NULL != *bf) | ||
196 | { | 105 | { |
197 | if (GNUNET_YES == GNUNET_CONTAINER_bloomfilter_test(*bf, &mhash)) | 106 | GNUNET_break_op (0); |
198 | return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE; | 107 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; |
199 | } | 108 | } |
200 | else | 109 | if (NULL != bf) |
201 | { | 110 | { |
202 | *bf = GNUNET_CONTAINER_bloomfilter_init(NULL, 8, BLOOMFILTER_K); | 111 | GNUNET_CRYPTO_hash (reply_block, reply_block_size, &chash); |
112 | GNUNET_BLOCK_mingle_hash (&chash, bf_mutator, &mhash); | ||
113 | if (NULL != *bf) | ||
114 | { | ||
115 | if (GNUNET_YES == GNUNET_CONTAINER_bloomfilter_test(*bf, &mhash)) | ||
116 | return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE; | ||
117 | } | ||
118 | else | ||
119 | { | ||
120 | *bf = GNUNET_CONTAINER_bloomfilter_init(NULL, 8, BLOOMFILTER_K); | ||
121 | } | ||
122 | GNUNET_CONTAINER_bloomfilter_add(*bf, &mhash); | ||
203 | } | 123 | } |
204 | GNUNET_CONTAINER_bloomfilter_add(*bf, &mhash); | ||
205 | } | ||
206 | return GNUNET_BLOCK_EVALUATION_OK_MORE; | 124 | return GNUNET_BLOCK_EVALUATION_OK_MORE; |
207 | } | 125 | } |
208 | 126 | ||
@@ -212,35 +130,30 @@ block_plugin_gns_evaluate (void *cls, enum GNUNET_BLOCK_Type type, | |||
212 | * | 130 | * |
213 | * @param cls closure | 131 | * @param cls closure |
214 | * @param type block type | 132 | * @param type block type |
215 | * @param block block to get the key for | 133 | * @param reply_block block to get the key for |
216 | * @param block_size number of bytes in block | 134 | * @param reply_block_size number of bytes in @a reply_block |
217 | * @param key set to the key (query) for the given block | 135 | * @param key set to the key (query) for the given block |
218 | * @return GNUNET_OK on success, GNUNET_SYSERR if type not supported | 136 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported |
219 | * (or if extracting a key from a block of this type does not work) | 137 | * (or if extracting a key from a block of this type does not work) |
220 | */ | 138 | */ |
221 | static int | 139 | static int |
222 | block_plugin_gns_get_key (void *cls, enum GNUNET_BLOCK_Type type, | 140 | block_plugin_gns_get_key (void *cls, enum GNUNET_BLOCK_Type type, |
223 | const void *block, size_t block_size, | 141 | const void *reply_block, size_t reply_block_size, |
224 | struct GNUNET_HashCode * key) | 142 | struct GNUNET_HashCode *key) |
225 | { | 143 | { |
226 | struct GNUNET_CRYPTO_ShortHashCode pkey_hash; | 144 | const struct GNUNET_NAMESTORE_Block *block; |
227 | const struct GNSNameRecordBlock *nrb = block; | ||
228 | const char *name; | ||
229 | 145 | ||
230 | if (type != GNUNET_BLOCK_TYPE_GNS_NAMERECORD) | 146 | if (type != GNUNET_BLOCK_TYPE_GNS_NAMERECORD) |
231 | return GNUNET_SYSERR; | 147 | return GNUNET_SYSERR; |
232 | name = (const char *) &nrb[1]; | 148 | if (reply_block_size < sizeof (struct GNUNET_NAMESTORE_Block)) |
233 | if (NULL == memchr (name, '\0', | 149 | { |
234 | block_size - sizeof (struct GNSNameRecordBlock))) | 150 | GNUNET_break_op (0); |
235 | { | 151 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; |
236 | /* malformed, no 0-termination in name */ | 152 | } |
237 | GNUNET_break_op (0); | 153 | block = reply_block; |
238 | return GNUNET_SYSERR; | 154 | GNUNET_CRYPTO_hash (&block->derived_key, |
239 | } | 155 | sizeof (block->derived_key), |
240 | GNUNET_CRYPTO_short_hash (&nrb->public_key, | 156 | key); |
241 | sizeof (struct GNUNET_CRYPTO_EccPublicKey), | ||
242 | &pkey_hash); | ||
243 | GNUNET_GNS_get_key_for_record (name, &pkey_hash, key); | ||
244 | return GNUNET_OK; | 157 | return GNUNET_OK; |
245 | } | 158 | } |
246 | 159 | ||
@@ -258,7 +171,7 @@ libgnunet_plugin_block_gns_init (void *cls) | |||
258 | }; | 171 | }; |
259 | struct GNUNET_BLOCK_PluginFunctions *api; | 172 | struct GNUNET_BLOCK_PluginFunctions *api; |
260 | 173 | ||
261 | api = GNUNET_malloc (sizeof (struct GNUNET_BLOCK_PluginFunctions)); | 174 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); |
262 | api->evaluate = &block_plugin_gns_evaluate; | 175 | api->evaluate = &block_plugin_gns_evaluate; |
263 | api->get_key = &block_plugin_gns_get_key; | 176 | api->get_key = &block_plugin_gns_get_key; |
264 | api->types = types; | 177 | api->types = types; |