aboutsummaryrefslogtreecommitdiff
path: root/src/set/gnunet-service-set.c
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2013-05-15 10:48:55 +0000
committerFlorian Dold <florian.dold@gmail.com>2013-05-15 10:48:55 +0000
commit6f54b50858457dfa2b5f0b519fbf230e1119c6b2 (patch)
tree5f84bfa599cb50522999cad892344e2fecbfa963 /src/set/gnunet-service-set.c
parent6625c27a83831b61a80683f4385b6a90b9a45b31 (diff)
downloadgnunet-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.c180
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;
72static struct Incoming *incoming_tail; 72static 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 */
78static uint32_t request_id = 1; 79static 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 */
87void
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 */
141static void
142destroy_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 */
165static void
166destroy_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 */
192void
193handle_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,