diff options
author | Christian Grothoff <christian@grothoff.org> | 2011-09-27 08:12:07 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2011-09-27 08:12:07 +0000 |
commit | e83f3d39b93b4a1aa721c6de33a9c1f04c82896d (patch) | |
tree | 41d52a5348227efb54115e038bc9cb850df0c7b9 /src/dht/gnunet-service-dht_routing.c | |
parent | 1f6511d450641f20c69f616dbdbbbb1badbbbc5a (diff) | |
download | gnunet-e83f3d39b93b4a1aa721c6de33a9c1f04c82896d.tar.gz gnunet-e83f3d39b93b4a1aa721c6de33a9c1f04c82896d.zip |
hxing
Diffstat (limited to 'src/dht/gnunet-service-dht_routing.c')
-rw-r--r-- | src/dht/gnunet-service-dht_routing.c | 172 |
1 files changed, 152 insertions, 20 deletions
diff --git a/src/dht/gnunet-service-dht_routing.c b/src/dht/gnunet-service-dht_routing.c index 535a63267..1d43cfd3d 100644 --- a/src/dht/gnunet-service-dht_routing.c +++ b/src/dht/gnunet-service-dht_routing.c | |||
@@ -46,6 +46,11 @@ struct RecentRequest | |||
46 | struct GNUNET_PeerIdentity peer; | 46 | struct GNUNET_PeerIdentity peer; |
47 | 47 | ||
48 | /** | 48 | /** |
49 | * Key of this request. | ||
50 | */ | ||
51 | GNUNET_HashCode key; | ||
52 | |||
53 | /** | ||
49 | * Position of this node in the min heap. | 54 | * Position of this node in the min heap. |
50 | */ | 55 | */ |
51 | struct GNUNET_CONTAINER_HeapNode *heap_node; | 56 | struct GNUNET_CONTAINER_HeapNode *heap_node; |
@@ -56,12 +61,6 @@ struct RecentRequest | |||
56 | struct GNUNET_CONTAINER_BloomFilter *reply_bf; | 61 | struct GNUNET_CONTAINER_BloomFilter *reply_bf; |
57 | 62 | ||
58 | /** | 63 | /** |
59 | * Timestamp of this request, for ordering | ||
60 | * the min heap. | ||
61 | */ | ||
62 | struct GNUNET_TIME_Absolute timestamp; | ||
63 | |||
64 | /** | ||
65 | * Type of the requested block. | 64 | * Type of the requested block. |
66 | */ | 65 | */ |
67 | enum GNUNET_BLOCK_Type type; | 66 | enum GNUNET_BLOCK_Type type; |
@@ -82,11 +81,6 @@ struct RecentRequest | |||
82 | */ | 81 | */ |
83 | uint32_t reply_bf_mutator; | 82 | uint32_t reply_bf_mutator; |
84 | 83 | ||
85 | /** | ||
86 | * Key of this request. | ||
87 | */ | ||
88 | GNUNET_HashCode key; | ||
89 | |||
90 | }; | 84 | }; |
91 | 85 | ||
92 | 86 | ||
@@ -102,6 +96,118 @@ static struct GNUNET_CONTAINER_MultiHashMap *recent_map; | |||
102 | 96 | ||
103 | 97 | ||
104 | /** | 98 | /** |
99 | * Closure for the 'process' function. | ||
100 | */ | ||
101 | struct ProcessContext | ||
102 | { | ||
103 | /** | ||
104 | * Path of the original PUT | ||
105 | */ | ||
106 | const struct GNUNET_PeerIdentity *put_path; | ||
107 | |||
108 | /** | ||
109 | * Path of the reply. | ||
110 | */ | ||
111 | const struct GNUNET_PeerIdentity *get_path; | ||
112 | |||
113 | /** | ||
114 | * Payload of the reply. | ||
115 | */ | ||
116 | const void *data; | ||
117 | |||
118 | /** | ||
119 | * Expiration time of the result. | ||
120 | */ | ||
121 | GNUNET_TIME_Absolute expiration_time; | ||
122 | |||
123 | /** | ||
124 | * Number of entries in 'put_path'. | ||
125 | */ | ||
126 | unsigned int put_path_length; | ||
127 | |||
128 | /** | ||
129 | * Number of entries in 'get_path'. | ||
130 | */ | ||
131 | unsigned int get_path_length; | ||
132 | |||
133 | /** | ||
134 | * Number of bytes in 'data'. | ||
135 | */ | ||
136 | size_t data_size; | ||
137 | |||
138 | /** | ||
139 | * Type of the reply. | ||
140 | */ | ||
141 | enum GNUNET_BLOCK_Type type; | ||
142 | |||
143 | }; | ||
144 | |||
145 | |||
146 | /** | ||
147 | * Forward the result to the given peer if it matches the request. | ||
148 | * | ||
149 | * @param cls the 'struct ProcessContext' with the result | ||
150 | * @param key the query | ||
151 | * @param value the 'struct RecentRequest' with the request | ||
152 | * @return GNUNET_OK (continue to iterate), | ||
153 | * GNUNET_SYSERR if the result is malformed or type unsupported | ||
154 | */ | ||
155 | static int | ||
156 | process (void *cls, | ||
157 | const GNUNET_HashCode *key, | ||
158 | void *value) | ||
159 | { | ||
160 | struct ProcessContext *pc = cls; | ||
161 | struct RecentRequest *rr = value; | ||
162 | enum GNUNET_BLOCK_EvaluationResult eval; | ||
163 | |||
164 | if ( (rr->type != GNUNET_BLOCK_TYPE_ANY) && | ||
165 | (rr->type != pc->type) ) | ||
166 | return GNUNET_OK; /* type missmatch */ | ||
167 | eval = GNUNET_BLOCK_evaluate (block_context, | ||
168 | pc->type, | ||
169 | key, | ||
170 | &rr->reply_bf, | ||
171 | rr->reply_bf_mutator, | ||
172 | rr->xquery, | ||
173 | rr->xquery_size, | ||
174 | pc->data, | ||
175 | pc->data_size); | ||
176 | switch (eval) | ||
177 | { | ||
178 | case GNUNET_BLOCK_EVALUATION_OK_MORE: | ||
179 | case GNUNET_BLOCK_EVALUATION_OK_LAST: | ||
180 | GDS_NEIGHBOURS_handle_reply (&rr->target, | ||
181 | pc->type, | ||
182 | pc->expiration_time, | ||
183 | key, | ||
184 | pc->put_path_length, | ||
185 | pc->put_path, | ||
186 | pc->get_path_length, | ||
187 | pc->get_path, | ||
188 | pc->data, | ||
189 | pc->data_size); | ||
190 | break; | ||
191 | case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE: | ||
192 | return GNUNET_OK; | ||
193 | case GNUNET_BLOCK_EVALUATION_RESULT_INVALID: | ||
194 | GNUNET_break_op (0); | ||
195 | return GNUNET_SYSERR; | ||
196 | case GNUNET_BLOCK_EVALUATION_REQUEST_VALID: | ||
197 | case GNUNET_BLOCK_EVALUATION_REQUEST_VALID: | ||
198 | GNUNET_break (0); | ||
199 | return GNUNET_OK; | ||
200 | case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED: | ||
201 | return GNUNET_SYSERR; | ||
202 | default: | ||
203 | GNUNET_break (0); | ||
204 | return GNUNET_SYSERR; | ||
205 | } | ||
206 | return GNUNET_OK; | ||
207 | } | ||
208 | |||
209 | |||
210 | /** | ||
105 | * Handle a reply (route to origin). Only forwards the reply back to | 211 | * Handle a reply (route to origin). Only forwards the reply back to |
106 | * other peers waiting for it. Does not do local caching or | 212 | * other peers waiting for it. Does not do local caching or |
107 | * forwarding to local clients. Essentially calls | 213 | * forwarding to local clients. Essentially calls |
@@ -123,12 +229,26 @@ GDS_ROUTING_process (enum GNUNET_BLOCK_Type type, | |||
123 | GNUNET_TIME_Absolute expiration_time, | 229 | GNUNET_TIME_Absolute expiration_time, |
124 | const GNUNET_HashCode *key, | 230 | const GNUNET_HashCode *key, |
125 | unsigned int put_path_length, | 231 | unsigned int put_path_length, |
126 | struct GNUNET_PeerIdentity *put_path, | 232 | const struct GNUNET_PeerIdentity *put_path, |
127 | unsigned int get_path_length, | 233 | unsigned int get_path_length, |
128 | struct GNUNET_PeerIdentity *get_path, | 234 | const struct GNUNET_PeerIdentity *get_path, |
129 | const void *data, | 235 | const void *data, |
130 | size_t data_size) | 236 | size_t data_size) |
131 | { | 237 | { |
238 | struct ProcessContext pc; | ||
239 | |||
240 | pc.type = type; | ||
241 | pc.expiration_time = expiration_time; | ||
242 | pc.put_path_length = put_path_length; | ||
243 | pc.put_path = put_path; | ||
244 | pc.get_path_length = get_path_length; | ||
245 | pc.get_path = get_path; | ||
246 | pc.data = data; | ||
247 | pc.data_size = data_size; | ||
248 | GNUNET_CONTAINER_multihashmap_iterate (recent_map, | ||
249 | key, | ||
250 | &process, | ||
251 | &pc); | ||
132 | } | 252 | } |
133 | 253 | ||
134 | 254 | ||
@@ -152,24 +272,33 @@ GDS_ROUTING_add (const GNUNET_PeerIdentity *sender, | |||
152 | const struct GNUNET_CONTAINER_BloomFilter *reply_bf, | 272 | const struct GNUNET_CONTAINER_BloomFilter *reply_bf, |
153 | uint32_t reply_bf_mutator) | 273 | uint32_t reply_bf_mutator) |
154 | { | 274 | { |
155 | if (GNUNET_CONTAINER_heap_get_size (recent_heap) >= DHT_MAX_RECENT) | 275 | struct RecentRequest *recent_req; |
276 | |||
277 | while (GNUNET_CONTAINER_heap_get_size (recent_heap) >= DHT_MAX_RECENT) | ||
156 | { | 278 | { |
157 | recent_req = GNUNET_CONTAINER_heap_peek (recent_heap); | 279 | recent_req = GNUNET_CONTAINER_heap_peek (recent_heap); |
158 | GNUNET_assert (recent_req != NULL); | 280 | GNUNET_assert (recent_req != NULL); |
159 | GNUNET_SCHEDULER_cancel (recent_req->remove_task); | ||
160 | GNUNET_CONTAINER_heap_remove_node (recent_req->heap_node); | 281 | GNUNET_CONTAINER_heap_remove_node (recent_req->heap_node); |
161 | GNUNET_CONTAINER_bloomfilter_free (recent_req->bloom); | 282 | GNUNET_CONTAINER_bloomfilter_free (recent_req->bloom); |
162 | GNUNET_free (recent_req); | 283 | GNUNET_free (recent_req); |
163 | } | 284 | } |
164 | 285 | ||
165 | recent_req = GNUNET_malloc (sizeof (struct RecentRequest)); | 286 | recent_req = GNUNET_malloc (sizeof (struct RecentRequest) + xquery_size); |
166 | recent_req->uid = msg_ctx->unique_id; | 287 | recent_req->peer = *sender; |
167 | memcpy (&recent_req->key, &msg_ctx->key, sizeof (GNUNET_HashCode)); | 288 | recent_req->key = *key; |
168 | recent_req->heap_node = | 289 | recent_req->heap_node = |
169 | GNUNET_CONTAINER_heap_insert (recent_heap, recent_req, | 290 | GNUNET_CONTAINER_heap_insert (recent_heap, recent_req, |
170 | GNUNET_TIME_absolute_get ().abs_value); | 291 | GNUNET_TIME_absolute_get ().abs_value); |
171 | recent_req->bloom = | 292 | recent_req->reply_bf = |
172 | GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE, DHT_BLOOM_K); | 293 | GNUNET_CONTAINER_bloomfilter_copy (reply_bf); |
294 | recent_req->type = type; | ||
295 | recent_req->xquery = &recent_req[1]; | ||
296 | recent_req->xquery_size = xquery_size; | ||
297 | recent_req->reply_bf_mutator = reply_bf_mutator; | ||
298 | GNUNET_CONTAINER_multihashmap_put (recent_map, | ||
299 | key, | ||
300 | recent_req, | ||
301 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
173 | 302 | ||
174 | 303 | ||
175 | } | 304 | } |
@@ -194,6 +323,8 @@ GDS_ROUTING_init () | |||
194 | void | 323 | void |
195 | GDS_ROUTING_done () | 324 | GDS_ROUTING_done () |
196 | { | 325 | { |
326 | struct RecentRequest *recent_req; | ||
327 | |||
197 | while (GNUNET_CONTAINER_heap_get_size (recent_heap) > 0) | 328 | while (GNUNET_CONTAINER_heap_get_size (recent_heap) > 0) |
198 | { | 329 | { |
199 | recent_req = GNUNET_CONTAINER_heap_peek (recent_heap); | 330 | recent_req = GNUNET_CONTAINER_heap_peek (recent_heap); |
@@ -202,6 +333,7 @@ GDS_ROUTING_done () | |||
202 | GNUNET_CONTAINER_bloomfilter_free (recent_req->bloom); | 333 | GNUNET_CONTAINER_bloomfilter_free (recent_req->bloom); |
203 | GNUNET_free (recent_req); | 334 | GNUNET_free (recent_req); |
204 | } | 335 | } |
336 | GNUNET_assert (0 == GNUNET_CONTAINER_heap_size (recent_heap)); | ||
205 | GNUNET_CONTAINER_heap_destroy (recent_heap); | 337 | GNUNET_CONTAINER_heap_destroy (recent_heap); |
206 | recent_heap = NULL; | 338 | recent_heap = NULL; |
207 | GNUNET_CONTAINER_multihashmap_destroy (recent_map); | 339 | GNUNET_CONTAINER_multihashmap_destroy (recent_map); |