aboutsummaryrefslogtreecommitdiff
path: root/src/social/gnunet-service-social.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/social/gnunet-service-social.c')
-rw-r--r--src/social/gnunet-service-social.c267
1 files changed, 170 insertions, 97 deletions
diff --git a/src/social/gnunet-service-social.c b/src/social/gnunet-service-social.c
index 828506c07..85679c63c 100644
--- a/src/social/gnunet-service-social.c
+++ b/src/social/gnunet-service-social.c
@@ -296,6 +296,11 @@ struct Host
296 struct GNUNET_CONTAINER_MultiHashMap *join_reqs; 296 struct GNUNET_CONTAINER_MultiHashMap *join_reqs;
297 297
298 /** 298 /**
299 * Messages being relayed.
300 */
301 struct GNUNET_CONTAINER_MultiHashMap *relay_msgs;
302
303 /**
299 * @see enum GNUNET_PSYC_Policy 304 * @see enum GNUNET_PSYC_Policy
300 */ 305 */
301 enum GNUNET_PSYC_Policy policy; 306 enum GNUNET_PSYC_Policy policy;
@@ -407,6 +412,15 @@ static void
407cleanup_place (struct Place *plc); 412cleanup_place (struct Place *plc);
408 413
409 414
415static struct MessageTransmitQueue *
416psyc_transmit_queue_message (struct Place *plc,
417 struct GNUNET_SERVER_Client *client,
418 size_t data_size,
419 const void *data,
420 uint16_t first_ptype, uint16_t last_ptype,
421 struct MessageTransmitQueue *tmit_msg);
422
423
410int 424int
411place_entry_cleanup (void *cls, const struct GNUNET_HashCode *key, void *value) 425place_entry_cleanup (void *cls, const struct GNUNET_HashCode *key, void *value)
412{ 426{
@@ -471,6 +485,7 @@ cleanup_host (struct Host *hst)
471 if (NULL != hst->master) 485 if (NULL != hst->master)
472 GNUNET_PSYC_master_stop (hst->master, GNUNET_NO, NULL, NULL); // FIXME 486 GNUNET_PSYC_master_stop (hst->master, GNUNET_NO, NULL, NULL); // FIXME
473 GNUNET_CONTAINER_multihashmap_destroy (hst->join_reqs); 487 GNUNET_CONTAINER_multihashmap_destroy (hst->join_reqs);
488 GNUNET_CONTAINER_multihashmap_destroy (hst->relay_msgs);
474 GNUNET_CONTAINER_multihashmap_remove (hosts, &plc->pub_key_hash, plc); 489 GNUNET_CONTAINER_multihashmap_remove (hosts, &plc->pub_key_hash, plc);
475} 490}
476 491
@@ -746,8 +761,6 @@ psyc_recv_join_dcsn (void *cls,
746 */ 761 */
747static void 762static void
748psyc_recv_message (void *cls, 763psyc_recv_message (void *cls,
749 uint64_t message_id,
750 uint32_t flags,
751 const struct GNUNET_PSYC_MessageHeader *msg) 764 const struct GNUNET_PSYC_MessageHeader *msg)
752{ 765{
753 struct Place *plc = cls; 766 struct Place *plc = cls;
@@ -765,71 +778,122 @@ psyc_recv_message (void *cls,
765 778
766 779
767static void 780static void
781host_relay_message_part (struct Host *hst,
782 const struct GNUNET_MessageHeader *pmsg,
783 const struct GNUNET_CRYPTO_EcdsaPublicKey *nym_pub_key)
784{
785 /* separate queue per nym */
786 struct GNUNET_HashCode nym_pub_hash;
787 GNUNET_CRYPTO_hash (nym_pub_key, sizeof (*nym_pub_key), &nym_pub_hash);
788
789 struct MessageTransmitQueue *
790 tmit_msg = GNUNET_CONTAINER_multihashmap_get (hst->relay_msgs, &nym_pub_hash);
791
792 uint16_t ptype = ntohs (pmsg->type);
793
794 if (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_METHOD == ptype)
795 {
796 /* FIXME: last message was unfinished, cancel & remove from queue */
797 }
798
799 tmit_msg = psyc_transmit_queue_message (&hst->plc, NULL, ntohs (pmsg->size),
800 pmsg, ptype, ptype, tmit_msg);
801
802 switch (ptype)
803 {
804 case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_METHOD:
805 GNUNET_CONTAINER_multihashmap_put (hst->relay_msgs, &nym_pub_hash, tmit_msg,
806 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
807 break;
808 case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_END:
809 case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_CANCEL:
810 GNUNET_CONTAINER_multihashmap_remove (hst->relay_msgs, &nym_pub_hash, tmit_msg);
811 break;
812 }
813}
814
815
816static void
768place_recv_relay_method (void *cls, 817place_recv_relay_method (void *cls,
818 const struct GNUNET_PSYC_MessageHeader *msg,
769 const struct GNUNET_PSYC_MessageMethod *meth, 819 const struct GNUNET_PSYC_MessageMethod *meth,
770 uint64_t message_id, 820 uint64_t message_id,
771 uint32_t flags,
772 uint64_t fragment_offset,
773 uint32_t tmit_flags,
774 const struct GNUNET_CRYPTO_EcdsaPublicKey *nym_pub_key,
775 const char *method_name) 821 const char *method_name)
776{ 822{
777 struct Host *hst = cls; 823 struct Place *plc = cls;
778 struct Place *plc = &hst->plc;
779
780 824
825 if (GNUNET_PSYC_MESSAGE_REQUEST & ntohs (msg->flags)
826 && GNUNET_YES == plc->is_host);
827 {
828 struct Host *hst = cls;
829 host_relay_message_part (hst, &meth->header, &msg->slave_pub_key);
830 }
781} 831}
782 832
783 833
784static void 834static void
785place_recv_relay_modifier (void *cls, 835place_recv_relay_modifier (void *cls,
786 const struct GNUNET_MessageHeader *msg, 836 const struct GNUNET_PSYC_MessageHeader *msg,
837 const struct GNUNET_MessageHeader *pmsg,
787 uint64_t message_id, 838 uint64_t message_id,
788 uint32_t flags,
789 uint64_t fragment_offset,
790 enum GNUNET_PSYC_Operator oper, 839 enum GNUNET_PSYC_Operator oper,
791 const char *name, 840 const char *name,
792 const void *value, 841 const void *value,
793 uint16_t value_size, 842 uint16_t value_size,
794 uint16_t full_value_size) 843 uint16_t full_value_size)
795{ 844{
845 struct Place *plc = cls;
796 846
847 if (GNUNET_PSYC_MESSAGE_REQUEST & ntohs (msg->flags)
848 && GNUNET_YES == plc->is_host);
849 {
850 struct Host *hst = cls;
851 host_relay_message_part (hst, pmsg, &msg->slave_pub_key);
852 }
797} 853}
798 854
799
800static void 855static void
801place_recv_relay_eom (void *cls, 856place_recv_relay_data (void *cls,
802 const struct GNUNET_MessageHeader *msg, 857 const struct GNUNET_PSYC_MessageHeader *msg,
803 uint64_t message_id, 858 const struct GNUNET_MessageHeader *pmsg,
804 uint32_t flags, 859 uint64_t message_id,
805 uint64_t fragment_offset, 860 const void *data,
806 uint8_t cancelled) 861 uint16_t data_size)
807{ 862{
863 struct Place *plc = cls;
808 864
865 if (GNUNET_PSYC_MESSAGE_REQUEST & ntohs (msg->flags)
866 && GNUNET_YES == plc->is_host);
867 {
868 struct Host *hst = cls;
869 host_relay_message_part (hst, pmsg, &msg->slave_pub_key);
870 }
809} 871}
810 872
811 873
812static void 874static void
813place_recv_relay_data (void *cls, 875place_recv_relay_eom (void *cls,
814 const struct GNUNET_MessageHeader *msg, 876 const struct GNUNET_PSYC_MessageHeader *msg,
815 uint64_t message_id, 877 const struct GNUNET_MessageHeader *pmsg,
816 uint32_t flags, 878 uint64_t message_id,
817 uint64_t fragment_offset, 879 uint8_t is_cancelled)
818 const void *data,
819 uint16_t data_size)
820{ 880{
881 struct Place *plc = cls;
821 882
883 if (GNUNET_PSYC_MESSAGE_REQUEST & ntohs (msg->flags)
884 && GNUNET_YES == plc->is_host);
885 {
886 struct Host *hst = cls;
887 host_relay_message_part (hst, pmsg, &msg->slave_pub_key);
888 }
822} 889}
823 890
824 891
825static void 892static void
826place_recv_save_method (void *cls, 893place_recv_save_method (void *cls,
894 const struct GNUNET_PSYC_MessageHeader *msg,
827 const struct GNUNET_PSYC_MessageMethod *meth, 895 const struct GNUNET_PSYC_MessageMethod *meth,
828 uint64_t message_id, 896 uint64_t message_id,
829 uint32_t flags,
830 uint64_t fragment_offset,
831 uint32_t tmit_flags,
832 const struct GNUNET_CRYPTO_EcdsaPublicKey *nym_pub_key,
833 const char *method_name) 897 const char *method_name)
834{ 898{
835 struct Place *plc = cls; 899 struct Place *plc = cls;
@@ -841,28 +905,26 @@ place_recv_save_method (void *cls,
841 GNUNET_h2s_full (&plc->pub_key_hash), sizeof (place_pub_hash_ascii)); 905 GNUNET_h2s_full (&plc->pub_key_hash), sizeof (place_pub_hash_ascii));
842 906
843 char *filename = NULL; 907 char *filename = NULL;
844 GNUNET_asprintf (&filename, "%s%c%s%c%s%c%.part" PRIu64, 908 GNUNET_asprintf (&filename, "%s%c" "%s%c" "%s%c" "%" PRIu64 ".part",
845 dir_social, DIR_SEPARATOR, 909 dir_social, DIR_SEPARATOR,
846 "files", DIR_SEPARATOR, 910 "files", DIR_SEPARATOR,
847 place_pub_hash_ascii.encoding, DIR_SEPARATOR, 911 place_pub_hash_ascii.encoding, DIR_SEPARATOR,
848 message_id); 912 GNUNET_ntohll (msg->message_id));
849 913
850 /* save if does not already exist */ 914 /* save if does not already exist */
851 if (GNUNET_NO == GNUNET_DISK_file_test (filename)) 915 if (GNUNET_YES != GNUNET_DISK_file_test (filename))
852 { 916 {
853 plc->file_save = GNUNET_YES; 917 plc->file_save = GNUNET_YES;
854 } 918 }
855
856 GNUNET_free (filename); 919 GNUNET_free (filename);
857} 920}
858 921
859 922
860static void 923static void
861place_recv_save_data (void *cls, 924place_recv_save_data (void *cls,
862 const struct GNUNET_MessageHeader *msg, 925 const struct GNUNET_PSYC_MessageHeader *msg,
926 const struct GNUNET_MessageHeader *pmsg,
863 uint64_t message_id, 927 uint64_t message_id,
864 uint32_t flags,
865 uint64_t fragment_offset,
866 const void *data, 928 const void *data,
867 uint16_t data_size) 929 uint16_t data_size)
868{ 930{
@@ -875,11 +937,11 @@ place_recv_save_data (void *cls,
875 GNUNET_h2s_full (&plc->pub_key_hash), sizeof (place_pub_hash_ascii)); 937 GNUNET_h2s_full (&plc->pub_key_hash), sizeof (place_pub_hash_ascii));
876 938
877 char *filename = NULL; 939 char *filename = NULL;
878 GNUNET_asprintf (&filename, "%s%c%s%c%s%c%.part" PRIu64, 940 GNUNET_asprintf (&filename, "%s%c" "%s%c" "%s%c" "%" PRIu64 ".part",
879 dir_social, DIR_SEPARATOR, 941 dir_social, DIR_SEPARATOR,
880 "files", DIR_SEPARATOR, 942 "files", DIR_SEPARATOR,
881 place_pub_hash_ascii.encoding, DIR_SEPARATOR, 943 place_pub_hash_ascii.encoding, DIR_SEPARATOR,
882 message_id); 944 GNUNET_ntohll (msg->message_id));
883 GNUNET_DISK_directory_create_for_file (filename); 945 GNUNET_DISK_directory_create_for_file (filename);
884 struct GNUNET_DISK_FileHandle * 946 struct GNUNET_DISK_FileHandle *
885 fh = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_WRITE, 947 fh = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_WRITE,
@@ -896,11 +958,10 @@ place_recv_save_data (void *cls,
896 958
897static void 959static void
898place_recv_save_eom (void *cls, 960place_recv_save_eom (void *cls,
899 const struct GNUNET_MessageHeader *msg, 961 const struct GNUNET_PSYC_MessageHeader *msg,
962 const struct GNUNET_MessageHeader *pmsg,
900 uint64_t message_id, 963 uint64_t message_id,
901 uint32_t flags, 964 uint8_t is_cancelled)
902 uint64_t fragment_offset,
903 uint8_t cancelled)
904{ 965{
905 struct Place *plc = cls; 966 struct Place *plc = cls;
906 if (GNUNET_YES != plc->file_save) 967 if (GNUNET_YES != plc->file_save)
@@ -910,19 +971,14 @@ place_recv_save_eom (void *cls,
910 memcpy (&place_pub_hash_ascii.encoding, 971 memcpy (&place_pub_hash_ascii.encoding,
911 GNUNET_h2s_full (&plc->pub_key_hash), sizeof (place_pub_hash_ascii)); 972 GNUNET_h2s_full (&plc->pub_key_hash), sizeof (place_pub_hash_ascii));
912 973
913 char *fn_part = NULL;
914 GNUNET_asprintf (&fn_part, "%s%c%s%c%s%c%.part" PRIu64,
915 dir_social, DIR_SEPARATOR,
916 "files", DIR_SEPARATOR,
917 place_pub_hash_ascii.encoding, DIR_SEPARATOR,
918 message_id);
919
920 char *fn = NULL; 974 char *fn = NULL;
921 GNUNET_asprintf (&fn, "%s%c%s%c%s%c%" PRIu64, 975 GNUNET_asprintf (&fn, "%s%c%s%c%s%c%" PRIu64,
922 dir_social, DIR_SEPARATOR, 976 dir_social, DIR_SEPARATOR,
923 "files", DIR_SEPARATOR, 977 "files", DIR_SEPARATOR,
924 place_pub_hash_ascii.encoding, DIR_SEPARATOR, 978 place_pub_hash_ascii.encoding, DIR_SEPARATOR,
925 message_id); 979 GNUNET_ntohll (msg->message_id));
980 char *fn_part = NULL;
981 GNUNET_asprintf (&fn_part, "%s.part", fn);
926 982
927 rename (fn_part, fn); 983 rename (fn_part, fn);
928 984
@@ -937,9 +993,10 @@ place_recv_save_eom (void *cls,
937static void 993static void
938place_init (struct Place *plc) 994place_init (struct Place *plc)
939{ 995{
940 996 plc->slicer = GNUNET_PSYC_slicer_create ();
941} 997}
942 998
999
943/** 1000/**
944 * Add a place to the @e places hash map. 1001 * Add a place to the @e places hash map.
945 * 1002 *
@@ -1054,8 +1111,7 @@ app_place_add (const char *app_id,
1054 } 1111 }
1055 } 1112 }
1056 1113
1057 1114 size_t app_id_size = strlen (app_id) + 1;
1058 size_t app_id_size = strlen (app_id);
1059 void *app_id_value = GNUNET_malloc (app_id_size); 1115 void *app_id_value = GNUNET_malloc (app_id_size);
1060 memcpy (app_id_value, app_id, app_id_size); 1116 memcpy (app_id_value, app_id, app_id_size);
1061 1117
@@ -1142,21 +1198,28 @@ app_place_save (const char *app_id,
1142 1198
1143int 1199int
1144app_place_remove (const char *app_id, 1200app_place_remove (const char *app_id,
1201 const struct GNUNET_CRYPTO_EcdsaPublicKey *ego_pub_key,
1145 const struct GNUNET_CRYPTO_EddsaPublicKey *place_pub_key) 1202 const struct GNUNET_CRYPTO_EddsaPublicKey *place_pub_key)
1146{ 1203{
1204 struct GNUNET_HashCode ego_pub_hash;
1147 struct GNUNET_HashCode place_pub_hash; 1205 struct GNUNET_HashCode place_pub_hash;
1206 GNUNET_CRYPTO_hash (ego_pub_key, sizeof (*ego_pub_key), &ego_pub_hash);
1148 GNUNET_CRYPTO_hash (place_pub_key, sizeof (*place_pub_key), &place_pub_hash); 1207 GNUNET_CRYPTO_hash (place_pub_key, sizeof (*place_pub_key), &place_pub_hash);
1149 1208
1209 struct GNUNET_CRYPTO_HashAsciiEncoded ego_pub_hash_ascii;
1150 struct GNUNET_CRYPTO_HashAsciiEncoded place_pub_hash_ascii; 1210 struct GNUNET_CRYPTO_HashAsciiEncoded place_pub_hash_ascii;
1211 memcpy (&ego_pub_hash_ascii.encoding,
1212 GNUNET_h2s_full (&ego_pub_hash), sizeof (ego_pub_hash_ascii));
1151 memcpy (&place_pub_hash_ascii.encoding, 1213 memcpy (&place_pub_hash_ascii.encoding,
1152 GNUNET_h2s_full (&place_pub_hash), sizeof (place_pub_hash_ascii)); 1214 GNUNET_h2s_full (&place_pub_hash), sizeof (place_pub_hash_ascii));
1153 1215
1154 char *app_place_filename = NULL; 1216 char *app_place_filename = NULL;
1155 GNUNET_asprintf (&app_place_filename, 1217 GNUNET_asprintf (&app_place_filename,
1156 "%s%c" "%s%/", 1218 "%s%c" "%s%c" "%s%c" "%s%c" "%s",
1157 dir_social, DIR_SEPARATOR, 1219 dir_social, DIR_SEPARATOR,
1158 "apps", DIR_SEPARATOR, 1220 "apps", DIR_SEPARATOR,
1159 app_id, DIR_SEPARATOR, 1221 app_id, DIR_SEPARATOR,
1222 ego_pub_hash_ascii.encoding, DIR_SEPARATOR,
1160 place_pub_hash_ascii.encoding); 1223 place_pub_hash_ascii.encoding);
1161 1224
1162 struct GNUNET_HashCode app_id_hash; 1225 struct GNUNET_HashCode app_id_hash;
@@ -1175,23 +1238,24 @@ app_place_remove (const char *app_id,
1175 void *app_id_value = GNUNET_CONTAINER_multihashmap_get (place_apps, &app_id_hash); 1238 void *app_id_value = GNUNET_CONTAINER_multihashmap_get (place_apps, &app_id_hash);
1176 if (NULL != app_id_value) 1239 if (NULL != app_id_value)
1177 { 1240 {
1241 GNUNET_CONTAINER_multihashmap_remove (place_apps, &app_id_hash, app_id_value);
1178 GNUNET_free (app_id_value); 1242 GNUNET_free (app_id_value);
1179 GNUNET_CONTAINER_multihashmap_remove_all (place_apps, &app_id_hash);
1180 } 1243 }
1181 } 1244 }
1182 1245
1246 int ret = GNUNET_OK;
1183 1247
1184 int ret = unlink (app_place_filename); 1248 if (0 != unlink (app_place_filename))
1185 GNUNET_free (app_place_filename);
1186 if (0 != ret)
1187 { 1249 {
1188 GNUNET_break (0); 1250 GNUNET_break (0);
1189 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1251 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1190 "Error removing app place: unlink returned %d\n", errno); 1252 "Error removing app place file: %s: %s\n",
1191 return GNUNET_SYSERR; 1253 app_place_filename, strerror (errno), errno);
1254 ret = GNUNET_SYSERR;
1192 } 1255 }
1256 GNUNET_free (app_place_filename);
1193 1257
1194 return GNUNET_OK; 1258 return ret;
1195} 1259}
1196 1260
1197 1261
@@ -1222,13 +1286,13 @@ host_enter (const struct HostEnterRequest *hreq, struct Host **ret_hst)
1222 hst = GNUNET_new (struct Host); 1286 hst = GNUNET_new (struct Host);
1223 hst->policy = hreq->policy; 1287 hst->policy = hreq->policy;
1224 hst->join_reqs = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); 1288 hst->join_reqs = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO);
1289 hst->relay_msgs = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO);
1225 1290
1226 struct Place *plc = &hst->plc; 1291 struct Place *plc = &hst->plc;
1227 place_init (plc); 1292 place_init (plc);
1228 plc->is_host = GNUNET_YES; 1293 plc->is_host = GNUNET_YES;
1229 plc->pub_key = hreq->place_pub_key; 1294 plc->pub_key = hreq->place_pub_key;
1230 plc->pub_key_hash = place_pub_hash; 1295 plc->pub_key_hash = place_pub_hash;
1231 plc->slicer = GNUNET_PSYC_slicer_create ();
1232 1296
1233 GNUNET_CONTAINER_multihashmap_put (hosts, &plc->pub_key_hash, plc, 1297 GNUNET_CONTAINER_multihashmap_put (hosts, &plc->pub_key_hash, plc,
1234 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 1298 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
@@ -1294,7 +1358,7 @@ client_recv_msg_proc_set (void *cls, struct GNUNET_SERVER_Client *client,
1294 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1358 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1295 return; 1359 return;
1296 } 1360 }
1297 1361#if 0
1298 GNUNET_PSYC_slicer_method_remove (plc->slicer, method_prefix, 1362 GNUNET_PSYC_slicer_method_remove (plc->slicer, method_prefix,
1299 place_recv_relay_method, 1363 place_recv_relay_method,
1300 place_recv_relay_modifier, 1364 place_recv_relay_modifier,
@@ -1305,10 +1369,10 @@ client_recv_msg_proc_set (void *cls, struct GNUNET_SERVER_Client *client,
1305 NULL, 1369 NULL,
1306 place_recv_save_data, 1370 place_recv_save_data,
1307 place_recv_save_eom); 1371 place_recv_save_eom);
1308 1372#endif
1309 if (flags & GNUNET_SOCIAL_MSG_PROC_RELAY) 1373 if (flags & GNUNET_SOCIAL_MSG_PROC_RELAY)
1310 { 1374 {
1311 GNUNET_PSYC_slicer_method_add (plc->slicer, method_prefix, 1375 GNUNET_PSYC_slicer_method_add (plc->slicer, method_prefix, NULL,
1312 place_recv_relay_method, 1376 place_recv_relay_method,
1313 place_recv_relay_modifier, 1377 place_recv_relay_modifier,
1314 place_recv_relay_data, 1378 place_recv_relay_data,
@@ -1317,7 +1381,7 @@ client_recv_msg_proc_set (void *cls, struct GNUNET_SERVER_Client *client,
1317 } 1381 }
1318 if (flags & GNUNET_SOCIAL_MSG_PROC_SAVE) 1382 if (flags & GNUNET_SOCIAL_MSG_PROC_SAVE)
1319 { 1383 {
1320 GNUNET_PSYC_slicer_method_add (plc->slicer, method_prefix, 1384 GNUNET_PSYC_slicer_method_add (plc->slicer, method_prefix, NULL,
1321 place_recv_save_method, 1385 place_recv_save_method,
1322 NULL, 1386 NULL,
1323 place_recv_save_data, 1387 place_recv_save_data,
@@ -1540,7 +1604,6 @@ guest_enter (const struct GuestEnterRequest *greq, struct Guest **ret_gst)
1540 plc->ego_pub_key = ego_pub_key; 1604 plc->ego_pub_key = ego_pub_key;
1541 plc->ego_pub_hash = ego_pub_hash; 1605 plc->ego_pub_hash = ego_pub_hash;
1542 plc->ego_key = ego->key; 1606 plc->ego_key = ego->key;
1543 plc->slicer = GNUNET_PSYC_slicer_create ();
1544 1607
1545 if (NULL == plc_gst) 1608 if (NULL == plc_gst)
1546 { 1609 {
@@ -1920,16 +1983,18 @@ client_recv_app_connect (void *cls, struct GNUNET_SERVER_Client *client,
1920 */ 1983 */
1921static void 1984static void
1922client_recv_app_detach (void *cls, struct GNUNET_SERVER_Client *client, 1985client_recv_app_detach (void *cls, struct GNUNET_SERVER_Client *client,
1923 const struct GNUNET_MessageHeader *msg) 1986 const struct GNUNET_MessageHeader *msg)
1924{ 1987{
1925 struct Client * 1988 struct Client *
1926 ctx = GNUNET_SERVER_client_get_user_context (client, struct Client); 1989 ctx = GNUNET_SERVER_client_get_user_context (client, struct Client);
1927 GNUNET_assert (NULL != ctx); 1990 GNUNET_assert (NULL != ctx);
1928 1991
1992 struct Place *plc = ctx->plc;
1993
1929 const struct AppDetachRequest *req 1994 const struct AppDetachRequest *req
1930 = (const struct AppDetachRequest *) msg; 1995 = (const struct AppDetachRequest *) msg;
1931 1996
1932 int ret = app_place_remove (ctx->app_id, &req->place_pub_key); 1997 int ret = app_place_remove (ctx->app_id, &plc->ego_pub_key, &req->place_pub_key);
1933 client_send_result (client, req->op_id, ret, NULL, 0); 1998 client_send_result (client, req->op_id, ret, NULL, 0);
1934 1999
1935 GNUNET_SERVER_receive_done (client, GNUNET_OK); 2000 GNUNET_SERVER_receive_done (client, GNUNET_OK);
@@ -1939,7 +2004,9 @@ client_recv_app_detach (void *cls, struct GNUNET_SERVER_Client *client,
1939int 2004int
1940app_places_entry_remove (void *cls, const struct GNUNET_HashCode *key, void *value) 2005app_places_entry_remove (void *cls, const struct GNUNET_HashCode *key, void *value)
1941{ 2006{
1942 app_place_remove (value, cls); 2007 struct Place *plc = cls;
2008 const char *app_id = value;
2009 app_place_remove (app_id, &plc->ego_pub_key, &plc->pub_key);
1943 return GNUNET_YES; 2010 return GNUNET_YES;
1944} 2011}
1945 2012
@@ -1962,7 +2029,7 @@ client_recv_place_leave (void *cls, struct GNUNET_SERVER_Client *client,
1962 place_apps = GNUNET_CONTAINER_multihashmap_get (places_apps, &plc->pub_key_hash); 2029 place_apps = GNUNET_CONTAINER_multihashmap_get (places_apps, &plc->pub_key_hash);
1963 if (NULL != place_apps) 2030 if (NULL != place_apps)
1964 { 2031 {
1965 GNUNET_CONTAINER_multihashmap_iterate (place_apps, app_places_entry_remove, &plc->pub_key); 2032 GNUNET_CONTAINER_multihashmap_iterate (place_apps, app_places_entry_remove, plc);
1966 } 2033 }
1967 2034
1968 /* FIXME: disconnect from the network, but keep local connection for history access */ 2035 /* FIXME: disconnect from the network, but keep local connection for history access */
@@ -2459,15 +2526,14 @@ guest_transmit_notify_mod (void *cls, uint16_t *data_size, void *data,
2459 * @param tmit_msg 2526 * @param tmit_msg
2460 * Next item in message transmission queue. 2527 * Next item in message transmission queue.
2461 * @param[out] pmeth 2528 * @param[out] pmeth
2462 * The message method is returned here. 2529 * The malloc'd message method is returned here.
2463 * 2530 *
2464 * @return #GNUNET_OK on success 2531 * @return #GNUNET_OK on success
2465 * #GNUNET_NO if there are no more messages in queue. 2532 * #GNUNET_NO if there are no more messages in queue.
2466 * #GNUNET_SYSERR if the next message is malformed. 2533 * #GNUNET_SYSERR if the next message is malformed.
2467 */ 2534 */
2468static int 2535static struct GNUNET_PSYC_MessageMethod *
2469psyc_transmit_queue_next_method (struct Place *plc, 2536psyc_transmit_queue_next_method (struct Place *plc)
2470 struct GNUNET_PSYC_MessageMethod **pmeth)
2471{ 2537{
2472 struct MessageTransmitQueue *tmit_msg = plc->tmit_msgs_head; 2538 struct MessageTransmitQueue *tmit_msg = plc->tmit_msgs_head;
2473 if (NULL == tmit_msg) 2539 if (NULL == tmit_msg)
@@ -2488,25 +2554,28 @@ psyc_transmit_queue_next_method (struct Place *plc,
2488 "%p psyc_transmit_queue_next_method: unexpected message part of type %u.\n", 2554 "%p psyc_transmit_queue_next_method: unexpected message part of type %u.\n",
2489 plc, NULL != pmsg ? ntohs (pmsg->type) : 0); 2555 plc, NULL != pmsg ? ntohs (pmsg->type) : 0);
2490 GNUNET_break (0); 2556 GNUNET_break (0);
2491 return GNUNET_SYSERR; 2557 return NULL;
2492 } 2558 }
2493 2559
2494 uint16_t psize = ntohs (pmsg->size); 2560 uint16_t psize = ntohs (pmsg->size);
2495 *pmeth = (struct GNUNET_PSYC_MessageMethod *) pmsg; 2561 struct GNUNET_PSYC_MessageMethod *
2496 if (psize < sizeof (**pmeth) + 1 || '\0' != *((char *) *pmeth + psize - 1)) 2562 pmeth = (struct GNUNET_PSYC_MessageMethod *) GNUNET_copy_message (pmsg);
2563
2564 if (psize < sizeof (*pmeth) + 1 || '\0' != *((char *) pmeth + psize - 1))
2497 { 2565 {
2498 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2566 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2499 "%p psyc_transmit_queue_next_method: invalid method name.\n", 2567 "%p psyc_transmit_queue_next_method: invalid method name.\n",
2500 plc, ntohs (pmsg->type)); 2568 plc, ntohs (pmsg->type));
2501 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2569 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2502 "%u <= %u || NUL != %u\n", 2570 "%u <= %u || NUL != %u\n",
2503 sizeof (**pmeth), psize, *((char *) *pmeth + psize - 1)); 2571 sizeof (*pmeth), psize, *((char *) pmeth + psize - 1));
2504 GNUNET_break (0); 2572 GNUNET_break (0);
2505 return GNUNET_SYSERR; 2573 GNUNET_free (pmeth);
2574 return NULL;
2506 } 2575 }
2507 2576
2508 psyc_transmit_queue_next_part (plc, tmit_msg, tmit_frag); 2577 psyc_transmit_queue_next_part (plc, tmit_msg, tmit_frag);
2509 return GNUNET_OK; 2578 return pmeth;
2510} 2579}
2511 2580
2512 2581
@@ -2516,19 +2585,21 @@ psyc_transmit_queue_next_method (struct Place *plc,
2516static int 2585static int
2517psyc_master_transmit_message (struct Host *hst) 2586psyc_master_transmit_message (struct Host *hst)
2518{ 2587{
2588 struct Place *plc = &hst->plc;
2519 2589
2520 if (NULL == hst->tmit_handle) 2590 if (NULL == hst->tmit_handle)
2521 { 2591 {
2522 struct GNUNET_PSYC_MessageMethod *pmeth = NULL; 2592 struct GNUNET_PSYC_MessageMethod *
2523 int ret = psyc_transmit_queue_next_method (&hst->plc, &pmeth); 2593 pmeth = psyc_transmit_queue_next_method (plc);
2524 if (GNUNET_OK != ret) 2594 if (NULL == pmeth)
2525 return ret; 2595 return GNUNET_SYSERR;
2526 2596
2527 hst->tmit_handle 2597 hst->tmit_handle
2528 = GNUNET_PSYC_master_transmit (hst->master, (const char *) &pmeth[1], 2598 = GNUNET_PSYC_master_transmit (hst->master, (const char *) &pmeth[1],
2529 &host_transmit_notify_mod, 2599 &host_transmit_notify_mod,
2530 &host_transmit_notify_data, hst, 2600 &host_transmit_notify_data, hst,
2531 pmeth->flags); 2601 pmeth->flags);
2602 GNUNET_free (pmeth);
2532 } 2603 }
2533 else 2604 else
2534 { 2605 {
@@ -2544,18 +2615,21 @@ psyc_master_transmit_message (struct Host *hst)
2544static int 2615static int
2545psyc_slave_transmit_message (struct Guest *gst) 2616psyc_slave_transmit_message (struct Guest *gst)
2546{ 2617{
2618 struct Place *plc = &gst->plc;
2619
2547 if (NULL == gst->tmit_handle) 2620 if (NULL == gst->tmit_handle)
2548 { 2621 {
2549 struct GNUNET_PSYC_MessageMethod *pmeth = NULL; 2622 struct GNUNET_PSYC_MessageMethod *
2550 int ret = psyc_transmit_queue_next_method (&gst->plc, &pmeth); 2623 pmeth = psyc_transmit_queue_next_method (plc);
2551 if (GNUNET_OK != ret) 2624 if (NULL == pmeth)
2552 return ret; 2625 return GNUNET_SYSERR;
2553 2626
2554 gst->tmit_handle 2627 gst->tmit_handle
2555 = GNUNET_PSYC_slave_transmit (gst->slave, (const char *) &pmeth[1], 2628 = GNUNET_PSYC_slave_transmit (gst->slave, (const char *) &pmeth[1],
2556 &guest_transmit_notify_mod, 2629 &guest_transmit_notify_mod,
2557 &guest_transmit_notify_data, gst, 2630 &guest_transmit_notify_data, gst,
2558 pmeth->flags); 2631 pmeth->flags);
2632 GNUNET_free (pmeth);
2559 } 2633 }
2560 else 2634 else
2561 { 2635 {
@@ -2723,15 +2797,14 @@ client_recv_psyc_message (void *cls, struct GNUNET_SERVER_Client *client,
2723 * A historic message arrived from PSYC. 2797 * A historic message arrived from PSYC.
2724 */ 2798 */
2725static void 2799static void
2726psyc_recv_history_message (void *cls, uint64_t message_id, uint32_t flags, 2800psyc_recv_history_message (void *cls, const struct GNUNET_PSYC_MessageHeader *msg)
2727 const struct GNUNET_PSYC_MessageHeader *msg)
2728{ 2801{
2729 struct OperationClosure *opcls = cls; 2802 struct OperationClosure *opcls = cls;
2730 struct Place *plc = opcls->plc; 2803 struct Place *plc = opcls->plc;
2731 2804
2732 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2805 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2733 "%p Received historic message #%" PRId64 " (flags: %x)\n", 2806 "%p Received historic message #%" PRId64 " (flags: %x)\n",
2734 plc, message_id, flags); 2807 plc, GNUNET_ntohll (msg->message_id), ntohl (msg->flags));
2735 2808
2736 uint16_t size = ntohs (msg->header.size); 2809 uint16_t size = ntohs (msg->header.size);
2737 2810
@@ -2807,14 +2880,14 @@ client_recv_history_replay (void *cls, struct GNUNET_SERVER_Client *client,
2807 GNUNET_ntohll (req->start_message_id), 2880 GNUNET_ntohll (req->start_message_id),
2808 GNUNET_ntohll (req->end_message_id), 2881 GNUNET_ntohll (req->end_message_id),
2809 method_prefix, opcls->flags, 2882 method_prefix, opcls->flags,
2810 &psyc_recv_history_message, NULL, 2883 psyc_recv_history_message, NULL,
2811 &psyc_recv_history_result, opcls); 2884 psyc_recv_history_result, opcls);
2812 else 2885 else
2813 GNUNET_PSYC_channel_history_replay_latest (plc->channel, 2886 GNUNET_PSYC_channel_history_replay_latest (plc->channel,
2814 GNUNET_ntohll (req->message_limit), 2887 GNUNET_ntohll (req->message_limit),
2815 method_prefix, opcls->flags, 2888 method_prefix, opcls->flags,
2816 &psyc_recv_history_message, NULL, 2889 psyc_recv_history_message, NULL,
2817 &psyc_recv_history_result, opcls); 2890 psyc_recv_history_result, opcls);
2818 2891
2819 GNUNET_SERVER_receive_done (client, GNUNET_OK); 2892 GNUNET_SERVER_receive_done (client, GNUNET_OK);
2820} 2893}