aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/include/gnunet_protocols.h4
-rw-r--r--src/mesh/gnunet-service-mesh.c199
-rw-r--r--src/mesh/mesh_protocol.h25
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;
339static struct GNUNET_DHT_Handle *dht_handle; 339static struct GNUNET_DHT_Handle *dht_handle;
340 340
341/** 341/**
342 * Handle to server
343 */
344static 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 */
344static GNUNET_PEER_Id myid; 349static 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 */
907static size_t
908send_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 */
980static int iterate_resend_multicast (void *cls, 1022static 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 */
158struct 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 */