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.c931
1 files changed, 533 insertions, 398 deletions
diff --git a/src/multicast/gnunet-service-multicast.c b/src/multicast/gnunet-service-multicast.c
index de65e0ab7..9683efcff 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 *
@@ -443,6 +464,9 @@ replay_key_hash (uint64_t fragment_id, uint64_t message_id,
443static int 464static int
444replay_req_remove_cadet (struct Channel *chn) 465replay_req_remove_cadet (struct Channel *chn)
445{ 466{
467 if (NULL == chn || NULL == chn->group)
468 return GNUNET_SYSERR;
469
446 struct GNUNET_CONTAINER_MultiHashMap * 470 struct GNUNET_CONTAINER_MultiHashMap *
447 grp_replay_req = GNUNET_CONTAINER_multihashmap_get (replay_req_cadet, 471 grp_replay_req = GNUNET_CONTAINER_multihashmap_get (replay_req_cadet,
448 &chn->group->pub_key_hash); 472 &chn->group->pub_key_hash);
@@ -497,7 +521,7 @@ replay_req_remove_client (struct Group *grp, struct GNUNET_SERVICE_Client *clien
497 { 521 {
498 if (c == client) 522 if (c == client)
499 { 523 {
500 GNUNET_CONTAINER_multihashmap_remove (replay_req_client, &key, client); 524 GNUNET_CONTAINER_multihashmap_remove (grp_replay_req, &key, client);
501 GNUNET_CONTAINER_multihashmap_iterator_destroy (it); 525 GNUNET_CONTAINER_multihashmap_iterator_destroy (it);
502 return GNUNET_YES; 526 return GNUNET_YES;
503 } 527 }
@@ -653,6 +677,9 @@ client_send_origin (struct GNUNET_HashCode *pub_key_hash,
653static void 677static void
654client_send_ack (struct GNUNET_HashCode *pub_key_hash) 678client_send_ack (struct GNUNET_HashCode *pub_key_hash)
655{ 679{
680 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
681 "Sending message ACK to client.\n");
682
656 static struct GNUNET_MessageHeader *msg = NULL; 683 static struct GNUNET_MessageHeader *msg = NULL;
657 if (NULL == msg) 684 if (NULL == msg)
658 { 685 {
@@ -672,36 +699,6 @@ struct CadetTransmitClosure
672 699
673 700
674/** 701/**
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. 702 * Send a message to a CADET channel.
706 * 703 *
707 * @param chn Channel. 704 * @param chn Channel.
@@ -710,53 +707,22 @@ cadet_notify_transmit_ready (void *cls, size_t buf_size, void *buf)
710static void 707static void
711cadet_send_channel (struct Channel *chn, const struct GNUNET_MessageHeader *msg) 708cadet_send_channel (struct Channel *chn, const struct GNUNET_MessageHeader *msg)
712{ 709{
713 uint16_t msg_size = ntohs (msg->size); 710 struct GNUNET_MQ_Envelope *
714 struct GNUNET_MessageHeader *msg_copy = GNUNET_malloc (msg_size); 711 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 712
713 GNUNET_MQ_send (GNUNET_CADET_get_mq (chn->channel), env);
731 714
732/** 715 if (0 < chn->window_size)
733 * Create new outgoing CADET channel. 716 {
734 * 717 client_send_ack (&chn->group_pub_hash);
735 * @param peer 718 }
736 * Peer to connect to. 719 else
737 * @param group_pub_key 720 {
738 * Public key of group the channel belongs to. 721 chn->msgs_pending++;
739 * @param group_pub_hash 722 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
740 * Hash of @a group_pub_key. 723 "%p Queuing message. Pending messages: %u\n",
741 * 724 chn, chn->msgs_pending);
742 * @return Channel. 725 }
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} 726}
761 727
762 728
@@ -787,7 +753,7 @@ cadet_send_join_decision_cb (void *cls,
787 const struct MulticastJoinDecisionMessageHeader *hdcsn = cls; 753 const struct MulticastJoinDecisionMessageHeader *hdcsn = cls;
788 struct Channel *chn = channel; 754 struct Channel *chn = channel;
789 755
790 const struct MulticastJoinDecisionMessage *dcsn = 756 const struct MulticastJoinDecisionMessage *dcsn =
791 (struct MulticastJoinDecisionMessage *) &hdcsn[1]; 757 (struct MulticastJoinDecisionMessage *) &hdcsn[1];
792 758
793 if (0 == memcmp (&hdcsn->member_pub_key, &chn->member_pub_key, sizeof (chn->member_pub_key)) 759 if (0 == memcmp (&hdcsn->member_pub_key, &chn->member_pub_key, sizeof (chn->member_pub_key))
@@ -870,31 +836,74 @@ cadet_send_parents (struct GNUNET_HashCode *pub_key_hash,
870 836
871 837
872/** 838/**
873 * New incoming CADET channel. 839 * CADET channel connect handler.
840 *
841 * @see GNUNET_CADET_ConnectEventHandler()
874 */ 842 */
875static void * 843static void *
876cadet_notify_channel_new (void *cls, 844cadet_notify_connect (void *cls,
877 struct GNUNET_CADET_Channel *channel, 845 struct GNUNET_CADET_Channel *channel,
878 const struct GNUNET_PeerIdentity *initiator, 846 const struct GNUNET_PeerIdentity *source)
879 const struct GNUNET_HashCode *port,
880 enum GNUNET_CADET_ChannelOption options)
881{ 847{
882 return NULL; 848 struct Channel *chn = GNUNET_malloc (sizeof *chn);
849 chn->group = cls;
850 chn->channel = channel;
851 chn->direction = DIR_INCOMING;
852 chn->join_status = JOIN_NOT_ASKED;
853
854 GNUNET_CONTAINER_multihashmap_put (channels_in, &chn->group_pub_hash, chn,
855 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
856 return chn;
883} 857}
884 858
885 859
886/** 860/**
887 * CADET channel is being destroyed. 861 * CADET window size change handler.
862 *
863 * @see GNUNET_CADET_WindowSizeEventHandler()
888 */ 864 */
889static void 865static void
890cadet_notify_channel_end (void *cls, 866cadet_notify_window_change (void *cls,
891 const struct GNUNET_CADET_Channel *channel, 867 const struct GNUNET_CADET_Channel *channel,
892 void *ctx) 868 int window_size)
893{ 869{
894 if (NULL == ctx) 870 struct Channel *chn = cls;
871
872 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
873 "%p Window size changed to %d. Pending messages: %u\n",
874 chn, window_size, chn->msgs_pending);
875
876 chn->is_connected = GNUNET_YES;
877 chn->window_size = (int32_t) window_size;
878
879 for (int i = 0; i < window_size; i++)
880 {
881 if (0 < chn->msgs_pending)
882 {
883 client_send_ack (&chn->group_pub_hash);
884 chn->msgs_pending--;
885 }
886 else
887 {
888 break;
889 }
890 }
891}
892
893
894/**
895 * CADET channel disconnect handler.
896 *
897 * @see GNUNET_CADET_DisconnectEventHandler()
898 */
899static void
900cadet_notify_disconnect (void *cls,
901 const struct GNUNET_CADET_Channel *channel)
902{
903 if (NULL == cls)
895 return; 904 return;
896 905
897 struct Channel *chn = ctx; 906 struct Channel *chn = cls;
898 if (NULL != chn->group) 907 if (NULL != chn->group)
899 { 908 {
900 if (GNUNET_NO == chn->group->is_origin) 909 if (GNUNET_NO == chn->group->is_origin)
@@ -905,12 +914,331 @@ cadet_notify_channel_end (void *cls,
905 } 914 }
906 } 915 }
907 916
908 while (GNUNET_YES == replay_req_remove_cadet (chn)); 917 int ret;
918 do
919 {
920 ret = replay_req_remove_cadet (chn);
921 }
922 while (GNUNET_YES == ret);
909 923
910 GNUNET_free (chn); 924 GNUNET_free (chn);
911} 925}
912 926
913 927
928static int
929check_cadet_join_request (void *cls,
930 const struct MulticastJoinRequestMessage *req)
931{
932 struct Channel *chn = cls;
933
934 if (NULL == chn
935 || JOIN_NOT_ASKED != chn->join_status)
936 {
937 return GNUNET_SYSERR;
938 }
939
940 uint16_t size = ntohs (req->header.size);
941 if (size < sizeof (*req))
942 {
943 GNUNET_break_op (0);
944 return GNUNET_SYSERR;
945 }
946 if (ntohl (req->purpose.size) != (size
947 - sizeof (req->header)
948 - sizeof (req->reserved)
949 - sizeof (req->signature)))
950 {
951 GNUNET_break_op (0);
952 return GNUNET_SYSERR;
953 }
954 if (GNUNET_OK !=
955 GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_MULTICAST_REQUEST,
956 &req->purpose, &req->signature,
957 &req->member_pub_key))
958 {
959 GNUNET_break_op (0);
960 return GNUNET_SYSERR;
961 }
962
963 return GNUNET_OK;
964}
965
966
967/**
968 * Incoming join request message from CADET.
969 */
970static void
971handle_cadet_join_request (void *cls,
972 const struct MulticastJoinRequestMessage *req)
973{
974 struct Channel *chn = cls;
975 GNUNET_CADET_receive_done (chn->channel);
976
977 struct GNUNET_HashCode group_pub_hash;
978 GNUNET_CRYPTO_hash (&req->group_pub_key, sizeof (req->group_pub_key), &group_pub_hash);
979 chn->group_pub_key = req->group_pub_key;
980 chn->group_pub_hash = group_pub_hash;
981 chn->member_pub_key = req->member_pub_key;
982 chn->peer = req->peer;
983 chn->join_status = JOIN_WAITING;
984
985 client_send_all (&group_pub_hash, &req->header);
986}
987
988
989static int
990check_cadet_join_decision (void *cls,
991 const struct MulticastJoinDecisionMessageHeader *hdcsn)
992{
993 uint16_t size = ntohs (hdcsn->header.size);
994 if (size < sizeof (struct MulticastJoinDecisionMessageHeader) +
995 sizeof (struct MulticastJoinDecisionMessage))
996 {
997 GNUNET_break_op (0);
998 return GNUNET_SYSERR;
999 }
1000
1001 struct Channel *chn = cls;
1002 if (NULL == chn)
1003 {
1004 GNUNET_break (0);
1005 return GNUNET_SYSERR;
1006 }
1007 if (NULL == chn->group || GNUNET_NO != chn->group->is_origin)
1008 {
1009 GNUNET_break (0);
1010 return GNUNET_SYSERR;
1011 }
1012 switch (chn->join_status)
1013 {
1014 case JOIN_REFUSED:
1015 return GNUNET_SYSERR;
1016
1017 case JOIN_ADMITTED:
1018 return GNUNET_OK;
1019
1020 case JOIN_NOT_ASKED:
1021 case JOIN_WAITING:
1022 break;
1023 }
1024
1025 return GNUNET_OK;
1026}
1027
1028
1029/**
1030 * Incoming join decision message from CADET.
1031 */
1032static void
1033handle_cadet_join_decision (void *cls,
1034 const struct MulticastJoinDecisionMessageHeader *hdcsn)
1035{
1036 const struct MulticastJoinDecisionMessage *
1037 dcsn = (const struct MulticastJoinDecisionMessage *) &hdcsn[1];
1038
1039 struct Channel *chn = cls;
1040 GNUNET_CADET_receive_done (chn->channel);
1041
1042 // FIXME: do we need to copy chn->peer or compare it with hdcsn->peer?
1043 struct Member *mem = (struct Member *) chn->group;
1044 client_send_join_decision (mem, hdcsn);
1045 if (GNUNET_YES == ntohl (dcsn->is_admitted))
1046 {
1047 chn->join_status = JOIN_ADMITTED;
1048 }
1049 else
1050 {
1051 chn->join_status = JOIN_REFUSED;
1052 cadet_channel_destroy (chn);
1053 }
1054}
1055
1056
1057static int
1058check_cadet_message (void *cls,
1059 const struct GNUNET_MULTICAST_MessageHeader *msg)
1060{
1061 uint16_t size = ntohs (msg->header.size);
1062 if (size < sizeof (*msg))
1063 {
1064 GNUNET_break_op (0);
1065 return GNUNET_SYSERR;
1066 }
1067
1068 struct Channel *chn = cls;
1069 if (NULL == chn)
1070 {
1071 GNUNET_break (0);
1072 return GNUNET_SYSERR;
1073 }
1074 if (ntohl (msg->purpose.size) != (size
1075 - sizeof (msg->header)
1076 - sizeof (msg->hop_counter)
1077 - sizeof (msg->signature)))
1078 {
1079 GNUNET_break_op (0);
1080 return GNUNET_SYSERR;
1081 }
1082 if (GNUNET_OK !=
1083 GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_MULTICAST_MESSAGE,
1084 &msg->purpose, &msg->signature,
1085 &chn->group_pub_key))
1086 {
1087 GNUNET_break_op (0);
1088 return GNUNET_SYSERR;
1089 }
1090
1091 return GNUNET_OK;
1092}
1093
1094
1095/**
1096 * Incoming multicast message from CADET.
1097 */
1098static void
1099handle_cadet_message (void *cls,
1100 const struct GNUNET_MULTICAST_MessageHeader *msg)
1101{
1102 struct Channel *chn = cls;
1103 GNUNET_CADET_receive_done (chn->channel);
1104 client_send_all (&chn->group_pub_hash, &msg->header);
1105}
1106
1107
1108static int
1109check_cadet_request (void *cls,
1110 const struct GNUNET_MULTICAST_RequestHeader *req)
1111{
1112 uint16_t size = ntohs (req->header.size);
1113 if (size < sizeof (*req))
1114 {
1115 GNUNET_break_op (0);
1116 return GNUNET_SYSERR;
1117 }
1118
1119 struct Channel *chn = cls;
1120 if (NULL == chn)
1121 {
1122 GNUNET_break (0);
1123 return GNUNET_SYSERR;
1124 }
1125 if (ntohl (req->purpose.size) != (size
1126 - sizeof (req->header)
1127 - sizeof (req->member_pub_key)
1128 - sizeof (req->signature)))
1129 {
1130 GNUNET_break_op (0);
1131 return GNUNET_SYSERR;
1132 }
1133 if (GNUNET_OK !=
1134 GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_MULTICAST_REQUEST,
1135 &req->purpose, &req->signature,
1136 &req->member_pub_key))
1137 {
1138 GNUNET_break_op (0);
1139 return GNUNET_SYSERR;
1140 }
1141
1142 return GNUNET_OK;
1143}
1144
1145
1146/**
1147 * Incoming multicast request message from CADET.
1148 */
1149static void
1150handle_cadet_request (void *cls,
1151 const struct GNUNET_MULTICAST_RequestHeader *req)
1152{
1153 struct Channel *chn = cls;
1154 GNUNET_CADET_receive_done (chn->channel);
1155 client_send_origin (&chn->group_pub_hash, &req->header);
1156}
1157
1158
1159static int
1160check_cadet_replay_request (void *cls,
1161 const struct MulticastReplayRequestMessage *req)
1162{
1163 uint16_t size = ntohs (req->header.size);
1164 if (size < sizeof (*req))
1165 {
1166 GNUNET_break_op (0);
1167 return GNUNET_SYSERR;
1168 }
1169
1170 struct Channel *chn = cls;
1171 if (NULL == chn)
1172 {
1173 GNUNET_break_op (0);
1174 return GNUNET_SYSERR;
1175 }
1176
1177 return GNUNET_OK;
1178}
1179
1180
1181/**
1182 * Incoming multicast replay request from CADET.
1183 */
1184static void
1185handle_cadet_replay_request (void *cls,
1186 const struct MulticastReplayRequestMessage *req)
1187{
1188 struct Channel *chn = cls;
1189 GNUNET_CADET_receive_done (chn->channel);
1190
1191 struct MulticastReplayRequestMessage rep = *req;
1192 GNUNET_memcpy (&rep.member_pub_key, &chn->member_pub_key, sizeof (chn->member_pub_key));
1193
1194 struct GNUNET_CONTAINER_MultiHashMap *
1195 grp_replay_req = GNUNET_CONTAINER_multihashmap_get (replay_req_cadet,
1196 &chn->group->pub_key_hash);
1197 if (NULL == grp_replay_req)
1198 {
1199 grp_replay_req = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO);
1200 GNUNET_CONTAINER_multihashmap_put (replay_req_cadet,
1201 &chn->group->pub_key_hash, grp_replay_req,
1202 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
1203 }
1204 struct GNUNET_HashCode key_hash;
1205 replay_key_hash (rep.fragment_id, rep.message_id, rep.fragment_offset,
1206 rep.flags, &key_hash);
1207 GNUNET_CONTAINER_multihashmap_put (grp_replay_req, &key_hash, chn,
1208 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1209
1210 client_send_random (&chn->group_pub_hash, &rep.header);
1211}
1212
1213
1214static int
1215check_cadet_replay_response (void *cls,
1216 const struct MulticastReplayResponseMessage *res)
1217{
1218 struct Channel *chn = cls;
1219 if (NULL == chn)
1220 {
1221 GNUNET_break (0);
1222 return GNUNET_SYSERR;
1223 }
1224 return GNUNET_OK;
1225}
1226
1227
1228/**
1229 * Incoming multicast replay response from CADET.
1230 */
1231static void
1232handle_cadet_replay_response (void *cls,
1233 const struct MulticastReplayResponseMessage *res)
1234{
1235 struct Channel *chn = cls;
1236 GNUNET_CADET_receive_done (chn->channel);
1237
1238 /* @todo FIXME: got replay error response, send request to other members */
1239}
1240
1241
914static void 1242static void
915group_set_cadet_port_hash (struct Group *grp) 1243group_set_cadet_port_hash (struct Group *grp)
916{ 1244{
@@ -925,6 +1253,78 @@ group_set_cadet_port_hash (struct Group *grp)
925} 1253}
926 1254
927 1255
1256
1257/**
1258 * Create new outgoing CADET channel.
1259 *
1260 * @param peer
1261 * Peer to connect to.
1262 * @param group_pub_key
1263 * Public key of group the channel belongs to.
1264 * @param group_pub_hash
1265 * Hash of @a group_pub_key.
1266 *
1267 * @return Channel.
1268 */
1269static struct Channel *
1270cadet_channel_create (struct Group *grp, struct GNUNET_PeerIdentity *peer)
1271{
1272 struct Channel *chn = GNUNET_malloc (sizeof (*chn));
1273 chn->group = grp;
1274 chn->group_pub_key = grp->pub_key;
1275 chn->group_pub_hash = grp->pub_key_hash;
1276 chn->peer = *peer;
1277 chn->direction = DIR_OUTGOING;
1278 chn->is_connected = GNUNET_NO;
1279 chn->join_status = JOIN_WAITING;
1280
1281 struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
1282 GNUNET_MQ_hd_var_size (cadet_message,
1283 GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE,
1284 struct GNUNET_MULTICAST_MessageHeader,
1285 chn),
1286
1287 GNUNET_MQ_hd_var_size (cadet_join_decision,
1288 GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION,
1289 struct MulticastJoinDecisionMessageHeader,
1290 chn),
1291
1292 GNUNET_MQ_hd_var_size (cadet_replay_request,
1293 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST,
1294 struct MulticastReplayRequestMessage,
1295 chn),
1296
1297 GNUNET_MQ_hd_var_size (cadet_replay_response,
1298 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_RESPONSE,
1299 struct MulticastReplayResponseMessage,
1300 chn),
1301
1302 GNUNET_MQ_handler_end ()
1303 };
1304
1305 chn->channel = GNUNET_CADET_channel_create (cadet, chn, &chn->peer,
1306 &grp->cadet_port_hash,
1307 GNUNET_CADET_OPTION_RELIABLE,
1308 cadet_notify_window_change,
1309 cadet_notify_disconnect,
1310 cadet_handlers);
1311 GNUNET_CONTAINER_multihashmap_put (channels_out, &chn->group_pub_hash, chn,
1312 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1313 return chn;
1314}
1315
1316
1317/**
1318 * Destroy outgoing CADET channel.
1319 */
1320static void
1321cadet_channel_destroy (struct Channel *chn)
1322{
1323 GNUNET_CADET_channel_destroy (chn->channel);
1324 GNUNET_CONTAINER_multihashmap_remove_all (channels_out, &chn->group_pub_hash);
1325 GNUNET_free (chn);
1326}
1327
928/** 1328/**
929 * Handle a connecting client starting an origin. 1329 * Handle a connecting client starting an origin.
930 */ 1330 */
@@ -961,8 +1361,44 @@ handle_client_origin_start (void *cls,
961 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); 1361 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
962 1362
963 group_set_cadet_port_hash (grp); 1363 group_set_cadet_port_hash (grp);
964 orig->cadet_port = GNUNET_CADET_open_port (cadet, &grp->cadet_port_hash, 1364
965 cadet_notify_channel_new, NULL); 1365 struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
1366 GNUNET_MQ_hd_var_size (cadet_message,
1367 GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE,
1368 struct GNUNET_MULTICAST_MessageHeader,
1369 grp),
1370
1371 GNUNET_MQ_hd_var_size (cadet_request,
1372 GNUNET_MESSAGE_TYPE_MULTICAST_REQUEST,
1373 struct GNUNET_MULTICAST_RequestHeader,
1374 grp),
1375
1376 GNUNET_MQ_hd_var_size (cadet_join_request,
1377 GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_REQUEST,
1378 struct MulticastJoinRequestMessage,
1379 grp),
1380
1381 GNUNET_MQ_hd_var_size (cadet_replay_request,
1382 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST,
1383 struct MulticastReplayRequestMessage,
1384 grp),
1385
1386 GNUNET_MQ_hd_var_size (cadet_replay_response,
1387 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_RESPONSE,
1388 struct MulticastReplayResponseMessage,
1389 grp),
1390
1391 GNUNET_MQ_handler_end ()
1392 };
1393
1394
1395 orig->cadet_port = GNUNET_CADET_open_port (cadet,
1396 &grp->cadet_port_hash,
1397 cadet_notify_connect,
1398 NULL,
1399 cadet_notify_window_change,
1400 cadet_notify_disconnect,
1401 cadet_handlers);
966 } 1402 }
967 else 1403 else
968 { 1404 {
@@ -1258,10 +1694,8 @@ handle_client_multicast_message (void *cls,
1258 } 1694 }
1259 1695
1260 client_send_all (&grp->pub_key_hash, &out->header); 1696 client_send_all (&grp->pub_key_hash, &out->header);
1261 if (0 == cadet_send_children (&grp->pub_key_hash, &out->header)) 1697 cadet_send_children (&grp->pub_key_hash, &out->header);
1262 { 1698 client_send_ack (&grp->pub_key_hash);
1263 client_send_ack (&grp->pub_key_hash);
1264 }
1265 GNUNET_free (out); 1699 GNUNET_free (out);
1266 1700
1267 GNUNET_SERVICE_client_continue (client); 1701 GNUNET_SERVICE_client_continue (client);
@@ -1544,278 +1978,6 @@ handle_client_replay_response (void *cls,
1544 1978
1545 1979
1546/** 1980/**
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. 1981 * A new client connected.
1820 * 1982 *
1821 * @param cls NULL 1983 * @param cls NULL
@@ -1899,32 +2061,6 @@ client_notify_disconnect (void *cls,
1899 2061
1900 2062
1901/** 2063/**
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. 2064 * Service started.
1929 * 2065 *
1930 * @param cls closure 2066 * @param cls closure
@@ -1949,9 +2085,8 @@ run (void *cls,
1949 replay_req_cadet = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); 2085 replay_req_cadet = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO);
1950 replay_req_client = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); 2086 replay_req_client = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO);
1951 2087
1952 cadet = GNUNET_CADET_connect (cfg, NULL, 2088 cadet = GNUNET_CADET_connect (cfg);
1953 cadet_notify_channel_end, 2089
1954 cadet_handlers);
1955 GNUNET_assert (NULL != cadet); 2090 GNUNET_assert (NULL != cadet);
1956 2091
1957 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, 2092 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,