aboutsummaryrefslogtreecommitdiff
path: root/src/mesh/gnunet-service-mesh_channel.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesh/gnunet-service-mesh_channel.c')
-rw-r--r--src/mesh/gnunet-service-mesh_channel.c242
1 files changed, 107 insertions, 135 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}