aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGabor X Toth <*@tg-x.net>2014-05-26 22:16:05 +0000
committerGabor X Toth <*@tg-x.net>2014-05-26 22:16:05 +0000
commit83495695331fcfa8824d7a6d407b82cfcfc8b13c (patch)
tree2d2a7717d81890f5142da9561bccf9e164b1deee /src
parent1cfab01aaea932539c39dcb2118ec4d6c6d44381 (diff)
downloadgnunet-83495695331fcfa8824d7a6d407b82cfcfc8b13c.tar.gz
gnunet-83495695331fcfa8824d7a6d407b82cfcfc8b13c.zip
psyc, multicast: join decision, tests
Diffstat (limited to 'src')
-rw-r--r--src/include/gnunet_multicast_service.h67
-rw-r--r--src/include/gnunet_psyc_service.h119
-rw-r--r--src/multicast/Makefile.am2
-rw-r--r--src/multicast/gnunet-service-multicast.c160
-rw-r--r--src/multicast/multicast.h51
-rw-r--r--src/multicast/multicast_api.c120
-rw-r--r--src/psyc/gnunet-service-psyc.c261
-rw-r--r--src/psyc/psyc.h19
-rw-r--r--src/psyc/psyc_api.c147
-rw-r--r--src/psyc/test_psyc.c86
10 files changed, 665 insertions, 367 deletions
diff --git a/src/include/gnunet_multicast_service.h b/src/include/gnunet_multicast_service.h
index 7ceb2e352..5079a087b 100644
--- a/src/include/gnunet_multicast_service.h
+++ b/src/include/gnunet_multicast_service.h
@@ -230,7 +230,7 @@ GNUNET_NETWORK_STRUCT_END
230/** 230/**
231 * Handle that identifies a join request. 231 * Handle that identifies a join request.
232 * 232 *
233 * Used to match calls to #GNUNET_MULTICAST_JoinCallback to the 233 * Used to match calls to #GNUNET_MULTICAST_JoinRequestCallback to the
234 * corresponding calls to #GNUNET_MULTICAST_join_decision(). 234 * corresponding calls to #GNUNET_MULTICAST_join_decision().
235 */ 235 */
236struct GNUNET_MULTICAST_JoinHandle; 236struct GNUNET_MULTICAST_JoinHandle;
@@ -240,11 +240,12 @@ struct GNUNET_MULTICAST_JoinHandle;
240 * Function to call with the decision made for a join request. 240 * Function to call with the decision made for a join request.
241 * 241 *
242 * Must be called once and only once in response to an invocation of the 242 * Must be called once and only once in response to an invocation of the
243 * #GNUNET_MULTICAST_JoinCallback. 243 * #GNUNET_MULTICAST_JoinRequestCallback.
244 * 244 *
245 * @param jh Join request handle. 245 * @param jh Join request handle.
246 * @param is_admitted #GNUNET_YES if joining is approved, 246 * @param is_admitted #GNUNET_YES if the join is approved,
247 * #GNUNET_NO if it is disapproved 247 * #GNUNET_NO if it is disapproved,
248 * #GNUNET_SYSERR if we cannot answer the request.
248 * @param relay_count Number of relays given. 249 * @param relay_count Number of relays given.
249 * @param relays Array of suggested peers that might be useful relays to use 250 * @param relays Array of suggested peers that might be useful relays to use
250 * when joining the multicast group (essentially a list of peers that 251 * when joining the multicast group (essentially a list of peers that
@@ -261,7 +262,7 @@ struct GNUNET_MULTICAST_JoinHandle;
261struct GNUNET_MULTICAST_ReplayHandle * 262struct GNUNET_MULTICAST_ReplayHandle *
262GNUNET_MULTICAST_join_decision (struct GNUNET_MULTICAST_JoinHandle *jh, 263GNUNET_MULTICAST_join_decision (struct GNUNET_MULTICAST_JoinHandle *jh,
263 int is_admitted, 264 int is_admitted,
264 unsigned int relay_count, 265 uint16_t relay_count,
265 const struct GNUNET_PeerIdentity *relays, 266 const struct GNUNET_PeerIdentity *relays,
266 const struct GNUNET_MessageHeader *join_resp); 267 const struct GNUNET_MessageHeader *join_resp);
267 268
@@ -273,16 +274,40 @@ GNUNET_MULTICAST_join_decision (struct GNUNET_MULTICAST_JoinHandle *jh,
273 * with the decision. 274 * with the decision.
274 * 275 *
275 * @param cls Closure. 276 * @param cls Closure.
276 * @param peer Identity of the member that wants to join. 277 * @param member_key Public key of the member requesting join.
277 * @param member_key Requesting member's public key.
278 * @param join_msg Application-dependent join message from the new member. 278 * @param join_msg Application-dependent join message from the new member.
279 * @param jh Join handle to pass to GNUNET_MULTICAST_join_decison(). 279 * @param jh Join handle to pass to GNUNET_MULTICAST_join_decison().
280 */ 280 */
281typedef void 281typedef void
282(*GNUNET_MULTICAST_JoinCallback) (void *cls, 282(*GNUNET_MULTICAST_JoinRequestCallback) (void *cls,
283 const struct GNUNET_CRYPTO_EddsaPublicKey *member_key, 283 const struct GNUNET_CRYPTO_EddsaPublicKey *member_key,
284 const struct GNUNET_MessageHeader *join_msg, 284 const struct GNUNET_MessageHeader *join_msg,
285 struct GNUNET_MULTICAST_JoinHandle *jh); 285 struct GNUNET_MULTICAST_JoinHandle *jh);
286
287
288/**
289 * Method called to inform about the decision in response to a join request.
290 *
291 * If @a is_admitted is not #GNUNET_YES, then the multicast service disconnects
292 * the client and the multicast member handle returned by
293 * GNUNET_MULTICAST_member_join() is invalidated.
294 *
295 * @param cls Closure.
296 * @param is_admitted #GNUNET_YES or #GNUNET_NO or #GNUNET_SYSERR
297 * @param peer The peer we are connected to and the join decision is from.
298 * @param relay_count Number of peers in the @a relays array.
299 * @param relays Peer identities of members of the group, which serve as relays
300 * and can be used to join the group at. If empty, only the origin can
301 * be used to connect to the group.
302 * @param join_msg Application-dependent join message from the origin.
303 */
304typedef void
305(*GNUNET_MULTICAST_JoinDecisionCallback) (void *cls,
306 int is_admitted,
307 const struct GNUNET_PeerIdentity *peer,
308 uint16_t relay_count,
309 const struct GNUNET_PeerIdentity *relays,
310 const struct GNUNET_MessageHeader *join_msg);
286 311
287 312
288/** 313/**
@@ -542,9 +567,9 @@ GNUNET_MULTICAST_replay_response2 (struct GNUNET_MULTICAST_ReplayHandle *rh,
542 * @param cfg Configuration to use. 567 * @param cfg Configuration to use.
543 * @param priv_key ECC key that will be used to sign messages for this 568 * @param priv_key ECC key that will be used to sign messages for this
544 * multicast session; public key is used to identify the multicast group; 569 * multicast session; public key is used to identify the multicast group;
545 * @param next_fragment_id Next fragment ID to continue counting fragments from 570 * @param max_fragment_id Maximum fragment ID already sent to the group.
546 * when restarting the origin. 1 for a new group. 571 * 0 for a new group.
547 * @param join_cb Function called to approve / disapprove joining of a peer. 572 * @param join_request_cb Function called to approve / disapprove joining of a peer.
548 * @param member_test_cb Function multicast can use to test group membership. 573 * @param member_test_cb Function multicast can use to test group membership.
549 * @param replay_frag_cb Function that can be called to replay a message fragment. 574 * @param replay_frag_cb Function that can be called to replay a message fragment.
550 * @param replay_msg_cb Function that can be called to replay a message. 575 * @param replay_msg_cb Function that can be called to replay a message.
@@ -558,8 +583,8 @@ GNUNET_MULTICAST_replay_response2 (struct GNUNET_MULTICAST_ReplayHandle *rh,
558struct GNUNET_MULTICAST_Origin * 583struct GNUNET_MULTICAST_Origin *
559GNUNET_MULTICAST_origin_start (const struct GNUNET_CONFIGURATION_Handle *cfg, 584GNUNET_MULTICAST_origin_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
560 const struct GNUNET_CRYPTO_EddsaPrivateKey *priv_key, 585 const struct GNUNET_CRYPTO_EddsaPrivateKey *priv_key,
561 uint64_t next_fragment_id, 586 uint64_t max_fragment_id,
562 GNUNET_MULTICAST_JoinCallback join_cb, 587 GNUNET_MULTICAST_JoinRequestCallback join_request_cb,
563 GNUNET_MULTICAST_MembershipTestCallback member_test_cb, 588 GNUNET_MULTICAST_MembershipTestCallback member_test_cb,
564 GNUNET_MULTICAST_ReplayFragmentCallback replay_frag_cb, 589 GNUNET_MULTICAST_ReplayFragmentCallback replay_frag_cb,
565 GNUNET_MULTICAST_ReplayMessageCallback replay_msg_cb, 590 GNUNET_MULTICAST_ReplayMessageCallback replay_msg_cb,
@@ -667,11 +692,12 @@ GNUNET_MULTICAST_origin_stop (struct GNUNET_MULTICAST_Origin *origin);
667 * of multicast messages. 692 * of multicast messages.
668 * @param relay_count Number of peers in the @a relays array. 693 * @param relay_count Number of peers in the @a relays array.
669 * @param relays Peer identities of members of the group, which serve as relays 694 * @param relays Peer identities of members of the group, which serve as relays
670 * and can be used to join the group at. and send the @a join_request to. 695 * and can be used to join the group at and send the @a join_request to.
671 * If empty, the @a join_request is sent directly to the @a origin. 696 * If empty, the @a join_request is sent directly to the @a origin.
672 * @param join_msg Application-dependent join message to be passed to the 697 * @param join_msg Application-dependent join message to be passed to the
673 * @a origin. 698 * @a origin.
674 * @param join_cb Function called to approve / disapprove joining of a peer. 699 * @param join_request_cb Function called to approve / disapprove joining of a peer.
700 * @param join_decision_cb Function called to inform about the join decision.
675 * @param mem_test_cb Function multicast can use to test group membership. 701 * @param mem_test_cb Function multicast can use to test group membership.
676 * @param replay_frag_cb Function that can be called to replay message fragments 702 * @param replay_frag_cb Function that can be called to replay message fragments
677 * this peer already knows from this group. NULL if this 703 * this peer already knows from this group. NULL if this
@@ -690,10 +716,11 @@ GNUNET_MULTICAST_member_join (const struct GNUNET_CONFIGURATION_Handle *cfg,
690 const struct GNUNET_CRYPTO_EddsaPublicKey *group_key, 716 const struct GNUNET_CRYPTO_EddsaPublicKey *group_key,
691 const struct GNUNET_CRYPTO_EddsaPrivateKey *member_key, 717 const struct GNUNET_CRYPTO_EddsaPrivateKey *member_key,
692 const struct GNUNET_PeerIdentity *origin, 718 const struct GNUNET_PeerIdentity *origin,
693 uint32_t relay_count, 719 uint16_t relay_count,
694 const struct GNUNET_PeerIdentity *relays, 720 const struct GNUNET_PeerIdentity *relays,
695 const struct GNUNET_MessageHeader *join_request, 721 const struct GNUNET_MessageHeader *join_request,
696 GNUNET_MULTICAST_JoinCallback join_cb, 722 GNUNET_MULTICAST_JoinRequestCallback join_request_cb,
723 GNUNET_MULTICAST_JoinDecisionCallback join_decision_cb,
697 GNUNET_MULTICAST_MembershipTestCallback mem_test_cb, 724 GNUNET_MULTICAST_MembershipTestCallback mem_test_cb,
698 GNUNET_MULTICAST_ReplayFragmentCallback replay_frag_cb, 725 GNUNET_MULTICAST_ReplayFragmentCallback replay_frag_cb,
699 GNUNET_MULTICAST_ReplayMessageCallback replay_msg_cb, 726 GNUNET_MULTICAST_ReplayMessageCallback replay_msg_cb,
diff --git a/src/include/gnunet_psyc_service.h b/src/include/gnunet_psyc_service.h
index 2ae20adc5..4f4c99c1f 100644
--- a/src/include/gnunet_psyc_service.h
+++ b/src/include/gnunet_psyc_service.h
@@ -325,17 +325,18 @@ typedef void
325/** 325/**
326 * Method called from PSYC upon receiving a join request. 326 * Method called from PSYC upon receiving a join request.
327 * 327 *
328 * @param cls Closure. 328 * @param cls Closure.
329 * @param slave requesting to join. 329 * @param slave_key Public key of the slave requesting join.
330 * @param join_msg Join message sent along with the request. 330 * @param join_msg Join message sent along with the request.
331 * @param jh Join handle to use with GNUNET_PSYC_join_decision() 331 * @param jh Join handle to use with GNUNET_PSYC_join_decision()
332 */ 332 */
333typedef void 333typedef void
334(*GNUNET_PSYC_JoinCallback) (void *cls, 334(*GNUNET_PSYC_JoinRequestCallback) (void *cls,
335 const struct GNUNET_CRYPTO_EddsaPublicKey 335 const struct
336 *slave_key, 336 GNUNET_CRYPTO_EddsaPublicKey *slave_key,
337 const struct GNUNET_PSYC_MessageHeader *join_msg, 337 const struct
338 struct GNUNET_PSYC_JoinHandle *jh); 338 GNUNET_PSYC_MessageHeader *join_msg,
339 struct GNUNET_PSYC_JoinHandle *jh);
339 340
340 341
341/** 342/**
@@ -344,32 +345,30 @@ typedef void
344 * Must be called once and only once in response to an invocation of the 345 * Must be called once and only once in response to an invocation of the
345 * #GNUNET_PSYC_JoinCallback. 346 * #GNUNET_PSYC_JoinCallback.
346 * 347 *
347 * @param jh Join request handle. 348 * @param jh Join request handle.
348 * @param is_admitted #GNUNET_YES if joining is approved, 349 * @param is_admitted #GNUNET_YES if the join is approved,
349 * #GNUNET_NO if it is disapproved. 350 * #GNUNET_NO if it is disapproved,
350 * @param relay_count Number of relays given. 351 * #GNUNET_SYSERR if we cannot answer the request.
351 * @param relays Array of suggested peers that might be useful relays to use 352 * @param relay_count Number of relays given.
353 * @param relays Array of suggested peers that might be useful relays to use
352 * when joining the multicast group (essentially a list of peers that 354 * when joining the multicast group (essentially a list of peers that
353 * are already part of the multicast group and might thus be willing 355 * are already part of the multicast group and might thus be willing
354 * to help with routing). If empty, only this local peer (which must 356 * to help with routing). If empty, only this local peer (which must
355 * be the multicast origin) is a good candidate for building the 357 * be the multicast origin) is a good candidate for building the
356 * multicast tree. Note that it is unnecessary to specify our own 358 * multicast tree. Note that it is unnecessary to specify our own
357 * peer identity in this array. 359 * peer identity in this array.
358 * @param method_name Method name for the message transmitted with the response. 360 * @param join_resp Application-dependent join response message to send along
359 * @param env Environment containing transient variables for the message, 361 * with the decision.
360 * or NULL. 362 *
361 * @param data Data of the message. 363 * @return #GNUNET_OK on success,
362 * @param data_size Size of @a data. 364 * #GNUNET_SYSERR if @a join_resp is too large.
363 */ 365 */
364void 366int
365GNUNET_PSYC_join_decision (struct GNUNET_PSYC_JoinHandle *jh, 367GNUNET_PSYC_join_decision (struct GNUNET_PSYC_JoinHandle *jh,
366 int is_admitted, 368 int is_admitted,
367 uint32_t relay_count, 369 uint32_t relay_count,
368 const struct GNUNET_PeerIdentity *relays, 370 const struct GNUNET_PeerIdentity *relays,
369 const char *method_name, 371 const struct GNUNET_PSYC_MessageHeader *join_resp);
370 const struct GNUNET_ENV_Environment *env,
371 const void *data,
372 size_t data_size);
373 372
374 373
375/** 374/**
@@ -400,29 +399,31 @@ typedef void
400 * or part messages, the respective methods must call other PSYC functions to 399 * or part messages, the respective methods must call other PSYC functions to
401 * inform PSYC about the meaning of the respective events. 400 * inform PSYC about the meaning of the respective events.
402 * 401 *
403 * @param cfg Configuration to use (to connect to PSYC service). 402 * @param cfg Configuration to use (to connect to PSYC service).
404 * @param channel_key ECC key that will be used to sign messages for this 403 * @param channel_key ECC key that will be used to sign messages for this
405 * PSYC session. The public key is used to identify the PSYC channel. 404 * PSYC session. The public key is used to identify the PSYC channel.
406 * Note that end-users will usually not use the private key directly, but 405 * Note that end-users will usually not use the private key directly, but
407 * rather look it up in GNS for places managed by other users, or select 406 * rather look it up in GNS for places managed by other users, or select
408 * a file with the private key(s) when setting up their own channels 407 * a file with the private key(s) when setting up their own channels
409 * FIXME: we'll likely want to use NOT the p521 curve here, but a cheaper 408 * FIXME: we'll likely want to use NOT the p521 curve here, but a cheaper
410 * one in the future. 409 * one in the future.
411 * @param policy Channel policy specifying join and history restrictions. 410 * @param policy Channel policy specifying join and history restrictions.
412 * Used to automate join decisions. 411 * Used to automate join decisions.
413 * @param message_cb Function to invoke on message parts received from slaves. 412 * @param master_start_cb Function to invoke after the channel master started.
414 * @param join_cb Function to invoke when a peer wants to join. 413 * @param join_request_cb Function to invoke when a slave wants to join.
415 * @param master_started_cb Function to invoke after the channel master started. 414 * @param message_cb Function to invoke on message parts sent to the channel
416 * @param cls Closure for @a method and @a join_cb. 415 * and received from slaves
416 * @param cls Closure for @a method and @a join_cb.
417 *
417 * @return Handle for the channel master, NULL on error. 418 * @return Handle for the channel master, NULL on error.
418 */ 419 */
419struct GNUNET_PSYC_Master * 420struct GNUNET_PSYC_Master *
420GNUNET_PSYC_master_start (const struct GNUNET_CONFIGURATION_Handle *cfg, 421GNUNET_PSYC_master_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
421 const struct GNUNET_CRYPTO_EddsaPrivateKey *channel_key, 422 const struct GNUNET_CRYPTO_EddsaPrivateKey *channel_key,
422 enum GNUNET_PSYC_Policy policy, 423 enum GNUNET_PSYC_Policy policy,
424 GNUNET_PSYC_MasterStartCallback master_start_cb,
425 GNUNET_PSYC_JoinRequestCallback join_request_cb,
423 GNUNET_PSYC_MessageCallback message_cb, 426 GNUNET_PSYC_MessageCallback message_cb,
424 GNUNET_PSYC_JoinCallback join_cb,
425 GNUNET_PSYC_MasterStartCallback master_started_cb,
426 void *cls); 427 void *cls);
427 428
428 429
@@ -580,13 +581,30 @@ struct GNUNET_PSYC_Slave;
580 581
581 582
582/** 583/**
583 * Function called after the slave joined. 584 * Function called after the slave connected to the PSYC service.
584 * 585 *
585 * @param cls Closure. 586 * @param cls Closure.
586 * @param max_message_id Last message ID sent to the channel. 587 * @param max_message_id Last message ID sent to the channel.
587 */ 588 */
588typedef void 589typedef void
589(*GNUNET_PSYC_SlaveJoinCallback) (void *cls, uint64_t max_message_id); 590(*GNUNET_PSYC_SlaveConnectCallback) (void *cls, uint64_t max_message_id);
591
592
593/**
594 * Method called to inform about the decision in response to a join request.
595 *
596 * If @a is_admitted is not #GNUNET_YES, then sending messages to the channel is
597 * not possible, but earlier history can be still queried.
598 *
599 * @param cls Closure.
600 * @param is_admitted #GNUNET_YES or #GNUNET_NO or #GNUNET_SYSERR
601 * @param join_msg Application-dependent join message from the origin.
602 */
603typedef void
604(*GNUNET_PSYC_JoinDecisionCallback) (void *cls,
605 int is_admitted,
606 const struct
607 GNUNET_PSYC_MessageHeader *join_msg);
590 608
591 609
592/** 610/**
@@ -599,24 +617,28 @@ typedef void
599 * notification on failure (as the channel may simply take days to approve, 617 * notification on failure (as the channel may simply take days to approve,
600 * and disapproval is simply being ignored). 618 * and disapproval is simply being ignored).
601 * 619 *
602 * @param cfg Configuration to use. 620 * @param cfg Configuration to use.
603 * @param channel_key ECC public key that identifies the channel we wish to join. 621 * @param channel_key ECC public key that identifies the channel we wish to join.
604 * @param slave_key ECC private-public key pair that identifies the slave, and 622 * @param slave_key ECC private-public key pair that identifies the slave, and
605 * used by multicast to sign the join request and subsequent unicast 623 * used by multicast to sign the join request and subsequent unicast
606 * requests sent to the master. 624 * requests sent to the master.
607 * @param origin Peer identity of the origin. 625 * @param origin Peer identity of the origin.
608 * @param relay_count Number of peers in the @a relays array. 626 * @param relay_count Number of peers in the @a relays array.
609 * @param relays Peer identities of members of the multicast group, which serve 627 * @param relays Peer identities of members of the multicast group, which serve
610 * as relays and used to join the group at. 628 * as relays and used to join the group at.
611 * @param message_cb Function to invoke on message parts received from the 629 * @param message_cb Function to invoke on message parts received from the
612 * channel, typically at least contains method handlers for @e join and 630 * channel, typically at least contains method handlers for @e join and
613 * @e part. 631 * @e part.
614 * @param slave_joined_cb Function invoked once we have joined the channel. 632 * @param slave_connect_cb Function invoked once we have connected to the
615 * @param cls Closure for @a message_cb and @a slave_joined_cb. 633 * PSYC service.
616 * @param method_name Method name for the join request. 634 * @param join_decision_cb Function invoked once we have received a join
617 * @param env Environment containing transient variables for the request, or NULL. 635 * decision.
618 * @param data Payload for the join message. 636 * @param cls Closure for @a message_cb and @a slave_joined_cb.
619 * @param data_size Number of bytes in @a data. 637 * @param method_name Method name for the join request.
638 * @param env Environment containing transient variables for the request, or NULL.
639 * @param data Payload for the join message.
640 * @param data_size Number of bytes in @a data.
641 *
620 * @return Handle for the slave, NULL on error. 642 * @return Handle for the slave, NULL on error.
621 */ 643 */
622struct GNUNET_PSYC_Slave * 644struct GNUNET_PSYC_Slave *
@@ -627,7 +649,8 @@ GNUNET_PSYC_slave_join (const struct GNUNET_CONFIGURATION_Handle *cfg,
627 uint32_t relay_count, 649 uint32_t relay_count,
628 const struct GNUNET_PeerIdentity *relays, 650 const struct GNUNET_PeerIdentity *relays,
629 GNUNET_PSYC_MessageCallback message_cb, 651 GNUNET_PSYC_MessageCallback message_cb,
630 GNUNET_PSYC_SlaveJoinCallback slave_joined_cb, 652 GNUNET_PSYC_SlaveConnectCallback slave_connect_cb,
653 GNUNET_PSYC_JoinDecisionCallback join_decision_cb,
631 void *cls, 654 void *cls,
632 const char *method_name, 655 const char *method_name,
633 const struct GNUNET_ENV_Environment *env, 656 const struct GNUNET_ENV_Environment *env,
diff --git a/src/multicast/Makefile.am b/src/multicast/Makefile.am
index b2c1702e4..8ccc7b88a 100644
--- a/src/multicast/Makefile.am
+++ b/src/multicast/Makefile.am
@@ -46,10 +46,12 @@ gnunet_service_multicast_SOURCES = \
46 gnunet-service-multicast.c 46 gnunet-service-multicast.c
47gnunet_service_multicast_LDADD = \ 47gnunet_service_multicast_LDADD = \
48 $(top_builddir)/src/util/libgnunetutil.la \ 48 $(top_builddir)/src/util/libgnunetutil.la \
49 $(top_builddir)/src/core/libgnunetcore.la \
49 $(top_builddir)/src/statistics/libgnunetstatistics.la \ 50 $(top_builddir)/src/statistics/libgnunetstatistics.la \
50 $(GN_LIBINTL) 51 $(GN_LIBINTL)
51gnunet_service_multicast_DEPENDENCIES = \ 52gnunet_service_multicast_DEPENDENCIES = \
52 $(top_builddir)/src/util/libgnunetutil.la \ 53 $(top_builddir)/src/util/libgnunetutil.la \
54 $(top_builddir)/src/core/libgnunetcore.la \
53 $(top_builddir)/src/statistics/libgnunetstatistics.la 55 $(top_builddir)/src/statistics/libgnunetstatistics.la
54 56
55 57
diff --git a/src/multicast/gnunet-service-multicast.c b/src/multicast/gnunet-service-multicast.c
index d412d3f8e..5421c1b2b 100644
--- a/src/multicast/gnunet-service-multicast.c
+++ b/src/multicast/gnunet-service-multicast.c
@@ -27,6 +27,7 @@
27#include "gnunet_util_lib.h" 27#include "gnunet_util_lib.h"
28#include "gnunet_signatures.h" 28#include "gnunet_signatures.h"
29#include "gnunet_statistics_service.h" 29#include "gnunet_statistics_service.h"
30#include "gnunet_core_service.h"
30#include "gnunet_multicast_service.h" 31#include "gnunet_multicast_service.h"
31#include "multicast.h" 32#include "multicast.h"
32 33
@@ -36,6 +37,22 @@
36static const struct GNUNET_CONFIGURATION_Handle *cfg; 37static const struct GNUNET_CONFIGURATION_Handle *cfg;
37 38
38/** 39/**
40 * Server handle.
41 */
42static struct GNUNET_SERVER_Handle *server;
43
44/**
45 * Core handle.
46 * Only used during initialization.
47 */
48static struct GNUNET_CORE_Handle *core;
49
50/**
51 * Identity of this peer.
52 */
53static struct GNUNET_PeerIdentity this_peer;
54
55/**
39 * Handle to the statistics service. 56 * Handle to the statistics service.
40 */ 57 */
41static struct GNUNET_STATISTICS_Handle *stats; 58static struct GNUNET_STATISTICS_Handle *stats;
@@ -62,7 +79,6 @@ static struct GNUNET_CONTAINER_MultiHashMap *members;
62 */ 79 */
63static struct GNUNET_CONTAINER_MultiHashMap *group_members; 80static struct GNUNET_CONTAINER_MultiHashMap *group_members;
64 81
65
66/** 82/**
67 * List of connected clients. 83 * List of connected clients.
68 */ 84 */
@@ -147,7 +163,7 @@ struct Member
147 /** 163 /**
148 * Join request sent to the origin / members. 164 * Join request sent to the origin / members.
149 */ 165 */
150 struct MulticastJoinRequestMessage *join_request; 166 struct MulticastJoinRequestMessage *join_req;
151 167
152 /** 168 /**
153 * Join decision sent in reply to our request. 169 * Join decision sent in reply to our request.
@@ -155,7 +171,7 @@ struct Member
155 * Only a positive decision is stored here, in case of a negative decision the 171 * Only a positive decision is stored here, in case of a negative decision the
156 * client is disconnected. 172 * client is disconnected.
157 */ 173 */
158 struct MulticastJoinDecisionMessage *join_decision; 174 struct MulticastJoinDecisionMessageHeader *join_dcsn;
159 175
160 /** 176 /**
161 * Last request fragment ID sent to the origin. 177 * Last request fragment ID sent to the origin.
@@ -171,9 +187,19 @@ struct Member
171 * @param tc unused 187 * @param tc unused
172 */ 188 */
173static void 189static void
174cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 190shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
175{ 191{
176 /* FIXME: do clean up here */ 192 if (NULL != core)
193 {
194 GNUNET_CORE_disconnect (core);
195 core = NULL;
196 }
197 if (NULL != stats)
198 {
199 GNUNET_STATISTICS_destroy (stats, GNUNET_YES);
200 stats = NULL;
201 }
202 /* FIXME: do more clean up here */
177} 203}
178 204
179/** 205/**
@@ -206,8 +232,11 @@ cleanup_member (struct Member *mem)
206 grp_mem); 232 grp_mem);
207 GNUNET_CONTAINER_multihashmap_destroy (grp_mem); 233 GNUNET_CONTAINER_multihashmap_destroy (grp_mem);
208 } 234 }
209 if (NULL != mem->join_decision) 235 if (NULL != mem->join_dcsn)
210 GNUNET_free (mem->join_decision); 236 {
237 GNUNET_free (mem->join_dcsn);
238 mem->join_dcsn = NULL;
239 }
211 GNUNET_CONTAINER_multihashmap_remove (members, &grp->pub_key_hash, mem); 240 GNUNET_CONTAINER_multihashmap_remove (members, &grp->pub_key_hash, mem);
212} 241}
213 242
@@ -329,7 +358,7 @@ member_message_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash,
329 const struct GNUNET_MessageHeader *msg = cls; 358 const struct GNUNET_MessageHeader *msg = cls;
330 struct Member *mem = member; 359 struct Member *mem = member;
331 360
332 if (NULL != mem->join_decision) 361 if (NULL != mem->join_dcsn)
333 { /* Only send message to admitted members */ 362 { /* Only send message to admitted members */
334 message_to_clients (&mem->grp, msg); 363 message_to_clients (&mem->grp, msg);
335 } 364 }
@@ -374,7 +403,7 @@ message_to_origin (struct Group *grp, const struct GNUNET_MessageHeader *msg)
374 * Handle a connecting client starting an origin. 403 * Handle a connecting client starting an origin.
375 */ 404 */
376static void 405static void
377handle_origin_start (void *cls, struct GNUNET_SERVER_Client *client, 406client_origin_start (void *cls, struct GNUNET_SERVER_Client *client,
378 const struct GNUNET_MessageHeader *m) 407 const struct GNUNET_MessageHeader *m)
379{ 408{
380 const struct MulticastOriginStartMessage * 409 const struct MulticastOriginStartMessage *
@@ -424,8 +453,8 @@ handle_origin_start (void *cls, struct GNUNET_SERVER_Client *client,
424 * Handle a connecting client joining a group. 453 * Handle a connecting client joining a group.
425 */ 454 */
426static void 455static void
427handle_member_join (void *cls, struct GNUNET_SERVER_Client *client, 456client_member_join (void *cls, struct GNUNET_SERVER_Client *client,
428 const struct GNUNET_MessageHeader *m) 457 const struct GNUNET_MessageHeader *m)
429{ 458{
430 const struct MulticastMemberJoinMessage * 459 const struct MulticastMemberJoinMessage *
431 msg = (const struct MulticastMemberJoinMessage *) m; 460 msg = (const struct MulticastMemberJoinMessage *) m;
@@ -487,16 +516,16 @@ handle_member_join (void *cls, struct GNUNET_SERVER_Client *client,
487 516
488 GNUNET_SERVER_client_set_user_context (client, grp); 517 GNUNET_SERVER_client_set_user_context (client, grp);
489 518
490 if (NULL != mem->join_decision) 519 if (NULL != mem->join_dcsn)
491 { /* Already got a join decision, send it to client. */ 520 { /* Already got a join decision, send it to client. */
492 GNUNET_SERVER_notification_context_add (nc, client); 521 GNUNET_SERVER_notification_context_add (nc, client);
493 GNUNET_SERVER_notification_context_unicast (nc, client, 522 GNUNET_SERVER_notification_context_unicast (nc, client,
494 (struct GNUNET_MessageHeader *) 523 (struct GNUNET_MessageHeader *)
495 mem->join_decision, 524 mem->join_dcsn,
496 GNUNET_NO); 525 GNUNET_NO);
497 } 526 }
498 else if (grp->clients_head == grp->clients_tail) 527 else if (grp->clients_head == grp->clients_tail)
499 { /* First client, send join request. */ 528 { /* First client of the group, send join request. */
500 struct GNUNET_PeerIdentity *relays = (struct GNUNET_PeerIdentity *) &msg[1]; 529 struct GNUNET_PeerIdentity *relays = (struct GNUNET_PeerIdentity *) &msg[1];
501 uint32_t relay_count = ntohs (msg->relay_count); 530 uint32_t relay_count = ntohs (msg->relay_count);
502 uint16_t relay_size = relay_count * sizeof (*relays); 531 uint16_t relay_size = relay_count * sizeof (*relays);
@@ -515,6 +544,7 @@ handle_member_join (void *cls, struct GNUNET_SERVER_Client *client,
515 req->header.size = htons (sizeof (*req) + join_msg_size); 544 req->header.size = htons (sizeof (*req) + join_msg_size);
516 req->header.type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_REQUEST); 545 req->header.type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_REQUEST);
517 req->group_key = grp->pub_key; 546 req->group_key = grp->pub_key;
547 req->member_peer = this_peer;
518 GNUNET_CRYPTO_eddsa_key_get_public (&mem->priv_key, &req->member_key); 548 GNUNET_CRYPTO_eddsa_key_get_public (&mem->priv_key, &req->member_key);
519 if (0 < join_msg_size) 549 if (0 < join_msg_size)
520 memcpy (&req[1], join_msg, join_msg_size); 550 memcpy (&req[1], join_msg, join_msg_size);
@@ -531,14 +561,14 @@ handle_member_join (void *cls, struct GNUNET_SERVER_Client *client,
531 GNUNET_assert (0); 561 GNUNET_assert (0);
532 } 562 }
533 563
534 if (NULL != mem->join_request) 564 if (NULL != mem->join_req)
535 GNUNET_free (mem->join_request); 565 GNUNET_free (mem->join_req);
536 mem->join_request = req; 566 mem->join_req = req;
537 567
538 if (GNUNET_YES 568 if (GNUNET_YES
539 == GNUNET_CONTAINER_multihashmap_contains (origins, &grp->pub_key_hash)) 569 == GNUNET_CONTAINER_multihashmap_contains (origins, &grp->pub_key_hash))
540 { /* Local origin */ 570 { /* Local origin */
541 message_to_origin (grp, (struct GNUNET_MessageHeader *) mem->join_request); 571 message_to_origin (grp, (struct GNUNET_MessageHeader *) mem->join_req);
542 } 572 }
543 else 573 else
544 { 574 {
@@ -553,34 +583,15 @@ handle_member_join (void *cls, struct GNUNET_SERVER_Client *client,
553 * Join decision from client. 583 * Join decision from client.
554 */ 584 */
555static void 585static void
556handle_join_decision (void *cls, struct GNUNET_SERVER_Client *client, 586client_join_decision (void *cls, struct GNUNET_SERVER_Client *client,
557 const struct GNUNET_MessageHeader *m) 587 const struct GNUNET_MessageHeader *m)
558{ 588{
559 struct Group * 589 struct Group *
560 grp = GNUNET_SERVER_client_get_user_context (client, struct Group); 590 grp = GNUNET_SERVER_client_get_user_context (client, struct Group);
561 const struct MulticastClientJoinDecisionMessage * 591 const struct MulticastJoinDecisionMessageHeader *
562 cl_dcsn = (const struct MulticastClientJoinDecisionMessage *) m; 592 hdcsn = (const struct MulticastJoinDecisionMessageHeader *) m;
563 593 const struct MulticastJoinDecisionMessage *
564 struct GNUNET_PeerIdentity *relays = (struct GNUNET_PeerIdentity *) &cl_dcsn[1]; 594 dcsn = (const struct MulticastJoinDecisionMessage *) &hdcsn[1];
565 uint32_t relay_count = ntohs (cl_dcsn->relay_count);
566 uint16_t relay_size = relay_count * sizeof (*relays);
567
568 struct GNUNET_MessageHeader *join_msg = NULL;
569 uint16_t join_msg_size = 0;
570 if (sizeof (*cl_dcsn) + relay_size + sizeof (*m) <= ntohs (m->size))
571 {
572 join_msg = (struct GNUNET_MessageHeader *)
573 (((char *) &cl_dcsn[1]) + relay_size);
574 join_msg_size = ntohs (join_msg->size);
575 }
576
577 int keep_dcsn = GNUNET_NO;
578 struct MulticastJoinDecisionMessage *
579 dcsn = GNUNET_malloc (sizeof (*dcsn) + join_msg_size);
580 dcsn->header.size = htons (sizeof (*dcsn) + join_msg_size);
581 dcsn->header.type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION);
582 dcsn->is_admitted = cl_dcsn->is_admitted;
583 memcpy (&dcsn[1], join_msg, join_msg_size);
584 595
585 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 596 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
586 "%p Got join decision from client for group %s..\n", 597 "%p Got join decision from client for group %s..\n",
@@ -595,7 +606,7 @@ handle_join_decision (void *cls, struct GNUNET_SERVER_Client *client,
595 if (NULL != grp_mem) 606 if (NULL != grp_mem)
596 { 607 {
597 struct GNUNET_HashCode member_key_hash; 608 struct GNUNET_HashCode member_key_hash;
598 GNUNET_CRYPTO_hash (&cl_dcsn->member_key, sizeof (cl_dcsn->member_key), 609 GNUNET_CRYPTO_hash (&hdcsn->member_key, sizeof (hdcsn->member_key),
599 &member_key_hash); 610 &member_key_hash);
600 struct Member * 611 struct Member *
601 mem = GNUNET_CONTAINER_multihashmap_get (grp_mem, &member_key_hash); 612 mem = GNUNET_CONTAINER_multihashmap_get (grp_mem, &member_key_hash);
@@ -604,19 +615,21 @@ handle_join_decision (void *cls, struct GNUNET_SERVER_Client *client,
604 grp, GNUNET_h2s (&member_key_hash), mem); 615 grp, GNUNET_h2s (&member_key_hash), mem);
605 if (NULL != mem) 616 if (NULL != mem)
606 { 617 {
607 message_to_clients (grp, (struct GNUNET_MessageHeader *) dcsn); 618 message_to_clients (&mem->grp, (struct GNUNET_MessageHeader *) hdcsn);
608 if (GNUNET_YES == dcsn->is_admitted) 619 if (GNUNET_YES == ntohl (dcsn->is_admitted))
609 { /* Member admitted, store join_decision. */ 620 { /* Member admitted, store join_decision. */
610 mem->join_decision = dcsn; 621 uint16_t dcsn_size = ntohs (dcsn->header.size);
611 keep_dcsn = GNUNET_YES; 622 mem->join_dcsn = GNUNET_malloc (dcsn_size);
623 memcpy (mem->join_dcsn, dcsn, dcsn_size);
612 } 624 }
613 else 625 else
614 { /* Refused entry, disconnect clients. */ 626 { /* Refused entry, disconnect clients. */
615 struct ClientList *cl = mem->grp.clients_head; 627 struct ClientList *cl = mem->grp.clients_head;
616 while (NULL != cl) 628 while (NULL != cl)
617 { 629 {
618 GNUNET_SERVER_client_disconnect (cl->client); 630 struct GNUNET_SERVER_Client *client = cl->client;
619 cl = cl->next; 631 cl = cl->next;
632 GNUNET_SERVER_client_disconnect (client);
620 } 633 }
621 } 634 }
622 } 635 }
@@ -624,10 +637,8 @@ handle_join_decision (void *cls, struct GNUNET_SERVER_Client *client,
624 } 637 }
625 else 638 else
626 { 639 {
627 /* FIXME: send join decision to remote peers */ 640 /* FIXME: send join decision to hdcsn->peer */
628 } 641 }
629 if (GNUNET_NO == keep_dcsn)
630 GNUNET_free (dcsn);
631 GNUNET_SERVER_receive_done (client, GNUNET_OK); 642 GNUNET_SERVER_receive_done (client, GNUNET_OK);
632} 643}
633 644
@@ -635,7 +646,7 @@ handle_join_decision (void *cls, struct GNUNET_SERVER_Client *client,
635 * Incoming message from a client. 646 * Incoming message from a client.
636 */ 647 */
637static void 648static void
638handle_multicast_message (void *cls, struct GNUNET_SERVER_Client *client, 649client_multicast_message (void *cls, struct GNUNET_SERVER_Client *client,
639 const struct GNUNET_MessageHeader *m) 650 const struct GNUNET_MessageHeader *m)
640{ 651{
641 struct Group * 652 struct Group *
@@ -670,7 +681,7 @@ handle_multicast_message (void *cls, struct GNUNET_SERVER_Client *client,
670 * Incoming request from a client. 681 * Incoming request from a client.
671 */ 682 */
672static void 683static void
673handle_multicast_request (void *cls, struct GNUNET_SERVER_Client *client, 684client_multicast_request (void *cls, struct GNUNET_SERVER_Client *client,
674 const struct GNUNET_MessageHeader *m) 685 const struct GNUNET_MessageHeader *m)
675{ 686{
676 struct Group * 687 struct Group *
@@ -708,37 +719,34 @@ handle_multicast_request (void *cls, struct GNUNET_SERVER_Client *client,
708 GNUNET_SERVER_receive_done (client, GNUNET_OK); 719 GNUNET_SERVER_receive_done (client, GNUNET_OK);
709} 720}
710 721
722
711/** 723/**
712 * Process multicast requests. 724 * Core connected.
713 *
714 * @param cls closure
715 * @param server the initialized server
716 * @param cfg configuration to use
717 */ 725 */
718static void 726static void
719run (void *cls, struct GNUNET_SERVER_Handle *server, 727core_connected_cb (void *cls, const struct GNUNET_PeerIdentity *my_identity)
720 const struct GNUNET_CONFIGURATION_Handle *c)
721{ 728{
729 this_peer = *my_identity;
730
722 static const struct GNUNET_SERVER_MessageHandler handlers[] = { 731 static const struct GNUNET_SERVER_MessageHandler handlers[] = {
723 { &handle_origin_start, NULL, 732 { &client_origin_start, NULL,
724 GNUNET_MESSAGE_TYPE_MULTICAST_ORIGIN_START, 0 }, 733 GNUNET_MESSAGE_TYPE_MULTICAST_ORIGIN_START, 0 },
725 734
726 { &handle_member_join, NULL, 735 { &client_member_join, NULL,
727 GNUNET_MESSAGE_TYPE_MULTICAST_MEMBER_JOIN, 0 }, 736 GNUNET_MESSAGE_TYPE_MULTICAST_MEMBER_JOIN, 0 },
728 737
729 { &handle_join_decision, NULL, 738 { &client_join_decision, NULL,
730 GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION, 0 }, 739 GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION, 0 },
731 740
732 { &handle_multicast_message, NULL, 741 { &client_multicast_message, NULL,
733 GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE, 0 }, 742 GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE, 0 },
734 743
735 { &handle_multicast_request, NULL, 744 { &client_multicast_request, NULL,
736 GNUNET_MESSAGE_TYPE_MULTICAST_REQUEST, 0 }, 745 GNUNET_MESSAGE_TYPE_MULTICAST_REQUEST, 0 },
737 746
738 {NULL, NULL, 0, 0} 747 {NULL, NULL, 0, 0}
739 }; 748 };
740 749
741 cfg = c;
742 stats = GNUNET_STATISTICS_create ("multicast", cfg); 750 stats = GNUNET_STATISTICS_create ("multicast", cfg);
743 origins = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES); 751 origins = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES);
744 members = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES); 752 members = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES);
@@ -747,12 +755,30 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
747 755
748 GNUNET_SERVER_add_handlers (server, handlers); 756 GNUNET_SERVER_add_handlers (server, handlers);
749 GNUNET_SERVER_disconnect_notify (server, &client_disconnect, NULL); 757 GNUNET_SERVER_disconnect_notify (server, &client_disconnect, NULL);
750 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup_task, 758 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
751 NULL); 759 NULL);
752} 760}
753 761
754 762
755/** 763/**
764 * Service started.
765 *
766 * @param cls closure
767 * @param server the initialized server
768 * @param cfg configuration to use
769 */
770static void
771run (void *cls, struct GNUNET_SERVER_Handle *srv,
772 const struct GNUNET_CONFIGURATION_Handle *c)
773{
774 cfg = c;
775 server = srv;
776 core = GNUNET_CORE_connect (cfg, NULL, core_connected_cb, NULL, NULL,
777 NULL, GNUNET_NO, NULL, GNUNET_NO, NULL);
778}
779
780
781/**
756 * The main function for the multicast service. 782 * The main function for the multicast service.
757 * 783 *
758 * @param argc number of arguments from the command line 784 * @param argc number of arguments from the command line
diff --git a/src/multicast/multicast.h b/src/multicast/multicast.h
index 85c5714e6..76492e868 100644
--- a/src/multicast/multicast.h
+++ b/src/multicast/multicast.h
@@ -77,7 +77,7 @@ struct MulticastJoinRequestMessage
77 77
78 78
79/** 79/**
80 * Header of a join decision sent to a remote peer. 80 * Header of a join decision message sent to a peer requesting join.
81 */ 81 */
82struct MulticastJoinDecisionMessage 82struct MulticastJoinDecisionMessage
83{ 83{
@@ -87,19 +87,28 @@ struct MulticastJoinDecisionMessage
87 struct GNUNET_MessageHeader header; 87 struct GNUNET_MessageHeader header;
88 88
89 /** 89 /**
90 * #GNUNET_YES if the peer was admitted. 90 * #GNUNET_YES if the peer was admitted
91 * #GNUNET_NO if entry was refused,
92 * #GNUNET_SYSERR if the request could not be answered.
91 */ 93 */
92 uint8_t is_admitted; 94 int32_t is_admitted;
95
96 /**
97 * Number of relays given.
98 */
99 uint32_t relay_count;
100
101 /* Followed by relay_count peer identities */
93 102
94 /* Followed by the join response message */ 103 /* Followed by the join response message */
95}; 104};
96 105
97 106
98/** 107/**
99 * Message sent from the client to the service to notify the service 108 * Header added to a struct MulticastJoinDecisionMessage
100 * about a join decision. 109 * when sent between the client and service.
101 */ 110 */
102struct MulticastClientJoinDecisionMessage 111struct MulticastJoinDecisionMessageHeader
103{ 112{
104 /** 113 /**
105 * Type: GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION 114 * Type: GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION
@@ -107,29 +116,18 @@ struct MulticastClientJoinDecisionMessage
107 struct GNUNET_MessageHeader header; 116 struct GNUNET_MessageHeader header;
108 117
109 /** 118 /**
110 * Number of relays given. 119 * C->S: Peer to send the join decision to.
120 * S->C: Peer we received the join decision from.
111 */ 121 */
112 uint32_t relay_count; 122 struct GNUNET_PeerIdentity peer;
113 123
114 /** 124 /**
115 * Public key of the joining member. 125 * C->S: Public key of the member requesting join.
126 * S->C: Unused.
116 */ 127 */
117 struct GNUNET_CRYPTO_EddsaPublicKey member_key; 128 struct GNUNET_CRYPTO_EddsaPublicKey member_key;
118 129
119 /** 130 /* Followed by struct MulticastJoinDecisionMessage */
120 * Peer identity of the joining member.
121 */
122 struct GNUNET_PeerIdentity member_peer;
123
124 /**
125 * #GNUNET_YES if the peer was admitted.
126 */
127 uint8_t is_admitted;
128
129 /* Followed by relay_count peer identities */
130
131 /* Followed by the join response message */
132
133}; 131};
134 132
135 133
@@ -139,7 +137,6 @@ struct MulticastClientJoinDecisionMessage
139 */ 137 */
140struct MulticastMembershipTestResultMessage 138struct MulticastMembershipTestResultMessage
141{ 139{
142
143 /** 140 /**
144 * Type: GNUNET_MESSAGE_TYPE_MULTICAST_MEMBERSHIP_TEST_RESULT 141 * Type: GNUNET_MESSAGE_TYPE_MULTICAST_MEMBERSHIP_TEST_RESULT
145 */ 142 */
@@ -151,11 +148,11 @@ struct MulticastMembershipTestResultMessage
151 uint32_t uid; 148 uint32_t uid;
152 149
153 /** 150 /**
154 * #GNUNET_YES if the peer is a member, #GNUNET_NO if peer was not a member, 151 * #GNUNET_YES if the peer is a member
155 * #GNUNET_SYSERR if we cannot answer the test. 152 * #GNUNET_NO if peer is not a member,
153 * #GNUNET_SYSERR if the test could not be answered.
156 */ 154 */
157 int32_t is_admitted; 155 int32_t is_admitted;
158
159}; 156};
160 157
161 158
diff --git a/src/multicast/multicast_api.c b/src/multicast/multicast_api.c
index 501ff4b70..e568e77ee 100644
--- a/src/multicast/multicast_api.c
+++ b/src/multicast/multicast_api.c
@@ -132,7 +132,7 @@ struct GNUNET_MULTICAST_Group
132 struct GNUNET_CRYPTO_EddsaPublicKey pub_key; 132 struct GNUNET_CRYPTO_EddsaPublicKey pub_key;
133 struct GNUNET_HashCode pub_key_hash; 133 struct GNUNET_HashCode pub_key_hash;
134 134
135 GNUNET_MULTICAST_JoinCallback join_cb; 135 GNUNET_MULTICAST_JoinRequestCallback join_req_cb;
136 GNUNET_MULTICAST_MembershipTestCallback member_test_cb; 136 GNUNET_MULTICAST_MembershipTestCallback member_test_cb;
137 GNUNET_MULTICAST_ReplayFragmentCallback replay_frag_cb; 137 GNUNET_MULTICAST_ReplayFragmentCallback replay_frag_cb;
138 GNUNET_MULTICAST_ReplayMessageCallback replay_msg_cb; 138 GNUNET_MULTICAST_ReplayMessageCallback replay_msg_cb;
@@ -177,10 +177,7 @@ struct GNUNET_MULTICAST_Member
177 struct GNUNET_MULTICAST_Group grp; 177 struct GNUNET_MULTICAST_Group grp;
178 struct GNUNET_MULTICAST_MemberTransmitHandle tmit; 178 struct GNUNET_MULTICAST_MemberTransmitHandle tmit;
179 179
180 struct GNUNET_CRYPTO_EddsaPrivateKey priv_key; 180 GNUNET_MULTICAST_JoinDecisionCallback join_dcsn_cb;
181 struct GNUNET_PeerIdentity origin;
182 struct GNUNET_PeerIdentity relays;
183 uint32_t relay_count;
184 181
185 uint64_t next_fragment_id; 182 uint64_t next_fragment_id;
186}; 183};
@@ -197,12 +194,12 @@ struct GNUNET_MULTICAST_JoinHandle
197 struct GNUNET_MULTICAST_Group *group; 194 struct GNUNET_MULTICAST_Group *group;
198 195
199 /** 196 /**
200 * Public key of the joining member. 197 * Public key of the member requesting join.
201 */ 198 */
202 struct GNUNET_CRYPTO_EddsaPublicKey member_key; 199 struct GNUNET_CRYPTO_EddsaPublicKey member_key;
203 200
204 /** 201 /**
205 * Peer identity of the joining member. 202 * Peer identity of the member requesting join.
206 */ 203 */
207 struct GNUNET_PeerIdentity member_peer; 204 struct GNUNET_PeerIdentity member_peer;
208}; 205};
@@ -476,8 +473,9 @@ request_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash, void *origin)
476 "Calling request callback for a request of type %u and size %u.\n", 473 "Calling request callback for a request of type %u and size %u.\n",
477 ntohs (req->header.type), ntohs (req->header.size)); 474 ntohs (req->header.type), ntohs (req->header.size));
478 475
479 orig->request_cb (orig->grp.cb_cls, &req->member_key, 476 if (NULL != orig->request_cb)
480 (const struct GNUNET_MessageHeader *) req, 0); 477 orig->request_cb (orig->grp.cb_cls, &req->member_key,
478 (const struct GNUNET_MessageHeader *) req, 0);
481 return GNUNET_YES; 479 return GNUNET_YES;
482} 480}
483 481
@@ -501,7 +499,8 @@ join_request_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash,
501 if (sizeof (*req) + sizeof (*msg) <= ntohs (req->header.size)) 499 if (sizeof (*req) + sizeof (*msg) <= ntohs (req->header.size))
502 msg = (const struct GNUNET_MessageHeader *) &req[1]; 500 msg = (const struct GNUNET_MessageHeader *) &req[1];
503 501
504 grp->join_cb (grp->cb_cls, &req->member_key, msg, jh); 502 if (NULL != grp->join_req_cb)
503 grp->join_req_cb (grp->cb_cls, &req->member_key, msg, jh);
505 return GNUNET_YES; 504 return GNUNET_YES;
506} 505}
507 506
@@ -513,15 +512,44 @@ static int
513join_decision_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash, 512join_decision_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash,
514 void *member) 513 void *member)
515{ 514{
516 const struct MulticastJoinDecisionMessage *dcsn = cls; 515 const struct MulticastJoinDecisionMessageHeader *hdcsn = cls;
516 const struct MulticastJoinDecisionMessage *
517 dcsn = (const struct MulticastJoinDecisionMessage *) &hdcsn[1];
517 struct GNUNET_MULTICAST_Member *mem = member; 518 struct GNUNET_MULTICAST_Member *mem = member;
518 struct GNUNET_MULTICAST_Group *grp = &mem->grp; 519 struct GNUNET_MULTICAST_Group *grp = &mem->grp;
519 520
520 const struct GNUNET_MessageHeader *msg = NULL; 521 uint16_t dcsn_size = ntohs (dcsn->header.size);
521 if (sizeof (*dcsn) + sizeof (*msg) <= ntohs (dcsn->header.size)) 522 int is_admitted = ntohl (dcsn->is_admitted);
522 msg = (const struct GNUNET_MessageHeader *) &dcsn[1]; 523
524 const struct GNUNET_MessageHeader *join_resp = NULL;
525 uint16_t join_resp_size = 0;
526
527 uint16_t relay_count = ntohl (dcsn->relay_count);
528 const struct GNUNET_PeerIdentity *relays = NULL;
529 uint16_t relay_size = relay_count * sizeof (*relays);
530 if (0 < relay_count && dcsn_size < sizeof (*dcsn) + relay_size)
531 relays = (struct GNUNET_PeerIdentity *) &dcsn[1];
532
533 if (sizeof (*dcsn) + relay_size + sizeof (*join_resp) <= dcsn_size)
534 {
535 join_resp = (const struct GNUNET_MessageHeader *) &dcsn[1];
536 join_resp_size = ntohs (join_resp->size);
537 }
538 if (dcsn_size < sizeof (*dcsn) + relay_size + join_resp_size)
539 {
540 LOG (GNUNET_ERROR_TYPE_DEBUG,
541 "Received invalid join decision message from multicast.\n");
542 GNUNET_break_op (0);
543 is_admitted = GNUNET_SYSERR;
544 }
545
546 if (NULL != mem->join_dcsn_cb)
547 mem->join_dcsn_cb (grp->cb_cls, is_admitted, &hdcsn->peer,
548 relay_count, relays, join_resp);
549
550 if (GNUNET_YES != is_admitted)
551 GNUNET_MULTICAST_member_part (mem);
523 552
524 // FIXME: grp->join_decision_cb (grp->cb_cls, msg);
525 return GNUNET_YES; 553 return GNUNET_YES;
526} 554}
527 555
@@ -599,7 +627,6 @@ message_handler (void *cls, const struct GNUNET_MessageHeader *msg)
599 GNUNET_break (0); 627 GNUNET_break (0);
600 break; 628 break;
601 } 629 }
602
603 if (NULL != origins) 630 if (NULL != origins)
604 GNUNET_CONTAINER_multihashmap_get_multiple (origins, &grp->pub_key_hash, 631 GNUNET_CONTAINER_multihashmap_get_multiple (origins, &grp->pub_key_hash,
605 request_cb, (void *) msg); 632 request_cb, (void *) msg);
@@ -615,9 +642,11 @@ message_handler (void *cls, const struct GNUNET_MessageHeader *msg)
615 break; 642 break;
616 643
617 case GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION: 644 case GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION:
618 if (NULL != origins) 645 if (GNUNET_NO != grp->is_origin)
619 GNUNET_CONTAINER_multihashmap_get_multiple (origins, &grp->pub_key_hash, 646 {
620 join_decision_cb, (void *) msg); 647 GNUNET_break (0);
648 break;
649 }
621 if (NULL != members) 650 if (NULL != members)
622 GNUNET_CONTAINER_multihashmap_get_multiple (members, &grp->pub_key_hash, 651 GNUNET_CONTAINER_multihashmap_get_multiple (members, &grp->pub_key_hash,
623 join_decision_cb, (void *) msg); 652 join_decision_cb, (void *) msg);
@@ -636,11 +665,12 @@ message_handler (void *cls, const struct GNUNET_MessageHeader *msg)
636 * Function to call with the decision made for a join request. 665 * Function to call with the decision made for a join request.
637 * 666 *
638 * Must be called once and only once in response to an invocation of the 667 * Must be called once and only once in response to an invocation of the
639 * #GNUNET_MULTICAST_JoinCallback. 668 * #GNUNET_MULTICAST_JoinRequestCallback.
640 * 669 *
641 * @param jh Join request handle. 670 * @param jh Join request handle.
642 * @param is_admitted #GNUNET_YES if joining is approved, 671 * @param is_admitted #GNUNET_YES if the join is approved,
643 * #GNUNET_NO if it is disapproved 672 * #GNUNET_NO if it is disapproved,
673 * #GNUNET_SYSERR if we cannot answer the request.
644 * @param relay_count Number of relays given. 674 * @param relay_count Number of relays given.
645 * @param relays Array of suggested peers that might be useful relays to use 675 * @param relays Array of suggested peers that might be useful relays to use
646 * when joining the multicast group (essentially a list of peers that 676 * when joining the multicast group (essentially a list of peers that
@@ -657,25 +687,31 @@ message_handler (void *cls, const struct GNUNET_MessageHeader *msg)
657struct GNUNET_MULTICAST_ReplayHandle * 687struct GNUNET_MULTICAST_ReplayHandle *
658GNUNET_MULTICAST_join_decision (struct GNUNET_MULTICAST_JoinHandle *jh, 688GNUNET_MULTICAST_join_decision (struct GNUNET_MULTICAST_JoinHandle *jh,
659 int is_admitted, 689 int is_admitted,
660 unsigned int relay_count, 690 uint16_t relay_count,
661 const struct GNUNET_PeerIdentity *relays, 691 const struct GNUNET_PeerIdentity *relays,
662 const struct GNUNET_MessageHeader *join_resp) 692 const struct GNUNET_MessageHeader *join_resp)
663{ 693{
664 struct GNUNET_MULTICAST_Group *grp = jh->group; 694 struct GNUNET_MULTICAST_Group *grp = jh->group;
665 uint16_t join_resp_size = (NULL != join_resp) ? ntohs (join_resp->size) : 0; 695 uint16_t join_resp_size = (NULL != join_resp) ? ntohs (join_resp->size) : 0;
666 uint16_t relay_size = relay_count * sizeof (*relays); 696 uint16_t relay_size = relay_count * sizeof (*relays);
667 struct MulticastClientJoinDecisionMessage * dcsn; 697 struct MulticastJoinDecisionMessageHeader * hdcsn;
698 struct MulticastJoinDecisionMessage *dcsn;
668 struct MessageQueue * 699 struct MessageQueue *
669 mq = GNUNET_malloc (sizeof (*mq) + sizeof (*dcsn) 700 mq = GNUNET_malloc (sizeof (*mq) + sizeof (*hdcsn) + sizeof (*dcsn)
670 + relay_size + join_resp_size); 701 + relay_size + join_resp_size);
671 702
672 dcsn = (struct MulticastClientJoinDecisionMessage *) &mq[1]; 703 hdcsn = (struct MulticastJoinDecisionMessageHeader *) &mq[1];
704 hdcsn->header.type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION);
705 hdcsn->header.size = htons (sizeof (*hdcsn) + sizeof (*dcsn)
706 + relay_size + join_resp_size);
707 hdcsn->member_key = jh->member_key;
708 hdcsn->peer = jh->member_peer;
709
710 dcsn = (struct MulticastJoinDecisionMessage *) &hdcsn[1];
673 dcsn->header.type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION); 711 dcsn->header.type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION);
674 dcsn->header.size = htons (sizeof (*dcsn) + relay_size + join_resp_size); 712 dcsn->header.size = htons (sizeof (*dcsn) + relay_size + join_resp_size);
675 dcsn->member_key = jh->member_key; 713 dcsn->is_admitted = htonl (is_admitted);
676 dcsn->member_peer = jh->member_peer; 714 dcsn->relay_count = htonl (relay_count);
677 dcsn->is_admitted = is_admitted;
678 dcsn->relay_count = relay_count;
679 if (0 < relay_size) 715 if (0 < relay_size)
680 memcpy (&dcsn[1], relays, relay_size); 716 memcpy (&dcsn[1], relays, relay_size);
681 if (0 < join_resp_size) 717 if (0 < join_resp_size)
@@ -763,7 +799,7 @@ GNUNET_MULTICAST_replay_response2 (struct GNUNET_MULTICAST_ReplayHandle *rh,
763 * multicast session; public key is used to identify the multicast group; 799 * multicast session; public key is used to identify the multicast group;
764 * @param max_fragment_id Maximum fragment ID already sent to the group. 800 * @param max_fragment_id Maximum fragment ID already sent to the group.
765 * 0 for a new group. 801 * 0 for a new group.
766 * @param join_cb Function called to approve / disapprove joining of a peer. 802 * @param join_request_cb Function called to approve / disapprove joining of a peer.
767 * @param member_test_cb Function multicast can use to test group membership. 803 * @param member_test_cb Function multicast can use to test group membership.
768 * @param replay_frag_cb Function that can be called to replay a message fragment. 804 * @param replay_frag_cb Function that can be called to replay a message fragment.
769 * @param replay_msg_cb Function that can be called to replay a message. 805 * @param replay_msg_cb Function that can be called to replay a message.
@@ -779,7 +815,7 @@ struct GNUNET_MULTICAST_Origin *
779GNUNET_MULTICAST_origin_start (const struct GNUNET_CONFIGURATION_Handle *cfg, 815GNUNET_MULTICAST_origin_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
780 const struct GNUNET_CRYPTO_EddsaPrivateKey *priv_key, 816 const struct GNUNET_CRYPTO_EddsaPrivateKey *priv_key,
781 uint64_t max_fragment_id, 817 uint64_t max_fragment_id,
782 GNUNET_MULTICAST_JoinCallback join_cb, 818 GNUNET_MULTICAST_JoinRequestCallback join_request_cb,
783 GNUNET_MULTICAST_MembershipTestCallback member_test_cb, 819 GNUNET_MULTICAST_MembershipTestCallback member_test_cb,
784 GNUNET_MULTICAST_ReplayFragmentCallback replay_frag_cb, 820 GNUNET_MULTICAST_ReplayFragmentCallback replay_frag_cb,
785 GNUNET_MULTICAST_ReplayMessageCallback replay_msg_cb, 821 GNUNET_MULTICAST_ReplayMessageCallback replay_msg_cb,
@@ -801,7 +837,7 @@ GNUNET_MULTICAST_origin_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
801 grp->cfg = cfg; 837 grp->cfg = cfg;
802 838
803 grp->cb_cls = cls; 839 grp->cb_cls = cls;
804 grp->join_cb = join_cb; 840 grp->join_req_cb = join_request_cb;
805 grp->member_test_cb = member_test_cb; 841 grp->member_test_cb = member_test_cb;
806 grp->replay_frag_cb = replay_frag_cb; 842 grp->replay_frag_cb = replay_frag_cb;
807 grp->replay_msg_cb = replay_msg_cb; 843 grp->replay_msg_cb = replay_msg_cb;
@@ -963,7 +999,8 @@ GNUNET_MULTICAST_origin_to_all_cancel (struct GNUNET_MULTICAST_OriginTransmitHan
963 * If empty, the @a join_request is sent directly to the @a origin. 999 * If empty, the @a join_request is sent directly to the @a origin.
964 * @param join_msg Application-dependent join message to be passed to the peer 1000 * @param join_msg Application-dependent join message to be passed to the peer
965 * @a origin. 1001 * @a origin.
966 * @param join_cb Function called to approve / disapprove joining of a peer. 1002 * @param join_request_cb Function called to approve / disapprove joining of a peer.
1003 * @param join_decision_cb Function called to inform about the join decision.
967 * @param member_test_cb Function multicast can use to test group membership. 1004 * @param member_test_cb Function multicast can use to test group membership.
968 * @param replay_frag_cb Function that can be called to replay message fragments 1005 * @param replay_frag_cb Function that can be called to replay message fragments
969 * this peer already knows from this group. NULL if this 1006 * this peer already knows from this group. NULL if this
@@ -982,10 +1019,11 @@ GNUNET_MULTICAST_member_join (const struct GNUNET_CONFIGURATION_Handle *cfg,
982 const struct GNUNET_CRYPTO_EddsaPublicKey *group_key, 1019 const struct GNUNET_CRYPTO_EddsaPublicKey *group_key,
983 const struct GNUNET_CRYPTO_EddsaPrivateKey *member_key, 1020 const struct GNUNET_CRYPTO_EddsaPrivateKey *member_key,
984 const struct GNUNET_PeerIdentity *origin, 1021 const struct GNUNET_PeerIdentity *origin,
985 uint32_t relay_count, 1022 uint16_t relay_count,
986 const struct GNUNET_PeerIdentity *relays, 1023 const struct GNUNET_PeerIdentity *relays,
987 const struct GNUNET_MessageHeader *join_msg, 1024 const struct GNUNET_MessageHeader *join_msg,
988 GNUNET_MULTICAST_JoinCallback join_cb, 1025 GNUNET_MULTICAST_JoinRequestCallback join_request_cb,
1026 GNUNET_MULTICAST_JoinDecisionCallback join_decision_cb,
989 GNUNET_MULTICAST_MembershipTestCallback member_test_cb, 1027 GNUNET_MULTICAST_MembershipTestCallback member_test_cb,
990 GNUNET_MULTICAST_ReplayFragmentCallback replay_frag_cb, 1028 GNUNET_MULTICAST_ReplayFragmentCallback replay_frag_cb,
991 GNUNET_MULTICAST_ReplayMessageCallback replay_msg_cb, 1029 GNUNET_MULTICAST_ReplayMessageCallback replay_msg_cb,
@@ -1014,18 +1052,14 @@ GNUNET_MULTICAST_member_join (const struct GNUNET_CONFIGURATION_Handle *cfg,
1014 grp->cfg = cfg; 1052 grp->cfg = cfg;
1015 grp->pub_key = *group_key; 1053 grp->pub_key = *group_key;
1016 1054
1017 grp->join_cb = join_cb; 1055 mem->join_dcsn_cb = join_decision_cb;
1056 grp->join_req_cb = join_request_cb;
1018 grp->member_test_cb = member_test_cb; 1057 grp->member_test_cb = member_test_cb;
1019 grp->replay_frag_cb = replay_frag_cb; 1058 grp->replay_frag_cb = replay_frag_cb;
1020 grp->message_cb = message_cb; 1059 grp->message_cb = message_cb;
1021 grp->cb_cls = cls; 1060 grp->cb_cls = cls;
1022 1061
1023 mem->origin = *origin; 1062 GNUNET_CRYPTO_eddsa_key_get_public (member_key, &grp->pub_key);
1024 mem->relay_count = relay_count;
1025 mem->relays = *relays;
1026 mem->priv_key = *member_key;
1027
1028 GNUNET_CRYPTO_eddsa_key_get_public (&mem->priv_key, &grp->pub_key);
1029 GNUNET_CRYPTO_hash (&grp->pub_key, sizeof (grp->pub_key), &grp->pub_key_hash); 1063 GNUNET_CRYPTO_hash (&grp->pub_key, sizeof (grp->pub_key), &grp->pub_key_hash);
1030 1064
1031 if (NULL == members) 1065 if (NULL == members)
diff --git a/src/psyc/gnunet-service-psyc.c b/src/psyc/gnunet-service-psyc.c
index 2b9ee7135..cef89b828 100644
--- a/src/psyc/gnunet-service-psyc.c
+++ b/src/psyc/gnunet-service-psyc.c
@@ -387,6 +387,11 @@ struct Slave
387 struct GNUNET_MessageHeader *join_req; 387 struct GNUNET_MessageHeader *join_req;
388 388
389 /** 389 /**
390 * Join decision received from multicast.
391 */
392 struct SlaveJoinDecision *join_dcsn;
393
394 /**
390 * Maximum request ID for this channel. 395 * Maximum request ID for this channel.
391 */ 396 */
392 uint64_t max_request_id; 397 uint64_t max_request_id;
@@ -397,6 +402,10 @@ static inline void
397transmit_message (struct Channel *ch); 402transmit_message (struct Channel *ch);
398 403
399 404
405static uint64_t
406message_queue_drop (struct Channel *ch);
407
408
400/** 409/**
401 * Task run during shutdown. 410 * Task run during shutdown.
402 * 411 *
@@ -413,7 +422,7 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
413 } 422 }
414 if (NULL != stats) 423 if (NULL != stats)
415 { 424 {
416 GNUNET_STATISTICS_destroy (stats, GNUNET_NO); 425 GNUNET_STATISTICS_destroy (stats, GNUNET_YES);
417 stats = NULL; 426 stats = NULL;
418 } 427 }
419} 428}
@@ -471,7 +480,8 @@ cleanup_slave (struct Slave *slv)
471static void 480static void
472cleanup_channel (struct Channel *ch) 481cleanup_channel (struct Channel *ch)
473{ 482{
474 /* FIXME: fragment_cache_clear */ 483 message_queue_drop (ch);
484 GNUNET_CONTAINER_multihashmap_remove_all (recv_cache, &ch->pub_key_hash);
475 485
476 if (NULL != ch->store_op) 486 if (NULL != ch->store_op)
477 GNUNET_PSYCSTORE_operation_cancel (ch->store_op); 487 GNUNET_PSYCSTORE_operation_cancel (ch->store_op);
@@ -570,7 +580,7 @@ struct JoinMemTestClosure
570 580
571 581
572/** 582/**
573 * Membership test result callback used for join requests.m 583 * Membership test result callback used for join requests.
574 */ 584 */
575static void 585static void
576join_mem_test_cb (void *cls, int64_t result, const char *err_msg) 586join_mem_test_cb (void *cls, int64_t result, const char *err_msg)
@@ -585,8 +595,7 @@ join_mem_test_cb (void *cls, int64_t result, const char *err_msg)
585 &slave_key_hash); 595 &slave_key_hash);
586 GNUNET_CONTAINER_multihashmap_put (mst->join_reqs, &slave_key_hash, jcls->jh, 596 GNUNET_CONTAINER_multihashmap_put (mst->join_reqs, &slave_key_hash, jcls->jh,
587 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 597 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
588 msg_to_clients (jcls->ch, 598 msg_to_clients (jcls->ch, &jcls->master_join_req->header);
589 (struct GNUNET_MessageHeader *) jcls->master_join_req);
590 } 599 }
591 else 600 else
592 { 601 {
@@ -602,9 +611,10 @@ join_mem_test_cb (void *cls, int64_t result, const char *err_msg)
602 * Incoming join request from multicast. 611 * Incoming join request from multicast.
603 */ 612 */
604static void 613static void
605join_cb (void *cls, const struct GNUNET_CRYPTO_EddsaPublicKey *slave_key, 614mcast_join_request_cb (void *cls,
606 const struct GNUNET_MessageHeader *join_msg, 615 const struct GNUNET_CRYPTO_EddsaPublicKey *slave_key,
607 struct GNUNET_MULTICAST_JoinHandle *jh) 616 const struct GNUNET_MessageHeader *join_msg,
617 struct GNUNET_MULTICAST_JoinHandle *jh)
608{ 618{
609 struct Channel *ch = cls; 619 struct Channel *ch = cls;
610 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%p Got join request.\n", ch); 620 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%p Got join request.\n", ch);
@@ -643,21 +653,58 @@ join_cb (void *cls, const struct GNUNET_CRYPTO_EddsaPublicKey *slave_key,
643} 653}
644 654
645 655
656/**
657 * Join decision received from multicast.
658 */
659static void
660mcast_join_decision_cb (void *cls, int is_admitted,
661 const struct GNUNET_PeerIdentity *peer,
662 uint16_t relay_count,
663 const struct GNUNET_PeerIdentity *relays,
664 const struct GNUNET_MessageHeader *join_resp)
665{
666 struct Slave *slv = cls;
667 struct Channel *ch = &slv->ch;
668 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
669 "%p Got join decision: %d\n", slv, is_admitted);
670
671 uint16_t join_resp_size = (NULL != join_resp) ? ntohs (join_resp->size) : 0;
672 struct SlaveJoinDecision *
673 dcsn = slv->join_dcsn = GNUNET_malloc (sizeof (*dcsn) + join_resp_size);
674 dcsn->header.size = htons (sizeof (*dcsn) + join_resp_size);
675 dcsn->header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION);
676 dcsn->is_admitted = htonl (is_admitted);
677 if (0 < join_resp_size)
678 memcpy (&dcsn[1], join_resp, join_resp_size);
679
680 msg_to_clients (ch, &dcsn->header);
681
682 if (GNUNET_YES == is_admitted)
683 {
684 ch->ready = GNUNET_YES;
685 }
686 else
687 {
688 slv->member = NULL;
689 }
690}
691
692
646static void 693static void
647membership_test_cb (void *cls, 694mcast_membership_test_cb (void *cls,
648 const struct GNUNET_CRYPTO_EddsaPublicKey *slave_key, 695 const struct GNUNET_CRYPTO_EddsaPublicKey *slave_key,
649 uint64_t message_id, uint64_t group_generation, 696 uint64_t message_id, uint64_t group_generation,
650 struct GNUNET_MULTICAST_MembershipTestHandle *mth) 697 struct GNUNET_MULTICAST_MembershipTestHandle *mth)
651{ 698{
652 699
653} 700}
654 701
655 702
656static void 703static void
657replay_fragment_cb (void *cls, 704mcast_replay_fragment_cb (void *cls,
658 const struct GNUNET_CRYPTO_EddsaPublicKey *slave_key, 705 const struct GNUNET_CRYPTO_EddsaPublicKey *slave_key,
659 uint64_t fragment_id, uint64_t flags, 706 uint64_t fragment_id, uint64_t flags,
660 struct GNUNET_MULTICAST_ReplayHandle *rh) 707 struct GNUNET_MULTICAST_ReplayHandle *rh)
661 708
662{ 709{
663 710
@@ -665,12 +712,12 @@ replay_fragment_cb (void *cls,
665 712
666 713
667static void 714static void
668replay_message_cb (void *cls, 715mcast_replay_message_cb (void *cls,
669 const struct GNUNET_CRYPTO_EddsaPublicKey *slave_key, 716 const struct GNUNET_CRYPTO_EddsaPublicKey *slave_key,
670 uint64_t message_id, 717 uint64_t message_id,
671 uint64_t fragment_offset, 718 uint64_t fragment_offset,
672 uint64_t flags, 719 uint64_t flags,
673 struct GNUNET_MULTICAST_ReplayHandle *rh) 720 struct GNUNET_MULTICAST_ReplayHandle *rh)
674{ 721{
675 722
676} 723}
@@ -744,7 +791,7 @@ mmsg_to_clients (struct Channel *ch,
744 pmsg->message_id = mmsg->message_id; 791 pmsg->message_id = mmsg->message_id;
745 792
746 memcpy (&pmsg[1], &mmsg[1], size - sizeof (*mmsg)); 793 memcpy (&pmsg[1], &mmsg[1], size - sizeof (*mmsg));
747 msg_to_clients (ch, (const struct GNUNET_MessageHeader *) pmsg); 794 msg_to_clients (ch, &pmsg->header);
748 GNUNET_free (pmsg); 795 GNUNET_free (pmsg);
749} 796}
750 797
@@ -988,6 +1035,7 @@ fragment_queue_run (struct Channel *ch, uint64_t msg_id,
988 * has already been delivered to the client. 1035 * has already been delivered to the client.
989 * 1036 *
990 * @param ch Channel. 1037 * @param ch Channel.
1038 *
991 * @return Number of messages removed from queue and sent to client. 1039 * @return Number of messages removed from queue and sent to client.
992 */ 1040 */
993static uint64_t 1041static uint64_t
@@ -1061,6 +1109,43 @@ message_queue_run (struct Channel *ch)
1061 1109
1062 1110
1063/** 1111/**
1112 * Drop message queue of a channel.
1113 *
1114 * Remove all messages in queue without sending it to clients.
1115 *
1116 * @param ch Channel.
1117 *
1118 * @return Number of messages removed from queue.
1119 */
1120static uint64_t
1121message_queue_drop (struct Channel *ch)
1122{
1123 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1124 "%p Dropping message queue.\n", ch);
1125 uint64_t n = 0;
1126 uint64_t msg_id;
1127 while (GNUNET_YES == GNUNET_CONTAINER_heap_peek2 (ch->recv_msgs, NULL,
1128 &msg_id))
1129 {
1130 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1131 "%p Dropping message %" PRIu64 " from queue.\n", ch, msg_id);
1132 struct GNUNET_HashCode msg_id_hash;
1133 hash_key_from_hll (&msg_id_hash, msg_id);
1134
1135 struct FragmentQueue *
1136 fragq = GNUNET_CONTAINER_multihashmap_get (ch->recv_frags, &msg_id_hash);
1137
1138 fragment_queue_run (ch, msg_id, fragq, GNUNET_YES);
1139 GNUNET_CONTAINER_heap_remove_root (ch->recv_msgs);
1140 n++;
1141 }
1142 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1143 "%p Removed %" PRIu64 " messages from queue.\n", ch, n);
1144 return n;
1145}
1146
1147
1148/**
1064 * Handle incoming message from multicast. 1149 * Handle incoming message from multicast.
1065 * 1150 *
1066 * @param ch Channel. 1151 * @param ch Channel.
@@ -1069,7 +1154,7 @@ message_queue_run (struct Channel *ch)
1069 * @return #GNUNET_OK or #GNUNET_SYSERR 1154 * @return #GNUNET_OK or #GNUNET_SYSERR
1070 */ 1155 */
1071static int 1156static int
1072handle_multicast_message (struct Channel *ch, 1157client_multicast_message (struct Channel *ch,
1073 const struct GNUNET_MULTICAST_MessageHeader *mmsg) 1158 const struct GNUNET_MULTICAST_MessageHeader *mmsg)
1074{ 1159{
1075 GNUNET_PSYCSTORE_fragment_store (store, &ch->pub_key, mmsg, 0, NULL, NULL); 1160 GNUNET_PSYCSTORE_fragment_store (store, &ch->pub_key, mmsg, 0, NULL, NULL);
@@ -1106,7 +1191,7 @@ handle_multicast_message (struct Channel *ch,
1106 * Store it using PSYCstore and send it to the client of the channel. 1191 * Store it using PSYCstore and send it to the client of the channel.
1107 */ 1192 */
1108static void 1193static void
1109message_cb (void *cls, const struct GNUNET_MessageHeader *msg) 1194mcast_message_cb (void *cls, const struct GNUNET_MessageHeader *msg)
1110{ 1195{
1111 struct Channel *ch = cls; 1196 struct Channel *ch = cls;
1112 uint16_t type = ntohs (msg->type); 1197 uint16_t type = ntohs (msg->type);
@@ -1120,7 +1205,7 @@ message_cb (void *cls, const struct GNUNET_MessageHeader *msg)
1120 { 1205 {
1121 case GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE: 1206 case GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE:
1122 { 1207 {
1123 handle_multicast_message (ch, (const struct 1208 client_multicast_message (ch, (const struct
1124 GNUNET_MULTICAST_MessageHeader *) msg); 1209 GNUNET_MULTICAST_MessageHeader *) msg);
1125 break; 1210 break;
1126 } 1211 }
@@ -1141,9 +1226,10 @@ message_cb (void *cls, const struct GNUNET_MessageHeader *msg)
1141 * @param flags Request flags. 1226 * @param flags Request flags.
1142 */ 1227 */
1143static void 1228static void
1144request_cb (void *cls, const struct GNUNET_CRYPTO_EddsaPublicKey *slave_key, 1229mcast_request_cb (void *cls,
1145 const struct GNUNET_MessageHeader *msg, 1230 const struct GNUNET_CRYPTO_EddsaPublicKey *slave_key,
1146 enum GNUNET_MULTICAST_MessageFlags flags) 1231 const struct GNUNET_MessageHeader *msg,
1232 enum GNUNET_MULTICAST_MessageFlags flags)
1147{ 1233{
1148 struct Master *mst = cls; 1234 struct Master *mst = cls;
1149 struct Channel *ch = &mst->ch; 1235 struct Channel *ch = &mst->ch;
@@ -1183,7 +1269,7 @@ request_cb (void *cls, const struct GNUNET_CRYPTO_EddsaPublicKey *slave_key,
1183 pmsg->flags = htonl (GNUNET_PSYC_MESSAGE_REQUEST); 1269 pmsg->flags = htonl (GNUNET_PSYC_MESSAGE_REQUEST);
1184 1270
1185 memcpy (&pmsg[1], &req[1], size - sizeof (*req)); 1271 memcpy (&pmsg[1], &req[1], size - sizeof (*req));
1186 msg_to_clients (ch, (const struct GNUNET_MessageHeader *) pmsg); 1272 msg_to_clients (ch, &pmsg->header);
1187 GNUNET_free (pmsg); 1273 GNUNET_free (pmsg);
1188 break; 1274 break;
1189 } 1275 }
@@ -1221,11 +1307,13 @@ master_counters_cb (void *cls, int result, uint64_t max_fragment_id,
1221 ch->max_state_message_id = max_state_message_id; 1307 ch->max_state_message_id = max_state_message_id;
1222 mst->max_group_generation = max_group_generation; 1308 mst->max_group_generation = max_group_generation;
1223 mst->origin 1309 mst->origin
1224 = GNUNET_MULTICAST_origin_start (cfg, &mst->priv_key, 1310 = GNUNET_MULTICAST_origin_start (cfg, &mst->priv_key, max_fragment_id,
1225 max_fragment_id, 1311 &mcast_join_request_cb,
1226 join_cb, membership_test_cb, 1312 &mcast_membership_test_cb,
1227 replay_fragment_cb, replay_message_cb, 1313 &mcast_replay_fragment_cb,
1228 request_cb, message_cb, ch); 1314 &mcast_replay_message_cb,
1315 &mcast_request_cb,
1316 &mcast_message_cb, ch);
1229 ch->ready = GNUNET_YES; 1317 ch->ready = GNUNET_YES;
1230 } 1318 }
1231 else 1319 else
@@ -1266,11 +1354,13 @@ slave_counters_cb (void *cls, int result, uint64_t max_fragment_id,
1266 = GNUNET_MULTICAST_member_join (cfg, &ch->pub_key, &slv->priv_key, 1354 = GNUNET_MULTICAST_member_join (cfg, &ch->pub_key, &slv->priv_key,
1267 &slv->origin, 1355 &slv->origin,
1268 slv->relay_count, slv->relays, 1356 slv->relay_count, slv->relays,
1269 slv->join_req, join_cb, 1357 slv->join_req,
1270 membership_test_cb, 1358 &mcast_join_request_cb,
1271 replay_fragment_cb, replay_message_cb, 1359 &mcast_join_decision_cb,
1272 message_cb, ch); 1360 &mcast_membership_test_cb,
1273 ch->ready = GNUNET_YES; 1361 &mcast_replay_fragment_cb,
1362 &mcast_replay_message_cb,
1363 &mcast_message_cb, ch);
1274 } 1364 }
1275 else 1365 else
1276 { 1366 {
@@ -1297,7 +1387,7 @@ channel_init (struct Channel *ch)
1297 * Handle a connecting client starting a channel master. 1387 * Handle a connecting client starting a channel master.
1298 */ 1388 */
1299static void 1389static void
1300handle_master_start (void *cls, struct GNUNET_SERVER_Client *client, 1390client_master_start (void *cls, struct GNUNET_SERVER_Client *client,
1301 const struct GNUNET_MessageHeader *msg) 1391 const struct GNUNET_MessageHeader *msg)
1302{ 1392{
1303 const struct MasterStartRequest *req 1393 const struct MasterStartRequest *req
@@ -1363,7 +1453,7 @@ handle_master_start (void *cls, struct GNUNET_SERVER_Client *client,
1363 * Handle a connecting client joining as a channel slave. 1453 * Handle a connecting client joining as a channel slave.
1364 */ 1454 */
1365static void 1455static void
1366handle_slave_join (void *cls, struct GNUNET_SERVER_Client *client, 1456client_slave_join (void *cls, struct GNUNET_SERVER_Client *client,
1367 const struct GNUNET_MessageHeader *msg) 1457 const struct GNUNET_MessageHeader *msg)
1368{ 1458{
1369 const struct SlaveJoinRequest *req 1459 const struct SlaveJoinRequest *req
@@ -1389,6 +1479,8 @@ handle_slave_join (void *cls, struct GNUNET_SERVER_Client *client,
1389 { 1479 {
1390 slv = GNUNET_new (struct Slave); 1480 slv = GNUNET_new (struct Slave);
1391 slv->priv_key = req->slave_key; 1481 slv->priv_key = req->slave_key;
1482 slv->pub_key = slv_pub_key;
1483 slv->pub_key_hash = slv_pub_key_hash;
1392 slv->origin = req->origin; 1484 slv->origin = req->origin;
1393 slv->relay_count = ntohl (req->relay_count); 1485 slv->relay_count = ntohl (req->relay_count);
1394 if (0 < slv->relay_count) 1486 if (0 < slv->relay_count)
@@ -1411,10 +1503,10 @@ handle_slave_join (void *cls, struct GNUNET_SERVER_Client *client,
1411 if (NULL == ch_slv) 1503 if (NULL == ch_slv)
1412 { 1504 {
1413 ch_slv = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES); 1505 ch_slv = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES);
1414 GNUNET_CONTAINER_multihashmap_put (channel_slaves, &pub_key_hash, ch_slv, 1506 GNUNET_CONTAINER_multihashmap_put (channel_slaves, &ch->pub_key_hash, ch_slv,
1415 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 1507 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1416 } 1508 }
1417 GNUNET_CONTAINER_multihashmap_put (ch_slv, &slv_pub_key_hash, ch, 1509 GNUNET_CONTAINER_multihashmap_put (ch_slv, &slv->pub_key_hash, ch,
1418 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); 1510 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
1419 GNUNET_CONTAINER_multihashmap_put (slaves, &ch->pub_key_hash, ch, 1511 GNUNET_CONTAINER_multihashmap_put (slaves, &ch->pub_key_hash, ch,
1420 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 1512 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
@@ -1434,6 +1526,29 @@ handle_slave_join (void *cls, struct GNUNET_SERVER_Client *client,
1434 GNUNET_SERVER_notification_context_add (nc, client); 1526 GNUNET_SERVER_notification_context_add (nc, client);
1435 GNUNET_SERVER_notification_context_unicast (nc, client, &res.header, 1527 GNUNET_SERVER_notification_context_unicast (nc, client, &res.header,
1436 GNUNET_NO); 1528 GNUNET_NO);
1529
1530 if (NULL == slv->member)
1531 {
1532 slv->member
1533 = GNUNET_MULTICAST_member_join (cfg, &ch->pub_key, &slv->priv_key,
1534 &slv->origin,
1535 slv->relay_count, slv->relays,
1536 slv->join_req,
1537 &mcast_join_request_cb,
1538 &mcast_join_decision_cb,
1539 &mcast_membership_test_cb,
1540 &mcast_replay_fragment_cb,
1541 &mcast_replay_message_cb,
1542 &mcast_message_cb, ch);
1543
1544 }
1545 else if (NULL != slv->join_dcsn)
1546 {
1547 GNUNET_SERVER_notification_context_add (nc, client);
1548 GNUNET_SERVER_notification_context_unicast (nc, client,
1549 &slv->join_dcsn->header,
1550 GNUNET_NO);
1551 }
1437 } 1552 }
1438 1553
1439 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1554 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1451,7 +1566,7 @@ handle_slave_join (void *cls, struct GNUNET_SERVER_Client *client,
1451 1566
1452struct JoinDecisionClosure 1567struct JoinDecisionClosure
1453{ 1568{
1454 uint8_t is_admitted; 1569 int32_t is_admitted;
1455 struct GNUNET_MessageHeader *msg; 1570 struct GNUNET_MessageHeader *msg;
1456}; 1571};
1457 1572
@@ -1460,8 +1575,8 @@ struct JoinDecisionClosure
1460 * Iterator callback for responding to join requests of a slave. 1575 * Iterator callback for responding to join requests of a slave.
1461 */ 1576 */
1462static int 1577static int
1463join_decision_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash, 1578send_join_decision_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash,
1464 void *jh) 1579 void *jh)
1465{ 1580{
1466 struct JoinDecisionClosure *jcls = cls; 1581 struct JoinDecisionClosure *jcls = cls;
1467 // FIXME: add relays 1582 // FIXME: add relays
@@ -1474,7 +1589,7 @@ join_decision_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash,
1474 * Join decision from client. 1589 * Join decision from client.
1475 */ 1590 */
1476static void 1591static void
1477handle_join_decision (void *cls, struct GNUNET_SERVER_Client *client, 1592client_join_decision (void *cls, struct GNUNET_SERVER_Client *client,
1478 const struct GNUNET_MessageHeader *msg) 1593 const struct GNUNET_MessageHeader *msg)
1479{ 1594{
1480 struct Channel * 1595 struct Channel *
@@ -1484,7 +1599,7 @@ handle_join_decision (void *cls, struct GNUNET_SERVER_Client *client,
1484 1599
1485 struct MasterJoinDecision *dcsn = (struct MasterJoinDecision *) msg; 1600 struct MasterJoinDecision *dcsn = (struct MasterJoinDecision *) msg;
1486 struct JoinDecisionClosure jcls; 1601 struct JoinDecisionClosure jcls;
1487 jcls.is_admitted = dcsn->is_admitted; 1602 jcls.is_admitted = ntohl (dcsn->is_admitted);
1488 jcls.msg 1603 jcls.msg
1489 = (sizeof (*dcsn) + sizeof (struct GNUNET_PSYC_MessageHeader) 1604 = (sizeof (*dcsn) + sizeof (struct GNUNET_PSYC_MessageHeader)
1490 <= ntohs (msg->size)) 1605 <= ntohs (msg->size))
@@ -1494,8 +1609,17 @@ handle_join_decision (void *cls, struct GNUNET_SERVER_Client *client,
1494 struct GNUNET_HashCode slave_key_hash; 1609 struct GNUNET_HashCode slave_key_hash;
1495 GNUNET_CRYPTO_hash (&dcsn->slave_key, sizeof (dcsn->slave_key), 1610 GNUNET_CRYPTO_hash (&dcsn->slave_key, sizeof (dcsn->slave_key),
1496 &slave_key_hash); 1611 &slave_key_hash);
1612
1613 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1614 "%p Got join decision (%d) from client for channel %s..\n",
1615 mst, jcls.is_admitted, GNUNET_h2s (&ch->pub_key_hash));
1616 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1617 "%p ..and slave %s.\n",
1618 mst, GNUNET_h2s (&slave_key_hash));
1619
1497 GNUNET_CONTAINER_multihashmap_get_multiple (mst->join_reqs, &slave_key_hash, 1620 GNUNET_CONTAINER_multihashmap_get_multiple (mst->join_reqs, &slave_key_hash,
1498 &join_decision_cb, &jcls); 1621 &send_join_decision_cb, &jcls);
1622 GNUNET_CONTAINER_multihashmap_remove_all (mst->join_reqs, &slave_key_hash);
1499 GNUNET_SERVER_receive_done (client, GNUNET_OK); 1623 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1500} 1624}
1501 1625
@@ -1758,10 +1882,10 @@ transmit_cancel (struct Channel *ch, struct GNUNET_SERVER_Client *client)
1758 1882
1759 1883
1760/** 1884/**
1761 * Incoming message from a client. 1885 * Incoming message from a master or slave client.
1762 */ 1886 */
1763static void 1887static void
1764handle_psyc_message (void *cls, struct GNUNET_SERVER_Client *client, 1888client_psyc_message (void *cls, struct GNUNET_SERVER_Client *client,
1765 const struct GNUNET_MessageHeader *msg) 1889 const struct GNUNET_MessageHeader *msg)
1766{ 1890{
1767 struct Channel * 1891 struct Channel *
@@ -1775,8 +1899,7 @@ handle_psyc_message (void *cls, struct GNUNET_SERVER_Client *client,
1775 if (GNUNET_YES != ch->ready) 1899 if (GNUNET_YES != ch->ready)
1776 { 1900 {
1777 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1901 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1778 "%p Dropping message from client, channel is not ready yet.\n", 1902 "%p Channel is not ready, dropping message from client.\n", ch);
1779 ch);
1780 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1903 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1781 return; 1904 return;
1782 } 1905 }
@@ -1784,7 +1907,7 @@ handle_psyc_message (void *cls, struct GNUNET_SERVER_Client *client,
1784 uint16_t size = ntohs (msg->size); 1907 uint16_t size = ntohs (msg->size);
1785 if (GNUNET_MULTICAST_FRAGMENT_MAX_PAYLOAD < size - sizeof (*msg)) 1908 if (GNUNET_MULTICAST_FRAGMENT_MAX_PAYLOAD < size - sizeof (*msg))
1786 { 1909 {
1787 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%p Message payload too large\n", ch); 1910 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%p Message payload too large.\n", ch);
1788 GNUNET_break (0); 1911 GNUNET_break (0);
1789 transmit_cancel (ch, client); 1912 transmit_cancel (ch, client);
1790 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1913 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
@@ -1817,7 +1940,7 @@ handle_psyc_message (void *cls, struct GNUNET_SERVER_Client *client,
1817 * Client requests to add a slave to the membership database. 1940 * Client requests to add a slave to the membership database.
1818 */ 1941 */
1819static void 1942static void
1820handle_slave_add (void *cls, struct GNUNET_SERVER_Client *client, 1943client_slave_add (void *cls, struct GNUNET_SERVER_Client *client,
1821 const struct GNUNET_MessageHeader *msg) 1944 const struct GNUNET_MessageHeader *msg)
1822{ 1945{
1823 1946
@@ -1828,7 +1951,7 @@ handle_slave_add (void *cls, struct GNUNET_SERVER_Client *client,
1828 * Client requests to remove a slave from the membership database. 1951 * Client requests to remove a slave from the membership database.
1829 */ 1952 */
1830static void 1953static void
1831handle_slave_remove (void *cls, struct GNUNET_SERVER_Client *client, 1954client_slave_remove (void *cls, struct GNUNET_SERVER_Client *client,
1832 const struct GNUNET_MessageHeader *msg) 1955 const struct GNUNET_MessageHeader *msg)
1833{ 1956{
1834 1957
@@ -1839,7 +1962,7 @@ handle_slave_remove (void *cls, struct GNUNET_SERVER_Client *client,
1839 * Client requests channel history from PSYCstore. 1962 * Client requests channel history from PSYCstore.
1840 */ 1963 */
1841static void 1964static void
1842handle_story_request (void *cls, struct GNUNET_SERVER_Client *client, 1965client_story_request (void *cls, struct GNUNET_SERVER_Client *client,
1843 const struct GNUNET_MessageHeader *msg) 1966 const struct GNUNET_MessageHeader *msg)
1844{ 1967{
1845 1968
@@ -1850,7 +1973,7 @@ handle_story_request (void *cls, struct GNUNET_SERVER_Client *client,
1850 * Client requests best matching state variable from PSYCstore. 1973 * Client requests best matching state variable from PSYCstore.
1851 */ 1974 */
1852static void 1975static void
1853handle_state_get (void *cls, struct GNUNET_SERVER_Client *client, 1976client_state_get (void *cls, struct GNUNET_SERVER_Client *client,
1854 const struct GNUNET_MessageHeader *msg) 1977 const struct GNUNET_MessageHeader *msg)
1855{ 1978{
1856 1979
@@ -1861,7 +1984,7 @@ handle_state_get (void *cls, struct GNUNET_SERVER_Client *client,
1861 * Client requests state variables with a given prefix from PSYCstore. 1984 * Client requests state variables with a given prefix from PSYCstore.
1862 */ 1985 */
1863static void 1986static void
1864handle_state_get_prefix (void *cls, struct GNUNET_SERVER_Client *client, 1987client_state_get_prefix (void *cls, struct GNUNET_SERVER_Client *client,
1865 const struct GNUNET_MessageHeader *msg) 1988 const struct GNUNET_MessageHeader *msg)
1866{ 1989{
1867 1990
@@ -1880,31 +2003,31 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
1880 const struct GNUNET_CONFIGURATION_Handle *c) 2003 const struct GNUNET_CONFIGURATION_Handle *c)
1881{ 2004{
1882 static const struct GNUNET_SERVER_MessageHandler handlers[] = { 2005 static const struct GNUNET_SERVER_MessageHandler handlers[] = {
1883 { &handle_master_start, NULL, 2006 { &client_master_start, NULL,
1884 GNUNET_MESSAGE_TYPE_PSYC_MASTER_START, 0 }, 2007 GNUNET_MESSAGE_TYPE_PSYC_MASTER_START, 0 },
1885 2008
1886 { &handle_slave_join, NULL, 2009 { &client_slave_join, NULL,
1887 GNUNET_MESSAGE_TYPE_PSYC_SLAVE_JOIN, 0 }, 2010 GNUNET_MESSAGE_TYPE_PSYC_SLAVE_JOIN, 0 },
1888 2011
1889 { &handle_join_decision, NULL, 2012 { &client_join_decision, NULL,
1890 GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION, 0 }, 2013 GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION, 0 },
1891 2014
1892 { &handle_psyc_message, NULL, 2015 { &client_psyc_message, NULL,
1893 GNUNET_MESSAGE_TYPE_PSYC_MESSAGE, 0 }, 2016 GNUNET_MESSAGE_TYPE_PSYC_MESSAGE, 0 },
1894 2017
1895 { &handle_slave_add, NULL, 2018 { &client_slave_add, NULL,
1896 GNUNET_MESSAGE_TYPE_PSYC_CHANNEL_SLAVE_ADD, 0 }, 2019 GNUNET_MESSAGE_TYPE_PSYC_CHANNEL_SLAVE_ADD, 0 },
1897 2020
1898 { &handle_slave_remove, NULL, 2021 { &client_slave_remove, NULL,
1899 GNUNET_MESSAGE_TYPE_PSYC_CHANNEL_SLAVE_RM, 0 }, 2022 GNUNET_MESSAGE_TYPE_PSYC_CHANNEL_SLAVE_RM, 0 },
1900 2023
1901 { &handle_story_request, NULL, 2024 { &client_story_request, NULL,
1902 GNUNET_MESSAGE_TYPE_PSYC_STORY_REQUEST, 0 }, 2025 GNUNET_MESSAGE_TYPE_PSYC_STORY_REQUEST, 0 },
1903 2026
1904 { &handle_state_get, NULL, 2027 { &client_state_get, NULL,
1905 GNUNET_MESSAGE_TYPE_PSYC_STATE_GET, 0 }, 2028 GNUNET_MESSAGE_TYPE_PSYC_STATE_GET, 0 },
1906 2029
1907 { &handle_state_get_prefix, NULL, 2030 { &client_state_get_prefix, NULL,
1908 GNUNET_MESSAGE_TYPE_PSYC_STATE_GET_PREFIX, 0 } 2031 GNUNET_MESSAGE_TYPE_PSYC_STATE_GET_PREFIX, 0 }
1909 }; 2032 };
1910 2033
diff --git a/src/psyc/psyc.h b/src/psyc/psyc.h
index 47f2a0122..66c8de898 100644
--- a/src/psyc/psyc.h
+++ b/src/psyc/psyc.h
@@ -250,19 +250,36 @@ struct MasterJoinDecision
250 struct GNUNET_MessageHeader header; 250 struct GNUNET_MessageHeader header;
251 251
252 /** 252 /**
253 * #GNUNET_YES if the slave was admitted.
254 */
255 int32_t is_admitted;
256
257 /**
253 * Public key of the joining slave. 258 * Public key of the joining slave.
254 */ 259 */
255 struct GNUNET_CRYPTO_EddsaPublicKey slave_key; 260 struct GNUNET_CRYPTO_EddsaPublicKey slave_key;
256 261
262 /* Followed by struct GNUNET_MessageHeader join_response */
263};
264
265
266struct SlaveJoinDecision
267{
268 /**
269 * Type: GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION
270 */
271 struct GNUNET_MessageHeader header;
272
257 /** 273 /**
258 * #GNUNET_YES if the slave was admitted. 274 * #GNUNET_YES if the slave was admitted.
259 */ 275 */
260 uint8_t is_admitted; 276 int32_t is_admitted;
261 277
262 /* Followed by struct GNUNET_MessageHeader join_response */ 278 /* Followed by struct GNUNET_MessageHeader join_response */
263}; 279};
264 280
265 281
282
266GNUNET_NETWORK_STRUCT_END 283GNUNET_NETWORK_STRUCT_END
267 284
268#endif 285#endif
diff --git a/src/psyc/psyc_api.c b/src/psyc/psyc_api.c
index ee49a584f..7ec9d21b7 100644
--- a/src/psyc/psyc_api.c
+++ b/src/psyc/psyc_api.c
@@ -198,9 +198,9 @@ struct GNUNET_PSYC_Master
198 GNUNET_PSYC_MasterStartCallback start_cb; 198 GNUNET_PSYC_MasterStartCallback start_cb;
199 199
200 /** 200 /**
201 * Join handler callback. 201 * Join request callback.
202 */ 202 */
203 GNUNET_PSYC_JoinCallback join_cb; 203 GNUNET_PSYC_JoinRequestCallback join_req_cb;
204}; 204};
205 205
206 206
@@ -211,14 +211,16 @@ struct GNUNET_PSYC_Slave
211{ 211{
212 struct GNUNET_PSYC_Channel ch; 212 struct GNUNET_PSYC_Channel ch;
213 213
214 GNUNET_PSYC_SlaveJoinCallback join_cb; 214 GNUNET_PSYC_SlaveConnectCallback connect_cb;
215
216 GNUNET_PSYC_JoinDecisionCallback join_dcsn_cb;
215}; 217};
216 218
217 219
218/** 220/**
219 * Handle that identifies a join request. 221 * Handle that identifies a join request.
220 * 222 *
221 * Used to match calls to #GNUNET_PSYC_JoinCallback to the 223 * Used to match calls to #GNUNET_PSYC_JoinRequestCallback to the
222 * corresponding calls to GNUNET_PSYC_join_decision(). 224 * corresponding calls to GNUNET_PSYC_join_decision().
223 */ 225 */
224struct GNUNET_PSYC_JoinHandle 226struct GNUNET_PSYC_JoinHandle
@@ -922,7 +924,22 @@ handle_psyc_join_request (struct GNUNET_PSYC_Master *mst,
922 jh->mst = mst; 924 jh->mst = mst;
923 jh->slave_key = req->slave_key; 925 jh->slave_key = req->slave_key;
924 926
925 mst->join_cb (mst->ch.cb_cls, &req->slave_key, msg, jh); 927 if (NULL != mst->join_req_cb)
928 mst->join_req_cb (mst->ch.cb_cls, &req->slave_key, msg, jh);
929}
930
931
932static void
933handle_psyc_join_decision (struct GNUNET_PSYC_Slave *slv,
934 const struct SlaveJoinDecision *dcsn)
935{
936 struct GNUNET_PSYC_MessageHeader *msg = NULL;
937 if (ntohs (dcsn->header.size) <= sizeof (*dcsn) + sizeof (*msg))
938 msg = (struct GNUNET_PSYC_MessageHeader *) &dcsn[1];
939
940 struct GNUNET_PSYC_JoinHandle *jh = GNUNET_malloc (sizeof (*jh));
941 if (NULL != slv->join_dcsn_cb)
942 slv->join_dcsn_cb (slv->ch.cb_cls, ntohl (dcsn->is_admitted), msg);
926} 943}
927 944
928 945
@@ -971,6 +988,9 @@ message_handler (void *cls,
971 case GNUNET_MESSAGE_TYPE_PSYC_JOIN_REQUEST: 988 case GNUNET_MESSAGE_TYPE_PSYC_JOIN_REQUEST:
972 size_min = sizeof (struct MasterJoinRequest); 989 size_min = sizeof (struct MasterJoinRequest);
973 break; 990 break;
991 case GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION:
992 size_min = sizeof (struct SlaveJoinDecision);
993 break;
974 default: 994 default:
975 GNUNET_break_op (0); 995 GNUNET_break_op (0);
976 return; 996 return;
@@ -995,8 +1015,8 @@ message_handler (void *cls,
995 case GNUNET_MESSAGE_TYPE_PSYC_SLAVE_JOIN_ACK: 1015 case GNUNET_MESSAGE_TYPE_PSYC_SLAVE_JOIN_ACK:
996 { 1016 {
997 struct CountersResult *cres = (struct CountersResult *) msg; 1017 struct CountersResult *cres = (struct CountersResult *) msg;
998 if (NULL != slv->join_cb) 1018 if (NULL != slv->connect_cb)
999 slv->join_cb (ch->cb_cls, GNUNET_ntohll (cres->max_message_id)); 1019 slv->connect_cb (ch->cb_cls, GNUNET_ntohll (cres->max_message_id));
1000 break; 1020 break;
1001 } 1021 }
1002 case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_ACK: 1022 case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_ACK:
@@ -1013,6 +1033,11 @@ message_handler (void *cls,
1013 handle_psyc_join_request ((struct GNUNET_PSYC_Master *) ch, 1033 handle_psyc_join_request ((struct GNUNET_PSYC_Master *) ch,
1014 (const struct MasterJoinRequest *) msg); 1034 (const struct MasterJoinRequest *) msg);
1015 break; 1035 break;
1036
1037 case GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION:
1038 handle_psyc_join_decision ((struct GNUNET_PSYC_Slave *) ch,
1039 (const struct SlaveJoinDecision *) msg);
1040 break;
1016 } 1041 }
1017 1042
1018 if (NULL != ch->client) 1043 if (NULL != ch->client)
@@ -1175,20 +1200,20 @@ disconnect (void *c)
1175 * or part messages, the respective methods must call other PSYC functions to 1200 * or part messages, the respective methods must call other PSYC functions to
1176 * inform PSYC about the meaning of the respective events. 1201 * inform PSYC about the meaning of the respective events.
1177 * 1202 *
1178 * @param cfg Configuration to use (to connect to PSYC service). 1203 * @param cfg Configuration to use (to connect to PSYC service).
1179 * @param channel_key ECC key that will be used to sign messages for this 1204 * @param channel_key ECC key that will be used to sign messages for this
1180 * PSYC session. The public key is used to identify the PSYC channel. 1205 * PSYC session. The public key is used to identify the PSYC channel.
1181 * Note that end-users will usually not use the private key directly, but 1206 * Note that end-users will usually not use the private key directly, but
1182 * rather look it up in GNS for places managed by other users, or select 1207 * rather look it up in GNS for places managed by other users, or select
1183 * a file with the private key(s) when setting up their own channels 1208 * a file with the private key(s) when setting up their own channels
1184 * FIXME: we'll likely want to use NOT the p521 curve here, but a cheaper 1209 * FIXME: we'll likely want to use NOT the p521 curve here, but a cheaper
1185 * one in the future. 1210 * one in the future.
1186 * @param policy Channel policy specifying join and history restrictions. 1211 * @param policy Channel policy specifying join and history restrictions.
1187 * Used to automate join decisions. 1212 * Used to automate join decisions.
1188 * @param message_cb Function to invoke on message parts received from slaves. 1213 * @param message_cb Function to invoke on message parts received from slaves.
1189 * @param join_cb Function to invoke when a peer wants to join. 1214 * @param join_request_cb Function to invoke when a slave wants to join.
1190 * @param master_started_cb Function to invoke after the channel master started. 1215 * @param master_start_cb Function to invoke after the channel master started.
1191 * @param cls Closure for @a master_started_cb and @a join_cb. 1216 * @param cls Closure for @a method and @a join_cb.
1192 * 1217 *
1193 * @return Handle for the channel master, NULL on error. 1218 * @return Handle for the channel master, NULL on error.
1194 */ 1219 */
@@ -1196,9 +1221,9 @@ struct GNUNET_PSYC_Master *
1196GNUNET_PSYC_master_start (const struct GNUNET_CONFIGURATION_Handle *cfg, 1221GNUNET_PSYC_master_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
1197 const struct GNUNET_CRYPTO_EddsaPrivateKey *channel_key, 1222 const struct GNUNET_CRYPTO_EddsaPrivateKey *channel_key,
1198 enum GNUNET_PSYC_Policy policy, 1223 enum GNUNET_PSYC_Policy policy,
1224 GNUNET_PSYC_MasterStartCallback start_cb,
1225 GNUNET_PSYC_JoinRequestCallback join_request_cb,
1199 GNUNET_PSYC_MessageCallback message_cb, 1226 GNUNET_PSYC_MessageCallback message_cb,
1200 GNUNET_PSYC_JoinCallback join_cb,
1201 GNUNET_PSYC_MasterStartCallback master_started_cb,
1202 void *cls) 1227 void *cls)
1203{ 1228{
1204 struct GNUNET_PSYC_Master *mst = GNUNET_malloc (sizeof (*mst)); 1229 struct GNUNET_PSYC_Master *mst = GNUNET_malloc (sizeof (*mst));
@@ -1210,8 +1235,8 @@ GNUNET_PSYC_master_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
1210 req->channel_key = *channel_key; 1235 req->channel_key = *channel_key;
1211 req->policy = policy; 1236 req->policy = policy;
1212 1237
1213 mst->start_cb = master_started_cb; 1238 mst->start_cb = start_cb;
1214 mst->join_cb = join_cb; 1239 mst->join_req_cb = join_request_cb;
1215 ch->message_cb = message_cb; 1240 ch->message_cb = message_cb;
1216 ch->cb_cls = cls; 1241 ch->cb_cls = cls;
1217 ch->cfg = cfg; 1242 ch->cfg = cfg;
@@ -1244,8 +1269,9 @@ GNUNET_PSYC_master_stop (struct GNUNET_PSYC_Master *master)
1244 * #GNUNET_PSYC_JoinCallback. 1269 * #GNUNET_PSYC_JoinCallback.
1245 * 1270 *
1246 * @param jh Join request handle. 1271 * @param jh Join request handle.
1247 * @param is_admitted #GNUNET_YES if joining is approved, 1272 * @param is_admitted #GNUNET_YES if the join is approved,
1248 * #GNUNET_NO if it is disapproved. 1273 * #GNUNET_NO if it is disapproved,
1274 * #GNUNET_SYSERR if we cannot answer the request.
1249 * @param relay_count Number of relays given. 1275 * @param relay_count Number of relays given.
1250 * @param relays Array of suggested peers that might be useful relays to use 1276 * @param relays Array of suggested peers that might be useful relays to use
1251 * when joining the multicast group (essentially a list of peers that 1277 * when joining the multicast group (essentially a list of peers that
@@ -1254,48 +1280,42 @@ GNUNET_PSYC_master_stop (struct GNUNET_PSYC_Master *master)
1254 * be the multicast origin) is a good candidate for building the 1280 * be the multicast origin) is a good candidate for building the
1255 * multicast tree. Note that it is unnecessary to specify our own 1281 * multicast tree. Note that it is unnecessary to specify our own
1256 * peer identity in this array. 1282 * peer identity in this array.
1257 * @param method_name Method name for the message transmitted with the response. 1283 * @param join_resp Application-dependent join response message.
1258 * @param env Environment containing transient variables for the message, or NULL. 1284 *
1259 * @param data Data of the message. 1285 * @return #GNUNET_OK on success,
1260 * @param data_size Size of @a data. 1286 * #GNUNET_SYSERR if the message is too large.
1261 */ 1287 */
1262void 1288int
1263GNUNET_PSYC_join_decision (struct GNUNET_PSYC_JoinHandle *jh, 1289GNUNET_PSYC_join_decision (struct GNUNET_PSYC_JoinHandle *jh,
1264 int is_admitted, 1290 int is_admitted,
1265 uint32_t relay_count, 1291 uint32_t relay_count,
1266 const struct GNUNET_PeerIdentity *relays, 1292 const struct GNUNET_PeerIdentity *relays,
1267 const char *method_name, 1293 const struct GNUNET_PSYC_MessageHeader *join_resp)
1268 const struct GNUNET_ENV_Environment *env,
1269 const void *data,
1270 size_t data_size)
1271{ 1294{
1272 struct GNUNET_PSYC_Channel *ch = &jh->mst->ch; 1295 struct GNUNET_PSYC_Channel *ch = &jh->mst->ch;
1273
1274 struct MasterJoinDecision *dcsn; 1296 struct MasterJoinDecision *dcsn;
1275 struct GNUNET_PSYC_MessageHeader *pmsg = NULL; 1297 uint16_t join_resp_size
1276 uint16_t pmsg_size = 0; 1298 = (NULL != join_resp) ? ntohs (join_resp->header.size) : 0;
1277/* FIXME:
1278 sizeof (*pmsg)
1279 + sizeof (struct GNUNET_PSYC_MessageMethod)
1280 + vars_size
1281 + sizeof (struct GNUNET_MessageHeader) + data_size
1282 + sizeof (struct GNUNET_MessageHeader);
1283*/
1284 uint16_t relay_size = relay_count * sizeof (*relays); 1299 uint16_t relay_size = relay_count * sizeof (*relays);
1285 struct MessageQueue * 1300
1286 mq = GNUNET_malloc (sizeof (*mq) + sizeof (*dcsn) + relay_size + pmsg_size); 1301 if (GNUNET_MULTICAST_FRAGMENT_MAX_PAYLOAD
1302 < sizeof (*dcsn) + relay_size + join_resp_size)
1303 return GNUNET_SYSERR;
1304
1305 struct MessageQueue *mq = GNUNET_malloc (sizeof (*mq) + sizeof (*dcsn)
1306 + relay_size + join_resp_size);
1287 dcsn = (struct MasterJoinDecision *) &mq[1]; 1307 dcsn = (struct MasterJoinDecision *) &mq[1];
1288 dcsn->header.size = htons (sizeof (*dcsn) + relay_size + pmsg_size); 1308 dcsn->header.size = htons (sizeof (*dcsn) + relay_size + join_resp_size);
1289 dcsn->header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION); 1309 dcsn->header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION);
1290 dcsn->is_admitted = (GNUNET_YES == is_admitted) ? GNUNET_YES : GNUNET_NO; 1310 dcsn->is_admitted = htonl (is_admitted);
1291 dcsn->slave_key = jh->slave_key; 1311 dcsn->slave_key = jh->slave_key;
1292 1312
1293 /* FIXME: add message parts to pmsg */ 1313 if (0 < join_resp_size)
1294 if (0 < pmsg_size) 1314 memcpy (&dcsn[1], join_resp, join_resp_size);
1295 memcpy (&dcsn[1], pmsg, pmsg_size);
1296 1315
1297 GNUNET_CONTAINER_DLL_insert_tail (ch->tmit_head, ch->tmit_tail, mq); 1316 GNUNET_CONTAINER_DLL_insert_tail (ch->tmit_head, ch->tmit_tail, mq);
1298 transmit_next (ch); 1317 transmit_next (ch);
1318 return GNUNET_OK;
1299} 1319}
1300 1320
1301 1321
@@ -1359,24 +1379,27 @@ GNUNET_PSYC_master_transmit_cancel (struct GNUNET_PSYC_MasterTransmitHandle *th)
1359 * notification on failure (as the channel may simply take days to approve, 1379 * notification on failure (as the channel may simply take days to approve,
1360 * and disapproval is simply being ignored). 1380 * and disapproval is simply being ignored).
1361 * 1381 *
1362 * @param cfg Configuration to use. 1382 * @param cfg Configuration to use.
1363 * @param channel_key ECC public key that identifies the channel we wish to join. 1383 * @param channel_key ECC public key that identifies the channel we wish to join.
1364 * @param slave_key ECC private-public key pair that identifies the slave, and 1384 * @param slave_key ECC private-public key pair that identifies the slave, and
1365 * used by multicast to sign the join request and subsequent unicast 1385 * used by multicast to sign the join request and subsequent unicast
1366 * requests sent to the master. 1386 * requests sent to the master.
1367 * @param origin Peer identity of the origin. 1387 * @param origin Peer identity of the origin.
1368 * @param relay_count Number of peers in the @a relays array. 1388 * @param relay_count Number of peers in the @a relays array.
1369 * @param relays Peer identities of members of the multicast group, which serve 1389 * @param relays Peer identities of members of the multicast group, which serve
1370 * as relays and used to join the group at. 1390 * as relays and used to join the group at.
1371 * @param message_cb Function to invoke on message parts received from the 1391 * @param message_cb Function to invoke on message parts received from the
1372 * channel, typically at least contains method handlers for @e join and 1392 * channel, typically at least contains method handlers for @e join and
1373 * @e part. 1393 * @e part.
1374 * @param slave_joined_cb Function invoked once we have joined the channel. 1394 * @param slave_connect_cb Function invoked once we have connected to the
1375 * @param cls Closure for @a message_cb and @a slave_joined_cb. 1395 * PSYC service.
1376 * @param method_name Method name for the join request. 1396 * @param join_decision_cb Function invoked once we have received a join
1377 * @param env Environment containing transient variables for the request, or NULL. 1397 * decision.
1378 * @param data Payload for the join message. 1398 * @param cls Closure for @a message_cb and @a slave_joined_cb.
1379 * @param data_size Number of bytes in @a data. 1399 * @param method_name Method name for the join request.
1400 * @param env Environment containing transient variables for the request, or NULL.
1401 * @param data Payload for the join message.
1402 * @param data_size Number of bytes in @a data.
1380 * 1403 *
1381 * @return Handle for the slave, NULL on error. 1404 * @return Handle for the slave, NULL on error.
1382 */ 1405 */
@@ -1388,7 +1411,8 @@ GNUNET_PSYC_slave_join (const struct GNUNET_CONFIGURATION_Handle *cfg,
1388 uint32_t relay_count, 1411 uint32_t relay_count,
1389 const struct GNUNET_PeerIdentity *relays, 1412 const struct GNUNET_PeerIdentity *relays,
1390 GNUNET_PSYC_MessageCallback message_cb, 1413 GNUNET_PSYC_MessageCallback message_cb,
1391 GNUNET_PSYC_SlaveJoinCallback slave_joined_cb, 1414 GNUNET_PSYC_SlaveConnectCallback connect_cb,
1415 GNUNET_PSYC_JoinDecisionCallback join_decision_cb,
1392 void *cls, 1416 void *cls,
1393 const char *method_name, 1417 const char *method_name,
1394 const struct GNUNET_ENV_Environment *env, 1418 const struct GNUNET_ENV_Environment *env,
@@ -1408,7 +1432,8 @@ GNUNET_PSYC_slave_join (const struct GNUNET_CONFIGURATION_Handle *cfg,
1408 req->relay_count = htonl (relay_count); 1432 req->relay_count = htonl (relay_count);
1409 memcpy (&req[1], relays, relay_count * sizeof (*relays)); 1433 memcpy (&req[1], relays, relay_count * sizeof (*relays));
1410 1434
1411 slv->join_cb = slave_joined_cb; 1435 slv->connect_cb = connect_cb;
1436 slv->join_dcsn_cb = join_decision_cb;
1412 ch->message_cb = message_cb; 1437 ch->message_cb = message_cb;
1413 ch->cb_cls = cls; 1438 ch->cb_cls = cls;
1414 1439
diff --git a/src/psyc/test_psyc.c b/src/psyc/test_psyc.c
index 4195e464b..8b4aad773 100644
--- a/src/psyc/test_psyc.c
+++ b/src/psyc/test_psyc.c
@@ -35,9 +35,9 @@
35#include "gnunet_env_lib.h" 35#include "gnunet_env_lib.h"
36#include "gnunet_psyc_service.h" 36#include "gnunet_psyc_service.h"
37 37
38#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) 38#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
39 39
40#define DEBUG_SERVICE 0 40#define DEBUG_SERVICE 1
41 41
42 42
43/** 43/**
@@ -79,6 +79,7 @@ struct TransmitClosure
79 79
80struct TransmitClosure *tmit; 80struct TransmitClosure *tmit;
81 81
82static int join_req_count;
82 83
83enum 84enum
84{ 85{
@@ -167,8 +168,8 @@ end ()
167 168
168 169
169static void 170static void
170master_message (void *cls, uint64_t message_id, uint32_t flags, 171master_message_cb (void *cls, uint64_t message_id, uint32_t flags,
171 const struct GNUNET_MessageHeader *msg) 172 const struct GNUNET_MessageHeader *msg)
172{ 173{
173 if (NULL == msg) 174 if (NULL == msg)
174 { 175 {
@@ -211,8 +212,8 @@ master_message (void *cls, uint64_t message_id, uint32_t flags,
211 212
212 213
213static void 214static void
214slave_message (void *cls, uint64_t message_id, uint32_t flags, 215slave_message_cb (void *cls, uint64_t message_id, uint32_t flags,
215 const struct GNUNET_MessageHeader *msg) 216 const struct GNUNET_MessageHeader *msg)
216{ 217{
217 if (NULL == msg) 218 if (NULL == msg)
218 { 219 {
@@ -243,23 +244,6 @@ slave_message (void *cls, uint64_t message_id, uint32_t flags,
243 244
244 245
245static void 246static void
246join_request (void *cls, const struct GNUNET_CRYPTO_EddsaPublicKey *slave_key,
247 const struct GNUNET_PSYC_MessageHeader *msg,
248 struct GNUNET_PSYC_JoinHandle *jh)
249{
250 struct GNUNET_HashCode slave_key_hash;
251 GNUNET_CRYPTO_hash (slave_key, sizeof (*slave_key), &slave_key_hash);
252 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
253 "Got join request from %s.\n",
254 GNUNET_h2s (&slave_key_hash));
255
256 GNUNET_PSYC_join_decision (jh, GNUNET_YES, 0, NULL, "_notice_join", NULL,
257 "you're in", 9);
258 // FIXME: also test refusing entry
259}
260
261
262static void
263transmit_resume (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 247transmit_resume (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
264{ 248{
265 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmission resumed.\n"); 249 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmission resumed.\n");
@@ -392,9 +376,23 @@ tmit_notify_data (void *cls, uint16_t *data_size, void *data)
392 376
393 377
394static void 378static void
395slave_joined (void *cls, uint64_t max_message_id) 379slave_join ();
380
381
382static void
383join_decision_cb (void *cls, int is_admitted,
384 const struct GNUNET_PSYC_MessageHeader *join_msg)
396{ 385{
397 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Slave joined: %lu\n", max_message_id); 386 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
387 "Slave got join decision: %d\n", is_admitted);
388
389 if (GNUNET_YES != is_admitted)
390 { /* First join request is refused, retry. */
391 //GNUNET_assert (1 == join_req_count);
392 slave_join ();
393 return;
394 }
395
398 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Slave sending request to master.\n"); 396 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Slave sending request to master.\n");
399 397
400 test = TEST_SLAVE_TRANSMIT; 398 test = TEST_SLAVE_TRANSMIT;
@@ -414,20 +412,46 @@ slave_joined (void *cls, uint64_t max_message_id)
414 GNUNET_PSYC_SLAVE_TRANSMIT_NONE); 412 GNUNET_PSYC_SLAVE_TRANSMIT_NONE);
415} 413}
416 414
415
416static void
417join_request_cb (void *cls, const struct GNUNET_CRYPTO_EddsaPublicKey *slave_key,
418 const struct GNUNET_PSYC_MessageHeader *msg,
419 struct GNUNET_PSYC_JoinHandle *jh)
420{
421 struct GNUNET_HashCode slave_key_hash;
422 GNUNET_CRYPTO_hash (slave_key, sizeof (*slave_key), &slave_key_hash);
423 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
424 "Got join request from %s.\n",
425 GNUNET_h2s (&slave_key_hash));
426
427 /* Reject first request */
428 int is_admitted = (0 < join_req_count++) ? GNUNET_YES : GNUNET_NO;
429 GNUNET_PSYC_join_decision (jh, is_admitted, 0, NULL, NULL);
430}
431
432
433static void
434slave_connect_cb (void *cls, uint64_t max_message_id)
435{
436 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
437 "Slave connected: %lu\n", max_message_id);
438}
439
440
417static void 441static void
418slave_join () 442slave_join ()
419{ 443{
420 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Joining slave.\n"); 444 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Joining slave.\n");
421 445
422 struct GNUNET_PeerIdentity origin; 446 struct GNUNET_PeerIdentity origin; // FIXME: this peer
423 struct GNUNET_PeerIdentity relays[16];
424 struct GNUNET_ENV_Environment *env = GNUNET_ENV_environment_create (); 447 struct GNUNET_ENV_Environment *env = GNUNET_ENV_environment_create ();
425 GNUNET_ENV_environment_add (env, GNUNET_ENV_OP_ASSIGN, 448 GNUNET_ENV_environment_add (env, GNUNET_ENV_OP_ASSIGN,
426 "_foo", "bar baz", 7); 449 "_foo", "bar baz", 7);
427 GNUNET_ENV_environment_add (env, GNUNET_ENV_OP_ASSIGN, 450 GNUNET_ENV_environment_add (env, GNUNET_ENV_OP_ASSIGN,
428 "_foo_bar", "foo bar baz", 11); 451 "_foo_bar", "foo bar baz", 11);
429 slv = GNUNET_PSYC_slave_join (cfg, &channel_pub_key, slave_key, &origin, 452 slv = GNUNET_PSYC_slave_join (cfg, &channel_pub_key, slave_key, &origin,
430 16, relays, &slave_message, &slave_joined, NULL, 453 0, NULL, &slave_message_cb,
454 &slave_connect_cb, &join_decision_cb, NULL,
431 "_request_join", env, "some data", 9); 455 "_request_join", env, "some data", 9);
432 GNUNET_ENV_environment_destroy (env); 456 GNUNET_ENV_environment_destroy (env);
433} 457}
@@ -485,7 +509,7 @@ master_transmit ()
485 509
486 510
487static void 511static void
488master_started (void *cls, uint64_t max_message_id) 512master_start_cb (void *cls, uint64_t max_message_id)
489{ 513{
490 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 514 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
491 "Master started: %" PRIu64 "\n", max_message_id); 515 "Master started: %" PRIu64 "\n", max_message_id);
@@ -521,8 +545,8 @@ run (void *cls,
521 545
522 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Starting master.\n"); 546 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Starting master.\n");
523 mst = GNUNET_PSYC_master_start (cfg, channel_key, GNUNET_PSYC_CHANNEL_PRIVATE, 547 mst = GNUNET_PSYC_master_start (cfg, channel_key, GNUNET_PSYC_CHANNEL_PRIVATE,
524 &master_message, &join_request, 548 &master_start_cb, &join_request_cb,
525 &master_started, NULL); 549 &master_message_cb, NULL);
526} 550}
527 551
528 552