diff options
-rwxr-xr-x | contrib/gnunet-logread | 2 | ||||
-rw-r--r-- | src/include/gnunet_client_manager_lib.h | 6 | ||||
-rw-r--r-- | src/include/gnunet_common.h | 9 | ||||
-rw-r--r-- | src/include/gnunet_multicast_service.h | 8 | ||||
-rw-r--r-- | src/include/gnunet_protocols.h | 22 | ||||
-rw-r--r-- | src/include/gnunet_psyc_service.h | 111 | ||||
-rw-r--r-- | src/include/gnunet_psyc_util_lib.h | 28 | ||||
-rw-r--r-- | src/include/gnunet_social_service.h | 261 | ||||
-rw-r--r-- | src/multicast/gnunet-service-multicast.c | 7 | ||||
-rw-r--r-- | src/multicast/multicast_api.c | 76 | ||||
-rw-r--r-- | src/psyc/gnunet-service-psyc.c | 112 | ||||
-rw-r--r-- | src/psyc/psyc.h | 16 | ||||
-rw-r--r-- | src/psyc/psyc_api.c | 133 | ||||
-rw-r--r-- | src/psyc/psyc_util_lib.c | 268 | ||||
-rw-r--r-- | src/psyc/test_psyc.c | 93 | ||||
-rw-r--r-- | src/social/Makefile.am | 5 | ||||
-rw-r--r-- | src/social/gnunet-service-social.c | 1219 | ||||
-rw-r--r-- | src/social/social.h | 85 | ||||
-rw-r--r-- | src/social/social_api.c | 1259 | ||||
-rw-r--r-- | src/social/test_social.c | 686 | ||||
-rw-r--r-- | src/util/client_manager.c | 56 |
21 files changed, 3942 insertions, 520 deletions
diff --git a/contrib/gnunet-logread b/contrib/gnunet-logread index 773a5ff93..173ed2387 100755 --- a/contrib/gnunet-logread +++ b/contrib/gnunet-logread | |||
@@ -47,7 +47,7 @@ if (exists $opts{n}) | |||
47 | $ipc = $opts{i} || '/tmp/gnunet-logread-ipc.sock'; | 47 | $ipc = $opts{i} || '/tmp/gnunet-logread-ipc.sock'; |
48 | $msg_level = exists $levels{$opts{L}} ? $levels{$opts{L}} : 0; | 48 | $msg_level = exists $levels{$opts{L}} ? $levels{$opts{L}} : 0; |
49 | $msg_regex = $opts{m}; | 49 | $msg_regex = $opts{m}; |
50 | print STDERR "RE: /$msg_regex/\n"; | 50 | print STDERR "RE: /$msg_regex/\n" if defined $msg_regex; |
51 | open IPC, '>', $ipc or die "$ipc: $!\n"; | 51 | open IPC, '>', $ipc or die "$ipc: $!\n"; |
52 | } | 52 | } |
53 | 53 | ||
diff --git a/src/include/gnunet_client_manager_lib.h b/src/include/gnunet_client_manager_lib.h index 6ed2ddb17..07d9d2807 100644 --- a/src/include/gnunet_client_manager_lib.h +++ b/src/include/gnunet_client_manager_lib.h | |||
@@ -119,10 +119,14 @@ GNUNET_CLIENT_MANAGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
119 | * | 119 | * |
120 | * @param mgr Client manager connection. | 120 | * @param mgr Client manager connection. |
121 | * @param transmit_queue Transmit pending messages in queue before disconnecting. | 121 | * @param transmit_queue Transmit pending messages in queue before disconnecting. |
122 | * @param disconnect_cb Function called after disconnected from the service. | ||
123 | * @param disconnect_cls Closure for @a disconnect_cb. | ||
122 | */ | 124 | */ |
123 | void | 125 | void |
124 | GNUNET_CLIENT_MANAGER_disconnect (struct GNUNET_CLIENT_MANAGER_Connection *mgr, | 126 | GNUNET_CLIENT_MANAGER_disconnect (struct GNUNET_CLIENT_MANAGER_Connection *mgr, |
125 | int transmit_queue); | 127 | int transmit_queue, |
128 | GNUNET_ContinuationCallback disconnect_cb, | ||
129 | void *disconnect_cls); | ||
126 | 130 | ||
127 | 131 | ||
128 | /** | 132 | /** |
diff --git a/src/include/gnunet_common.h b/src/include/gnunet_common.h index d8444e100..2b501f91f 100644 --- a/src/include/gnunet_common.h +++ b/src/include/gnunet_common.h | |||
@@ -264,6 +264,15 @@ typedef int | |||
264 | const char *filename); | 264 | const char *filename); |
265 | 265 | ||
266 | 266 | ||
267 | /** | ||
268 | * Generic continuation callback. | ||
269 | * | ||
270 | * @param cls Closure. | ||
271 | */ | ||
272 | typedef void | ||
273 | (*GNUNET_ContinuationCallback) (void *cls); | ||
274 | |||
275 | |||
267 | /* ****************************** logging ***************************** */ | 276 | /* ****************************** logging ***************************** */ |
268 | 277 | ||
269 | /** | 278 | /** |
diff --git a/src/include/gnunet_multicast_service.h b/src/include/gnunet_multicast_service.h index 41227b925..5b8ff1894 100644 --- a/src/include/gnunet_multicast_service.h +++ b/src/include/gnunet_multicast_service.h | |||
@@ -666,7 +666,9 @@ GNUNET_MULTICAST_origin_to_all_cancel (struct GNUNET_MULTICAST_OriginTransmitHan | |||
666 | * @param origin Multicast group to stop. | 666 | * @param origin Multicast group to stop. |
667 | */ | 667 | */ |
668 | void | 668 | void |
669 | GNUNET_MULTICAST_origin_stop (struct GNUNET_MULTICAST_Origin *origin); | 669 | GNUNET_MULTICAST_origin_stop (struct GNUNET_MULTICAST_Origin *origin, |
670 | GNUNET_ContinuationCallback stop_cb, | ||
671 | void *stop_cls); | ||
670 | 672 | ||
671 | 673 | ||
672 | /** | 674 | /** |
@@ -795,7 +797,9 @@ GNUNET_MULTICAST_member_replay_cancel (struct GNUNET_MULTICAST_MemberReplayHandl | |||
795 | * @param member Membership handle. | 797 | * @param member Membership handle. |
796 | */ | 798 | */ |
797 | void | 799 | void |
798 | GNUNET_MULTICAST_member_part (struct GNUNET_MULTICAST_Member *member); | 800 | GNUNET_MULTICAST_member_part (struct GNUNET_MULTICAST_Member *member, |
801 | GNUNET_ContinuationCallback part_cb, | ||
802 | void *part_cls); | ||
799 | 803 | ||
800 | 804 | ||
801 | /** | 805 | /** |
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index 3451cdbf4..cff78eea6 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h | |||
@@ -2158,32 +2158,34 @@ extern "C" | |||
2158 | /** C->S: request to add channel slave to the membership database */ | 2158 | /** C->S: request to add channel slave to the membership database */ |
2159 | #define GNUNET_MESSAGE_TYPE_PSYC_CHANNEL_SLAVE_RM 690 | 2159 | #define GNUNET_MESSAGE_TYPE_PSYC_CHANNEL_SLAVE_RM 690 |
2160 | 2160 | ||
2161 | 2161 | /** S<--C: PSYC message which contains one or more message parts. */ | |
2162 | /** M<->S<->C: PSYC message which contains one or more message parts. */ | ||
2163 | #define GNUNET_MESSAGE_TYPE_PSYC_MESSAGE 691 | 2162 | #define GNUNET_MESSAGE_TYPE_PSYC_MESSAGE 691 |
2164 | 2163 | ||
2164 | /** M<->S<->C: PSYC message which contains a header and one or more message parts. */ | ||
2165 | #define GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_HEADER 692 // FIXME: start using this where appropriate | ||
2166 | |||
2165 | /** Message part: method */ | 2167 | /** Message part: method */ |
2166 | #define GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_METHOD 692 | 2168 | #define GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_METHOD 693 |
2167 | 2169 | ||
2168 | /** Message part: modifier */ | 2170 | /** Message part: modifier */ |
2169 | #define GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MODIFIER 693 | 2171 | #define GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MODIFIER 694 |
2170 | 2172 | ||
2171 | /** Message part: modifier continuation */ | 2173 | /** Message part: modifier continuation */ |
2172 | #define GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MOD_CONT 694 | 2174 | #define GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MOD_CONT 695 |
2173 | 2175 | ||
2174 | /** Message part: data */ | 2176 | /** Message part: data */ |
2175 | #define GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_DATA 695 | 2177 | #define GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_DATA 696 |
2176 | 2178 | ||
2177 | /** Message part: end of message */ | 2179 | /** Message part: end of message */ |
2178 | #define GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_END 696 | 2180 | #define GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_END 697 |
2179 | 2181 | ||
2180 | /** Message part: message cancelled */ | 2182 | /** Message part: message cancelled */ |
2181 | #define GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_CANCEL 697 | 2183 | #define GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_CANCEL 698 |
2182 | 2184 | ||
2183 | /** S->C: message acknowledgement */ | 2185 | /** S->C: message acknowledgement */ |
2184 | #define GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_ACK 698 | 2186 | #define GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_ACK 699 |
2185 | 2187 | ||
2186 | /* 699-700 */ | 2188 | /* 700 */ |
2187 | 2189 | ||
2188 | /** C->S: client requests channel history from PSYCstore. */ | 2190 | /** C->S: client requests channel history from PSYCstore. */ |
2189 | #define GNUNET_MESSAGE_TYPE_PSYC_STORY_REQUEST 701 | 2191 | #define GNUNET_MESSAGE_TYPE_PSYC_STORY_REQUEST 701 |
diff --git a/src/include/gnunet_psyc_service.h b/src/include/gnunet_psyc_service.h index 2ea282fa3..7097c46a8 100644 --- a/src/include/gnunet_psyc_service.h +++ b/src/include/gnunet_psyc_service.h | |||
@@ -190,6 +190,24 @@ enum GNUNET_PSYC_StateDeltaValues | |||
190 | GNUNET_NETWORK_STRUCT_BEGIN | 190 | GNUNET_NETWORK_STRUCT_BEGIN |
191 | 191 | ||
192 | /** | 192 | /** |
193 | * A PSYC message. | ||
194 | * | ||
195 | * Used for single-fragment messages e.g. in a join request or response. | ||
196 | */ | ||
197 | struct GNUNET_PSYC_Message | ||
198 | { | ||
199 | /** | ||
200 | * Message header with size and type information. | ||
201 | */ | ||
202 | struct GNUNET_MessageHeader header; | ||
203 | |||
204 | /* Followed by concatenated PSYC message parts: | ||
205 | * messages with GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_* types | ||
206 | */ | ||
207 | }; | ||
208 | |||
209 | |||
210 | /** | ||
193 | * Header of a PSYC message. | 211 | * Header of a PSYC message. |
194 | * | 212 | * |
195 | * Only present when receiving a message. | 213 | * Only present when receiving a message. |
@@ -215,6 +233,12 @@ struct GNUNET_PSYC_MessageHeader | |||
215 | uint64_t message_id GNUNET_PACKED; | 233 | uint64_t message_id GNUNET_PACKED; |
216 | 234 | ||
217 | /** | 235 | /** |
236 | * Byte offset of this @e fragment of the @e message. | ||
237 | * FIXME: use data_offset instead | ||
238 | */ | ||
239 | uint64_t fragment_offset GNUNET_PACKED; | ||
240 | |||
241 | /** | ||
218 | * Sending slave's public key. | 242 | * Sending slave's public key. |
219 | * Not set if the message is from the master. | 243 | * Not set if the message is from the master. |
220 | */ | 244 | */ |
@@ -299,6 +323,9 @@ struct GNUNET_PSYC_CountersResultMessage | |||
299 | }; | 323 | }; |
300 | 324 | ||
301 | 325 | ||
326 | /** | ||
327 | * Join request sent to a PSYC master. | ||
328 | */ | ||
302 | struct GNUNET_PSYC_JoinRequestMessage | 329 | struct GNUNET_PSYC_JoinRequestMessage |
303 | { | 330 | { |
304 | /** | 331 | /** |
@@ -314,6 +341,9 @@ struct GNUNET_PSYC_JoinRequestMessage | |||
314 | }; | 341 | }; |
315 | 342 | ||
316 | 343 | ||
344 | /** | ||
345 | * Join decision sent in reply to a join request. | ||
346 | */ | ||
317 | struct GNUNET_PSYC_JoinDecisionMessage | 347 | struct GNUNET_PSYC_JoinDecisionMessage |
318 | { | 348 | { |
319 | /** | 349 | /** |
@@ -379,23 +409,42 @@ struct GNUNET_PSYC_JoinHandle; | |||
379 | 409 | ||
380 | 410 | ||
381 | /** | 411 | /** |
382 | * Method called from PSYC upon receiving part of a message. | 412 | * Method called from PSYC upon receiving a message. |
383 | * | 413 | * |
384 | * @param cls Closure. | 414 | * @param cls Closure. |
385 | * @param message_id Sequence number of the message. | 415 | * @param message_id Sequence number of the message. |
386 | * @param flags OR'ed GNUNET_PSYC_MessageFlags | 416 | * @param flags OR'ed GNUNET_PSYC_MessageFlags |
387 | * @param msg Message part, one of the following types: | 417 | * @param msg Message part, one of the following types: |
388 | * - GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_HEADER | ||
389 | * - GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_METHOD | ||
390 | * - GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MODIFIER | ||
391 | * - GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MOD_CONT | ||
392 | * - GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_DATA | ||
393 | */ | 418 | */ |
394 | typedef void | 419 | typedef void |
395 | (*GNUNET_PSYC_MessageCallback) (void *cls, | 420 | (*GNUNET_PSYC_MessageCallback) (void *cls, |
396 | uint64_t message_id, | 421 | uint64_t message_id, |
397 | uint32_t flags, | 422 | uint32_t flags, |
398 | const struct GNUNET_MessageHeader *msg); | 423 | const struct GNUNET_PSYC_MessageHeader *msg); |
424 | |||
425 | |||
426 | /** | ||
427 | * Method called from PSYC upon receiving part of a message. | ||
428 | * | ||
429 | * @param cls Closure. | ||
430 | * @param message_id Sequence number of the message. | ||
431 | * @param data_offset Byte offset of data, only set if @a msg has a type | ||
432 | * #GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_DATA | ||
433 | * @param flags OR'ed GNUNET_PSYC_MessageFlags | ||
434 | * @param msg Message part, one of the following types: | ||
435 | * - #GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_HEADER | ||
436 | * - #GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_METHOD | ||
437 | * - #GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MODIFIER | ||
438 | * - #GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MOD_CONT | ||
439 | * - #GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_DATA | ||
440 | * or NULL if an error occurred while receiving a message. | ||
441 | */ | ||
442 | typedef void | ||
443 | (*GNUNET_PSYC_MessagePartCallback) (void *cls, | ||
444 | uint64_t message_id, | ||
445 | uint64_t data_offset, | ||
446 | uint32_t flags, | ||
447 | const struct GNUNET_MessageHeader *msg); | ||
399 | 448 | ||
400 | 449 | ||
401 | /** | 450 | /** |
@@ -408,10 +457,9 @@ typedef void | |||
408 | */ | 457 | */ |
409 | typedef void | 458 | typedef void |
410 | (*GNUNET_PSYC_JoinRequestCallback) (void *cls, | 459 | (*GNUNET_PSYC_JoinRequestCallback) (void *cls, |
411 | const struct | 460 | const struct GNUNET_PSYC_JoinRequestMessage *req, |
412 | GNUNET_CRYPTO_EcdsaPublicKey *slave_key, | 461 | const struct GNUNET_CRYPTO_EcdsaPublicKey *slave_key, |
413 | const struct | 462 | const struct GNUNET_PSYC_Message *join_msg, |
414 | GNUNET_PSYC_MessageHeader *join_msg, | ||
415 | struct GNUNET_PSYC_JoinHandle *jh); | 463 | struct GNUNET_PSYC_JoinHandle *jh); |
416 | 464 | ||
417 | 465 | ||
@@ -445,7 +493,7 @@ GNUNET_PSYC_join_decision (struct GNUNET_PSYC_JoinHandle *jh, | |||
445 | int is_admitted, | 493 | int is_admitted, |
446 | uint32_t relay_count, | 494 | uint32_t relay_count, |
447 | const struct GNUNET_PeerIdentity *relays, | 495 | const struct GNUNET_PeerIdentity *relays, |
448 | const struct GNUNET_PSYC_MessageHeader *join_resp); | 496 | const struct GNUNET_PSYC_Message *join_resp); |
449 | 497 | ||
450 | 498 | ||
451 | /** | 499 | /** |
@@ -501,6 +549,7 @@ GNUNET_PSYC_master_start (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
501 | GNUNET_PSYC_MasterStartCallback master_start_cb, | 549 | GNUNET_PSYC_MasterStartCallback master_start_cb, |
502 | GNUNET_PSYC_JoinRequestCallback join_request_cb, | 550 | GNUNET_PSYC_JoinRequestCallback join_request_cb, |
503 | GNUNET_PSYC_MessageCallback message_cb, | 551 | GNUNET_PSYC_MessageCallback message_cb, |
552 | GNUNET_PSYC_MessagePartCallback message_part_cb, | ||
504 | void *cls); | 553 | void *cls); |
505 | 554 | ||
506 | 555 | ||
@@ -645,10 +694,21 @@ GNUNET_PSYC_master_transmit_cancel (struct GNUNET_PSYC_MasterTransmitHandle *th) | |||
645 | /** | 694 | /** |
646 | * Stop a PSYC master channel. | 695 | * Stop a PSYC master channel. |
647 | * | 696 | * |
648 | * @param master PSYC channel master to stop. | 697 | * @param master |
698 | * PSYC channel master to stop. | ||
699 | * @param keep_active | ||
700 | * Keep place active after last application disconnected. | ||
701 | * @param stop_cb | ||
702 | * Function called after the master stopped | ||
703 | * and disconnected from the psyc service. | ||
704 | * @param stop_cls | ||
705 | * Closure for @a part_cb. | ||
649 | */ | 706 | */ |
650 | void | 707 | void |
651 | GNUNET_PSYC_master_stop (struct GNUNET_PSYC_Master *master); | 708 | GNUNET_PSYC_master_stop (struct GNUNET_PSYC_Master *master, |
709 | int keep_active, | ||
710 | GNUNET_ContinuationCallback stop_cb, | ||
711 | void *stop_cls); | ||
652 | 712 | ||
653 | 713 | ||
654 | /** | 714 | /** |
@@ -679,9 +739,9 @@ typedef void | |||
679 | */ | 739 | */ |
680 | typedef void | 740 | typedef void |
681 | (*GNUNET_PSYC_JoinDecisionCallback) (void *cls, | 741 | (*GNUNET_PSYC_JoinDecisionCallback) (void *cls, |
742 | const struct GNUNET_PSYC_JoinDecisionMessage *dcsn, | ||
682 | int is_admitted, | 743 | int is_admitted, |
683 | const struct | 744 | const struct GNUNET_PSYC_Message *join_msg); |
684 | GNUNET_PSYC_MessageHeader *join_msg); | ||
685 | 745 | ||
686 | 746 | ||
687 | /** | 747 | /** |
@@ -726,10 +786,11 @@ GNUNET_PSYC_slave_join (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
726 | uint32_t relay_count, | 786 | uint32_t relay_count, |
727 | const struct GNUNET_PeerIdentity *relays, | 787 | const struct GNUNET_PeerIdentity *relays, |
728 | GNUNET_PSYC_MessageCallback message_cb, | 788 | GNUNET_PSYC_MessageCallback message_cb, |
789 | GNUNET_PSYC_MessagePartCallback message_part_cb, | ||
729 | GNUNET_PSYC_SlaveConnectCallback slave_connect_cb, | 790 | GNUNET_PSYC_SlaveConnectCallback slave_connect_cb, |
730 | GNUNET_PSYC_JoinDecisionCallback join_decision_cb, | 791 | GNUNET_PSYC_JoinDecisionCallback join_decision_cb, |
731 | void *cls, | 792 | void *cls, |
732 | const struct GNUNET_MessageHeader *join_msg); | 793 | const struct GNUNET_PSYC_Message *join_msg); |
733 | 794 | ||
734 | 795 | ||
735 | /** | 796 | /** |
@@ -738,10 +799,21 @@ GNUNET_PSYC_slave_join (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
738 | * Will terminate the connection to the PSYC service. Polite clients should | 799 | * Will terminate the connection to the PSYC service. Polite clients should |
739 | * first explicitly send a part request (via GNUNET_PSYC_slave_transmit()). | 800 | * first explicitly send a part request (via GNUNET_PSYC_slave_transmit()). |
740 | * | 801 | * |
741 | * @param slave Slave handle. | 802 | * @param slave |
803 | * Slave handle. | ||
804 | * @param keep_active | ||
805 | * Keep place active after last application disconnected. | ||
806 | * @param part_cb | ||
807 | * Function called after the slave parted the channel | ||
808 | * and disconnected from the psyc service. | ||
809 | * @param part_cls | ||
810 | * Closure for @a part_cb. | ||
742 | */ | 811 | */ |
743 | void | 812 | void |
744 | GNUNET_PSYC_slave_part (struct GNUNET_PSYC_Slave *slave); | 813 | GNUNET_PSYC_slave_part (struct GNUNET_PSYC_Slave *slave, |
814 | int keep_active, | ||
815 | GNUNET_ContinuationCallback part_cb, | ||
816 | void *part_cls); | ||
745 | 817 | ||
746 | 818 | ||
747 | /** | 819 | /** |
@@ -937,6 +1009,7 @@ GNUNET_PSYC_channel_story_tell (struct GNUNET_PSYC_Channel *channel, | |||
937 | uint64_t start_message_id, | 1009 | uint64_t start_message_id, |
938 | uint64_t end_message_id, | 1010 | uint64_t end_message_id, |
939 | GNUNET_PSYC_MessageCallback message_cb, | 1011 | GNUNET_PSYC_MessageCallback message_cb, |
1012 | GNUNET_PSYC_MessagePartCallback message_part_cb, | ||
940 | GNUNET_PSYC_FinishCallback finish_cb, | 1013 | GNUNET_PSYC_FinishCallback finish_cb, |
941 | void *cls); | 1014 | void *cls); |
942 | 1015 | ||
diff --git a/src/include/gnunet_psyc_util_lib.h b/src/include/gnunet_psyc_util_lib.h index f356b245b..b71f52910 100644 --- a/src/include/gnunet_psyc_util_lib.h +++ b/src/include/gnunet_psyc_util_lib.h | |||
@@ -55,12 +55,36 @@ extern "C" | |||
55 | * @return Message header with size information, | 55 | * @return Message header with size information, |
56 | * followed by the message parts. | 56 | * followed by the message parts. |
57 | */ | 57 | */ |
58 | struct GNUNET_MessageHeader * | 58 | struct GNUNET_PSYC_Message * |
59 | GNUNET_PSYC_message_create (const char *method_name, | 59 | GNUNET_PSYC_message_create (const char *method_name, |
60 | const struct GNUNET_ENV_Environment *env, | 60 | const struct GNUNET_ENV_Environment *env, |
61 | const void *data, | 61 | const void *data, |
62 | size_t data_size); | 62 | size_t data_size); |
63 | 63 | ||
64 | /** | ||
65 | * Parse PSYC message. | ||
66 | * | ||
67 | * @param msg | ||
68 | * The PSYC message to parse. | ||
69 | * @param env | ||
70 | * The environment for the message with a list of modifiers. | ||
71 | * @param[out] method_name | ||
72 | * Pointer to the method name inside @a pmsg. | ||
73 | * @param[out] data | ||
74 | * Pointer to data inside @a pmsg. | ||
75 | * @param[out] data_size | ||
76 | * Size of @data is written here. | ||
77 | * | ||
78 | * @return #GNUNET_OK on success, | ||
79 | * #GNUNET_SYSERR on parse error. | ||
80 | */ | ||
81 | int | ||
82 | GNUNET_PSYC_message_parse (const struct GNUNET_PSYC_Message *msg, | ||
83 | const char **method_name, | ||
84 | struct GNUNET_ENV_Environment *env, | ||
85 | const void **data, | ||
86 | uint16_t *data_size); | ||
87 | |||
64 | 88 | ||
65 | void | 89 | void |
66 | GNUNET_PSYC_log_message (enum GNUNET_ErrorType kind, | 90 | GNUNET_PSYC_log_message (enum GNUNET_ErrorType kind, |
@@ -150,7 +174,7 @@ struct GNUNET_PSYC_ReceiveHandle; | |||
150 | */ | 174 | */ |
151 | struct GNUNET_PSYC_ReceiveHandle * | 175 | struct GNUNET_PSYC_ReceiveHandle * |
152 | GNUNET_PSYC_receive_create (GNUNET_PSYC_MessageCallback message_cb, | 176 | GNUNET_PSYC_receive_create (GNUNET_PSYC_MessageCallback message_cb, |
153 | GNUNET_PSYC_MessageCallback hist_message_cb, | 177 | GNUNET_PSYC_MessagePartCallback message_part_cb, |
154 | void *cb_cls); | 178 | void *cb_cls); |
155 | 179 | ||
156 | 180 | ||
diff --git a/src/include/gnunet_social_service.h b/src/include/gnunet_social_service.h index f8b24c161..ca1578820 100644 --- a/src/include/gnunet_social_service.h +++ b/src/include/gnunet_social_service.h | |||
@@ -81,6 +81,8 @@ struct GNUNET_SOCIAL_Slicer; | |||
81 | * | 81 | * |
82 | * @param cls | 82 | * @param cls |
83 | * Closure. | 83 | * Closure. |
84 | * @param msg | ||
85 | * Message part, as it arrived from the network. | ||
84 | * @param message_id | 86 | * @param message_id |
85 | * Message counter, monotonically increasing from 1. | 87 | * Message counter, monotonically increasing from 1. |
86 | * @param nym | 88 | * @param nym |
@@ -92,12 +94,53 @@ struct GNUNET_SOCIAL_Slicer; | |||
92 | * Original method name from PSYC. | 94 | * Original method name from PSYC. |
93 | * May be more specific than the registered method name due to | 95 | * May be more specific than the registered method name due to |
94 | * try-and-slice matching. | 96 | * try-and-slice matching. |
95 | * @param env | 97 | */ |
96 | * Environment with operations and variables for the message. | 98 | typedef void |
97 | * Only set for the first call of this function for each @a message_id, | 99 | (*GNUNET_SOCIAL_MethodCallback) (void *cls, |
98 | * NULL when notifying about further data fragments. | 100 | const struct GNUNET_PSYC_MessageMethod *msg, |
99 | * It has to be freed using GNUNET_ENV_environment_destroy() | 101 | uint64_t message_id, |
100 | * when it is not needed anymore. | 102 | uint32_t flags, |
103 | const struct GNUNET_SOCIAL_Nym *nym, | ||
104 | const char *method_name); | ||
105 | |||
106 | |||
107 | /** | ||
108 | * Function called upon receiving a data fragment of a message. | ||
109 | * | ||
110 | * @param cls | ||
111 | * Closure. | ||
112 | * @param message_id | ||
113 | * Message ID this data fragment belongs to. | ||
114 | * @param msg | ||
115 | * Message part, as it arrived from the network. | ||
116 | * @param oper | ||
117 | * Operation to perform. | ||
118 | * @param name | ||
119 | * Name of the modifier. | ||
120 | * @param value | ||
121 | * Value of the modifier. | ||
122 | * @param value_size | ||
123 | * Size of @value. | ||
124 | */ | ||
125 | typedef void | ||
126 | (*GNUNET_SOCIAL_ModifierCallback) (void *cls, | ||
127 | const struct GNUNET_PSYC_MessageModifier *msg, | ||
128 | uint64_t message_id, | ||
129 | enum GNUNET_ENV_Operator oper, | ||
130 | const char *name, | ||
131 | const void *value, | ||
132 | uint16_t value_size); | ||
133 | |||
134 | |||
135 | /** | ||
136 | * Function called upon receiving a data fragment of a message. | ||
137 | * | ||
138 | * @param cls | ||
139 | * Closure. | ||
140 | * @param message_id | ||
141 | * Message ID this data fragment belongs to. | ||
142 | * @param msg | ||
143 | * Message part, as it arrived from the network. | ||
101 | * @param data_offset | 144 | * @param data_offset |
102 | * Byte offset of @a data in the overall data of the method. | 145 | * Byte offset of @a data in the overall data of the method. |
103 | * @param data_size | 146 | * @param data_size |
@@ -106,21 +149,37 @@ struct GNUNET_SOCIAL_Slicer; | |||
106 | * Data stream given to the method. | 149 | * Data stream given to the method. |
107 | * @param end | 150 | * @param end |
108 | * End of message? | 151 | * End of message? |
109 | * #GNUNET_NO if there are further fragments, | 152 | * #GNUNET_NO if there are further fragments, |
110 | * #GNUNET_YES if this is the last fragment, | 153 | * #GNUNET_YES if this is the last fragment, |
111 | * #GNUNET_SYSERR indicates the message was cancelled by the sender. | 154 | * #GNUNET_SYSERR indicates the message was cancelled by the sender. |
112 | */ | 155 | */ |
113 | typedef void | 156 | typedef void |
114 | (*GNUNET_SOCIAL_MethodCallback) (void *cls, | 157 | (*GNUNET_SOCIAL_DataCallback) (void *cls, |
115 | uint64_t message_id, | 158 | const struct GNUNET_MessageHeader *msg, |
116 | uint32_t flags, | 159 | uint64_t message_id, |
117 | const struct GNUNET_SOCIAL_Nym *nym, | 160 | uint64_t data_offset, |
118 | const char *method_name, | 161 | const void *data, |
119 | struct GNUNET_ENV_Environment *env, | 162 | uint16_t data_size); |
120 | uint64_t data_offset, | 163 | |
121 | size_t data_size, | 164 | |
122 | const void *data, | 165 | /** |
123 | int end); | 166 | * End of message. |
167 | * | ||
168 | * @param cls | ||
169 | * Closure. | ||
170 | * @param msg | ||
171 | * Message part, as it arrived from the network. | ||
172 | * @param message_id | ||
173 | * Message ID this data fragment belongs to. | ||
174 | * @param cancelled. | ||
175 | * #GNUNET_YES if the message was cancelled, | ||
176 | * #GNUNET_NO if the message is complete. | ||
177 | */ | ||
178 | typedef void | ||
179 | (*GNUNET_SOCIAL_EndOfMessageCallback) (void *cls, | ||
180 | const struct GNUNET_MessageHeader *msg, | ||
181 | uint64_t message_id, | ||
182 | uint8_t cancelled); | ||
124 | 183 | ||
125 | 184 | ||
126 | /** | 185 | /** |
@@ -148,20 +207,27 @@ void | |||
148 | GNUNET_SOCIAL_slicer_add (struct GNUNET_SOCIAL_Slicer *slicer, | 207 | GNUNET_SOCIAL_slicer_add (struct GNUNET_SOCIAL_Slicer *slicer, |
149 | const char *method_name, | 208 | const char *method_name, |
150 | GNUNET_SOCIAL_MethodCallback method_cb, | 209 | GNUNET_SOCIAL_MethodCallback method_cb, |
210 | GNUNET_SOCIAL_ModifierCallback modifier_cb, | ||
211 | GNUNET_SOCIAL_DataCallback data_cb, | ||
212 | GNUNET_SOCIAL_EndOfMessageCallback eom_cb, | ||
151 | void *cls); | 213 | void *cls); |
152 | 214 | ||
153 | 215 | ||
154 | /** | 216 | /** |
155 | * Remove a registered method from the try-and-slice instance. | 217 | * Remove a registered method handler from the try-and-slice instance. |
156 | * | 218 | * |
157 | * @param slicer The try-and-slice instance. | 219 | * @param slicer The try-and-slice instance. |
158 | * @param method_name Name of the method to remove. | 220 | * @param method_name Name of the method to remove. |
159 | * @param method Method handler. | 221 | * @param method Method handler. |
160 | */ | 222 | */ |
161 | void | 223 | int |
162 | GNUNET_SOCIAL_slicer_remove (struct GNUNET_SOCIAL_Slicer *slicer, | 224 | GNUNET_SOCIAL_slicer_remove (struct GNUNET_SOCIAL_Slicer *slicer, |
163 | const char *method_name, | 225 | const char *method_name, |
164 | GNUNET_SOCIAL_MethodCallback method_cb); | 226 | GNUNET_SOCIAL_MethodCallback method_cb, |
227 | GNUNET_SOCIAL_ModifierCallback modifier_cb, | ||
228 | GNUNET_SOCIAL_DataCallback data_cb, | ||
229 | GNUNET_SOCIAL_EndOfMessageCallback eom_cb); | ||
230 | |||
165 | 231 | ||
166 | /** | 232 | /** |
167 | * Destroy a given try-and-slice instance. | 233 | * Destroy a given try-and-slice instance. |
@@ -257,7 +323,7 @@ typedef void | |||
257 | */ | 323 | */ |
258 | struct GNUNET_SOCIAL_Host * | 324 | struct GNUNET_SOCIAL_Host * |
259 | GNUNET_SOCIAL_host_enter (const struct GNUNET_CONFIGURATION_Handle *cfg, | 325 | GNUNET_SOCIAL_host_enter (const struct GNUNET_CONFIGURATION_Handle *cfg, |
260 | struct GNUNET_IDENTITY_Ego *ego, | 326 | const struct GNUNET_IDENTITY_Ego *ego, |
261 | const struct GNUNET_CRYPTO_EddsaPrivateKey *place_key, | 327 | const struct GNUNET_CRYPTO_EddsaPrivateKey *place_key, |
262 | enum GNUNET_PSYC_Policy policy, | 328 | enum GNUNET_PSYC_Policy policy, |
263 | struct GNUNET_SOCIAL_Slicer *slicer, | 329 | struct GNUNET_SOCIAL_Slicer *slicer, |
@@ -268,17 +334,32 @@ GNUNET_SOCIAL_host_enter (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
268 | 334 | ||
269 | 335 | ||
270 | /** | 336 | /** |
271 | * Admit @a nym to the place. | 337 | * Decision whether to admit @a nym into the place or refuse entry. |
272 | * | ||
273 | * The @a nym reference will remain valid until either the @a host or @a nym | ||
274 | * leaves the place. | ||
275 | * | 338 | * |
276 | * @param host Host of the place. | 339 | * @param hst |
277 | * @param nym Handle for the entity that wants to enter. | 340 | * Host of the place. |
341 | * @param nym | ||
342 | * Handle for the entity that wanted to enter. | ||
343 | * @param is_admitted | ||
344 | * #GNUNET_YES if @a nym is admitted, | ||
345 | * #GNUNET_NO if @a nym is refused entry, | ||
346 | * #GNUNET_SYSERR if we cannot answer the request. | ||
347 | * @param method_name | ||
348 | * Method name for the rejection message. | ||
349 | * @param env | ||
350 | * Environment containing variables for the message, or NULL. | ||
351 | * @param data | ||
352 | * Data for the rejection message to send back. | ||
353 | * @param data_size | ||
354 | * Number of bytes in @a data for method. | ||
355 | * @return #GNUNET_OK on success, | ||
356 | * #GNUNET_SYSERR if the message is too large. | ||
278 | */ | 357 | */ |
279 | void | 358 | int |
280 | GNUNET_SOCIAL_host_admit (struct GNUNET_SOCIAL_Host *host, | 359 | GNUNET_SOCIAL_host_entry_decision (struct GNUNET_SOCIAL_Host *hst, |
281 | struct GNUNET_SOCIAL_Nym *nym); | 360 | struct GNUNET_SOCIAL_Nym *nym, |
361 | int is_admitted, | ||
362 | const struct GNUNET_PSYC_Message *entry_resp); | ||
282 | 363 | ||
283 | 364 | ||
284 | /** | 365 | /** |
@@ -297,35 +378,17 @@ GNUNET_SOCIAL_host_eject (struct GNUNET_SOCIAL_Host *host, | |||
297 | 378 | ||
298 | 379 | ||
299 | /** | 380 | /** |
300 | * Refuse @a nym entry into the place. | ||
301 | * | ||
302 | * @param host Host of the place. | ||
303 | * @param nym Handle for the entity that wanted to enter. | ||
304 | * @param method_name Method name for the rejection message. | ||
305 | * @param env Environment containing variables for the message, or NULL. | ||
306 | * @param data Data for the rejection message to send back. | ||
307 | * @param data_size Number of bytes in @a data for method. | ||
308 | */ | ||
309 | void | ||
310 | GNUNET_SOCIAL_host_refuse_entry (struct GNUNET_SOCIAL_Host *host, | ||
311 | struct GNUNET_SOCIAL_Nym *nym, | ||
312 | const char *method_name, | ||
313 | const struct GNUNET_ENV_Environment *env, | ||
314 | const void *data, | ||
315 | size_t data_size); | ||
316 | |||
317 | |||
318 | /** | ||
319 | * Get the public key of a @a nym. | 381 | * Get the public key of a @a nym. |
320 | * | 382 | * |
321 | * Suitable, for example, to be used with GNUNET_NAMESTORE_zone_to_name(). | 383 | * Suitable, for example, to be used with GNUNET_NAMESTORE_zone_to_name(). |
322 | * | 384 | * |
323 | * @param nym Pseudonym to map to a cryptographic identifier. | 385 | * @param nym |
324 | * @param[out] nym_key Set to the public key of the nym. | 386 | * Pseudonym to map to a cryptographic identifier. |
387 | * | ||
388 | * @return Public key of nym; | ||
325 | */ | 389 | */ |
326 | void | 390 | struct GNUNET_CRYPTO_EcdsaPublicKey * |
327 | GNUNET_SOCIAL_nym_get_key (struct GNUNET_SOCIAL_Nym *nym, | 391 | GNUNET_SOCIAL_nym_get_key (struct GNUNET_SOCIAL_Nym *nym); |
328 | struct GNUNET_CRYPTO_EddsaPublicKey *nym_key); | ||
329 | 392 | ||
330 | 393 | ||
331 | /** | 394 | /** |
@@ -418,9 +481,20 @@ GNUNET_SOCIAL_host_announce (struct GNUNET_SOCIAL_Host *host, | |||
418 | 481 | ||
419 | 482 | ||
420 | /** | 483 | /** |
484 | * Resume transmitting announcement. | ||
485 | * | ||
486 | * @param a | ||
487 | * The announcement to resume. | ||
488 | */ | ||
489 | void | ||
490 | GNUNET_SOCIAL_host_announce_resume (struct GNUNET_SOCIAL_Announcement *a); | ||
491 | |||
492 | |||
493 | /** | ||
421 | * Cancel announcement. | 494 | * Cancel announcement. |
422 | * | 495 | * |
423 | * @param a The announcement to cancel. | 496 | * @param a |
497 | * The announcement to cancel. | ||
424 | */ | 498 | */ |
425 | void | 499 | void |
426 | GNUNET_SOCIAL_host_announce_cancel (struct GNUNET_SOCIAL_Announcement *a); | 500 | GNUNET_SOCIAL_host_announce_cancel (struct GNUNET_SOCIAL_Announcement *a); |
@@ -431,7 +505,8 @@ GNUNET_SOCIAL_host_announce_cancel (struct GNUNET_SOCIAL_Announcement *a); | |||
431 | * | 505 | * |
432 | * The returned handle can be used to access the place API. | 506 | * The returned handle can be used to access the place API. |
433 | * | 507 | * |
434 | * @param host Handle for the host. | 508 | * @param host |
509 | * Handle for the host. | ||
435 | * | 510 | * |
436 | * @return Handle for the hosted place, valid as long as @a host is valid. | 511 | * @return Handle for the hosted place, valid as long as @a host is valid. |
437 | */ | 512 | */ |
@@ -444,11 +519,21 @@ GNUNET_SOCIAL_host_get_place (struct GNUNET_SOCIAL_Host *host); | |||
444 | * | 519 | * |
445 | * Invalidates host handle. | 520 | * Invalidates host handle. |
446 | * | 521 | * |
447 | * @param host Host leaving the place. | 522 | * @param host |
448 | * @param keep_active Keep the place active after last host disconnected. | 523 | * Host leaving the place. |
524 | * @param keep_active | ||
525 | * Keep the place active after last host disconnected. | ||
526 | * @param leave_cb | ||
527 | * Function called after the host left the place | ||
528 | * and disconnected from the social service. | ||
529 | * @param leave_cls | ||
530 | * Closure for @a leave_cb. | ||
449 | */ | 531 | */ |
450 | void | 532 | void |
451 | GNUNET_SOCIAL_host_leave (struct GNUNET_SOCIAL_Host *host, int keep_active); | 533 | GNUNET_SOCIAL_host_leave (struct GNUNET_SOCIAL_Host *host, |
534 | int keep_active, | ||
535 | GNUNET_ContinuationCallback leave_cb, | ||
536 | void *leave_cls); | ||
452 | 537 | ||
453 | 538 | ||
454 | /** | 539 | /** |
@@ -493,13 +578,10 @@ typedef void | |||
493 | * @param data | 578 | * @param data |
494 | * Payload of the message. | 579 | * Payload of the message. |
495 | */ | 580 | */ |
496 | typedef int | 581 | typedef void |
497 | (*GNUNET_SOCIAL_EntryDecisionCallback) (void *cls, | 582 | (*GNUNET_SOCIAL_EntryDecisionCallback) (void *cls, |
498 | int is_admitted, | 583 | int is_admitted, |
499 | const char *method_name, | 584 | const struct GNUNET_PSYC_Message *entry_resp); |
500 | struct GNUNET_ENV_Environment *env, | ||
501 | size_t data_size, | ||
502 | const void *data); | ||
503 | 585 | ||
504 | 586 | ||
505 | /** | 587 | /** |
@@ -521,15 +603,12 @@ typedef int | |||
521 | */ | 603 | */ |
522 | struct GNUNET_SOCIAL_Guest * | 604 | struct GNUNET_SOCIAL_Guest * |
523 | GNUNET_SOCIAL_guest_enter (const struct GNUNET_CONFIGURATION_Handle *cfg, | 605 | GNUNET_SOCIAL_guest_enter (const struct GNUNET_CONFIGURATION_Handle *cfg, |
524 | struct GNUNET_IDENTITY_Ego *ego, | 606 | const struct GNUNET_IDENTITY_Ego *ego, |
525 | struct GNUNET_CRYPTO_EddsaPublicKey *place_key, | 607 | const struct GNUNET_CRYPTO_EddsaPublicKey *place_key, |
526 | struct GNUNET_PeerIdentity *origin, | 608 | const struct GNUNET_PeerIdentity *origin, |
527 | uint32_t relay_count, | 609 | uint32_t relay_count, |
528 | struct GNUNET_PeerIdentity *relays, | 610 | const struct GNUNET_PeerIdentity *relays, |
529 | const char *method_name, | 611 | const struct GNUNET_PSYC_Message *entry_msg, |
530 | const struct GNUNET_ENV_Environment *env, | ||
531 | const void *data, | ||
532 | size_t data_size, | ||
533 | struct GNUNET_SOCIAL_Slicer *slicer, | 612 | struct GNUNET_SOCIAL_Slicer *slicer, |
534 | GNUNET_SOCIAL_GuestEnterCallback local_enter_cb, | 613 | GNUNET_SOCIAL_GuestEnterCallback local_enter_cb, |
535 | GNUNET_SOCIAL_EntryDecisionCallback entry_decision_cb, | 614 | GNUNET_SOCIAL_EntryDecisionCallback entry_decision_cb, |
@@ -558,10 +637,7 @@ struct GNUNET_SOCIAL_Guest * | |||
558 | GNUNET_SOCIAL_guest_enter_by_name (const struct GNUNET_CONFIGURATION_Handle *cfg, | 637 | GNUNET_SOCIAL_guest_enter_by_name (const struct GNUNET_CONFIGURATION_Handle *cfg, |
559 | struct GNUNET_IDENTITY_Ego *ego, | 638 | struct GNUNET_IDENTITY_Ego *ego, |
560 | char *gns_name, | 639 | char *gns_name, |
561 | const char *method_name, | 640 | const struct GNUNET_PSYC_Message *join_msg, |
562 | const struct GNUNET_ENV_Environment *env, | ||
563 | const void *data, | ||
564 | size_t data_size, | ||
565 | struct GNUNET_SOCIAL_Slicer *slicer, | 641 | struct GNUNET_SOCIAL_Slicer *slicer, |
566 | GNUNET_SOCIAL_GuestEnterCallback local_enter_cb, | 642 | GNUNET_SOCIAL_GuestEnterCallback local_enter_cb, |
567 | GNUNET_SOCIAL_EntryDecisionCallback entry_decision_cb, | 643 | GNUNET_SOCIAL_EntryDecisionCallback entry_decision_cb, |
@@ -612,9 +688,20 @@ GNUNET_SOCIAL_guest_talk (struct GNUNET_SOCIAL_Guest *guest, | |||
612 | 688 | ||
613 | 689 | ||
614 | /** | 690 | /** |
691 | * Resume talking to the host of the place. | ||
692 | * | ||
693 | * @param tr | ||
694 | * Talk request to resume. | ||
695 | */ | ||
696 | void | ||
697 | GNUNET_SOCIAL_guest_talk_resume (struct GNUNET_SOCIAL_TalkRequest *tr); | ||
698 | |||
699 | |||
700 | /** | ||
615 | * Cancel talking to the host of the place. | 701 | * Cancel talking to the host of the place. |
616 | * | 702 | * |
617 | * @param tr Talk request to cancel. | 703 | * @param tr |
704 | * Talk request to cancel. | ||
618 | */ | 705 | */ |
619 | void | 706 | void |
620 | GNUNET_SOCIAL_guest_talk_cancel (struct GNUNET_SOCIAL_TalkRequest *tr); | 707 | GNUNET_SOCIAL_guest_talk_cancel (struct GNUNET_SOCIAL_TalkRequest *tr); |
@@ -625,11 +712,21 @@ GNUNET_SOCIAL_guest_talk_cancel (struct GNUNET_SOCIAL_TalkRequest *tr); | |||
625 | * | 712 | * |
626 | * Notifies the owner of the place about leaving, and destroys the place handle. | 713 | * Notifies the owner of the place about leaving, and destroys the place handle. |
627 | * | 714 | * |
628 | * @param place Place to leave permanently. | 715 | * @param place |
629 | * @param keep_active Keep place active after last application disconnected. | 716 | * Place to leave permanently. |
717 | * @param keep_active | ||
718 | * Keep place active after last application disconnected. | ||
719 | * @param leave_cb | ||
720 | * Function called after the guest left the place | ||
721 | * and disconnected from the social service. | ||
722 | * @param leave_cls | ||
723 | * Closure for @a leave_cb. | ||
630 | */ | 724 | */ |
631 | void | 725 | void |
632 | GNUNET_SOCIAL_guest_leave (struct GNUNET_SOCIAL_Guest *guest, int keep_active); | 726 | GNUNET_SOCIAL_guest_leave (struct GNUNET_SOCIAL_Guest *guest, |
727 | int keep_active, | ||
728 | GNUNET_ContinuationCallback leave_cb, | ||
729 | void *leave_cls); | ||
633 | 730 | ||
634 | 731 | ||
635 | /** | 732 | /** |
diff --git a/src/multicast/gnunet-service-multicast.c b/src/multicast/gnunet-service-multicast.c index 1bb27f96e..1b8e5c8b6 100644 --- a/src/multicast/gnunet-service-multicast.c +++ b/src/multicast/gnunet-service-multicast.c | |||
@@ -423,6 +423,7 @@ client_origin_start (void *cls, struct GNUNET_SERVER_Client *client, | |||
423 | { | 423 | { |
424 | orig = GNUNET_new (struct Origin); | 424 | orig = GNUNET_new (struct Origin); |
425 | orig->priv_key = msg->group_key; | 425 | orig->priv_key = msg->group_key; |
426 | orig->max_fragment_id = GNUNET_ntohll (msg->max_fragment_id); | ||
426 | grp = &orig->grp; | 427 | grp = &orig->grp; |
427 | grp->is_origin = GNUNET_YES; | 428 | grp->is_origin = GNUNET_YES; |
428 | grp->pub_key = pub_key; | 429 | grp->pub_key = pub_key; |
@@ -482,6 +483,7 @@ client_member_join (void *cls, struct GNUNET_SERVER_Client *client, | |||
482 | mem->priv_key = msg->member_key; | 483 | mem->priv_key = msg->member_key; |
483 | mem->pub_key = mem_pub_key; | 484 | mem->pub_key = mem_pub_key; |
484 | mem->pub_key_hash = mem_pub_key_hash; | 485 | mem->pub_key_hash = mem_pub_key_hash; |
486 | mem->max_fragment_id = 0; // FIXME | ||
485 | 487 | ||
486 | grp = &mem->grp; | 488 | grp = &mem->grp; |
487 | grp->is_origin = GNUNET_NO; | 489 | grp->is_origin = GNUNET_NO; |
@@ -663,7 +665,7 @@ client_multicast_message (void *cls, struct GNUNET_SERVER_Client *client, | |||
663 | struct GNUNET_MULTICAST_MessageHeader * | 665 | struct GNUNET_MULTICAST_MessageHeader * |
664 | msg = (struct GNUNET_MULTICAST_MessageHeader *) m; | 666 | msg = (struct GNUNET_MULTICAST_MessageHeader *) m; |
665 | 667 | ||
666 | msg->fragment_id = GNUNET_htonll (orig->max_fragment_id++); | 668 | msg->fragment_id = GNUNET_htonll (++orig->max_fragment_id); |
667 | msg->purpose.size = htonl (sizeof (*msg) + ntohs (m->size) | 669 | msg->purpose.size = htonl (sizeof (*msg) + ntohs (m->size) |
668 | - sizeof (msg->header) | 670 | - sizeof (msg->header) |
669 | - sizeof (msg->hop_counter) | 671 | - sizeof (msg->hop_counter) |
@@ -699,8 +701,7 @@ client_multicast_request (void *cls, struct GNUNET_SERVER_Client *client, | |||
699 | struct GNUNET_MULTICAST_RequestHeader * | 701 | struct GNUNET_MULTICAST_RequestHeader * |
700 | req = (struct GNUNET_MULTICAST_RequestHeader *) m; | 702 | req = (struct GNUNET_MULTICAST_RequestHeader *) m; |
701 | 703 | ||
702 | req->fragment_id = GNUNET_ntohll (mem->max_fragment_id++); | 704 | req->fragment_id = GNUNET_ntohll (++mem->max_fragment_id); |
703 | |||
704 | req->purpose.size = htonl (sizeof (*req) + ntohs (m->size) | 705 | req->purpose.size = htonl (sizeof (*req) + ntohs (m->size) |
705 | - sizeof (req->header) | 706 | - sizeof (req->header) |
706 | - sizeof (req->member_key) | 707 | - sizeof (req->member_key) |
diff --git a/src/multicast/multicast_api.c b/src/multicast/multicast_api.c index d2a0412bb..fb2630081 100644 --- a/src/multicast/multicast_api.c +++ b/src/multicast/multicast_api.c | |||
@@ -88,6 +88,16 @@ struct GNUNET_MULTICAST_Group | |||
88 | void *cb_cls; | 88 | void *cb_cls; |
89 | 89 | ||
90 | /** | 90 | /** |
91 | * Function called after disconnected from the service. | ||
92 | */ | ||
93 | GNUNET_ContinuationCallback disconnect_cb; | ||
94 | |||
95 | /** | ||
96 | * Closure for @a disconnect_cb. | ||
97 | */ | ||
98 | void *disconnect_cls; | ||
99 | |||
100 | /** | ||
91 | * Are we currently transmitting a message? | 101 | * Are we currently transmitting a message? |
92 | */ | 102 | */ |
93 | uint8_t in_transmit; | 103 | uint8_t in_transmit; |
@@ -96,6 +106,12 @@ struct GNUNET_MULTICAST_Group | |||
96 | * Is this the origin or a member? | 106 | * Is this the origin or a member? |
97 | */ | 107 | */ |
98 | uint8_t is_origin; | 108 | uint8_t is_origin; |
109 | |||
110 | /** | ||
111 | * Is this channel in the process of disconnecting from the service? | ||
112 | * #GNUNET_YES or #GNUNET_NO | ||
113 | */ | ||
114 | uint8_t is_disconnecting; | ||
99 | }; | 115 | }; |
100 | 116 | ||
101 | 117 | ||
@@ -320,8 +336,9 @@ member_recv_join_decision (void *cls, | |||
320 | mem->join_dcsn_cb (grp->cb_cls, is_admitted, &hdcsn->peer, | 336 | mem->join_dcsn_cb (grp->cb_cls, is_admitted, &hdcsn->peer, |
321 | relay_count, relays, join_resp); | 337 | relay_count, relays, join_resp); |
322 | 338 | ||
323 | if (GNUNET_YES != is_admitted) | 339 | // FIXME: |
324 | GNUNET_MULTICAST_member_part (mem); | 340 | //if (GNUNET_YES != is_admitted) |
341 | // GNUNET_MULTICAST_member_part (mem); | ||
325 | } | 342 | } |
326 | 343 | ||
327 | 344 | ||
@@ -371,6 +388,33 @@ static struct GNUNET_CLIENT_MANAGER_MessageHandler member_handlers[] = | |||
371 | }; | 388 | }; |
372 | 389 | ||
373 | 390 | ||
391 | static void | ||
392 | group_cleanup (struct GNUNET_MULTICAST_Group *grp) | ||
393 | { | ||
394 | GNUNET_free (grp->connect_msg); | ||
395 | if (NULL != grp->disconnect_cb) | ||
396 | grp->disconnect_cb (grp->disconnect_cls); | ||
397 | } | ||
398 | |||
399 | |||
400 | static void | ||
401 | origin_cleanup (void *cls) | ||
402 | { | ||
403 | struct GNUNET_MULTICAST_Origin *orig = cls; | ||
404 | group_cleanup (&orig->grp); | ||
405 | GNUNET_free (orig); | ||
406 | } | ||
407 | |||
408 | |||
409 | static void | ||
410 | member_cleanup (void *cls) | ||
411 | { | ||
412 | struct GNUNET_MULTICAST_Member *mem = cls; | ||
413 | group_cleanup (&mem->grp); | ||
414 | GNUNET_free (mem); | ||
415 | } | ||
416 | |||
417 | |||
374 | /** | 418 | /** |
375 | * Function to call with the decision made for a join request. | 419 | * Function to call with the decision made for a join request. |
376 | * | 420 | * |
@@ -565,10 +609,18 @@ GNUNET_MULTICAST_origin_start (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
565 | * @param origin Multicast group to stop. | 609 | * @param origin Multicast group to stop. |
566 | */ | 610 | */ |
567 | void | 611 | void |
568 | GNUNET_MULTICAST_origin_stop (struct GNUNET_MULTICAST_Origin *orig) | 612 | GNUNET_MULTICAST_origin_stop (struct GNUNET_MULTICAST_Origin *orig, |
613 | GNUNET_ContinuationCallback stop_cb, | ||
614 | void *stop_cls) | ||
569 | { | 615 | { |
570 | GNUNET_CLIENT_MANAGER_disconnect (orig->grp.client, GNUNET_YES); | 616 | struct GNUNET_MULTICAST_Group *grp = &orig->grp; |
571 | GNUNET_free (orig); | 617 | |
618 | grp->is_disconnecting = GNUNET_YES; | ||
619 | grp->disconnect_cb = stop_cb; | ||
620 | grp->disconnect_cls = stop_cls; | ||
621 | |||
622 | GNUNET_CLIENT_MANAGER_disconnect (orig->grp.client, GNUNET_YES, | ||
623 | &origin_cleanup, orig); | ||
572 | } | 624 | } |
573 | 625 | ||
574 | 626 | ||
@@ -774,10 +826,18 @@ GNUNET_MULTICAST_member_join (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
774 | * @param member Membership handle. | 826 | * @param member Membership handle. |
775 | */ | 827 | */ |
776 | void | 828 | void |
777 | GNUNET_MULTICAST_member_part (struct GNUNET_MULTICAST_Member *mem) | 829 | GNUNET_MULTICAST_member_part (struct GNUNET_MULTICAST_Member *mem, |
830 | GNUNET_ContinuationCallback part_cb, | ||
831 | void *part_cls) | ||
778 | { | 832 | { |
779 | GNUNET_CLIENT_MANAGER_disconnect (mem->grp.client, GNUNET_YES); | 833 | struct GNUNET_MULTICAST_Group *grp = &mem->grp; |
780 | GNUNET_free (mem); | 834 | |
835 | grp->is_disconnecting = GNUNET_YES; | ||
836 | grp->disconnect_cb = part_cb; | ||
837 | grp->disconnect_cls = part_cls; | ||
838 | |||
839 | GNUNET_CLIENT_MANAGER_disconnect (mem->grp.client, GNUNET_YES, | ||
840 | &member_cleanup, mem); | ||
781 | } | 841 | } |
782 | 842 | ||
783 | 843 | ||
diff --git a/src/psyc/gnunet-service-psyc.c b/src/psyc/gnunet-service-psyc.c index 866275a79..8fc080baf 100644 --- a/src/psyc/gnunet-service-psyc.c +++ b/src/psyc/gnunet-service-psyc.c | |||
@@ -168,7 +168,7 @@ struct FragmentQueue | |||
168 | * Is the message queued for delivery to the client? | 168 | * Is the message queued for delivery to the client? |
169 | * i.e. added to the recv_msgs queue | 169 | * i.e. added to the recv_msgs queue |
170 | */ | 170 | */ |
171 | uint8_t queued; | 171 | uint8_t is_queued; |
172 | }; | 172 | }; |
173 | 173 | ||
174 | 174 | ||
@@ -382,7 +382,7 @@ struct Slave | |||
382 | /** | 382 | /** |
383 | * Join request to be transmitted to the master on join. | 383 | * Join request to be transmitted to the master on join. |
384 | */ | 384 | */ |
385 | struct GNUNET_MessageHeader *join_req; | 385 | struct GNUNET_PSYC_Message *join_msg; |
386 | 386 | ||
387 | /** | 387 | /** |
388 | * Join decision received from multicast. | 388 | * Join decision received from multicast. |
@@ -435,7 +435,7 @@ cleanup_master (struct Master *mst) | |||
435 | struct Channel *chn = &mst->chn; | 435 | struct Channel *chn = &mst->chn; |
436 | 436 | ||
437 | if (NULL != mst->origin) | 437 | if (NULL != mst->origin) |
438 | GNUNET_MULTICAST_origin_stop (mst->origin); | 438 | GNUNET_MULTICAST_origin_stop (mst->origin, NULL, NULL); // FIXME |
439 | GNUNET_CONTAINER_multihashmap_destroy (mst->join_reqs); | 439 | GNUNET_CONTAINER_multihashmap_destroy (mst->join_reqs); |
440 | GNUNET_CONTAINER_multihashmap_remove (masters, &chn->pub_key_hash, chn); | 440 | GNUNET_CONTAINER_multihashmap_remove (masters, &chn->pub_key_hash, chn); |
441 | } | 441 | } |
@@ -462,12 +462,21 @@ cleanup_slave (struct Slave *slv) | |||
462 | } | 462 | } |
463 | GNUNET_CONTAINER_multihashmap_remove (slaves, &chn->pub_key_hash, slv); | 463 | GNUNET_CONTAINER_multihashmap_remove (slaves, &chn->pub_key_hash, slv); |
464 | 464 | ||
465 | if (NULL != slv->join_req) | 465 | if (NULL != slv->join_msg) |
466 | GNUNET_free (slv->join_req); | 466 | { |
467 | GNUNET_free (slv->join_msg); | ||
468 | slv->join_msg = NULL; | ||
469 | } | ||
467 | if (NULL != slv->relays) | 470 | if (NULL != slv->relays) |
471 | { | ||
468 | GNUNET_free (slv->relays); | 472 | GNUNET_free (slv->relays); |
473 | slv->relays = NULL; | ||
474 | } | ||
469 | if (NULL != slv->member) | 475 | if (NULL != slv->member) |
470 | GNUNET_MULTICAST_member_part (slv->member); | 476 | { |
477 | GNUNET_MULTICAST_member_part (slv->member, NULL, NULL); // FIXME | ||
478 | slv->member = NULL; | ||
479 | } | ||
471 | GNUNET_CONTAINER_multihashmap_remove (slaves, &chn->pub_key_hash, chn); | 480 | GNUNET_CONTAINER_multihashmap_remove (slaves, &chn->pub_key_hash, chn); |
472 | } | 481 | } |
473 | 482 | ||
@@ -482,7 +491,10 @@ cleanup_channel (struct Channel *chn) | |||
482 | GNUNET_CONTAINER_multihashmap_remove_all (recv_cache, &chn->pub_key_hash); | 491 | GNUNET_CONTAINER_multihashmap_remove_all (recv_cache, &chn->pub_key_hash); |
483 | 492 | ||
484 | if (NULL != chn->store_op) | 493 | if (NULL != chn->store_op) |
494 | { | ||
485 | GNUNET_PSYCSTORE_operation_cancel (chn->store_op); | 495 | GNUNET_PSYCSTORE_operation_cancel (chn->store_op); |
496 | chn->store_op = NULL; | ||
497 | } | ||
486 | 498 | ||
487 | (GNUNET_YES == chn->is_master) | 499 | (GNUNET_YES == chn->is_master) |
488 | ? cleanup_master ((struct Master *) chn) | 500 | ? cleanup_master ((struct Master *) chn) |
@@ -574,7 +586,7 @@ struct JoinMemTestClosure | |||
574 | struct GNUNET_CRYPTO_EcdsaPublicKey slave_key; | 586 | struct GNUNET_CRYPTO_EcdsaPublicKey slave_key; |
575 | struct Channel *chn; | 587 | struct Channel *chn; |
576 | struct GNUNET_MULTICAST_JoinHandle *jh; | 588 | struct GNUNET_MULTICAST_JoinHandle *jh; |
577 | struct MasterJoinRequest *master_join_req; | 589 | struct GNUNET_PSYC_JoinRequestMessage *join_msg; |
578 | }; | 590 | }; |
579 | 591 | ||
580 | 592 | ||
@@ -594,14 +606,14 @@ join_mem_test_cb (void *cls, int64_t result, const char *err_msg) | |||
594 | &slave_key_hash); | 606 | &slave_key_hash); |
595 | GNUNET_CONTAINER_multihashmap_put (mst->join_reqs, &slave_key_hash, jcls->jh, | 607 | GNUNET_CONTAINER_multihashmap_put (mst->join_reqs, &slave_key_hash, jcls->jh, |
596 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | 608 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); |
597 | client_send_msg (jcls->chn, &jcls->master_join_req->header); | 609 | client_send_msg (jcls->chn, &jcls->join_msg->header); |
598 | } | 610 | } |
599 | else | 611 | else |
600 | { | 612 | { |
601 | // FIXME: add relays | 613 | // FIXME: add relays |
602 | GNUNET_MULTICAST_join_decision (jcls->jh, result, 0, NULL, NULL); | 614 | GNUNET_MULTICAST_join_decision (jcls->jh, result, 0, NULL, NULL); |
603 | } | 615 | } |
604 | GNUNET_free (jcls->master_join_req); | 616 | GNUNET_free (jcls->join_msg); |
605 | GNUNET_free (jcls); | 617 | GNUNET_free (jcls); |
606 | } | 618 | } |
607 | 619 | ||
@@ -633,7 +645,8 @@ mcast_recv_join_request (void *cls, | |||
633 | } | 645 | } |
634 | } | 646 | } |
635 | 647 | ||
636 | struct MasterJoinRequest *req = GNUNET_malloc (sizeof (*req) + join_msg_size); | 648 | struct GNUNET_PSYC_JoinRequestMessage * |
649 | req = GNUNET_malloc (sizeof (*req) + join_msg_size); | ||
637 | req->header.size = htons (sizeof (*req) + join_msg_size); | 650 | req->header.size = htons (sizeof (*req) + join_msg_size); |
638 | req->header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_JOIN_REQUEST); | 651 | req->header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_JOIN_REQUEST); |
639 | req->slave_key = *slave_key; | 652 | req->slave_key = *slave_key; |
@@ -644,7 +657,7 @@ mcast_recv_join_request (void *cls, | |||
644 | jcls->slave_key = *slave_key; | 657 | jcls->slave_key = *slave_key; |
645 | jcls->chn = chn; | 658 | jcls->chn = chn; |
646 | jcls->jh = jh; | 659 | jcls->jh = jh; |
647 | jcls->master_join_req = req; | 660 | jcls->join_msg = req; |
648 | 661 | ||
649 | GNUNET_PSYCSTORE_membership_test (store, &chn->pub_key, slave_key, | 662 | GNUNET_PSYCSTORE_membership_test (store, &chn->pub_key, slave_key, |
650 | chn->max_message_id, 0, | 663 | chn->max_message_id, 0, |
@@ -780,6 +793,7 @@ client_send_mcast_msg (struct Channel *chn, | |||
780 | pmsg->header.size = htons (psize); | 793 | pmsg->header.size = htons (psize); |
781 | pmsg->header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE); | 794 | pmsg->header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE); |
782 | pmsg->message_id = mmsg->message_id; | 795 | pmsg->message_id = mmsg->message_id; |
796 | pmsg->fragment_offset = mmsg->fragment_offset; | ||
783 | 797 | ||
784 | memcpy (&pmsg[1], &mmsg[1], size - sizeof (*mmsg)); | 798 | memcpy (&pmsg[1], &mmsg[1], size - sizeof (*mmsg)); |
785 | client_send_msg (chn, &pmsg->header); | 799 | client_send_msg (chn, &pmsg->header); |
@@ -810,6 +824,7 @@ client_send_mcast_req (struct Master *mst, | |||
810 | pmsg->header.size = htons (psize); | 824 | pmsg->header.size = htons (psize); |
811 | pmsg->header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE); | 825 | pmsg->header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE); |
812 | pmsg->message_id = req->request_id; | 826 | pmsg->message_id = req->request_id; |
827 | pmsg->fragment_offset = req->fragment_offset; | ||
813 | pmsg->flags = htonl (GNUNET_PSYC_MESSAGE_REQUEST); | 828 | pmsg->flags = htonl (GNUNET_PSYC_MESSAGE_REQUEST); |
814 | 829 | ||
815 | memcpy (&pmsg[1], &req[1], size - sizeof (*req)); | 830 | memcpy (&pmsg[1], &req[1], size - sizeof (*req)); |
@@ -870,11 +885,12 @@ fragment_queue_insert (struct Channel *chn, | |||
870 | { | 885 | { |
871 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 886 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
872 | "%p Adding message fragment to cache. " | 887 | "%p Adding message fragment to cache. " |
873 | "message_id: %" PRIu64 ", fragment_id: %" PRIu64 ", " | 888 | "message_id: %" PRIu64 ", fragment_id: %" PRIu64 "\n", |
874 | "header_size: %" PRIu64 " + %u).\n", | ||
875 | chn, GNUNET_ntohll (mmsg->message_id), | 889 | chn, GNUNET_ntohll (mmsg->message_id), |
876 | GNUNET_ntohll (mmsg->fragment_id), | 890 | GNUNET_ntohll (mmsg->fragment_id)); |
877 | fragq->header_size, size); | 891 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
892 | "%p header_size: %" PRIu64 " + %u\n", | ||
893 | chn, fragq->header_size, size); | ||
878 | cache_entry = GNUNET_new (struct RecvCacheEntry); | 894 | cache_entry = GNUNET_new (struct RecvCacheEntry); |
879 | cache_entry->ref_count = 1; | 895 | cache_entry->ref_count = 1; |
880 | cache_entry->mmsg = GNUNET_malloc (size); | 896 | cache_entry->mmsg = GNUNET_malloc (size); |
@@ -955,11 +971,11 @@ fragment_queue_insert (struct Channel *chn, | |||
955 | case MSG_FRAG_STATE_DATA: | 971 | case MSG_FRAG_STATE_DATA: |
956 | case MSG_FRAG_STATE_END: | 972 | case MSG_FRAG_STATE_END: |
957 | case MSG_FRAG_STATE_CANCEL: | 973 | case MSG_FRAG_STATE_CANCEL: |
958 | if (GNUNET_NO == fragq->queued) | 974 | if (GNUNET_NO == fragq->is_queued) |
959 | { | 975 | { |
960 | GNUNET_CONTAINER_heap_insert (chn->recv_msgs, NULL, | 976 | GNUNET_CONTAINER_heap_insert (chn->recv_msgs, NULL, |
961 | GNUNET_ntohll (mmsg->message_id)); | 977 | GNUNET_ntohll (mmsg->message_id)); |
962 | fragq->queued = GNUNET_YES; | 978 | fragq->is_queued = GNUNET_YES; |
963 | } | 979 | } |
964 | } | 980 | } |
965 | 981 | ||
@@ -1034,7 +1050,7 @@ fragment_queue_run (struct Channel *chn, uint64_t msg_id, | |||
1034 | if (MSG_FRAG_STATE_END <= fragq->state) | 1050 | if (MSG_FRAG_STATE_END <= fragq->state) |
1035 | { | 1051 | { |
1036 | struct GNUNET_HashCode msg_id_hash; | 1052 | struct GNUNET_HashCode msg_id_hash; |
1037 | hash_key_from_nll (&msg_id_hash, msg_id); | 1053 | hash_key_from_hll (&msg_id_hash, msg_id); |
1038 | 1054 | ||
1039 | GNUNET_CONTAINER_multihashmap_remove (chn->recv_frags, &msg_id_hash, fragq); | 1055 | GNUNET_CONTAINER_multihashmap_remove (chn->recv_frags, &msg_id_hash, fragq); |
1040 | GNUNET_CONTAINER_heap_destroy (fragq->fragments); | 1056 | GNUNET_CONTAINER_heap_destroy (fragq->fragments); |
@@ -1042,7 +1058,7 @@ fragment_queue_run (struct Channel *chn, uint64_t msg_id, | |||
1042 | } | 1058 | } |
1043 | else | 1059 | else |
1044 | { | 1060 | { |
1045 | fragq->queued = GNUNET_NO; | 1061 | fragq->is_queued = GNUNET_NO; |
1046 | } | 1062 | } |
1047 | } | 1063 | } |
1048 | 1064 | ||
@@ -1331,13 +1347,18 @@ store_recv_slave_counters (void *cls, int result, uint64_t max_fragment_id, | |||
1331 | = GNUNET_MULTICAST_member_join (cfg, &chn->pub_key, &slv->priv_key, | 1347 | = GNUNET_MULTICAST_member_join (cfg, &chn->pub_key, &slv->priv_key, |
1332 | &slv->origin, | 1348 | &slv->origin, |
1333 | slv->relay_count, slv->relays, | 1349 | slv->relay_count, slv->relays, |
1334 | slv->join_req, | 1350 | &slv->join_msg->header, |
1335 | &mcast_recv_join_request, | 1351 | &mcast_recv_join_request, |
1336 | &mcast_recv_join_decision, | 1352 | &mcast_recv_join_decision, |
1337 | &mcast_recv_membership_test, | 1353 | &mcast_recv_membership_test, |
1338 | &mcast_recv_replay_fragment, | 1354 | &mcast_recv_replay_fragment, |
1339 | &mcast_recv_replay_message, | 1355 | &mcast_recv_replay_message, |
1340 | &mcast_recv_message, chn); | 1356 | &mcast_recv_message, chn); |
1357 | if (NULL != slv->join_msg) | ||
1358 | { | ||
1359 | GNUNET_free (slv->join_msg); | ||
1360 | slv->join_msg = NULL; | ||
1361 | } | ||
1341 | } | 1362 | } |
1342 | else | 1363 | else |
1343 | { | 1364 | { |
@@ -1435,6 +1456,7 @@ client_recv_slave_join (void *cls, struct GNUNET_SERVER_Client *client, | |||
1435 | { | 1456 | { |
1436 | const struct SlaveJoinRequest *req | 1457 | const struct SlaveJoinRequest *req |
1437 | = (const struct SlaveJoinRequest *) msg; | 1458 | = (const struct SlaveJoinRequest *) msg; |
1459 | uint16_t req_size = ntohs (req->header.size); | ||
1438 | 1460 | ||
1439 | struct GNUNET_CRYPTO_EcdsaPublicKey slv_pub_key; | 1461 | struct GNUNET_CRYPTO_EcdsaPublicKey slv_pub_key; |
1440 | struct GNUNET_HashCode pub_key_hash, slv_pub_key_hash; | 1462 | struct GNUNET_HashCode pub_key_hash, slv_pub_key_hash; |
@@ -1460,15 +1482,32 @@ client_recv_slave_join (void *cls, struct GNUNET_SERVER_Client *client, | |||
1460 | slv->pub_key_hash = slv_pub_key_hash; | 1482 | slv->pub_key_hash = slv_pub_key_hash; |
1461 | slv->origin = req->origin; | 1483 | slv->origin = req->origin; |
1462 | slv->relay_count = ntohl (req->relay_count); | 1484 | slv->relay_count = ntohl (req->relay_count); |
1485 | |||
1486 | const struct GNUNET_PeerIdentity * | ||
1487 | relays = (const struct GNUNET_PeerIdentity *) &req[1]; | ||
1488 | uint16_t relay_size = slv->relay_count * sizeof (*relays); | ||
1489 | uint16_t join_msg_size = 0; | ||
1490 | |||
1491 | if (sizeof (*req) + relay_size + sizeof (struct GNUNET_MessageHeader) | ||
1492 | <= req_size) | ||
1493 | { | ||
1494 | join_msg_size = ntohs (slv->join_msg->header.size); | ||
1495 | slv->join_msg = GNUNET_malloc (join_msg_size); | ||
1496 | memcpy (slv->join_msg, ((char *) &req[1]) + relay_size, join_msg_size); | ||
1497 | } | ||
1498 | if (sizeof (*req) + relay_size + join_msg_size != req_size) | ||
1499 | { | ||
1500 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1501 | "%u + %u + %u != %u\n", | ||
1502 | sizeof (*req), relay_size, join_msg_size, req_size); | ||
1503 | GNUNET_break (0); | ||
1504 | GNUNET_SERVER_client_disconnect (client); | ||
1505 | return; | ||
1506 | } | ||
1463 | if (0 < slv->relay_count) | 1507 | if (0 < slv->relay_count) |
1464 | { | 1508 | { |
1465 | const struct GNUNET_PeerIdentity *relays | 1509 | slv->relays = GNUNET_malloc (relay_size); |
1466 | = (const struct GNUNET_PeerIdentity *) &req[1]; | 1510 | memcpy (slv->relays, &req[1], relay_size); |
1467 | slv->relays | ||
1468 | = GNUNET_malloc (slv->relay_count * sizeof (struct GNUNET_PeerIdentity)); | ||
1469 | uint32_t i; | ||
1470 | for (i = 0; i < slv->relay_count; i++) | ||
1471 | memcpy (&slv->relays[i], &relays[i], sizeof (*relays)); | ||
1472 | } | 1511 | } |
1473 | 1512 | ||
1474 | chn = &slv->chn; | 1513 | chn = &slv->chn; |
@@ -1510,14 +1549,18 @@ client_recv_slave_join (void *cls, struct GNUNET_SERVER_Client *client, | |||
1510 | = GNUNET_MULTICAST_member_join (cfg, &chn->pub_key, &slv->priv_key, | 1549 | = GNUNET_MULTICAST_member_join (cfg, &chn->pub_key, &slv->priv_key, |
1511 | &slv->origin, | 1550 | &slv->origin, |
1512 | slv->relay_count, slv->relays, | 1551 | slv->relay_count, slv->relays, |
1513 | slv->join_req, | 1552 | &slv->join_msg->header, |
1514 | &mcast_recv_join_request, | 1553 | &mcast_recv_join_request, |
1515 | &mcast_recv_join_decision, | 1554 | &mcast_recv_join_decision, |
1516 | &mcast_recv_membership_test, | 1555 | &mcast_recv_membership_test, |
1517 | &mcast_recv_replay_fragment, | 1556 | &mcast_recv_replay_fragment, |
1518 | &mcast_recv_replay_message, | 1557 | &mcast_recv_replay_message, |
1519 | &mcast_recv_message, chn); | 1558 | &mcast_recv_message, chn); |
1520 | 1559 | if (NULL != slv->join_msg) | |
1560 | { | ||
1561 | GNUNET_free (slv->join_msg); | ||
1562 | slv->join_msg = NULL; | ||
1563 | } | ||
1521 | } | 1564 | } |
1522 | else if (NULL != slv->join_dcsn) | 1565 | else if (NULL != slv->join_dcsn) |
1523 | { | 1566 | { |
@@ -1549,13 +1592,14 @@ struct JoinDecisionClosure | |||
1549 | 1592 | ||
1550 | 1593 | ||
1551 | /** | 1594 | /** |
1552 | * Iterator callback for responding to join requests of a slave. | 1595 | * Iterator callback for sending join decisions to multicast. |
1553 | */ | 1596 | */ |
1554 | static int | 1597 | static int |
1555 | mcast_send_join_decision (void *cls, const struct GNUNET_HashCode *pub_key_hash, | 1598 | mcast_send_join_decision (void *cls, const struct GNUNET_HashCode *pub_key_hash, |
1556 | void *jh) | 1599 | void *value) |
1557 | { | 1600 | { |
1558 | struct JoinDecisionClosure *jcls = cls; | 1601 | struct JoinDecisionClosure *jcls = cls; |
1602 | struct GNUNET_MULTICAST_JoinHandle *jh = value; | ||
1559 | // FIXME: add relays | 1603 | // FIXME: add relays |
1560 | GNUNET_MULTICAST_join_decision (jh, jcls->is_admitted, 0, NULL, jcls->msg); | 1604 | GNUNET_MULTICAST_join_decision (jh, jcls->is_admitted, 0, NULL, jcls->msg); |
1561 | return GNUNET_YES; | 1605 | return GNUNET_YES; |
@@ -1579,8 +1623,7 @@ client_recv_join_decision (void *cls, struct GNUNET_SERVER_Client *client, | |||
1579 | struct JoinDecisionClosure jcls; | 1623 | struct JoinDecisionClosure jcls; |
1580 | jcls.is_admitted = ntohl (dcsn->is_admitted); | 1624 | jcls.is_admitted = ntohl (dcsn->is_admitted); |
1581 | jcls.msg | 1625 | jcls.msg |
1582 | = (sizeof (*dcsn) + sizeof (struct GNUNET_PSYC_MessageHeader) | 1626 | = (sizeof (*dcsn) + sizeof (*jcls.msg) <= ntohs (msg->size)) |
1583 | <= ntohs (msg->size)) | ||
1584 | ? (struct GNUNET_MessageHeader *) &dcsn[1] | 1627 | ? (struct GNUNET_MessageHeader *) &dcsn[1] |
1585 | : NULL; | 1628 | : NULL; |
1586 | 1629 | ||
@@ -1901,6 +1944,9 @@ client_recv_psyc_message (void *cls, struct GNUNET_SERVER_Client *client, | |||
1901 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 1944 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
1902 | return; | 1945 | return; |
1903 | } | 1946 | } |
1947 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1948 | "%p Received message with first part type %u and last part type %u.\n", | ||
1949 | chn, first_ptype, last_ptype); | ||
1904 | 1950 | ||
1905 | queue_message (chn, client, size - sizeof (*msg), &msg[1], | 1951 | queue_message (chn, client, size - sizeof (*msg), &msg[1], |
1906 | first_ptype, last_ptype); | 1952 | first_ptype, last_ptype); |
diff --git a/src/psyc/psyc.h b/src/psyc/psyc.h index 995fb1fa4..82800a334 100644 --- a/src/psyc/psyc.h +++ b/src/psyc/psyc.h | |||
@@ -229,22 +229,6 @@ struct OperationResult | |||
229 | */ | 229 | */ |
230 | }; | 230 | }; |
231 | 231 | ||
232 | |||
233 | struct MasterJoinRequest | ||
234 | { | ||
235 | /** | ||
236 | * Type: GNUNET_MESSAGE_TYPE_PSYC_MASTER_JOIN_REQUEST | ||
237 | */ | ||
238 | struct GNUNET_MessageHeader header; | ||
239 | /** | ||
240 | * Public key of the joining slave. | ||
241 | */ | ||
242 | struct GNUNET_CRYPTO_EcdsaPublicKey slave_key; | ||
243 | |||
244 | /* Followed by struct GNUNET_MessageHeader join_request */ | ||
245 | }; | ||
246 | |||
247 | |||
248 | GNUNET_NETWORK_STRUCT_END | 232 | GNUNET_NETWORK_STRUCT_END |
249 | 233 | ||
250 | #endif | 234 | #endif |
diff --git a/src/psyc/psyc_api.c b/src/psyc/psyc_api.c index 88b007a0f..a43b1ef5f 100644 --- a/src/psyc/psyc_api.c +++ b/src/psyc/psyc_api.c | |||
@@ -74,6 +74,16 @@ struct GNUNET_PSYC_Channel | |||
74 | struct GNUNET_MessageHeader *connect_msg; | 74 | struct GNUNET_MessageHeader *connect_msg; |
75 | 75 | ||
76 | /** | 76 | /** |
77 | * Function called after disconnected from the service. | ||
78 | */ | ||
79 | GNUNET_ContinuationCallback disconnect_cb; | ||
80 | |||
81 | /** | ||
82 | * Closure for @a disconnect_cb. | ||
83 | */ | ||
84 | void *disconnect_cls; | ||
85 | |||
86 | /** | ||
77 | * Are we polling for incoming messages right now? | 87 | * Are we polling for incoming messages right now? |
78 | */ | 88 | */ |
79 | uint8_t in_receive; | 89 | uint8_t in_receive; |
@@ -82,6 +92,12 @@ struct GNUNET_PSYC_Channel | |||
82 | * Is this a master or slave channel? | 92 | * Is this a master or slave channel? |
83 | */ | 93 | */ |
84 | uint8_t is_master; | 94 | uint8_t is_master; |
95 | |||
96 | /** | ||
97 | * Is this channel in the process of disconnecting from the service? | ||
98 | * #GNUNET_YES or #GNUNET_NO | ||
99 | */ | ||
100 | uint8_t is_disconnecting; | ||
85 | }; | 101 | }; |
86 | 102 | ||
87 | 103 | ||
@@ -232,19 +248,26 @@ master_recv_join_request (void *cls, | |||
232 | struct GNUNET_PSYC_Master * | 248 | struct GNUNET_PSYC_Master * |
233 | mst = GNUNET_CLIENT_MANAGER_get_user_context_ (client, | 249 | mst = GNUNET_CLIENT_MANAGER_get_user_context_ (client, |
234 | sizeof (struct GNUNET_PSYC_Channel)); | 250 | sizeof (struct GNUNET_PSYC_Channel)); |
235 | 251 | if (NULL == mst->join_req_cb) | |
236 | const struct MasterJoinRequest *req = (const struct MasterJoinRequest *) msg; | 252 | return; |
237 | 253 | ||
238 | struct GNUNET_PSYC_MessageHeader *pmsg = NULL; | 254 | const struct GNUNET_PSYC_JoinRequestMessage * |
239 | if (ntohs (req->header.size) <= sizeof (*req) + sizeof (*pmsg)) | 255 | req = (const struct GNUNET_PSYC_JoinRequestMessage *) msg; |
240 | pmsg = (struct GNUNET_PSYC_MessageHeader *) &req[1]; | 256 | const struct GNUNET_PSYC_Message *join_msg = NULL; |
257 | if (sizeof (*req) + sizeof (*join_msg) <= ntohs (req->header.size)) | ||
258 | { | ||
259 | join_msg = (struct GNUNET_PSYC_Message *) &req[1]; | ||
260 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
261 | "Received join_msg of type %u and size %u.\n", | ||
262 | ntohs (join_msg->header.type), ntohs (join_msg->header.size)); | ||
263 | } | ||
241 | 264 | ||
242 | struct GNUNET_PSYC_JoinHandle *jh = GNUNET_malloc (sizeof (*jh)); | 265 | struct GNUNET_PSYC_JoinHandle *jh = GNUNET_malloc (sizeof (*jh)); |
243 | jh->mst = mst; | 266 | jh->mst = mst; |
244 | jh->slave_key = req->slave_key; | 267 | jh->slave_key = req->slave_key; |
245 | 268 | ||
246 | if (NULL != mst->join_req_cb) | 269 | if (NULL != mst->join_req_cb) |
247 | mst->join_req_cb (mst->cb_cls, &req->slave_key, pmsg, jh); | 270 | mst->join_req_cb (mst->cb_cls, req, &req->slave_key, join_msg, jh); |
248 | } | 271 | } |
249 | 272 | ||
250 | 273 | ||
@@ -273,13 +296,12 @@ slave_recv_join_decision (void *cls, | |||
273 | const struct GNUNET_PSYC_JoinDecisionMessage * | 296 | const struct GNUNET_PSYC_JoinDecisionMessage * |
274 | dcsn = (const struct GNUNET_PSYC_JoinDecisionMessage *) msg; | 297 | dcsn = (const struct GNUNET_PSYC_JoinDecisionMessage *) msg; |
275 | 298 | ||
276 | struct GNUNET_PSYC_MessageHeader *pmsg = NULL; | 299 | struct GNUNET_PSYC_Message *pmsg = NULL; |
277 | if (ntohs (dcsn->header.size) <= sizeof (*dcsn) + sizeof (*pmsg)) | 300 | if (ntohs (dcsn->header.size) <= sizeof (*dcsn) + sizeof (*pmsg)) |
278 | pmsg = (struct GNUNET_PSYC_MessageHeader *) &dcsn[1]; | 301 | pmsg = (struct GNUNET_PSYC_Message *) &dcsn[1]; |
279 | 302 | ||
280 | struct GNUNET_PSYC_JoinHandle *jh = GNUNET_malloc (sizeof (*jh)); | ||
281 | if (NULL != slv->join_dcsn_cb) | 303 | if (NULL != slv->join_dcsn_cb) |
282 | slv->join_dcsn_cb (slv->cb_cls, ntohl (dcsn->is_admitted), pmsg); | 304 | slv->join_dcsn_cb (slv->cb_cls, dcsn, ntohl (dcsn->is_admitted), pmsg); |
283 | } | 305 | } |
284 | 306 | ||
285 | 307 | ||
@@ -299,7 +321,7 @@ static struct GNUNET_CLIENT_MANAGER_MessageHandler master_handlers[] = | |||
299 | 321 | ||
300 | { &master_recv_join_request, NULL, | 322 | { &master_recv_join_request, NULL, |
301 | GNUNET_MESSAGE_TYPE_PSYC_JOIN_REQUEST, | 323 | GNUNET_MESSAGE_TYPE_PSYC_JOIN_REQUEST, |
302 | sizeof (struct MasterJoinRequest), GNUNET_YES }, | 324 | sizeof (struct GNUNET_PSYC_JoinRequestMessage), GNUNET_YES }, |
303 | 325 | ||
304 | { &channel_recv_disconnect, NULL, 0, 0, GNUNET_NO }, | 326 | { &channel_recv_disconnect, NULL, 0, 0, GNUNET_NO }, |
305 | 327 | ||
@@ -331,6 +353,35 @@ static struct GNUNET_CLIENT_MANAGER_MessageHandler slave_handlers[] = | |||
331 | }; | 353 | }; |
332 | 354 | ||
333 | 355 | ||
356 | static void | ||
357 | channel_cleanup (struct GNUNET_PSYC_Channel *chn) | ||
358 | { | ||
359 | GNUNET_PSYC_transmit_destroy (chn->tmit); | ||
360 | GNUNET_PSYC_receive_destroy (chn->recv); | ||
361 | GNUNET_free (chn->connect_msg); | ||
362 | if (NULL != chn->disconnect_cb) | ||
363 | chn->disconnect_cb (chn->disconnect_cls); | ||
364 | } | ||
365 | |||
366 | |||
367 | static void | ||
368 | master_cleanup (void *cls) | ||
369 | { | ||
370 | struct GNUNET_PSYC_Master *mst = cls; | ||
371 | channel_cleanup (&mst->chn); | ||
372 | GNUNET_free (mst); | ||
373 | } | ||
374 | |||
375 | |||
376 | static void | ||
377 | slave_cleanup (void *cls) | ||
378 | { | ||
379 | struct GNUNET_PSYC_Slave *slv = cls; | ||
380 | channel_cleanup (&slv->chn); | ||
381 | GNUNET_free (slv); | ||
382 | } | ||
383 | |||
384 | |||
334 | /** | 385 | /** |
335 | * Start a PSYC master channel. | 386 | * Start a PSYC master channel. |
336 | * | 387 | * |
@@ -367,6 +418,7 @@ GNUNET_PSYC_master_start (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
367 | GNUNET_PSYC_MasterStartCallback start_cb, | 418 | GNUNET_PSYC_MasterStartCallback start_cb, |
368 | GNUNET_PSYC_JoinRequestCallback join_request_cb, | 419 | GNUNET_PSYC_JoinRequestCallback join_request_cb, |
369 | GNUNET_PSYC_MessageCallback message_cb, | 420 | GNUNET_PSYC_MessageCallback message_cb, |
421 | GNUNET_PSYC_MessagePartCallback message_part_cb, | ||
370 | void *cls) | 422 | void *cls) |
371 | { | 423 | { |
372 | struct GNUNET_PSYC_Master *mst = GNUNET_malloc (sizeof (*mst)); | 424 | struct GNUNET_PSYC_Master *mst = GNUNET_malloc (sizeof (*mst)); |
@@ -390,7 +442,7 @@ GNUNET_PSYC_master_start (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
390 | GNUNET_CLIENT_MANAGER_set_user_context_ (chn->client, mst, sizeof (*chn)); | 442 | GNUNET_CLIENT_MANAGER_set_user_context_ (chn->client, mst, sizeof (*chn)); |
391 | 443 | ||
392 | chn->tmit = GNUNET_PSYC_transmit_create (chn->client); | 444 | chn->tmit = GNUNET_PSYC_transmit_create (chn->client); |
393 | chn->recv = GNUNET_PSYC_receive_create (message_cb, message_cb, cls); | 445 | chn->recv = GNUNET_PSYC_receive_create (message_cb, message_part_cb, cls); |
394 | 446 | ||
395 | channel_send_connect_msg (chn); | 447 | channel_send_connect_msg (chn); |
396 | return mst; | 448 | return mst; |
@@ -404,10 +456,21 @@ GNUNET_PSYC_master_start (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
404 | * @param keep_active FIXME | 456 | * @param keep_active FIXME |
405 | */ | 457 | */ |
406 | void | 458 | void |
407 | GNUNET_PSYC_master_stop (struct GNUNET_PSYC_Master *mst) | 459 | GNUNET_PSYC_master_stop (struct GNUNET_PSYC_Master *mst, |
460 | int keep_active, | ||
461 | GNUNET_ContinuationCallback stop_cb, | ||
462 | void *stop_cls) | ||
408 | { | 463 | { |
409 | GNUNET_CLIENT_MANAGER_disconnect (mst->chn.client, GNUNET_YES); | 464 | struct GNUNET_PSYC_Channel *chn = &mst->chn; |
410 | GNUNET_free (mst); | 465 | |
466 | /* FIXME: send msg to service */ | ||
467 | |||
468 | chn->is_disconnecting = GNUNET_YES; | ||
469 | chn->disconnect_cb = stop_cb; | ||
470 | chn->disconnect_cls = stop_cls; | ||
471 | |||
472 | GNUNET_CLIENT_MANAGER_disconnect (mst->chn.client, GNUNET_YES, | ||
473 | &master_cleanup, mst); | ||
411 | } | 474 | } |
412 | 475 | ||
413 | 476 | ||
@@ -439,7 +502,7 @@ GNUNET_PSYC_join_decision (struct GNUNET_PSYC_JoinHandle *jh, | |||
439 | int is_admitted, | 502 | int is_admitted, |
440 | uint32_t relay_count, | 503 | uint32_t relay_count, |
441 | const struct GNUNET_PeerIdentity *relays, | 504 | const struct GNUNET_PeerIdentity *relays, |
442 | const struct GNUNET_PSYC_MessageHeader *join_resp) | 505 | const struct GNUNET_PSYC_Message *join_resp) |
443 | { | 506 | { |
444 | struct GNUNET_PSYC_Channel *chn = &jh->mst->chn; | 507 | struct GNUNET_PSYC_Channel *chn = &jh->mst->chn; |
445 | struct GNUNET_PSYC_JoinDecisionMessage *dcsn; | 508 | struct GNUNET_PSYC_JoinDecisionMessage *dcsn; |
@@ -461,6 +524,7 @@ GNUNET_PSYC_join_decision (struct GNUNET_PSYC_JoinHandle *jh, | |||
461 | memcpy (&dcsn[1], join_resp, join_resp_size); | 524 | memcpy (&dcsn[1], join_resp, join_resp_size); |
462 | 525 | ||
463 | GNUNET_CLIENT_MANAGER_transmit (chn->client, &dcsn->header); | 526 | GNUNET_CLIENT_MANAGER_transmit (chn->client, &dcsn->header); |
527 | GNUNET_free (jh); | ||
464 | return GNUNET_OK; | 528 | return GNUNET_OK; |
465 | } | 529 | } |
466 | 530 | ||
@@ -576,15 +640,19 @@ GNUNET_PSYC_slave_join (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
576 | uint32_t relay_count, | 640 | uint32_t relay_count, |
577 | const struct GNUNET_PeerIdentity *relays, | 641 | const struct GNUNET_PeerIdentity *relays, |
578 | GNUNET_PSYC_MessageCallback message_cb, | 642 | GNUNET_PSYC_MessageCallback message_cb, |
643 | GNUNET_PSYC_MessagePartCallback message_part_cb, | ||
579 | GNUNET_PSYC_SlaveConnectCallback connect_cb, | 644 | GNUNET_PSYC_SlaveConnectCallback connect_cb, |
580 | GNUNET_PSYC_JoinDecisionCallback join_decision_cb, | 645 | GNUNET_PSYC_JoinDecisionCallback join_decision_cb, |
581 | void *cls, | 646 | void *cls, |
582 | const struct GNUNET_MessageHeader *join_msg) | 647 | const struct GNUNET_PSYC_Message *join_msg) |
583 | { | 648 | { |
584 | struct GNUNET_PSYC_Slave *slv = GNUNET_malloc (sizeof (*slv)); | 649 | struct GNUNET_PSYC_Slave *slv = GNUNET_malloc (sizeof (*slv)); |
585 | struct GNUNET_PSYC_Channel *chn = &slv->chn; | 650 | struct GNUNET_PSYC_Channel *chn = &slv->chn; |
651 | |||
652 | uint16_t relay_size = relay_count * sizeof (*relays); | ||
653 | uint16_t join_msg_size = ntohs (join_msg->header.size); | ||
586 | struct SlaveJoinRequest *req | 654 | struct SlaveJoinRequest *req |
587 | = GNUNET_malloc (sizeof (*req) + relay_count * sizeof (*relays)); | 655 | = GNUNET_malloc (sizeof (*req) + relay_size + join_msg_size); |
588 | req->header.size = htons (sizeof (*req) | 656 | req->header.size = htons (sizeof (*req) |
589 | + relay_count * sizeof (*relays)); | 657 | + relay_count * sizeof (*relays)); |
590 | req->header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_SLAVE_JOIN); | 658 | req->header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_SLAVE_JOIN); |
@@ -592,7 +660,12 @@ GNUNET_PSYC_slave_join (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
592 | req->slave_key = *slave_key; | 660 | req->slave_key = *slave_key; |
593 | req->origin = *origin; | 661 | req->origin = *origin; |
594 | req->relay_count = htonl (relay_count); | 662 | req->relay_count = htonl (relay_count); |
595 | memcpy (&req[1], relays, relay_count * sizeof (*relays)); | 663 | |
664 | if (0 < relay_size) | ||
665 | memcpy (&req[1], relays, relay_size); | ||
666 | |||
667 | if (0 < join_msg_size) | ||
668 | memcpy ((char *) &req[1] + relay_size, join_msg, join_msg_size); | ||
596 | 669 | ||
597 | chn->connect_msg = (struct GNUNET_MessageHeader *) req; | 670 | chn->connect_msg = (struct GNUNET_MessageHeader *) req; |
598 | chn->cfg = cfg; | 671 | chn->cfg = cfg; |
@@ -605,7 +678,7 @@ GNUNET_PSYC_slave_join (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
605 | chn->client = GNUNET_CLIENT_MANAGER_connect (cfg, "psyc", slave_handlers); | 678 | chn->client = GNUNET_CLIENT_MANAGER_connect (cfg, "psyc", slave_handlers); |
606 | GNUNET_CLIENT_MANAGER_set_user_context_ (chn->client, slv, sizeof (*chn)); | 679 | GNUNET_CLIENT_MANAGER_set_user_context_ (chn->client, slv, sizeof (*chn)); |
607 | 680 | ||
608 | chn->recv = GNUNET_PSYC_receive_create (message_cb, message_cb, cls); | 681 | chn->recv = GNUNET_PSYC_receive_create (message_cb, message_part_cb, cls); |
609 | chn->tmit = GNUNET_PSYC_transmit_create (chn->client); | 682 | chn->tmit = GNUNET_PSYC_transmit_create (chn->client); |
610 | 683 | ||
611 | channel_send_connect_msg (chn); | 684 | channel_send_connect_msg (chn); |
@@ -622,10 +695,21 @@ GNUNET_PSYC_slave_join (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
622 | * @param slave Slave handle. | 695 | * @param slave Slave handle. |
623 | */ | 696 | */ |
624 | void | 697 | void |
625 | GNUNET_PSYC_slave_part (struct GNUNET_PSYC_Slave *slv) | 698 | GNUNET_PSYC_slave_part (struct GNUNET_PSYC_Slave *slv, |
699 | int keep_active, | ||
700 | GNUNET_ContinuationCallback part_cb, | ||
701 | void *part_cls) | ||
626 | { | 702 | { |
627 | GNUNET_CLIENT_MANAGER_disconnect (slv->chn.client, GNUNET_YES); | 703 | struct GNUNET_PSYC_Channel *chn = &slv->chn; |
628 | GNUNET_free (slv); | 704 | |
705 | /* FIXME: send msg to service */ | ||
706 | |||
707 | chn->is_disconnecting = GNUNET_YES; | ||
708 | chn->disconnect_cb = part_cb; | ||
709 | chn->disconnect_cls = part_cls; | ||
710 | |||
711 | GNUNET_CLIENT_MANAGER_disconnect (slv->chn.client, GNUNET_YES, | ||
712 | &slave_cleanup, slv); | ||
629 | } | 713 | } |
630 | 714 | ||
631 | 715 | ||
@@ -796,6 +880,7 @@ GNUNET_PSYC_channel_story_tell (struct GNUNET_PSYC_Channel *channel, | |||
796 | uint64_t start_message_id, | 880 | uint64_t start_message_id, |
797 | uint64_t end_message_id, | 881 | uint64_t end_message_id, |
798 | GNUNET_PSYC_MessageCallback message_cb, | 882 | GNUNET_PSYC_MessageCallback message_cb, |
883 | GNUNET_PSYC_MessagePartCallback message_part_cb, | ||
799 | GNUNET_PSYC_FinishCallback finish_cb, | 884 | GNUNET_PSYC_FinishCallback finish_cb, |
800 | void *cls) | 885 | void *cls) |
801 | { | 886 | { |
diff --git a/src/psyc/psyc_util_lib.c b/src/psyc/psyc_util_lib.c index 8ab0bdad2..6177976de 100644 --- a/src/psyc/psyc_util_lib.c +++ b/src/psyc/psyc_util_lib.c | |||
@@ -76,7 +76,11 @@ struct GNUNET_PSYC_TransmitHandle | |||
76 | * | 76 | * |
77 | */ | 77 | */ |
78 | const char *mod_value; | 78 | const char *mod_value; |
79 | size_t mod_value_size; | 79 | |
80 | /** | ||
81 | * Number of bytes remaining to be transmitted from the current modifier value. | ||
82 | */ | ||
83 | uint32_t mod_value_remaining; | ||
80 | 84 | ||
81 | /** | 85 | /** |
82 | * State of the current message being received from client. | 86 | * State of the current message being received from client. |
@@ -104,14 +108,14 @@ struct GNUNET_PSYC_TransmitHandle | |||
104 | struct GNUNET_PSYC_ReceiveHandle | 108 | struct GNUNET_PSYC_ReceiveHandle |
105 | { | 109 | { |
106 | /** | 110 | /** |
107 | * Message part callback. | 111 | * Message callback. |
108 | */ | 112 | */ |
109 | GNUNET_PSYC_MessageCallback message_cb; | 113 | GNUNET_PSYC_MessageCallback message_cb; |
110 | 114 | ||
111 | /** | 115 | /** |
112 | * Message part callback for historic message. | 116 | * Message part callback. |
113 | */ | 117 | */ |
114 | GNUNET_PSYC_MessageCallback hist_message_cb; | 118 | GNUNET_PSYC_MessagePartCallback message_part_cb; |
115 | 119 | ||
116 | /** | 120 | /** |
117 | * Closure for the callbacks. | 121 | * Closure for the callbacks. |
@@ -149,6 +153,7 @@ struct GNUNET_PSYC_ReceiveHandle | |||
149 | uint32_t mod_value_size; | 153 | uint32_t mod_value_size; |
150 | }; | 154 | }; |
151 | 155 | ||
156 | |||
152 | /**** Messages ****/ | 157 | /**** Messages ****/ |
153 | 158 | ||
154 | 159 | ||
@@ -167,7 +172,7 @@ struct GNUNET_PSYC_ReceiveHandle | |||
167 | * @return Message header with size information, | 172 | * @return Message header with size information, |
168 | * followed by the message parts. | 173 | * followed by the message parts. |
169 | */ | 174 | */ |
170 | struct GNUNET_MessageHeader * | 175 | struct GNUNET_PSYC_Message * |
171 | GNUNET_PSYC_message_create (const char *method_name, | 176 | GNUNET_PSYC_message_create (const char *method_name, |
172 | const struct GNUNET_ENV_Environment *env, | 177 | const struct GNUNET_ENV_Environment *env, |
173 | const void *data, | 178 | const void *data, |
@@ -188,7 +193,7 @@ GNUNET_PSYC_message_create (const char *method_name, | |||
188 | } | 193 | } |
189 | } | 194 | } |
190 | 195 | ||
191 | struct GNUNET_MessageHeader *msg; | 196 | struct GNUNET_PSYC_Message *msg; |
192 | uint16_t method_name_size = strlen (method_name) + 1; | 197 | uint16_t method_name_size = strlen (method_name) + 1; |
193 | if (method_name_size == 1) | 198 | if (method_name_size == 1) |
194 | return NULL; | 199 | return NULL; |
@@ -199,12 +204,13 @@ GNUNET_PSYC_message_create (const char *method_name, | |||
199 | + ((0 < data_size) ? sizeof (*pmsg) + data_size : 0)/* data */ | 204 | + ((0 < data_size) ? sizeof (*pmsg) + data_size : 0)/* data */ |
200 | + sizeof (*pmsg); /* end of message */ | 205 | + sizeof (*pmsg); /* end of message */ |
201 | msg = GNUNET_malloc (msg_size); | 206 | msg = GNUNET_malloc (msg_size); |
202 | msg->size = htons (msg_size); | 207 | msg->header.size = htons (msg_size); |
203 | msg->type = htons (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE); | 208 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE); /* FIXME */ |
204 | 209 | ||
205 | pmeth = (struct GNUNET_PSYC_MessageMethod *) &msg[1]; | 210 | pmeth = (struct GNUNET_PSYC_MessageMethod *) &msg[1]; |
211 | pmeth->header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_METHOD); | ||
206 | pmeth->header.size = htons (sizeof (*pmeth) + method_name_size); | 212 | pmeth->header.size = htons (sizeof (*pmeth) + method_name_size); |
207 | memcpy (pmeth, method_name, method_name_size); | 213 | memcpy (&pmeth[1], method_name, method_name_size); |
208 | 214 | ||
209 | uint16_t p = sizeof (*msg) + sizeof (*pmeth) + method_name_size; | 215 | uint16_t p = sizeof (*msg) + sizeof (*pmeth) + method_name_size; |
210 | if (NULL != env) | 216 | if (NULL != env) |
@@ -215,7 +221,7 @@ GNUNET_PSYC_message_create (const char *method_name, | |||
215 | uint16_t mod_name_size = strlen (mod->name) + 1; | 221 | uint16_t mod_name_size = strlen (mod->name) + 1; |
216 | pmod = (struct GNUNET_PSYC_MessageModifier *) ((char *) msg + p); | 222 | pmod = (struct GNUNET_PSYC_MessageModifier *) ((char *) msg + p); |
217 | pmod->header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MODIFIER); | 223 | pmod->header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MODIFIER); |
218 | pmod->header.size = sizeof (*pmod) + mod_name_size + 1 + mod->value_size; | 224 | pmod->header.size = sizeof (*pmod) + mod_name_size + mod->value_size; |
219 | p += pmod->header.size; | 225 | p += pmod->header.size; |
220 | pmod->header.size = htons (pmod->header.size); | 226 | pmod->header.size = htons (pmod->header.size); |
221 | 227 | ||
@@ -241,6 +247,7 @@ GNUNET_PSYC_message_create (const char *method_name, | |||
241 | pmsg->size = htons (sizeof (*pmsg)); | 247 | pmsg->size = htons (sizeof (*pmsg)); |
242 | pmsg->type = htons (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_END); | 248 | pmsg->type = htons (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_END); |
243 | 249 | ||
250 | GNUNET_assert (p + sizeof (*pmsg) == msg_size); | ||
244 | return msg; | 251 | return msg; |
245 | } | 252 | } |
246 | 253 | ||
@@ -276,8 +283,8 @@ GNUNET_PSYC_log_message (enum GNUNET_ErrorType kind, | |||
276 | uint16_t name_size = ntohs (mod->name_size); | 283 | uint16_t name_size = ntohs (mod->name_size); |
277 | char oper = ' ' < mod->oper ? mod->oper : ' '; | 284 | char oper = ' ' < mod->oper ? mod->oper : ' '; |
278 | GNUNET_log (kind, "\t%c%.*s\t%.*s\n", oper, name_size, &mod[1], | 285 | GNUNET_log (kind, "\t%c%.*s\t%.*s\n", oper, name_size, &mod[1], |
279 | size - sizeof (*mod) - name_size - 1, | 286 | size - sizeof (*mod) - name_size, |
280 | ((char *) &mod[1]) + name_size + 1); | 287 | ((char *) &mod[1]) + name_size); |
281 | break; | 288 | break; |
282 | } | 289 | } |
283 | case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MOD_CONT: | 290 | case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MOD_CONT: |
@@ -331,7 +338,7 @@ transmit_queue_insert (struct GNUNET_PSYC_TransmitHandle *tmit, | |||
331 | uint16_t size = (NULL != msg) ? ntohs (msg->size) : 0; | 338 | uint16_t size = (NULL != msg) ? ntohs (msg->size) : 0; |
332 | 339 | ||
333 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 340 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
334 | "Queueing message of type %u and size %u (end: %u)).\n", | 341 | "Queueing message part of type %u and size %u (end: %u)).\n", |
335 | ntohs (msg->type), size, end); | 342 | ntohs (msg->type), size, end); |
336 | 343 | ||
337 | if (NULL != tmit->msg) | 344 | if (NULL != tmit->msg) |
@@ -396,6 +403,9 @@ transmit_data (struct GNUNET_PSYC_TransmitHandle *tmit) | |||
396 | msg->type = htons (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_DATA); | 403 | msg->type = htons (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_DATA); |
397 | 404 | ||
398 | int notify_ret = tmit->notify_data (tmit->notify_data_cls, &data_size, &msg[1]); | 405 | int notify_ret = tmit->notify_data (tmit->notify_data_cls, &data_size, &msg[1]); |
406 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
407 | "transmit_data (ret: %d, size: %u): %.*s\n", | ||
408 | notify_ret, data_size, data_size, &msg[1]); | ||
399 | switch (notify_ret) | 409 | switch (notify_ret) |
400 | { | 410 | { |
401 | case GNUNET_NO: | 411 | case GNUNET_NO: |
@@ -463,9 +473,15 @@ transmit_mod (struct GNUNET_PSYC_TransmitHandle *tmit) | |||
463 | msg->size = sizeof (struct GNUNET_PSYC_MessageModifier); | 473 | msg->size = sizeof (struct GNUNET_PSYC_MessageModifier); |
464 | notify_ret = tmit->notify_mod (tmit->notify_mod_cls, &data_size, &mod[1], | 474 | notify_ret = tmit->notify_mod (tmit->notify_mod_cls, &data_size, &mod[1], |
465 | &mod->oper, &mod->value_size); | 475 | &mod->oper, &mod->value_size); |
466 | mod->name_size = strnlen ((char *) &mod[1], data_size); | 476 | |
477 | mod->name_size = strnlen ((char *) &mod[1], data_size) + 1; | ||
478 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
479 | "transmit_mod (ret: %d, size: %u + %u): %.*s\n", | ||
480 | notify_ret, mod->name_size, mod->value_size, data_size, &mod[1]); | ||
467 | if (mod->name_size < data_size) | 481 | if (mod->name_size < data_size) |
468 | { | 482 | { |
483 | tmit->mod_value_remaining | ||
484 | = mod->value_size - (data_size - mod->name_size); | ||
469 | mod->value_size = htonl (mod->value_size); | 485 | mod->value_size = htonl (mod->value_size); |
470 | mod->name_size = htons (mod->name_size); | 486 | mod->name_size = htons (mod->name_size); |
471 | } | 487 | } |
@@ -483,6 +499,10 @@ transmit_mod (struct GNUNET_PSYC_TransmitHandle *tmit) | |||
483 | msg->size = sizeof (struct GNUNET_MessageHeader); | 499 | msg->size = sizeof (struct GNUNET_MessageHeader); |
484 | notify_ret = tmit->notify_mod (tmit->notify_mod_cls, | 500 | notify_ret = tmit->notify_mod (tmit->notify_mod_cls, |
485 | &data_size, &msg[1], NULL, NULL); | 501 | &data_size, &msg[1], NULL, NULL); |
502 | tmit->mod_value_remaining -= data_size; | ||
503 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
504 | "transmit_mod (ret: %d, size: %u): %.*s\n", | ||
505 | notify_ret, data_size, data_size, &msg[1]); | ||
486 | break; | 506 | break; |
487 | } | 507 | } |
488 | default: | 508 | default: |
@@ -497,26 +517,19 @@ transmit_mod (struct GNUNET_PSYC_TransmitHandle *tmit) | |||
497 | tmit->paused = GNUNET_YES; | 517 | tmit->paused = GNUNET_YES; |
498 | return; | 518 | return; |
499 | } | 519 | } |
500 | tmit->state = GNUNET_PSYC_MESSAGE_STATE_MOD_CONT; | 520 | tmit->state |
521 | = (0 == tmit->mod_value_remaining) | ||
522 | ? GNUNET_PSYC_MESSAGE_STATE_MODIFIER | ||
523 | : GNUNET_PSYC_MESSAGE_STATE_MOD_CONT; | ||
501 | break; | 524 | break; |
502 | 525 | ||
503 | case GNUNET_YES: | 526 | case GNUNET_YES: /* End of modifiers. */ |
504 | if (0 == data_size) | 527 | GNUNET_assert (0 == tmit->mod_value_remaining); |
505 | { | ||
506 | /* End of modifiers. */ | ||
507 | tmit->state = GNUNET_PSYC_MESSAGE_STATE_DATA; | ||
508 | if (0 == tmit->acks_pending) | ||
509 | transmit_data (tmit); | ||
510 | |||
511 | return; | ||
512 | } | ||
513 | tmit->state = GNUNET_PSYC_MESSAGE_STATE_MODIFIER; | ||
514 | break; | 528 | break; |
515 | 529 | ||
516 | default: | 530 | default: |
517 | LOG (GNUNET_ERROR_TYPE_ERROR, | 531 | LOG (GNUNET_ERROR_TYPE_ERROR, |
518 | "TransmitNotifyModifier callback returned error " | 532 | "TransmitNotifyModifier callback returned with error.\n"); |
519 | "when requesting a modifier.\n"); | ||
520 | 533 | ||
521 | tmit->state = GNUNET_PSYC_MESSAGE_STATE_CANCEL; | 534 | tmit->state = GNUNET_PSYC_MESSAGE_STATE_CANCEL; |
522 | msg->type = htons (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_CANCEL); | 535 | msg->type = htons (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_CANCEL); |
@@ -533,7 +546,16 @@ transmit_mod (struct GNUNET_PSYC_TransmitHandle *tmit) | |||
533 | transmit_queue_insert (tmit, msg, GNUNET_NO); | 546 | transmit_queue_insert (tmit, msg, GNUNET_NO); |
534 | } | 547 | } |
535 | 548 | ||
536 | transmit_mod (tmit); | 549 | if (GNUNET_YES == notify_ret) |
550 | { | ||
551 | tmit->state = GNUNET_PSYC_MESSAGE_STATE_DATA; | ||
552 | if (0 == tmit->acks_pending) | ||
553 | transmit_data (tmit); | ||
554 | } | ||
555 | else | ||
556 | { | ||
557 | transmit_mod (tmit); | ||
558 | } | ||
537 | } | 559 | } |
538 | 560 | ||
539 | 561 | ||
@@ -547,9 +569,10 @@ transmit_notify_env (void *cls, uint16_t *data_size, void *data, uint8_t *oper, | |||
547 | size_t value_size = 0; | 569 | size_t value_size = 0; |
548 | const char *value = NULL; | 570 | const char *value = NULL; |
549 | 571 | ||
550 | if (NULL != oper && NULL != tmit->mod) | 572 | if (NULL != oper) |
551 | { /* New modifier */ | 573 | { /* New modifier */ |
552 | tmit->mod = tmit->mod->next; | 574 | if (NULL != tmit->mod) |
575 | tmit->mod = tmit->mod->next; | ||
553 | if (NULL == tmit->mod) | 576 | if (NULL == tmit->mod) |
554 | { /* No more modifiers, continue with data */ | 577 | { /* No more modifiers, continue with data */ |
555 | *data_size = 0; | 578 | *data_size = 0; |
@@ -559,30 +582,29 @@ transmit_notify_env (void *cls, uint16_t *data_size, void *data, uint8_t *oper, | |||
559 | GNUNET_assert (tmit->mod->value_size < UINT32_MAX); | 582 | GNUNET_assert (tmit->mod->value_size < UINT32_MAX); |
560 | *full_value_size = tmit->mod->value_size; | 583 | *full_value_size = tmit->mod->value_size; |
561 | *oper = tmit->mod->oper; | 584 | *oper = tmit->mod->oper; |
562 | name_size = strlen (tmit->mod->name); | 585 | name_size = strlen (tmit->mod->name) + 1; |
563 | 586 | ||
564 | if (name_size + 1 + tmit->mod->value_size <= *data_size) | 587 | if (name_size + tmit->mod->value_size <= *data_size) |
565 | { | 588 | { |
566 | *data_size = name_size + 1 + tmit->mod->value_size; | 589 | *data_size = name_size + tmit->mod->value_size; |
567 | } | 590 | } |
568 | else | 591 | else |
569 | { | 592 | { |
570 | tmit->mod_value_size = tmit->mod->value_size; | 593 | value_size = *data_size - name_size; |
571 | value_size = *data_size - name_size - 1; | ||
572 | tmit->mod_value_size -= value_size; | ||
573 | tmit->mod_value = tmit->mod->value + value_size; | 594 | tmit->mod_value = tmit->mod->value + value_size; |
574 | } | 595 | } |
575 | 596 | ||
576 | memcpy (data, tmit->mod->name, name_size); | 597 | memcpy (data, tmit->mod->name, name_size); |
577 | ((char *)data)[name_size] = '\0'; | 598 | memcpy ((char *)data + name_size, tmit->mod->value, value_size); |
578 | memcpy ((char *)data + name_size + 1, tmit->mod->value, value_size); | 599 | return GNUNET_NO; |
579 | } | 600 | } |
580 | else if (NULL != tmit->mod_value && 0 < tmit->mod_value_size) | 601 | else |
581 | { /* Modifier continuation */ | 602 | { /* Modifier continuation */ |
603 | GNUNET_assert (NULL != tmit->mod_value && 0 < tmit->mod_value_remaining); | ||
582 | value = tmit->mod_value; | 604 | value = tmit->mod_value; |
583 | if (tmit->mod_value_size <= *data_size) | 605 | if (tmit->mod_value_remaining <= *data_size) |
584 | { | 606 | { |
585 | value_size = tmit->mod_value_size; | 607 | value_size = tmit->mod_value_remaining; |
586 | tmit->mod_value = NULL; | 608 | tmit->mod_value = NULL; |
587 | } | 609 | } |
588 | else | 610 | else |
@@ -590,7 +612,6 @@ transmit_notify_env (void *cls, uint16_t *data_size, void *data, uint8_t *oper, | |||
590 | value_size = *data_size; | 612 | value_size = *data_size; |
591 | tmit->mod_value += value_size; | 613 | tmit->mod_value += value_size; |
592 | } | 614 | } |
593 | tmit->mod_value_size -= value_size; | ||
594 | 615 | ||
595 | if (*data_size < value_size) | 616 | if (*data_size < value_size) |
596 | { | 617 | { |
@@ -603,9 +624,8 @@ transmit_notify_env (void *cls, uint16_t *data_size, void *data, uint8_t *oper, | |||
603 | 624 | ||
604 | *data_size = value_size; | 625 | *data_size = value_size; |
605 | memcpy (data, value, value_size); | 626 | memcpy (data, value, value_size); |
627 | return (tmit->mod_value = NULL) ? GNUNET_YES : GNUNET_NO; | ||
606 | } | 628 | } |
607 | |||
608 | return 0 == tmit->mod_value_size ? GNUNET_YES : GNUNET_NO; | ||
609 | } | 629 | } |
610 | 630 | ||
611 | 631 | ||
@@ -663,10 +683,16 @@ GNUNET_PSYC_transmit_message (struct GNUNET_PSYC_TransmitHandle *tmit, | |||
663 | { | 683 | { |
664 | tmit->notify_mod = &transmit_notify_env; | 684 | tmit->notify_mod = &transmit_notify_env; |
665 | tmit->notify_mod_cls = tmit; | 685 | tmit->notify_mod_cls = tmit; |
666 | tmit->mod | 686 | if (NULL != env) |
667 | = (NULL != env) | 687 | { |
668 | ? GNUNET_ENV_environment_head (env) | 688 | struct GNUNET_ENV_Modifier mod = {}; |
669 | : NULL; | 689 | mod.next = GNUNET_ENV_environment_head (env); |
690 | tmit->mod = &mod; | ||
691 | } | ||
692 | else | ||
693 | { | ||
694 | tmit->mod = NULL; | ||
695 | } | ||
670 | } | 696 | } |
671 | 697 | ||
672 | transmit_mod (tmit); | 698 | transmit_mod (tmit); |
@@ -762,12 +788,12 @@ GNUNET_PSYC_transmit_got_ack (struct GNUNET_PSYC_TransmitHandle *tmit) | |||
762 | */ | 788 | */ |
763 | struct GNUNET_PSYC_ReceiveHandle * | 789 | struct GNUNET_PSYC_ReceiveHandle * |
764 | GNUNET_PSYC_receive_create (GNUNET_PSYC_MessageCallback message_cb, | 790 | GNUNET_PSYC_receive_create (GNUNET_PSYC_MessageCallback message_cb, |
765 | GNUNET_PSYC_MessageCallback hist_message_cb, | 791 | GNUNET_PSYC_MessagePartCallback message_part_cb, |
766 | void *cb_cls) | 792 | void *cb_cls) |
767 | { | 793 | { |
768 | struct GNUNET_PSYC_ReceiveHandle *recv = GNUNET_malloc (sizeof (*recv)); | 794 | struct GNUNET_PSYC_ReceiveHandle *recv = GNUNET_malloc (sizeof (*recv)); |
769 | recv->message_cb = message_cb; | 795 | recv->message_cb = message_cb; |
770 | recv->hist_message_cb = hist_message_cb; | 796 | recv->message_part_cb = message_part_cb; |
771 | recv->cb_cls = cb_cls; | 797 | recv->cb_cls = cb_cls; |
772 | return recv; | 798 | return recv; |
773 | } | 799 | } |
@@ -800,13 +826,11 @@ GNUNET_PSYC_receive_reset (struct GNUNET_PSYC_ReceiveHandle *recv) | |||
800 | static void | 826 | static void |
801 | recv_error (struct GNUNET_PSYC_ReceiveHandle *recv) | 827 | recv_error (struct GNUNET_PSYC_ReceiveHandle *recv) |
802 | { | 828 | { |
803 | GNUNET_PSYC_MessageCallback message_cb | 829 | if (NULL != recv->message_part_cb) |
804 | = recv->flags & GNUNET_PSYC_MESSAGE_HISTORIC | 830 | recv->message_part_cb (recv->cb_cls, recv->message_id, 0, recv->flags, NULL); |
805 | ? recv->hist_message_cb | ||
806 | : recv->message_cb; | ||
807 | 831 | ||
808 | if (NULL != message_cb) | 832 | if (NULL != recv->message_cb) |
809 | message_cb (recv->cb_cls, recv->message_id, recv->flags, NULL); | 833 | recv->message_cb (recv->cb_cls, recv->message_id, recv->flags, NULL); |
810 | 834 | ||
811 | GNUNET_PSYC_receive_reset (recv); | 835 | GNUNET_PSYC_receive_reset (recv); |
812 | } | 836 | } |
@@ -827,6 +851,7 @@ GNUNET_PSYC_receive_message (struct GNUNET_PSYC_ReceiveHandle *recv, | |||
827 | { | 851 | { |
828 | uint16_t size = ntohs (msg->header.size); | 852 | uint16_t size = ntohs (msg->header.size); |
829 | uint32_t flags = ntohl (msg->flags); | 853 | uint32_t flags = ntohl (msg->flags); |
854 | uint64_t message_id; | ||
830 | 855 | ||
831 | GNUNET_PSYC_log_message (GNUNET_ERROR_TYPE_DEBUG, | 856 | GNUNET_PSYC_log_message (GNUNET_ERROR_TYPE_DEBUG, |
832 | (struct GNUNET_MessageHeader *) msg); | 857 | (struct GNUNET_MessageHeader *) msg); |
@@ -858,6 +883,7 @@ GNUNET_PSYC_receive_message (struct GNUNET_PSYC_ReceiveHandle *recv, | |||
858 | recv_error (recv); | 883 | recv_error (recv); |
859 | return GNUNET_SYSERR; | 884 | return GNUNET_SYSERR; |
860 | } | 885 | } |
886 | message_id = recv->message_id; | ||
861 | 887 | ||
862 | uint16_t pos = 0, psize = 0, ptype, size_eq, size_min; | 888 | uint16_t pos = 0, psize = 0, ptype, size_eq, size_min; |
863 | 889 | ||
@@ -964,10 +990,10 @@ GNUNET_PSYC_receive_message (struct GNUNET_PSYC_ReceiveHandle *recv, | |||
964 | 990 | ||
965 | uint16_t name_size = ntohs (mod->name_size); | 991 | uint16_t name_size = ntohs (mod->name_size); |
966 | recv->mod_value_size_expected = ntohl (mod->value_size); | 992 | recv->mod_value_size_expected = ntohl (mod->value_size); |
967 | recv->mod_value_size = psize - sizeof (*mod) - name_size - 1; | 993 | recv->mod_value_size = psize - sizeof (*mod) - name_size; |
968 | 994 | ||
969 | if (psize < sizeof (*mod) + name_size + 1 | 995 | if (psize < sizeof (*mod) + name_size |
970 | || '\0' != *((char *) &mod[1] + name_size) | 996 | || '\0' != *((char *) &mod[1] + name_size - 1) |
971 | || recv->mod_value_size_expected < recv->mod_value_size) | 997 | || recv->mod_value_size_expected < recv->mod_value_size) |
972 | { | 998 | { |
973 | LOG (GNUNET_ERROR_TYPE_WARNING, "Dropping malformed modifier.\n"); | 999 | LOG (GNUNET_ERROR_TYPE_WARNING, "Dropping malformed modifier.\n"); |
@@ -1018,13 +1044,9 @@ GNUNET_PSYC_receive_message (struct GNUNET_PSYC_ReceiveHandle *recv, | |||
1018 | } | 1044 | } |
1019 | } | 1045 | } |
1020 | 1046 | ||
1021 | GNUNET_PSYC_MessageCallback message_cb | 1047 | if (NULL != recv->message_part_cb) |
1022 | = recv->flags & GNUNET_PSYC_MESSAGE_HISTORIC | 1048 | recv->message_part_cb (recv->cb_cls, recv->message_id, 0, // FIXME: data_offset |
1023 | ? recv->hist_message_cb | 1049 | recv->flags, pmsg); |
1024 | : recv->message_cb; | ||
1025 | |||
1026 | if (NULL != message_cb) | ||
1027 | message_cb (recv->cb_cls, recv->message_id, recv->flags, pmsg); | ||
1028 | 1050 | ||
1029 | switch (ptype) | 1051 | switch (ptype) |
1030 | { | 1052 | { |
@@ -1034,6 +1056,9 @@ GNUNET_PSYC_receive_message (struct GNUNET_PSYC_ReceiveHandle *recv, | |||
1034 | break; | 1056 | break; |
1035 | } | 1057 | } |
1036 | } | 1058 | } |
1059 | |||
1060 | if (NULL != recv->message_cb) | ||
1061 | recv->message_cb (recv->cb_cls, message_id, flags, msg); | ||
1037 | return GNUNET_OK; | 1062 | return GNUNET_OK; |
1038 | } | 1063 | } |
1039 | 1064 | ||
@@ -1063,6 +1088,7 @@ GNUNET_PSYC_receive_check_parts (uint16_t data_size, const char *data, | |||
1063 | for (pos = 0; pos < data_size; pos += psize, parts++) | 1088 | for (pos = 0; pos < data_size; pos += psize, parts++) |
1064 | { | 1089 | { |
1065 | pmsg = (const struct GNUNET_MessageHeader *) (data + pos); | 1090 | pmsg = (const struct GNUNET_MessageHeader *) (data + pos); |
1091 | GNUNET_PSYC_log_message (GNUNET_ERROR_TYPE_DEBUG, pmsg); | ||
1066 | psize = ntohs (pmsg->size); | 1092 | psize = ntohs (pmsg->size); |
1067 | ptype = ntohs (pmsg->type); | 1093 | ptype = ntohs (pmsg->type); |
1068 | if (0 == parts && NULL != first_ptype) | 1094 | if (0 == parts && NULL != first_ptype) |
@@ -1084,3 +1110,111 @@ GNUNET_PSYC_receive_check_parts (uint16_t data_size, const char *data, | |||
1084 | } | 1110 | } |
1085 | return parts; | 1111 | return parts; |
1086 | } | 1112 | } |
1113 | |||
1114 | |||
1115 | struct ParseMessageClosure | ||
1116 | { | ||
1117 | struct GNUNET_ENV_Environment *env; | ||
1118 | const char **method_name; | ||
1119 | const void **data; | ||
1120 | uint16_t *data_size; | ||
1121 | enum GNUNET_PSYC_MessageState msg_state; | ||
1122 | }; | ||
1123 | |||
1124 | |||
1125 | static void | ||
1126 | parse_message_part_cb (void *cls, uint64_t message_id, uint64_t data_offset, | ||
1127 | uint32_t flags, const struct GNUNET_MessageHeader *msg) | ||
1128 | { | ||
1129 | struct ParseMessageClosure *pmc = cls; | ||
1130 | if (NULL == msg) | ||
1131 | { | ||
1132 | pmc->msg_state = GNUNET_PSYC_MESSAGE_STATE_ERROR; | ||
1133 | return; | ||
1134 | } | ||
1135 | |||
1136 | switch (ntohs (msg->type)) | ||
1137 | { | ||
1138 | case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_METHOD: | ||
1139 | { | ||
1140 | struct GNUNET_PSYC_MessageMethod * | ||
1141 | pmeth = (struct GNUNET_PSYC_MessageMethod *) msg; | ||
1142 | *pmc->method_name = (const char *) &pmeth[1]; | ||
1143 | pmc->msg_state = GNUNET_PSYC_MESSAGE_STATE_METHOD; | ||
1144 | break; | ||
1145 | } | ||
1146 | |||
1147 | case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MODIFIER: | ||
1148 | { | ||
1149 | struct GNUNET_PSYC_MessageModifier * | ||
1150 | pmod = (struct GNUNET_PSYC_MessageModifier *) msg; | ||
1151 | |||
1152 | const char *name = (const char *) &pmod[1]; | ||
1153 | const void *value = name + pmod->name_size; | ||
1154 | GNUNET_ENV_environment_add (pmc->env, pmod->oper, name, value, | ||
1155 | pmod->value_size); | ||
1156 | pmc->msg_state = GNUNET_PSYC_MESSAGE_STATE_MODIFIER; | ||
1157 | break; | ||
1158 | } | ||
1159 | |||
1160 | case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_DATA: | ||
1161 | *pmc->data = &msg[1]; | ||
1162 | *pmc->data_size = ntohs (msg->size) - sizeof (*msg); | ||
1163 | pmc->msg_state = GNUNET_PSYC_MESSAGE_STATE_DATA; | ||
1164 | break; | ||
1165 | |||
1166 | case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_END: | ||
1167 | pmc->msg_state = GNUNET_PSYC_MESSAGE_STATE_END; | ||
1168 | break; | ||
1169 | |||
1170 | default: | ||
1171 | pmc->msg_state = GNUNET_PSYC_MESSAGE_STATE_ERROR; | ||
1172 | } | ||
1173 | } | ||
1174 | |||
1175 | |||
1176 | /** | ||
1177 | * Parse PSYC message. | ||
1178 | * | ||
1179 | * @param msg | ||
1180 | * The PSYC message to parse. | ||
1181 | * @param[out] method_name | ||
1182 | * Pointer to the method name inside @a pmsg. | ||
1183 | * @param env | ||
1184 | * The environment for the message with a list of modifiers. | ||
1185 | * @param[out] data | ||
1186 | * Pointer to data inside @a pmsg. | ||
1187 | * @param[out] data_size | ||
1188 | * Size of @data is written here. | ||
1189 | * | ||
1190 | * @return #GNUNET_OK on success, | ||
1191 | * #GNUNET_SYSERR on parse error. | ||
1192 | */ | ||
1193 | int | ||
1194 | GNUNET_PSYC_message_parse (const struct GNUNET_PSYC_Message *msg, | ||
1195 | const char **method_name, | ||
1196 | struct GNUNET_ENV_Environment *env, | ||
1197 | const void **data, | ||
1198 | uint16_t *data_size) | ||
1199 | { | ||
1200 | struct ParseMessageClosure cls; | ||
1201 | cls.env = env; | ||
1202 | cls.method_name = method_name; | ||
1203 | cls.data = data; | ||
1204 | cls.data_size = data_size; | ||
1205 | |||
1206 | uint16_t msg_size = ntohs (msg->header.size); | ||
1207 | struct GNUNET_PSYC_MessageHeader * | ||
1208 | pmsg = GNUNET_malloc (sizeof (*pmsg) + msg_size - sizeof (*msg)); | ||
1209 | memcpy (&pmsg[1], &msg[1], msg_size - sizeof (*msg)); | ||
1210 | |||
1211 | struct GNUNET_PSYC_ReceiveHandle * | ||
1212 | recv = GNUNET_PSYC_receive_create (NULL, &parse_message_part_cb, &cls); | ||
1213 | GNUNET_PSYC_receive_message (recv, pmsg); | ||
1214 | GNUNET_PSYC_receive_destroy (recv); | ||
1215 | GNUNET_free (pmsg); | ||
1216 | |||
1217 | return (GNUNET_PSYC_MESSAGE_STATE_END == cls.msg_state) | ||
1218 | ? GNUNET_OK | ||
1219 | : GNUNET_SYSERR; | ||
1220 | } | ||
diff --git a/src/psyc/test_psyc.c b/src/psyc/test_psyc.c index 0077bc9b7..495e3be47 100644 --- a/src/psyc/test_psyc.c +++ b/src/psyc/test_psyc.c | |||
@@ -62,8 +62,6 @@ static struct GNUNET_CRYPTO_EcdsaPrivateKey *slave_key; | |||
62 | static struct GNUNET_CRYPTO_EddsaPublicKey channel_pub_key; | 62 | static struct GNUNET_CRYPTO_EddsaPublicKey channel_pub_key; |
63 | static struct GNUNET_CRYPTO_EcdsaPublicKey slave_pub_key; | 63 | static struct GNUNET_CRYPTO_EcdsaPublicKey slave_pub_key; |
64 | 64 | ||
65 | struct GNUNET_PSYC_MasterTransmitHandle *mth; | ||
66 | |||
67 | struct TransmitClosure | 65 | struct TransmitClosure |
68 | { | 66 | { |
69 | struct GNUNET_PSYC_MasterTransmitHandle *mst_tmit; | 67 | struct GNUNET_PSYC_MasterTransmitHandle *mst_tmit; |
@@ -95,6 +93,28 @@ static void | |||
95 | master_transmit (); | 93 | master_transmit (); |
96 | 94 | ||
97 | 95 | ||
96 | void master_stopped (void *cls) | ||
97 | { | ||
98 | if (NULL != tmit) | ||
99 | { | ||
100 | GNUNET_ENV_environment_destroy (tmit->env); | ||
101 | GNUNET_free (tmit); | ||
102 | tmit = NULL; | ||
103 | } | ||
104 | GNUNET_SCHEDULER_shutdown (); | ||
105 | } | ||
106 | |||
107 | void slave_parted (void *cls) | ||
108 | { | ||
109 | if (NULL != mst) | ||
110 | { | ||
111 | GNUNET_PSYC_master_stop (mst, GNUNET_NO, &master_stopped, NULL); | ||
112 | mst = NULL; | ||
113 | } | ||
114 | else | ||
115 | master_stopped (NULL); | ||
116 | } | ||
117 | |||
98 | /** | 118 | /** |
99 | * Clean up all resources used. | 119 | * Clean up all resources used. |
100 | */ | 120 | */ |
@@ -103,21 +123,11 @@ cleanup () | |||
103 | { | 123 | { |
104 | if (NULL != slv) | 124 | if (NULL != slv) |
105 | { | 125 | { |
106 | GNUNET_PSYC_slave_part (slv); | 126 | GNUNET_PSYC_slave_part (slv, GNUNET_NO, &slave_parted, NULL); |
107 | slv = NULL; | 127 | slv = NULL; |
108 | } | 128 | } |
109 | if (NULL != mst) | 129 | else |
110 | { | 130 | slave_parted (NULL); |
111 | GNUNET_PSYC_master_stop (mst); | ||
112 | mst = NULL; | ||
113 | } | ||
114 | if (NULL != tmit) | ||
115 | { | ||
116 | GNUNET_ENV_environment_destroy (tmit->env); | ||
117 | GNUNET_free (tmit); | ||
118 | tmit = NULL; | ||
119 | } | ||
120 | GNUNET_SCHEDULER_shutdown (); | ||
121 | } | 131 | } |
122 | 132 | ||
123 | 133 | ||
@@ -171,7 +181,20 @@ end () | |||
171 | 181 | ||
172 | static void | 182 | static void |
173 | master_message_cb (void *cls, uint64_t message_id, uint32_t flags, | 183 | master_message_cb (void *cls, uint64_t message_id, uint32_t flags, |
174 | const struct GNUNET_MessageHeader *msg) | 184 | const struct GNUNET_PSYC_MessageHeader *msg) |
185 | { | ||
186 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
187 | "Master got PSYC message fragment of size %u " | ||
188 | "belonging to message ID %llu with flags %x\n", | ||
189 | ntohs (msg->header.size), message_id, flags); | ||
190 | // FIXME | ||
191 | } | ||
192 | |||
193 | |||
194 | static void | ||
195 | master_message_part_cb (void *cls, uint64_t message_id, | ||
196 | uint64_t data_offset, uint32_t flags, | ||
197 | const struct GNUNET_MessageHeader *msg) | ||
175 | { | 198 | { |
176 | if (NULL == msg) | 199 | if (NULL == msg) |
177 | { | 200 | { |
@@ -215,7 +238,20 @@ master_message_cb (void *cls, uint64_t message_id, uint32_t flags, | |||
215 | 238 | ||
216 | static void | 239 | static void |
217 | slave_message_cb (void *cls, uint64_t message_id, uint32_t flags, | 240 | slave_message_cb (void *cls, uint64_t message_id, uint32_t flags, |
218 | const struct GNUNET_MessageHeader *msg) | 241 | const struct GNUNET_PSYC_MessageHeader *msg) |
242 | { | ||
243 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
244 | "Slave got PSYC message fragment of size %u " | ||
245 | "belonging to message ID %llu with flags %x\n", | ||
246 | ntohs (msg->header.size), message_id, flags); | ||
247 | // FIXME | ||
248 | } | ||
249 | |||
250 | |||
251 | static void | ||
252 | slave_message_part_cb (void *cls, uint64_t message_id, | ||
253 | uint64_t data_offset, uint32_t flags, | ||
254 | const struct GNUNET_MessageHeader *msg) | ||
219 | { | 255 | { |
220 | if (NULL == msg) | 256 | if (NULL == msg) |
221 | { | 257 | { |
@@ -371,7 +407,7 @@ tmit_notify_mod (void *cls, uint16_t *data_size, void *data, uint8_t *oper, | |||
371 | memcpy (data, value, value_size); | 407 | memcpy (data, value, value_size); |
372 | } | 408 | } |
373 | 409 | ||
374 | return 0 == tmit->mod_value_size ? GNUNET_YES : GNUNET_NO; | 410 | return GNUNET_NO; |
375 | } | 411 | } |
376 | 412 | ||
377 | 413 | ||
@@ -380,8 +416,10 @@ slave_join (); | |||
380 | 416 | ||
381 | 417 | ||
382 | static void | 418 | static void |
383 | join_decision_cb (void *cls, int is_admitted, | 419 | join_decision_cb (void *cls, |
384 | const struct GNUNET_PSYC_MessageHeader *join_msg) | 420 | const struct GNUNET_PSYC_JoinDecisionMessage *dcsn, |
421 | int is_admitted, | ||
422 | const struct GNUNET_PSYC_Message *join_msg) | ||
385 | { | 423 | { |
386 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 424 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
387 | "Slave got join decision: %d\n", is_admitted); | 425 | "Slave got join decision: %d\n", is_admitted); |
@@ -415,8 +453,10 @@ join_decision_cb (void *cls, int is_admitted, | |||
415 | 453 | ||
416 | 454 | ||
417 | static void | 455 | static void |
418 | join_request_cb (void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *slave_key, | 456 | join_request_cb (void *cls, |
419 | const struct GNUNET_PSYC_MessageHeader *msg, | 457 | const struct GNUNET_PSYC_JoinRequestMessage *req, |
458 | const struct GNUNET_CRYPTO_EcdsaPublicKey *slave_key, | ||
459 | const struct GNUNET_PSYC_Message *join_msg, | ||
420 | struct GNUNET_PSYC_JoinHandle *jh) | 460 | struct GNUNET_PSYC_JoinHandle *jh) |
421 | { | 461 | { |
422 | struct GNUNET_HashCode slave_key_hash; | 462 | struct GNUNET_HashCode slave_key_hash; |
@@ -450,11 +490,11 @@ slave_join () | |||
450 | "_foo", "bar baz", 7); | 490 | "_foo", "bar baz", 7); |
451 | GNUNET_ENV_environment_add (env, GNUNET_ENV_OP_ASSIGN, | 491 | GNUNET_ENV_environment_add (env, GNUNET_ENV_OP_ASSIGN, |
452 | "_foo_bar", "foo bar baz", 11); | 492 | "_foo_bar", "foo bar baz", 11); |
453 | struct GNUNET_MessageHeader * | 493 | struct GNUNET_PSYC_Message * |
454 | join_msg = GNUNET_PSYC_message_create ("_request_join", env, "some data", 9); | 494 | join_msg = GNUNET_PSYC_message_create ("_request_join", env, "some data", 9); |
455 | 495 | ||
456 | slv = GNUNET_PSYC_slave_join (cfg, &channel_pub_key, slave_key, &origin, | 496 | slv = GNUNET_PSYC_slave_join (cfg, &channel_pub_key, slave_key, &origin, 0, NULL, |
457 | 0, NULL, &slave_message_cb, | 497 | &slave_message_cb, &slave_message_part_cb, |
458 | &slave_connect_cb, &join_decision_cb, NULL, | 498 | &slave_connect_cb, &join_decision_cb, NULL, |
459 | join_msg); | 499 | join_msg); |
460 | GNUNET_ENV_environment_destroy (env); | 500 | GNUNET_ENV_environment_destroy (env); |
@@ -551,7 +591,8 @@ run (void *cls, | |||
551 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Starting master.\n"); | 591 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Starting master.\n"); |
552 | mst = GNUNET_PSYC_master_start (cfg, channel_key, GNUNET_PSYC_CHANNEL_PRIVATE, | 592 | mst = GNUNET_PSYC_master_start (cfg, channel_key, GNUNET_PSYC_CHANNEL_PRIVATE, |
553 | &master_start_cb, &join_request_cb, | 593 | &master_start_cb, &join_request_cb, |
554 | &master_message_cb, NULL); | 594 | &master_message_cb, &master_message_part_cb, |
595 | NULL); | ||
555 | } | 596 | } |
556 | 597 | ||
557 | 598 | ||
diff --git a/src/social/Makefile.am b/src/social/Makefile.am index 04184dbc6..02b1bf823 100644 --- a/src/social/Makefile.am +++ b/src/social/Makefile.am | |||
@@ -24,6 +24,11 @@ libgnunetsocial_la_SOURCES = \ | |||
24 | libgnunetsocial_la_LIBADD = \ | 24 | libgnunetsocial_la_LIBADD = \ |
25 | $(top_builddir)/src/util/libgnunetutil.la \ | 25 | $(top_builddir)/src/util/libgnunetutil.la \ |
26 | $(top_builddir)/src/env/libgnunetenv.la \ | 26 | $(top_builddir)/src/env/libgnunetenv.la \ |
27 | $(top_builddir)/src/psyc/libgnunetpsycutil.la \ | ||
28 | $(top_builddir)/src/core/libgnunetcore.la \ | ||
29 | $(top_builddir)/src/identity/libgnunetidentity.la \ | ||
30 | $(top_builddir)/src/gns/libgnunetgns.la \ | ||
31 | $(top_builddir)/src/namestore/libgnunetnamestore.la \ | ||
27 | $(GN_LIBINTL) $(XLIB) | 32 | $(GN_LIBINTL) $(XLIB) |
28 | libgnunetsocial_la_LDFLAGS = \ | 33 | libgnunetsocial_la_LDFLAGS = \ |
29 | $(GN_LIB_LDFLAGS) $(WINFLAGS) \ | 34 | $(GN_LIB_LDFLAGS) $(WINFLAGS) \ |
diff --git a/src/social/gnunet-service-social.c b/src/social/gnunet-service-social.c index ab67bedd6..90d12200d 100644 --- a/src/social/gnunet-service-social.c +++ b/src/social/gnunet-service-social.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include "gnunet_protocols.h" | 32 | #include "gnunet_protocols.h" |
33 | #include "gnunet_statistics_service.h" | 33 | #include "gnunet_statistics_service.h" |
34 | #include "gnunet_psyc_service.h" | 34 | #include "gnunet_psyc_service.h" |
35 | #include "gnunet_psyc_util_lib.h" | ||
35 | #include "gnunet_social_service.h" | 36 | #include "gnunet_social_service.h" |
36 | #include "social.h" | 37 | #include "social.h" |
37 | 38 | ||
@@ -71,41 +72,56 @@ static struct GNUNET_CONTAINER_MultiHashMap *place_guests; | |||
71 | 72 | ||
72 | 73 | ||
73 | /** | 74 | /** |
74 | * Message in the transmission queue. | 75 | * Message fragment transmission queue. |
75 | */ | 76 | */ |
76 | struct TransmitMessage | 77 | struct FragmentTransmitQueue |
77 | { | 78 | { |
78 | struct TransmitMessage *prev; | 79 | struct FragmentTransmitQueue *prev; |
79 | struct TransmitMessage *next; | 80 | struct FragmentTransmitQueue *next; |
80 | 81 | ||
81 | struct GNUNET_SERVER_Client *client; | 82 | struct GNUNET_SERVER_Client *client; |
82 | 83 | ||
83 | /** | 84 | /** |
84 | * ID assigned to the message. | 85 | * Pointer to the next message part inside the data after this struct. |
85 | */ | 86 | */ |
86 | uint64_t id; | 87 | struct GNUNET_MessageHeader *next_part; |
87 | 88 | ||
88 | /** | 89 | /** |
89 | * Size of @a buf | 90 | * Size of message. |
90 | */ | 91 | */ |
91 | uint16_t size; | 92 | uint16_t size; |
92 | 93 | ||
93 | /** | 94 | /** |
94 | * @see enum MessageState | 95 | * @see enum GNUNET_PSYC_MessageState |
95 | */ | 96 | */ |
96 | uint8_t state; | 97 | uint8_t state; |
97 | 98 | ||
98 | /* Followed by message */ | 99 | /* Followed by one or more message parts. */ |
99 | }; | 100 | }; |
100 | 101 | ||
101 | 102 | ||
102 | /** | 103 | /** |
104 | * Message transmission queue. | ||
105 | */ | ||
106 | struct MessageTransmitQueue | ||
107 | { | ||
108 | struct MessageTransmitQueue *prev; | ||
109 | struct MessageTransmitQueue *next; | ||
110 | |||
111 | struct FragmentTransmitQueue *frags_head; | ||
112 | struct FragmentTransmitQueue *frags_tail; | ||
113 | |||
114 | struct GNUNET_SERVER_Client *client; | ||
115 | }; | ||
116 | |||
117 | /** | ||
103 | * List of connected clients. | 118 | * List of connected clients. |
104 | */ | 119 | */ |
105 | struct ClientList | 120 | struct ClientListItem |
106 | { | 121 | { |
107 | struct ClientList *prev; | 122 | struct ClientListItem *prev; |
108 | struct ClientList *next; | 123 | struct ClientListItem *next; |
124 | |||
109 | struct GNUNET_SERVER_Client *client; | 125 | struct GNUNET_SERVER_Client *client; |
110 | }; | 126 | }; |
111 | 127 | ||
@@ -115,11 +131,11 @@ struct ClientList | |||
115 | */ | 131 | */ |
116 | struct Place | 132 | struct Place |
117 | { | 133 | { |
118 | struct ClientList *clients_head; | 134 | struct ClientListItem *clients_head; |
119 | struct ClientList *clients_tail; | 135 | struct ClientListItem *clients_tail; |
120 | 136 | ||
121 | struct TransmitMessage *tmit_head; | 137 | struct MessageTransmitQueue *tmit_msgs_head; |
122 | struct TransmitMessage *tmit_tail; | 138 | struct MessageTransmitQueue *tmit_msgs_tail; |
123 | 139 | ||
124 | /** | 140 | /** |
125 | * Public key of the channel. | 141 | * Public key of the channel. |
@@ -132,9 +148,27 @@ struct Place | |||
132 | struct GNUNET_HashCode pub_key_hash; | 148 | struct GNUNET_HashCode pub_key_hash; |
133 | 149 | ||
134 | /** | 150 | /** |
151 | * Last message ID received for the place. | ||
152 | * 0 if there is no such message. | ||
153 | */ | ||
154 | uint64_t max_message_id; | ||
155 | |||
156 | /** | ||
135 | * Is this a host (#GNUNET_YES), or guest (#GNUNET_NO)? | 157 | * Is this a host (#GNUNET_YES), or guest (#GNUNET_NO)? |
136 | */ | 158 | */ |
137 | uint8_t is_host; | 159 | uint8_t is_host; |
160 | |||
161 | /** | ||
162 | * Is this place ready to receive messages from client? | ||
163 | * #GNUNET_YES or #GNUNET_NO | ||
164 | */ | ||
165 | uint8_t is_ready; | ||
166 | |||
167 | /** | ||
168 | * Is the client disconnected? | ||
169 | * #GNUNET_YES or #GNUNET_NO | ||
170 | */ | ||
171 | uint8_t is_disconnected; | ||
138 | }; | 172 | }; |
139 | 173 | ||
140 | 174 | ||
@@ -146,7 +180,7 @@ struct Host | |||
146 | /** | 180 | /** |
147 | * Place struct common for Host and Guest | 181 | * Place struct common for Host and Guest |
148 | */ | 182 | */ |
149 | struct Place pl; | 183 | struct Place plc; |
150 | 184 | ||
151 | /** | 185 | /** |
152 | * Private key of the channel. | 186 | * Private key of the channel. |
@@ -184,17 +218,17 @@ struct Guest | |||
184 | /** | 218 | /** |
185 | * Place struct common for Host and Guest. | 219 | * Place struct common for Host and Guest. |
186 | */ | 220 | */ |
187 | struct Place pl; | 221 | struct Place plc; |
188 | 222 | ||
189 | /** | 223 | /** |
190 | * Private key of the slave. | 224 | * Private key of the slave. |
191 | */ | 225 | */ |
192 | struct GNUNET_CRYPTO_EddsaPrivateKey priv_key; | 226 | struct GNUNET_CRYPTO_EcdsaPrivateKey priv_key; |
193 | 227 | ||
194 | /** | 228 | /** |
195 | * Public key of the slave. | 229 | * Public key of the slave. |
196 | */ | 230 | */ |
197 | struct GNUNET_CRYPTO_EddsaPublicKey pub_key; | 231 | struct GNUNET_CRYPTO_EcdsaPublicKey pub_key; |
198 | 232 | ||
199 | /** | 233 | /** |
200 | * Hash of @a pub_key. | 234 | * Hash of @a pub_key. |
@@ -230,11 +264,32 @@ struct Guest | |||
230 | * Join request to be transmitted to the master on join. | 264 | * Join request to be transmitted to the master on join. |
231 | */ | 265 | */ |
232 | struct GNUNET_MessageHeader *join_req; | 266 | struct GNUNET_MessageHeader *join_req; |
267 | |||
268 | /** | ||
269 | * Join decision received from PSYC. | ||
270 | */ | ||
271 | struct GNUNET_PSYC_JoinDecisionMessage *join_dcsn; | ||
272 | |||
273 | }; | ||
274 | |||
275 | |||
276 | struct Client | ||
277 | { | ||
278 | /** | ||
279 | * Place where the client entered. | ||
280 | */ | ||
281 | struct Place *plc; | ||
282 | |||
283 | /** | ||
284 | * Message queue for the message currently being transmitted | ||
285 | * by this client. | ||
286 | */ | ||
287 | struct MessageTransmitQueue *tmit_msg; | ||
233 | }; | 288 | }; |
234 | 289 | ||
235 | 290 | ||
236 | static inline void | 291 | static int |
237 | transmit_message (struct Place *pl); | 292 | psyc_transmit_message (struct Place *plc); |
238 | 293 | ||
239 | 294 | ||
240 | /** | 295 | /** |
@@ -265,12 +320,12 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
265 | static void | 320 | static void |
266 | cleanup_host (struct Host *hst) | 321 | cleanup_host (struct Host *hst) |
267 | { | 322 | { |
268 | struct Place *pl = &hst->pl; | 323 | struct Place *plc = &hst->plc; |
269 | 324 | ||
270 | if (NULL != hst->master) | 325 | if (NULL != hst->master) |
271 | GNUNET_PSYC_master_stop (hst->master); | 326 | GNUNET_PSYC_master_stop (hst->master, GNUNET_NO, NULL, NULL); // FIXME |
272 | GNUNET_CONTAINER_multihashmap_destroy (hst->join_reqs); | 327 | GNUNET_CONTAINER_multihashmap_destroy (hst->join_reqs); |
273 | GNUNET_CONTAINER_multihashmap_remove (hosts, &pl->pub_key_hash, pl); | 328 | GNUNET_CONTAINER_multihashmap_remove (hosts, &plc->pub_key_hash, plc); |
274 | } | 329 | } |
275 | 330 | ||
276 | 331 | ||
@@ -280,28 +335,28 @@ cleanup_host (struct Host *hst) | |||
280 | static void | 335 | static void |
281 | cleanup_guest (struct Guest *gst) | 336 | cleanup_guest (struct Guest *gst) |
282 | { | 337 | { |
283 | struct Place *pl = &gst->pl; | 338 | struct Place *plc = &gst->plc; |
284 | struct GNUNET_CONTAINER_MultiHashMap * | 339 | struct GNUNET_CONTAINER_MultiHashMap * |
285 | pl_gst = GNUNET_CONTAINER_multihashmap_get (place_guests, | 340 | plc_gst = GNUNET_CONTAINER_multihashmap_get (place_guests, |
286 | &pl->pub_key_hash); | 341 | &plc->pub_key_hash); |
287 | GNUNET_assert (NULL != pl_gst); | 342 | GNUNET_assert (NULL != plc_gst); |
288 | GNUNET_CONTAINER_multihashmap_remove (pl_gst, &gst->pub_key_hash, gst); | 343 | GNUNET_CONTAINER_multihashmap_remove (plc_gst, &gst->pub_key_hash, gst); |
289 | 344 | ||
290 | if (0 == GNUNET_CONTAINER_multihashmap_size (pl_gst)) | 345 | if (0 == GNUNET_CONTAINER_multihashmap_size (plc_gst)) |
291 | { | 346 | { |
292 | GNUNET_CONTAINER_multihashmap_remove (place_guests, &pl->pub_key_hash, | 347 | GNUNET_CONTAINER_multihashmap_remove (place_guests, &plc->pub_key_hash, |
293 | pl_gst); | 348 | plc_gst); |
294 | GNUNET_CONTAINER_multihashmap_destroy (pl_gst); | 349 | GNUNET_CONTAINER_multihashmap_destroy (plc_gst); |
295 | } | 350 | } |
296 | GNUNET_CONTAINER_multihashmap_remove (guests, &pl->pub_key_hash, gst); | 351 | GNUNET_CONTAINER_multihashmap_remove (guests, &plc->pub_key_hash, gst); |
297 | 352 | ||
298 | if (NULL != gst->join_req) | 353 | if (NULL != gst->join_req) |
299 | GNUNET_free (gst->join_req); | 354 | GNUNET_free (gst->join_req); |
300 | if (NULL != gst->relays) | 355 | if (NULL != gst->relays) |
301 | GNUNET_free (gst->relays); | 356 | GNUNET_free (gst->relays); |
302 | if (NULL != gst->slave) | 357 | if (NULL != gst->slave) |
303 | GNUNET_PSYC_slave_part (gst->slave); | 358 | GNUNET_PSYC_slave_part (gst->slave, GNUNET_NO, NULL, NULL); // FIXME |
304 | GNUNET_CONTAINER_multihashmap_remove (guests, &pl->pub_key_hash, pl); | 359 | GNUNET_CONTAINER_multihashmap_remove (guests, &plc->pub_key_hash, plc); |
305 | } | 360 | } |
306 | 361 | ||
307 | 362 | ||
@@ -309,12 +364,23 @@ cleanup_guest (struct Guest *gst) | |||
309 | * Clean up place data structures after a client disconnected. | 364 | * Clean up place data structures after a client disconnected. |
310 | */ | 365 | */ |
311 | static void | 366 | static void |
312 | cleanup_place (struct Place *pl) | 367 | cleanup_place (struct Place *plc) |
313 | { | 368 | { |
314 | (GNUNET_YES == pl->is_host) | 369 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
315 | ? cleanup_host ((struct Host *) pl) | 370 | "%p Cleaning up place %s\n", |
316 | : cleanup_guest ((struct Guest *) pl); | 371 | plc, GNUNET_h2s (&plc->pub_key_hash)); |
317 | GNUNET_free (pl); | 372 | |
373 | (GNUNET_YES == plc->is_host) | ||
374 | ? cleanup_host ((struct Host *) plc) | ||
375 | : cleanup_guest ((struct Guest *) plc); | ||
376 | GNUNET_free (plc); | ||
377 | } | ||
378 | |||
379 | |||
380 | static void | ||
381 | schedule_cleanup_place (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
382 | { | ||
383 | cleanup_place (cls); | ||
318 | } | 384 | } |
319 | 385 | ||
320 | 386 | ||
@@ -331,76 +397,1073 @@ client_disconnect (void *cls, struct GNUNET_SERVER_Client *client) | |||
331 | if (NULL == client) | 397 | if (NULL == client) |
332 | return; | 398 | return; |
333 | 399 | ||
334 | struct Place * | 400 | struct Client * |
335 | pl = GNUNET_SERVER_client_get_user_context (client, struct Place); | 401 | ctx = GNUNET_SERVER_client_get_user_context (client, struct Client); |
336 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 402 | if (NULL == ctx) |
337 | "%p Client (%s) disconnected from place %s\n", | ||
338 | pl, (GNUNET_YES == pl->is_host) ? "host" : "guest", | ||
339 | GNUNET_h2s (&pl->pub_key_hash)); | ||
340 | |||
341 | if (NULL == pl) | ||
342 | { | 403 | { |
343 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 404 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
344 | "%p User context is NULL in client_disconnect()\n", pl); | 405 | "%p User context is NULL in client_disconnect()\n", ctx); |
345 | GNUNET_break (0); | 406 | GNUNET_break (0); |
346 | return; | 407 | return; |
347 | } | 408 | } |
348 | 409 | ||
349 | struct ClientList *cl = pl->clients_head; | 410 | struct Place *plc = ctx->plc; |
350 | while (NULL != cl) | 411 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
412 | "%p Client (%s) disconnected from place %s\n", | ||
413 | plc, (GNUNET_YES == plc->is_host) ? "host" : "guest", | ||
414 | GNUNET_h2s (&plc->pub_key_hash)); | ||
415 | |||
416 | struct ClientListItem *cli = plc->clients_head; | ||
417 | while (NULL != cli) | ||
351 | { | 418 | { |
352 | if (cl->client == client) | 419 | if (cli->client == client) |
353 | { | 420 | { |
354 | GNUNET_CONTAINER_DLL_remove (pl->clients_head, pl->clients_tail, cl); | 421 | GNUNET_CONTAINER_DLL_remove (plc->clients_head, plc->clients_tail, cli); |
355 | GNUNET_free (cl); | 422 | GNUNET_free (cli); |
356 | break; | 423 | break; |
357 | } | 424 | } |
358 | cl = cl->next; | 425 | cli = cli->next; |
359 | } | 426 | } |
360 | 427 | ||
361 | if (NULL == pl->clients_head) | 428 | if (NULL == plc->clients_head) |
362 | { /* Last client disconnected. */ | 429 | { /* Last client disconnected. */ |
363 | if (NULL != pl->tmit_head) | 430 | if (GNUNET_YES != plc->is_disconnected) |
364 | { /* Send pending messages to PSYC before cleanup. */ | 431 | { |
365 | //FIXME: transmit_message (pl); | 432 | plc->is_disconnected = GNUNET_YES; |
433 | if (NULL != plc->tmit_msgs_head) | ||
434 | { /* Send pending messages to PSYC before cleanup. */ | ||
435 | psyc_transmit_message (plc); | ||
436 | } | ||
437 | else | ||
438 | { | ||
439 | cleanup_place (plc); | ||
440 | } | ||
366 | } | 441 | } |
367 | else | 442 | } |
443 | } | ||
444 | |||
445 | |||
446 | /** | ||
447 | * Send message to all clients connected to the channel. | ||
448 | */ | ||
449 | static void | ||
450 | client_send_msg (const struct Place *plc, | ||
451 | const struct GNUNET_MessageHeader *msg) | ||
452 | { | ||
453 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
454 | "%p Sending message to clients.\n", plc); | ||
455 | |||
456 | struct ClientListItem *cli = plc->clients_head; | ||
457 | while (NULL != cli) | ||
458 | { | ||
459 | GNUNET_SERVER_notification_context_add (nc, cli->client); | ||
460 | GNUNET_SERVER_notification_context_unicast (nc, cli->client, msg, GNUNET_NO); | ||
461 | cli = cli->next; | ||
462 | } | ||
463 | } | ||
464 | |||
465 | |||
466 | /** | ||
467 | * Called after a PSYC master is started. | ||
468 | */ | ||
469 | static void | ||
470 | psyc_master_started (void *cls, uint64_t max_message_id) | ||
471 | { | ||
472 | struct Host *hst = cls; | ||
473 | struct Place *plc = &hst->plc; | ||
474 | plc->max_message_id = max_message_id; | ||
475 | plc->is_ready = GNUNET_YES; | ||
476 | |||
477 | struct CountersResult res; | ||
478 | res.header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER_ACK); | ||
479 | res.header.size = htons (sizeof (res)); | ||
480 | res.result_code = htonl (GNUNET_OK); | ||
481 | res.max_message_id = GNUNET_htonll (plc->max_message_id); | ||
482 | |||
483 | client_send_msg (plc, &res.header); | ||
484 | } | ||
485 | |||
486 | |||
487 | /** | ||
488 | * Called when a PSYC master receives a join request. | ||
489 | */ | ||
490 | static void | ||
491 | psyc_recv_join_request (void *cls, | ||
492 | const struct GNUNET_PSYC_JoinRequestMessage *req, | ||
493 | const struct GNUNET_CRYPTO_EcdsaPublicKey *slave_key, | ||
494 | const struct GNUNET_PSYC_Message *join_msg, | ||
495 | struct GNUNET_PSYC_JoinHandle *jh) | ||
496 | { | ||
497 | struct Host *hst = cls; | ||
498 | struct GNUNET_HashCode slave_key_hash; | ||
499 | GNUNET_CRYPTO_hash (slave_key, sizeof (*slave_key), &slave_key_hash); | ||
500 | GNUNET_CONTAINER_multihashmap_put (hst->join_reqs, &slave_key_hash, jh, | ||
501 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
502 | client_send_msg (&hst->plc, &req->header); | ||
503 | } | ||
504 | |||
505 | |||
506 | /** | ||
507 | * Called after a PSYC slave is connected. | ||
508 | */ | ||
509 | static void | ||
510 | psyc_slave_connected (void *cls, uint64_t max_message_id) | ||
511 | { | ||
512 | struct Guest *gst = cls; | ||
513 | struct Place *plc = &gst->plc; | ||
514 | plc->max_message_id = max_message_id; | ||
515 | plc->is_ready = GNUNET_YES; | ||
516 | |||
517 | struct CountersResult res; | ||
518 | res.header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER_ACK); | ||
519 | res.header.size = htons (sizeof (res)); | ||
520 | res.result_code = htonl (GNUNET_OK); | ||
521 | res.max_message_id = GNUNET_htonll (plc->max_message_id); | ||
522 | |||
523 | client_send_msg (plc, &res.header); | ||
524 | } | ||
525 | |||
526 | |||
527 | /** | ||
528 | * Called when a PSYC slave receives a join decision. | ||
529 | */ | ||
530 | static void | ||
531 | psyc_recv_join_dcsn (void *cls, | ||
532 | const struct GNUNET_PSYC_JoinDecisionMessage *dcsn, | ||
533 | int is_admitted, | ||
534 | const struct GNUNET_PSYC_Message *join_msg) | ||
535 | { | ||
536 | struct Guest *gst = cls; | ||
537 | client_send_msg (&gst->plc, &dcsn->header); | ||
538 | } | ||
539 | |||
540 | |||
541 | /** | ||
542 | * Called when a PSYC master or slave receives a message. | ||
543 | */ | ||
544 | static void | ||
545 | psyc_recv_message (void *cls, | ||
546 | uint64_t message_id, | ||
547 | uint32_t flags, | ||
548 | const struct GNUNET_PSYC_MessageHeader *msg) | ||
549 | { | ||
550 | struct Place *plc = cls; | ||
551 | client_send_msg (plc, &msg->header); | ||
552 | |||
553 | /* FIXME: further processing */ | ||
554 | } | ||
555 | |||
556 | |||
557 | /** | ||
558 | * Initialize place data structure. | ||
559 | */ | ||
560 | static void | ||
561 | place_init (struct Place *plc) | ||
562 | { | ||
563 | |||
564 | } | ||
565 | |||
566 | |||
567 | /** | ||
568 | * Handle a connecting client entering a place as host. | ||
569 | */ | ||
570 | static void | ||
571 | client_recv_host_enter (void *cls, struct GNUNET_SERVER_Client *client, | ||
572 | const struct GNUNET_MessageHeader *msg) | ||
573 | { | ||
574 | const struct HostEnterRequest *req | ||
575 | = (const struct HostEnterRequest *) msg; | ||
576 | |||
577 | struct GNUNET_CRYPTO_EddsaPublicKey pub_key; | ||
578 | struct GNUNET_HashCode pub_key_hash; | ||
579 | |||
580 | GNUNET_CRYPTO_eddsa_key_get_public (&req->place_key, &pub_key); | ||
581 | GNUNET_CRYPTO_hash (&pub_key, sizeof (pub_key), &pub_key_hash); | ||
582 | |||
583 | struct Host * | ||
584 | hst = GNUNET_CONTAINER_multihashmap_get (hosts, &pub_key_hash); | ||
585 | struct Place *plc; | ||
586 | |||
587 | if (NULL == hst) | ||
588 | { | ||
589 | hst = GNUNET_new (struct Host); | ||
590 | hst->policy = ntohl (req->policy); | ||
591 | hst->priv_key = req->place_key; | ||
592 | hst->join_reqs = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); | ||
593 | |||
594 | plc = &hst->plc; | ||
595 | plc->is_host = GNUNET_YES; | ||
596 | plc->pub_key = pub_key; | ||
597 | plc->pub_key_hash = pub_key_hash; | ||
598 | place_init (plc); | ||
599 | |||
600 | GNUNET_CONTAINER_multihashmap_put (hosts, &plc->pub_key_hash, plc, | ||
601 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
602 | hst->master = GNUNET_PSYC_master_start (cfg, &hst->priv_key, hst->policy, | ||
603 | &psyc_master_started, | ||
604 | &psyc_recv_join_request, | ||
605 | &psyc_recv_message, NULL, hst); | ||
606 | } | ||
607 | else | ||
608 | { | ||
609 | plc = &hst->plc; | ||
610 | |||
611 | struct CountersResult res; | ||
612 | res.header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER_ACK); | ||
613 | res.header.size = htons (sizeof (res)); | ||
614 | res.result_code = htonl (GNUNET_OK); | ||
615 | res.max_message_id = GNUNET_htonll (plc->max_message_id); | ||
616 | |||
617 | GNUNET_SERVER_notification_context_add (nc, client); | ||
618 | GNUNET_SERVER_notification_context_unicast (nc, client, &res.header, | ||
619 | GNUNET_NO); | ||
620 | } | ||
621 | |||
622 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
623 | "%p Client connected as host to place %s.\n", | ||
624 | hst, GNUNET_h2s (&plc->pub_key_hash)); | ||
625 | |||
626 | struct ClientListItem *cli = GNUNET_new (struct ClientListItem); | ||
627 | cli->client = client; | ||
628 | GNUNET_CONTAINER_DLL_insert (plc->clients_head, plc->clients_tail, cli); | ||
629 | |||
630 | struct Client *ctx = GNUNET_new (struct Client); | ||
631 | ctx->plc = plc; | ||
632 | GNUNET_SERVER_client_set_user_context (client, ctx); | ||
633 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
634 | } | ||
635 | |||
636 | |||
637 | /** | ||
638 | * Handle a connecting client entering a place as guest. | ||
639 | */ | ||
640 | static void | ||
641 | client_recv_guest_enter (void *cls, struct GNUNET_SERVER_Client *client, | ||
642 | const struct GNUNET_MessageHeader *msg) | ||
643 | { | ||
644 | const struct GuestEnterRequest *req | ||
645 | = (const struct GuestEnterRequest *) msg; | ||
646 | uint16_t req_size = ntohs (req->header.size); | ||
647 | |||
648 | struct GNUNET_CRYPTO_EcdsaPublicKey gst_pub_key; | ||
649 | struct GNUNET_HashCode pub_key_hash, gst_pub_key_hash; | ||
650 | |||
651 | GNUNET_CRYPTO_ecdsa_key_get_public (&req->guest_key, &gst_pub_key); | ||
652 | GNUNET_CRYPTO_hash (&gst_pub_key, sizeof (gst_pub_key), &gst_pub_key_hash); | ||
653 | GNUNET_CRYPTO_hash (&req->place_key, sizeof (req->place_key), &pub_key_hash); | ||
654 | |||
655 | struct GNUNET_CONTAINER_MultiHashMap * | ||
656 | plc_gst = GNUNET_CONTAINER_multihashmap_get (place_guests, &pub_key_hash); | ||
657 | struct Guest *gst = NULL; | ||
658 | struct Place *plc; | ||
659 | |||
660 | if (NULL != plc_gst) | ||
661 | { | ||
662 | gst = GNUNET_CONTAINER_multihashmap_get (plc_gst, &gst_pub_key_hash); | ||
663 | } | ||
664 | if (NULL == gst || NULL == gst->slave) | ||
665 | { | ||
666 | gst = GNUNET_new (struct Guest); | ||
667 | gst->priv_key = req->guest_key; | ||
668 | gst->pub_key = gst_pub_key; | ||
669 | gst->pub_key_hash = gst_pub_key_hash; | ||
670 | gst->origin = req->origin; | ||
671 | gst->relay_count = ntohl (req->relay_count); | ||
672 | |||
673 | const struct GNUNET_PeerIdentity * | ||
674 | relays = (const struct GNUNET_PeerIdentity *) &req[1]; | ||
675 | uint16_t relay_size = gst->relay_count * sizeof (*relays); | ||
676 | struct GNUNET_PSYC_Message *join_msg = NULL; | ||
677 | uint16_t join_msg_size = 0; | ||
678 | |||
679 | if (sizeof (*req) + relay_size + sizeof (struct GNUNET_MessageHeader) | ||
680 | <= req_size) | ||
681 | { | ||
682 | join_msg = (struct GNUNET_PSYC_Message *) | ||
683 | (((char *) &req[1]) + relay_size); | ||
684 | join_msg_size = ntohs (join_msg->header.size); | ||
685 | } | ||
686 | if (sizeof (*req) + relay_size + join_msg_size != req_size) | ||
687 | { | ||
688 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
689 | "%u + %u + %u != %u\n", | ||
690 | sizeof (*req), relay_size, join_msg_size, req_size); | ||
691 | GNUNET_break (0); | ||
692 | GNUNET_SERVER_client_disconnect (client); | ||
693 | return; | ||
694 | } | ||
695 | if (0 < gst->relay_count) | ||
696 | { | ||
697 | gst->relays = GNUNET_malloc (relay_size); | ||
698 | memcpy (gst->relays, &req[1], relay_size); | ||
699 | } | ||
700 | |||
701 | plc = &gst->plc; | ||
702 | plc->is_host = GNUNET_NO; | ||
703 | plc->pub_key = req->place_key; | ||
704 | plc->pub_key_hash = pub_key_hash; | ||
705 | place_init (plc); | ||
706 | |||
707 | if (NULL == plc_gst) | ||
708 | { | ||
709 | plc_gst = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES); | ||
710 | GNUNET_CONTAINER_multihashmap_put (place_guests, &plc->pub_key_hash, plc_gst, | ||
711 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
712 | } | ||
713 | GNUNET_CONTAINER_multihashmap_put (plc_gst, &gst->pub_key_hash, plc, | ||
714 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | ||
715 | GNUNET_CONTAINER_multihashmap_put (guests, &plc->pub_key_hash, plc, | ||
716 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
717 | gst->slave | ||
718 | = GNUNET_PSYC_slave_join (cfg, &plc->pub_key, &gst->priv_key, | ||
719 | &gst->origin, gst->relay_count, gst->relays, | ||
720 | &psyc_recv_message, NULL, &psyc_slave_connected, | ||
721 | &psyc_recv_join_dcsn, gst, join_msg); | ||
722 | } | ||
723 | else | ||
724 | { | ||
725 | plc = &gst->plc; | ||
726 | |||
727 | struct CountersResult res; | ||
728 | res.header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER_ACK); | ||
729 | res.header.size = htons (sizeof (res)); | ||
730 | res.result_code = htonl (GNUNET_OK); | ||
731 | res.max_message_id = GNUNET_htonll (plc->max_message_id); | ||
732 | |||
733 | GNUNET_SERVER_notification_context_add (nc, client); | ||
734 | GNUNET_SERVER_notification_context_unicast (nc, client, &res.header, | ||
735 | GNUNET_NO); | ||
736 | if (NULL != gst->join_dcsn) | ||
368 | { | 737 | { |
369 | cleanup_place (pl); | 738 | GNUNET_SERVER_notification_context_add (nc, client); |
739 | GNUNET_SERVER_notification_context_unicast (nc, client, | ||
740 | &gst->join_dcsn->header, | ||
741 | GNUNET_NO); | ||
370 | } | 742 | } |
371 | } | 743 | } |
744 | |||
745 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
746 | "%p Client connected as guest to place %s.\n", | ||
747 | gst, GNUNET_h2s (&plc->pub_key_hash)); | ||
748 | |||
749 | struct ClientListItem *cli = GNUNET_new (struct ClientListItem); | ||
750 | cli->client = client; | ||
751 | GNUNET_CONTAINER_DLL_insert (plc->clients_head, plc->clients_tail, cli); | ||
752 | |||
753 | struct Client *ctx = GNUNET_new (struct Client); | ||
754 | ctx->plc = plc; | ||
755 | GNUNET_SERVER_client_set_user_context (client, ctx); | ||
756 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
372 | } | 757 | } |
373 | 758 | ||
374 | 759 | ||
760 | struct JoinDecisionClosure | ||
761 | { | ||
762 | int32_t is_admitted; | ||
763 | struct GNUNET_PSYC_Message *msg; | ||
764 | }; | ||
765 | |||
766 | |||
767 | /** | ||
768 | * Iterator callback for responding to join requests. | ||
769 | */ | ||
770 | static int | ||
771 | psyc_send_join_decision (void *cls, const struct GNUNET_HashCode *pub_key_hash, | ||
772 | void *value) | ||
773 | { | ||
774 | struct JoinDecisionClosure *jcls = cls; | ||
775 | struct GNUNET_PSYC_JoinHandle *jh = value; | ||
776 | // FIXME: add relays | ||
777 | GNUNET_PSYC_join_decision (jh, jcls->is_admitted, 0, NULL, jcls->msg); | ||
778 | return GNUNET_YES; | ||
779 | } | ||
780 | |||
781 | |||
782 | /** | ||
783 | * Handle an entry decision from a host client. | ||
784 | */ | ||
375 | static void | 785 | static void |
376 | client_home_enter (void *cls, struct GNUNET_SERVER_Client *client, | 786 | client_recv_join_decision (void *cls, struct GNUNET_SERVER_Client *client, |
377 | const struct GNUNET_MessageHeader *msg) | 787 | const struct GNUNET_MessageHeader *msg) |
378 | { | 788 | { |
789 | struct Client * | ||
790 | ctx = GNUNET_SERVER_client_get_user_context (client, struct Client); | ||
791 | GNUNET_assert (NULL != ctx); | ||
792 | struct Place *plc = ctx->plc; | ||
793 | GNUNET_assert (GNUNET_YES == plc->is_host); | ||
794 | struct Host *hst = (struct Host *) plc; | ||
795 | |||
796 | struct GNUNET_PSYC_JoinDecisionMessage * | ||
797 | dcsn = (struct GNUNET_PSYC_JoinDecisionMessage *) msg; | ||
798 | struct JoinDecisionClosure jcls; | ||
799 | jcls.is_admitted = ntohl (dcsn->is_admitted); | ||
800 | jcls.msg | ||
801 | = (sizeof (*dcsn) + sizeof (*jcls.msg) <= ntohs (msg->size)) | ||
802 | ? (struct GNUNET_PSYC_Message *) &dcsn[1] | ||
803 | : NULL; | ||
804 | |||
805 | struct GNUNET_HashCode slave_key_hash; | ||
806 | GNUNET_CRYPTO_hash (&dcsn->slave_key, sizeof (dcsn->slave_key), | ||
807 | &slave_key_hash); | ||
379 | 808 | ||
809 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
810 | "%p Got join decision (%d) from client for place %s..\n", | ||
811 | hst, jcls.is_admitted, GNUNET_h2s (&plc->pub_key_hash)); | ||
812 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
813 | "%p ..and slave %s.\n", | ||
814 | hst, GNUNET_h2s (&slave_key_hash)); | ||
815 | |||
816 | GNUNET_CONTAINER_multihashmap_get_multiple (hst->join_reqs, &slave_key_hash, | ||
817 | &psyc_send_join_decision, &jcls); | ||
818 | GNUNET_CONTAINER_multihashmap_remove_all (hst->join_reqs, &slave_key_hash); | ||
819 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
380 | } | 820 | } |
381 | 821 | ||
382 | 822 | ||
823 | /** | ||
824 | * Send acknowledgement to a client. | ||
825 | * | ||
826 | * Sent after a message fragment has been passed on to multicast. | ||
827 | * | ||
828 | * @param plc The place struct for the client. | ||
829 | */ | ||
383 | static void | 830 | static void |
384 | client_place_enter (void *cls, struct GNUNET_SERVER_Client *client, | 831 | send_message_ack (struct Place *plc, struct GNUNET_SERVER_Client *client) |
385 | const struct GNUNET_MessageHeader *msg) | 832 | { |
833 | struct GNUNET_MessageHeader res; | ||
834 | res.size = htons (sizeof (res)); | ||
835 | res.type = htons (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_ACK); | ||
836 | |||
837 | GNUNET_SERVER_notification_context_add (nc, client); | ||
838 | GNUNET_SERVER_notification_context_unicast (nc, client, &res, GNUNET_NO); | ||
839 | } | ||
840 | |||
841 | |||
842 | /** | ||
843 | * Proceed to the next message part in the transmission queue. | ||
844 | * | ||
845 | * @param plc | ||
846 | * Place where the transmission is going on. | ||
847 | * @param tmit_msg | ||
848 | * Currently transmitted message. | ||
849 | * @param tmit_frag | ||
850 | * Currently transmitted message fragment. | ||
851 | * | ||
852 | * @return @a tmit_frag, or NULL if reached the end of fragment. | ||
853 | */ | ||
854 | static struct FragmentTransmitQueue * | ||
855 | psyc_transmit_queue_next_part (struct Place *plc, | ||
856 | struct MessageTransmitQueue *tmit_msg, | ||
857 | struct FragmentTransmitQueue *tmit_frag) | ||
858 | { | ||
859 | uint16_t psize = ntohs (tmit_frag->next_part->size); | ||
860 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
861 | "%p psyc_transmit_queue_next_part: %x + %u - %x = %u < %u\n", | ||
862 | plc, tmit_frag->next_part, psize, &tmit_frag[1], | ||
863 | (char *) tmit_frag->next_part + psize - ((char *) &tmit_frag[1]), | ||
864 | tmit_frag->size); | ||
865 | if ((char *) tmit_frag->next_part + psize - ((char *) &tmit_frag[1]) | ||
866 | < tmit_frag->size) | ||
867 | { | ||
868 | tmit_frag->next_part | ||
869 | = (struct GNUNET_MessageHeader *) ((char *) tmit_frag->next_part + psize); | ||
870 | } | ||
871 | else /* Reached end of current fragment. */ | ||
872 | { | ||
873 | if (NULL != tmit_frag->client) | ||
874 | send_message_ack (plc, tmit_frag->client); | ||
875 | GNUNET_CONTAINER_DLL_remove (tmit_msg->frags_head, tmit_msg->frags_tail, tmit_frag); | ||
876 | GNUNET_free (tmit_frag); | ||
877 | tmit_frag = NULL; | ||
878 | } | ||
879 | return tmit_frag; | ||
880 | } | ||
881 | |||
882 | |||
883 | /** | ||
884 | * Proceed to next message in transmission queue. | ||
885 | * | ||
886 | * @param plc | ||
887 | * Place where the transmission is going on. | ||
888 | * @param tmit_msg | ||
889 | * Currently transmitted message. | ||
890 | * | ||
891 | * @return The next message in queue, or NULL if queue is empty. | ||
892 | */ | ||
893 | static struct MessageTransmitQueue * | ||
894 | psyc_transmit_queue_next_msg (struct Place *plc, | ||
895 | struct MessageTransmitQueue *tmit_msg) | ||
896 | { | ||
897 | GNUNET_CONTAINER_DLL_remove (plc->tmit_msgs_head, plc->tmit_msgs_tail, tmit_msg); | ||
898 | GNUNET_free (tmit_msg); | ||
899 | return plc->tmit_msgs_head; | ||
900 | } | ||
901 | |||
902 | |||
903 | /** | ||
904 | * Callback for data transmission to PSYC. | ||
905 | */ | ||
906 | static int | ||
907 | psyc_transmit_notify_data (void *cls, uint16_t *data_size, void *data) | ||
386 | { | 908 | { |
909 | struct Place *plc = cls; | ||
910 | struct MessageTransmitQueue *tmit_msg = plc->tmit_msgs_head; | ||
911 | GNUNET_assert (NULL != tmit_msg); | ||
912 | struct FragmentTransmitQueue *tmit_frag = tmit_msg->frags_head; | ||
913 | if (NULL == tmit_frag) | ||
914 | { /* Rest of the message have not arrived yet, pause transmission */ | ||
915 | *data_size = 0; | ||
916 | return GNUNET_NO; | ||
917 | } | ||
918 | struct GNUNET_MessageHeader *pmsg = tmit_frag->next_part; | ||
919 | if (NULL == pmsg) | ||
920 | { | ||
921 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
922 | "%p psyc_transmit_notify_data: nothing to send.\n", plc); | ||
923 | *data_size = 0; | ||
924 | return GNUNET_NO; | ||
925 | } | ||
387 | 926 | ||
927 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
928 | "%p psyc_transmit_notify_data()\n", plc); | ||
929 | GNUNET_PSYC_log_message (GNUNET_ERROR_TYPE_DEBUG, pmsg); | ||
930 | |||
931 | uint16_t ptype = ntohs (pmsg->type); | ||
932 | uint16_t pdata_size = ntohs (pmsg->size) - sizeof (*pmsg); | ||
933 | int ret; | ||
934 | |||
935 | switch (ptype) | ||
936 | { | ||
937 | case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_DATA: | ||
938 | if (*data_size < pdata_size) | ||
939 | { | ||
940 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
941 | "%p psyc_transmit_notify_data: buffer size too small for data.\n", plc); | ||
942 | *data_size = 0; | ||
943 | return GNUNET_NO; | ||
944 | } | ||
945 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
946 | "%p psyc_transmit_notify_data: sending %u bytes.\n", | ||
947 | plc, pdata_size); | ||
948 | |||
949 | *data_size = pdata_size; | ||
950 | memcpy (data, &pmsg[1], *data_size); | ||
951 | ret = GNUNET_NO; | ||
952 | break; | ||
953 | |||
954 | case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_END: | ||
955 | case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_CANCEL: | ||
956 | *data_size = 0; | ||
957 | ret = GNUNET_YES; | ||
958 | break; | ||
959 | |||
960 | default: | ||
961 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
962 | "%p psyc_transmit_notify_data: unexpected message part of type %u.\n", | ||
963 | plc, ptype); | ||
964 | ret = GNUNET_SYSERR; | ||
965 | } | ||
966 | |||
967 | if (GNUNET_SYSERR == ret) | ||
968 | { | ||
969 | *data_size = 0; | ||
970 | tmit_msg = psyc_transmit_queue_next_msg (plc, tmit_msg); | ||
971 | plc->is_disconnected = GNUNET_YES; | ||
972 | GNUNET_SERVER_client_disconnect (tmit_frag->client); | ||
973 | GNUNET_SCHEDULER_add_now (&schedule_cleanup_place, plc); | ||
974 | return ret; | ||
975 | } | ||
976 | else | ||
977 | { | ||
978 | psyc_transmit_queue_next_part (plc, tmit_msg, tmit_frag); | ||
979 | |||
980 | if (NULL == tmit_msg->frags_head | ||
981 | && GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_END <= ptype) | ||
982 | { /* Reached end of current message. */ | ||
983 | tmit_msg = psyc_transmit_queue_next_msg (plc, tmit_msg); | ||
984 | } | ||
985 | } | ||
986 | |||
987 | if (ret != GNUNET_NO) | ||
988 | { | ||
989 | if (NULL != tmit_msg) | ||
990 | { | ||
991 | psyc_transmit_message (plc); | ||
992 | } | ||
993 | else if (GNUNET_YES == plc->is_disconnected) | ||
994 | { | ||
995 | /* FIXME: handle partial message (when still in_transmit) */ | ||
996 | cleanup_place (plc); | ||
997 | } | ||
998 | } | ||
999 | return ret; | ||
388 | } | 1000 | } |
389 | 1001 | ||
390 | 1002 | ||
1003 | /** | ||
1004 | * Callback for modifier transmission to PSYC. | ||
1005 | */ | ||
1006 | static int | ||
1007 | psyc_transmit_notify_mod (void *cls, uint16_t *data_size, void *data, | ||
1008 | uint8_t *oper, uint32_t *full_value_size) | ||
1009 | { | ||
1010 | struct Place *plc = cls; | ||
1011 | struct MessageTransmitQueue *tmit_msg = plc->tmit_msgs_head; | ||
1012 | GNUNET_assert (NULL != tmit_msg); | ||
1013 | struct FragmentTransmitQueue *tmit_frag = tmit_msg->frags_head; | ||
1014 | if (NULL == tmit_frag) | ||
1015 | { /* Rest of the message have not arrived yet, pause transmission */ | ||
1016 | *data_size = 0; | ||
1017 | return GNUNET_NO; | ||
1018 | } | ||
1019 | struct GNUNET_MessageHeader *pmsg = tmit_frag->next_part; | ||
1020 | if (NULL == pmsg) | ||
1021 | { | ||
1022 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1023 | "%p psyc_transmit_notify_mod: nothing to send.\n", plc); | ||
1024 | *data_size = 0; | ||
1025 | return GNUNET_NO; | ||
1026 | } | ||
1027 | |||
1028 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1029 | "%p psyc_transmit_notify_mod()\n", plc); | ||
1030 | GNUNET_PSYC_log_message (GNUNET_ERROR_TYPE_DEBUG, pmsg); | ||
1031 | |||
1032 | uint16_t ptype = ntohs (pmsg->type); | ||
1033 | int ret; | ||
1034 | |||
1035 | switch (ptype) | ||
1036 | { | ||
1037 | case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MODIFIER: | ||
1038 | { | ||
1039 | if (NULL == oper) | ||
1040 | { | ||
1041 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1042 | "%p psyc_transmit_notify_mod: oper is NULL.\n", plc); | ||
1043 | ret = GNUNET_SYSERR; | ||
1044 | break; | ||
1045 | } | ||
1046 | struct GNUNET_PSYC_MessageModifier * | ||
1047 | pmod = (struct GNUNET_PSYC_MessageModifier *) tmit_frag->next_part; | ||
1048 | uint16_t mod_size = ntohs (pmod->header.size) - sizeof (*pmod); | ||
1049 | |||
1050 | if (*data_size < mod_size) | ||
1051 | { | ||
1052 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1053 | "%p psyc_transmit_notify_mod: buffer size too small for data.\n", plc); | ||
1054 | *data_size = 0; | ||
1055 | return GNUNET_NO; | ||
1056 | } | ||
1057 | |||
1058 | *full_value_size = ntohl (pmod->value_size); | ||
1059 | *oper = pmod->oper; | ||
1060 | *data_size = mod_size; | ||
1061 | memcpy (data, &pmod[1], mod_size); | ||
1062 | ret = GNUNET_NO; | ||
1063 | #if REMOVE // FIXME | ||
1064 | ret = (mod_size - strnlen ((char *) &pmod[1], mod_size) - 1 | ||
1065 | == *full_value_size) | ||
1066 | ? GNUNET_YES | ||
1067 | : GNUNET_NO; | ||
1068 | #endif | ||
1069 | break; | ||
1070 | } | ||
1071 | |||
1072 | case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MOD_CONT: | ||
1073 | { | ||
1074 | if (NULL != oper) | ||
1075 | { | ||
1076 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1077 | "%p psyc_transmit_notify_mod: oper is not NULL.\n", plc); | ||
1078 | ret = GNUNET_SYSERR; | ||
1079 | break; | ||
1080 | } | ||
1081 | uint16_t mod_size = ntohs (pmsg->size) - sizeof (*pmsg); | ||
1082 | if (*data_size < mod_size) | ||
1083 | { | ||
1084 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1085 | "%p psyc_transmit_notify_mod: buffer size too small for data.\n", plc); | ||
1086 | *data_size = 0; | ||
1087 | return GNUNET_NO; | ||
1088 | } | ||
1089 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1090 | "%p psyc_transmit_notify_mod: sending %u bytes.\n", plc, mod_size); | ||
1091 | |||
1092 | *data_size = mod_size; | ||
1093 | memcpy (data, &pmsg[1], *data_size); | ||
1094 | ret = GNUNET_NO; | ||
1095 | break; | ||
1096 | } | ||
1097 | |||
1098 | case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_DATA: | ||
1099 | case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_END: | ||
1100 | case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_CANCEL: | ||
1101 | *data_size = 0; | ||
1102 | ret = GNUNET_YES; | ||
1103 | break; | ||
1104 | |||
1105 | default: | ||
1106 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1107 | "%p psyc_transmit_notify_mod: unexpected message part of type %u.\n", | ||
1108 | plc, ptype); | ||
1109 | ret = GNUNET_SYSERR; | ||
1110 | } | ||
1111 | |||
1112 | if (GNUNET_SYSERR == ret) | ||
1113 | { | ||
1114 | *data_size = 0; | ||
1115 | ret = GNUNET_SYSERR; | ||
1116 | tmit_msg = psyc_transmit_queue_next_msg (plc, tmit_msg); | ||
1117 | plc->is_disconnected = GNUNET_YES; | ||
1118 | GNUNET_SERVER_client_disconnect (tmit_frag->client); | ||
1119 | GNUNET_SCHEDULER_add_now (&schedule_cleanup_place, plc); | ||
1120 | } | ||
1121 | else | ||
1122 | { | ||
1123 | psyc_transmit_queue_next_part (plc, tmit_msg, tmit_frag); | ||
1124 | |||
1125 | if (NULL == tmit_msg->frags_head | ||
1126 | && GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_END <= ptype) | ||
1127 | { /* Reached end of current message. */ | ||
1128 | tmit_msg = psyc_transmit_queue_next_msg (plc, tmit_msg); | ||
1129 | } | ||
1130 | } | ||
1131 | return ret; | ||
1132 | } | ||
1133 | |||
1134 | /** | ||
1135 | * Callback for data transmission from a host to PSYC. | ||
1136 | */ | ||
1137 | static int | ||
1138 | host_transmit_notify_data (void *cls, uint16_t *data_size, void *data) | ||
1139 | { | ||
1140 | int ret = psyc_transmit_notify_data (cls, data_size, data); | ||
1141 | |||
1142 | if (GNUNET_NO != ret) | ||
1143 | { | ||
1144 | struct Host *hst = cls; | ||
1145 | hst->tmit_handle = NULL; | ||
1146 | } | ||
1147 | return ret; | ||
1148 | } | ||
1149 | |||
1150 | |||
1151 | /** | ||
1152 | * Callback for the transmit functions of multicast. | ||
1153 | */ | ||
1154 | static int | ||
1155 | guest_transmit_notify_data (void *cls, uint16_t *data_size, void *data) | ||
1156 | { | ||
1157 | int ret = psyc_transmit_notify_data (cls, data_size, data); | ||
1158 | |||
1159 | if (GNUNET_NO != ret) | ||
1160 | { | ||
1161 | struct Guest *gst = cls; | ||
1162 | gst->tmit_handle = NULL; | ||
1163 | } | ||
1164 | return ret; | ||
1165 | } | ||
1166 | |||
1167 | |||
1168 | /** | ||
1169 | * Callback for modifier transmission from a host to PSYC. | ||
1170 | */ | ||
1171 | static int | ||
1172 | host_transmit_notify_mod (void *cls, uint16_t *data_size, void *data, | ||
1173 | uint8_t *oper, uint32_t *full_value_size) | ||
1174 | { | ||
1175 | int ret = psyc_transmit_notify_mod (cls, data_size, data, | ||
1176 | oper, full_value_size); | ||
1177 | if (GNUNET_SYSERR == ret) | ||
1178 | { | ||
1179 | struct Host *hst = cls; | ||
1180 | hst->tmit_handle = NULL; | ||
1181 | } | ||
1182 | return ret; | ||
1183 | } | ||
1184 | |||
1185 | |||
1186 | /** | ||
1187 | * Callback for modifier transmission from a guest to PSYC. | ||
1188 | */ | ||
1189 | static int | ||
1190 | guest_transmit_notify_mod (void *cls, uint16_t *data_size, void *data, | ||
1191 | uint8_t *oper, uint32_t *full_value_size) | ||
1192 | { | ||
1193 | int ret = psyc_transmit_notify_mod (cls, data_size, data, | ||
1194 | oper, full_value_size); | ||
1195 | if (GNUNET_SYSERR == ret) | ||
1196 | { | ||
1197 | struct Guest *gst = cls; | ||
1198 | gst->tmit_handle = NULL; | ||
1199 | } | ||
1200 | return ret; | ||
1201 | } | ||
1202 | |||
1203 | |||
1204 | /** | ||
1205 | * Get method part of next message from transmission queue. | ||
1206 | * | ||
1207 | * @param tmit_msg | ||
1208 | * Next item in message transmission queue. | ||
1209 | * @param[out] pmeth | ||
1210 | * The message method is returned here. | ||
1211 | * | ||
1212 | * @return #GNUNET_OK on success | ||
1213 | * #GNUNET_NO if there are no more messages in queue. | ||
1214 | * #GNUNET_SYSERR if the next message is malformed. | ||
1215 | */ | ||
1216 | static int | ||
1217 | psyc_transmit_queue_next_method (struct Place *plc, | ||
1218 | struct GNUNET_PSYC_MessageMethod **pmeth) | ||
1219 | { | ||
1220 | struct MessageTransmitQueue *tmit_msg = plc->tmit_msgs_head; | ||
1221 | if (NULL == tmit_msg) | ||
1222 | return GNUNET_NO; | ||
1223 | |||
1224 | struct FragmentTransmitQueue *tmit_frag = tmit_msg->frags_head; | ||
1225 | if (NULL == tmit_frag) | ||
1226 | { | ||
1227 | GNUNET_break (0); | ||
1228 | return GNUNET_NO; | ||
1229 | } | ||
1230 | |||
1231 | struct GNUNET_MessageHeader *pmsg = tmit_frag->next_part; | ||
1232 | if (NULL == pmsg | ||
1233 | || GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_METHOD != ntohs (pmsg->type)) | ||
1234 | { | ||
1235 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1236 | "%p psyc_transmit_queue_next_method: unexpected message part of type %u.\n", | ||
1237 | plc, ntohs (pmsg->type)); | ||
1238 | GNUNET_break (0); | ||
1239 | return GNUNET_SYSERR; | ||
1240 | } | ||
1241 | |||
1242 | uint16_t psize = ntohs (pmsg->size); | ||
1243 | *pmeth = (struct GNUNET_PSYC_MessageMethod *) pmsg; | ||
1244 | |||
1245 | if (psize < sizeof (**pmeth) + 1 || '\0' != *((char *) *pmeth + psize - 1)) | ||
1246 | { | ||
1247 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1248 | "%p psyc_transmit_queue_next_method: invalid method name.\n", | ||
1249 | plc, ntohs (pmsg->type)); | ||
1250 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1251 | "%u <= %u || NUL != %u\n", | ||
1252 | sizeof (**pmeth), psize, *((char *) *pmeth + psize - 1)); | ||
1253 | GNUNET_break (0); | ||
1254 | return GNUNET_SYSERR; | ||
1255 | } | ||
1256 | psyc_transmit_queue_next_part (plc, tmit_msg, tmit_frag); | ||
1257 | return GNUNET_OK; | ||
1258 | } | ||
1259 | |||
1260 | |||
1261 | /** | ||
1262 | * Transmit the next message in queue from the host to the PSYC channel. | ||
1263 | */ | ||
1264 | static int | ||
1265 | psyc_master_transmit_message (struct Host *hst) | ||
1266 | { | ||
1267 | |||
1268 | if (NULL == hst->tmit_handle) | ||
1269 | { | ||
1270 | struct GNUNET_PSYC_MessageMethod *pmeth = NULL; | ||
1271 | int ret = psyc_transmit_queue_next_method (&hst->plc, &pmeth); | ||
1272 | if (GNUNET_OK != ret) | ||
1273 | return ret; | ||
1274 | |||
1275 | hst->tmit_handle | ||
1276 | = GNUNET_PSYC_master_transmit (hst->master, (const char *) &pmeth[1], | ||
1277 | &host_transmit_notify_mod, | ||
1278 | &host_transmit_notify_data, hst, | ||
1279 | pmeth->flags); | ||
1280 | } | ||
1281 | else | ||
1282 | { | ||
1283 | GNUNET_PSYC_master_transmit_resume (hst->tmit_handle); | ||
1284 | } | ||
1285 | return GNUNET_OK; | ||
1286 | } | ||
1287 | |||
1288 | |||
1289 | /** | ||
1290 | * Transmit the next message in queue from a guest to the PSYC channel. | ||
1291 | */ | ||
1292 | static int | ||
1293 | psyc_slave_transmit_message (struct Guest *gst) | ||
1294 | { | ||
1295 | if (NULL == gst->tmit_handle) | ||
1296 | { | ||
1297 | struct GNUNET_PSYC_MessageMethod *pmeth = NULL; | ||
1298 | int ret = psyc_transmit_queue_next_method (&gst->plc, &pmeth); | ||
1299 | if (GNUNET_OK != ret) | ||
1300 | return ret; | ||
1301 | |||
1302 | gst->tmit_handle | ||
1303 | = GNUNET_PSYC_slave_transmit (gst->slave, (const char *) &pmeth[1], | ||
1304 | &guest_transmit_notify_mod, | ||
1305 | &guest_transmit_notify_data, gst, | ||
1306 | pmeth->flags); | ||
1307 | } | ||
1308 | else | ||
1309 | { | ||
1310 | GNUNET_PSYC_slave_transmit_resume (gst->tmit_handle); | ||
1311 | } | ||
1312 | return GNUNET_OK; | ||
1313 | } | ||
1314 | |||
1315 | |||
1316 | /** | ||
1317 | * Transmit a message to PSYC. | ||
1318 | */ | ||
1319 | static int | ||
1320 | psyc_transmit_message (struct Place *plc) | ||
1321 | { | ||
1322 | return | ||
1323 | (plc->is_host) | ||
1324 | ? psyc_master_transmit_message ((struct Host *) plc) | ||
1325 | : psyc_slave_transmit_message ((struct Guest *) plc); | ||
1326 | } | ||
1327 | |||
1328 | |||
1329 | /** | ||
1330 | * Queue message parts for sending to PSYC. | ||
1331 | * | ||
1332 | * @param plc Place to send to. | ||
1333 | * @param client Client the message originates from. | ||
1334 | * @param data_size Size of @a data. | ||
1335 | * @param data Concatenated message parts. | ||
1336 | * @param first_ptype First message part type in @a data. | ||
1337 | * @param last_ptype Last message part type in @a data. | ||
1338 | */ | ||
1339 | static struct MessageTransmitQueue * | ||
1340 | psyc_transmit_queue_message (struct Place *plc, | ||
1341 | struct GNUNET_SERVER_Client *client, | ||
1342 | size_t data_size, | ||
1343 | const void *data, | ||
1344 | uint16_t first_ptype, uint16_t last_ptype, | ||
1345 | struct MessageTransmitQueue *tmit_msg) | ||
1346 | { | ||
1347 | if (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_METHOD == first_ptype) | ||
1348 | { | ||
1349 | tmit_msg = GNUNET_malloc (sizeof (*tmit_msg)); | ||
1350 | GNUNET_CONTAINER_DLL_insert_tail (plc->tmit_msgs_head, plc->tmit_msgs_tail, tmit_msg); | ||
1351 | } | ||
1352 | else if (NULL == tmit_msg) | ||
1353 | { | ||
1354 | return NULL; | ||
1355 | } | ||
1356 | |||
1357 | struct FragmentTransmitQueue * | ||
1358 | tmit_frag = GNUNET_malloc (sizeof (*tmit_frag) + data_size); | ||
1359 | memcpy (&tmit_frag[1], data, data_size); | ||
1360 | tmit_frag->next_part = (struct GNUNET_MessageHeader *) &tmit_frag[1]; | ||
1361 | tmit_frag->client = client; | ||
1362 | tmit_frag->size = data_size; | ||
1363 | |||
1364 | GNUNET_CONTAINER_DLL_insert_tail (tmit_msg->frags_head, tmit_msg->frags_tail, tmit_frag); | ||
1365 | tmit_msg->client = client; | ||
1366 | return tmit_msg; | ||
1367 | } | ||
1368 | |||
1369 | |||
1370 | /** | ||
1371 | * Cancel transmission of current message to PSYC. | ||
1372 | * | ||
1373 | * @param plc Place to send to. | ||
1374 | * @param client Client the message originates from. | ||
1375 | */ | ||
391 | static void | 1376 | static void |
392 | client_join_decision (void *cls, struct GNUNET_SERVER_Client *client, | 1377 | psyc_transmit_cancel (struct Place *plc, struct GNUNET_SERVER_Client *client) |
393 | const struct GNUNET_MessageHeader *msg) | ||
394 | { | 1378 | { |
1379 | uint16_t type = GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_CANCEL; | ||
1380 | |||
1381 | struct GNUNET_MessageHeader msg; | ||
1382 | msg.size = htons (sizeof (msg)); | ||
1383 | msg.type = htons (type); | ||
395 | 1384 | ||
1385 | psyc_transmit_queue_message (plc, client, sizeof (msg), &msg, type, type, NULL); | ||
1386 | psyc_transmit_message (plc); | ||
1387 | |||
1388 | /* FIXME: cleanup */ | ||
396 | } | 1389 | } |
397 | 1390 | ||
398 | 1391 | ||
1392 | /** | ||
1393 | * Handle an incoming message from a client, to be transmitted to the place. | ||
1394 | */ | ||
399 | static void | 1395 | static void |
400 | client_psyc_message (void *cls, struct GNUNET_SERVER_Client *client, | 1396 | client_recv_psyc_message (void *cls, struct GNUNET_SERVER_Client *client, |
401 | const struct GNUNET_MessageHeader *msg) | 1397 | const struct GNUNET_MessageHeader *msg) |
402 | { | 1398 | { |
1399 | struct Client * | ||
1400 | ctx = GNUNET_SERVER_client_get_user_context (client, struct Client); | ||
1401 | GNUNET_assert (NULL != ctx); | ||
1402 | struct Place *plc = ctx->plc; | ||
1403 | int ret = GNUNET_SYSERR; | ||
403 | 1404 | ||
1405 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1406 | "%p Received message from client.\n", plc); | ||
1407 | GNUNET_PSYC_log_message (GNUNET_ERROR_TYPE_DEBUG, msg); | ||
1408 | |||
1409 | if (GNUNET_YES != plc->is_ready) | ||
1410 | { | ||
1411 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1412 | "%p Place is not ready yet, disconnecting client.\n", plc); | ||
1413 | GNUNET_break (0); | ||
1414 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
1415 | return; | ||
1416 | } | ||
1417 | |||
1418 | uint16_t size = ntohs (msg->size); | ||
1419 | uint16_t psize = size - sizeof (*msg); | ||
1420 | if (psize < sizeof (struct GNUNET_MessageHeader) | ||
1421 | || GNUNET_MULTICAST_FRAGMENT_MAX_PAYLOAD < psize) | ||
1422 | { | ||
1423 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1424 | "%p Received message with invalid payload size (%u) from client.\n", | ||
1425 | plc, psize); | ||
1426 | GNUNET_break (0); | ||
1427 | psyc_transmit_cancel (plc, client); | ||
1428 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
1429 | return; | ||
1430 | } | ||
1431 | |||
1432 | uint16_t first_ptype = 0, last_ptype = 0; | ||
1433 | if (GNUNET_SYSERR | ||
1434 | == GNUNET_PSYC_receive_check_parts (psize, (const char *) &msg[1], | ||
1435 | &first_ptype, &last_ptype)) | ||
1436 | { | ||
1437 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1438 | "%p Received invalid message part from client.\n", plc); | ||
1439 | GNUNET_break (0); | ||
1440 | psyc_transmit_cancel (plc, client); | ||
1441 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
1442 | return; | ||
1443 | } | ||
1444 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1445 | "%p Received message with first part type %u and last part type %u.\n", | ||
1446 | plc, first_ptype, last_ptype); | ||
1447 | |||
1448 | ctx->tmit_msg | ||
1449 | = psyc_transmit_queue_message (plc, client, psize, &msg[1], | ||
1450 | first_ptype, last_ptype, ctx->tmit_msg); | ||
1451 | if (NULL != ctx->tmit_msg) | ||
1452 | { | ||
1453 | if (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_END <= last_ptype) | ||
1454 | ctx->tmit_msg = NULL; | ||
1455 | ret = psyc_transmit_message (plc); | ||
1456 | } | ||
1457 | |||
1458 | if (GNUNET_OK != ret) | ||
1459 | { | ||
1460 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1461 | "%p Received invalid message part from client.\n", plc); | ||
1462 | GNUNET_break (0); | ||
1463 | psyc_transmit_cancel (plc, client); | ||
1464 | ret = GNUNET_SYSERR; | ||
1465 | } | ||
1466 | GNUNET_SERVER_receive_done (client, ret); | ||
404 | } | 1467 | } |
405 | 1468 | ||
406 | 1469 | ||
@@ -416,16 +1479,16 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, | |||
416 | const struct GNUNET_CONFIGURATION_Handle *c) | 1479 | const struct GNUNET_CONFIGURATION_Handle *c) |
417 | { | 1480 | { |
418 | static const struct GNUNET_SERVER_MessageHandler handlers[] = { | 1481 | static const struct GNUNET_SERVER_MessageHandler handlers[] = { |
419 | { &client_home_enter, NULL, | 1482 | { &client_recv_host_enter, NULL, |
420 | GNUNET_MESSAGE_TYPE_SOCIAL_HOME_ENTER, 0 }, | 1483 | GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER, 0 }, |
421 | 1484 | ||
422 | { &client_place_enter, NULL, | 1485 | { &client_recv_guest_enter, NULL, |
423 | GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_ENTER, 0 }, | 1486 | GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER, 0 }, |
424 | 1487 | ||
425 | { &client_join_decision, NULL, | 1488 | { &client_recv_join_decision, NULL, |
426 | GNUNET_MESSAGE_TYPE_SOCIAL_JOIN_DECISION, 0 }, | 1489 | GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION, 0 }, |
427 | 1490 | ||
428 | { &client_psyc_message, NULL, | 1491 | { &client_recv_psyc_message, NULL, |
429 | GNUNET_MESSAGE_TYPE_PSYC_MESSAGE, 0 } | 1492 | GNUNET_MESSAGE_TYPE_PSYC_MESSAGE, 0 } |
430 | }; | 1493 | }; |
431 | 1494 | ||
diff --git a/src/social/social.h b/src/social/social.h index 7f854eed8..00edaefd1 100644 --- a/src/social/social.h +++ b/src/social/social.h | |||
@@ -19,7 +19,7 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | /** | 21 | /** |
22 | * @file psyc/psyc.h | 22 | * @file social/social.h |
23 | * @brief Common type definitions for the Social service and API. | 23 | * @brief Common type definitions for the Social service and API. |
24 | * @author Gabor X Toth | 24 | * @author Gabor X Toth |
25 | */ | 25 | */ |
@@ -30,16 +30,99 @@ | |||
30 | #include "platform.h" | 30 | #include "platform.h" |
31 | #include "gnunet_social_service.h" | 31 | #include "gnunet_social_service.h" |
32 | 32 | ||
33 | enum MessageState | ||
34 | { | ||
35 | MSG_STATE_START = 0, | ||
36 | MSG_STATE_HEADER = 1, | ||
37 | MSG_STATE_METHOD = 2, | ||
38 | MSG_STATE_MODIFIER = 3, | ||
39 | MSG_STATE_MOD_CONT = 4, | ||
40 | MSG_STATE_DATA = 5, | ||
41 | MSG_STATE_END = 6, | ||
42 | MSG_STATE_CANCEL = 7, | ||
43 | MSG_STATE_ERROR = 8, | ||
44 | }; | ||
45 | |||
33 | 46 | ||
34 | GNUNET_NETWORK_STRUCT_BEGIN | 47 | GNUNET_NETWORK_STRUCT_BEGIN |
35 | 48 | ||
36 | /**** library -> service ****/ | 49 | /**** library -> service ****/ |
37 | 50 | ||
38 | 51 | ||
52 | struct HostEnterRequest | ||
53 | { | ||
54 | /** | ||
55 | * Type: GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER | ||
56 | */ | ||
57 | struct GNUNET_MessageHeader header; | ||
58 | |||
59 | uint32_t policy GNUNET_PACKED; | ||
60 | |||
61 | struct GNUNET_CRYPTO_EcdsaPrivateKey host_key; | ||
62 | |||
63 | struct GNUNET_CRYPTO_EddsaPrivateKey place_key; | ||
64 | }; | ||
65 | |||
66 | |||
67 | struct GuestEnterRequest | ||
68 | { | ||
69 | /** | ||
70 | * Type: GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER_ADDR | ||
71 | */ | ||
72 | struct GNUNET_MessageHeader header; | ||
73 | |||
74 | uint32_t relay_count GNUNET_PACKED; | ||
75 | |||
76 | struct GNUNET_CRYPTO_EcdsaPrivateKey guest_key; | ||
77 | |||
78 | struct GNUNET_CRYPTO_EddsaPublicKey place_key; | ||
79 | |||
80 | struct GNUNET_PeerIdentity origin; | ||
81 | |||
82 | /* Followed by struct GNUNET_PeerIdentity relays[relay_count] */ | ||
83 | |||
84 | /* Followed by struct GNUNET_MessageHeader join_msg */ | ||
85 | }; | ||
86 | |||
39 | 87 | ||
40 | /**** service -> library ****/ | 88 | /**** service -> library ****/ |
41 | 89 | ||
42 | 90 | ||
91 | struct CountersResult | ||
92 | { | ||
93 | /** | ||
94 | * Type: GNUNET_MESSAGE_TYPE_PSYC_RESULT_COUNTERS | ||
95 | */ | ||
96 | struct GNUNET_MessageHeader header; | ||
97 | |||
98 | /** | ||
99 | * Status code for the operation. | ||
100 | */ | ||
101 | int32_t result_code GNUNET_PACKED; | ||
102 | |||
103 | /** | ||
104 | * Last message ID sent to the channel. | ||
105 | */ | ||
106 | uint64_t max_message_id; | ||
107 | }; | ||
108 | |||
109 | |||
110 | #if REMOVE | ||
111 | struct NymEnterRequest | ||
112 | { | ||
113 | /** | ||
114 | * Type: GNUNET_MESSAGE_TYPE_SOCIAL_NYM_ENTER | ||
115 | */ | ||
116 | struct GNUNET_MessageHeader header; | ||
117 | /** | ||
118 | * Public key of the joining slave. | ||
119 | */ | ||
120 | struct GNUNET_CRYPTO_EcdsaPublicKey nym_key; | ||
121 | |||
122 | /* Followed by struct GNUNET_MessageHeader join_request */ | ||
123 | }; | ||
124 | #endif | ||
125 | |||
43 | 126 | ||
44 | GNUNET_NETWORK_STRUCT_END | 127 | GNUNET_NETWORK_STRUCT_END |
45 | 128 | ||
diff --git a/src/social/social_api.c b/src/social/social_api.c index ee13c7d61..d19f83e89 100644 --- a/src/social/social_api.c +++ b/src/social/social_api.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * This file is part of GNUnet | 2 | * This file is part of GNUnet |
3 | * (C) 2013 Christian Grothoff (and other contributing authors) | 3 | * (C) 2013 Christian Grothoff (and other contributing authors) |
4 | * | 4 | * |
@@ -25,30 +25,93 @@ | |||
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include <inttypes.h> | 27 | #include <inttypes.h> |
28 | #include <string.h> | ||
28 | 29 | ||
29 | #include "platform.h" | 30 | #include "platform.h" |
30 | #include "gnunet_util_lib.h" | 31 | #include "gnunet_util_lib.h" |
31 | #include "gnunet_env_lib.h" | 32 | #include "gnunet_env_lib.h" |
33 | #include "gnunet_core_service.h" | ||
34 | #include "gnunet_identity_service.h" | ||
35 | #include "gnunet_namestore_service.h" | ||
36 | #include "gnunet_gns_service.h" | ||
32 | #include "gnunet_psyc_service.h" | 37 | #include "gnunet_psyc_service.h" |
38 | #include "gnunet_psyc_util_lib.h" | ||
33 | #include "gnunet_social_service.h" | 39 | #include "gnunet_social_service.h" |
34 | #include "social.h" | 40 | #include "social.h" |
35 | 41 | ||
42 | #define LOG(kind,...) GNUNET_log_from (kind, "social-api",__VA_ARGS__) | ||
36 | 43 | ||
37 | /** | ||
38 | * Handle for a pseudonym of another user in the network. | ||
39 | */ | ||
40 | struct GNUNET_SOCIAL_Nym | ||
41 | { | ||
42 | |||
43 | }; | ||
44 | 44 | ||
45 | static struct GNUNET_CORE_Handle *core; | ||
46 | static struct GNUNET_GNS_Handle *gns; | ||
47 | static struct GNUNET_NAMESTORE_Handle *namestore; | ||
48 | static struct GNUNET_PeerIdentity this_peer; | ||
45 | 49 | ||
46 | /** | 50 | /** |
47 | * Handle for a place where social interactions happen. | 51 | * Handle for a place where social interactions happen. |
48 | */ | 52 | */ |
49 | struct GNUNET_SOCIAL_Place | 53 | struct GNUNET_SOCIAL_Place |
50 | { | 54 | { |
51 | 55 | /** | |
56 | * Configuration to use. | ||
57 | */ | ||
58 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
59 | |||
60 | /** | ||
61 | * Client connection to the service. | ||
62 | */ | ||
63 | struct GNUNET_CLIENT_MANAGER_Connection *client; | ||
64 | |||
65 | /** | ||
66 | * Transmission handle; | ||
67 | */ | ||
68 | struct GNUNET_PSYC_TransmitHandle *tmit; | ||
69 | |||
70 | /** | ||
71 | * Receipt handle; | ||
72 | */ | ||
73 | struct GNUNET_PSYC_ReceiveHandle *recv; | ||
74 | |||
75 | /** | ||
76 | * Message to send on reconnect. | ||
77 | */ | ||
78 | struct GNUNET_MessageHeader *connect_msg; | ||
79 | |||
80 | /** | ||
81 | * Slicer for processing incoming methods. | ||
82 | */ | ||
83 | struct GNUNET_SOCIAL_Slicer *slicer; | ||
84 | |||
85 | /** | ||
86 | * Function called after disconnected from the service. | ||
87 | */ | ||
88 | GNUNET_ContinuationCallback disconnect_cb; | ||
89 | |||
90 | /** | ||
91 | * Closure for @a disconnect_cb. | ||
92 | */ | ||
93 | void *disconnect_cls; | ||
94 | |||
95 | /** | ||
96 | * Public key of the place. | ||
97 | */ | ||
98 | struct GNUNET_CRYPTO_EddsaPublicKey pub_key; | ||
99 | |||
100 | /** | ||
101 | * Private key of the ego. | ||
102 | */ | ||
103 | struct GNUNET_CRYPTO_EcdsaPrivateKey ego_key; | ||
104 | |||
105 | /** | ||
106 | * Does this place belong to a host (#GNUNET_YES) or guest (#GNUNET_NO)? | ||
107 | */ | ||
108 | uint8_t is_host; | ||
109 | |||
110 | /** | ||
111 | * Is this place in the process of disconnecting from the service? | ||
112 | * #GNUNET_YES or #GNUNET_NO | ||
113 | */ | ||
114 | uint8_t is_disconnecting; | ||
52 | }; | 115 | }; |
53 | 116 | ||
54 | 117 | ||
@@ -57,7 +120,20 @@ struct GNUNET_SOCIAL_Place | |||
57 | */ | 120 | */ |
58 | struct GNUNET_SOCIAL_Host | 121 | struct GNUNET_SOCIAL_Host |
59 | { | 122 | { |
123 | struct GNUNET_SOCIAL_Place plc; | ||
60 | 124 | ||
125 | struct GNUNET_CRYPTO_EddsaPrivateKey place_key; | ||
126 | |||
127 | GNUNET_SOCIAL_HostEnterCallback enter_cb; | ||
128 | |||
129 | GNUNET_SOCIAL_AnswerDoorCallback answer_door_cb; | ||
130 | |||
131 | GNUNET_SOCIAL_FarewellCallback farewell_cb; | ||
132 | |||
133 | /** | ||
134 | * Closure for callbacks. | ||
135 | */ | ||
136 | void *cb_cls; | ||
61 | }; | 137 | }; |
62 | 138 | ||
63 | 139 | ||
@@ -66,16 +142,91 @@ struct GNUNET_SOCIAL_Host | |||
66 | */ | 142 | */ |
67 | struct GNUNET_SOCIAL_Guest | 143 | struct GNUNET_SOCIAL_Guest |
68 | { | 144 | { |
145 | struct GNUNET_SOCIAL_Place plc; | ||
69 | 146 | ||
147 | GNUNET_SOCIAL_GuestEnterCallback enter_cb; | ||
148 | |||
149 | GNUNET_SOCIAL_EntryDecisionCallback entry_dcsn_cb; | ||
150 | |||
151 | /** | ||
152 | * Closure for callbacks. | ||
153 | */ | ||
154 | void *cb_cls; | ||
70 | }; | 155 | }; |
71 | 156 | ||
72 | 157 | ||
73 | /** | 158 | /** |
74 | * Handle to an implementation of try-and-slice. | 159 | * Handle for a pseudonym of another user in the network. |
160 | */ | ||
161 | struct GNUNET_SOCIAL_Nym | ||
162 | { | ||
163 | struct GNUNET_CRYPTO_EcdsaPublicKey pub_key; | ||
164 | struct GNUNET_HashCode pub_key_hash; | ||
165 | }; | ||
166 | |||
167 | |||
168 | /** | ||
169 | * Hash map of all nyms. | ||
170 | * pub_key_hash -> struct GNUNET_SOCIAL_Nym * | ||
171 | */ | ||
172 | struct GNUNET_CONTAINER_MultiHashMap *nyms; | ||
173 | |||
174 | |||
175 | /** | ||
176 | * Handle for a try-and-slice instance. | ||
75 | */ | 177 | */ |
76 | struct GNUNET_SOCIAL_Slicer | 178 | struct GNUNET_SOCIAL_Slicer |
77 | { | 179 | { |
180 | /** | ||
181 | * Message handlers: method_name -> SlicerCallbacks | ||
182 | */ | ||
183 | struct GNUNET_CONTAINER_MultiHashMap *handlers; | ||
184 | |||
185 | |||
186 | /** | ||
187 | * Currently being processed message part. | ||
188 | */ | ||
189 | const struct GNUNET_MessageHeader *msg; | ||
190 | |||
191 | /** | ||
192 | * ID of currently being received message. | ||
193 | */ | ||
194 | uint64_t message_id; | ||
195 | |||
196 | /** | ||
197 | * Method name of currently being received message. | ||
198 | */ | ||
199 | char *method_name; | ||
200 | |||
201 | /** | ||
202 | * Public key of the nym the current message originates from. | ||
203 | */ | ||
204 | struct GNUNET_CRYPTO_EcdsaPublicKey nym_key; | ||
205 | |||
206 | /** | ||
207 | * Size of @a method_name (including terminating \0). | ||
208 | */ | ||
209 | uint16_t method_name_size; | ||
210 | }; | ||
211 | |||
78 | 212 | ||
213 | /** | ||
214 | * Callbacks for a slicer method handler. | ||
215 | */ | ||
216 | struct SlicerCallbacks | ||
217 | { | ||
218 | GNUNET_SOCIAL_MethodCallback method_cb; | ||
219 | GNUNET_SOCIAL_ModifierCallback modifier_cb; | ||
220 | GNUNET_SOCIAL_DataCallback data_cb; | ||
221 | GNUNET_SOCIAL_EndOfMessageCallback eom_cb; | ||
222 | void *cls; | ||
223 | }; | ||
224 | |||
225 | |||
226 | struct SlicerRemoveClosure | ||
227 | { | ||
228 | struct GNUNET_SOCIAL_Slicer *slicer; | ||
229 | struct SlicerCallbacks rm_cbs; | ||
79 | }; | 230 | }; |
80 | 231 | ||
81 | 232 | ||
@@ -118,6 +269,181 @@ struct GNUNET_SOCIAL_HistoryLesson | |||
118 | }; | 269 | }; |
119 | 270 | ||
120 | 271 | ||
272 | static struct GNUNET_SOCIAL_Nym * | ||
273 | nym_get_or_create (const struct GNUNET_CRYPTO_EcdsaPublicKey *pub_key) | ||
274 | { | ||
275 | struct GNUNET_SOCIAL_Nym *nym = NULL; | ||
276 | struct GNUNET_HashCode pub_key_hash; | ||
277 | |||
278 | if (NULL == pub_key) | ||
279 | return NULL; | ||
280 | |||
281 | GNUNET_CRYPTO_hash (pub_key, sizeof (*pub_key), &pub_key_hash); | ||
282 | |||
283 | if (NULL == nyms) | ||
284 | nyms = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES); | ||
285 | else | ||
286 | nym = GNUNET_CONTAINER_multihashmap_get (nyms, &pub_key_hash); | ||
287 | |||
288 | if (NULL == nym) | ||
289 | { | ||
290 | nym = GNUNET_new (struct GNUNET_SOCIAL_Nym); | ||
291 | nym->pub_key = *pub_key; | ||
292 | nym->pub_key_hash = pub_key_hash; | ||
293 | GNUNET_CONTAINER_multihashmap_put (nyms, &nym->pub_key_hash, nym, | ||
294 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | ||
295 | } | ||
296 | return nym; | ||
297 | } | ||
298 | |||
299 | |||
300 | static void | ||
301 | nym_destroy (struct GNUNET_SOCIAL_Nym *nym) | ||
302 | { | ||
303 | GNUNET_CONTAINER_multihashmap_remove (nyms, &nym->pub_key_hash, nym); | ||
304 | GNUNET_free (nym); | ||
305 | } | ||
306 | |||
307 | |||
308 | /** | ||
309 | * Call a handler for an incoming message part. | ||
310 | * | ||
311 | * @param cls | ||
312 | * @param key | ||
313 | * @param value | ||
314 | * | ||
315 | * @return | ||
316 | */ | ||
317 | int | ||
318 | slicer_handler_notify (void *cls, const struct GNUNET_HashCode *key, | ||
319 | void *value) | ||
320 | { | ||
321 | struct GNUNET_SOCIAL_Slicer *slicer = cls; | ||
322 | const struct GNUNET_MessageHeader *msg = slicer->msg; | ||
323 | struct SlicerCallbacks *cbs = value; | ||
324 | uint16_t ptype = ntohs (msg->type); | ||
325 | |||
326 | switch (ptype) | ||
327 | { | ||
328 | case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_METHOD: | ||
329 | { | ||
330 | if (NULL == cbs->method_cb) | ||
331 | break; | ||
332 | struct GNUNET_PSYC_MessageMethod * | ||
333 | meth = (struct GNUNET_PSYC_MessageMethod *) msg; | ||
334 | cbs->method_cb (cbs->cls, meth, slicer->message_id, | ||
335 | ntohl (meth->flags), | ||
336 | nym_get_or_create (&slicer->nym_key), | ||
337 | slicer->method_name); | ||
338 | break; | ||
339 | } | ||
340 | |||
341 | case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MODIFIER: | ||
342 | { | ||
343 | if (NULL == cbs->modifier_cb) | ||
344 | break; | ||
345 | struct GNUNET_PSYC_MessageModifier * | ||
346 | mod = (struct GNUNET_PSYC_MessageModifier *) msg; | ||
347 | cbs->modifier_cb (cbs->cls, mod, slicer->message_id, | ||
348 | mod->oper, (const char *) &mod[1], | ||
349 | (const void *) &mod[1] + ntohs (mod->name_size), | ||
350 | ntohs (mod->value_size)); | ||
351 | break; | ||
352 | } | ||
353 | |||
354 | case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MOD_CONT: | ||
355 | { | ||
356 | if (NULL == cbs->modifier_cb) | ||
357 | break; | ||
358 | /* FIXME: concatenate until done */ | ||
359 | break; | ||
360 | } | ||
361 | |||
362 | case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_DATA: | ||
363 | { | ||
364 | if (NULL == cbs->data_cb) | ||
365 | break; | ||
366 | uint64_t data_offset = 0; // FIXME | ||
367 | cbs->data_cb (cbs->cls, msg, slicer->message_id, | ||
368 | data_offset, &msg[1], ntohs (msg->size) - sizeof (*msg)); | ||
369 | break; | ||
370 | } | ||
371 | |||
372 | case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_END: | ||
373 | if (NULL == cbs->eom_cb) | ||
374 | break; | ||
375 | cbs->eom_cb (cbs->cls, msg, slicer->message_id, GNUNET_NO); | ||
376 | break; | ||
377 | |||
378 | case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_CANCEL: | ||
379 | if (NULL == cbs->eom_cb) | ||
380 | break; | ||
381 | cbs->eom_cb (cbs->cls, msg, slicer->message_id, GNUNET_YES); | ||
382 | break; | ||
383 | } | ||
384 | return GNUNET_YES; | ||
385 | } | ||
386 | |||
387 | |||
388 | /** | ||
389 | * Process an incoming message part and call matching handlers. | ||
390 | * | ||
391 | * @param cls | ||
392 | * Closure. | ||
393 | * @param message_id | ||
394 | * ID of the message. | ||
395 | * @param flags | ||
396 | * Flags for the message. | ||
397 | * @see enum GNUNET_PSYC_MessageFlags | ||
398 | * @param msg | ||
399 | * The message part. as it arrived from the network. | ||
400 | */ | ||
401 | static void | ||
402 | slicer_message (void *cls, uint64_t message_id, uint64_t fragment_offset, | ||
403 | uint32_t flags, const struct GNUNET_MessageHeader *msg) | ||
404 | { | ||
405 | struct GNUNET_SOCIAL_Slicer *slicer = cls; | ||
406 | uint16_t ptype = ntohs (msg->type); | ||
407 | if (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_METHOD == ptype) | ||
408 | { | ||
409 | struct GNUNET_PSYC_MessageMethod * | ||
410 | meth = (struct GNUNET_PSYC_MessageMethod *) msg; | ||
411 | slicer->method_name_size = ntohs (meth->header.size) - sizeof (*meth); | ||
412 | slicer->method_name = GNUNET_malloc (slicer->method_name_size); | ||
413 | memcpy (slicer->method_name, &meth[1], slicer->method_name_size); | ||
414 | slicer->message_id = message_id; | ||
415 | } | ||
416 | else | ||
417 | { | ||
418 | GNUNET_assert (message_id == slicer->message_id); | ||
419 | } | ||
420 | |||
421 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
422 | "Slicer received message of type %u and size %u, " | ||
423 | "with ID %" PRIu64 " and method %s\n", | ||
424 | ptype, ntohs (msg->size), message_id, slicer->method_name); | ||
425 | |||
426 | slicer->msg = msg; | ||
427 | char *name = GNUNET_malloc (slicer->method_name_size); | ||
428 | memcpy (name, slicer->method_name, slicer->method_name_size); | ||
429 | do | ||
430 | { | ||
431 | struct GNUNET_HashCode key; | ||
432 | uint16_t name_len = strlen (name); | ||
433 | GNUNET_CRYPTO_hash (name, name_len, &key); | ||
434 | GNUNET_CONTAINER_multihashmap_get_multiple (slicer->handlers, &key, | ||
435 | &slicer_handler_notify, slicer); | ||
436 | char *p = strrchr (name, '_'); | ||
437 | if (NULL == p) | ||
438 | break; | ||
439 | *p = '\0'; | ||
440 | } while (1); | ||
441 | GNUNET_free (name); | ||
442 | slicer->msg = NULL; | ||
443 | |||
444 | if (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_END <= ptype) | ||
445 | GNUNET_free (slicer->method_name); | ||
446 | } | ||
121 | 447 | ||
122 | 448 | ||
123 | /** | 449 | /** |
@@ -128,7 +454,9 @@ struct GNUNET_SOCIAL_HistoryLesson | |||
128 | struct GNUNET_SOCIAL_Slicer * | 454 | struct GNUNET_SOCIAL_Slicer * |
129 | GNUNET_SOCIAL_slicer_create (void) | 455 | GNUNET_SOCIAL_slicer_create (void) |
130 | { | 456 | { |
131 | return NULL; | 457 | struct GNUNET_SOCIAL_Slicer *slicer = GNUNET_malloc (sizeof (*slicer)); |
458 | slicer->handlers = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); | ||
459 | return slicer; | ||
132 | } | 460 | } |
133 | 461 | ||
134 | 462 | ||
@@ -148,36 +476,338 @@ void | |||
148 | GNUNET_SOCIAL_slicer_add (struct GNUNET_SOCIAL_Slicer *slicer, | 476 | GNUNET_SOCIAL_slicer_add (struct GNUNET_SOCIAL_Slicer *slicer, |
149 | const char *method_name, | 477 | const char *method_name, |
150 | GNUNET_SOCIAL_MethodCallback method_cb, | 478 | GNUNET_SOCIAL_MethodCallback method_cb, |
479 | GNUNET_SOCIAL_ModifierCallback modifier_cb, | ||
480 | GNUNET_SOCIAL_DataCallback data_cb, | ||
481 | GNUNET_SOCIAL_EndOfMessageCallback eom_cb, | ||
151 | void *cls) | 482 | void *cls) |
152 | { | 483 | { |
484 | struct GNUNET_HashCode key; | ||
485 | GNUNET_CRYPTO_hash (method_name, strlen (method_name), &key); | ||
486 | |||
487 | struct SlicerCallbacks *cbs = GNUNET_malloc (sizeof (*cbs)); | ||
488 | cbs->method_cb = method_cb; | ||
489 | cbs->modifier_cb = modifier_cb; | ||
490 | cbs->data_cb = data_cb; | ||
491 | cbs->eom_cb = eom_cb; | ||
492 | cbs->cls = cls; | ||
493 | |||
494 | GNUNET_CONTAINER_multihashmap_put (slicer->handlers, &key, cbs, | ||
495 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
496 | } | ||
153 | 497 | ||
498 | |||
499 | int | ||
500 | slicer_remove_handler (void *cls, const struct GNUNET_HashCode *key, void *value) | ||
501 | { | ||
502 | struct SlicerRemoveClosure *rm_cls = cls; | ||
503 | struct GNUNET_SOCIAL_Slicer *slicer = rm_cls->slicer; | ||
504 | struct SlicerCallbacks *rm_cbs = &rm_cls->rm_cbs; | ||
505 | struct SlicerCallbacks *cbs = value; | ||
506 | |||
507 | if (cbs->method_cb == rm_cbs->method_cb | ||
508 | && cbs->modifier_cb == rm_cbs->modifier_cb | ||
509 | && cbs->data_cb == rm_cbs->data_cb | ||
510 | && cbs->eom_cb == rm_cbs->eom_cb) | ||
511 | { | ||
512 | GNUNET_CONTAINER_multihashmap_remove (slicer->handlers, key, cbs); | ||
513 | GNUNET_free (cbs); | ||
514 | return GNUNET_NO; | ||
515 | } | ||
516 | return GNUNET_YES; | ||
154 | } | 517 | } |
155 | 518 | ||
156 | 519 | ||
157 | /** | 520 | /** |
158 | * Remove a registered method from the try-and-slice instance. | 521 | * Remove a registered method from the try-and-slice instance. |
159 | * | 522 | * |
523 | * Removes the first matching handler registered with @a method and the given callbacks. | ||
524 | * | ||
160 | * @param slicer The try-and-slice instance. | 525 | * @param slicer The try-and-slice instance. |
161 | * @param method_name Name of the method to remove. | 526 | * @param method_name Name of the method to remove. |
162 | * @param method Method handler. | 527 | * @param method Method handler. |
528 | * | ||
529 | * @return #GNUNET_OK if a method handler was removed, | ||
530 | * #GNUNET_NO if no handler matched the given method name and callbacks. | ||
163 | */ | 531 | */ |
164 | void | 532 | int |
165 | GNUNET_SOCIAL_slicer_remove (struct GNUNET_SOCIAL_Slicer *slicer, | 533 | GNUNET_SOCIAL_slicer_remove (struct GNUNET_SOCIAL_Slicer *slicer, |
166 | const char *method_name, | 534 | const char *method_name, |
167 | GNUNET_SOCIAL_MethodCallback method_cb) | 535 | GNUNET_SOCIAL_MethodCallback method_cb, |
536 | GNUNET_SOCIAL_ModifierCallback modifier_cb, | ||
537 | GNUNET_SOCIAL_DataCallback data_cb, | ||
538 | GNUNET_SOCIAL_EndOfMessageCallback eom_cb) | ||
168 | { | 539 | { |
540 | struct GNUNET_HashCode key; | ||
541 | GNUNET_CRYPTO_hash (method_name, strlen (method_name), &key); | ||
542 | |||
543 | struct SlicerRemoveClosure rm_cls; | ||
544 | rm_cls.slicer = slicer; | ||
545 | struct SlicerCallbacks *rm_cbs = &rm_cls.rm_cbs; | ||
546 | rm_cbs->method_cb = method_cb; | ||
547 | rm_cbs->modifier_cb = modifier_cb; | ||
548 | rm_cbs->data_cb = data_cb; | ||
549 | rm_cbs->eom_cb = eom_cb; | ||
550 | |||
551 | return | ||
552 | (GNUNET_SYSERR | ||
553 | == GNUNET_CONTAINER_multihashmap_get_multiple (slicer->handlers, &key, | ||
554 | &slicer_remove_handler, | ||
555 | &rm_cls)) | ||
556 | ? GNUNET_NO | ||
557 | : GNUNET_OK; | ||
558 | } | ||
559 | |||
169 | 560 | ||
561 | int | ||
562 | slicer_free_handler (void *cls, const struct GNUNET_HashCode *key, void *value) | ||
563 | { | ||
564 | struct SlicerCallbacks *cbs = value; | ||
565 | GNUNET_free (cbs); | ||
566 | return GNUNET_YES; | ||
170 | } | 567 | } |
171 | 568 | ||
569 | |||
172 | /** | 570 | /** |
173 | * Destroy a given try-and-slice instance. | 571 | * Destroy a given try-and-slice instance. |
174 | * | 572 | * |
175 | * @param slicer slicer to destroy | 573 | * @param slicer |
574 | * Slicer to destroy | ||
176 | */ | 575 | */ |
177 | void | 576 | void |
178 | GNUNET_SOCIAL_slicer_destroy (struct GNUNET_SOCIAL_Slicer *slicer) | 577 | GNUNET_SOCIAL_slicer_destroy (struct GNUNET_SOCIAL_Slicer *slicer) |
179 | { | 578 | { |
579 | GNUNET_CONTAINER_multihashmap_iterate (slicer->handlers, &slicer_free_handler, | ||
580 | NULL); | ||
581 | GNUNET_CONTAINER_multihashmap_destroy (slicer->handlers); | ||
582 | GNUNET_free (slicer); | ||
583 | } | ||
584 | |||
585 | |||
586 | static void | ||
587 | place_send_connect_msg (struct GNUNET_SOCIAL_Place *plc) | ||
588 | { | ||
589 | uint16_t cmsg_size = ntohs (plc->connect_msg->size); | ||
590 | struct GNUNET_MessageHeader * cmsg = GNUNET_malloc (cmsg_size); | ||
591 | memcpy (cmsg, plc->connect_msg, cmsg_size); | ||
592 | GNUNET_CLIENT_MANAGER_transmit_now (plc->client, cmsg); | ||
593 | } | ||
594 | |||
595 | |||
596 | static void | ||
597 | place_recv_message_ack (void *cls, | ||
598 | struct GNUNET_CLIENT_MANAGER_Connection *client, | ||
599 | const struct GNUNET_MessageHeader *msg) | ||
600 | { | ||
601 | struct GNUNET_SOCIAL_Place * | ||
602 | plc = GNUNET_CLIENT_MANAGER_get_user_context_ (client, sizeof (*plc)); | ||
603 | GNUNET_PSYC_transmit_got_ack (plc->tmit); | ||
604 | } | ||
605 | |||
606 | |||
607 | static void | ||
608 | place_recv_message (void *cls, | ||
609 | struct GNUNET_CLIENT_MANAGER_Connection *client, | ||
610 | const struct GNUNET_MessageHeader *msg) | ||
611 | { | ||
612 | struct GNUNET_SOCIAL_Place * | ||
613 | plc = GNUNET_CLIENT_MANAGER_get_user_context_ (client, sizeof (*plc)); | ||
614 | GNUNET_PSYC_receive_message (plc->recv, | ||
615 | (const struct GNUNET_PSYC_MessageHeader *) msg); | ||
616 | } | ||
617 | |||
618 | |||
619 | static void | ||
620 | place_recv_disconnect (void *cls, | ||
621 | struct GNUNET_CLIENT_MANAGER_Connection *client, | ||
622 | const struct GNUNET_MessageHeader *msg) | ||
623 | { | ||
624 | struct GNUNET_SOCIAL_Place * | ||
625 | plc = GNUNET_CLIENT_MANAGER_get_user_context_ (client, sizeof (*plc)); | ||
626 | |||
627 | GNUNET_CLIENT_MANAGER_reconnect (client); | ||
628 | place_send_connect_msg (plc); | ||
629 | } | ||
630 | |||
631 | |||
632 | static void | ||
633 | host_recv_enter_ack (void *cls, | ||
634 | struct GNUNET_CLIENT_MANAGER_Connection *client, | ||
635 | const struct GNUNET_MessageHeader *msg) | ||
636 | { | ||
637 | struct GNUNET_SOCIAL_Host * | ||
638 | hst = GNUNET_CLIENT_MANAGER_get_user_context_ (client, | ||
639 | sizeof (struct GNUNET_SOCIAL_Place)); | ||
640 | |||
641 | struct GNUNET_PSYC_CountersResultMessage * | ||
642 | cres = (struct GNUNET_PSYC_CountersResultMessage *) msg; | ||
643 | if (NULL != hst->enter_cb) | ||
644 | hst->enter_cb (hst->cb_cls, GNUNET_ntohll (cres->max_message_id)); | ||
645 | } | ||
646 | |||
647 | |||
648 | static void | ||
649 | host_recv_enter_request (void *cls, | ||
650 | struct GNUNET_CLIENT_MANAGER_Connection *client, | ||
651 | const struct GNUNET_MessageHeader *msg) | ||
652 | { | ||
653 | struct GNUNET_SOCIAL_Host * | ||
654 | hst = GNUNET_CLIENT_MANAGER_get_user_context_ (client, | ||
655 | sizeof (struct GNUNET_SOCIAL_Place)); | ||
656 | if (NULL == hst->answer_door_cb) | ||
657 | return; | ||
658 | |||
659 | const char *method_name = NULL; | ||
660 | struct GNUNET_ENV_Environment *env = NULL; | ||
661 | const void *data = NULL; | ||
662 | uint16_t data_size = 0; | ||
663 | |||
664 | const struct GNUNET_PSYC_JoinRequestMessage * | ||
665 | req = (const struct GNUNET_PSYC_JoinRequestMessage *) msg; | ||
666 | const struct GNUNET_PSYC_Message *entry_msg = NULL; | ||
667 | if (sizeof (*req) + sizeof (*entry_msg) <= ntohs (req->header.size)) | ||
668 | { | ||
669 | entry_msg = (struct GNUNET_PSYC_Message *) &req[1]; | ||
670 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
671 | "Received entry_msg of type %u and size %u.\n", | ||
672 | ntohs (entry_msg->header.type), ntohs (entry_msg->header.size)); | ||
673 | |||
674 | env = GNUNET_ENV_environment_create (); | ||
675 | if (GNUNET_OK != GNUNET_PSYC_message_parse (entry_msg, &method_name, env, | ||
676 | &data, &data_size)) | ||
677 | { | ||
678 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
679 | "Ignoring invalid entry request from nym %s.\n", | ||
680 | GNUNET_CRYPTO_ecdsa_public_key_to_string (&req->slave_key)); | ||
681 | GNUNET_break_op (0); | ||
682 | GNUNET_ENV_environment_destroy (env); | ||
683 | return; | ||
684 | } | ||
685 | } | ||
686 | |||
687 | struct GNUNET_SOCIAL_Nym *nym = nym_get_or_create (&req->slave_key); | ||
688 | hst->answer_door_cb (hst->cb_cls, nym, method_name, env, | ||
689 | data_size, data); | ||
690 | |||
691 | if (NULL != env) | ||
692 | GNUNET_ENV_environment_destroy (env); | ||
693 | } | ||
694 | |||
695 | |||
696 | static void | ||
697 | guest_recv_enter_ack (void *cls, | ||
698 | struct GNUNET_CLIENT_MANAGER_Connection *client, | ||
699 | const struct GNUNET_MessageHeader *msg) | ||
700 | { | ||
701 | struct GNUNET_SOCIAL_Guest * | ||
702 | gst = GNUNET_CLIENT_MANAGER_get_user_context_ (client, | ||
703 | sizeof (struct GNUNET_SOCIAL_Place)); | ||
704 | |||
705 | struct GNUNET_PSYC_CountersResultMessage * | ||
706 | cres = (struct GNUNET_PSYC_CountersResultMessage *) msg; | ||
707 | if (NULL != gst->enter_cb) | ||
708 | gst->enter_cb (gst->cb_cls, ntohl (cres->result_code), | ||
709 | GNUNET_ntohll (cres->max_message_id)); | ||
710 | } | ||
711 | |||
712 | |||
713 | static void | ||
714 | guest_recv_join_decision (void *cls, | ||
715 | struct GNUNET_CLIENT_MANAGER_Connection *client, | ||
716 | const struct GNUNET_MessageHeader *msg) | ||
717 | { | ||
718 | struct GNUNET_SOCIAL_Guest * | ||
719 | gst = GNUNET_CLIENT_MANAGER_get_user_context_ (client, | ||
720 | sizeof (struct GNUNET_SOCIAL_Place)); | ||
721 | const struct GNUNET_PSYC_JoinDecisionMessage * | ||
722 | dcsn = (const struct GNUNET_PSYC_JoinDecisionMessage *) msg; | ||
723 | |||
724 | struct GNUNET_PSYC_Message *pmsg = NULL; | ||
725 | if (ntohs (dcsn->header.size) <= sizeof (*dcsn) + sizeof (*pmsg)) | ||
726 | pmsg = (struct GNUNET_PSYC_Message *) &dcsn[1]; | ||
727 | |||
728 | if (NULL != gst->entry_dcsn_cb) | ||
729 | gst->entry_dcsn_cb (gst->cb_cls, ntohl (dcsn->is_admitted), pmsg); | ||
730 | } | ||
731 | |||
732 | |||
733 | static struct GNUNET_CLIENT_MANAGER_MessageHandler host_handlers[] = | ||
734 | { | ||
735 | { &host_recv_enter_ack, NULL, | ||
736 | GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER_ACK, | ||
737 | sizeof (struct CountersResult), GNUNET_NO }, | ||
738 | |||
739 | { &host_recv_enter_request, NULL, | ||
740 | GNUNET_MESSAGE_TYPE_PSYC_JOIN_REQUEST, | ||
741 | sizeof (struct GNUNET_PSYC_JoinRequestMessage), GNUNET_YES }, | ||
742 | |||
743 | { &place_recv_message, NULL, | ||
744 | GNUNET_MESSAGE_TYPE_PSYC_MESSAGE, | ||
745 | sizeof (struct GNUNET_PSYC_MessageHeader), GNUNET_YES }, | ||
746 | |||
747 | { &place_recv_message_ack, NULL, | ||
748 | GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_ACK, | ||
749 | sizeof (struct GNUNET_MessageHeader), GNUNET_NO }, | ||
750 | |||
751 | { &place_recv_disconnect, NULL, 0, 0, GNUNET_NO }, | ||
752 | |||
753 | { NULL, NULL, 0, 0, GNUNET_NO } | ||
754 | }; | ||
755 | |||
756 | |||
757 | static struct GNUNET_CLIENT_MANAGER_MessageHandler guest_handlers[] = | ||
758 | { | ||
759 | { &guest_recv_enter_ack, NULL, | ||
760 | GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER_ACK, | ||
761 | sizeof (struct CountersResult), GNUNET_NO }, | ||
762 | |||
763 | { &host_recv_enter_request, NULL, | ||
764 | GNUNET_MESSAGE_TYPE_PSYC_JOIN_REQUEST, | ||
765 | sizeof (struct GNUNET_PSYC_JoinRequestMessage), GNUNET_YES }, | ||
766 | |||
767 | { &place_recv_message, NULL, | ||
768 | GNUNET_MESSAGE_TYPE_PSYC_MESSAGE, | ||
769 | sizeof (struct GNUNET_PSYC_MessageHeader), GNUNET_YES }, | ||
770 | |||
771 | { &place_recv_message_ack, NULL, | ||
772 | GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_ACK, | ||
773 | sizeof (struct GNUNET_MessageHeader), GNUNET_NO }, | ||
774 | |||
775 | { &guest_recv_join_decision, NULL, | ||
776 | GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION, | ||
777 | sizeof (struct GNUNET_PSYC_JoinDecisionMessage), GNUNET_YES }, | ||
778 | |||
779 | { &place_recv_disconnect, NULL, 0, 0, GNUNET_NO }, | ||
780 | |||
781 | { NULL, NULL, 0, 0, GNUNET_NO } | ||
782 | }; | ||
783 | |||
784 | |||
785 | static void | ||
786 | place_cleanup (struct GNUNET_SOCIAL_Place *plc) | ||
787 | { | ||
788 | GNUNET_PSYC_transmit_destroy (plc->tmit); | ||
789 | GNUNET_PSYC_receive_destroy (plc->recv); | ||
790 | GNUNET_free (plc->connect_msg); | ||
791 | if (NULL != plc->disconnect_cb) | ||
792 | plc->disconnect_cb (plc->disconnect_cls); | ||
793 | } | ||
794 | |||
795 | |||
796 | static void | ||
797 | host_cleanup (void *cls) | ||
798 | { | ||
799 | struct GNUNET_SOCIAL_Host *hst = cls; | ||
800 | place_cleanup (&hst->plc); | ||
801 | GNUNET_free (hst); | ||
802 | } | ||
803 | |||
180 | 804 | ||
805 | static void | ||
806 | guest_cleanup (void *cls) | ||
807 | { | ||
808 | struct GNUNET_SOCIAL_Guest *gst = cls; | ||
809 | place_cleanup (&gst->plc); | ||
810 | GNUNET_free (gst); | ||
181 | } | 811 | } |
182 | 812 | ||
183 | 813 | ||
@@ -187,46 +817,179 @@ GNUNET_SOCIAL_slicer_destroy (struct GNUNET_SOCIAL_Slicer *slicer) | |||
187 | * A place is created upon first entering, and it is active until permanently | 817 | * A place is created upon first entering, and it is active until permanently |
188 | * left using GNUNET_SOCIAL_host_leave(). | 818 | * left using GNUNET_SOCIAL_host_leave(). |
189 | * | 819 | * |
190 | * @param cfg Configuration to contact the social service. | 820 | * @param cfg |
191 | * @param place_keyfile File with the private-public key pair of the place, | 821 | * Configuration to contact the social service. |
192 | * created if the file does not exist; pass NULL for ephemeral places. | 822 | * @param ego |
193 | * @param policy Policy specifying entry and history restrictions of the place. | 823 | * Identity of the host. |
194 | * @param ego Identity of the host. | 824 | * @param place_key |
195 | * @param slicer Slicer to handle incoming messages. | 825 | * Private-public key pair of the place. |
196 | * @param listener_cb Function to handle new nyms that want to enter. | 826 | * NULL for ephemeral places. |
197 | * @param farewell_cb Function to handle departing nyms. | 827 | * @param policy |
198 | * @param cls Closure for @a listener_cb and @a farewell_cb. | 828 | * Policy specifying entry and history restrictions for the place. |
829 | * @param slicer | ||
830 | * Slicer to handle incoming messages. | ||
831 | * @param answer_door_cb | ||
832 | * Function to handle new nyms that want to enter. | ||
833 | * @param farewell_cb | ||
834 | * Function to handle departing nyms. | ||
835 | * @param cls | ||
836 | * Closure for the callbacks. | ||
199 | * | 837 | * |
200 | * @return Handle for the host. | 838 | * @return Handle for the host. |
201 | */ | 839 | */ |
202 | struct GNUNET_SOCIAL_Host * | 840 | struct GNUNET_SOCIAL_Host * |
203 | GNUNET_SOCIAL_host_enter (const struct GNUNET_CONFIGURATION_Handle *cfg, | 841 | GNUNET_SOCIAL_host_enter (const struct GNUNET_CONFIGURATION_Handle *cfg, |
204 | const char *place_keyfile, | 842 | const struct GNUNET_IDENTITY_Ego *ego, |
843 | const struct GNUNET_CRYPTO_EddsaPrivateKey *place_key, | ||
205 | enum GNUNET_PSYC_Policy policy, | 844 | enum GNUNET_PSYC_Policy policy, |
206 | struct GNUNET_IDENTITY_Ego *ego, | ||
207 | struct GNUNET_SOCIAL_Slicer *slicer, | 845 | struct GNUNET_SOCIAL_Slicer *slicer, |
208 | GNUNET_SOCIAL_AnswerDoorCallback listener_cb, | 846 | GNUNET_SOCIAL_HostEnterCallback enter_cb, |
847 | GNUNET_SOCIAL_AnswerDoorCallback answer_door_cb, | ||
209 | GNUNET_SOCIAL_FarewellCallback farewell_cb, | 848 | GNUNET_SOCIAL_FarewellCallback farewell_cb, |
210 | void *cls) | 849 | void *cls) |
211 | { | 850 | { |
212 | return NULL; | 851 | struct GNUNET_SOCIAL_Host *hst = GNUNET_malloc (sizeof (*hst)); |
852 | struct GNUNET_SOCIAL_Place *plc = &hst->plc; | ||
853 | struct HostEnterRequest *req = GNUNET_malloc (sizeof (*req)); | ||
854 | |||
855 | if (NULL != place_key) | ||
856 | { | ||
857 | hst->place_key = *place_key; | ||
858 | } | ||
859 | else | ||
860 | { | ||
861 | struct GNUNET_CRYPTO_EddsaPrivateKey * | ||
862 | ephemeral_key = GNUNET_CRYPTO_eddsa_key_create (); | ||
863 | hst->place_key = *ephemeral_key; | ||
864 | GNUNET_CRYPTO_eddsa_key_get_public (&hst->place_key, &plc->pub_key); | ||
865 | GNUNET_CRYPTO_eddsa_key_clear (ephemeral_key); | ||
866 | GNUNET_free (ephemeral_key); | ||
867 | } | ||
868 | plc->ego_key = *GNUNET_IDENTITY_ego_get_private_key (ego); | ||
869 | |||
870 | req->header.size = htons (sizeof (*req)); | ||
871 | req->header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER); | ||
872 | req->policy = policy; | ||
873 | req->place_key = hst->place_key; | ||
874 | req->host_key = plc->ego_key; | ||
875 | |||
876 | plc->connect_msg = (struct GNUNET_MessageHeader *) req; | ||
877 | plc->cfg = cfg; | ||
878 | plc->is_host = GNUNET_YES; | ||
879 | plc->slicer = slicer; | ||
880 | |||
881 | hst->plc.ego_key = *GNUNET_IDENTITY_ego_get_private_key (ego); | ||
882 | hst->enter_cb = enter_cb; | ||
883 | hst->answer_door_cb = answer_door_cb; | ||
884 | hst->cb_cls = cls; | ||
885 | |||
886 | plc->client = GNUNET_CLIENT_MANAGER_connect (cfg, "social", host_handlers); | ||
887 | GNUNET_CLIENT_MANAGER_set_user_context_ (plc->client, hst, sizeof (*plc)); | ||
888 | |||
889 | plc->tmit = GNUNET_PSYC_transmit_create (plc->client); | ||
890 | plc->recv = GNUNET_PSYC_receive_create (NULL, &slicer_message, plc->slicer); | ||
891 | |||
892 | place_send_connect_msg (plc); | ||
893 | return hst; | ||
213 | } | 894 | } |
214 | 895 | ||
215 | 896 | ||
216 | /** | 897 | /** |
217 | * Admit @a nym to the place. | 898 | * Enter a place as host. |
218 | * | 899 | * |
219 | * The @a nym reference will remain valid until either the @a host or @a nym | 900 | * A place is created upon first entering, and it is active until permanently |
220 | * leaves the place. | 901 | * left using GNUNET_SOCIAL_host_leave(). |
221 | * | 902 | * |
222 | * @param host Host of the place. | 903 | * @param cfg |
223 | * @param nym Handle for the entity that wants to enter. | 904 | * Configuration to contact the social service. |
905 | * @param ego | ||
906 | * Identity of the host. | ||
907 | * @param gns_name | ||
908 | * GNS name in the zone of the @a ego that contains the | ||
909 | * public key of the place in a PLACE record. | ||
910 | * @param policy | ||
911 | * Policy specifying entry and history restrictions for the place. | ||
912 | * @param slicer | ||
913 | * Slicer to handle incoming messages. | ||
914 | * @param answer_door_cb | ||
915 | * Function to handle new nyms that want to enter. | ||
916 | * @param farewell_cb | ||
917 | * Function to handle departing nyms. | ||
918 | * @param cls | ||
919 | * Closure for the callbacks. | ||
920 | * | ||
921 | * @return Handle for the host. | ||
224 | */ | 922 | */ |
225 | void | 923 | struct GNUNET_SOCIAL_Host * |
226 | GNUNET_SOCIAL_host_admit (struct GNUNET_SOCIAL_Host *host, | 924 | GNUNET_SOCIAL_host_enter_by_name (const struct GNUNET_CONFIGURATION_Handle *cfg, |
227 | struct GNUNET_SOCIAL_Nym *nym) | 925 | struct GNUNET_IDENTITY_Ego *ego, |
926 | const char *gns_name, | ||
927 | enum GNUNET_PSYC_Policy policy, | ||
928 | struct GNUNET_SOCIAL_Slicer *slicer, | ||
929 | GNUNET_SOCIAL_HostEnterCallback enter_cb, | ||
930 | GNUNET_SOCIAL_AnswerDoorCallback answer_door_cb, | ||
931 | GNUNET_SOCIAL_FarewellCallback farewell_cb, | ||
932 | void *cls) | ||
228 | { | 933 | { |
934 | struct GNUNET_CRYPTO_EddsaPrivateKey place_key = {}; | ||
229 | 935 | ||
936 | /* FIXME: | ||
937 | * 1. get public key by looking up PLACE entry under gns_name | ||
938 | * in the zone of the ego. | ||
939 | * 2. get private key from $GNUNET_DATA_HOME/social/places/PUB_KEY_HASH | ||
940 | */ | ||
941 | |||
942 | return GNUNET_SOCIAL_host_enter (cfg, ego, &place_key, policy, slicer, | ||
943 | enter_cb, answer_door_cb, farewell_cb, cls); | ||
944 | } | ||
945 | |||
946 | |||
947 | /** | ||
948 | * Decision whether to admit @a nym into the place or refuse entry. | ||
949 | * | ||
950 | * @param hst | ||
951 | * Host of the place. | ||
952 | * @param nym | ||
953 | * Handle for the entity that wanted to enter. | ||
954 | * @param is_admitted | ||
955 | * #GNUNET_YES if @a nym is admitted, | ||
956 | * #GNUNET_NO if @a nym is refused entry, | ||
957 | * #GNUNET_SYSERR if we cannot answer the request. | ||
958 | * @param method_name | ||
959 | * Method name for the rejection message. | ||
960 | * @param env | ||
961 | * Environment containing variables for the message, or NULL. | ||
962 | * @param data | ||
963 | * Data for the rejection message to send back. | ||
964 | * @param data_size | ||
965 | * Number of bytes in @a data for method. | ||
966 | * @return #GNUNET_OK on success, | ||
967 | * #GNUNET_SYSERR if the message is too large. | ||
968 | */ | ||
969 | int | ||
970 | GNUNET_SOCIAL_host_entry_decision (struct GNUNET_SOCIAL_Host *hst, | ||
971 | struct GNUNET_SOCIAL_Nym *nym, | ||
972 | int is_admitted, | ||
973 | const struct GNUNET_PSYC_Message *entry_resp) | ||
974 | { | ||
975 | struct GNUNET_PSYC_JoinDecisionMessage *dcsn; | ||
976 | uint16_t entry_resp_size | ||
977 | = (NULL != entry_resp) ? ntohs (entry_resp->header.size) : 0; | ||
978 | |||
979 | if (GNUNET_MULTICAST_FRAGMENT_MAX_PAYLOAD < sizeof (*dcsn) + entry_resp_size) | ||
980 | return GNUNET_SYSERR; | ||
981 | |||
982 | dcsn = GNUNET_malloc (sizeof (*dcsn) + entry_resp_size); | ||
983 | dcsn->header.size = htons (sizeof (*dcsn) + entry_resp_size); | ||
984 | dcsn->header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION); | ||
985 | dcsn->is_admitted = htonl (is_admitted); | ||
986 | dcsn->slave_key = nym->pub_key; | ||
987 | |||
988 | if (0 < entry_resp_size) | ||
989 | memcpy (&dcsn[1], entry_resp, entry_resp_size); | ||
990 | |||
991 | GNUNET_CLIENT_MANAGER_transmit (hst->plc.client, &dcsn->header); | ||
992 | return GNUNET_OK; | ||
230 | } | 993 | } |
231 | 994 | ||
232 | 995 | ||
@@ -249,63 +1012,60 @@ GNUNET_SOCIAL_host_eject (struct GNUNET_SOCIAL_Host *host, | |||
249 | 1012 | ||
250 | 1013 | ||
251 | /** | 1014 | /** |
252 | * Refuse @a nym entry into the place. | 1015 | * Get the public key of a @a nym. |
253 | * | 1016 | * |
254 | * @param host Host of the place. | 1017 | * Suitable, for example, to be used with GNUNET_NAMESTORE_zone_to_name(). |
255 | * @param nym Handle for the entity that wanted to enter. | 1018 | * |
256 | * @param method_name Method name for the rejection message. | 1019 | * @param nym Pseudonym to map to a cryptographic identifier. |
257 | * @param env Environment containing variables for the message, or NULL. | 1020 | * @param[out] nym_key Set to the public key of the nym. |
258 | * @param data Data for the rejection message to send back. | ||
259 | * @param data_size Number of bytes in @a data for method. | ||
260 | */ | 1021 | */ |
261 | void | 1022 | struct GNUNET_CRYPTO_EcdsaPublicKey * |
262 | GNUNET_SOCIAL_host_refuse_entry (struct GNUNET_SOCIAL_Host *host, | 1023 | GNUNET_SOCIAL_nym_get_key (struct GNUNET_SOCIAL_Nym *nym) |
263 | struct GNUNET_SOCIAL_Nym *nym, | ||
264 | const char *method_name, | ||
265 | const struct GNUNET_ENV_Environment *env, | ||
266 | const void *data, | ||
267 | size_t data_size) | ||
268 | { | 1024 | { |
269 | 1025 | return &nym->pub_key; | |
270 | } | 1026 | } |
271 | 1027 | ||
272 | 1028 | ||
273 | /** | 1029 | /** |
274 | * Get the public key of a @a nym. | 1030 | * Obtain the private-public key pair of the hosted place. |
275 | * | 1031 | * |
276 | * Suitable, for example, to be used with GNUNET_NAMESTORE_zone_to_name(). | 1032 | * The public part is suitable for storing in GNS within a PLACE record, |
1033 | * along with peer IDs to join at. | ||
277 | * | 1034 | * |
278 | * @param nym Pseudonym to map to a cryptographic identifier. | 1035 | * @param host |
279 | * @param[out] nym_key Set to the public key of the nym. | 1036 | * Host of the place. |
1037 | * | ||
1038 | * @return Private-public key pair of the hosted place. | ||
280 | */ | 1039 | */ |
281 | void | 1040 | const struct GNUNET_CRYPTO_EddsaPrivateKey * |
282 | GNUNET_SOCIAL_nym_get_key (struct GNUNET_SOCIAL_Nym *nym, | 1041 | GNUNET_SOCIAL_host_get_place_key (struct GNUNET_SOCIAL_Host *hst) |
283 | struct GNUNET_CRYPTO_EddsaPublicKey *nym_key) | 1042 | { |
1043 | return &hst->place_key; | ||
1044 | } | ||
1045 | |||
1046 | |||
1047 | static void | ||
1048 | namestore_result_host_advertise (void *cls, int32_t success, const char *emsg) | ||
284 | { | 1049 | { |
285 | 1050 | ||
286 | } | 1051 | } |
287 | 1052 | ||
288 | 1053 | ||
289 | /** | 1054 | /** |
290 | * Obtain the private-public key pair of the host. | 1055 | * Connected to core service. |
291 | * | ||
292 | * @param host Host to get the key of. | ||
293 | * @param[out] host_key Set to the private-public key pair of the host. The | ||
294 | * public part is suitable for storing in GNS within a "PLACE" | ||
295 | * record, along with peer IDs to join at. | ||
296 | */ | 1056 | */ |
297 | void | 1057 | static void |
298 | GNUNET_SOCIAL_host_get_key (struct GNUNET_SOCIAL_Host *host, | 1058 | core_connected_cb (void *cls, const struct GNUNET_PeerIdentity *my_identity) |
299 | struct GNUNET_CRYPTO_EddsaPrivateKey *host_key) | ||
300 | { | 1059 | { |
301 | 1060 | this_peer = *my_identity; | |
1061 | // FIXME | ||
302 | } | 1062 | } |
303 | 1063 | ||
304 | 1064 | ||
305 | /** | 1065 | /** |
306 | * Advertise the place in the GNS zone of the @e ego of the @a host. | 1066 | * Advertise the place in the GNS zone of the @e ego of the @a host. |
307 | * | 1067 | * |
308 | * @param host Host of the place. | 1068 | * @param hst Host of the place. |
309 | * @param name The name for the PLACE record to put in the zone. | 1069 | * @param name The name for the PLACE record to put in the zone. |
310 | * @param peer_count Number of elements in the @a peers array. | 1070 | * @param peer_count Number of elements in the @a peers array. |
311 | * @param peers List of peers in the PLACE record that can be used to send join | 1071 | * @param peers List of peers in the PLACE record that can be used to send join |
@@ -314,14 +1074,37 @@ GNUNET_SOCIAL_host_get_key (struct GNUNET_SOCIAL_Host *host, | |||
314 | * @param password Password used to encrypt the record. | 1074 | * @param password Password used to encrypt the record. |
315 | */ | 1075 | */ |
316 | void | 1076 | void |
317 | GNUNET_SOCIAL_host_advertise (struct GNUNET_SOCIAL_Host *host, | 1077 | GNUNET_SOCIAL_host_advertise (struct GNUNET_SOCIAL_Host *hst, |
318 | const char *name, | 1078 | const char *name, |
319 | size_t peer_count, | 1079 | size_t peer_count, |
320 | const struct GNUNET_PeerIdentity *peers, | 1080 | const struct GNUNET_PeerIdentity *peers, |
321 | struct GNUNET_TIME_Relative expiration_time, | 1081 | struct GNUNET_TIME_Relative expiration_time, |
322 | const char *password) | 1082 | const char *password) |
323 | { | 1083 | { |
324 | 1084 | struct GNUNET_SOCIAL_Place *plc = &hst->plc; | |
1085 | if (NULL == namestore) | ||
1086 | namestore = GNUNET_NAMESTORE_connect (plc->cfg); | ||
1087 | if (NULL == core) | ||
1088 | core = GNUNET_CORE_connect (plc->cfg, NULL, core_connected_cb, NULL, NULL, | ||
1089 | NULL, GNUNET_NO, NULL, GNUNET_NO, NULL); | ||
1090 | |||
1091 | struct GNUNET_GNSRECORD_Data rd = { 0 }; | ||
1092 | rd.record_type = GNUNET_GNSRECORD_TYPE_PLACE; | ||
1093 | rd.flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; | ||
1094 | rd.expiration_time | ||
1095 | = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_WEEKS, 1).rel_value_us; | ||
1096 | |||
1097 | struct GNUNET_GNSRECORD_PlaceData *rec = GNUNET_malloc (sizeof (*rec)); | ||
1098 | rec->place_key = plc->pub_key; | ||
1099 | rec->origin = this_peer; | ||
1100 | rec->relay_count = htons (0); // FIXME | ||
1101 | |||
1102 | rd.data_size = sizeof (*rec); | ||
1103 | rd.data = rec; | ||
1104 | |||
1105 | GNUNET_NAMESTORE_records_store (namestore, &hst->plc.ego_key, | ||
1106 | name, 1, &rd, namestore_result_host_advertise, | ||
1107 | hst); | ||
325 | } | 1108 | } |
326 | 1109 | ||
327 | 1110 | ||
@@ -342,26 +1125,43 @@ GNUNET_SOCIAL_host_advertise (struct GNUNET_SOCIAL_Host *host, | |||
342 | * @return NULL on error (announcement already in progress?). | 1125 | * @return NULL on error (announcement already in progress?). |
343 | */ | 1126 | */ |
344 | struct GNUNET_SOCIAL_Announcement * | 1127 | struct GNUNET_SOCIAL_Announcement * |
345 | GNUNET_SOCIAL_host_announce (struct GNUNET_SOCIAL_Host *host, | 1128 | GNUNET_SOCIAL_host_announce (struct GNUNET_SOCIAL_Host *hst, |
346 | const char *method_name, | 1129 | const char *method_name, |
347 | const struct GNUNET_ENV_Environment *env, | 1130 | const struct GNUNET_ENV_Environment *env, |
348 | GNUNET_CONNECTION_TransmitReadyNotify notify, | 1131 | GNUNET_PSYC_TransmitNotifyData notify_data, |
349 | void *notify_cls, | 1132 | void *notify_data_cls, |
350 | enum GNUNET_SOCIAL_AnnounceFlags flags) | 1133 | enum GNUNET_SOCIAL_AnnounceFlags flags) |
351 | { | 1134 | { |
352 | return NULL; | 1135 | if (GNUNET_OK == |
1136 | GNUNET_PSYC_transmit_message (hst->plc.tmit, method_name, env, | ||
1137 | NULL, notify_data, notify_data_cls, flags)); | ||
1138 | return (struct GNUNET_SOCIAL_Announcement *) hst->plc.tmit; | ||
1139 | } | ||
1140 | |||
1141 | |||
1142 | /** | ||
1143 | * Resume transmitting announcement. | ||
1144 | * | ||
1145 | * @param a | ||
1146 | * The announcement to resume. | ||
1147 | */ | ||
1148 | void | ||
1149 | GNUNET_SOCIAL_host_announce_resume (struct GNUNET_SOCIAL_Announcement *a) | ||
1150 | { | ||
1151 | GNUNET_PSYC_transmit_resume ((struct GNUNET_PSYC_TransmitHandle *) a); | ||
353 | } | 1152 | } |
354 | 1153 | ||
355 | 1154 | ||
356 | /** | 1155 | /** |
357 | * Cancel announcement. | 1156 | * Cancel announcement. |
358 | * | 1157 | * |
359 | * @param a The announcement to cancel. | 1158 | * @param a |
1159 | * The announcement to cancel. | ||
360 | */ | 1160 | */ |
361 | void | 1161 | void |
362 | GNUNET_SOCIAL_host_announce_cancel (struct GNUNET_SOCIAL_Announcement *a) | 1162 | GNUNET_SOCIAL_host_announce_cancel (struct GNUNET_SOCIAL_Announcement *a) |
363 | { | 1163 | { |
364 | 1164 | GNUNET_PSYC_transmit_cancel ((struct GNUNET_PSYC_TransmitHandle *) a); | |
365 | } | 1165 | } |
366 | 1166 | ||
367 | 1167 | ||
@@ -375,9 +1175,9 @@ GNUNET_SOCIAL_host_announce_cancel (struct GNUNET_SOCIAL_Announcement *a) | |||
375 | * @return Handle for the hosted place, valid as long as @a host is valid. | 1175 | * @return Handle for the hosted place, valid as long as @a host is valid. |
376 | */ | 1176 | */ |
377 | struct GNUNET_SOCIAL_Place * | 1177 | struct GNUNET_SOCIAL_Place * |
378 | GNUNET_SOCIAL_host_get_place (struct GNUNET_SOCIAL_Host *host) | 1178 | GNUNET_SOCIAL_host_get_place (struct GNUNET_SOCIAL_Host *hst) |
379 | { | 1179 | { |
380 | return NULL; | 1180 | return &hst->plc; |
381 | } | 1181 | } |
382 | 1182 | ||
383 | 1183 | ||
@@ -390,22 +1190,65 @@ GNUNET_SOCIAL_host_get_place (struct GNUNET_SOCIAL_Host *host) | |||
390 | * @param keep_active Keep the place active after last host disconnected. | 1190 | * @param keep_active Keep the place active after last host disconnected. |
391 | */ | 1191 | */ |
392 | void | 1192 | void |
393 | GNUNET_SOCIAL_host_leave (struct GNUNET_SOCIAL_Host *host, int keep_active) | 1193 | GNUNET_SOCIAL_host_leave (struct GNUNET_SOCIAL_Host *hst, |
1194 | int keep_active, | ||
1195 | GNUNET_ContinuationCallback leave_cb, | ||
1196 | void *leave_cls) | ||
394 | { | 1197 | { |
1198 | struct GNUNET_SOCIAL_Place *plc = &hst->plc; | ||
1199 | |||
1200 | /* FIXME: send msg to service */ | ||
1201 | |||
1202 | plc->is_disconnecting = GNUNET_YES; | ||
1203 | plc->disconnect_cb = leave_cb; | ||
1204 | plc->disconnect_cls = leave_cls; | ||
395 | 1205 | ||
1206 | GNUNET_CLIENT_MANAGER_disconnect (plc->client, GNUNET_YES, | ||
1207 | &host_cleanup, hst); | ||
396 | } | 1208 | } |
397 | 1209 | ||
398 | 1210 | ||
1211 | static struct GuestEnterRequest * | ||
1212 | guest_enter_request_create (const struct GNUNET_CRYPTO_EcdsaPrivateKey *guest_key, | ||
1213 | const struct GNUNET_CRYPTO_EddsaPublicKey *place_key, | ||
1214 | const struct GNUNET_PeerIdentity *origin, | ||
1215 | size_t relay_count, | ||
1216 | const struct GNUNET_PeerIdentity *relays, | ||
1217 | const struct GNUNET_PSYC_Message *join_msg) | ||
1218 | { | ||
1219 | uint16_t join_msg_size = ntohs (join_msg->header.size); | ||
1220 | uint16_t relay_size = relay_count * sizeof (*relays); | ||
1221 | |||
1222 | struct GuestEnterRequest * | ||
1223 | req = GNUNET_malloc (sizeof (*req) + relay_size + join_msg_size); | ||
1224 | |||
1225 | req->header.size = htons (sizeof (*req) + relay_size + join_msg_size); | ||
1226 | req->header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER); | ||
1227 | req->place_key = *place_key; | ||
1228 | req->guest_key = *guest_key; | ||
1229 | req->origin = *origin; | ||
1230 | req->relay_count = relay_count; | ||
1231 | |||
1232 | uint16_t p = sizeof (*req); | ||
1233 | if (0 < relay_size) | ||
1234 | { | ||
1235 | memcpy ((char *) req + p, relays, relay_size); | ||
1236 | p += relay_size; | ||
1237 | } | ||
1238 | |||
1239 | memcpy ((char *) req + p, join_msg, join_msg_size); | ||
1240 | return req; | ||
1241 | } | ||
1242 | |||
399 | /** | 1243 | /** |
400 | * Request entry to a place as a guest. | 1244 | * Request entry to a place as a guest. |
401 | * | 1245 | * |
402 | * @param cfg Configuration to contact the social service. | 1246 | * @param cfg Configuration to contact the social service. |
403 | * @param ego Identity of the guest. | 1247 | * @param ego Identity of the guest. |
404 | * @param address GNS name of the place to enter. Either in the form of | 1248 | * @param crypto_address Public key of the place to enter. |
405 | * 'room.friend.gnu', or 'NYMPUBKEY.zkey'. This latter case refers to | 1249 | * @param origin Peer identity of the origin of the underlying multicast group. |
406 | * the 'PLACE' record of the empty label ("+") in the GNS zone with the | 1250 | * @param relay_count Number of elements in the @a relays array. |
407 | * nym's public key 'NYMPUBKEY', and can be used to request entry to a | 1251 | * @param relays Relays for the underlying multicast group. |
408 | * pseudonym's place directly. | ||
409 | * @param method_name Method name for the message. | 1252 | * @param method_name Method name for the message. |
410 | * @param env Environment containing variables for the message, or NULL. | 1253 | * @param env Environment containing variables for the message, or NULL. |
411 | * @param data Payload for the message to give to the enter callback. | 1254 | * @param data Payload for the message to give to the enter callback. |
@@ -416,26 +1259,132 @@ GNUNET_SOCIAL_host_leave (struct GNUNET_SOCIAL_Host *host, int keep_active) | |||
416 | */ | 1259 | */ |
417 | struct GNUNET_SOCIAL_Guest * | 1260 | struct GNUNET_SOCIAL_Guest * |
418 | GNUNET_SOCIAL_guest_enter (const struct GNUNET_CONFIGURATION_Handle *cfg, | 1261 | GNUNET_SOCIAL_guest_enter (const struct GNUNET_CONFIGURATION_Handle *cfg, |
419 | struct GNUNET_IDENTITY_Ego *ego, | 1262 | const struct GNUNET_IDENTITY_Ego *ego, |
420 | char *address, | 1263 | const struct GNUNET_CRYPTO_EddsaPublicKey *place_key, |
421 | const char *method_name, | 1264 | const struct GNUNET_PeerIdentity *origin, |
422 | const struct GNUNET_ENV_Environment *env, | 1265 | uint32_t relay_count, |
423 | const void *data, | 1266 | const struct GNUNET_PeerIdentity *relays, |
424 | size_t data_size, | 1267 | const struct GNUNET_PSYC_Message *entry_msg, |
425 | struct GNUNET_SOCIAL_Slicer *slicer) | 1268 | struct GNUNET_SOCIAL_Slicer *slicer, |
1269 | GNUNET_SOCIAL_GuestEnterCallback local_enter_cb, | ||
1270 | GNUNET_SOCIAL_EntryDecisionCallback entry_dcsn_cb, | ||
1271 | void *cls) | ||
426 | { | 1272 | { |
427 | return NULL; | 1273 | struct GNUNET_SOCIAL_Guest *gst = GNUNET_malloc (sizeof (*gst)); |
1274 | struct GNUNET_SOCIAL_Place *plc = &gst->plc; | ||
1275 | |||
1276 | struct GuestEnterRequest * | ||
1277 | req = guest_enter_request_create (&plc->ego_key, place_key, origin, | ||
1278 | relay_count, relays, entry_msg); | ||
1279 | plc->connect_msg = &req->header; | ||
1280 | plc->ego_key = *GNUNET_IDENTITY_ego_get_private_key (ego); | ||
1281 | plc->pub_key = *place_key; | ||
1282 | plc->cfg = cfg; | ||
1283 | plc->is_host = GNUNET_YES; | ||
1284 | plc->slicer = slicer; | ||
1285 | |||
1286 | gst->enter_cb = local_enter_cb; | ||
1287 | gst->entry_dcsn_cb = entry_dcsn_cb; | ||
1288 | gst->cb_cls = cls; | ||
1289 | |||
1290 | plc->client = GNUNET_CLIENT_MANAGER_connect (cfg, "social", guest_handlers); | ||
1291 | GNUNET_CLIENT_MANAGER_set_user_context_ (plc->client, gst, sizeof (*plc)); | ||
1292 | |||
1293 | plc->tmit = GNUNET_PSYC_transmit_create (plc->client); | ||
1294 | plc->recv = GNUNET_PSYC_receive_create (NULL, &slicer_message, plc->slicer); | ||
1295 | |||
1296 | place_send_connect_msg (plc); | ||
1297 | return gst; | ||
1298 | } | ||
1299 | |||
1300 | |||
1301 | /** | ||
1302 | * Result of a GNS name lookup for entering a place. | ||
1303 | * | ||
1304 | * @see GNUNET_SOCIAL_guest_enter_by_name | ||
1305 | */ | ||
1306 | static void | ||
1307 | gns_result_guest_enter (void *cls, uint32_t rd_count, | ||
1308 | const struct GNUNET_GNSRECORD_Data *rd) | ||
1309 | { | ||
1310 | struct GNUNET_SOCIAL_Guest *gst = cls; | ||
1311 | struct GNUNET_SOCIAL_Place *plc = &gst->plc; | ||
1312 | |||
1313 | const struct GNUNET_GNSRECORD_PlaceData * | ||
1314 | rec = (const struct GNUNET_GNSRECORD_PlaceData *) rd->data; | ||
1315 | |||
1316 | if (0 == rd_count) | ||
1317 | { | ||
1318 | if (NULL != gst->enter_cb) | ||
1319 | gst->enter_cb (gst->cb_cls, GNUNET_SYSERR, 0); | ||
1320 | return; | ||
1321 | } | ||
1322 | |||
1323 | |||
1324 | if (rd->data_size < sizeof (*rec)) | ||
1325 | { | ||
1326 | GNUNET_break_op (0); | ||
1327 | if (NULL != gst->enter_cb) | ||
1328 | gst->enter_cb (gst->cb_cls, GNUNET_SYSERR, 0); | ||
1329 | return; | ||
1330 | } | ||
1331 | |||
1332 | struct GuestEnterRequest * | ||
1333 | req = (struct GuestEnterRequest *) plc->connect_msg; | ||
1334 | uint16_t req_size = ntohs (req->header.size); | ||
1335 | |||
1336 | struct GNUNET_PeerIdentity *relays = NULL; | ||
1337 | uint16_t relay_count = ntohs (rec->relay_count); | ||
1338 | |||
1339 | if (0 < relay_count) | ||
1340 | { | ||
1341 | uint16_t relay_size = relay_count * sizeof (struct GNUNET_PeerIdentity); | ||
1342 | struct GuestEnterRequest * | ||
1343 | req2 = GNUNET_malloc (req_size + relay_size); | ||
1344 | |||
1345 | req2->header.size = htons (req_size + relay_size); | ||
1346 | req2->header.type = req->header.type; | ||
1347 | req2->guest_key = req->guest_key; | ||
1348 | |||
1349 | uint16_t p = sizeof (*req); | ||
1350 | if (0 < relay_size) | ||
1351 | { | ||
1352 | memcpy ((char *) req2 + p, relays, relay_size); | ||
1353 | p += relay_size; | ||
1354 | } | ||
1355 | |||
1356 | memcpy ((char *) req + p, &req[1], req_size - sizeof (*req)); | ||
1357 | |||
1358 | plc->connect_msg = &req2->header; | ||
1359 | GNUNET_free (req); | ||
1360 | req = req2; | ||
1361 | } | ||
1362 | |||
1363 | req->place_key = rec->place_key; | ||
1364 | req->origin = rec->origin; | ||
1365 | req->relay_count = rec->relay_count; | ||
1366 | memcpy (&req[1], &rec[1], | ||
1367 | ntohl (rec->relay_count) * sizeof (struct GNUNET_PeerIdentity)); | ||
1368 | |||
1369 | plc->connect_msg = &req->header; | ||
1370 | plc->pub_key = req->place_key; | ||
1371 | |||
1372 | plc->tmit = GNUNET_PSYC_transmit_create (plc->client); | ||
1373 | plc->recv = GNUNET_PSYC_receive_create (NULL, &slicer_message, plc); | ||
1374 | |||
1375 | place_send_connect_msg (plc); | ||
428 | } | 1376 | } |
429 | 1377 | ||
430 | /** | 1378 | /** |
431 | * Request entry to a place as a guest. | 1379 | * Request entry to a place as a guest. |
432 | * | 1380 | * |
433 | * @param cfg Configuration to contact the social service. | 1381 | * @param cfg Configuration to contact the social service. |
434 | * @param ego Identity of the guest. | 1382 | * @param ego Identity of the guest. |
435 | * @param crypto_address Public key of the place to enter. | 1383 | * @param address GNS name of the place to enter. Either in the form of |
436 | * @param origin Peer identity of the origin of the underlying multicast group. | 1384 | * 'room.friend.gnu', or 'NYMPUBKEY.zkey'. This latter case refers to |
437 | * @param relay_count Number of elements in the @a relays array. | 1385 | * the 'PLACE' record of the empty label ("+") in the GNS zone with the |
438 | * @param relays Relays for the underlying multicast group. | 1386 | * nym's public key 'NYMPUBKEY', and can be used to request entry to a |
1387 | * pseudonym's place directly. | ||
439 | * @param method_name Method name for the message. | 1388 | * @param method_name Method name for the message. |
440 | * @param env Environment containing variables for the message, or NULL. | 1389 | * @param env Environment containing variables for the message, or NULL. |
441 | * @param data Payload for the message to give to the enter callback. | 1390 | * @param data Payload for the message to give to the enter callback. |
@@ -445,41 +1394,75 @@ GNUNET_SOCIAL_guest_enter (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
445 | * @return NULL on errors, otherwise handle for the guest. | 1394 | * @return NULL on errors, otherwise handle for the guest. |
446 | */ | 1395 | */ |
447 | struct GNUNET_SOCIAL_Guest * | 1396 | struct GNUNET_SOCIAL_Guest * |
448 | GNUNET_SOCIAL_guest_enter2 (const struct GNUNET_CONFIGURATION_Handle *cfg, | 1397 | GNUNET_SOCIAL_guest_enter_by_name (const struct GNUNET_CONFIGURATION_Handle *cfg, |
449 | struct GNUNET_IDENTITY_Ego *ego, | 1398 | struct GNUNET_IDENTITY_Ego *ego, |
450 | struct GNUNET_CRYPTO_EddsaPublicKey *crypto_address, | 1399 | char *gns_name, |
451 | struct GNUNET_PeerIdentity *origin, | 1400 | const struct GNUNET_PSYC_Message *join_msg, |
452 | size_t relay_count, | 1401 | struct GNUNET_SOCIAL_Slicer *slicer, |
453 | struct GNUNET_PeerIdentity *relays, | 1402 | GNUNET_SOCIAL_GuestEnterCallback local_enter_cb, |
454 | const char *method_name, | 1403 | GNUNET_SOCIAL_EntryDecisionCallback entry_decision_cb, |
455 | const struct GNUNET_ENV_Environment *env, | 1404 | void *cls) |
456 | const void *data, | ||
457 | size_t data_size, | ||
458 | struct GNUNET_SOCIAL_Slicer *slicer) | ||
459 | { | 1405 | { |
460 | return NULL; | 1406 | struct GNUNET_SOCIAL_Guest *gst = GNUNET_malloc (sizeof (*gst)); |
1407 | struct GNUNET_SOCIAL_Place *plc = &gst->plc; | ||
1408 | |||
1409 | gst->enter_cb = local_enter_cb; | ||
1410 | gst->cb_cls = cls; | ||
1411 | |||
1412 | plc->ego_key = *GNUNET_IDENTITY_ego_get_private_key (ego); | ||
1413 | plc->cfg = cfg; | ||
1414 | plc->is_host = GNUNET_NO; | ||
1415 | plc->slicer = slicer; | ||
1416 | |||
1417 | struct GuestEnterRequest * | ||
1418 | req = guest_enter_request_create (&plc->ego_key, NULL, NULL, 0, NULL, | ||
1419 | join_msg); | ||
1420 | plc->connect_msg = &req->header; | ||
1421 | |||
1422 | /* FIXME: get the public key of the origin and relays | ||
1423 | * by looking up the PLACE record of gns_name. | ||
1424 | */ | ||
1425 | if (NULL == gns) | ||
1426 | gns = GNUNET_GNS_connect (cfg); | ||
1427 | |||
1428 | plc->client = GNUNET_CLIENT_MANAGER_connect (cfg, "social", guest_handlers); | ||
1429 | GNUNET_CLIENT_MANAGER_set_user_context_ (plc->client, gst, sizeof (*plc)); | ||
1430 | |||
1431 | struct GNUNET_CRYPTO_EcdsaPublicKey ego_pub_key; | ||
1432 | GNUNET_IDENTITY_ego_get_public_key (ego, &ego_pub_key); | ||
1433 | GNUNET_GNS_lookup (gns, gns_name, &ego_pub_key, | ||
1434 | GNUNET_GNSRECORD_TYPE_PLACE, GNUNET_GNS_LO_DEFAULT, | ||
1435 | NULL, gns_result_guest_enter, gst); | ||
1436 | |||
1437 | return gst; | ||
461 | } | 1438 | } |
462 | 1439 | ||
463 | 1440 | ||
464 | /** | 1441 | /** |
465 | * Talk to the host of the place. | 1442 | * Talk to the host of the place. |
466 | * | 1443 | * |
467 | * @param place Place where we want to talk to the host. | 1444 | * @param place |
468 | * @param method_name Method to invoke on the host. | 1445 | * Place where we want to talk to the host. |
469 | * @param env Environment containing variables for the message, or NULL. | 1446 | * @param method_name |
470 | * @param notify Function to use to get the payload for the method. | 1447 | * Method to invoke on the host. |
471 | * @param notify_cls Closure for @a notify. | 1448 | * @param env |
472 | * @param flags Flags for the message being sent. | 1449 | * Environment containing variables for the message, or NULL. |
1450 | * @param notify_data | ||
1451 | * Function to use to get the payload for the method. | ||
1452 | * @param notify_data_cls | ||
1453 | * Closure for @a notify_data. | ||
1454 | * @param flags | ||
1455 | * Flags for the message being sent. | ||
473 | * | 1456 | * |
474 | * @return NULL if we are already trying to talk to the host, | 1457 | * @return NULL if we are already trying to talk to the host, |
475 | * otherwise handle to cancel the request. | 1458 | * otherwise handle to cancel the request. |
476 | */ | 1459 | */ |
477 | struct GNUNET_SOCIAL_TalkRequest * | 1460 | struct GNUNET_SOCIAL_TalkRequest * |
478 | GNUNET_SOCIAL_guest_talk (struct GNUNET_SOCIAL_Place *place, | 1461 | GNUNET_SOCIAL_guest_talk (struct GNUNET_SOCIAL_Guest *guest, |
479 | const char *method_name, | 1462 | const char *method_name, |
480 | const struct GNUNET_ENV_Environment *env, | 1463 | const struct GNUNET_ENV_Environment *env, |
481 | GNUNET_CONNECTION_TransmitReadyNotify notify, | 1464 | GNUNET_PSYC_TransmitNotifyData notify_data, |
482 | void *notify_cls, | 1465 | void *notify_data_cls, |
483 | enum GNUNET_SOCIAL_TalkFlags flags) | 1466 | enum GNUNET_SOCIAL_TalkFlags flags) |
484 | { | 1467 | { |
485 | return NULL; | 1468 | return NULL; |
@@ -487,14 +1470,28 @@ GNUNET_SOCIAL_guest_talk (struct GNUNET_SOCIAL_Place *place, | |||
487 | 1470 | ||
488 | 1471 | ||
489 | /** | 1472 | /** |
1473 | * Resume talking to the host of the place. | ||
1474 | * | ||
1475 | * @param tr | ||
1476 | * Talk request to resume. | ||
1477 | */ | ||
1478 | void | ||
1479 | GNUNET_SOCIAL_guest_talk_resume (struct GNUNET_SOCIAL_TalkRequest *tr) | ||
1480 | { | ||
1481 | GNUNET_PSYC_transmit_resume ((struct GNUNET_PSYC_TransmitHandle *) tr); | ||
1482 | } | ||
1483 | |||
1484 | |||
1485 | /** | ||
490 | * Cancel talking to the host of the place. | 1486 | * Cancel talking to the host of the place. |
491 | * | 1487 | * |
492 | * @param tr Talk request to cancel. | 1488 | * @param tr |
1489 | * Talk request to cancel. | ||
493 | */ | 1490 | */ |
494 | void | 1491 | void |
495 | GNUNET_SOCIAL_guest_talk_cancel (struct GNUNET_SOCIAL_TalkRequest *tr) | 1492 | GNUNET_SOCIAL_guest_talk_cancel (struct GNUNET_SOCIAL_TalkRequest *tr) |
496 | { | 1493 | { |
497 | 1494 | GNUNET_PSYC_transmit_cancel ((struct GNUNET_PSYC_TransmitHandle *) tr); | |
498 | } | 1495 | } |
499 | 1496 | ||
500 | 1497 | ||
@@ -507,9 +1504,21 @@ GNUNET_SOCIAL_guest_talk_cancel (struct GNUNET_SOCIAL_TalkRequest *tr) | |||
507 | * @param keep_active Keep place active after last application disconnected. | 1504 | * @param keep_active Keep place active after last application disconnected. |
508 | */ | 1505 | */ |
509 | void | 1506 | void |
510 | GNUNET_SOCIAL_guest_leave (struct GNUNET_SOCIAL_Place *place, int keep_active) | 1507 | GNUNET_SOCIAL_guest_leave (struct GNUNET_SOCIAL_Guest *gst, |
1508 | int keep_active, | ||
1509 | GNUNET_ContinuationCallback leave_cb, | ||
1510 | void *leave_cls) | ||
511 | { | 1511 | { |
1512 | struct GNUNET_SOCIAL_Place *plc = &gst->plc; | ||
1513 | |||
1514 | /* FIXME: send msg to service */ | ||
1515 | |||
1516 | plc->is_disconnecting = GNUNET_YES; | ||
1517 | plc->disconnect_cb = leave_cb; | ||
1518 | plc->disconnect_cls = leave_cls; | ||
512 | 1519 | ||
1520 | GNUNET_CLIENT_MANAGER_disconnect (plc->client, GNUNET_YES, | ||
1521 | &guest_cleanup, gst); | ||
513 | } | 1522 | } |
514 | 1523 | ||
515 | 1524 | ||
@@ -523,9 +1532,9 @@ GNUNET_SOCIAL_guest_leave (struct GNUNET_SOCIAL_Place *place, int keep_active) | |||
523 | * @return Handle for the place, valid as long as @a guest is valid. | 1532 | * @return Handle for the place, valid as long as @a guest is valid. |
524 | */ | 1533 | */ |
525 | struct GNUNET_SOCIAL_Place * | 1534 | struct GNUNET_SOCIAL_Place * |
526 | GNUNET_SOCIAL_guest_get_place (struct GNUNET_SOCIAL_Host *guest) | 1535 | GNUNET_SOCIAL_guest_get_place (struct GNUNET_SOCIAL_Guest *gst) |
527 | { | 1536 | { |
528 | return NULL; | 1537 | return &gst->plc; |
529 | } | 1538 | } |
530 | 1539 | ||
531 | 1540 | ||
@@ -671,6 +1680,4 @@ GNUNET_SOCIAL_place_look_at (struct GNUNET_SOCIAL_Place *place, | |||
671 | } | 1680 | } |
672 | 1681 | ||
673 | 1682 | ||
674 | |||
675 | |||
676 | /* end of social_api.c */ | 1683 | /* end of social_api.c */ |
diff --git a/src/social/test_social.c b/src/social/test_social.c index 053e347d1..340c4482a 100644 --- a/src/social/test_social.c +++ b/src/social/test_social.c | |||
@@ -17,7 +17,6 @@ | |||
17 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 17 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
18 | * Boston, MA 02111-1307, USA. | 18 | * Boston, MA 02111-1307, USA. |
19 | */ | 19 | */ |
20 | |||
21 | /** | 20 | /** |
22 | * @file social/test_social.c | 21 | * @file social/test_social.c |
23 | * @brief Tests for the Social API. | 22 | * @brief Tests for the Social API. |
@@ -32,32 +31,132 @@ | |||
32 | #include "gnunet_util_lib.h" | 31 | #include "gnunet_util_lib.h" |
33 | #include "gnunet_testing_lib.h" | 32 | #include "gnunet_testing_lib.h" |
34 | #include "gnunet_env_lib.h" | 33 | #include "gnunet_env_lib.h" |
34 | #include "gnunet_psyc_util_lib.h" | ||
35 | #include "gnunet_social_service.h" | 35 | #include "gnunet_social_service.h" |
36 | #include "gnunet_core_service.h" | ||
37 | #include "gnunet_identity_service.h" | ||
36 | 38 | ||
37 | #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30) | 39 | #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30) |
38 | 40 | ||
39 | #define DEBUG_SERVICE 0 | 41 | #define DEBUG_SERVICE 0 |
42 | #define DATA2ARG(data) data, sizeof (data) | ||
40 | 43 | ||
41 | /** | 44 | /** |
42 | * Return value from 'main'. | 45 | * Return value from 'main'. |
43 | */ | 46 | */ |
44 | static int res; | 47 | int res; |
45 | |||
46 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
47 | 48 | ||
48 | /** | 49 | /** |
49 | * Handle for task for timeout termination. | 50 | * Handle for task for timeout termination. |
50 | */ | 51 | */ |
51 | static GNUNET_SCHEDULER_TaskIdentifier end_badly_task; | 52 | GNUNET_SCHEDULER_TaskIdentifier end_badly_task; |
53 | |||
54 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
55 | |||
56 | struct GNUNET_CORE_Handle *core; | ||
57 | struct GNUNET_PeerIdentity this_peer; | ||
58 | |||
59 | struct GNUNET_IDENTITY_Handle *id; | ||
60 | |||
61 | const struct GNUNET_IDENTITY_Ego *host_ego; | ||
62 | const struct GNUNET_IDENTITY_Ego *guest_ego; | ||
63 | |||
64 | const char *host_name = "Host One"; | ||
65 | const char *guest_name = "Guest One"; | ||
66 | |||
67 | struct GNUNET_CRYPTO_EddsaPrivateKey *place_key; | ||
68 | struct GNUNET_CRYPTO_EcdsaPrivateKey *guest_key; | ||
69 | |||
70 | struct GNUNET_CRYPTO_EddsaPublicKey place_pub_key; | ||
71 | struct GNUNET_CRYPTO_EcdsaPublicKey guest_pub_key; | ||
72 | |||
73 | struct GNUNET_SOCIAL_Slicer *host_slicer; | ||
74 | struct GNUNET_SOCIAL_Slicer *guest_slicer; | ||
75 | |||
76 | struct GNUNET_SOCIAL_Host *hst; | ||
77 | struct GNUNET_SOCIAL_Guest *gst; | ||
78 | |||
79 | struct GuestEnterMessage | ||
80 | { | ||
81 | struct GNUNET_PSYC_Message *msg; | ||
82 | const char *method_name; | ||
83 | struct GNUNET_ENV_Environment *env; | ||
84 | void *data; | ||
85 | uint16_t data_size; | ||
86 | } guest_enter_msg; | ||
87 | |||
88 | struct TransmitClosure | ||
89 | { | ||
90 | struct GNUNET_SOCIAL_Announcement *host_ann; | ||
91 | struct GNUNET_SOCIAL_TalkRequest *guest_talk; | ||
92 | struct GNUNET_ENV_Environment *env; | ||
93 | char *data[16]; | ||
94 | uint8_t data_delay[16]; | ||
95 | uint8_t data_count; | ||
96 | uint8_t paused; | ||
97 | uint8_t n; | ||
98 | } tmit; | ||
99 | |||
100 | uint8_t join_req_count; | ||
101 | struct GNUNET_PSYC_Message *join_resp; | ||
102 | |||
103 | enum | ||
104 | { | ||
105 | TEST_NONE = 0, | ||
106 | TEST_HOST_ANSWER_DOOR_REFUSE = 1, | ||
107 | TEST_GUEST_RECV_ENTRY_DCSN_REFUSE = 2, | ||
108 | TEST_HOST_ANSWER_DOOR_ADMIT = 3, | ||
109 | TEST_GUEST_RECV_ENTRY_DCSN_ADMIT = 4, | ||
110 | TEST_HOST_ANNOUNCE = 5, | ||
111 | TEST_HOST_ANNOUNCE_END = 6, | ||
112 | TEST_GUEST_TALK = 7, | ||
113 | TEST_GUEST_TALK_END = 8, | ||
114 | TEST_GUEST_LEAVE = 9, | ||
115 | TEST_HOST_LEAVE = 10, | ||
116 | } test; | ||
117 | |||
118 | |||
119 | void | ||
120 | guest_enter (); | ||
121 | |||
122 | |||
123 | void | ||
124 | guest_talk (); | ||
125 | |||
126 | |||
127 | void | ||
128 | host_announce2 (); | ||
52 | 129 | ||
53 | 130 | ||
54 | /** | 131 | /** |
55 | * Clean up all resources used. | 132 | * Clean up all resources used. |
56 | */ | 133 | */ |
57 | static void | 134 | void |
58 | cleanup () | 135 | cleanup () |
59 | { | 136 | { |
137 | if (NULL != core) | ||
138 | { | ||
139 | GNUNET_CORE_disconnect (core); | ||
140 | core = NULL; | ||
141 | } | ||
60 | 142 | ||
143 | if (NULL != id) | ||
144 | { | ||
145 | GNUNET_IDENTITY_disconnect (id); | ||
146 | id = NULL; | ||
147 | } | ||
148 | |||
149 | if (NULL != gst) | ||
150 | { | ||
151 | GNUNET_SOCIAL_guest_leave (gst, GNUNET_NO, NULL, NULL); | ||
152 | gst = NULL; | ||
153 | } | ||
154 | if (NULL != hst) | ||
155 | { | ||
156 | GNUNET_SOCIAL_host_leave (hst, GNUNET_NO, NULL, NULL); | ||
157 | hst = NULL; | ||
158 | } | ||
159 | GNUNET_SCHEDULER_shutdown (); | ||
61 | } | 160 | } |
62 | 161 | ||
63 | 162 | ||
@@ -67,7 +166,7 @@ cleanup () | |||
67 | * @param cls NULL | 166 | * @param cls NULL |
68 | * @param tc scheduler context | 167 | * @param tc scheduler context |
69 | */ | 168 | */ |
70 | static void | 169 | void |
71 | end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 170 | end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
72 | { | 171 | { |
73 | res = 1; | 172 | res = 1; |
@@ -82,7 +181,7 @@ end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
82 | * @param cls NULL | 181 | * @param cls NULL |
83 | * @param tc scheduler context | 182 | * @param tc scheduler context |
84 | */ | 183 | */ |
85 | static void | 184 | void |
86 | end_normally (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 185 | end_normally (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
87 | { | 186 | { |
88 | res = 0; | 187 | res = 0; |
@@ -94,7 +193,7 @@ end_normally (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
94 | /** | 193 | /** |
95 | * Finish the test case (successfully). | 194 | * Finish the test case (successfully). |
96 | */ | 195 | */ |
97 | static void | 196 | void |
98 | end () | 197 | end () |
99 | { | 198 | { |
100 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ending tests.\n"); | 199 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ending tests.\n"); |
@@ -109,6 +208,564 @@ end () | |||
109 | } | 208 | } |
110 | 209 | ||
111 | 210 | ||
211 | static void | ||
212 | transmit_resume (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
213 | { | ||
214 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmission resumed.\n"); | ||
215 | struct TransmitClosure *tmit = cls; | ||
216 | if (NULL != tmit->host_ann) | ||
217 | GNUNET_SOCIAL_host_announce_resume (tmit->host_ann); | ||
218 | else | ||
219 | GNUNET_SOCIAL_guest_talk_resume (tmit->guest_talk); | ||
220 | } | ||
221 | |||
222 | |||
223 | int | ||
224 | notify_data (void *cls, uint16_t *data_size, void *data) | ||
225 | { | ||
226 | struct TransmitClosure *tmit = cls; | ||
227 | if (NULL != tmit->env) | ||
228 | { | ||
229 | GNUNET_ENV_environment_destroy (tmit->env); | ||
230 | tmit->env = NULL; | ||
231 | } | ||
232 | if (0 == tmit->data_count) | ||
233 | { | ||
234 | *data_size = 0; | ||
235 | return GNUNET_YES; | ||
236 | } | ||
237 | |||
238 | uint16_t size = strlen (tmit->data[tmit->n]) + 1; | ||
239 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
240 | "Transmit notify data: %u bytes available, " | ||
241 | "processing fragment %u/%u (size %u).\n", | ||
242 | *data_size, tmit->n + 1, tmit->data_count, size); | ||
243 | if (*data_size < size) | ||
244 | { | ||
245 | *data_size = 0; | ||
246 | GNUNET_assert (0); | ||
247 | return GNUNET_SYSERR; | ||
248 | } | ||
249 | |||
250 | if (GNUNET_YES != tmit->paused && 0 < tmit->data_delay[tmit->n]) | ||
251 | { | ||
252 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmission paused.\n"); | ||
253 | tmit->paused = GNUNET_YES; | ||
254 | GNUNET_SCHEDULER_add_delayed ( | ||
255 | GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, | ||
256 | tmit->data_delay[tmit->n]), | ||
257 | &transmit_resume, tmit); | ||
258 | *data_size = 0; | ||
259 | return GNUNET_NO; | ||
260 | } | ||
261 | tmit->paused = GNUNET_NO; | ||
262 | |||
263 | *data_size = size; | ||
264 | memcpy (data, tmit->data[tmit->n], size); | ||
265 | |||
266 | return ++tmit->n < tmit->data_count ? GNUNET_NO : GNUNET_YES; | ||
267 | } | ||
268 | |||
269 | |||
270 | void host_left () | ||
271 | { | ||
272 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
273 | "The host has left the place.\n"); | ||
274 | GNUNET_SOCIAL_slicer_destroy (host_slicer); | ||
275 | host_slicer = NULL; | ||
276 | hst = NULL; | ||
277 | |||
278 | end (); | ||
279 | } | ||
280 | |||
281 | |||
282 | void | ||
283 | schedule_host_leave (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
284 | { | ||
285 | test = TEST_HOST_LEAVE; | ||
286 | GNUNET_SOCIAL_host_leave (hst, GNUNET_NO, &host_left, NULL); | ||
287 | } | ||
288 | |||
289 | |||
290 | void | ||
291 | host_farewell (void *cls, | ||
292 | struct GNUNET_SOCIAL_Nym *nym, | ||
293 | struct GNUNET_ENV_Environment *env, | ||
294 | size_t variable_count, | ||
295 | struct GNUNET_ENV_Modifier *variables) | ||
296 | { | ||
297 | struct GNUNET_CRYPTO_EcdsaPublicKey * | ||
298 | nym_key = GNUNET_SOCIAL_nym_get_key (nym); | ||
299 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
300 | "Nym %s has left the place.\n", | ||
301 | GNUNET_CRYPTO_ecdsa_public_key_to_string (nym_key)); | ||
302 | GNUNET_assert (0 == memcmp (&guest_pub_key, nym_key, sizeof (*nym_key))); | ||
303 | |||
304 | GNUNET_SCHEDULER_add_now (&schedule_host_leave, NULL); | ||
305 | } | ||
306 | |||
307 | |||
308 | void | ||
309 | guest_left (void *cls) | ||
310 | { | ||
311 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
312 | "The guest has left the place.\n"); | ||
313 | GNUNET_SOCIAL_slicer_destroy (guest_slicer); | ||
314 | guest_slicer = NULL; | ||
315 | gst = NULL; | ||
316 | |||
317 | GNUNET_SCHEDULER_add_now (&schedule_host_leave, NULL); | ||
318 | } | ||
319 | |||
320 | |||
321 | void | ||
322 | schedule_guest_leave (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
323 | { | ||
324 | test = TEST_GUEST_LEAVE; | ||
325 | /* FIXME test keep_active */ | ||
326 | GNUNET_SOCIAL_guest_leave (gst, GNUNET_NO, &guest_left, NULL); | ||
327 | } | ||
328 | |||
329 | |||
330 | |||
331 | void | ||
332 | guest_recv_method (void *cls, | ||
333 | const struct GNUNET_PSYC_MessageMethod *meth, | ||
334 | uint64_t message_id, | ||
335 | uint32_t flags, | ||
336 | const struct GNUNET_SOCIAL_Nym *nym, | ||
337 | const char *method_name) | ||
338 | { | ||
339 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
340 | "Test #%u: Guest received method for message ID %" PRIu64 ":\n" | ||
341 | "%s\n", | ||
342 | test, message_id, method_name); | ||
343 | /* FIXME: check message */ | ||
344 | } | ||
345 | |||
346 | |||
347 | void | ||
348 | guest_recv_modifier (void *cls, | ||
349 | const struct GNUNET_PSYC_MessageModifier *mod, | ||
350 | uint64_t message_id, | ||
351 | enum GNUNET_ENV_Operator oper, | ||
352 | const char *name, | ||
353 | const void *value, | ||
354 | uint16_t value_size) | ||
355 | { | ||
356 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
357 | "Test #%u: Guest received modifier for message ID %" PRIu64 ":\n" | ||
358 | "%c%s: %.*s\n", | ||
359 | test, message_id, oper, name, value_size, value); | ||
360 | } | ||
361 | |||
362 | |||
363 | void | ||
364 | guest_recv_data (void *cls, | ||
365 | const struct GNUNET_MessageHeader *msg, | ||
366 | uint64_t message_id, | ||
367 | uint64_t data_offset, | ||
368 | const void *data, | ||
369 | uint16_t data_size) | ||
370 | { | ||
371 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
372 | "Test #%u: Guest received data for message ID %" PRIu64 ":\n" | ||
373 | "%.*s\n", | ||
374 | test, message_id, data_size, data); | ||
375 | } | ||
376 | |||
377 | |||
378 | void | ||
379 | guest_recv_eom (void *cls, | ||
380 | const struct GNUNET_MessageHeader *msg, | ||
381 | uint64_t message_id, | ||
382 | uint8_t cancelled) | ||
383 | { | ||
384 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
385 | "Test #%u: Guest received end of message ID %" PRIu64 | ||
386 | ", cancelled: %u\n", | ||
387 | test, message_id, cancelled); | ||
388 | |||
389 | switch (test) | ||
390 | { | ||
391 | case TEST_HOST_ANNOUNCE: | ||
392 | test = TEST_HOST_ANNOUNCE_END; | ||
393 | break; | ||
394 | |||
395 | case TEST_HOST_ANNOUNCE_END: | ||
396 | guest_talk (); | ||
397 | break; | ||
398 | |||
399 | case TEST_GUEST_TALK: | ||
400 | test = TEST_GUEST_TALK_END; | ||
401 | break; | ||
402 | |||
403 | case TEST_GUEST_TALK_END: | ||
404 | GNUNET_SCHEDULER_add_now (&schedule_guest_leave, NULL); | ||
405 | break; | ||
406 | |||
407 | default: | ||
408 | GNUNET_assert (0); | ||
409 | } | ||
410 | } | ||
411 | |||
412 | |||
413 | void | ||
414 | host_recv_method (void *cls, | ||
415 | const struct GNUNET_PSYC_MessageMethod *meth, | ||
416 | uint64_t message_id, | ||
417 | uint32_t flags, | ||
418 | const struct GNUNET_SOCIAL_Nym *nym, | ||
419 | const char *method_name) | ||
420 | { | ||
421 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
422 | "Test #%u: Host received method for message ID %" PRIu64 ":\n" | ||
423 | "%s\n", | ||
424 | test, message_id, method_name); | ||
425 | /* FIXME: check message */ | ||
426 | } | ||
427 | |||
428 | |||
429 | void | ||
430 | host_recv_modifier (void *cls, | ||
431 | const struct GNUNET_PSYC_MessageModifier *mod, | ||
432 | uint64_t message_id, | ||
433 | enum GNUNET_ENV_Operator oper, | ||
434 | const char *name, | ||
435 | const void *value, | ||
436 | uint16_t value_size) | ||
437 | { | ||
438 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
439 | "Test #%u: Host received modifier for message ID %" PRIu64 ":\n" | ||
440 | "%c%s: %.*s\n", | ||
441 | test, message_id, oper, name, value_size, value); | ||
442 | } | ||
443 | |||
444 | |||
445 | void | ||
446 | host_recv_data (void *cls, | ||
447 | const struct GNUNET_MessageHeader *msg, | ||
448 | uint64_t message_id, | ||
449 | uint64_t data_offset, | ||
450 | const void *data, | ||
451 | uint16_t data_size) | ||
452 | { | ||
453 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
454 | "Test #%u: Host received data for message ID %" PRIu64 ":\n" | ||
455 | "%.*s\n", | ||
456 | test, message_id, data_size, data); | ||
457 | } | ||
458 | |||
459 | |||
460 | void | ||
461 | host_recv_eom (void *cls, | ||
462 | const struct GNUNET_MessageHeader *msg, | ||
463 | uint64_t message_id, | ||
464 | uint8_t cancelled) | ||
465 | { | ||
466 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
467 | "Test #%u: Host received end of message ID %" PRIu64 | ||
468 | ", cancelled: %u\n", | ||
469 | test, message_id, cancelled); | ||
470 | |||
471 | switch (test) | ||
472 | { | ||
473 | case TEST_HOST_ANNOUNCE: | ||
474 | test = TEST_HOST_ANNOUNCE_END; | ||
475 | //host_announce2 (); | ||
476 | break; | ||
477 | |||
478 | case TEST_HOST_ANNOUNCE_END: | ||
479 | guest_talk (); | ||
480 | break; | ||
481 | |||
482 | case TEST_GUEST_TALK: | ||
483 | test = TEST_GUEST_TALK_END; | ||
484 | break; | ||
485 | |||
486 | case TEST_GUEST_TALK_END: | ||
487 | GNUNET_SCHEDULER_add_now (&schedule_guest_leave, NULL); | ||
488 | break; | ||
489 | |||
490 | default: | ||
491 | GNUNET_assert (0); | ||
492 | } | ||
493 | } | ||
494 | |||
495 | |||
496 | void | ||
497 | guest_talk () | ||
498 | { | ||
499 | test = TEST_GUEST_TALK; | ||
500 | |||
501 | tmit = (struct TransmitClosure) {}; | ||
502 | tmit.env = GNUNET_ENV_environment_create (); | ||
503 | GNUNET_ENV_environment_add (tmit.env, GNUNET_ENV_OP_ASSIGN, | ||
504 | "_bar_foo", DATA2ARG ("one two three")); | ||
505 | GNUNET_ENV_environment_add (tmit.env, GNUNET_ENV_OP_ASSIGN, | ||
506 | "_bar_baz", DATA2ARG ("four five")); | ||
507 | tmit.data[0] = "zzz xxx yyy"; | ||
508 | tmit.data[1] = "zyx wvu tsr qpo"; | ||
509 | tmit.data[2] = "testing ten nine eight"; | ||
510 | tmit.data_count = 3; | ||
511 | |||
512 | tmit.host_ann | ||
513 | = GNUNET_SOCIAL_host_announce (hst, "_message_guest", tmit.env, | ||
514 | ¬ify_data, &tmit, | ||
515 | GNUNET_SOCIAL_TALK_NONE); | ||
516 | } | ||
517 | |||
518 | void | ||
519 | host_announce () | ||
520 | { | ||
521 | test = TEST_HOST_ANNOUNCE; | ||
522 | |||
523 | tmit = (struct TransmitClosure) {}; | ||
524 | tmit.env = GNUNET_ENV_environment_create (); | ||
525 | GNUNET_ENV_environment_add (tmit.env, GNUNET_ENV_OP_ASSIGN, | ||
526 | "_foo", DATA2ARG ("bar baz")); | ||
527 | GNUNET_ENV_environment_add (tmit.env, GNUNET_ENV_OP_ASSIGN, | ||
528 | "_foo_bar", DATA2ARG ("foo bar")); | ||
529 | GNUNET_ENV_environment_add (tmit.env, GNUNET_ENV_OP_ASSIGN, | ||
530 | "_foo_bar_baz", DATA2ARG ("foo bar baz")); | ||
531 | tmit.data[0] = "aaa bbb ccc"; | ||
532 | tmit.data[1] = "abc def ghi jkl"; | ||
533 | tmit.data[2] = "testing one two three"; | ||
534 | tmit.data[3] = "four five"; | ||
535 | tmit.data_count = 4; | ||
536 | |||
537 | tmit.host_ann | ||
538 | = GNUNET_SOCIAL_host_announce (hst, "_message_host", tmit.env, | ||
539 | ¬ify_data, &tmit, | ||
540 | GNUNET_SOCIAL_ANNOUNCE_NONE); | ||
541 | } | ||
542 | |||
543 | void | ||
544 | host_announce2 () | ||
545 | { | ||
546 | test = TEST_HOST_ANNOUNCE; | ||
547 | |||
548 | tmit = (struct TransmitClosure) {}; | ||
549 | tmit.env = GNUNET_ENV_environment_create (); | ||
550 | GNUNET_ENV_environment_add (tmit.env, GNUNET_ENV_OP_ASSIGN, | ||
551 | "_foo2", DATA2ARG ("BAR BAZ")); | ||
552 | GNUNET_ENV_environment_add (tmit.env, GNUNET_ENV_OP_ASSIGN, | ||
553 | "_foo2_bar", DATA2ARG ("FOO BAR")); | ||
554 | GNUNET_ENV_environment_add (tmit.env, GNUNET_ENV_OP_ASSIGN, | ||
555 | "_foo2_bar", DATA2ARG ("FOO BAR BAZ")); | ||
556 | tmit.data[0] = "AAA BBB CCC"; | ||
557 | tmit.data[1] = "ABC DEF GHI JKL"; | ||
558 | tmit.data[2] = "TESTING ONE TWO THREE"; | ||
559 | tmit.data_count = 3; | ||
560 | |||
561 | tmit.host_ann | ||
562 | = GNUNET_SOCIAL_host_announce (hst, "_message_host_two", tmit.env, | ||
563 | ¬ify_data, &tmit, | ||
564 | GNUNET_SOCIAL_ANNOUNCE_NONE); | ||
565 | } | ||
566 | |||
567 | |||
568 | void | ||
569 | guest_recv_entry_decision (void *cls, | ||
570 | int is_admitted, | ||
571 | const struct GNUNET_PSYC_Message *entry_resp) | ||
572 | { | ||
573 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
574 | "Guest received entry decision (try %u): %d.\n", | ||
575 | join_req_count, is_admitted); | ||
576 | |||
577 | if (NULL != entry_resp) | ||
578 | { | ||
579 | struct GNUNET_ENV_Environment *env = GNUNET_ENV_environment_create (); | ||
580 | const char *method_name = NULL; | ||
581 | const void *data = NULL; | ||
582 | uint16_t data_size = 0; | ||
583 | GNUNET_PSYC_message_parse (entry_resp, &method_name, env, &data, &data_size); | ||
584 | |||
585 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
586 | "%s\n%.*s\n", | ||
587 | method_name, data_size, data); | ||
588 | /* FIXME: check response message */ | ||
589 | } | ||
590 | |||
591 | switch (test) | ||
592 | { | ||
593 | case TEST_GUEST_RECV_ENTRY_DCSN_REFUSE: | ||
594 | GNUNET_assert (GNUNET_NO == is_admitted); | ||
595 | guest_enter (); | ||
596 | break; | ||
597 | |||
598 | case TEST_GUEST_RECV_ENTRY_DCSN_ADMIT: | ||
599 | GNUNET_assert (GNUNET_YES == is_admitted); | ||
600 | host_announce (); | ||
601 | break; | ||
602 | |||
603 | default: | ||
604 | GNUNET_assert (0); | ||
605 | } | ||
606 | } | ||
607 | |||
608 | |||
609 | void | ||
610 | host_answer_door (void *cls, | ||
611 | struct GNUNET_SOCIAL_Nym *nym, | ||
612 | const char *method_name, | ||
613 | struct GNUNET_ENV_Environment *env, | ||
614 | size_t data_size, | ||
615 | const void *data) | ||
616 | { | ||
617 | join_req_count++; | ||
618 | |||
619 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
620 | "Host received entry request from guest (try %u).\n", | ||
621 | join_req_count); | ||
622 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
623 | "%s\n%.*s\n", | ||
624 | method_name, data_size, data); | ||
625 | |||
626 | switch (test) | ||
627 | { | ||
628 | case TEST_HOST_ANSWER_DOOR_REFUSE: | ||
629 | test = TEST_GUEST_RECV_ENTRY_DCSN_REFUSE; | ||
630 | join_resp = GNUNET_PSYC_message_create ("_refuse_nym", env, | ||
631 | DATA2ARG ("Go away!")); | ||
632 | GNUNET_SOCIAL_host_entry_decision (hst, nym, GNUNET_NO, join_resp); | ||
633 | break; | ||
634 | |||
635 | case TEST_HOST_ANSWER_DOOR_ADMIT: | ||
636 | test = TEST_GUEST_RECV_ENTRY_DCSN_ADMIT; | ||
637 | join_resp = GNUNET_PSYC_message_create ("_admit_nym", env, | ||
638 | DATA2ARG ("Welcome, nym!")); | ||
639 | GNUNET_SOCIAL_host_entry_decision (hst, nym, GNUNET_YES, join_resp); | ||
640 | break; | ||
641 | |||
642 | default: | ||
643 | GNUNET_assert (0); | ||
644 | } | ||
645 | } | ||
646 | |||
647 | |||
648 | void | ||
649 | guest_recv_local_enter (void *cls, int result, uint64_t max_message_id) | ||
650 | { | ||
651 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Guest entered to local place.\n"); | ||
652 | |||
653 | } | ||
654 | |||
655 | |||
656 | void | ||
657 | guest_enter () | ||
658 | { | ||
659 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Entering to place as guest.\n"); | ||
660 | |||
661 | struct GuestEnterMessage *emsg = &guest_enter_msg; | ||
662 | |||
663 | emsg->method_name = "_request_enter"; | ||
664 | emsg->env = GNUNET_ENV_environment_create (); | ||
665 | GNUNET_ENV_environment_add (emsg->env, GNUNET_ENV_OP_ASSIGN, | ||
666 | "_abc", "abc def", 7); | ||
667 | GNUNET_ENV_environment_add (emsg->env, GNUNET_ENV_OP_ASSIGN, | ||
668 | "_abc_def", "abc def ghi", 11); | ||
669 | emsg->data = "let me in"; | ||
670 | emsg->data_size = strlen (emsg->data) + 1; | ||
671 | emsg->msg = GNUNET_PSYC_message_create (emsg->method_name, emsg->env, | ||
672 | emsg->data, emsg->data_size); | ||
673 | |||
674 | gst = GNUNET_SOCIAL_guest_enter (cfg, guest_ego, &place_pub_key, | ||
675 | &this_peer, 0, NULL, emsg->msg, | ||
676 | guest_slicer, &guest_recv_local_enter, | ||
677 | &guest_recv_entry_decision, NULL); | ||
678 | } | ||
679 | |||
680 | |||
681 | void id_guest_ego_cb (void *cls, const struct GNUNET_IDENTITY_Ego *ego) | ||
682 | { | ||
683 | GNUNET_assert (NULL != ego); | ||
684 | guest_ego = ego; | ||
685 | |||
686 | guest_slicer = GNUNET_SOCIAL_slicer_create (); | ||
687 | GNUNET_SOCIAL_slicer_add (guest_slicer, "", | ||
688 | &guest_recv_method, &guest_recv_modifier, | ||
689 | &guest_recv_data, &guest_recv_eom, NULL); | ||
690 | test = TEST_HOST_ANSWER_DOOR_ADMIT; | ||
691 | //host_announce (); | ||
692 | guest_enter (); | ||
693 | } | ||
694 | |||
695 | |||
696 | void id_guest_created (void *cls, const char *emsg) | ||
697 | { | ||
698 | if (NULL != emsg) | ||
699 | { | ||
700 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
701 | "Could not create guest identity: %s\n", emsg); | ||
702 | #if 0 == DEBUG_SERVICE | ||
703 | GNUNET_assert (0); | ||
704 | #endif | ||
705 | } | ||
706 | |||
707 | GNUNET_IDENTITY_ego_lookup (cfg, guest_name, &id_guest_ego_cb, NULL); | ||
708 | } | ||
709 | |||
710 | |||
711 | void host_entered (void *cls, uint64_t max_message_id) | ||
712 | { | ||
713 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Host entered to place.\n"); | ||
714 | |||
715 | GNUNET_IDENTITY_create (id, guest_name, &id_guest_created, NULL); | ||
716 | } | ||
717 | |||
718 | |||
719 | void id_host_ego_cb (void *cls, const struct GNUNET_IDENTITY_Ego *ego) | ||
720 | { | ||
721 | GNUNET_assert (NULL != ego); | ||
722 | host_ego = ego; | ||
723 | |||
724 | host_slicer = GNUNET_SOCIAL_slicer_create (); | ||
725 | GNUNET_SOCIAL_slicer_add (host_slicer, "", | ||
726 | &host_recv_method, &host_recv_modifier, | ||
727 | &host_recv_data, &host_recv_eom, NULL); | ||
728 | |||
729 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Entering to place as host.\n"); | ||
730 | hst = GNUNET_SOCIAL_host_enter (cfg, host_ego, place_key, | ||
731 | GNUNET_PSYC_CHANNEL_PRIVATE, host_slicer, | ||
732 | &host_entered, &host_answer_door, | ||
733 | &host_farewell, NULL); | ||
734 | } | ||
735 | |||
736 | |||
737 | void id_host_created (void *cls, const char *emsg) | ||
738 | { | ||
739 | if (NULL != emsg) | ||
740 | { | ||
741 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
742 | "Could not create host identity: %s\n", emsg); | ||
743 | #if 0 == DEBUG_SERVICE | ||
744 | GNUNET_assert (0); | ||
745 | #endif | ||
746 | } | ||
747 | |||
748 | GNUNET_IDENTITY_ego_lookup (cfg, host_name, &id_host_ego_cb, NULL); | ||
749 | } | ||
750 | |||
751 | |||
752 | void identity_ego_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego, | ||
753 | void **ctx, const char *name) | ||
754 | { | ||
755 | |||
756 | } | ||
757 | |||
758 | |||
759 | void | ||
760 | core_connected (void *cls, const struct GNUNET_PeerIdentity *my_identity) | ||
761 | { | ||
762 | this_peer = *my_identity; | ||
763 | |||
764 | id = GNUNET_IDENTITY_connect (cfg, &identity_ego_cb, NULL); | ||
765 | GNUNET_IDENTITY_create (id, host_name, &id_host_created, NULL); | ||
766 | } | ||
767 | |||
768 | |||
112 | /** | 769 | /** |
113 | * Main function of the test, run from scheduler. | 770 | * Main function of the test, run from scheduler. |
114 | * | 771 | * |
@@ -116,7 +773,7 @@ end () | |||
116 | * @param cfg configuration we use (also to connect to Social service) | 773 | * @param cfg configuration we use (also to connect to Social service) |
117 | * @param peer handle to access more of the peer (not used) | 774 | * @param peer handle to access more of the peer (not used) |
118 | */ | 775 | */ |
119 | static void | 776 | void |
120 | #if DEBUG_SERVICE | 777 | #if DEBUG_SERVICE |
121 | run (void *cls, char *const *args, const char *cfgfile, | 778 | run (void *cls, char *const *args, const char *cfgfile, |
122 | const struct GNUNET_CONFIGURATION_Handle *c) | 779 | const struct GNUNET_CONFIGURATION_Handle *c) |
@@ -129,9 +786,14 @@ run (void *cls, | |||
129 | cfg = c; | 786 | cfg = c; |
130 | end_badly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL); | 787 | end_badly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL); |
131 | 788 | ||
132 | /* FIXME: add tests */ | 789 | place_key = GNUNET_CRYPTO_eddsa_key_create (); |
790 | guest_key = GNUNET_CRYPTO_ecdsa_key_create (); | ||
133 | 791 | ||
134 | end (); | 792 | GNUNET_CRYPTO_eddsa_key_get_public (place_key, &place_pub_key); |
793 | GNUNET_CRYPTO_ecdsa_key_get_public (guest_key, &guest_pub_key); | ||
794 | |||
795 | core = GNUNET_CORE_connect (cfg, NULL, &core_connected, NULL, NULL, | ||
796 | NULL, GNUNET_NO, NULL, GNUNET_NO, NULL); | ||
135 | } | 797 | } |
136 | 798 | ||
137 | 799 | ||
diff --git a/src/util/client_manager.c b/src/util/client_manager.c index c415ce845..6ab2c7c6d 100644 --- a/src/util/client_manager.c +++ b/src/util/client_manager.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #include "platform.h" | 30 | #include "platform.h" |
31 | #include "gnunet_util_lib.h" | 31 | #include "gnunet_util_lib.h" |
32 | 32 | ||
33 | #define LOG(kind,...) GNUNET_log_from (kind, "util",__VA_ARGS__) | 33 | #define LOG(kind,...) GNUNET_log_from (kind, "util-client-mgr", __VA_ARGS__) |
34 | 34 | ||
35 | 35 | ||
36 | /** | 36 | /** |
@@ -94,6 +94,16 @@ struct GNUNET_CLIENT_MANAGER_Connection | |||
94 | const struct GNUNET_CLIENT_MANAGER_MessageHandler *handlers; | 94 | const struct GNUNET_CLIENT_MANAGER_MessageHandler *handlers; |
95 | 95 | ||
96 | /** | 96 | /** |
97 | * Disconnect callback. | ||
98 | */ | ||
99 | void (*disconnect_cb)(void *); | ||
100 | |||
101 | /** | ||
102 | * Disconnect closure. | ||
103 | */ | ||
104 | void *disconnect_cls; | ||
105 | |||
106 | /** | ||
97 | * User context value. | 107 | * User context value. |
98 | * @see GNUNET_CLIENT_MANAGER_set_user_context() | 108 | * @see GNUNET_CLIENT_MANAGER_set_user_context() |
99 | * @see GNUNET_CLIENT_MANAGER_get_user_context() | 109 | * @see GNUNET_CLIENT_MANAGER_get_user_context() |
@@ -125,7 +135,7 @@ struct GNUNET_CLIENT_MANAGER_Connection | |||
125 | * #GNUNET_YES if GNUNET_CLIENT_MANAGER_disconnect() was called | 135 | * #GNUNET_YES if GNUNET_CLIENT_MANAGER_disconnect() was called |
126 | * and we're transmitting the last messages from the queue. | 136 | * and we're transmitting the last messages from the queue. |
127 | */ | 137 | */ |
128 | uint8_t disconnecting; | 138 | uint8_t is_disconnecting; |
129 | }; | 139 | }; |
130 | 140 | ||
131 | 141 | ||
@@ -185,6 +195,15 @@ static void | |||
185 | transmit_next (struct GNUNET_CLIENT_MANAGER_Connection *mgr); | 195 | transmit_next (struct GNUNET_CLIENT_MANAGER_Connection *mgr); |
186 | 196 | ||
187 | 197 | ||
198 | static void | ||
199 | schedule_disconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
200 | { | ||
201 | struct GNUNET_CLIENT_MANAGER_Connection *mgr = cls; | ||
202 | GNUNET_CLIENT_MANAGER_disconnect (mgr, GNUNET_NO, | ||
203 | mgr->disconnect_cb, mgr->disconnect_cls); | ||
204 | } | ||
205 | |||
206 | |||
188 | /** | 207 | /** |
189 | * Transmit next message to service. | 208 | * Transmit next message to service. |
190 | * | 209 | * |
@@ -221,7 +240,14 @@ send_next_message (void *cls, size_t buf_size, void *buf) | |||
221 | GNUNET_free (mqi); | 240 | GNUNET_free (mqi); |
222 | 241 | ||
223 | if (NULL != mgr->tmit_head) | 242 | if (NULL != mgr->tmit_head) |
243 | { | ||
224 | transmit_next (mgr); | 244 | transmit_next (mgr); |
245 | } | ||
246 | else if (GNUNET_YES == mgr->is_disconnecting) | ||
247 | { | ||
248 | GNUNET_SCHEDULER_add_now (&schedule_disconnect, mgr); | ||
249 | return size; | ||
250 | } | ||
225 | 251 | ||
226 | if (GNUNET_NO == mgr->in_receive) | 252 | if (GNUNET_NO == mgr->in_receive) |
227 | { | 253 | { |
@@ -247,8 +273,9 @@ transmit_next (struct GNUNET_CLIENT_MANAGER_Connection *mgr) | |||
247 | 273 | ||
248 | if (NULL == mgr->tmit_head) | 274 | if (NULL == mgr->tmit_head) |
249 | { | 275 | { |
250 | if (GNUNET_YES == mgr->disconnecting) | 276 | if (GNUNET_YES == mgr->is_disconnecting) |
251 | GNUNET_CLIENT_MANAGER_disconnect (mgr, GNUNET_NO); | 277 | GNUNET_CLIENT_MANAGER_disconnect (mgr, GNUNET_NO, |
278 | mgr->disconnect_cb, mgr->disconnect_cls); | ||
252 | return; | 279 | return; |
253 | } | 280 | } |
254 | 281 | ||
@@ -269,7 +296,7 @@ transmit_next (struct GNUNET_CLIENT_MANAGER_Connection *mgr) | |||
269 | * @param tc Scheduler context. | 296 | * @param tc Scheduler context. |
270 | */ | 297 | */ |
271 | static void | 298 | static void |
272 | reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 299 | schedule_reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
273 | { | 300 | { |
274 | struct GNUNET_CLIENT_MANAGER_Connection *mgr = cls; | 301 | struct GNUNET_CLIENT_MANAGER_Connection *mgr = cls; |
275 | mgr->reconnect_task = GNUNET_SCHEDULER_NO_TASK; | 302 | mgr->reconnect_task = GNUNET_SCHEDULER_NO_TASK; |
@@ -305,7 +332,7 @@ GNUNET_CLIENT_MANAGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
305 | mgr->service_name = service_name; | 332 | mgr->service_name = service_name; |
306 | mgr->handlers = handlers; | 333 | mgr->handlers = handlers; |
307 | mgr->reconnect_delay = GNUNET_TIME_UNIT_ZERO; | 334 | mgr->reconnect_delay = GNUNET_TIME_UNIT_ZERO; |
308 | mgr->reconnect_task = GNUNET_SCHEDULER_add_now (&reconnect, mgr); | 335 | mgr->reconnect_task = GNUNET_SCHEDULER_add_now (&schedule_reconnect, mgr); |
309 | return mgr; | 336 | return mgr; |
310 | } | 337 | } |
311 | 338 | ||
@@ -315,17 +342,25 @@ GNUNET_CLIENT_MANAGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
315 | * | 342 | * |
316 | * @param mgr Client manager connection. | 343 | * @param mgr Client manager connection. |
317 | * @param transmit_queue Transmit pending messages in queue before disconnecting. | 344 | * @param transmit_queue Transmit pending messages in queue before disconnecting. |
345 | * @param disconnect_cb Function called after disconnected from the service. | ||
346 | * @param disconnect_cls Closure for @a disconnect_cb. | ||
318 | */ | 347 | */ |
319 | void | 348 | void |
320 | GNUNET_CLIENT_MANAGER_disconnect (struct GNUNET_CLIENT_MANAGER_Connection *mgr, | 349 | GNUNET_CLIENT_MANAGER_disconnect (struct GNUNET_CLIENT_MANAGER_Connection *mgr, |
321 | int transmit_queue) | 350 | int transmit_queue, |
351 | GNUNET_ContinuationCallback disconnect_cb, | ||
352 | void *disconnect_cls) | ||
322 | { | 353 | { |
354 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting (%d)\n", transmit_queue); | ||
355 | mgr->disconnect_cb = disconnect_cb; | ||
356 | mgr->disconnect_cls = disconnect_cls; | ||
323 | if (NULL != mgr->tmit_head) | 357 | if (NULL != mgr->tmit_head) |
324 | { | 358 | { |
325 | if (GNUNET_YES == transmit_queue) | 359 | if (GNUNET_YES == transmit_queue) |
326 | { | 360 | { |
327 | mgr->disconnecting = GNUNET_YES; | 361 | mgr->is_disconnecting = GNUNET_YES; |
328 | transmit_next (mgr); | 362 | transmit_next (mgr); |
363 | return; | ||
329 | } | 364 | } |
330 | else | 365 | else |
331 | { | 366 | { |
@@ -350,7 +385,10 @@ GNUNET_CLIENT_MANAGER_disconnect (struct GNUNET_CLIENT_MANAGER_Connection *mgr, | |||
350 | GNUNET_CLIENT_disconnect (mgr->client); | 385 | GNUNET_CLIENT_disconnect (mgr->client); |
351 | mgr->client = NULL; | 386 | mgr->client = NULL; |
352 | } | 387 | } |
388 | if (NULL != mgr->disconnect_cb) | ||
389 | mgr->disconnect_cb (mgr->disconnect_cls); | ||
353 | GNUNET_free (mgr); | 390 | GNUNET_free (mgr); |
391 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Disconnected.\n"); | ||
354 | } | 392 | } |
355 | 393 | ||
356 | 394 | ||
@@ -380,7 +418,7 @@ GNUNET_CLIENT_MANAGER_reconnect (struct GNUNET_CLIENT_MANAGER_Connection *mgr) | |||
380 | "Scheduling task to reconnect to service in %s.\n", | 418 | "Scheduling task to reconnect to service in %s.\n", |
381 | GNUNET_STRINGS_relative_time_to_string (mgr->reconnect_delay, GNUNET_YES)); | 419 | GNUNET_STRINGS_relative_time_to_string (mgr->reconnect_delay, GNUNET_YES)); |
382 | mgr->reconnect_task = | 420 | mgr->reconnect_task = |
383 | GNUNET_SCHEDULER_add_delayed (mgr->reconnect_delay, &reconnect, mgr); | 421 | GNUNET_SCHEDULER_add_delayed (mgr->reconnect_delay, &schedule_reconnect, mgr); |
384 | mgr->reconnect_delay = GNUNET_TIME_STD_BACKOFF (mgr->reconnect_delay); | 422 | mgr->reconnect_delay = GNUNET_TIME_STD_BACKOFF (mgr->reconnect_delay); |
385 | } | 423 | } |
386 | 424 | ||