aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/set/gnunet-service-set.c142
-rw-r--r--src/set/gnunet-service-set.h12
-rw-r--r--src/set/gnunet-service-set_union.c6
3 files changed, 100 insertions, 60 deletions
diff --git a/src/set/gnunet-service-set.c b/src/set/gnunet-service-set.c
index bab29b097..cfc0068ab 100644
--- a/src/set/gnunet-service-set.c
+++ b/src/set/gnunet-service-set.c
@@ -91,6 +91,7 @@ static struct Set *
91set_get (struct GNUNET_SERVER_Client *client) 91set_get (struct GNUNET_SERVER_Client *client)
92{ 92{
93 struct Set *set; 93 struct Set *set;
94
94 for (set = sets_head; NULL != set; set = set->next) 95 for (set = sets_head; NULL != set; set = set->next)
95 if (set->client == client) 96 if (set->client == client)
96 return set; 97 return set;
@@ -99,16 +100,17 @@ set_get (struct GNUNET_SERVER_Client *client)
99 100
100 101
101/** 102/**
102 * Get the listener associated to a client, if any. 103 * Get the listener associated with the given client, if any.
103 * 104 *
104 * @param client the client 105 * @param client the client
105 * @return listener associated with the client, NULL 106 * @return listener associated with the client, NULL
106 * if there isn't any 107 * if there isn't any
107 */ 108 */
108static struct Listener * 109static struct Listener *
109get_listener (struct GNUNET_SERVER_Client *client) 110listener_get (struct GNUNET_SERVER_Client *client)
110{ 111{
111 struct Listener *listener; 112 struct Listener *listener;
113
112 for (listener = listeners_head; NULL != listener; listener = listener->next) 114 for (listener = listeners_head; NULL != listener; listener = listener->next)
113 if (listener->client == client) 115 if (listener->client == client)
114 return listener; 116 return listener;
@@ -127,6 +129,7 @@ static struct Incoming *
127get_incoming (uint32_t id) 129get_incoming (uint32_t id)
128{ 130{
129 struct Incoming *incoming; 131 struct Incoming *incoming;
132
130 for (incoming = incoming_head; NULL != incoming; incoming = incoming->next) 133 for (incoming = incoming_head; NULL != incoming; incoming = incoming->next)
131 if (incoming->accept_id == id) 134 if (incoming->accept_id == id)
132 return incoming; 135 return incoming;
@@ -193,7 +196,7 @@ handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
193 set = set_get (client); 196 set = set_get (client);
194 if (NULL != set) 197 if (NULL != set)
195 set_destroy (set); 198 set_destroy (set);
196 listener = get_listener (client); 199 listener = listener_get (client);
197 if (NULL != listener) 200 if (NULL != listener)
198 listener_destroy (listener); 201 listener_destroy (listener);
199} 202}
@@ -207,20 +210,13 @@ handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
207static void 210static void
208incoming_destroy (struct Incoming *incoming) 211incoming_destroy (struct Incoming *incoming)
209{ 212{
210 if (NULL != incoming->tc)
211 {
212 GNUNET_free (incoming->tc);
213 GNUNET_assert (NULL != incoming->tc->tunnel);
214 GNUNET_MESH_tunnel_destroy (incoming->tc->tunnel);
215 incoming->tc = NULL;
216 }
217 GNUNET_CONTAINER_DLL_remove (incoming_head, incoming_tail, incoming); 213 GNUNET_CONTAINER_DLL_remove (incoming_head, incoming_tail, incoming);
218 GNUNET_free (incoming); 214 GNUNET_free (incoming);
219} 215}
220 216
221 217
222static struct Listener * 218static struct Listener *
223get_listener_by_target (enum GNUNET_SET_OperationType op, 219listener_get_by_target (enum GNUNET_SET_OperationType op,
224 const struct GNUNET_HashCode *app_id) 220 const struct GNUNET_HashCode *app_id)
225{ 221{
226 struct Listener *l; 222 struct Listener *l;
@@ -237,12 +233,31 @@ get_listener_by_target (enum GNUNET_SET_OperationType op,
237} 233}
238 234
239 235
240 236/**
237 * Suggest the given request to the listener,
238 * who can accept or reject the request.
239 *
240 * @param incoming the incoming peer with the request to suggest
241 * @param listener the listener to suggest the request to
242 */
241static void 243static void
242tunnel_context_destroy (struct TunnelContext *tc) 244incoming_suggest (struct Incoming *incoming, struct Listener *listener)
243{ 245{
244 GNUNET_free (tc); 246 struct GNUNET_MQ_Envelope *mqm;
245 /* FIXME destroy the rest */ 247 struct GNUNET_SET_RequestMessage *cmsg;
248
249 GNUNET_assert (GNUNET_NO == incoming->suggested);
250 incoming->suggested = GNUNET_YES;
251
252 GNUNET_SCHEDULER_cancel (incoming->timeout_task);
253 mqm = GNUNET_MQ_msg_nested_mh (cmsg, GNUNET_MESSAGE_TYPE_SET_REQUEST,
254 incoming->context_msg);
255 GNUNET_assert (NULL != mqm);
256 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "suggesting request with accept id %u\n", incoming->accept_id);
257 cmsg->accept_id = htonl (incoming->accept_id);
258 cmsg->peer_id = incoming->tc->peer;
259 GNUNET_MQ_send (listener->client_mq, mqm);
260
246} 261}
247 262
248 263
@@ -264,49 +279,46 @@ handle_p2p_operation_request (void *cls,
264 struct TunnelContext *tc = *tunnel_ctx; 279 struct TunnelContext *tc = *tunnel_ctx;
265 struct Incoming *incoming; 280 struct Incoming *incoming;
266 const struct OperationRequestMessage *msg = (const struct OperationRequestMessage *) mh; 281 const struct OperationRequestMessage *msg = (const struct OperationRequestMessage *) mh;
267 struct GNUNET_MQ_Envelope *mqm;
268 struct GNUNET_SET_RequestMessage *cmsg;
269 struct Listener *listener; 282 struct Listener *listener;
270 const struct GNUNET_MessageHeader *context_msg;
271 283
272 if (CONTEXT_INCOMING != tc->type) 284 if (CONTEXT_INCOMING != tc->type)
273 { 285 {
274 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "unexpected operation request\n"); 286 /* unexpected request */
275 tunnel_context_destroy (tc); 287 GNUNET_break_op (0);
276 /* don't kill the whole mesh connection */ 288 /* kill the tunnel, cleaner will be called */
277 return GNUNET_OK; 289 return GNUNET_SYSERR;
278 } 290 }
279 291
280 incoming = tc->data; 292 incoming = tc->data;
281 293
282 context_msg = GNUNET_MQ_extract_nested_mh (msg); 294 if (GNUNET_YES == incoming->received_request)
283 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "received P2P operation request (op %u, app %s)\n",
284 ntohs (msg->operation), GNUNET_h2s (&msg->app_id));
285 listener = get_listener_by_target (ntohs (msg->operation), &msg->app_id);
286 if (NULL == listener)
287 { 295 {
288 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 296 /* double operation request */
289 "set operation request from peer failed: " 297 GNUNET_break_op (0);
290 "no set with matching application ID and operation type\n"); 298 return GNUNET_SYSERR;
291 tunnel_context_destroy (tc);
292 /* don't kill the whole mesh connection */
293 return GNUNET_OK;
294 } 299 }
295 mqm = GNUNET_MQ_msg_nested_mh (cmsg, GNUNET_MESSAGE_TYPE_SET_REQUEST, context_msg); 300
296 if (NULL == mqm) 301 incoming->accept_id = accept_id++;
302 incoming->context_msg =
303 GNUNET_copy_message (GNUNET_MQ_extract_nested_mh (msg));
304
305 if ( (NULL != incoming->context_msg) &&
306 (ntohs (incoming->context_msg->size) > GNUNET_SET_CONTEXT_MESSAGE_MAX_SIZE) )
297 { 307 {
298 /* FIXME: disconnect the peer */
299 GNUNET_break_op (0); 308 GNUNET_break_op (0);
300 tunnel_context_destroy (tc); 309 return GNUNET_SYSERR;
301 /* don't kill the whole mesh connection */
302 return GNUNET_OK;
303 } 310 }
304 incoming->accept_id = accept_id++;
305 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "sending request with accept id %u\n", incoming->accept_id);
306 cmsg->accept_id = htonl (incoming->accept_id);
307 cmsg->peer_id = incoming->tc->peer;
308 GNUNET_MQ_send (listener->client_mq, mqm);
309 311
312 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "received P2P operation request (op %u, app %s)\n",
313 ntohs (msg->operation), GNUNET_h2s (&msg->app_id));
314 listener = listener_get_by_target (ntohs (msg->operation), &msg->app_id);
315 if (NULL == listener)
316 {
317 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
318 "no listener matches incoming request, waiting with timeout\n");
319 return GNUNET_OK;
320 }
321 incoming_suggest (incoming, listener);
310 return GNUNET_OK; 322 return GNUNET_OK;
311} 323}
312 324
@@ -375,8 +387,9 @@ handle_client_listen (void *cls,
375{ 387{
376 struct GNUNET_SET_ListenMessage *msg = (struct GNUNET_SET_ListenMessage *) m; 388 struct GNUNET_SET_ListenMessage *msg = (struct GNUNET_SET_ListenMessage *) m;
377 struct Listener *listener; 389 struct Listener *listener;
390 struct Incoming *incoming;
378 391
379 if (NULL != get_listener (client)) 392 if (NULL != listener_get (client))
380 { 393 {
381 GNUNET_break (0); 394 GNUNET_break (0);
382 GNUNET_SERVER_client_disconnect (client); 395 GNUNET_SERVER_client_disconnect (client);
@@ -390,6 +403,17 @@ handle_client_listen (void *cls,
390 GNUNET_CONTAINER_DLL_insert_tail (listeners_head, listeners_tail, listener); 403 GNUNET_CONTAINER_DLL_insert_tail (listeners_head, listeners_tail, listener);
391 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "new listener created (op %u, app %s)\n", 404 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "new listener created (op %u, app %s)\n",
392 listener->operation, GNUNET_h2s (&listener->app_id)); 405 listener->operation, GNUNET_h2s (&listener->app_id));
406 for (incoming = incoming_head; NULL != incoming; incoming = incoming->next)
407 {
408 if ( (GNUNET_NO == incoming->received_request) ||
409 (GNUNET_YES == incoming->suggested) )
410 continue;
411 if (listener->operation != incoming->operation)
412 continue;
413 if (0 != GNUNET_CRYPTO_hash_cmp (&listener->app_id, &incoming->app_id))
414 continue;
415 incoming_suggest (incoming, listener);
416 }
393 GNUNET_SERVER_receive_done (client, GNUNET_OK); 417 GNUNET_SERVER_receive_done (client, GNUNET_OK);
394} 418}
395 419
@@ -459,7 +483,8 @@ handle_client_reject (void *cls,
459 return; 483 return;
460 } 484 }
461 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "peer request rejected by client\n"); 485 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "peer request rejected by client\n");
462 incoming_destroy (incoming); 486 /* the incoming peer will be destroyed in the tunnel end handler */
487 GNUNET_MESH_tunnel_destroy (incoming->tc->tunnel);
463 GNUNET_SERVER_receive_done (client, GNUNET_OK); 488 GNUNET_SERVER_receive_done (client, GNUNET_OK);
464} 489}
465 490
@@ -475,8 +500,8 @@ handle_client_reject (void *cls,
475 */ 500 */
476static void 501static void
477handle_client_add (void *cls, 502handle_client_add (void *cls,
478 struct GNUNET_SERVER_Client *client, 503 struct GNUNET_SERVER_Client *client,
479 const struct GNUNET_MessageHeader *m) 504 const struct GNUNET_MessageHeader *m)
480{ 505{
481 struct Set *set; 506 struct Set *set;
482 507
@@ -611,7 +636,7 @@ handle_client_accept (void *cls,
611 break; 636 break;
612 } 637 }
613 638
614 /* note: _GSS_*_accept has to make sure the socket and mq are set to NULL, 639 /* note: _GSS_*_accept has to make sure the tunnel and mq are set to NULL,
615 * otherwise they will be destroyed and disconnected */ 640 * otherwise they will be destroyed and disconnected */
616 incoming_destroy (incoming); 641 incoming_destroy (incoming);
617 GNUNET_SERVER_receive_done (client, GNUNET_OK); 642 GNUNET_SERVER_receive_done (client, GNUNET_OK);
@@ -635,19 +660,13 @@ shutdown_task (void *cls,
635 } 660 }
636 661
637 while (NULL != incoming_head) 662 while (NULL != incoming_head)
638 {
639 incoming_destroy (incoming_head); 663 incoming_destroy (incoming_head);
640 }
641 664
642 while (NULL != listeners_head) 665 while (NULL != listeners_head)
643 {
644 listener_destroy (listeners_head); 666 listener_destroy (listeners_head);
645 }
646 667
647 while (NULL != sets_head) 668 while (NULL != sets_head)
648 {
649 set_destroy (sets_head); 669 set_destroy (sets_head);
650 }
651 670
652 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "handled shutdown request\n"); 671 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "handled shutdown request\n");
653} 672}
@@ -706,7 +725,8 @@ tunnel_new_cb (void *cls,
706 tc->mq = GNUNET_MESH_mq_create (tunnel); 725 tc->mq = GNUNET_MESH_mq_create (tunnel);
707 tc->data = incoming; 726 tc->data = incoming;
708 tc->type = CONTEXT_INCOMING; 727 tc->type = CONTEXT_INCOMING;
709 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, incoming_timeout_cb, incoming); 728 incoming->timeout_task =
729 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, incoming_timeout_cb, incoming);
710 GNUNET_CONTAINER_DLL_insert_tail (incoming_head, incoming_tail, incoming); 730 GNUNET_CONTAINER_DLL_insert_tail (incoming_head, incoming_tail, incoming);
711 731
712 return tc; 732 return tc;
@@ -730,6 +750,15 @@ tunnel_end_cb (void *cls,
730{ 750{
731 struct TunnelContext *ctx = tunnel_ctx; 751 struct TunnelContext *ctx = tunnel_ctx;
732 752
753 /* tunnel is dead already */
754 ctx->tunnel = NULL;
755
756 if (NULL != ctx->mq)
757 {
758 GNUNET_MQ_destroy (ctx->mq);
759 ctx->mq = NULL;
760 }
761
733 switch (ctx->type) 762 switch (ctx->type)
734 { 763 {
735 case CONTEXT_INCOMING: 764 case CONTEXT_INCOMING:
@@ -746,6 +775,7 @@ tunnel_end_cb (void *cls,
746 GNUNET_assert (0); 775 GNUNET_assert (0);
747 } 776 }
748 777
778 GNUNET_free (tunnel_ctx);
749} 779}
750 780
751 781
diff --git a/src/set/gnunet-service-set.h b/src/set/gnunet-service-set.h
index d60b5f477..533fd0ef7 100644
--- a/src/set/gnunet-service-set.h
+++ b/src/set/gnunet-service-set.h
@@ -186,11 +186,23 @@ struct Incoming
186 enum GNUNET_SET_OperationType operation; 186 enum GNUNET_SET_OperationType operation;
187 187
188 /** 188 /**
189 * Has the incoming request been suggested to
190 * a client listener yet?
191 */
192 int suggested;
193
194 /**
189 * Unique request id for the request from 195 * Unique request id for the request from
190 * a remote peer, sent to the client, which will 196 * a remote peer, sent to the client, which will
191 * accept or reject the request. 197 * accept or reject the request.
192 */ 198 */
193 uint32_t accept_id; 199 uint32_t accept_id;
200
201 /**
202 * Timeout task, if the incoming peer has not been accepted
203 * after the timeout, it will be disconnected.
204 */
205 GNUNET_SCHEDULER_TaskIdentifier timeout_task;
194}; 206};
195 207
196 208
diff --git a/src/set/gnunet-service-set_union.c b/src/set/gnunet-service-set_union.c
index 670626cd4..5b1f28cf4 100644
--- a/src/set/gnunet-service-set_union.c
+++ b/src/set/gnunet-service-set_union.c
@@ -1370,9 +1370,8 @@ _GSS_union_handle_p2p_message (void *cls,
1370 1370
1371 if (CONTEXT_OPERATION_UNION != tc->type) 1371 if (CONTEXT_OPERATION_UNION != tc->type)
1372 { 1372 {
1373 /* FIXME: kill the tunnel */ 1373 GNUNET_break_op (0);
1374 /* never kill mesh */ 1374 return GNUNET_SYSERR;
1375 return GNUNET_OK;
1376 } 1375 }
1377 1376
1378 eo = tc->data; 1377 eo = tc->data;
@@ -1398,6 +1397,5 @@ _GSS_union_handle_p2p_message (void *cls,
1398 /* something wrong with mesh's message handlers? */ 1397 /* something wrong with mesh's message handlers? */
1399 GNUNET_assert (0); 1398 GNUNET_assert (0);
1400 } 1399 }
1401 /* never kill mesh! */
1402 return GNUNET_OK; 1400 return GNUNET_OK;
1403} 1401}