diff options
-rw-r--r-- | src/include/gnunet_protocols.h | 4 | ||||
-rw-r--r-- | src/mesh/gnunet-service-mesh.c | 199 | ||||
-rw-r--r-- | src/mesh/mesh_protocol.h | 25 |
3 files changed, 182 insertions, 46 deletions
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index 36cfe0535..d31b67c95 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h | |||
@@ -825,6 +825,10 @@ extern "C" | |||
825 | */ | 825 | */ |
826 | #define GNUNET_MESSAGE_TYPE_DATA_MESSAGE_TO_ORIGIN 262 | 826 | #define GNUNET_MESSAGE_TYPE_DATA_MESSAGE_TO_ORIGIN 262 |
827 | 827 | ||
828 | /** | ||
829 | * Send origin an ACK that the path is complete | ||
830 | */ | ||
831 | #define GNUNET_MESSAGE_TYPE_PATH_ACK 263 | ||
828 | 832 | ||
829 | /** | 833 | /** |
830 | * We need flow control | 834 | * We need flow control |
diff --git a/src/mesh/gnunet-service-mesh.c b/src/mesh/gnunet-service-mesh.c index e1ee58ed9..1d2994585 100644 --- a/src/mesh/gnunet-service-mesh.c +++ b/src/mesh/gnunet-service-mesh.c | |||
@@ -245,7 +245,7 @@ struct MeshTunnel | |||
245 | struct GNUNET_TIME_Absolute timestamp; | 245 | struct GNUNET_TIME_Absolute timestamp; |
246 | 246 | ||
247 | /** | 247 | /** |
248 | * Peers in the tunnelindexed by PeerIdentity (MeshPeerInfo) | 248 | * Peers in the tunnel, indexed by PeerIdentity -> (MeshPeerInfo) |
249 | */ | 249 | */ |
250 | struct GNUNET_CONTAINER_MultiHashMap* peers; | 250 | struct GNUNET_CONTAINER_MultiHashMap* peers; |
251 | 251 | ||
@@ -339,6 +339,11 @@ static struct GNUNET_CORE_Handle *core_handle; | |||
339 | static struct GNUNET_DHT_Handle *dht_handle; | 339 | static struct GNUNET_DHT_Handle *dht_handle; |
340 | 340 | ||
341 | /** | 341 | /** |
342 | * Handle to server | ||
343 | */ | ||
344 | static struct GNUNET_SERVER_Handle *server_handle; | ||
345 | |||
346 | /** | ||
342 | * Local peer own ID (memory efficient handle) | 347 | * Local peer own ID (memory efficient handle) |
343 | */ | 348 | */ |
344 | static GNUNET_PEER_Id myid; | 349 | static GNUNET_PEER_Id myid; |
@@ -735,28 +740,29 @@ struct MeshDataDescriptor | |||
735 | { | 740 | { |
736 | /** ID of the tunnel this packet travels in */ | 741 | /** ID of the tunnel this packet travels in */ |
737 | struct MESH_TunnelID *origin; | 742 | struct MESH_TunnelID *origin; |
738 | 743 | ||
739 | /** Ultimate destination of the packet */ | 744 | /** Ultimate destination of the packet */ |
740 | GNUNET_PEER_Id destination; | 745 | GNUNET_PEER_Id destination; |
741 | 746 | ||
742 | /** Number of identical messages sent to different hops (multicast) */ | 747 | /** Number of identical messages sent to different hops (multicast) */ |
743 | unsigned int copies; | 748 | unsigned int copies; |
744 | 749 | ||
745 | /** Size of the data */ | 750 | /** Size of the data */ |
746 | size_t size; | 751 | size_t size; |
747 | 752 | ||
748 | /** Client that asked for the transmission, if any */ | 753 | /** Client that asked for the transmission, if any */ |
749 | struct GNUNET_SERVER_Client *client; | 754 | struct GNUNET_SERVER_Client *client; |
750 | 755 | ||
751 | /** Who was this message directed to */ | 756 | /** Who was this message directed to */ |
752 | struct MeshPeerInfo *peer; | 757 | struct MeshPeerInfo *peer; |
753 | 758 | ||
754 | /** Which handler was used to request the transmission */ | 759 | /** Which handler was used to request the transmission */ |
755 | unsigned int handler_n; | 760 | unsigned int handler_n; |
756 | 761 | ||
757 | /* Data at the end */ | 762 | /* Data at the end */ |
758 | }; | 763 | }; |
759 | 764 | ||
765 | #if LATER | ||
760 | /** | 766 | /** |
761 | * Function called to notify a client about the socket | 767 | * Function called to notify a client about the socket |
762 | * being ready to queue more data. "buf" will be | 768 | * being ready to queue more data. "buf" will be |
@@ -797,7 +803,7 @@ send_core_data_to_origin (void *cls, size_t size, void *buf) | |||
797 | GNUNET_free(info); | 803 | GNUNET_free(info); |
798 | return total_size; | 804 | return total_size; |
799 | } | 805 | } |
800 | 806 | #endif | |
801 | 807 | ||
802 | /** | 808 | /** |
803 | * Function called to notify a client about the socket | 809 | * Function called to notify a client about the socket |
@@ -863,7 +869,10 @@ send_core_data_multicast (void *cls, size_t size, void *buf) | |||
863 | GNUNET_assert(NULL != info); | 869 | GNUNET_assert(NULL != info); |
864 | total_size = info->size + sizeof(struct GNUNET_MESH_DataMessageMulticast); | 870 | total_size = info->size + sizeof(struct GNUNET_MESH_DataMessageMulticast); |
865 | GNUNET_assert(total_size < GNUNET_SERVER_MAX_MESSAGE_SIZE); | 871 | GNUNET_assert(total_size < GNUNET_SERVER_MAX_MESSAGE_SIZE); |
866 | 872 | ||
873 | if (info->peer) { | ||
874 | info->peer->core_transmit[info->handler_n] = NULL; | ||
875 | } | ||
867 | if (total_size > size) { | 876 | if (total_size > size) { |
868 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, | 877 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, |
869 | "not enough buffer to send data futher\n"); | 878 | "not enough buffer to send data futher\n"); |
@@ -890,6 +899,39 @@ send_core_data_multicast (void *cls, size_t size, void *buf) | |||
890 | * NULL and "size" zero if the socket was closed for | 899 | * NULL and "size" zero if the socket was closed for |
891 | * writing in the meantime. | 900 | * writing in the meantime. |
892 | * | 901 | * |
902 | * @param cls closure (MeshDataDescriptor) | ||
903 | * @param size number of bytes available in buf | ||
904 | * @param buf where the callee should write the message | ||
905 | * @return number of bytes written to buf | ||
906 | */ | ||
907 | static size_t | ||
908 | send_core_path_ack (void *cls, size_t size, void *buf) { | ||
909 | struct MeshDataDescriptor *info = cls; | ||
910 | struct GNUNET_MESH_PathACK *msg = buf; | ||
911 | |||
912 | GNUNET_assert(NULL != info); | ||
913 | if (info->peer) { | ||
914 | info->peer->core_transmit[info->handler_n] = NULL; | ||
915 | } | ||
916 | if (sizeof(struct GNUNET_MESH_PathACK) > size) { | ||
917 | GNUNET_break(0); | ||
918 | return 0; | ||
919 | } | ||
920 | msg->header.size = htons(sizeof(struct GNUNET_MESH_PathACK)); | ||
921 | msg->header.type = htons(GNUNET_MESSAGE_TYPE_PATH_ACK); | ||
922 | GNUNET_PEER_resolve(info->origin->oid, &msg->oid); | ||
923 | msg->tid = htonl(info->origin->tid); | ||
924 | |||
925 | return sizeof(struct GNUNET_MESH_PathACK); | ||
926 | } | ||
927 | |||
928 | |||
929 | /** | ||
930 | * Function called to notify a client about the socket | ||
931 | * being ready to queue more data. "buf" will be | ||
932 | * NULL and "size" zero if the socket was closed for | ||
933 | * writing in the meantime. | ||
934 | * | ||
893 | * @param cls closure (data itself) | 935 | * @param cls closure (data itself) |
894 | * @param size number of bytes available in buf | 936 | * @param size number of bytes available in buf |
895 | * @param buf where the callee should write the message | 937 | * @param buf where the callee should write the message |
@@ -969,35 +1011,34 @@ send_client_raw (void *cls, size_t size, void *buf) | |||
969 | 1011 | ||
970 | 1012 | ||
971 | /** | 1013 | /** |
972 | * Iterator over hash map peer entries to resend a data packet to all peers | 1014 | * Iterator over hash map peer entries collect all neighbors who to resend the |
973 | * down the tunnel. | 1015 | * data to. |
974 | * | 1016 | * |
975 | * @param cls closure (original message) | 1017 | * @param cls closure (**GNUNET_PEER_Id to store hops to send packet) |
976 | * @param key current key code (peer id hash) | 1018 | * @param key current key code (peer id hash) |
977 | * @param value value in the hash map (peer_info) | 1019 | * @param value value in the hash map (peer_info) |
978 | * @return GNUNET_YES if we should continue to iterate, GNUNET_NO if not. | 1020 | * @return GNUNET_YES if we should continue to iterate, GNUNET_NO if not. |
979 | */ | 1021 | */ |
980 | static int iterate_resend_multicast (void *cls, | 1022 | static int iterate_collect_neighbors (void *cls, |
981 | const GNUNET_HashCode * key, | 1023 | const GNUNET_HashCode * key, |
982 | void *value) | 1024 | void *value) |
983 | { | 1025 | { |
984 | struct GNUNET_MESH_DataMessageMulticast *msg = cls; | ||
985 | struct GNUNET_PeerIdentity id; | ||
986 | struct MeshPeerInfo *peer_info = value; | 1026 | struct MeshPeerInfo *peer_info = value; |
1027 | GNUNET_PEER_Id **neighbors = cls; | ||
1028 | GNUNET_PEER_Id id; | ||
1029 | unsigned int i; | ||
987 | 1030 | ||
988 | if (peer_info->id == myid) { | 1031 | if (peer_info->id == myid) { |
989 | // TODO retransmit to interested clients | ||
990 | return GNUNET_YES; | 1032 | return GNUNET_YES; |
991 | } | 1033 | } |
992 | GNUNET_PEER_resolve(get_first_hop(peer_info->path), &id); | 1034 | id = get_first_hop(peer_info->path); |
993 | GNUNET_CORE_notify_transmit_ready(core_handle, | 1035 | for (i = 0; *neighbors[i] != 0; i++) { |
994 | 0, | 1036 | if (*neighbors[i] == id) return GNUNET_YES; |
995 | 0, | 1037 | } |
996 | GNUNET_TIME_UNIT_FOREVER_REL, | 1038 | *neighbors = GNUNET_realloc(*neighbors, (i + 2) * sizeof(GNUNET_PEER_Id)); |
997 | &id, | 1039 | *neighbors[i] = id; |
998 | ntohs(msg->header.size), | 1040 | *neighbors[i + 1] = 0; |
999 | &send_core_data_raw, | 1041 | |
1000 | msg); | ||
1001 | return GNUNET_YES; | 1042 | return GNUNET_YES; |
1002 | } | 1043 | } |
1003 | 1044 | ||
@@ -1125,21 +1166,31 @@ handle_mesh_path_create (void *cls, | |||
1125 | return 0; | 1166 | return 0; |
1126 | } | 1167 | } |
1127 | if (own_pos == size - 1) { /* it is for us! */ | 1168 | if (own_pos == size - 1) { /* it is for us! */ |
1128 | // struct MeshDataDescriptor *info; | 1169 | struct MeshDataDescriptor *info; |
1129 | 1170 | unsigned int j; | |
1130 | /* FIXME: implement real dedicated ACK */ | 1171 | |
1131 | // add_path_to_origin(orig_peer_info, path); /* inverts path! */ | 1172 | add_path_to_origin(orig_peer_info, path); /* inverts path! */ |
1132 | // GNUNET_PEER_resolve(get_first_hop(path), &id); /* path is inverted :) */ | 1173 | GNUNET_PEER_resolve(get_first_hop(path), &id); /* path is inverted :) */ |
1133 | // info = GNUNET_malloc(sizeof(struct MeshDataDescriptor)); | 1174 | info = GNUNET_malloc(sizeof(struct MeshDataDescriptor)); |
1134 | // info->origin = &t->id; | 1175 | info->origin = &t->id; |
1135 | // GNUNET_CORE_notify_transmit_ready(core_handle, | 1176 | info->peer = GNUNET_CONTAINER_multihashmap_get(peers, &id.hashPubKey); |
1136 | // 0, | 1177 | GNUNET_assert(info->peer); |
1137 | // 0, | 1178 | for (j = 0; info->peer->core_transmit[j]; j++) { |
1138 | // GNUNET_TIME_UNIT_FOREVER_REL, | 1179 | if (j == 9) { |
1139 | // &id, | 1180 | GNUNET_break(0); |
1140 | // sizeof(struct GNUNET_MessageHeader), | 1181 | return GNUNET_OK; |
1141 | // &send_core_data_to_origin, | 1182 | } |
1142 | // info); | 1183 | } |
1184 | info->handler_n = j; | ||
1185 | info->peer->core_transmit[j] = GNUNET_CORE_notify_transmit_ready( | ||
1186 | core_handle, | ||
1187 | 0, | ||
1188 | 100, | ||
1189 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
1190 | &id, | ||
1191 | sizeof(struct GNUNET_MessageHeader), | ||
1192 | &send_core_path_ack, | ||
1193 | info); | ||
1143 | } else { | 1194 | } else { |
1144 | add_path_to_peer(dest_peer_info, path); | 1195 | add_path_to_peer(dest_peer_info, path); |
1145 | GNUNET_PEER_resolve(get_first_hop(path), &id); | 1196 | GNUNET_PEER_resolve(get_first_hop(path), &id); |
@@ -1248,8 +1299,17 @@ handle_mesh_data_multicast (void *cls, | |||
1248 | *atsi) | 1299 | *atsi) |
1249 | { | 1300 | { |
1250 | struct GNUNET_MESH_DataMessageMulticast *msg; | 1301 | struct GNUNET_MESH_DataMessageMulticast *msg; |
1302 | struct GNUNET_PeerIdentity id; | ||
1251 | struct MeshTunnel *t; | 1303 | struct MeshTunnel *t; |
1304 | struct MeshClient *c; | ||
1305 | struct MeshDataDescriptor *dd; | ||
1306 | struct GNUNET_SERVER_NotificationContext *nc; | ||
1307 | GNUNET_PEER_Id *neighbors; | ||
1252 | size_t size; | 1308 | size_t size; |
1309 | uint16_t type; | ||
1310 | uint16_t i; | ||
1311 | uint16_t j; | ||
1312 | |||
1253 | 1313 | ||
1254 | size = ntohs(message->size); | 1314 | size = ntohs(message->size); |
1255 | if (size < sizeof(struct GNUNET_MESH_DataMessageMulticast)) { | 1315 | if (size < sizeof(struct GNUNET_MESH_DataMessageMulticast)) { |
@@ -1263,10 +1323,56 @@ handle_mesh_data_multicast (void *cls, | |||
1263 | return GNUNET_OK; | 1323 | return GNUNET_OK; |
1264 | } | 1324 | } |
1265 | 1325 | ||
1266 | GNUNET_CONTAINER_multihashmap_iterate(t->peers, | 1326 | /* Transmit to locally interested clients */ |
1267 | &iterate_resend_multicast, | 1327 | GNUNET_PEER_resolve(myid, &id); |
1268 | msg); | 1328 | if (GNUNET_CONTAINER_multihashmap_contains(t->peers, &id.hashPubKey)) { |
1329 | type = ntohs(msg[1].header.type); | ||
1330 | nc = GNUNET_SERVER_notification_context_create(server_handle, 10U); | ||
1331 | for (c = clients; c != NULL; c = c->next) { | ||
1332 | for (i = 0; i < c->type_counter; i++) { | ||
1333 | if (c->types[i] == type) { | ||
1334 | GNUNET_SERVER_notification_context_add(nc, c->handle); | ||
1335 | } | ||
1336 | } | ||
1337 | } | ||
1338 | } | ||
1269 | 1339 | ||
1340 | /* Retransmit to other peers */ | ||
1341 | neighbors = GNUNET_malloc(sizeof(GNUNET_PEER_Id)); | ||
1342 | neighbors[0] = 0; | ||
1343 | GNUNET_CONTAINER_multihashmap_iterate(t->peers, | ||
1344 | &iterate_collect_neighbors, | ||
1345 | &neighbors); | ||
1346 | if (!neighbors[0]) { | ||
1347 | return GNUNET_OK; | ||
1348 | } | ||
1349 | size -= sizeof(struct GNUNET_MESH_DataMessageMulticast); | ||
1350 | dd = GNUNET_malloc(sizeof(struct MeshDataDescriptor) + size); | ||
1351 | dd->origin = &t->id; | ||
1352 | dd->copies = 0; | ||
1353 | for (i = 0; 0 != neighbors[i]; i++) { | ||
1354 | GNUNET_PEER_resolve(neighbors[i], &id); | ||
1355 | dd->copies++; | ||
1356 | dd->destination = neighbors[i]; | ||
1357 | dd->peer = GNUNET_CONTAINER_multihashmap_get(peers, &id.hashPubKey); | ||
1358 | GNUNET_assert(dd->peer); | ||
1359 | for (j = 0; dd->peer->core_transmit[j]; j++) { | ||
1360 | if (j == 9) { | ||
1361 | GNUNET_break(0); | ||
1362 | return GNUNET_OK; | ||
1363 | } | ||
1364 | } | ||
1365 | dd->handler_n = j; | ||
1366 | dd->peer->core_transmit[j] = GNUNET_CORE_notify_transmit_ready( | ||
1367 | core_handle, | ||
1368 | 0, | ||
1369 | 0, | ||
1370 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
1371 | &id, | ||
1372 | ntohs(msg->header.size), | ||
1373 | &send_core_data_multicast, | ||
1374 | dd); | ||
1375 | } | ||
1270 | return GNUNET_OK; | 1376 | return GNUNET_OK; |
1271 | } | 1377 | } |
1272 | 1378 | ||
@@ -2237,6 +2343,7 @@ run (void *cls, | |||
2237 | "starting to run\n"); | 2343 | "starting to run\n"); |
2238 | GNUNET_SERVER_add_handlers (server, plugin_handlers); | 2344 | GNUNET_SERVER_add_handlers (server, plugin_handlers); |
2239 | GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL); | 2345 | GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL); |
2346 | server_handle = server; | ||
2240 | core_handle = GNUNET_CORE_connect (c, /* Main configuration */ | 2347 | core_handle = GNUNET_CORE_connect (c, /* Main configuration */ |
2241 | CORE_QUEUE_SIZE, /* queue size */ | 2348 | CORE_QUEUE_SIZE, /* queue size */ |
2242 | NULL, /* Closure passed to MESH functions */ | 2349 | NULL, /* Closure passed to MESH functions */ |
diff --git a/src/mesh/mesh_protocol.h b/src/mesh/mesh_protocol.h index c18d56400..8868d0c66 100644 --- a/src/mesh/mesh_protocol.h +++ b/src/mesh/mesh_protocol.h | |||
@@ -151,6 +151,31 @@ struct GNUNET_MESH_DataMessageToOrigin | |||
151 | */ | 151 | */ |
152 | }; | 152 | }; |
153 | 153 | ||
154 | |||
155 | /** | ||
156 | * Message for ack'ing a path | ||
157 | */ | ||
158 | struct GNUNET_MESH_PathACK | ||
159 | { | ||
160 | /** | ||
161 | * Type: GNUNET_MESSAGE_TYPE_PATH_ACK | ||
162 | */ | ||
163 | struct GNUNET_MessageHeader header; | ||
164 | |||
165 | /** | ||
166 | * TID of the tunnel | ||
167 | */ | ||
168 | uint32_t tid GNUNET_PACKED; | ||
169 | |||
170 | /** | ||
171 | * OID of the tunnel | ||
172 | */ | ||
173 | struct GNUNET_PeerIdentity oid; | ||
174 | |||
175 | /* TODO: signature */ | ||
176 | }; | ||
177 | |||
178 | |||
154 | /** | 179 | /** |
155 | * Message for mesh flow control | 180 | * Message for mesh flow control |
156 | */ | 181 | */ |