diff options
author | Florian Dold <florian.dold@gmail.com> | 2013-05-15 10:48:55 +0000 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2013-05-15 10:48:55 +0000 |
commit | 6f54b50858457dfa2b5f0b519fbf230e1119c6b2 (patch) | |
tree | 5f84bfa599cb50522999cad892344e2fecbfa963 /src/set/gnunet-service-set.c | |
parent | 6625c27a83831b61a80683f4385b6a90b9a45b31 (diff) | |
download | gnunet-6f54b50858457dfa2b5f0b519fbf230e1119c6b2.tar.gz gnunet-6f54b50858457dfa2b5f0b519fbf230e1119c6b2.zip |
test cases for mq, set works
Diffstat (limited to 'src/set/gnunet-service-set.c')
-rw-r--r-- | src/set/gnunet-service-set.c | 180 |
1 files changed, 138 insertions, 42 deletions
diff --git a/src/set/gnunet-service-set.c b/src/set/gnunet-service-set.c index aea198a61..3ed896775 100644 --- a/src/set/gnunet-service-set.c +++ b/src/set/gnunet-service-set.c | |||
@@ -72,24 +72,11 @@ static struct Incoming *incoming_head; | |||
72 | static struct Incoming *incoming_tail; | 72 | static struct Incoming *incoming_tail; |
73 | 73 | ||
74 | /** | 74 | /** |
75 | * Counter for allocating unique request IDs for clients. | 75 | * Counter for allocating unique IDs for clients, |
76 | * Used to identify incoming requests from remote peers. | 76 | * used to identify incoming operation requests from remote peers, |
77 | * that the client can choose to accept or refuse. | ||
77 | */ | 78 | */ |
78 | static uint32_t request_id = 1; | 79 | static uint32_t accept_id = 1; |
79 | |||
80 | |||
81 | /** | ||
82 | * Disconnect a client and free all resources | ||
83 | * that the client allocated (e.g. Sets or Listeners) | ||
84 | * | ||
85 | * @param client the client to disconnect | ||
86 | */ | ||
87 | void | ||
88 | _GSS_client_disconnect (struct GNUNET_SERVER_Client *client) | ||
89 | { | ||
90 | /* FIXME: clean up any data structures belonging to the client */ | ||
91 | GNUNET_SERVER_client_disconnect (client); | ||
92 | } | ||
93 | 80 | ||
94 | 81 | ||
95 | /** | 82 | /** |
@@ -140,13 +127,84 @@ get_incoming (uint32_t id) | |||
140 | { | 127 | { |
141 | struct Incoming *incoming; | 128 | struct Incoming *incoming; |
142 | for (incoming = incoming_head; NULL != incoming; incoming = incoming->next) | 129 | for (incoming = incoming_head; NULL != incoming; incoming = incoming->next) |
143 | if (incoming->request_id == id) | 130 | if (incoming->accept_id == id) |
144 | return incoming; | 131 | return incoming; |
145 | return NULL; | 132 | return NULL; |
146 | } | 133 | } |
147 | 134 | ||
148 | 135 | ||
149 | /** | 136 | /** |
137 | * Destroy a listener, free all resources associated with it. | ||
138 | * | ||
139 | * @param listener listener to destroy | ||
140 | */ | ||
141 | static void | ||
142 | destroy_listener (struct Listener *listener) | ||
143 | { | ||
144 | if (NULL != listener->client_mq) | ||
145 | { | ||
146 | GNUNET_MQ_destroy (listener->client_mq); | ||
147 | listener->client_mq = NULL; | ||
148 | } | ||
149 | if (NULL != listener->client) | ||
150 | { | ||
151 | GNUNET_SERVER_client_drop (listener->client); | ||
152 | listener->client = NULL; | ||
153 | } | ||
154 | |||
155 | GNUNET_CONTAINER_DLL_remove (listeners_head, listeners_tail, listener); | ||
156 | GNUNET_free (listener); | ||
157 | } | ||
158 | |||
159 | |||
160 | /** | ||
161 | * Destroy a set, and free all resources associated with it. | ||
162 | * | ||
163 | * @param set the set to destroy | ||
164 | */ | ||
165 | static void | ||
166 | destroy_set (struct Set *set) | ||
167 | { | ||
168 | switch (set->operation) | ||
169 | { | ||
170 | case GNUNET_SET_OPERATION_INTERSECTION: | ||
171 | GNUNET_assert (0); | ||
172 | break; | ||
173 | case GNUNET_SET_OPERATION_UNION: | ||
174 | _GSS_union_set_destroy (set); | ||
175 | break; | ||
176 | default: | ||
177 | GNUNET_assert (0); | ||
178 | break; | ||
179 | } | ||
180 | GNUNET_CONTAINER_DLL_remove (sets_head, sets_tail, set); | ||
181 | GNUNET_free (set); | ||
182 | } | ||
183 | |||
184 | |||
185 | /** | ||
186 | * Clean up after a client after it is | ||
187 | * disconnected (either by us or by itself) | ||
188 | * | ||
189 | * @param cls closure, unused | ||
190 | * @param client the client to clean up after | ||
191 | */ | ||
192 | void | ||
193 | handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client) | ||
194 | { | ||
195 | struct Set *set; | ||
196 | struct Listener *listener; | ||
197 | |||
198 | set = get_set (client); | ||
199 | if (NULL != set) | ||
200 | destroy_set (set); | ||
201 | listener = get_listener (client); | ||
202 | if (NULL != listener) | ||
203 | destroy_listener (listener); | ||
204 | } | ||
205 | |||
206 | |||
207 | /** | ||
150 | * Destroy an incoming request from a remote peer | 208 | * Destroy an incoming request from a remote peer |
151 | * | 209 | * |
152 | * @param incoming remote request to destroy | 210 | * @param incoming remote request to destroy |
@@ -186,16 +244,16 @@ handle_p2p_operation_request (void *cls, const struct GNUNET_MessageHeader *mh) | |||
186 | struct Listener *listener; | 244 | struct Listener *listener; |
187 | const struct GNUNET_MessageHeader *context_msg; | 245 | const struct GNUNET_MessageHeader *context_msg; |
188 | 246 | ||
189 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "got operation request\n"); | ||
190 | |||
191 | if (ntohs (mh->size) < sizeof *msg) | 247 | if (ntohs (mh->size) < sizeof *msg) |
192 | { | 248 | { |
249 | /* message is to small for its type */ | ||
193 | GNUNET_break (0); | 250 | GNUNET_break (0); |
194 | destroy_incoming (incoming); | 251 | destroy_incoming (incoming); |
195 | return; | 252 | return; |
196 | } | 253 | } |
197 | else if (ntohs (mh->size) == sizeof *msg) | 254 | else if (ntohs (mh->size) == sizeof *msg) |
198 | { | 255 | { |
256 | /* there is no context message */ | ||
199 | context_msg = NULL; | 257 | context_msg = NULL; |
200 | } | 258 | } |
201 | else | 259 | else |
@@ -209,13 +267,17 @@ handle_p2p_operation_request (void *cls, const struct GNUNET_MessageHeader *mh) | |||
209 | return; | 267 | return; |
210 | } | 268 | } |
211 | } | 269 | } |
270 | |||
271 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "received P2P operation request (op %u, app %s)\n", | ||
272 | ntohs (msg->operation), GNUNET_h2s (&msg->app_id)); | ||
273 | |||
212 | /* find the appropriate listener */ | 274 | /* find the appropriate listener */ |
213 | for (listener = listeners_head; | 275 | for (listener = listeners_head; |
214 | listener != NULL; | 276 | listener != NULL; |
215 | listener = listener->next) | 277 | listener = listener->next) |
216 | { | 278 | { |
217 | if ( (0 != GNUNET_CRYPTO_hash_cmp (&msg->app_id, &listener->app_id)) || | 279 | if ( (0 != GNUNET_CRYPTO_hash_cmp (&msg->app_id, &listener->app_id)) || |
218 | (htons (msg->operation) != listener->operation) ) | 280 | (ntohs (msg->operation) != listener->operation) ) |
219 | continue; | 281 | continue; |
220 | mqm = GNUNET_MQ_msg (cmsg, GNUNET_MESSAGE_TYPE_SET_REQUEST); | 282 | mqm = GNUNET_MQ_msg (cmsg, GNUNET_MESSAGE_TYPE_SET_REQUEST); |
221 | if (GNUNET_OK != GNUNET_MQ_nest_mh (mqm, context_msg)) | 283 | if (GNUNET_OK != GNUNET_MQ_nest_mh (mqm, context_msg)) |
@@ -225,11 +287,15 @@ handle_p2p_operation_request (void *cls, const struct GNUNET_MessageHeader *mh) | |||
225 | GNUNET_break (0); | 287 | GNUNET_break (0); |
226 | return; | 288 | return; |
227 | } | 289 | } |
228 | incoming->request_id = request_id++; | 290 | incoming->accept_id = accept_id++; |
229 | cmsg->request_id = htonl (incoming->request_id); | 291 | cmsg->accept_id = htonl (incoming->accept_id); |
230 | GNUNET_MQ_send (listener->client_mq, mqm); | 292 | GNUNET_MQ_send (listener->client_mq, mqm); |
231 | return; | 293 | return; |
232 | } | 294 | } |
295 | |||
296 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
297 | "set operation request from peer failed: " | ||
298 | "no set with matching application ID and operation type\n"); | ||
233 | } | 299 | } |
234 | 300 | ||
235 | 301 | ||
@@ -248,7 +314,8 @@ handle_client_create (void *cls, | |||
248 | struct SetCreateMessage *msg = (struct SetCreateMessage *) m; | 314 | struct SetCreateMessage *msg = (struct SetCreateMessage *) m; |
249 | struct Set *set; | 315 | struct Set *set; |
250 | 316 | ||
251 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "new set created\n"); | 317 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "client created new set (operation %u)\n", |
318 | ntohs (msg->operation)); | ||
252 | 319 | ||
253 | if (NULL != get_set (client)) | 320 | if (NULL != get_set (client)) |
254 | { | 321 | { |
@@ -276,9 +343,9 @@ handle_client_create (void *cls, | |||
276 | } | 343 | } |
277 | 344 | ||
278 | set->client = client; | 345 | set->client = client; |
346 | GNUNET_SERVER_client_keep (client); | ||
279 | set->client_mq = GNUNET_MQ_queue_for_server_client (client); | 347 | set->client_mq = GNUNET_MQ_queue_for_server_client (client); |
280 | GNUNET_CONTAINER_DLL_insert (sets_head, sets_tail, set); | 348 | GNUNET_CONTAINER_DLL_insert (sets_head, sets_tail, set); |
281 | |||
282 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 349 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
283 | } | 350 | } |
284 | 351 | ||
@@ -297,19 +364,22 @@ handle_client_listen (void *cls, | |||
297 | { | 364 | { |
298 | struct ListenMessage *msg = (struct ListenMessage *) m; | 365 | struct ListenMessage *msg = (struct ListenMessage *) m; |
299 | struct Listener *listener; | 366 | struct Listener *listener; |
300 | 367 | ||
301 | if (NULL != get_listener (client)) | 368 | if (NULL != get_listener (client)) |
302 | { | 369 | { |
303 | GNUNET_break (0); | 370 | GNUNET_break (0); |
304 | GNUNET_SERVER_client_disconnect (client); | 371 | GNUNET_SERVER_client_disconnect (client); |
305 | return; | 372 | return; |
306 | } | 373 | } |
307 | |||
308 | listener = GNUNET_new (struct Listener); | 374 | listener = GNUNET_new (struct Listener); |
375 | listener->client = client; | ||
376 | GNUNET_SERVER_client_keep (client); | ||
377 | listener->client_mq = GNUNET_MQ_queue_for_server_client (client); | ||
309 | listener->app_id = msg->app_id; | 378 | listener->app_id = msg->app_id; |
310 | listener->operation = msg->operation; | 379 | listener->operation = ntohs (msg->operation); |
311 | GNUNET_CONTAINER_DLL_insert_tail (listeners_head, listeners_tail, listener); | 380 | GNUNET_CONTAINER_DLL_insert_tail (listeners_head, listeners_tail, listener); |
312 | 381 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "new listener created (op %u, app %s)\n", | |
382 | listener->operation, GNUNET_h2s (&listener->app_id)); | ||
313 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 383 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
314 | } | 384 | } |
315 | 385 | ||
@@ -333,13 +403,13 @@ handle_client_remove (void *cls, | |||
333 | if (NULL == set) | 403 | if (NULL == set) |
334 | { | 404 | { |
335 | GNUNET_break (0); | 405 | GNUNET_break (0); |
336 | _GSS_client_disconnect (client); | 406 | GNUNET_SERVER_client_disconnect (client); |
337 | return; | 407 | return; |
338 | } | 408 | } |
339 | switch (set->operation) | 409 | switch (set->operation) |
340 | { | 410 | { |
341 | case GNUNET_SET_OPERATION_UNION: | 411 | case GNUNET_SET_OPERATION_UNION: |
342 | _GSS_union_add ((struct ElementMessage *) m, set); | 412 | _GSS_union_remove ((struct ElementMessage *) m, set); |
343 | case GNUNET_SET_OPERATION_INTERSECTION: | 413 | case GNUNET_SET_OPERATION_INTERSECTION: |
344 | /* FIXME: cfuchs */ | 414 | /* FIXME: cfuchs */ |
345 | break; | 415 | break; |
@@ -371,13 +441,13 @@ handle_client_add (void *cls, | |||
371 | if (NULL == set) | 441 | if (NULL == set) |
372 | { | 442 | { |
373 | GNUNET_break (0); | 443 | GNUNET_break (0); |
374 | _GSS_client_disconnect (client); | 444 | GNUNET_SERVER_client_disconnect (client); |
375 | return; | 445 | return; |
376 | } | 446 | } |
377 | switch (set->operation) | 447 | switch (set->operation) |
378 | { | 448 | { |
379 | case GNUNET_SET_OPERATION_UNION: | 449 | case GNUNET_SET_OPERATION_UNION: |
380 | _GSS_union_remove ((struct ElementMessage *) m, set); | 450 | _GSS_union_add ((struct ElementMessage *) m, set); |
381 | case GNUNET_SET_OPERATION_INTERSECTION: | 451 | case GNUNET_SET_OPERATION_INTERSECTION: |
382 | /* FIXME: cfuchs */ | 452 | /* FIXME: cfuchs */ |
383 | break; | 453 | break; |
@@ -408,7 +478,7 @@ handle_client_evaluate (void *cls, | |||
408 | if (NULL == set) | 478 | if (NULL == set) |
409 | { | 479 | { |
410 | GNUNET_break (0); | 480 | GNUNET_break (0); |
411 | _GSS_client_disconnect (client); | 481 | GNUNET_SERVER_client_disconnect (client); |
412 | return; | 482 | return; |
413 | } | 483 | } |
414 | 484 | ||
@@ -481,22 +551,30 @@ handle_client_accept (void *cls, | |||
481 | struct Incoming *incoming; | 551 | struct Incoming *incoming; |
482 | struct AcceptMessage *msg = (struct AcceptMessage *) mh; | 552 | struct AcceptMessage *msg = (struct AcceptMessage *) mh; |
483 | 553 | ||
484 | set = get_set (client); | ||
485 | 554 | ||
486 | if (NULL == set) | 555 | incoming = get_incoming (ntohl (msg->accept_id)); |
556 | |||
557 | if (NULL == incoming) | ||
487 | { | 558 | { |
488 | GNUNET_break (0); | 559 | GNUNET_break (0); |
489 | _GSS_client_disconnect (client); | 560 | GNUNET_SERVER_client_disconnect (client); |
490 | return; | 561 | return; |
491 | } | 562 | } |
492 | 563 | ||
493 | incoming = get_incoming (ntohl (msg->request_id)); | 564 | if (0 == ntohl (msg->request_id)) |
565 | { | ||
566 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "peer request rejected by client\n"); | ||
567 | destroy_incoming (incoming); | ||
568 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
569 | return; | ||
570 | } | ||
571 | |||
572 | set = get_set (client); | ||
494 | 573 | ||
495 | if ( (NULL == incoming) || | 574 | if (NULL == set) |
496 | (incoming->operation != set->operation) ) | ||
497 | { | 575 | { |
498 | GNUNET_break (0); | 576 | GNUNET_break (0); |
499 | _GSS_client_disconnect (client); | 577 | GNUNET_SERVER_client_disconnect (client); |
500 | return; | 578 | return; |
501 | } | 579 | } |
502 | 580 | ||
@@ -513,8 +591,10 @@ handle_client_accept (void *cls, | |||
513 | GNUNET_assert (0); | 591 | GNUNET_assert (0); |
514 | break; | 592 | break; |
515 | } | 593 | } |
516 | /* FIXME: destroy incoming */ | ||
517 | 594 | ||
595 | /* note: _GSS_*_accept has to make sure the socket and mq are set to NULL, | ||
596 | * otherwise they will be destroyed and disconnected */ | ||
597 | destroy_incoming (incoming); | ||
518 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 598 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
519 | } | 599 | } |
520 | 600 | ||
@@ -574,6 +654,21 @@ shutdown_task (void *cls, | |||
574 | stream_listen_socket = NULL; | 654 | stream_listen_socket = NULL; |
575 | } | 655 | } |
576 | 656 | ||
657 | while (NULL != incoming_head) | ||
658 | { | ||
659 | destroy_incoming (incoming_head); | ||
660 | } | ||
661 | |||
662 | while (NULL != listeners_head) | ||
663 | { | ||
664 | destroy_listener (listeners_head); | ||
665 | } | ||
666 | |||
667 | while (NULL != sets_head) | ||
668 | { | ||
669 | destroy_set (sets_head); | ||
670 | } | ||
671 | |||
577 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "handled shutdown request\n"); | 672 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "handled shutdown request\n"); |
578 | } | 673 | } |
579 | 674 | ||
@@ -604,6 +699,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, | |||
604 | 699 | ||
605 | configuration = cfg; | 700 | configuration = cfg; |
606 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, NULL); | 701 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, NULL); |
702 | GNUNET_SERVER_disconnect_notify (server, handle_client_disconnect, NULL); | ||
607 | GNUNET_SERVER_add_handlers (server, server_handlers); | 703 | GNUNET_SERVER_add_handlers (server, server_handlers); |
608 | stream_listen_socket = GNUNET_STREAM_listen (cfg, GNUNET_APPLICATION_TYPE_SET, | 704 | stream_listen_socket = GNUNET_STREAM_listen (cfg, GNUNET_APPLICATION_TYPE_SET, |
609 | &stream_listen_cb, NULL, | 705 | &stream_listen_cb, NULL, |