aboutsummaryrefslogtreecommitdiff
path: root/src/dht/gnunet-service-dht_routing.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-09-27 08:12:07 +0000
committerChristian Grothoff <christian@grothoff.org>2011-09-27 08:12:07 +0000
commite83f3d39b93b4a1aa721c6de33a9c1f04c82896d (patch)
tree41d52a5348227efb54115e038bc9cb850df0c7b9 /src/dht/gnunet-service-dht_routing.c
parent1f6511d450641f20c69f616dbdbbbb1badbbbc5a (diff)
downloadgnunet-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.c172
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 */
101struct 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 */
155static int
156process (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 ()
194void 323void
195GDS_ROUTING_done () 324GDS_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);