diff options
author | Christian Grothoff <christian@grothoff.org> | 2009-09-11 14:22:19 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2009-09-11 14:22:19 +0000 |
commit | 92b434b649de5bc75628eff46f17db18104a4dd8 (patch) | |
tree | 7d55ced99e9f0539f414c017c3504c4bd45da7f4 /src | |
parent | b60d9cfa7d42f0a933d7de137a2c8b17eaece4dd (diff) | |
download | gnunet-92b434b649de5bc75628eff46f17db18104a4dd8.tar.gz gnunet-92b434b649de5bc75628eff46f17db18104a4dd8.zip |
more FS coding
Diffstat (limited to 'src')
-rw-r--r-- | src/fs/fs_uri.c | 4 | ||||
-rw-r--r-- | src/fs/gnunet-service-fs.c | 490 | ||||
-rw-r--r-- | src/upnp/upnp_util.h | 2 |
3 files changed, 469 insertions, 27 deletions
diff --git a/src/fs/fs_uri.c b/src/fs/fs_uri.c index 4f4a82c2c..1c0686ed9 100644 --- a/src/fs/fs_uri.c +++ b/src/fs/fs_uri.c | |||
@@ -1481,7 +1481,9 @@ gather_uri_data (void *cls, | |||
1481 | * Construct a keyword-URI from meta-data (take all entries | 1481 | * Construct a keyword-URI from meta-data (take all entries |
1482 | * in the meta-data and construct one large keyword URI | 1482 | * in the meta-data and construct one large keyword URI |
1483 | * that lists all keywords that can be found in the meta-data). | 1483 | * that lists all keywords that can be found in the meta-data). |
1484 | * @deprecated | 1484 | * |
1485 | * @param md metadata to use | ||
1486 | * @return NULL on error, otherwise a KSK URI | ||
1485 | */ | 1487 | */ |
1486 | struct GNUNET_FS_Uri * | 1488 | struct GNUNET_FS_Uri * |
1487 | GNUNET_FS_uri_ksk_create_from_meta_data (const struct GNUNET_CONTAINER_MetaData *md) | 1489 | GNUNET_FS_uri_ksk_create_from_meta_data (const struct GNUNET_CONTAINER_MetaData *md) |
diff --git a/src/fs/gnunet-service-fs.c b/src/fs/gnunet-service-fs.c index bf64f73f1..b85a63d4b 100644 --- a/src/fs/gnunet-service-fs.c +++ b/src/fs/gnunet-service-fs.c | |||
@@ -22,6 +22,13 @@ | |||
22 | * @file fs/gnunet-service-fs.c | 22 | * @file fs/gnunet-service-fs.c |
23 | * @brief program that provides the file-sharing service | 23 | * @brief program that provides the file-sharing service |
24 | * @author Christian Grothoff | 24 | * @author Christian Grothoff |
25 | * | ||
26 | * TODO: | ||
27 | * - INDEX_START handling | ||
28 | * - INDEX_LIST handling | ||
29 | * - UNINDEX handling | ||
30 | * - bloomfilter support (GET, CS-request with BF, etc.) | ||
31 | * - all P2P messages | ||
25 | */ | 32 | */ |
26 | #include "platform.h" | 33 | #include "platform.h" |
27 | #include "gnunet_protocols.h" | 34 | #include "gnunet_protocols.h" |
@@ -30,9 +37,22 @@ | |||
30 | #include "gnunet_util_lib.h" | 37 | #include "gnunet_util_lib.h" |
31 | #include "fs.h" | 38 | #include "fs.h" |
32 | 39 | ||
40 | /** | ||
41 | * Our connection to the datastore. | ||
42 | */ | ||
33 | static struct GNUNET_DATASTORE_Handle *dsh; | 43 | static struct GNUNET_DATASTORE_Handle *dsh; |
34 | 44 | ||
35 | /** | 45 | /** |
46 | * Our scheduler. | ||
47 | */ | ||
48 | static struct GNUNET_SCHEDULER_Handle *sched; | ||
49 | |||
50 | /** | ||
51 | * Our configuration. | ||
52 | */ | ||
53 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
54 | |||
55 | /** | ||
36 | * Handle INDEX_START-message. | 56 | * Handle INDEX_START-message. |
37 | * | 57 | * |
38 | * @param cls closure | 58 | * @param cls closure |
@@ -141,7 +161,8 @@ handle_unindex (void *cls, | |||
141 | 161 | ||
142 | 162 | ||
143 | /** | 163 | /** |
144 | * FIXME | 164 | * Signature of a function that is called whenever a datastore |
165 | * request can be processed (or an entry put on the queue times out). | ||
145 | * | 166 | * |
146 | * @param cls closure | 167 | * @param cls closure |
147 | * @param ok GNUNET_OK if DS is ready, GNUNET_SYSERR on timeout | 168 | * @param ok GNUNET_OK if DS is ready, GNUNET_SYSERR on timeout |
@@ -151,65 +172,453 @@ typedef void (*RequestFunction)(void *cls, | |||
151 | 172 | ||
152 | 173 | ||
153 | /** | 174 | /** |
175 | * Doubly-linked list of our requests for the datastore. | ||
176 | */ | ||
177 | struct DatastoreRequestQueue | ||
178 | { | ||
179 | |||
180 | /** | ||
181 | * This is a doubly-linked list. | ||
182 | */ | ||
183 | struct DatastoreRequestQueue *next; | ||
184 | |||
185 | /** | ||
186 | * This is a doubly-linked list. | ||
187 | */ | ||
188 | struct DatastoreRequestQueue *prev; | ||
189 | |||
190 | /** | ||
191 | * Function to call (will issue the request). | ||
192 | */ | ||
193 | RequestFunction req; | ||
194 | |||
195 | /** | ||
196 | * Closure for req. | ||
197 | */ | ||
198 | void *req_cls; | ||
199 | |||
200 | /** | ||
201 | * When should this request time-out because we don't care anymore? | ||
202 | */ | ||
203 | struct GNUNET_TIME_Absolute timeout; | ||
204 | |||
205 | /** | ||
206 | * ID of task used for signaling timeout. | ||
207 | */ | ||
208 | GNUNET_SCHEDULER_TaskIdentifier task; | ||
209 | |||
210 | }; | ||
211 | |||
212 | |||
213 | /** | ||
214 | * Head of request queue for the datastore, sorted by timeout. | ||
215 | */ | ||
216 | static struct DatastoreRequestQueue *drq_head; | ||
217 | |||
218 | /** | ||
219 | * Tail of request queue for the datastore. | ||
220 | */ | ||
221 | static struct DatastoreRequestQueue *drq_tail; | ||
222 | |||
223 | |||
224 | /** | ||
154 | * Run the next DS request in our | 225 | * Run the next DS request in our |
155 | * queue, we're done with the current one. | 226 | * queue, we're done with the current one. |
156 | */ | 227 | */ |
157 | static void | 228 | static void |
158 | next_ds_request () | 229 | next_ds_request () |
159 | { | 230 | { |
231 | struct DatastoreRequestQueue *e; | ||
232 | |||
233 | while (NULL != (e = drq_head)) | ||
234 | { | ||
235 | if (0 != GNUNET_TIME_absolute_get_remaining (e->timeout).value) | ||
236 | break; | ||
237 | if (e->task != GNUNET_SCHEDULER_NO_TASK) | ||
238 | GNUNET_SCHEDULER_cancel (sched, e->task); | ||
239 | GNUNET_CONTAINER_DLL_remove (drq_head, drq_tail, e); | ||
240 | e->req (e->req_cls, GNUNET_NO); | ||
241 | GNUNET_free (e); | ||
242 | } | ||
243 | if (e == NULL) | ||
244 | return; | ||
245 | if (e->task != GNUNET_SCHEDULER_NO_TASK) | ||
246 | GNUNET_SCHEDULER_cancel (sched, e->task); | ||
247 | e->task = GNUNET_SCHEDULER_NO_TASK; | ||
248 | e->req (e->req_cls, GNUNET_YES); | ||
249 | GNUNET_CONTAINER_DLL_remove (drq_head, drq_tail, e); | ||
250 | GNUNET_free (e); | ||
160 | } | 251 | } |
161 | 252 | ||
162 | 253 | ||
163 | /** | 254 | /** |
164 | * FIXME. | 255 | * A datastore request had to be timed out. |
256 | * | ||
257 | * @param cls closure (of type "struct DatastoreRequestQueue*") | ||
258 | * @param tc task context, unused | ||
165 | */ | 259 | */ |
166 | static void | 260 | static void |
261 | timeout_ds_request (void *cls, | ||
262 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
263 | { | ||
264 | struct DatastoreRequestQueue *e = cls; | ||
265 | |||
266 | e->task = GNUNET_SCHEDULER_NO_TASK; | ||
267 | GNUNET_CONTAINER_DLL_remove (drq_head, drq_tail, e); | ||
268 | e->req (e->req_cls, GNUNET_NO); | ||
269 | GNUNET_free (e); | ||
270 | } | ||
271 | |||
272 | |||
273 | /** | ||
274 | * Queue a request for the datastore. | ||
275 | * | ||
276 | * @param deadline by when the request should run | ||
277 | * @param fun function to call once the request can be run | ||
278 | * @param fun_cls closure for fun | ||
279 | */ | ||
280 | static struct DatastoreRequestQueue * | ||
167 | queue_ds_request (struct GNUNET_TIME_Relative deadline, | 281 | queue_ds_request (struct GNUNET_TIME_Relative deadline, |
168 | RequestFunction fun, | 282 | RequestFunction fun, |
169 | void *fun_cls) | 283 | void *fun_cls) |
170 | { | 284 | { |
171 | } | 285 | struct DatastoreRequestQueue *e; |
286 | struct DatastoreRequestQueue *bef; | ||
172 | 287 | ||
288 | if (drq_head == NULL) | ||
289 | { | ||
290 | /* no other requests pending, run immediately */ | ||
291 | fun (fun_cls, GNUNET_OK); | ||
292 | return NULL; | ||
293 | } | ||
294 | e = GNUNET_malloc (sizeof (struct DatastoreRequestQueue)); | ||
295 | e->timeout = GNUNET_TIME_relative_to_absolute (deadline); | ||
296 | e->req = fun; | ||
297 | e->req_cls = fun_cls; | ||
298 | if (deadline.value == GNUNET_TIME_UNIT_FOREVER_REL.value) | ||
299 | { | ||
300 | /* local request, highest prio, put at head of queue | ||
301 | regardless of deadline */ | ||
302 | bef = NULL; | ||
303 | } | ||
304 | else | ||
305 | { | ||
306 | bef = drq_tail; | ||
307 | while ( (NULL != bef) && | ||
308 | (e->timeout.value < bef->timeout.value) ) | ||
309 | bef = bef->prev; | ||
310 | } | ||
311 | GNUNET_CONTAINER_DLL_insert_after (drq_head, drq_tail, bef, e); | ||
312 | if (deadline.value == GNUNET_TIME_UNIT_FOREVER_REL.value) | ||
313 | return e; | ||
314 | e->task = GNUNET_SCHEDULER_add_delayed (sched, | ||
315 | GNUNET_NO, | ||
316 | GNUNET_SCHEDULER_PRIORITY_BACKGROUND, | ||
317 | GNUNET_SCHEDULER_NO_TASK, | ||
318 | deadline, | ||
319 | &timeout_ds_request, | ||
320 | e); | ||
321 | return e; | ||
322 | } | ||
173 | 323 | ||
174 | 324 | ||
175 | /** | 325 | /** |
176 | * Closure for processing START_SEARCH | 326 | * Closure for processing START_SEARCH messages from a client. |
177 | * messages from a client. | ||
178 | */ | 327 | */ |
179 | struct LocalGetContext | 328 | struct LocalGetContext |
180 | { | 329 | { |
330 | |||
331 | /** | ||
332 | * This is a doubly-linked list. | ||
333 | */ | ||
334 | struct LocalGetContext *next; | ||
335 | |||
336 | /** | ||
337 | * This is a doubly-linked list. | ||
338 | */ | ||
339 | struct LocalGetContext *prev; | ||
340 | |||
181 | /** | 341 | /** |
182 | * Client that initiated the search. | 342 | * Client that initiated the search. |
183 | */ | 343 | */ |
184 | struct GNUNET_SERVER_Client *client; | 344 | struct GNUNET_SERVER_Client *client; |
185 | 345 | ||
346 | /** | ||
347 | * Array of results that we've already received | ||
348 | * (can be NULL). | ||
349 | */ | ||
350 | GNUNET_HashCode *results; | ||
186 | 351 | ||
352 | /** | ||
353 | * Bloomfilter over all results (for fast query construction); | ||
354 | * NULL if we don't have any results. | ||
355 | */ | ||
356 | struct GNUNET_CONTAINER_BloomFilter *results_bf; | ||
357 | |||
358 | /** | ||
359 | * DS request associated with this operation. | ||
360 | */ | ||
361 | struct DatastoreRequestQueue *req; | ||
362 | |||
363 | /** | ||
364 | * Current result message to transmit to client (or NULL). | ||
365 | */ | ||
366 | struct ContentMessage *result; | ||
367 | |||
368 | /** | ||
369 | * Type of the content that we're looking for. | ||
370 | * 0 for any. | ||
371 | */ | ||
372 | uint32_t type; | ||
373 | |||
374 | /** | ||
375 | * Desired anonymity level. | ||
376 | */ | ||
377 | uint32_t anonymity_level; | ||
378 | |||
379 | /** | ||
380 | * Number of results actually stored in the results array. | ||
381 | */ | ||
382 | unsigned int results_used; | ||
187 | 383 | ||
384 | /** | ||
385 | * Size of the results array in memory. | ||
386 | */ | ||
387 | unsigned int results_size; | ||
388 | |||
389 | /** | ||
390 | * If the request is for a DBLOCK or IBLOCK, this is the identity of | ||
391 | * the peer that is known to have a response. Set to all-zeros if | ||
392 | * such a target is not known (note that even if OUR anonymity | ||
393 | * level is >0 we may happen to know the responder's identity; | ||
394 | * nevertheless, we should probably not use it for a DHT-lookup | ||
395 | * or similar blunt actions in order to avoid exposing ourselves). | ||
396 | * <p> | ||
397 | * If the request is for an SBLOCK, this is the identity of the | ||
398 | * pseudonym to which the SBLOCK belongs. | ||
399 | * <p> | ||
400 | * If the request is for a KBLOCK, "target" must be all zeros. | ||
401 | */ | ||
402 | GNUNET_HashCode target; | ||
403 | |||
404 | /** | ||
405 | * Hash of the keyword (aka query) for KBLOCKs; Hash of | ||
406 | * the CHK-encoded block for DBLOCKS and IBLOCKS (aka query) | ||
407 | * and hash of the identifier XORed with the target for | ||
408 | * SBLOCKS (aka query). | ||
409 | */ | ||
410 | GNUNET_HashCode query; | ||
411 | |||
188 | }; | 412 | }; |
189 | 413 | ||
190 | 414 | ||
191 | static void | 415 | /** |
416 | * Head of doubly-linked LGC list. | ||
417 | */ | ||
418 | static struct LocalGetContext *lgc_head; | ||
419 | |||
420 | /** | ||
421 | * Tail of doubly-linked LGC list. | ||
422 | */ | ||
423 | static struct LocalGetContext *lgc_tail; | ||
424 | |||
425 | |||
426 | /** | ||
427 | * Free the state associated with a local get context. | ||
428 | * | ||
429 | * @param lgc the lgc to free | ||
430 | */ | ||
431 | static void | ||
432 | local_get_context_free (struct LocalGetContext *lgc) | ||
433 | { | ||
434 | GNUNET_CONTAINER_DLL_remove (lgc_head, lgc_tail, lgc); | ||
435 | GNUNET_SERVER_client_drop (lgc->client); | ||
436 | GNUNET_free_non_null (lgc->results); | ||
437 | if (lgc->results_bf != NULL) | ||
438 | GNUNET_CONTAINER_bloomfilter_free (lgc->results_bf); | ||
439 | if (lgc->req != NULL) | ||
440 | { | ||
441 | if (lgc->req->task != GNUNET_SCHEDULER_NO_TASK) | ||
442 | GNUNET_SCHEDULER_cancel (sched, lgc->req->task); | ||
443 | GNUNET_CONTAINER_DLL_remove (lgc_head, lgc_tail, lgc); | ||
444 | GNUNET_free (lgc->req); | ||
445 | } | ||
446 | GNUNET_free (lgc); | ||
447 | } | ||
448 | |||
449 | |||
450 | /** | ||
451 | * We're able to transmit the next (local) result to the client. | ||
452 | * Do it and ask the datastore for more. Or, on error, tell | ||
453 | * the datastore to stop giving us more. | ||
454 | * | ||
455 | * @param cls our closure (struct LocalGetContext) | ||
456 | * @param max maximum number of bytes we can transmit | ||
457 | * @param buf where to copy our message | ||
458 | * @return number of bytes copied to buf | ||
459 | */ | ||
460 | static size_t | ||
461 | transmit_local_result (void *cls, | ||
462 | size_t max, | ||
463 | void *buf) | ||
464 | { | ||
465 | struct LocalGetContext *lgc = cls; | ||
466 | uint16_t msize; | ||
467 | |||
468 | if (NULL == buf) | ||
469 | { | ||
470 | /* error, abort! */ | ||
471 | GNUNET_free (lgc->result); | ||
472 | lgc->result = NULL; | ||
473 | GNUNET_DATASTORE_get_next (dsh, GNUNET_NO); | ||
474 | return 0; | ||
475 | } | ||
476 | msize = ntohs (lgc->result->header.size); | ||
477 | GNUNET_assert (max >= msize); | ||
478 | memcpy (buf, lgc->result, msize); | ||
479 | GNUNET_free (lgc->result); | ||
480 | lgc->result = NULL; | ||
481 | GNUNET_DATASTORE_get_next (dsh, GNUNET_YES); | ||
482 | return msize; | ||
483 | } | ||
484 | |||
485 | |||
486 | /** | ||
487 | * We're processing (local) results for a search request | ||
488 | * from a (local) client. Pass applicable results to the | ||
489 | * client and if we are done either clean up (operation | ||
490 | * complete) or switch to P2P search (more results possible). | ||
491 | * | ||
492 | * @param cls our closure (struct LocalGetContext) | ||
493 | * @param key key for the content | ||
494 | * @param size number of bytes in data | ||
495 | * @param data content stored | ||
496 | * @param type type of the content | ||
497 | * @param priority priority of the content | ||
498 | * @param anonymity anonymity-level for the content | ||
499 | * @param expiration expiration time for the content | ||
500 | * @param uid unique identifier for the datum; | ||
501 | * maybe 0 if no unique identifier is available | ||
502 | */ | ||
503 | static void | ||
504 | process_local_get_result (void *cls, | ||
505 | const GNUNET_HashCode * key, | ||
506 | uint32_t size, | ||
507 | const void *data, | ||
508 | uint32_t type, | ||
509 | uint32_t priority, | ||
510 | uint32_t anonymity, | ||
511 | struct GNUNET_TIME_Absolute | ||
512 | expiration, | ||
513 | uint64_t uid) | ||
514 | { | ||
515 | struct LocalGetContext *lgc = cls; | ||
516 | size_t msize; | ||
517 | |||
518 | if (key == NULL) | ||
519 | { | ||
520 | /* no further results from datastore; continue | ||
521 | processing further requests from the client and | ||
522 | allow the next task to use the datastore; also, | ||
523 | switch to P2P requests or clean up our state. */ | ||
524 | next_ds_request (); | ||
525 | GNUNET_SERVER_receive_done (lgc->client, | ||
526 | GNUNET_OK); | ||
527 | if ( (lgc->results_used == 0) || | ||
528 | (lgc->type == GNUNET_DATASTORE_BLOCKTYPE_KBLOCK) || | ||
529 | (lgc->type == GNUNET_DATASTORE_BLOCKTYPE_SBLOCK) || | ||
530 | (lgc->type == GNUNET_DATASTORE_BLOCKTYPE_SKBLOCK) ) | ||
531 | { | ||
532 | // FIXME: initiate P2P search | ||
533 | return; | ||
534 | } | ||
535 | /* got all possible results, clean up! */ | ||
536 | local_get_context_free (lgc); | ||
537 | return; | ||
538 | } | ||
539 | if (lgc->results_used == lgc->results_size) | ||
540 | { | ||
541 | GNUNET_array_grow (lgc->results, | ||
542 | lgc->results_size, | ||
543 | lgc->results_size * 2 + 2); | ||
544 | if ( (lgc->type != GNUNET_DATASTORE_BLOCKTYPE_DBLOCK) || | ||
545 | (lgc->type != GNUNET_DATASTORE_BLOCKTYPE_IBLOCK) ) | ||
546 | { | ||
547 | // FIXME: possibly grow/create BF! | ||
548 | } | ||
549 | } | ||
550 | GNUNET_CRYPTO_hash (data, | ||
551 | size, | ||
552 | &lgc->results[lgc->results_used++]); | ||
553 | if ( (lgc->type != GNUNET_DATASTORE_BLOCKTYPE_DBLOCK) || | ||
554 | (lgc->type != GNUNET_DATASTORE_BLOCKTYPE_IBLOCK) ) | ||
555 | { | ||
556 | // FIXME: add result to BF! | ||
557 | } | ||
558 | msize = size + sizeof (struct ContentMessage); | ||
559 | GNUNET_assert (msize < GNUNET_SERVER_MAX_MESSAGE_SIZE); | ||
560 | lgc->result = GNUNET_malloc (msize); | ||
561 | lgc->result->header.size = htons (msize); | ||
562 | lgc->result->header.type = htons (GNUNET_MESSAGE_TYPE_FS_CONTENT); | ||
563 | lgc->result->type = htonl (type); | ||
564 | lgc->result->expiration = GNUNET_TIME_absolute_hton (expiration); | ||
565 | memcpy (&lgc->result[1], | ||
566 | data, | ||
567 | size); | ||
568 | GNUNET_SERVER_notify_transmit_ready (lgc->client, | ||
569 | msize, | ||
570 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
571 | &transmit_local_result, | ||
572 | lgc); | ||
573 | } | ||
574 | |||
575 | |||
576 | /** | ||
577 | * We're processing a search request from a local | ||
578 | * client. Now it is our turn to query the datastore. | ||
579 | * | ||
580 | * @param cls our closure (struct LocalGetContext) | ||
581 | * @param tc unused | ||
582 | */ | ||
583 | static void | ||
192 | transmit_local_get (void *cls, | 584 | transmit_local_get (void *cls, |
193 | int ok) | 585 | const struct GNUNET_SCHEDULER_TaskContext *tc) |
194 | { | 586 | { |
195 | struct LocalGetContext *lgc = cls; | 587 | struct LocalGetContext *lgc = cls; |
196 | // FIXME: search locally | ||
197 | 588 | ||
198 | GNUNET_assert (GNUNET_OK == ok); | 589 | GNUNET_DATASTORE_get (dsh, |
199 | GNUNET_SERVER_receive_done (lgc->client, | 590 | &lgc->query, |
200 | GNUNET_OK); | 591 | lgc->type, |
592 | &process_local_get_result, | ||
593 | lgc, | ||
594 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
595 | } | ||
201 | 596 | ||
202 | // once we're done processing the DS reply, do: | ||
203 | next_ds_request (); | ||
204 | // FIXME: if not found, initiate P2P search | ||
205 | 597 | ||
206 | // FIXME: once done with "client" handle: | 598 | /** |
207 | GNUNET_SERVER_client_drop (lgc->client); | 599 | * We're processing a search request from a local |
600 | * client. Now it is our turn to query the datastore. | ||
601 | * | ||
602 | * @param cls our closure (struct LocalGetContext) | ||
603 | * @param ok did we succeed to queue for datastore access, should always be GNUNET_OK | ||
604 | */ | ||
605 | static void | ||
606 | transmit_local_get_ready (void *cls, | ||
607 | int ok) | ||
608 | { | ||
609 | struct LocalGetContext *lgc = cls; | ||
610 | |||
611 | GNUNET_assert (GNUNET_OK == ok); | ||
612 | GNUNET_SCHEDULER_add_continuation (sched, | ||
613 | GNUNET_NO, | ||
614 | &transmit_local_get, | ||
615 | lgc, | ||
616 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); | ||
208 | } | 617 | } |
209 | 618 | ||
210 | 619 | ||
211 | /** | 620 | /** |
212 | * Handle START_SEARCH-message. | 621 | * Handle START_SEARCH-message (search request from client). |
213 | * | 622 | * |
214 | * @param cls closure | 623 | * @param cls closure |
215 | * @param client identification of the client | 624 | * @param client identification of the client |
@@ -227,10 +636,14 @@ handle_start_search (void *cls, | |||
227 | GNUNET_SERVER_client_keep (client); | 636 | GNUNET_SERVER_client_keep (client); |
228 | lgc = GNUNET_malloc (sizeof (struct LocalGetContext)); | 637 | lgc = GNUNET_malloc (sizeof (struct LocalGetContext)); |
229 | lgc->client = client; | 638 | lgc->client = client; |
230 | // lgc->x = y; | 639 | lgc->type = ntohl (sm->type); |
231 | queue_ds_request (GNUNET_TIME_UNIT_FOREVER_REL, | 640 | lgc->anonymity_level = ntohl (sm->anonymity_level); |
232 | &transmit_local_get, | 641 | lgc->target = sm->target; |
233 | lgc); | 642 | lgc->query = sm->query; |
643 | GNUNET_CONTAINER_DLL_insert (lgc_head, lgc_tail, lgc); | ||
644 | lgc->req = queue_ds_request (GNUNET_TIME_UNIT_FOREVER_REL, | ||
645 | &transmit_local_get_ready, | ||
646 | lgc); | ||
234 | } | 647 | } |
235 | 648 | ||
236 | 649 | ||
@@ -252,6 +665,29 @@ static struct GNUNET_SERVER_MessageHandler handlers[] = { | |||
252 | 665 | ||
253 | 666 | ||
254 | /** | 667 | /** |
668 | * A client disconnected. Remove all of its pending queries. | ||
669 | * | ||
670 | * @param cls closure, NULL | ||
671 | * @param client identification of the client | ||
672 | */ | ||
673 | static void | ||
674 | handle_client_disconnect (void *cls, | ||
675 | struct GNUNET_SERVER_Client | ||
676 | * client) | ||
677 | { | ||
678 | struct LocalGetContext *lgc; | ||
679 | |||
680 | lgc = lgc_head; | ||
681 | while ( (NULL != lgc) && | ||
682 | (lgc->client != client) ) | ||
683 | lgc = lgc->next; | ||
684 | if (lgc == NULL) | ||
685 | return; /* not one of our clients */ | ||
686 | local_get_context_free (lgc); | ||
687 | } | ||
688 | |||
689 | |||
690 | /** | ||
255 | * Task run during shutdown. | 691 | * Task run during shutdown. |
256 | * | 692 | * |
257 | * @param cls unused | 693 | * @param cls unused |
@@ -277,10 +713,12 @@ shutdown_task (void *cls, | |||
277 | */ | 713 | */ |
278 | static void | 714 | static void |
279 | run (void *cls, | 715 | run (void *cls, |
280 | struct GNUNET_SCHEDULER_Handle *sched, | 716 | struct GNUNET_SCHEDULER_Handle *s, |
281 | struct GNUNET_SERVER_Handle *server, | 717 | struct GNUNET_SERVER_Handle *server, |
282 | const struct GNUNET_CONFIGURATION_Handle *cfg) | 718 | const struct GNUNET_CONFIGURATION_Handle *c) |
283 | { | 719 | { |
720 | sched = s; | ||
721 | cfg = c; | ||
284 | dsh = GNUNET_DATASTORE_connect (cfg, | 722 | dsh = GNUNET_DATASTORE_connect (cfg, |
285 | sched); | 723 | sched); |
286 | if (NULL == dsh) | 724 | if (NULL == dsh) |
@@ -289,9 +727,11 @@ run (void *cls, | |||
289 | _("Failed to connect to datastore service.\n")); | 727 | _("Failed to connect to datastore service.\n")); |
290 | return; | 728 | return; |
291 | } | 729 | } |
730 | GNUNET_SERVER_disconnect_notify (server, | ||
731 | &handle_client_disconnect, | ||
732 | NULL); | ||
292 | GNUNET_SERVER_add_handlers (server, handlers); | 733 | GNUNET_SERVER_add_handlers (server, handlers); |
293 | // FIXME: also handle P2P messages! | 734 | // FIXME: also register with core to handle P2P messages! |
294 | |||
295 | GNUNET_SCHEDULER_add_delayed (sched, | 735 | GNUNET_SCHEDULER_add_delayed (sched, |
296 | GNUNET_YES, | 736 | GNUNET_YES, |
297 | GNUNET_SCHEDULER_PRIORITY_IDLE, | 737 | GNUNET_SCHEDULER_PRIORITY_IDLE, |
diff --git a/src/upnp/upnp_util.h b/src/upnp/upnp_util.h index 32c790493..1c7555b09 100644 --- a/src/upnp/upnp_util.h +++ b/src/upnp/upnp_util.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /** | 1 | /** |
2 | * @file transport/upnp_util.h Utility Functions | 2 | * @file upnp/upnp_util.h Utility Functions |
3 | * @ingroup core | 3 | * @ingroup core |
4 | * | 4 | * |
5 | * gaim | 5 | * gaim |