aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mesh/gnunet-service-mesh_channel.c242
-rw-r--r--src/mesh/gnunet-service-mesh_channel.h3
-rw-r--r--src/mesh/gnunet-service-mesh_connection.c1
-rw-r--r--src/mesh/gnunet-service-mesh_local.c58
-rw-r--r--src/mesh/gnunet-service-mesh_local.h34
-rw-r--r--src/mesh/gnunet-service-mesh_tunnel.c192
-rw-r--r--src/mesh/gnunet-service-mesh_tunnel.h86
7 files changed, 442 insertions, 174 deletions
diff --git a/src/mesh/gnunet-service-mesh_channel.c b/src/mesh/gnunet-service-mesh_channel.c
index 933949b16..d280e336f 100644
--- a/src/mesh/gnunet-service-mesh_channel.c
+++ b/src/mesh/gnunet-service-mesh_channel.c
@@ -33,6 +33,8 @@
33 33
34#define LOG(level, ...) GNUNET_log_from(level,"mesh-chn",__VA_ARGS__) 34#define LOG(level, ...) GNUNET_log_from(level,"mesh-chn",__VA_ARGS__)
35 35
36#define MESH_RETRANSMIT_MARGIN 4
37
36/** 38/**
37 * All the states a connection can be in. 39 * All the states a connection can be in.
38 */ 40 */
@@ -259,6 +261,16 @@ extern struct GNUNET_STATISTICS_Handle *stats;
259/******************************************************************************/ 261/******************************************************************************/
260 262
261/** 263/**
264 * Destroy a reliable message after it has been acknowledged, either by
265 * direct mid ACK or bitfield. Updates the appropriate data structures and
266 * timers and frees all memory.
267 *
268 * @param copy Message that is no longer needed: remote peer got it.
269 */
270static void
271rel_message_free (struct MeshReliableMessage *copy);
272
273/**
262 * We have received a message out of order, or the client is not ready. 274 * We have received a message out of order, or the client is not ready.
263 * Buffer it until we receive an ACK from the client or the missing 275 * Buffer it until we receive an ACK from the client or the missing
264 * message from the channel. 276 * message from the channel.
@@ -624,7 +636,7 @@ channel_send_connections_ack (struct MeshChannel *ch,
624 636
625 LOG (GNUNET_ERROR_TYPE_DEBUG, 637 LOG (GNUNET_ERROR_TYPE_DEBUG,
626 "Channel send connection %s ack on %s:%X\n", 638 "Channel send connection %s ack on %s:%X\n",
627 fwd ? "FWD" : "BCK", peer2s (ch->t->peer), ch->gid); 639 fwd ? "FWD" : "BCK", GMT_2s (ch->t), ch->gid);
628 GNUNET_break (to_allow == 0); 640 GNUNET_break (to_allow == 0);
629} 641}
630 642
@@ -677,7 +689,7 @@ channel_confirm (struct MeshChannel *ch, int fwd)
677 689
678 LOG (GNUNET_ERROR_TYPE_DEBUG, 690 LOG (GNUNET_ERROR_TYPE_DEBUG,
679 " channel confirm %s %s:%X\n", 691 " channel confirm %s %s:%X\n",
680 fwd ? "FWD" : "BCK", peer2s (ch->t->peer), ch->gid); 692 fwd ? "FWD" : "BCK", GMT_2s (ch->t), ch->gid);
681 ch->state = MESH_CHANNEL_READY; 693 ch->state = MESH_CHANNEL_READY;
682 694
683 rel = fwd ? ch->root_rel : ch->dest_rel; 695 rel = fwd ? ch->root_rel : ch->dest_rel;
@@ -817,34 +829,25 @@ channel_destroy (struct MeshChannel *ch)
817 return; 829 return;
818 830
819 LOG (GNUNET_ERROR_TYPE_DEBUG, "destroying channel %s:%u\n", 831 LOG (GNUNET_ERROR_TYPE_DEBUG, "destroying channel %s:%u\n",
820 peer2s (ch->t->peer), ch->gid); 832 GMT_2s (ch->t), ch->gid);
821 GMCH_debug (ch); 833 GMCH_debug (ch);
822 834
823 c = ch->root; 835 c = ch->root;
824 if (NULL != c) 836 if (NULL != c)
825 { 837 {
826 if (GNUNET_YES != GNUNET_CONTAINER_multihashmap32_remove (c->own_channels, 838 GML_channel_remove (c, ch->lid_root, ch);
827 ch->lid_root, ch))
828 {
829 GNUNET_break (0);
830 }
831 } 839 }
832 840
833 c = ch->dest; 841 c = ch->dest;
834 if (NULL != c) 842 if (NULL != c)
835 { 843 {
836 if (GNUNET_YES != 844 GML_channel_remove (c, ch->lid_dest, ch);
837 GNUNET_CONTAINER_multihashmap32_remove (c->incoming_channels,
838 ch->lid_dest, ch))
839 {
840 GNUNET_break (0);
841 }
842 } 845 }
843 846
844 channel_rel_free_all (ch->root_rel); 847 channel_rel_free_all (ch->root_rel);
845 channel_rel_free_all (ch->dest_rel); 848 channel_rel_free_all (ch->dest_rel);
846 849
847 GNUNET_CONTAINER_DLL_remove (ch->t->channel_head, ch->t->channel_tail, ch); 850 GMT_remove_channel (ch->t, ch);
848 GNUNET_STATISTICS_update (stats, "# channels", -1, GNUNET_NO); 851 GNUNET_STATISTICS_update (stats, "# channels", -1, GNUNET_NO);
849 852
850 GNUNET_free (ch); 853 GNUNET_free (ch);
@@ -875,26 +878,10 @@ channel_new (struct MeshTunnel3 *t,
875 878
876 if (NULL != owner) 879 if (NULL != owner)
877 { 880 {
878 while (NULL != channel_get (t, t->next_chid)) 881 ch->gid = GMT_get_next_chid (t);
879 { 882 GML_channel_add (owner, lid_root, ch);
880 LOG (GNUNET_ERROR_TYPE_DEBUG, "Channel %u exists (%p)...\n",
881 t->next_chid, channel_get (t, t->next_chid));
882 t->next_chid = (t->next_chid + 1) & ~GNUNET_MESH_LOCAL_CHANNEL_ID_CLI;
883 }
884 ch->gid = t->next_chid;
885 t->next_chid = (t->next_chid + 1) & ~GNUNET_MESH_LOCAL_CHANNEL_ID_CLI;
886
887 if (GNUNET_OK !=
888 GNUNET_CONTAINER_multihashmap32_put (owner->own_channels, lid_root, ch,
889 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
890 {
891 GNUNET_break (0);
892 channel_destroy (ch);
893 GNUNET_SERVER_receive_done (owner->handle, GNUNET_SYSERR);
894 return NULL;
895 }
896 } 883 }
897 GNUNET_CONTAINER_DLL_insert (t->channel_head, t->channel_tail, ch); 884 GMT_add_channel (t, ch);
898 885
899 return ch; 886 return ch;
900} 887}
@@ -932,7 +919,7 @@ channel_send_ack (struct MeshChannel *ch, int fwd)
932 msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK); 919 msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK);
933 LOG (GNUNET_ERROR_TYPE_DEBUG, 920 LOG (GNUNET_ERROR_TYPE_DEBUG,
934 " sending channel %s ack for channel %s:%X\n", 921 " sending channel %s ack for channel %s:%X\n",
935 fwd ? "FWD" : "BCK", peer2s (ch->t->peer), 922 fwd ? "FWD" : "BCK", GMT_2s (ch->t),
936 ch->gid); 923 ch->gid);
937 924
938 msg.chid = htonl (ch->gid); 925 msg.chid = htonl (ch->gid);
@@ -941,57 +928,6 @@ channel_send_ack (struct MeshChannel *ch, int fwd)
941 928
942 929
943/** 930/**
944 * Send a message to all clients (local and remote) of this channel
945 * notifying that the channel is no longer valid.
946 *
947 * If some peer or client should not receive the message,
948 * should be zero'ed out before calling this function.
949 *
950 * @param ch The channel whose clients to notify.
951 */
952static void
953channel_send_destroy (struct MeshChannel *ch)
954{
955 struct GNUNET_MESH_ChannelManage msg;
956
957 msg.header.size = htons (sizeof (msg));
958 msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY);
959 LOG (GNUNET_ERROR_TYPE_DEBUG,
960 " sending channel destroy for channel %s:%X\n",
961 peer2s (ch->t->peer),
962 ch->gid);
963
964 if (GMCH_is_terminal (ch, GNUNET_NO))
965 {
966 if (NULL != ch->root && GNUNET_NO == ch->root->shutting_down)
967 {
968 msg.chid = htonl (ch->lid_root);
969 send_local_channel_destroy (ch, GNUNET_NO);
970 }
971 }
972 else
973 {
974 msg.chid = htonl (ch->gid);
975 GMCH_send_prebuilt_message (&msg.header, ch, GNUNET_NO);
976 }
977
978 if (GMCH_is_terminal (ch, GNUNET_YES))
979 {
980 if (NULL != ch->dest && GNUNET_NO == ch->dest->shutting_down)
981 {
982 msg.chid = htonl (ch->lid_dest);
983 send_local_channel_destroy (ch, GNUNET_YES);
984 }
985 }
986 else
987 {
988 msg.chid = htonl (ch->gid);
989 GMCH_send_prebuilt_message (&msg.header, ch, GNUNET_YES);
990 }
991}
992
993
994/**
995 * Iterator for deleting each channel whose client endpoint disconnected. 931 * Iterator for deleting each channel whose client endpoint disconnected.
996 * 932 *
997 * @param cls Closure (client that has disconnected). 933 * @param cls Closure (client that has disconnected).
@@ -1010,29 +946,86 @@ channel_destroy_iterator (void *cls,
1010 struct MeshTunnel3 *t; 946 struct MeshTunnel3 *t;
1011 947
1012 LOG (GNUNET_ERROR_TYPE_DEBUG, 948 LOG (GNUNET_ERROR_TYPE_DEBUG,
1013 " Channel %X (%X / %X) destroy, due to client %u shutdown.\n", 949 " Channel %X (%X / %X) destroy, due to client %s shutdown.\n",
1014 ch->gid, ch->lid_root, ch->lid_dest, c->id); 950 ch->gid, ch->lid_root, ch->lid_dest, GML_2s (c));
1015 channel_debug (ch); 951 GMCH_debug (ch);
1016 952
1017 if (c == ch->dest) 953 if (c == ch->dest)
1018 { 954 {
1019 LOG (GNUNET_ERROR_TYPE_DEBUG, " Client %u is destination.\n", c->id); 955 LOG (GNUNET_ERROR_TYPE_DEBUG, " Client %s is destination.\n", GML_2s (c));
1020 } 956 }
1021 if (c == ch->root) 957 if (c == ch->root)
1022 { 958 {
1023 LOG (GNUNET_ERROR_TYPE_DEBUG, " Client %u is owner.\n", c->id); 959 LOG (GNUNET_ERROR_TYPE_DEBUG, " Client %s is owner.\n", GML_2s (c));
1024 } 960 }
1025 961
1026 t = ch->t; 962 t = ch->t;
1027 GMCH_send_destroy (ch); 963 GMCH_send_destroy (ch);
1028 channel_send_destroy (ch);
1029 channel_destroy (ch); 964 channel_destroy (ch);
1030 tunnel_destroy_if_empty (t); 965 GMT_destroy_if_empty (t);
1031 966
1032 return GNUNET_OK; 967 return GNUNET_OK;
1033} 968}
1034 969
1035 970
971/**
972 * Handle a loopback message: call the appropriate handler for the message type.
973 *
974 * @param ch Channel this message is on.
975 * @param msgh Message header.
976 * @param fwd Is this FWD traffic?
977 */
978void
979handle_loopback (struct MeshChannel *ch,
980 struct GNUNET_MessageHeader *msgh,
981 int fwd)
982{
983 uint16_t type;
984
985 type = ntohs (msgh->type);
986 LOG (GNUNET_ERROR_TYPE_DEBUG,
987 "Loopback %s message!\n",
988 GNUNET_MESH_DEBUG_M2S (type));
989
990 switch (type)
991 {
992 case GNUNET_MESSAGE_TYPE_MESH_DATA:
993 /* Don't send hop ACK, wait for client to ACK */
994 GMCH_handle_data (ch, (struct GNUNET_MESH_Data *) msgh, fwd);
995 break;
996
997 case GNUNET_MESSAGE_TYPE_MESH_DATA_ACK:
998 GMCH_handle_data_ack (ch, (struct GNUNET_MESH_DataACK *) msgh, fwd);
999 break;
1000
1001 case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
1002 // FIXME store channel in loopback tunnel?
1003 GMCH_handle_create ((struct GNUNET_MESH_ChannelCreate *) msgh,
1004 fwd);
1005 break;
1006
1007 case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK:
1008 GMCH_handle_ack (ch,
1009 (struct GNUNET_MESH_ChannelManage *) msgh,
1010 fwd);
1011 break;
1012
1013 case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY:
1014 GMCH_handle_destroy (ch,
1015 (struct GNUNET_MESH_ChannelManage *) msgh,
1016 fwd);
1017 break;
1018
1019 default:
1020 GNUNET_break_op (0);
1021 LOG (GNUNET_ERROR_TYPE_DEBUG,
1022 "end-to-end message not known (%u)\n",
1023 ntohs (msgh->type));
1024 }
1025}
1026
1027
1028
1036/******************************************************************************/ 1029/******************************************************************************/
1037/******************************** API ***********************************/ 1030/******************************** API ***********************************/
1038/******************************************************************************/ 1031/******************************************************************************/
@@ -1136,7 +1129,6 @@ void
1136GMCH_send_create (struct MeshChannel *ch) 1129GMCH_send_create (struct MeshChannel *ch)
1137{ 1130{
1138 struct GNUNET_MESH_ChannelMessage msg; 1131 struct GNUNET_MESH_ChannelMessage msg;
1139 struct MeshTunnel3 *t = ch->t;
1140 uint32_t opt; 1132 uint32_t opt;
1141 1133
1142 if (NULL == ch->dest) 1134 if (NULL == ch->dest)
@@ -1146,29 +1138,24 @@ GMCH_send_create (struct MeshChannel *ch)
1146 opt |= GNUNET_YES == ch->reliable ? GNUNET_MESH_OPTION_RELIABLE : 0; 1138 opt |= GNUNET_YES == ch->reliable ? GNUNET_MESH_OPTION_RELIABLE : 0;
1147 opt |= GNUNET_YES == ch->nobuffer ? GNUNET_MESH_OPTION_NOBUFFER : 0; 1139 opt |= GNUNET_YES == ch->nobuffer ? GNUNET_MESH_OPTION_NOBUFFER : 0;
1148 GML_send_channel_create (ch->dest, ch->lid_dest, ch->port, opt, 1140 GML_send_channel_create (ch->dest, ch->lid_dest, ch->port, opt,
1149 GNUNET_PEER_resolve2 (t->peer->id)); 1141 GMT_get_destination (ch->t));
1150 1142
1151} 1143}
1152 1144
1153/** 1145/**
1154 * Notify a client that the channel is no longer valid. 1146 * Notify a client that the channel is no longer valid.
1147 * FIXME send on tunnel if some client == NULL?
1155 * 1148 *
1156 * @param ch Channel that is destroyed. 1149 * @param ch Channel that is destroyed.
1157 * @param fwd Forward notification (owner->dest)?
1158 */ 1150 */
1159void 1151void
1160GMCH_send_destroy (struct MeshChannel *ch, int fwd) 1152GMCH_send_destroy (struct MeshChannel *ch)
1161{ 1153{
1162 struct GNUNET_MeshClient *c = fwd ? ch->dest : ch->root; 1154 if (NULL != ch->root)
1163 uint32_t id = fwd ? ch->lid_dest : ch->lid_root; 1155 GML_send_channel_destroy (ch->root, ch->lid_root);
1164
1165 if (NULL == c)
1166 {
1167// TODO: send on connection?
1168 return;
1169 }
1170 1156
1171 GML_send_channel_destroy (c, id); 1157 if (NULL != ch->dest)
1158 GML_send_channel_destroy (ch->dest, ch->lid_dest);
1172} 1159}
1173 1160
1174 1161
@@ -1198,7 +1185,7 @@ GMCH_send_data (struct MeshChannel *ch,
1198 * @param ch Channel this is about. 1185 * @param ch Channel this is about.
1199 * @param fwd Is for FWD traffic? (ACK dest->owner) 1186 * @param fwd Is for FWD traffic? (ACK dest->owner)
1200 */ 1187 */
1201static void 1188void
1202GMCH_send_ack (struct MeshChannel *ch, int fwd) 1189GMCH_send_ack (struct MeshChannel *ch, int fwd)
1203{ 1190{
1204 struct GNUNET_MESH_DataACK msg; 1191 struct GNUNET_MESH_DataACK msg;
@@ -1238,7 +1225,7 @@ GMCH_send_ack (struct MeshChannel *ch, int fwd)
1238 } 1225 }
1239 LOG (GNUNET_ERROR_TYPE_DEBUG, " final futures %llX\n", msg.futures); 1226 LOG (GNUNET_ERROR_TYPE_DEBUG, " final futures %llX\n", msg.futures);
1240 1227
1241 send_prebuilt_message_channel (&msg.header, ch, fwd); 1228 GMCH_send_prebuilt_message (&msg.header, ch, fwd);
1242 LOG (GNUNET_ERROR_TYPE_DEBUG, "send_data_ack END\n"); 1229 LOG (GNUNET_ERROR_TYPE_DEBUG, "send_data_ack END\n");
1243} 1230}
1244 1231
@@ -1257,12 +1244,12 @@ GMCH_debug (struct MeshChannel *ch)
1257 return; 1244 return;
1258 } 1245 }
1259 LOG (GNUNET_ERROR_TYPE_DEBUG, "Channel %s:%X (%p)\n", 1246 LOG (GNUNET_ERROR_TYPE_DEBUG, "Channel %s:%X (%p)\n",
1260 peer2s (ch->t->peer), ch->gid, ch); 1247 GMT_2s (ch->t), ch->gid, ch);
1261 LOG (GNUNET_ERROR_TYPE_DEBUG, " root %p/%p\n", 1248 LOG (GNUNET_ERROR_TYPE_DEBUG, " root %p/%p\n",
1262 ch->root, ch->root_rel); 1249 ch->root, ch->root_rel);
1263 if (NULL != ch->root) 1250 if (NULL != ch->root)
1264 { 1251 {
1265 LOG (GNUNET_ERROR_TYPE_DEBUG, " cli %u\n", ch->root->id); 1252 LOG (GNUNET_ERROR_TYPE_DEBUG, " cli %s\n", GML_2s (ch->root));
1266 LOG (GNUNET_ERROR_TYPE_DEBUG, " ready %s\n", 1253 LOG (GNUNET_ERROR_TYPE_DEBUG, " ready %s\n",
1267 ch->root_rel->client_ready ? "YES" : "NO"); 1254 ch->root_rel->client_ready ? "YES" : "NO");
1268 LOG (GNUNET_ERROR_TYPE_DEBUG, " id %X\n", ch->lid_root); 1255 LOG (GNUNET_ERROR_TYPE_DEBUG, " id %X\n", ch->lid_root);
@@ -1271,7 +1258,7 @@ GMCH_debug (struct MeshChannel *ch)
1271 ch->dest, ch->dest_rel); 1258 ch->dest, ch->dest_rel);
1272 if (NULL != ch->dest) 1259 if (NULL != ch->dest)
1273 { 1260 {
1274 LOG (GNUNET_ERROR_TYPE_DEBUG, " cli %u\n", ch->dest->id); 1261 LOG (GNUNET_ERROR_TYPE_DEBUG, " cli %s\n", GML_2s (ch->dest));
1275 LOG (GNUNET_ERROR_TYPE_DEBUG, " ready %s\n", 1262 LOG (GNUNET_ERROR_TYPE_DEBUG, " ready %s\n",
1276 ch->dest_rel->client_ready ? "YES" : "NO"); 1263 ch->dest_rel->client_ready ? "YES" : "NO");
1277 LOG (GNUNET_ERROR_TYPE_DEBUG, " id %X\n", ch->lid_dest); 1264 LOG (GNUNET_ERROR_TYPE_DEBUG, " id %X\n", ch->lid_dest);
@@ -1439,7 +1426,6 @@ GMCH_handle_data_ack (struct MeshChannel *ch,
1439/** 1426/**
1440 * Handler for channel create messages. 1427 * Handler for channel create messages.
1441 * 1428 *
1442 * @param t Tunnel this channel is to be created in.
1443 * @param msg Message. 1429 * @param msg Message.
1444 * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO; 1430 * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
1445 */ 1431 */
@@ -1452,7 +1438,6 @@ GMCH_handle_create (const struct GNUNET_MESH_ChannelCreate *msg,
1452 struct MeshClient *c; 1438 struct MeshClient *c;
1453 uint32_t port; 1439 uint32_t port;
1454 1440
1455 /* Check if channel exists */
1456 chid = ntohl (msg->chid); 1441 chid = ntohl (msg->chid);
1457 1442
1458 /* Create channel */ 1443 /* Create channel */
@@ -1522,14 +1507,13 @@ GMCH_handle_destroy (struct MeshChannel *ch,
1522 return; 1507 return;
1523 } 1508 }
1524 1509
1525 GMCH_send_destroy (ch, fwd); 1510 GMCH_send_destroy (ch);
1526 channel_destroy (ch); 1511 channel_destroy (ch);
1527} 1512}
1528 1513
1529 1514
1530/** 1515/**
1531 * Sends an already built message on a channel, properly registering 1516 * Sends an already built message on a channel.
1532 * all used resources and encrypting the message with the tunnel's key.
1533 * 1517 *
1534 * @param message Message to send. Function makes a copy of it. 1518 * @param message Message to send. Function makes a copy of it.
1535 * @param ch Channel on which this message is transmitted. 1519 * @param ch Channel on which this message is transmitted.
@@ -1539,30 +1523,18 @@ void
1539GMCH_send_prebuilt_message (const struct GNUNET_MessageHeader *message, 1523GMCH_send_prebuilt_message (const struct GNUNET_MessageHeader *message,
1540 struct MeshChannel *ch, int fwd) 1524 struct MeshChannel *ch, int fwd)
1541{ 1525{
1542 struct GNUNET_MESH_Encrypted *msg;
1543 size_t size = ntohs (message->size); 1526 size_t size = ntohs (message->size);
1544 char *cbuf[sizeof (struct GNUNET_MESH_Encrypted) + size]; 1527
1545 uint16_t type;
1546 uint64_t iv;
1547
1548 LOG (GNUNET_ERROR_TYPE_DEBUG, "Send on Channel %s:%X %s\n", 1528 LOG (GNUNET_ERROR_TYPE_DEBUG, "Send on Channel %s:%X %s\n",
1549 peer2s (ch->t->peer), ch->gid, fwd ? "FWD" : "BCK"); 1529 GMT_2s (ch->t), ch->gid, fwd ? "FWD" : "BCK");
1550 LOG (GNUNET_ERROR_TYPE_DEBUG, " %s\n", 1530 LOG (GNUNET_ERROR_TYPE_DEBUG, " %s\n",
1551 GNUNET_MESH_DEBUG_M2S (ntohs (message->type))); 1531 GNUNET_MESH_DEBUG_M2S (ntohs (message->type)));
1552 1532
1553 if (GMCH_is_terminal (ch, fwd) || ch->t->peer->id == myid) 1533 if (GMT_is_loopback (ch->t))
1554 { 1534 {
1555 GMT_handle_decrypted (ch->t, message, fwd); 1535 handle_loopback (ch->t, message, fwd);
1556 return; 1536 return;
1557 } 1537 }
1558 1538
1559 type = fwd ? GNUNET_MESSAGE_TYPE_MESH_FWD : GNUNET_MESSAGE_TYPE_MESH_BCK; 1539 GMT_send_prebuilt_message (message, ch->t, ch, fwd);
1560 iv = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_NONCE, UINT64_MAX);
1561
1562 msg = (struct GNUNET_MESH_Encrypted *) cbuf;
1563 msg->header.type = htons (type);
1564 msg->header.size = htons (sizeof (struct GNUNET_MESH_Encrypted) + size);
1565 msg->iv = GNUNET_htonll (iv);
1566 GMT_encrypt (ch->t, &msg[1], message, size, iv, fwd);
1567 GMT_send_prebuilt_message (msg, ch->t, ch, fwd);
1568} 1540}
diff --git a/src/mesh/gnunet-service-mesh_channel.h b/src/mesh/gnunet-service-mesh_channel.h
index 48f3e897d..a6f844290 100644
--- a/src/mesh/gnunet-service-mesh_channel.h
+++ b/src/mesh/gnunet-service-mesh_channel.h
@@ -141,10 +141,9 @@ GMCH_send_create (struct MeshChannel *ch);
141 * Notify a client that the channel is no longer valid. 141 * Notify a client that the channel is no longer valid.
142 * 142 *
143 * @param ch Channel that is destroyed. 143 * @param ch Channel that is destroyed.
144 * @param fwd Forward notification (owner->dest)?
145 */ 144 */
146void 145void
147GMCH_send_destroy (struct MeshChannel *ch, int fwd); 146GMCH_send_destroy (struct MeshChannel *ch);
148 147
149 148
150/** 149/**
diff --git a/src/mesh/gnunet-service-mesh_connection.c b/src/mesh/gnunet-service-mesh_connection.c
index edcb79953..776690a76 100644
--- a/src/mesh/gnunet-service-mesh_connection.c
+++ b/src/mesh/gnunet-service-mesh_connection.c
@@ -41,7 +41,6 @@
41 GNUNET_TIME_UNIT_MINUTES,\ 41 GNUNET_TIME_UNIT_MINUTES,\
42 10) 42 10)
43#define MESH_RETRANSMIT_TIME GNUNET_TIME_UNIT_SECONDS 43#define MESH_RETRANSMIT_TIME GNUNET_TIME_UNIT_SECONDS
44#define MESH_RETRANSMIT_MARGIN 4
45 44
46#define LOG(level, ...) GNUNET_log_from (level,"mesh-con",__VA_ARGS__) 45#define LOG(level, ...) GNUNET_log_from (level,"mesh-con",__VA_ARGS__)
47 46
diff --git a/src/mesh/gnunet-service-mesh_local.c b/src/mesh/gnunet-service-mesh_local.c
index 9d7db28bc..3fea3a714 100644
--- a/src/mesh/gnunet-service-mesh_local.c
+++ b/src/mesh/gnunet-service-mesh_local.c
@@ -848,6 +848,7 @@ GML_shutdown (void)
848 } 848 }
849} 849}
850 850
851
851/** 852/**
852 * Get a chennel from a client 853 * Get a chennel from a client
853 * 854 *
@@ -870,6 +871,49 @@ GML_channel_get (struct MeshClient *c, MESH_ChannelNumber chid)
870 return GNUNET_CONTAINER_multihashmap32_get (c->own_channels, chid); 871 return GNUNET_CONTAINER_multihashmap32_get (c->own_channels, chid);
871} 872}
872 873
874
875/**
876 * Add a channel to a client
877 *
878 * @param client Client.
879 * @param chid Channel ID.
880 * @param ch Channel.
881 */
882void
883GML_channel_add (struct MeshClient *client,
884 uint32_t chid,
885 struct MeshChannel *ch)
886{
887 if (chid >= GNUNET_MESH_LOCAL_CHANNEL_ID_SERV)
888 GNUNET_CONTAINER_multihashmap32_put (client->incoming_channels, chid, ch,
889 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
890 else if (chid >= GNUNET_MESH_LOCAL_CHANNEL_ID_CLI)
891 GNUNET_CONTAINER_multihashmap32_put (client->own_channels, chid, ch,
892 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
893 else
894 GNUNET_break (0);
895}
896
897/**
898 * Remove a channel from a client
899 *
900 * @param client Client.
901 * @param chid Channel ID.
902 * @param ch Channel.
903 */
904void
905GML_channel_remove (struct MeshClient *client,
906 uint32_t chid,
907 struct MeshChannel *ch)
908{
909 if (chid >= GNUNET_MESH_LOCAL_CHANNEL_ID_SERV)
910 GNUNET_CONTAINER_multihashmap32_remove (c->incoming_channels, chid, ch);
911 else if (chid >= GNUNET_MESH_LOCAL_CHANNEL_ID_CLI)
912 GNUNET_CONTAINER_multihashmap32_remove (c->own_channels, chid, ch);
913 else
914 GNUNET_break (0);
915}
916
873/** 917/**
874 * Check if client has registered with the service and has not disconnected 918 * Check if client has registered with the service and has not disconnected
875 * 919 *
@@ -1056,4 +1100,18 @@ GML_send_data (struct MeshClient *c,
1056} 1100}
1057 1101
1058 1102
1103/**
1104 * Get the static string to represent a client.
1105 *
1106 * @param c Client.
1107 *
1108 * @return Static string for the client.
1109 */
1110const char *
1111GML_2s (const struct MeshClient *c)
1112{
1113 static char buf[32];
1059 1114
1115 sprintf (buf, "%u", c->id);
1116 return buf;
1117}
diff --git a/src/mesh/gnunet-service-mesh_local.h b/src/mesh/gnunet-service-mesh_local.h
index 22a8f8e6d..637a87aeb 100644
--- a/src/mesh/gnunet-service-mesh_local.h
+++ b/src/mesh/gnunet-service-mesh_local.h
@@ -83,6 +83,30 @@ struct MeshChannel *
83GML_channel_get (struct MeshClient *client, uint32_t chid); 83GML_channel_get (struct MeshClient *client, uint32_t chid);
84 84
85/** 85/**
86 * Add a channel to a client
87 *
88 * @param client Client.
89 * @param chid Channel ID.
90 * @param ch Channel.
91 */
92void
93GML_channel_add (struct MeshClient *client,
94 uint32_t chid,
95 struct MeshChannel *ch);
96
97/**
98 * Remove a channel from a client
99 *
100 * @param client Client.
101 * @param chid Channel ID.
102 * @param ch Channel.
103 */
104void
105GML_channel_remove (struct MeshClient *client,
106 uint32_t chid,
107 struct MeshChannel *ch);
108
109/**
86 * Check if client has registered with the service and has not disconnected 110 * Check if client has registered with the service and has not disconnected
87 * 111 *
88 * @param client the client to check 112 * @param client the client to check
@@ -155,6 +179,16 @@ GML_send_data (struct MeshChannel *ch,
155 const struct GNUNET_MESH_Data *msg, 179 const struct GNUNET_MESH_Data *msg,
156 struct MeshClient *c, MESH_ChannelNumber id); 180 struct MeshClient *c, MESH_ChannelNumber id);
157 181
182/**
183 * Get the static string to represent a client.
184 *
185 * @param c Client.
186 *
187 * @return Static string for the client.
188 */
189const char *
190GML_2s (const struct MeshClient *c);
191
158 192
159#if 0 /* keep Emacsens' auto-indent happy */ 193#if 0 /* keep Emacsens' auto-indent happy */
160{ 194{
diff --git a/src/mesh/gnunet-service-mesh_tunnel.c b/src/mesh/gnunet-service-mesh_tunnel.c
index e709a0be5..362ce7e74 100644
--- a/src/mesh/gnunet-service-mesh_tunnel.c
+++ b/src/mesh/gnunet-service-mesh_tunnel.c
@@ -224,33 +224,6 @@ GMT_state2s (enum MeshTunnelState s)
224 } 224 }
225} 225}
226 226
227
228/**
229 * Search for a channel by global ID using full PeerIdentities.
230 *
231 * @param t Tunnel containing the channel.
232 * @param chid Public channel number.
233 *
234 * @return channel handler, NULL if doesn't exist
235 */
236static struct MeshChannel *
237get_channel (struct MeshTunnel3 *t, MESH_ChannelNumber chid)
238{
239 struct MeshTChannel *iter;
240
241 if (NULL == t)
242 return NULL;
243
244 for (iter = t->channel_head; NULL != iter; iter = iter->next)
245 {
246 if (GMCH_get_id (iter->ch) == chid)
247 break;
248 }
249
250 return NULL == iter ? NULL : iter->ch;
251}
252
253
254/** 227/**
255 * Pick a connection on which send the next data message. 228 * Pick a connection on which send the next data message.
256 * 229 *
@@ -314,7 +287,7 @@ handle_data (struct MeshTunnel3 *t,
314 GNUNET_MESH_DEBUG_M2S (ntohs (msg[1].header.type))); 287 GNUNET_MESH_DEBUG_M2S (ntohs (msg[1].header.type)));
315 288
316 /* Check channel */ 289 /* Check channel */
317 ch = get_channel (t, ntohl (msg->chid)); 290 ch = GMT_get_channel (t, ntohl (msg->chid));
318 if (NULL == ch) 291 if (NULL == ch)
319 { 292 {
320 GNUNET_STATISTICS_update (stats, "# data on unknown channel", 293 GNUNET_STATISTICS_update (stats, "# data on unknown channel",
@@ -345,7 +318,7 @@ handle_data_ack (struct MeshTunnel3 *t,
345 } 318 }
346 319
347 /* Check channel */ 320 /* Check channel */
348 ch = get_channel (t, ntohl (msg->chid)); 321 ch = GMT_get_channel (t, ntohl (msg->chid));
349 if (NULL == ch) 322 if (NULL == ch)
350 { 323 {
351 GNUNET_STATISTICS_update (stats, "# data ack on unknown channel", 324 GNUNET_STATISTICS_update (stats, "# data ack on unknown channel",
@@ -376,7 +349,7 @@ handle_ch_create (struct MeshTunnel3 *t,
376 } 349 }
377 350
378 /* Check channel */ 351 /* Check channel */
379 ch = get_channel (t, ntohl (msg->chid)); 352 ch = GMT_get_channel (t, ntohl (msg->chid));
380 if (NULL != ch) 353 if (NULL != ch)
381 { 354 {
382 /* Probably a retransmission, safe to ignore */ 355 /* Probably a retransmission, safe to ignore */
@@ -409,7 +382,7 @@ handle_ch_ack (struct MeshTunnel3 *t,
409 } 382 }
410 383
411 /* Check channel */ 384 /* Check channel */
412 ch = get_channel (t, ntohl (msg->chid)); 385 ch = GMT_get_channel (t, ntohl (msg->chid));
413 if (NULL == ch) 386 if (NULL == ch)
414 { 387 {
415 GNUNET_STATISTICS_update (stats, "# channel ack on unknown channel", 388 GNUNET_STATISTICS_update (stats, "# channel ack on unknown channel",
@@ -439,7 +412,7 @@ handle_ch_destroy (struct MeshTunnel3 *t,
439 } 412 }
440 413
441 /* Check channel */ 414 /* Check channel */
442 ch = get_channel (t, ntohl (msg->chid)); 415 ch = GMT_get_channel (t, ntohl (msg->chid));
443 if (NULL == ch) 416 if (NULL == ch)
444 { 417 {
445 /* Probably a retransmission, safe to ignore */ 418 /* Probably a retransmission, safe to ignore */
@@ -711,6 +684,74 @@ GMT_remove_connection (struct MeshTunnel3 *t, struct MeshConnection *c)
711 684
712 685
713/** 686/**
687 * Add a channel to a tunnel.
688 *
689 * @param t Tunnel.
690 * @param ch Channel.
691 */
692void
693GMT_add_channel (struct MeshTunnel3 *t, struct MeshChannel *ch)
694{
695 struct MeshTChannel *aux;
696
697 for (aux = t->channel_head; aux != NULL; aux = aux->next)
698 if (aux->ch == ch)
699 return;
700
701 aux = GNUNET_new (struct MeshTChannel);
702 aux->ch = ch;
703 GNUNET_CONTAINER_DLL_insert_tail (t->channel_head, t->channel_tail, aux);
704}
705
706
707/**
708 * Remove a channel from a tunnel.
709 *
710 * @param t Tunnel.
711 * @param ch Channel.
712 */
713void
714GMT_remove_channel (struct MeshTunnel3 *t, struct MeshChannel *ch)
715{
716 struct MeshTChannel *aux;
717
718 for (aux = t->channel_head; aux != NULL; aux = aux->next)
719 if (aux->ch == ch)
720 {
721 GNUNET_CONTAINER_DLL_remove (t->channel_head, t->channel_tail, aux);
722 GNUNET_free (aux);
723 return;
724 }
725}
726
727
728/**
729 * Search for a channel by global ID.
730 *
731 * @param t Tunnel containing the channel.
732 * @param chid Public channel number.
733 *
734 * @return channel handler, NULL if doesn't exist
735 */
736struct MeshChannel *
737GMT_get_channel (struct MeshTunnel3 *t, MESH_ChannelNumber chid)
738{
739 struct MeshTChannel *iter;
740
741 if (NULL == t)
742 return NULL;
743
744 for (iter = t->channel_head; NULL != iter; iter = iter->next)
745 {
746 if (GMCH_get_id (iter->ch) == chid)
747 break;
748 }
749
750 return NULL == iter ? NULL : iter->ch;
751}
752
753
754/**
714 * Tunnel is empty: destroy it. 755 * Tunnel is empty: destroy it.
715 * 756 *
716 * Notifies all connections about the destruction. 757 * Notifies all connections about the destruction.
@@ -874,6 +915,7 @@ GMT_use_path (struct MeshTunnel3 *t, struct MeshPeerPath *p)
874/** 915/**
875 * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME 916 * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
876 * Encrypt data with the tunnel key. 917 * Encrypt data with the tunnel key.
918 * Make static?
877 * 919 *
878 * @param t Tunnel whose key to use. 920 * @param t Tunnel whose key to use.
879 * @param dst Destination for the encrypted data. 921 * @param dst Destination for the encrypted data.
@@ -894,6 +936,7 @@ GMT_encrypt (struct MeshTunnel3 *t,
894/** 936/**
895 * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME 937 * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
896 * Decrypt data with the tunnel key. 938 * Decrypt data with the tunnel key.
939 * Make static?
897 * 940 *
898 * @param t Tunnel whose key to use. 941 * @param t Tunnel whose key to use.
899 * @param dst Destination for the plaintext. 942 * @param dst Destination for the plaintext.
@@ -1016,8 +1059,49 @@ GMT_get_buffer (struct MeshTunnel3 *t, int fwd)
1016 return buffer; 1059 return buffer;
1017} 1060}
1018 1061
1062
1063/**
1064 * Get the tunnel's destination.
1065 *
1066 * @param t Tunnel.
1067 *
1068 * @return ID of the destination peer.
1069 */
1070const struct GNUNET_PeerIdentity *
1071GMT_get_destination (struct MeshTunnel3 *t)
1072{
1073 return GMP_get_id (t->peer);
1074}
1075
1076
1077
1019/** 1078/**
1020 * Sends an already built message on a tunnel, choosing the best connection. 1079 * Get the tunnel's next free Channel ID.
1080 *
1081 * @param t Tunnel.
1082 *
1083 * @return ID of a channel free to use.
1084 */
1085MESH_ChannelNumber
1086GMT_get_next_chid (struct MeshTunnel3 *t)
1087{
1088 MESH_ChannelNumber chid;
1089
1090 while (NULL != GMT_get_channel (t, t->next_chid))
1091 {
1092 LOG (GNUNET_ERROR_TYPE_DEBUG, "Channel %u exists...\n", t->next_chid);
1093 t->next_chid = (t->next_chid + 1) & ~GNUNET_MESH_LOCAL_CHANNEL_ID_CLI;
1094 }
1095 chid = t->next_chid;
1096 t->next_chid = (t->next_chid + 1) & ~GNUNET_MESH_LOCAL_CHANNEL_ID_CLI;
1097
1098 return chid;
1099}
1100
1101
1102/**
1103 * Sends an already built message on a tunnel, encrypting it and
1104 * choosing the best connection.
1021 * 1105 *
1022 * @param message Message to send. Function modifies it. 1106 * @param message Message to send. Function modifies it.
1023 * @param t Tunnel on which this message is transmitted. 1107 * @param t Tunnel on which this message is transmitted.
@@ -1025,22 +1109,33 @@ GMT_get_buffer (struct MeshTunnel3 *t, int fwd)
1025 * @param fwd Is this a fwd message? 1109 * @param fwd Is this a fwd message?
1026 */ 1110 */
1027void 1111void
1028GMT_send_prebuilt_message (struct GNUNET_MESH_Encrypted *msg, 1112GMT_send_prebuilt_message (const struct GNUNET_MessageHeader *message,
1029 struct MeshTunnel3 *t, 1113 struct MeshTunnel3 *t,
1030 struct MeshChannel *ch, 1114 struct MeshChannel *ch,
1031 int fwd) 1115 int fwd)
1032{ 1116{
1033 struct MeshConnection *c; 1117 struct MeshConnection *c;
1118 struct GNUNET_MESH_Encrypted *msg;
1119 size_t size = ntohs (message->size);
1120 char *cbuf[sizeof (struct GNUNET_MESH_Encrypted) + size];
1121 uint64_t iv;
1034 uint16_t type; 1122 uint16_t type;
1035 1123
1036 LOG (GNUNET_ERROR_TYPE_DEBUG, "Send on Tunnel %s\n", GMP_2s (t->peer)); 1124 LOG (GNUNET_ERROR_TYPE_DEBUG, "Send on Tunnel %s\n", GMP_2s (t->peer));
1125
1126 iv = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_NONCE, UINT64_MAX);
1127 msg = (struct GNUNET_MESH_Encrypted *) cbuf;
1128 msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_ENCRYPTED);
1129 msg->header.size = htons (sizeof (struct GNUNET_MESH_Encrypted) + size);
1130 msg->iv = GNUNET_htonll (iv);
1131 GMT_encrypt (t, &msg[1], message, size, iv, fwd);
1037 c = tunnel_get_connection (t, fwd); 1132 c = tunnel_get_connection (t, fwd);
1038 if (NULL == c) 1133 if (NULL == c)
1039 { 1134 {
1040 GNUNET_break (GNUNET_YES == t->destroy); 1135 GNUNET_break (GNUNET_YES == t->destroy);
1041 return; 1136 return;
1042 } 1137 }
1043 type = ntohs (msg->header.type); 1138 type = ntohs (message->type);
1044 switch (type) 1139 switch (type)
1045 { 1140 {
1046 case GNUNET_MESSAGE_TYPE_MESH_FWD: 1141 case GNUNET_MESSAGE_TYPE_MESH_FWD:
@@ -1059,3 +1154,30 @@ GMT_send_prebuilt_message (struct GNUNET_MESH_Encrypted *msg,
1059 1154
1060 GMC_send_prebuilt_message (&msg->header, c, ch, fwd); 1155 GMC_send_prebuilt_message (&msg->header, c, ch, fwd);
1061} 1156}
1157
1158/**
1159 * Is the tunnel directed towards the local peer?
1160 *
1161 * @param t Tunnel.
1162 *
1163 * @return GNUNET_YES if it is loopback.
1164 */
1165int
1166GMT_is_loopback (const struct MeshTunnel3 *t)
1167{
1168 return (my_short_id == GMP_get_short_id(t->peer));
1169}
1170
1171
1172/**
1173 * Get the static string for the peer this tunnel is directed.
1174 *
1175 * @param t Tunnel.
1176 *
1177 * @return Static string the destination peer's ID.
1178 */
1179const char *
1180GMT_2s (const struct MeshTunnel3 *t)
1181{
1182 return GMP_2s (t->peer);
1183} \ No newline at end of file
diff --git a/src/mesh/gnunet-service-mesh_tunnel.h b/src/mesh/gnunet-service-mesh_tunnel.h
index 49e4ce4b2..242d2c318 100644
--- a/src/mesh/gnunet-service-mesh_tunnel.h
+++ b/src/mesh/gnunet-service-mesh_tunnel.h
@@ -153,7 +153,6 @@ GMT_change_state (struct MeshTunnel3* t, enum MeshTunnelState state);
153void 153void
154GMT_add_connection (struct MeshTunnel3 *t, struct MeshConnection *c); 154GMT_add_connection (struct MeshTunnel3 *t, struct MeshConnection *c);
155 155
156
157/** 156/**
158 * Remove a connection from a tunnel. 157 * Remove a connection from a tunnel.
159 * 158 *
@@ -164,6 +163,36 @@ void
164GMT_remove_connection (struct MeshTunnel3 *t, struct MeshConnection *c); 163GMT_remove_connection (struct MeshTunnel3 *t, struct MeshConnection *c);
165 164
166/** 165/**
166 * Add a channel to a tunnel.
167 *
168 * @param t Tunnel.
169 * @param ch Channel.
170 */
171void
172GMT_add_channel (struct MeshTunnel3 *t, struct MeshChannel *ch);
173
174/**
175 * Remove a channel from a tunnel.
176 *
177 * @param t Tunnel.
178 * @param ch Channel.
179 */
180void
181GMT_remove_channel (struct MeshTunnel3 *t, struct MeshChannel *ch);
182
183/**
184 * Search for a channel by global ID.
185 *
186 * @param t Tunnel containing the channel.
187 * @param chid Public channel number.
188 *
189 * @return channel handler, NULL if doesn't exist
190 */
191struct MeshChannel *
192GMT_get_channel (struct MeshTunnel3 *t, MESH_ChannelNumber chid);
193
194
195/**
167 * Cache a message to be sent once tunnel is online. 196 * Cache a message to be sent once tunnel is online.
168 * 197 *
169 * @param t Tunnel to hold the message. 198 * @param t Tunnel to hold the message.
@@ -227,6 +256,61 @@ GMT_get_state (struct MeshTunnel3 *t);
227unsigned int 256unsigned int
228GMT_get_buffer (struct MeshTunnel3 *t, int fwd); 257GMT_get_buffer (struct MeshTunnel3 *t, int fwd);
229 258
259/**
260 * Get the tunnel's destination.
261 *
262 * @param t Tunnel.
263 *
264 * @return ID of the destination peer.
265 */
266const struct GNUNET_PeerIdentity *
267GMT_get_destination (struct MeshTunnel3 *t);
268
269/**
270 * Get the tunnel's next free Channel ID.
271 *
272 * @param t Tunnel.
273 *
274 * @return ID of a channel free to use.
275 */
276MESH_ChannelNumber
277GMT_get_next_chid (struct MeshTunnel3 *t);
278
279/**
280 * Sends an already built message on a tunnel, encrypting it and
281 * choosing the best connection.
282 *
283 * @param message Message to send. Function modifies it.
284 * @param t Tunnel on which this message is transmitted.
285 * @param ch Channel on which this message is transmitted.
286 * @param fwd Is this a fwd message?
287 */
288void
289GMT_send_prebuilt_message (const struct GNUNET_MessageHeader *message,
290 struct MeshTunnel3 *t,
291 struct MeshChannel *ch,
292 int fwd);
293
294/**
295 * Is the tunnel directed towards the local peer?
296 *
297 * @param t Tunnel.
298 *
299 * @return GNUNET_YES if it is loopback.
300 */
301int
302GMT_is_loopback (const struct MeshTunnel3 *t);
303
304/**
305 * Get the static string for the peer this tunnel is directed.
306 *
307 * @param t Tunnel.
308 *
309 * @return Static string the destination peer's ID.
310 */
311const char *
312GMT_2s (const struct MeshTunnel3 *t);
313
230#if 0 /* keep Emacsens' auto-indent happy */ 314#if 0 /* keep Emacsens' auto-indent happy */
231{ 315{
232#endif 316#endif