2 This file is part of GNUnet.
3 (C) 2013 Christian Grothoff (and other contributing authors)
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
22 #include "gnunet_util_lib.h"
24 #include "gnunet_statistics_service.h"
26 #include "mesh_protocol_enc.h"
28 #include "gnunet-service-mesh_tunnel.h"
29 #include "gnunet-service-mesh_connection.h"
30 #include "gnunet-service-mesh_channel.h"
31 #include "gnunet-service-mesh_peer.h"
32 #include "mesh_path.h"
34 #define LOG(level, ...) GNUNET_log_from(level,"mesh-tun",__VA_ARGS__)
37 /******************************************************************************/
38 /******************************** STRUCTS **********************************/
39 /******************************************************************************/
43 struct MeshTChannel *next;
44 struct MeshTChannel *prev;
45 struct MeshChannel *ch;
48 struct MeshTConnection
50 struct MeshTConnection *next;
51 struct MeshTConnection *prev;
52 struct MeshConnection *c;
56 * Struct containing all information regarding a tunnel to a peer.
61 * Endpoint of the tunnel.
63 struct MeshPeer *peer;
66 * State of the tunnel.
68 enum MeshTunnelState state;
71 * Local peer ephemeral private key
73 struct GNUNET_CRYPTO_EccPrivateKey *my_eph_key;
76 * Local peer ephemeral public key
78 struct GNUNET_CRYPTO_EccPublicSignKey *my_eph;
81 * Remote peer's public key.
83 struct GNUNET_CRYPTO_EccPublicSignKey *peers_eph;
86 * Encryption ("our") key.
88 struct GNUNET_CRYPTO_SymmetricSessionKey e_key;
91 * Decryption ("their") key.
93 struct GNUNET_CRYPTO_SymmetricSessionKey d_key;
96 * Paths that are actively used to reach the destination peer.
98 struct MeshTConnection *connection_head;
99 struct MeshTConnection *connection_tail;
102 * Next connection number.
107 * Channels inside this tunnel.
109 struct MeshTChannel *channel_head;
110 struct MeshTChannel *channel_tail;
113 * Channel ID for the next created channel.
115 MESH_ChannelNumber next_chid;
118 * Channel ID for the next incoming channel.
120 MESH_ChannelNumber next_local_chid;
123 * Pending message count.
125 int pending_messages;
128 * Destroy flag: if true, destroy on last message.
133 * Queued messages, to transmit once tunnel gets connected.
135 struct MeshTunnelQueue *tq_head;
136 struct MeshTunnelQueue *tq_tail;
141 * Struct used to queue messages in a tunnel.
143 struct MeshTunnelQueue
148 struct MeshTunnelQueue *next;
149 struct MeshTunnelQueue *prev;
154 struct MeshChannel *ch;
159 /* struct GNUNET_MessageHeader *msg; */
162 /******************************************************************************/
163 /******************************* GLOBALS ***********************************/
164 /******************************************************************************/
167 * Global handle to the statistics service.
169 extern struct GNUNET_STATISTICS_Handle *stats;
172 * Default TTL for payload packets.
174 static unsigned long long default_ttl;
177 * Local peer own ID (memory efficient handle).
179 static GNUNET_PEER_Id my_short_id;
182 * Local peer own ID (full value).
184 const static struct GNUNET_PeerIdentity *my_full_id;
189 const static struct GNUNET_CRYPTO_EccPrivateKey *my_private_key;
192 /******************************************************************************/
193 /******************************** STATIC ***********************************/
194 /******************************************************************************/
197 * Get string description for tunnel state.
199 * @param s Tunnel state.
201 * @return String representation.
204 GMT_state2s (enum MeshTunnelState s)
206 static char buf[128];
210 case MESH_TUNNEL_NEW:
211 return "MESH_TUNNEL_NEW";
212 case MESH_TUNNEL_SEARCHING:
213 return "MESH_TUNNEL_SEARCHING";
214 case MESH_TUNNEL_WAITING:
215 return "MESH_TUNNEL_WAITING";
216 case MESH_TUNNEL_READY:
217 return "MESH_TUNNEL_READY";
218 case MESH_TUNNEL_RECONNECTING:
219 return "MESH_TUNNEL_RECONNECTING";
222 sprintf (buf, "%u (UNKNOWN STATE)", s);
229 * Search for a channel by global ID using full PeerIdentities.
231 * @param t Tunnel containing the channel.
232 * @param chid Public channel number.
234 * @return channel handler, NULL if doesn't exist
236 static struct MeshChannel *
237 get_channel (struct MeshTunnel3 *t, MESH_ChannelNumber chid)
239 struct MeshTChannel *iter;
244 for (iter = t->channel_head; NULL != iter; iter = iter->next)
246 if (GMCH_get_id (iter->ch) == chid)
250 return NULL == iter ? NULL : iter->ch;
255 * Pick a connection on which send the next data message.
257 * @param t Tunnel on which to send the message.
258 * @param fwd Is this a fwd message?
260 * @return The connection on which to send the next message.
262 static struct MeshConnection *
263 tunnel_get_connection (struct MeshTunnel3 *t, int fwd)
265 struct MeshTConnection *iter;
266 struct MeshConnection *best;
268 unsigned int lowest_q;
270 LOG (GNUNET_ERROR_TYPE_DEBUG, "tunnel_get_connection %s\n", GMP_2s (t->peer));
273 for (iter = t->connection_head; NULL != iter; iter = iter->next)
275 LOG (GNUNET_ERROR_TYPE_DEBUG, " connection %s: %u\n",
276 GNUNET_h2s (GMC_get_id (iter->c)), GMC_get_state (iter->c));
277 if (MESH_CONNECTION_READY == GMC_get_state (iter->c))
279 qn = GMC_get_qn (iter->c, fwd);
280 LOG (GNUNET_ERROR_TYPE_DEBUG, " q_n %u, \n", qn);
293 * Send all cached messages that we can, tunnel is online.
295 * @param t Tunnel that holds the messages.
296 * @param fwd Is this fwd?
299 tunnel_send_queued_data (struct MeshTunnel3 *t, int fwd)
301 struct MeshTunnelQueue *tq;
302 struct MeshTunnelQueue *next;
305 LOG (GNUNET_ERROR_TYPE_DEBUG,
306 "tunnel_send_queued_data on tunnel %s\n",
308 room = GMT_get_buffer (t, fwd);
309 LOG (GNUNET_ERROR_TYPE_DEBUG, " buffer space: %u\n", room);
310 for (tq = t->tq_head; NULL != tq && room > 0; tq = next)
314 GNUNET_CONTAINER_DLL_remove (t->tq_head, t->tq_tail, tq);
315 GMCH_send_prebuilt_message ((struct GNUNET_MessageHeader *) &tq[1],
323 handle_data (struct MeshTunnel3 *t,
324 const struct GNUNET_MESH_Data *msg,
327 struct MeshChannel *ch;
332 size = ntohs (msg->header.size);
334 sizeof (struct GNUNET_MESH_Data) +
335 sizeof (struct GNUNET_MessageHeader))
340 type = ntohs (msg->header.type);
341 LOG (GNUNET_ERROR_TYPE_DEBUG, "got a %s message\n",
342 GNUNET_MESH_DEBUG_M2S (type));
343 LOG (GNUNET_ERROR_TYPE_DEBUG, " payload of type %s\n",
344 GNUNET_MESH_DEBUG_M2S (ntohs (msg[1].header.type)));
347 ch = get_channel (t, ntohl (msg->chid));
350 GNUNET_STATISTICS_update (stats, "# data on unknown channel",
352 LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel %u unknown\n",
357 GMT_change_state (t, MESH_TUNNEL_READY);
358 GMCH_handle_data (ch, msg, fwd);
362 handle_data_ack (struct MeshTunnel3 *t,
363 const struct GNUNET_MESH_DataACK *msg,
366 struct MeshChannel *ch;
370 size = ntohs (msg->header.size);
371 if (size != sizeof (struct GNUNET_MESH_DataACK))
378 ch = get_channel (t, ntohl (msg->chid));
381 GNUNET_STATISTICS_update (stats, "# data ack on unknown channel",
383 LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel %u unknown\n",
388 GMCH_handle_data_ack (ch, msg, fwd);
392 handle_ch_create (struct MeshTunnel3 *t,
393 const struct GNUNET_MESH_ChannelCreate *msg,
396 struct MeshTChannel *tch;
397 struct MeshChannel *ch;
401 size = ntohs (msg->header.size);
402 if (size != sizeof (struct GNUNET_MESH_ChannelCreate))
409 ch = get_channel (t, ntohl (msg->chid));
412 /* Probably a retransmission, safe to ignore */
413 LOG (GNUNET_ERROR_TYPE_DEBUG, " already exists...\n");
417 ch = GMCH_handle_create (msg, fwd);
420 tch = GNUNET_new (struct MeshTChannel);
422 GNUNET_CONTAINER_DLL_insert (t->channel_head, t->channel_tail, tch);
426 handle_ch_ack (struct MeshTunnel3 *t,
427 const struct GNUNET_MESH_ChannelManage *msg,
430 struct MeshChannel *ch;
434 size = ntohs (msg->header.size);
435 if (size != sizeof (struct GNUNET_MESH_ChannelManage))
442 ch = get_channel (t, ntohl (msg->chid));
445 GNUNET_STATISTICS_update (stats, "# channel ack on unknown channel",
447 LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel %u unknown\n",
452 GMCH_handle_ack (ch, msg, fwd);
456 handle_ch_destroy (struct MeshTunnel3 *t,
457 const struct GNUNET_MESH_ChannelManage *msg,
460 struct MeshChannel *ch;
464 size = ntohs (msg->header.size);
465 if (size != sizeof (struct GNUNET_MESH_ChannelManage))
472 ch = get_channel (t, ntohl (msg->chid));
475 /* Probably a retransmission, safe to ignore */
479 GMCH_handle_destroy (ch, msg, fwd);
482 /******************************************************************************/
483 /******************************** API ***********************************/
484 /******************************************************************************/
487 * Demultiplex by message type and call appropriate handler for a message
488 * towards a channel of a local tunnel.
490 * @param t Tunnel this message came on.
491 * @param msgh Message header.
492 * @param fwd Is this message fwd?
495 GMT_handle_decrypted (struct MeshTunnel3 *t,
496 const struct GNUNET_MessageHeader *msgh,
501 type = ntohs (msgh->type);
502 LOG (GNUNET_ERROR_TYPE_DEBUG,
503 "Got a %s message!\n",
504 GNUNET_MESH_DEBUG_M2S (type));
508 case GNUNET_MESSAGE_TYPE_MESH_DATA:
509 /* Don't send hop ACK, wait for client to ACK */
510 handle_data (t, (struct GNUNET_MESH_Data *) msgh, fwd);
513 case GNUNET_MESSAGE_TYPE_MESH_DATA_ACK:
514 handle_data_ack (t, (struct GNUNET_MESH_DataACK *) msgh, fwd);
517 case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
519 (struct GNUNET_MESH_ChannelCreate *) msgh,
523 case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK:
525 (struct GNUNET_MESH_ChannelManage *) msgh,
529 case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY:
530 handle_ch_destroy (t,
531 (struct GNUNET_MESH_ChannelManage *) msgh,
537 LOG (GNUNET_ERROR_TYPE_DEBUG,
538 "end-to-end message not known (%u)\n",
545 * Cache a message to be sent once tunnel is online.
547 * @param t Tunnel to hold the message.
548 * @param ch Channel the message is about.
549 * @param msg Message itself (copy will be made).
550 * @param fwd Is this fwd?
553 GMT_queue_data (struct MeshTunnel3 *t,
554 struct MeshChannel *ch,
555 struct GNUNET_MessageHeader *msg,
558 struct MeshTunnelQueue *tq;
559 uint16_t size = ntohs (msg->size);
561 tq = GNUNET_malloc (sizeof (struct MeshTunnelQueue) + size);
564 memcpy (&tq[1], msg, size);
565 GNUNET_CONTAINER_DLL_insert_tail (t->tq_head, t->tq_tail, tq);
567 if (MESH_TUNNEL_READY == t->state)
568 tunnel_send_queued_data (t, fwd);
573 * Initialize the tunnel subsystem.
575 * @param c Configuration handle.
576 * @param id Peer identity.
577 * @param key ECC private key, to derive all other keys and do crypto.
580 GMT_init (const struct GNUNET_CONFIGURATION_Handle *c,
581 const struct GNUNET_PeerIdentity *id,
582 const struct GNUNET_CRYPTO_EccPrivateKey *key)
585 GNUNET_CONFIGURATION_get_value_number (c, "MESH", "DEFAULT_TTL",
588 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
589 "MESH", "DEFAULT_TTL", "USING DEFAULT");
593 my_private_key = key;
594 my_short_id = GNUNET_PEER_intern (my_full_id);
599 * Shut down the tunnel subsystem.
604 GNUNET_PEER_change_rc (my_short_id, -1);
614 struct MeshTunnel3 *t;
616 t = GNUNET_new (struct MeshTunnel3);
618 t->next_local_chid = GNUNET_MESH_LOCAL_CHANNEL_ID_SERV;
620 // GNUNET_CONTAINER_multihashmap_put (tunnels, tid, t,
621 // GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
624 // tunnel_destroy (t);
628 // char salt[] = "salt";
629 // GNUNET_CRYPTO_kdf (&t->e_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
630 // salt, sizeof (salt),
631 // &t->e_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
632 // &my_full_id, sizeof (struct GNUNET_PeerIdentity),
633 // GNUNET_PEER_resolve2 (t->peer->id), sizeof (struct GNUNET_PeerIdentity),
635 // GNUNET_CRYPTO_kdf (&t->d_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
636 // salt, sizeof (salt),
637 // &t->d_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
638 // GNUNET_PEER_resolve2 (t->peer->id), sizeof (struct GNUNET_PeerIdentity),
639 // &my_full_id, sizeof (struct GNUNET_PeerIdentity),
648 * Change the tunnel state.
650 * @param t Tunnel whose state to change.
651 * @param state New state.
654 GMT_change_state (struct MeshTunnel3* t, enum MeshTunnelState state)
658 LOG (GNUNET_ERROR_TYPE_DEBUG,
659 "Tunnel %s state was %s\n",
661 GMT_state2s (t->state));
662 LOG (GNUNET_ERROR_TYPE_DEBUG,
663 "Tunnel %s state is now %s\n",
665 GMT_state2s (state));
671 * Add a connection to a tunnel.
674 * @param c Connection.
677 GMT_add_connection (struct MeshTunnel3 *t, struct MeshConnection *c)
679 struct MeshTConnection *aux;
681 for (aux = t->connection_head; aux != NULL; aux = aux->next)
685 aux = GNUNET_new (struct MeshTConnection);
687 GNUNET_CONTAINER_DLL_insert_tail (t->connection_head, t->connection_tail, aux);
692 * Remove a connection from a tunnel.
695 * @param c Connection.
698 GMT_remove_connection (struct MeshTunnel3 *t, struct MeshConnection *c)
700 struct MeshTConnection *aux;
702 for (aux = t->connection_head; aux != NULL; aux = aux->next)
705 GNUNET_CONTAINER_DLL_remove (t->connection_head, t->connection_tail, aux);
713 * Tunnel is empty: destroy it.
715 * Notifies all connections about the destruction.
717 * @param t Tunnel to destroy.
720 GMT_destroy_empty (struct MeshTunnel3 *t)
722 struct MeshTConnection *iter;
724 for (iter = t->connection_head; NULL != iter; iter = iter->next)
726 GMC_send_destroy (iter->c);
729 if (0 == t->pending_messages)
732 t->destroy = GNUNET_YES;
737 * Destroy tunnel if empty (no more channels).
739 * @param t Tunnel to destroy if empty.
742 GMT_destroy_if_empty (struct MeshTunnel3 *t)
744 if (1 < GMT_count_channels (t))
747 GMT_destroy_empty (t);
752 * Destroy the tunnel.
754 * This function does not generate any warning traffic to clients or peers.
757 * Cancel messages belonging to this tunnel queued to neighbors.
758 * Free any allocated resources linked to the tunnel.
760 * @param t The tunnel to destroy.
763 GMT_destroy (struct MeshTunnel3 *t)
765 struct MeshTConnection *iter;
766 struct MeshTConnection *next;
771 LOG (GNUNET_ERROR_TYPE_DEBUG, "destroying tunnel %s\n", GMP_2s (t->peer));
773 // if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (tunnels, &t->id, t))
776 for (iter = t->connection_head; NULL != iter; iter = next)
779 GMC_destroy (iter->c);
783 GNUNET_STATISTICS_update (stats, "# tunnels", -1, GNUNET_NO);
784 GMP_set_tunnel (t->peer, NULL);
791 * Notifies a tunnel that a connection has broken that affects at least
792 * some of its peers. Sends a notification towards the root of the tree.
793 * In case the peer is the owner of the tree, notifies the client that owns
794 * the tunnel and tries to reconnect.
796 * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
798 * @param t Tunnel affected.
799 * @param p1 Peer that got disconnected from p2.
800 * @param p2 Peer that got disconnected from p1.
802 * @return Short ID of the peer disconnected (either p1 or p2).
803 * 0 if the tunnel remained unaffected.
806 GMT_notify_connection_broken (struct MeshTunnel3* t,
807 GNUNET_PEER_Id p1, GNUNET_PEER_Id p2)
809 // if (myid != p1 && myid != p2) FIXME
814 // if (tree_get_predecessor (t->tree) != 0)
816 // /* We are the peer still connected, notify owner of the disconnection. */
817 // struct GNUNET_MESH_PathBroken msg;
818 // struct GNUNET_PeerIdentity neighbor;
820 // msg.header.size = htons (sizeof (msg));
821 // msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_BROKEN);
822 // GNUNET_PEER_resolve (t->id.oid, &msg.oid);
823 // msg.tid = htonl (t->id.tid);
824 // msg.peer1 = my_full_id;
825 // GNUNET_PEER_resolve (pid, &msg.peer2);
826 // GNUNET_PEER_resolve (tree_get_predecessor (t->tree), &neighbor);
827 // send_prebuilt_message (&msg.header, &neighbor, t);
833 * @brief Use the given path for the tunnel.
834 * Update the next and prev hops (and RCs).
835 * (Re)start the path refresh in case the tunnel is locally owned.
837 * @param t Tunnel to update.
838 * @param p Path to use.
840 * @return Connection created.
842 struct MeshConnection *
843 GMT_use_path (struct MeshTunnel3 *t, struct MeshPeerPath *p)
845 struct MeshConnection *c;
846 struct GNUNET_HashCode cid;
847 unsigned int own_pos;
849 if (NULL == t || NULL == p)
855 for (own_pos = 0; own_pos < p->length; own_pos++)
857 if (p->peers[own_pos] == my_short_id)
860 if (own_pos > p->length - 1)
866 GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_NONCE, &cid);
867 c = GMC_new (&cid, t, p, own_pos);
868 GMT_add_connection (t, c);
874 * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
875 * Encrypt data with the tunnel key.
877 * @param t Tunnel whose key to use.
878 * @param dst Destination for the encrypted data.
879 * @param src Source of the plaintext.
880 * @param size Size of the plaintext.
881 * @param iv Initialization Vector to use.
882 * @param fwd Is this a fwd message?
885 GMT_encrypt (struct MeshTunnel3 *t,
886 void *dst, const void *src,
887 size_t size, uint64_t iv, int fwd)
889 memcpy (dst, src, size);
894 * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
895 * Decrypt data with the tunnel key.
897 * @param t Tunnel whose key to use.
898 * @param dst Destination for the plaintext.
899 * @param src Source of the encrypted data.
900 * @param size Size of the encrypted data.
901 * @param iv Initialization Vector to use.
902 * @param fwd Is this a fwd message?
905 GMT_decrypt (struct MeshTunnel3 *t,
906 void *dst, const void *src,
907 size_t size, uint64_t iv, int fwd)
909 memcpy (dst, src, size);
914 * Count established (ready) connections of a tunnel.
916 * @param t Tunnel on which to count.
918 * @return Number of connections.
921 GMT_count_connections (struct MeshTunnel3 *t)
923 struct MeshTConnection *iter;
926 for (count = 0, iter = t->connection_head;
928 iter = iter->next, count++);
934 * Count channels of a tunnel.
936 * @param t Tunnel on which to count.
938 * @return Number of channels.
941 GMT_count_channels (struct MeshTunnel3 *t)
943 struct MeshTChannel *iter;
946 for (count = 0, iter = t->channel_head;
948 iter = iter->next, count++);
955 * Get the total buffer space for a tunnel.
958 * @param fwd Is this for FWD traffic?
960 * @return Buffer space offered by all connections in the tunnel.
963 GMT_get_buffer (struct MeshTunnel3 *t, int fwd)
965 struct MeshTConnection *iter;
968 iter = t->connection_head;
971 /* If terminal, return biggest channel buffer */
972 if (NULL == iter || GMC_is_terminal (iter->c, fwd))
974 struct MeshTChannel *iter_ch;
977 if (NULL == t->channel_head)
980 for (iter_ch = t->channel_head; NULL != iter_ch; iter_ch = iter_ch->next)
982 ch_buf = GMCH_get_buffer (iter_ch->ch, fwd);
989 /* If not terminal, return sum of connection buffers */
992 if (GMC_get_state (iter->c) != MESH_CONNECTION_READY)
998 buffer += GMC_get_buffer (iter->c, fwd);
1006 * Sends an already built message on a tunnel, choosing the best connection.
1008 * @param message Message to send. Function modifies it.
1009 * @param t Tunnel on which this message is transmitted.
1010 * @param ch Channel on which this message is transmitted.
1011 * @param fwd Is this a fwd message?
1014 GMT_send_prebuilt_message (struct GNUNET_MESH_Encrypted *msg,
1015 struct MeshTunnel3 *t,
1016 struct MeshChannel *ch,
1019 struct MeshConnection *c;
1022 LOG (GNUNET_ERROR_TYPE_DEBUG, "Send on Tunnel %s\n", GMP_2s (t->peer));
1023 c = tunnel_get_connection (t, fwd);
1026 GNUNET_break (GNUNET_YES == t->destroy);
1029 type = ntohs (msg->header.type);
1032 case GNUNET_MESSAGE_TYPE_MESH_FWD:
1033 case GNUNET_MESSAGE_TYPE_MESH_BCK:
1034 case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
1035 case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY:
1036 msg->cid = *GMC_get_id (c);
1037 msg->ttl = htonl (default_ttl);
1040 LOG (GNUNET_ERROR_TYPE_DEBUG, "unkown type %s\n",
1041 GNUNET_MESH_DEBUG_M2S (type));
1046 GMC_send_prebuilt_message (&msg->header, c, ch, fwd);