aboutsummaryrefslogtreecommitdiff
path: root/src/multicast/gnunet-service-multicast.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/multicast/gnunet-service-multicast.c')
-rw-r--r--src/multicast/gnunet-service-multicast.c928
1 files changed, 530 insertions, 398 deletions
diff --git a/src/multicast/gnunet-service-multicast.c b/src/multicast/gnunet-service-multicast.c
index de65e0ab7..b068f1308 100644
--- a/src/multicast/gnunet-service-multicast.c
+++ b/src/multicast/gnunet-service-multicast.c
@@ -163,6 +163,16 @@ struct Channel
163 struct GNUNET_PeerIdentity peer; 163 struct GNUNET_PeerIdentity peer;
164 164
165 /** 165 /**
166 * Current window size, set by cadet_notify_window_change()
167 */
168 int32_t window_size;
169
170 /**
171 * Is the connection established?
172 */
173 int8_t is_connected;
174
175 /**
166 * Is the remote peer admitted to the group? 176 * Is the remote peer admitted to the group?
167 * @see enum JoinStatus 177 * @see enum JoinStatus
168 */ 178 */
@@ -336,6 +346,17 @@ struct ReplayRequestKey
336}; 346};
337 347
338 348
349static struct Channel *
350cadet_channel_create (struct Group *grp, struct GNUNET_PeerIdentity *peer);
351
352static void
353cadet_channel_destroy (struct Channel *chn);
354
355static void
356client_send_join_decision (struct Member *mem,
357 const struct MulticastJoinDecisionMessageHeader *hdcsn);
358
359
339/** 360/**
340 * Task run during shutdown. 361 * Task run during shutdown.
341 * 362 *
@@ -497,7 +518,7 @@ replay_req_remove_client (struct Group *grp, struct GNUNET_SERVICE_Client *clien
497 { 518 {
498 if (c == client) 519 if (c == client)
499 { 520 {
500 GNUNET_CONTAINER_multihashmap_remove (replay_req_client, &key, client); 521 GNUNET_CONTAINER_multihashmap_remove (grp_replay_req, &key, client);
501 GNUNET_CONTAINER_multihashmap_iterator_destroy (it); 522 GNUNET_CONTAINER_multihashmap_iterator_destroy (it);
502 return GNUNET_YES; 523 return GNUNET_YES;
503 } 524 }
@@ -653,6 +674,9 @@ client_send_origin (struct GNUNET_HashCode *pub_key_hash,
653static void 674static void
654client_send_ack (struct GNUNET_HashCode *pub_key_hash) 675client_send_ack (struct GNUNET_HashCode *pub_key_hash)
655{ 676{
677 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
678 "Sending message ACK to client.\n");
679
656 static struct GNUNET_MessageHeader *msg = NULL; 680 static struct GNUNET_MessageHeader *msg = NULL;
657 if (NULL == msg) 681 if (NULL == msg)
658 { 682 {
@@ -672,36 +696,6 @@ struct CadetTransmitClosure
672 696
673 697
674/** 698/**
675 * CADET is ready to transmit a message.
676 */
677size_t
678cadet_notify_transmit_ready (void *cls, size_t buf_size, void *buf)
679{
680 if (0 == buf_size)
681 {
682 /* FIXME: connection closed */
683 return 0;
684 }
685 struct CadetTransmitClosure *tcls = cls;
686 struct Channel *chn = tcls->chn;
687 uint16_t msg_size = ntohs (tcls->msg->size);
688 GNUNET_assert (msg_size <= buf_size);
689 GNUNET_memcpy (buf, tcls->msg, msg_size);
690 GNUNET_free (tcls);
691
692 if (0 == chn->msgs_pending)
693 {
694 GNUNET_break (0);
695 }
696 else if (0 == --chn->msgs_pending)
697 {
698 client_send_ack (&chn->group_pub_hash);
699 }
700 return msg_size;
701}
702
703
704/**
705 * Send a message to a CADET channel. 699 * Send a message to a CADET channel.
706 * 700 *
707 * @param chn Channel. 701 * @param chn Channel.
@@ -710,53 +704,22 @@ cadet_notify_transmit_ready (void *cls, size_t buf_size, void *buf)
710static void 704static void
711cadet_send_channel (struct Channel *chn, const struct GNUNET_MessageHeader *msg) 705cadet_send_channel (struct Channel *chn, const struct GNUNET_MessageHeader *msg)
712{ 706{
713 uint16_t msg_size = ntohs (msg->size); 707 struct GNUNET_MQ_Envelope *
714 struct GNUNET_MessageHeader *msg_copy = GNUNET_malloc (msg_size); 708 env = GNUNET_MQ_msg_copy (msg);
715 GNUNET_memcpy (msg_copy, msg, msg_size);
716
717 struct CadetTransmitClosure *tcls = GNUNET_malloc (sizeof (*tcls));
718 tcls->chn = chn;
719 tcls->msg = msg_copy;
720
721 chn->msgs_pending++;
722 chn->tmit_handle
723 = GNUNET_CADET_notify_transmit_ready (chn->channel, GNUNET_NO,
724 GNUNET_TIME_UNIT_FOREVER_REL,
725 msg_size,
726 &cadet_notify_transmit_ready,
727 tcls);
728 GNUNET_assert (NULL != chn->tmit_handle);
729}
730 709
710 GNUNET_MQ_send (GNUNET_CADET_get_mq (chn->channel), env);
731 711
732/** 712 if (0 < chn->window_size)
733 * Create new outgoing CADET channel. 713 {
734 * 714 client_send_ack (&chn->group_pub_hash);
735 * @param peer 715 }
736 * Peer to connect to. 716 else
737 * @param group_pub_key 717 {
738 * Public key of group the channel belongs to. 718 chn->msgs_pending++;
739 * @param group_pub_hash 719 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
740 * Hash of @a group_pub_key. 720 "%p Queuing message. Pending messages: %u\n",
741 * 721 chn, chn->msgs_pending);
742 * @return Channel. 722 }
743 */
744static struct Channel *
745cadet_channel_create (struct Group *grp, struct GNUNET_PeerIdentity *peer)
746{
747 struct Channel *chn = GNUNET_malloc (sizeof (*chn));
748 chn->group = grp;
749 chn->group_pub_key = grp->pub_key;
750 chn->group_pub_hash = grp->pub_key_hash;
751 chn->peer = *peer;
752 chn->direction = DIR_OUTGOING;
753 chn->join_status = JOIN_WAITING;
754 chn->channel = GNUNET_CADET_channel_create (cadet, chn, &chn->peer,
755 &grp->cadet_port_hash,
756 GNUNET_CADET_OPTION_RELIABLE);
757 GNUNET_CONTAINER_multihashmap_put (channels_out, &chn->group_pub_hash, chn,
758 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
759 return chn;
760} 723}
761 724
762 725
@@ -787,7 +750,7 @@ cadet_send_join_decision_cb (void *cls,
787 const struct MulticastJoinDecisionMessageHeader *hdcsn = cls; 750 const struct MulticastJoinDecisionMessageHeader *hdcsn = cls;
788 struct Channel *chn = channel; 751 struct Channel *chn = channel;
789 752
790 const struct MulticastJoinDecisionMessage *dcsn = 753 const struct MulticastJoinDecisionMessage *dcsn =
791 (struct MulticastJoinDecisionMessage *) &hdcsn[1]; 754 (struct MulticastJoinDecisionMessage *) &hdcsn[1];
792 755
793 if (0 == memcmp (&hdcsn->member_pub_key, &chn->member_pub_key, sizeof (chn->member_pub_key)) 756 if (0 == memcmp (&hdcsn->member_pub_key, &chn->member_pub_key, sizeof (chn->member_pub_key))
@@ -870,31 +833,74 @@ cadet_send_parents (struct GNUNET_HashCode *pub_key_hash,
870 833
871 834
872/** 835/**
873 * New incoming CADET channel. 836 * CADET channel connect handler.
837 *
838 * @see GNUNET_CADET_ConnectEventHandler()
874 */ 839 */
875static void * 840static void *
876cadet_notify_channel_new (void *cls, 841cadet_notify_connect (void *cls,
877 struct GNUNET_CADET_Channel *channel, 842 struct GNUNET_CADET_Channel *channel,
878 const struct GNUNET_PeerIdentity *initiator, 843 const struct GNUNET_PeerIdentity *source)
879 const struct GNUNET_HashCode *port, 844{
880 enum GNUNET_CADET_ChannelOption options) 845 struct Channel *chn = GNUNET_malloc (sizeof *chn);
846 chn->group = cls;
847 chn->channel = channel;
848 chn->direction = DIR_INCOMING;
849 chn->join_status = JOIN_NOT_ASKED;
850
851 GNUNET_CONTAINER_multihashmap_put (channels_in, &chn->group_pub_hash, chn,
852 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
853 return chn;
854}
855
856
857/**
858 * CADET window size change handler.
859 *
860 * @see GNUNET_CADET_WindowSizeEventHandler()
861 */
862static void
863cadet_notify_window_change (void *cls,
864 const struct GNUNET_CADET_Channel *channel,
865 int window_size)
881{ 866{
882 return NULL; 867 struct Channel *chn = cls;
868
869 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
870 "%p Window size changed to %d. Pending messages: %u\n",
871 chn, window_size, chn->msgs_pending);
872
873 chn->is_connected = GNUNET_YES;
874 chn->window_size = (int32_t) window_size;
875
876 for (int i = 0; i < window_size; i++)
877 {
878 if (0 < chn->msgs_pending)
879 {
880 client_send_ack (&chn->group_pub_hash);
881 chn->msgs_pending--;
882 }
883 else
884 {
885 break;
886 }
887 }
883} 888}
884 889
885 890
886/** 891/**
887 * CADET channel is being destroyed. 892 * CADET channel disconnect handler.
893 *
894 * @see GNUNET_CADET_DisconnectEventHandler()
888 */ 895 */
889static void 896static void
890cadet_notify_channel_end (void *cls, 897cadet_notify_disconnect (void *cls,
891 const struct GNUNET_CADET_Channel *channel, 898 const struct GNUNET_CADET_Channel *channel)
892 void *ctx)
893{ 899{
894 if (NULL == ctx) 900 if (NULL == cls)
895 return; 901 return;
896 902
897 struct Channel *chn = ctx; 903 struct Channel *chn = cls;
898 if (NULL != chn->group) 904 if (NULL != chn->group)
899 { 905 {
900 if (GNUNET_NO == chn->group->is_origin) 906 if (GNUNET_NO == chn->group->is_origin)
@@ -905,12 +911,331 @@ cadet_notify_channel_end (void *cls,
905 } 911 }
906 } 912 }
907 913
908 while (GNUNET_YES == replay_req_remove_cadet (chn)); 914 int ret;
915 do
916 {
917 ret = replay_req_remove_cadet (chn);
918 }
919 while (GNUNET_YES == ret);
909 920
910 GNUNET_free (chn); 921 GNUNET_free (chn);
911} 922}
912 923
913 924
925static int
926check_cadet_join_request (void *cls,
927 const struct MulticastJoinRequestMessage *req)
928{
929 struct Channel *chn = cls;
930
931 if (NULL == chn
932 || JOIN_NOT_ASKED != chn->join_status)
933 {
934 return GNUNET_SYSERR;
935 }
936
937 uint16_t size = ntohs (req->header.size);
938 if (size < sizeof (*req))
939 {
940 GNUNET_break_op (0);
941 return GNUNET_SYSERR;
942 }
943 if (ntohl (req->purpose.size) != (size
944 - sizeof (req->header)
945 - sizeof (req->reserved)
946 - sizeof (req->signature)))
947 {
948 GNUNET_break_op (0);
949 return GNUNET_SYSERR;
950 }
951 if (GNUNET_OK !=
952 GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_MULTICAST_REQUEST,
953 &req->purpose, &req->signature,
954 &req->member_pub_key))
955 {
956 GNUNET_break_op (0);
957 return GNUNET_SYSERR;
958 }
959
960 return GNUNET_OK;
961}
962
963
964/**
965 * Incoming join request message from CADET.
966 */
967static void
968handle_cadet_join_request (void *cls,
969 const struct MulticastJoinRequestMessage *req)
970{
971 struct Channel *chn = cls;
972 GNUNET_CADET_receive_done (chn->channel);
973
974 struct GNUNET_HashCode group_pub_hash;
975 GNUNET_CRYPTO_hash (&req->group_pub_key, sizeof (req->group_pub_key), &group_pub_hash);
976 chn->group_pub_key = req->group_pub_key;
977 chn->group_pub_hash = group_pub_hash;
978 chn->member_pub_key = req->member_pub_key;
979 chn->peer = req->peer;
980 chn->join_status = JOIN_WAITING;
981
982 client_send_all (&group_pub_hash, &req->header);
983}
984
985
986static int
987check_cadet_join_decision (void *cls,
988 const struct MulticastJoinDecisionMessageHeader *hdcsn)
989{
990 uint16_t size = ntohs (hdcsn->header.size);
991 if (size < sizeof (struct MulticastJoinDecisionMessageHeader) +
992 sizeof (struct MulticastJoinDecisionMessage))
993 {
994 GNUNET_break_op (0);
995 return GNUNET_SYSERR;
996 }
997
998 struct Channel *chn = cls;
999 if (NULL == chn)
1000 {
1001 GNUNET_break (0);
1002 return GNUNET_SYSERR;
1003 }
1004 if (NULL == chn->group || GNUNET_NO != chn->group->is_origin)
1005 {
1006 GNUNET_break (0);
1007 return GNUNET_SYSERR;
1008 }
1009 switch (chn->join_status)
1010 {
1011 case JOIN_REFUSED:
1012 return GNUNET_SYSERR;
1013
1014 case JOIN_ADMITTED:
1015 return GNUNET_OK;
1016
1017 case JOIN_NOT_ASKED:
1018 case JOIN_WAITING:
1019 break;
1020 }
1021
1022 return GNUNET_OK;
1023}
1024
1025
1026/**
1027 * Incoming join decision message from CADET.
1028 */
1029static void
1030handle_cadet_join_decision (void *cls,
1031 const struct MulticastJoinDecisionMessageHeader *hdcsn)
1032{
1033 const struct MulticastJoinDecisionMessage *
1034 dcsn = (const struct MulticastJoinDecisionMessage *) &hdcsn[1];
1035
1036 struct Channel *chn = cls;
1037 GNUNET_CADET_receive_done (chn->channel);
1038
1039 // FIXME: do we need to copy chn->peer or compare it with hdcsn->peer?
1040 struct Member *mem = (struct Member *) chn->group;
1041 client_send_join_decision (mem, hdcsn);
1042 if (GNUNET_YES == ntohl (dcsn->is_admitted))
1043 {
1044 chn->join_status = JOIN_ADMITTED;
1045 }
1046 else
1047 {
1048 chn->join_status = JOIN_REFUSED;
1049 cadet_channel_destroy (chn);
1050 }
1051}
1052
1053
1054static int
1055check_cadet_message (void *cls,
1056 const struct GNUNET_MULTICAST_MessageHeader *msg)
1057{
1058 uint16_t size = ntohs (msg->header.size);
1059 if (size < sizeof (*msg))
1060 {
1061 GNUNET_break_op (0);
1062 return GNUNET_SYSERR;
1063 }
1064
1065 struct Channel *chn = cls;
1066 if (NULL == chn)
1067 {
1068 GNUNET_break (0);
1069 return GNUNET_SYSERR;
1070 }
1071 if (ntohl (msg->purpose.size) != (size
1072 - sizeof (msg->header)
1073 - sizeof (msg->hop_counter)
1074 - sizeof (msg->signature)))
1075 {
1076 GNUNET_break_op (0);
1077 return GNUNET_SYSERR;
1078 }
1079 if (GNUNET_OK !=
1080 GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_MULTICAST_MESSAGE,
1081 &msg->purpose, &msg->signature,
1082 &chn->group_pub_key))
1083 {
1084 GNUNET_break_op (0);
1085 return GNUNET_SYSERR;
1086 }
1087
1088 return GNUNET_OK;
1089}
1090
1091
1092/**
1093 * Incoming multicast message from CADET.
1094 */
1095static void
1096handle_cadet_message (void *cls,
1097 const struct GNUNET_MULTICAST_MessageHeader *msg)
1098{
1099 struct Channel *chn = cls;
1100 GNUNET_CADET_receive_done (chn->channel);
1101 client_send_all (&chn->group_pub_hash, &msg->header);
1102}
1103
1104
1105static int
1106check_cadet_request (void *cls,
1107 const struct GNUNET_MULTICAST_RequestHeader *req)
1108{
1109 uint16_t size = ntohs (req->header.size);
1110 if (size < sizeof (*req))
1111 {
1112 GNUNET_break_op (0);
1113 return GNUNET_SYSERR;
1114 }
1115
1116 struct Channel *chn = cls;
1117 if (NULL == chn)
1118 {
1119 GNUNET_break (0);
1120 return GNUNET_SYSERR;
1121 }
1122 if (ntohl (req->purpose.size) != (size
1123 - sizeof (req->header)
1124 - sizeof (req->member_pub_key)
1125 - sizeof (req->signature)))
1126 {
1127 GNUNET_break_op (0);
1128 return GNUNET_SYSERR;
1129 }
1130 if (GNUNET_OK !=
1131 GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_MULTICAST_REQUEST,
1132 &req->purpose, &req->signature,
1133 &req->member_pub_key))
1134 {
1135 GNUNET_break_op (0);
1136 return GNUNET_SYSERR;
1137 }
1138
1139 return GNUNET_OK;
1140}
1141
1142
1143/**
1144 * Incoming multicast request message from CADET.
1145 */
1146static void
1147handle_cadet_request (void *cls,
1148 const struct GNUNET_MULTICAST_RequestHeader *req)
1149{
1150 struct Channel *chn = cls;
1151 GNUNET_CADET_receive_done (chn->channel);
1152 client_send_origin (&chn->group_pub_hash, &req->header);
1153}
1154
1155
1156static int
1157check_cadet_replay_request (void *cls,
1158 const struct MulticastReplayRequestMessage *req)
1159{
1160 uint16_t size = ntohs (req->header.size);
1161 if (size < sizeof (*req))
1162 {
1163 GNUNET_break_op (0);
1164 return GNUNET_SYSERR;
1165 }
1166
1167 struct Channel *chn = cls;
1168 if (NULL == chn)
1169 {
1170 GNUNET_break_op (0);
1171 return GNUNET_SYSERR;
1172 }
1173
1174 return GNUNET_OK;
1175}
1176
1177
1178/**
1179 * Incoming multicast replay request from CADET.
1180 */
1181static void
1182handle_cadet_replay_request (void *cls,
1183 const struct MulticastReplayRequestMessage *req)
1184{
1185 struct Channel *chn = cls;
1186 GNUNET_CADET_receive_done (chn->channel);
1187
1188 struct MulticastReplayRequestMessage rep = *req;
1189 GNUNET_memcpy (&rep.member_pub_key, &chn->member_pub_key, sizeof (chn->member_pub_key));
1190
1191 struct GNUNET_CONTAINER_MultiHashMap *
1192 grp_replay_req = GNUNET_CONTAINER_multihashmap_get (replay_req_cadet,
1193 &chn->group->pub_key_hash);
1194 if (NULL == grp_replay_req)
1195 {
1196 grp_replay_req = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO);
1197 GNUNET_CONTAINER_multihashmap_put (replay_req_cadet,
1198 &chn->group->pub_key_hash, grp_replay_req,
1199 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
1200 }
1201 struct GNUNET_HashCode key_hash;
1202 replay_key_hash (rep.fragment_id, rep.message_id, rep.fragment_offset,
1203 rep.flags, &key_hash);
1204 GNUNET_CONTAINER_multihashmap_put (grp_replay_req, &key_hash, chn,
1205 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1206
1207 client_send_random (&chn->group_pub_hash, &rep.header);
1208}
1209
1210
1211static int
1212check_cadet_replay_response (void *cls,
1213 const struct MulticastReplayResponseMessage *res)
1214{
1215 struct Channel *chn = cls;
1216 if (NULL == chn)
1217 {
1218 GNUNET_break (0);
1219 return GNUNET_SYSERR;
1220 }
1221 return GNUNET_OK;
1222}
1223
1224
1225/**
1226 * Incoming multicast replay response from CADET.
1227 */
1228static void
1229handle_cadet_replay_response (void *cls,
1230 const struct MulticastReplayResponseMessage *res)
1231{
1232 struct Channel *chn = cls;
1233 GNUNET_CADET_receive_done (chn->channel);
1234
1235 /* @todo FIXME: got replay error response, send request to other members */
1236}
1237
1238
914static void 1239static void
915group_set_cadet_port_hash (struct Group *grp) 1240group_set_cadet_port_hash (struct Group *grp)
916{ 1241{
@@ -925,6 +1250,78 @@ group_set_cadet_port_hash (struct Group *grp)
925} 1250}
926 1251
927 1252
1253
1254/**
1255 * Create new outgoing CADET channel.
1256 *
1257 * @param peer
1258 * Peer to connect to.
1259 * @param group_pub_key
1260 * Public key of group the channel belongs to.
1261 * @param group_pub_hash
1262 * Hash of @a group_pub_key.
1263 *
1264 * @return Channel.
1265 */
1266static struct Channel *
1267cadet_channel_create (struct Group *grp, struct GNUNET_PeerIdentity *peer)
1268{
1269 struct Channel *chn = GNUNET_malloc (sizeof (*chn));
1270 chn->group = grp;
1271 chn->group_pub_key = grp->pub_key;
1272 chn->group_pub_hash = grp->pub_key_hash;
1273 chn->peer = *peer;
1274 chn->direction = DIR_OUTGOING;
1275 chn->is_connected = GNUNET_NO;
1276 chn->join_status = JOIN_WAITING;
1277
1278 struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
1279 GNUNET_MQ_hd_var_size (cadet_message,
1280 GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE,
1281 struct GNUNET_MULTICAST_MessageHeader,
1282 chn),
1283
1284 GNUNET_MQ_hd_var_size (cadet_join_decision,
1285 GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION,
1286 struct MulticastJoinDecisionMessageHeader,
1287 chn),
1288
1289 GNUNET_MQ_hd_var_size (cadet_replay_request,
1290 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST,
1291 struct MulticastReplayRequestMessage,
1292 chn),
1293
1294 GNUNET_MQ_hd_var_size (cadet_replay_response,
1295 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_RESPONSE,
1296 struct MulticastReplayResponseMessage,
1297 chn),
1298
1299 GNUNET_MQ_handler_end ()
1300 };
1301
1302 chn->channel = GNUNET_CADET_channel_creatE (cadet, chn, &chn->peer,
1303 &grp->cadet_port_hash,
1304 GNUNET_CADET_OPTION_RELIABLE,
1305 cadet_notify_window_change,
1306 cadet_notify_disconnect,
1307 cadet_handlers);
1308 GNUNET_CONTAINER_multihashmap_put (channels_out, &chn->group_pub_hash, chn,
1309 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1310 return chn;
1311}
1312
1313
1314/**
1315 * Destroy outgoing CADET channel.
1316 */
1317static void
1318cadet_channel_destroy (struct Channel *chn)
1319{
1320 GNUNET_CADET_channel_destroy (chn->channel);
1321 GNUNET_CONTAINER_multihashmap_remove_all (channels_out, &chn->group_pub_hash);
1322 GNUNET_free (chn);
1323}
1324
928/** 1325/**
929 * Handle a connecting client starting an origin. 1326 * Handle a connecting client starting an origin.
930 */ 1327 */
@@ -961,8 +1358,44 @@ handle_client_origin_start (void *cls,
961 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); 1358 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
962 1359
963 group_set_cadet_port_hash (grp); 1360 group_set_cadet_port_hash (grp);
964 orig->cadet_port = GNUNET_CADET_open_port (cadet, &grp->cadet_port_hash, 1361
965 cadet_notify_channel_new, NULL); 1362 struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
1363 GNUNET_MQ_hd_var_size (cadet_message,
1364 GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE,
1365 struct GNUNET_MULTICAST_MessageHeader,
1366 grp),
1367
1368 GNUNET_MQ_hd_var_size (cadet_request,
1369 GNUNET_MESSAGE_TYPE_MULTICAST_REQUEST,
1370 struct GNUNET_MULTICAST_RequestHeader,
1371 grp),
1372
1373 GNUNET_MQ_hd_var_size (cadet_join_request,
1374 GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_REQUEST,
1375 struct MulticastJoinRequestMessage,
1376 grp),
1377
1378 GNUNET_MQ_hd_var_size (cadet_replay_request,
1379 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST,
1380 struct MulticastReplayRequestMessage,
1381 grp),
1382
1383 GNUNET_MQ_hd_var_size (cadet_replay_response,
1384 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_RESPONSE,
1385 struct MulticastReplayResponseMessage,
1386 grp),
1387
1388 GNUNET_MQ_handler_end ()
1389 };
1390
1391
1392 orig->cadet_port = GNUNET_CADET_open_porT (cadet,
1393 &grp->cadet_port_hash,
1394 cadet_notify_connect,
1395 NULL,
1396 cadet_notify_window_change,
1397 cadet_notify_disconnect,
1398 cadet_handlers);
966 } 1399 }
967 else 1400 else
968 { 1401 {
@@ -1258,10 +1691,8 @@ handle_client_multicast_message (void *cls,
1258 } 1691 }
1259 1692
1260 client_send_all (&grp->pub_key_hash, &out->header); 1693 client_send_all (&grp->pub_key_hash, &out->header);
1261 if (0 == cadet_send_children (&grp->pub_key_hash, &out->header)) 1694 cadet_send_children (&grp->pub_key_hash, &out->header);
1262 { 1695 client_send_ack (&grp->pub_key_hash);
1263 client_send_ack (&grp->pub_key_hash);
1264 }
1265 GNUNET_free (out); 1696 GNUNET_free (out);
1266 1697
1267 GNUNET_SERVICE_client_continue (client); 1698 GNUNET_SERVICE_client_continue (client);
@@ -1544,278 +1975,6 @@ handle_client_replay_response (void *cls,
1544 1975
1545 1976
1546/** 1977/**
1547 * Incoming join request message from CADET.
1548 */
1549int
1550cadet_recv_join_request (void *cls,
1551 struct GNUNET_CADET_Channel *channel,
1552 void **ctx,
1553 const struct GNUNET_MessageHeader *m)
1554{
1555 GNUNET_CADET_receive_done(channel);
1556 const struct MulticastJoinRequestMessage *
1557 req = (const struct MulticastJoinRequestMessage *) m;
1558 uint16_t size = ntohs (m->size);
1559 if (size < sizeof (*req))
1560 {
1561 GNUNET_break_op (0);
1562 return GNUNET_SYSERR;
1563 }
1564 if (NULL != *ctx)
1565 {
1566 GNUNET_break_op (0);
1567 return GNUNET_SYSERR;
1568 }
1569 if (ntohl (req->purpose.size) != (size
1570 - sizeof (req->header)
1571 - sizeof (req->reserved)
1572 - sizeof (req->signature)))
1573 {
1574 GNUNET_break_op (0);
1575 return GNUNET_SYSERR;
1576 }
1577 if (GNUNET_OK !=
1578 GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_MULTICAST_REQUEST,
1579 &req->purpose, &req->signature,
1580 &req->member_pub_key))
1581 {
1582 GNUNET_break_op (0);
1583 return GNUNET_SYSERR;
1584 }
1585
1586 struct GNUNET_HashCode group_pub_hash;
1587 GNUNET_CRYPTO_hash (&req->group_pub_key, sizeof (req->group_pub_key), &group_pub_hash);
1588
1589 struct Channel *chn = GNUNET_malloc (sizeof *chn);
1590 chn->channel = channel;
1591 chn->group_pub_key = req->group_pub_key;
1592 chn->group_pub_hash = group_pub_hash;
1593 chn->member_pub_key = req->member_pub_key;
1594 chn->peer = req->peer;
1595 chn->join_status = JOIN_WAITING;
1596 GNUNET_CONTAINER_multihashmap_put (channels_in, &chn->group_pub_hash, chn,
1597 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1598 *ctx = chn;
1599
1600 client_send_all (&group_pub_hash, m);
1601 return GNUNET_OK;
1602}
1603
1604
1605/**
1606 * Incoming join decision message from CADET.
1607 */
1608int
1609cadet_recv_join_decision (void *cls,
1610 struct GNUNET_CADET_Channel *channel,
1611 void **ctx,
1612 const struct GNUNET_MessageHeader *m)
1613{
1614 GNUNET_CADET_receive_done (channel);
1615 const struct MulticastJoinDecisionMessageHeader *
1616 hdcsn = (const struct MulticastJoinDecisionMessageHeader *) m;
1617 const struct MulticastJoinDecisionMessage *
1618 dcsn = (const struct MulticastJoinDecisionMessage *) &hdcsn[1];
1619 uint16_t size = ntohs (m->size);
1620 if (size < sizeof (struct MulticastJoinDecisionMessageHeader) +
1621 sizeof (struct MulticastJoinDecisionMessage))
1622 {
1623 GNUNET_break_op (0);
1624 return GNUNET_SYSERR;
1625 }
1626 struct Channel *chn = *ctx;
1627 if (NULL == chn)
1628 {
1629 GNUNET_break_op (0);
1630 return GNUNET_SYSERR;
1631 }
1632 if (NULL == chn->group || GNUNET_NO != chn->group->is_origin)
1633 {
1634 GNUNET_break_op (0);
1635 return GNUNET_SYSERR;
1636 }
1637 switch (chn->join_status)
1638 {
1639 case JOIN_REFUSED:
1640 return GNUNET_SYSERR;
1641
1642 case JOIN_ADMITTED:
1643 return GNUNET_OK;
1644
1645 case JOIN_NOT_ASKED:
1646 case JOIN_WAITING:
1647 break;
1648 }
1649
1650 // FIXME: do we need to copy chn->peer or compare it with hdcsn->peer?
1651 struct Member *mem = (struct Member *) chn->group;
1652 client_send_join_decision (mem, hdcsn);
1653 if (GNUNET_YES == ntohl (dcsn->is_admitted))
1654 {
1655 chn->join_status = JOIN_ADMITTED;
1656 return GNUNET_OK;
1657 }
1658 else
1659 {
1660 chn->join_status = JOIN_REFUSED;
1661 return GNUNET_SYSERR;
1662 }
1663}
1664
1665/**
1666 * Incoming multicast message from CADET.
1667 */
1668int
1669cadet_recv_message (void *cls,
1670 struct GNUNET_CADET_Channel *channel,
1671 void **ctx,
1672 const struct GNUNET_MessageHeader *m)
1673{
1674 GNUNET_CADET_receive_done(channel);
1675 const struct GNUNET_MULTICAST_MessageHeader *
1676 msg = (const struct GNUNET_MULTICAST_MessageHeader *) m;
1677 uint16_t size = ntohs (m->size);
1678 if (size < sizeof (*msg))
1679 {
1680 GNUNET_break_op (0);
1681 return GNUNET_SYSERR;
1682 }
1683 struct Channel *chn = *ctx;
1684 if (NULL == chn)
1685 {
1686 GNUNET_break_op (0);
1687 return GNUNET_SYSERR;
1688 }
1689 if (ntohl (msg->purpose.size) != (size
1690 - sizeof (msg->header)
1691 - sizeof (msg->hop_counter)
1692 - sizeof (msg->signature)))
1693 {
1694 GNUNET_break_op (0);
1695 return GNUNET_SYSERR;
1696 }
1697 if (GNUNET_OK !=
1698 GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_MULTICAST_MESSAGE,
1699 &msg->purpose, &msg->signature,
1700 &chn->group_pub_key))
1701 {
1702 GNUNET_break_op (0);
1703 return GNUNET_SYSERR;
1704 }
1705
1706 client_send_all (&chn->group_pub_hash, m);
1707 return GNUNET_OK;
1708}
1709
1710
1711/**
1712 * Incoming multicast request message from CADET.
1713 */
1714int
1715cadet_recv_request (void *cls,
1716 struct GNUNET_CADET_Channel *channel,
1717 void **ctx,
1718 const struct GNUNET_MessageHeader *m)
1719{
1720 GNUNET_CADET_receive_done(channel);
1721 const struct GNUNET_MULTICAST_RequestHeader *
1722 req = (const struct GNUNET_MULTICAST_RequestHeader *) m;
1723 uint16_t size = ntohs (m->size);
1724 if (size < sizeof (*req))
1725 {
1726 GNUNET_break_op (0);
1727 return GNUNET_SYSERR;
1728 }
1729 struct Channel *chn = *ctx;
1730 if (NULL == chn)
1731 {
1732 GNUNET_break_op (0);
1733 return GNUNET_SYSERR;
1734 }
1735 if (ntohl (req->purpose.size) != (size
1736 - sizeof (req->header)
1737 - sizeof (req->member_pub_key)
1738 - sizeof (req->signature)))
1739 {
1740 GNUNET_break_op (0);
1741 return GNUNET_SYSERR;
1742 }
1743 if (GNUNET_OK !=
1744 GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_MULTICAST_REQUEST,
1745 &req->purpose, &req->signature,
1746 &req->member_pub_key))
1747 {
1748 GNUNET_break_op (0);
1749 return GNUNET_SYSERR;
1750 }
1751
1752 client_send_origin (&chn->group_pub_hash, m);
1753 return GNUNET_OK;
1754}
1755
1756
1757/**
1758 * Incoming multicast replay request from CADET.
1759 */
1760int
1761cadet_recv_replay_request (void *cls,
1762 struct GNUNET_CADET_Channel *channel,
1763 void **ctx,
1764 const struct GNUNET_MessageHeader *m)
1765{
1766 GNUNET_CADET_receive_done(channel);
1767 struct MulticastReplayRequestMessage rep;
1768 uint16_t size = ntohs (m->size);
1769 if (size < sizeof (rep))
1770 {
1771 GNUNET_break_op (0);
1772 return GNUNET_SYSERR;
1773 }
1774 struct Channel *chn = *ctx;
1775
1776 GNUNET_memcpy (&rep, m, sizeof (rep));
1777 GNUNET_memcpy (&rep.member_pub_key, &chn->member_pub_key, sizeof (chn->member_pub_key));
1778
1779 struct GNUNET_CONTAINER_MultiHashMap *
1780 grp_replay_req = GNUNET_CONTAINER_multihashmap_get (replay_req_cadet,
1781 &chn->group->pub_key_hash);
1782 if (NULL == grp_replay_req)
1783 {
1784 grp_replay_req = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO);
1785 GNUNET_CONTAINER_multihashmap_put (replay_req_cadet,
1786 &chn->group->pub_key_hash, grp_replay_req,
1787 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
1788 }
1789 struct GNUNET_HashCode key_hash;
1790 replay_key_hash (rep.fragment_id, rep.message_id, rep.fragment_offset,
1791 rep.flags, &key_hash);
1792 GNUNET_CONTAINER_multihashmap_put (grp_replay_req, &key_hash, chn,
1793 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1794
1795 client_send_random (&chn->group_pub_hash, &rep.header);
1796 return GNUNET_OK;
1797}
1798
1799
1800/**
1801 * Incoming multicast replay response from CADET.
1802 */
1803int
1804cadet_recv_replay_response (void *cls,
1805 struct GNUNET_CADET_Channel *channel,
1806 void **ctx,
1807 const struct GNUNET_MessageHeader *m)
1808{
1809 GNUNET_CADET_receive_done(channel);
1810 //struct Channel *chn = *ctx;
1811
1812 /* @todo FIXME: got replay error response, send request to other members */
1813
1814 return GNUNET_OK;
1815}
1816
1817
1818/**
1819 * A new client connected. 1978 * A new client connected.
1820 * 1979 *
1821 * @param cls NULL 1980 * @param cls NULL
@@ -1899,32 +2058,6 @@ client_notify_disconnect (void *cls,
1899 2058
1900 2059
1901/** 2060/**
1902 * Message handlers for CADET.
1903 */
1904static const struct GNUNET_CADET_MessageHandler cadet_handlers[] = {
1905 { cadet_recv_join_request,
1906 GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_REQUEST, 0 },
1907
1908 { cadet_recv_join_decision,
1909 GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION, 0 },
1910
1911 { cadet_recv_message,
1912 GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE, 0 },
1913
1914 { cadet_recv_request,
1915 GNUNET_MESSAGE_TYPE_MULTICAST_REQUEST, 0 },
1916
1917 { cadet_recv_replay_request,
1918 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST, 0 },
1919
1920 { cadet_recv_replay_response,
1921 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_RESPONSE, 0 },
1922
1923 { NULL, 0, 0 }
1924};
1925
1926
1927/**
1928 * Service started. 2061 * Service started.
1929 * 2062 *
1930 * @param cls closure 2063 * @param cls closure
@@ -1949,9 +2082,8 @@ run (void *cls,
1949 replay_req_cadet = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); 2082 replay_req_cadet = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO);
1950 replay_req_client = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); 2083 replay_req_client = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO);
1951 2084
1952 cadet = GNUNET_CADET_connect (cfg, NULL, 2085 cadet = GNUNET_CADET_connecT (cfg);
1953 cadet_notify_channel_end, 2086
1954 cadet_handlers);
1955 GNUNET_assert (NULL != cadet); 2087 GNUNET_assert (NULL != cadet);
1956 2088
1957 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, 2089 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,