AM_CLFAGS = -g
libexec_PROGRAMS = \
- gnunet-service-cadet $(EXP_LIBEXEC)
+ gnunet-service-cadet \
+ gnunet-service-cadet-new \
+ $(EXP_LIBEXEC)
bin_PROGRAMS = \
gnunet-cadet
libgnunetcadet.la \
$(top_builddir)/src/util/libgnunetutil.la
+gnunet_service_cadet_new_SOURCES = \
+ gnunet-service-cadet-new.c gnunet-service-cadet-new.h \
+ gnunet-service-cadet-new_channel.c gnunet-service-cadet-new_channel.h \
+ gnunet-service-cadet-new_connection.c gnunet-service-cadet-new_connection.h \
+ gnunet-service-cadet-new_dht.c gnunet-service-cadet-new_dht.h \
+ gnunet-service-cadet-new_hello.c gnunet-service-cadet-new_hello.h \
+ gnunet-service-cadet-new_tunnels.c gnunet-service-cadet-new_tunnels.h \
+ gnunet-service-cadet-new_paths.c gnunet-service-cadet-new_paths.h \
+ gnunet-service-cadet-new_peer.c gnunet-service-cadet-new_peer.h
+gnunet_service_cadet_new_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/ats/libgnunetats.la \
+ $(top_builddir)/src/core/libgnunetcore.la \
+ $(top_builddir)/src/dht/libgnunetdht.la \
+ $(top_builddir)/src/statistics/libgnunetstatistics.la \
+ $(top_builddir)/src/transport/libgnunettransport.la \
+ $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \
+ $(top_builddir)/src/hello/libgnunethello.la \
+ $(top_builddir)/src/block/libgnunetblock.la
+
gnunet_service_cadet_SOURCES = \
gnunet-service-cadet_tunnel.c gnunet-service-cadet_tunnel.h \
gnunet-service-cadet_connection.c gnunet-service-cadet_connection.h \
if HAVE_TESTING
check_PROGRAMS = \
+ test_cadet_2_speed_reliable_backwards \
+ test_cadet_5_speed \
+ test_cadet_5_speed_ack \
+ test_cadet_5_speed_reliable \
+ test_cadet_5_speed_reliable_backwards \
test_cadet_single \
test_cadet_local \
test_cadet_2_forward \
test_cadet_2_speed_ack \
test_cadet_2_speed_backwards \
test_cadet_2_speed_reliable \
- test_cadet_2_speed_reliable_backwards \
test_cadet_5_forward \
test_cadet_5_signal \
test_cadet_5_keepalive \
- test_cadet_5_speed \
- test_cadet_5_speed_ack \
- test_cadet_5_speed_backwards \
- test_cadet_5_speed_reliable \
- test_cadet_5_speed_reliable_backwards
+ test_cadet_5_speed_backwards
endif
ld_cadet_test_lib = \
#include "gnunet_util_lib.h"
#include "gnunet_peer_lib.h"
#include "gnunet_core_service.h"
+#include "gnunet_cadet_service.h"
#include "gnunet_protocols.h"
#include <gnunet_cadet_service.h>
/************************** CONSTANTS ******************************/
/******************************************************************************/
+/**
+ * Minimum value for channel IDs of local clients.
+ */
#define GNUNET_CADET_LOCAL_CHANNEL_ID_CLI 0x80000000
-#define GNUNET_CADET_LOCAL_CHANNEL_ID_SERV 0xB0000000
+/**
+ * FIXME.
+ */
#define HIGH_PID 0xFF000000
+
+/**
+ * FIXME.
+ */
#define LOW_PID 0x00FFFFFF
+
/**
* Test if the two PIDs (of type `uint32_t`) are in the range where we
* have to worry about overflows. This is the case when @a pid is
GNUNET_NETWORK_STRUCT_BEGIN
+/**
+ * Number uniquely identifying a channel of a client.
+ */
+struct GNUNET_CADET_ClientChannelNumber
+{
+ /**
+ * Values for channel numbering.
+ * Local channel numbers given by the service (incoming) are
+ * smaller than #GNUNET_CADET_LOCAL_CHANNEL_ID_CLI.
+ * Local channel numbers given by the client (created) are
+ * larger than #GNUNET_CADET_LOCAL_CHANNEL_ID_CLI.
+ */
+ uint32_t channel_of_client GNUNET_PACKED;
+};
+
+
/**
* Message for a client to create and destroy channels.
*/
struct GNUNET_HashCode port GNUNET_PACKED;
};
-/**
- * Type for channel numbering.
- * - Local channel numbers given by the service (incoming) are >= 0xB0000000
- * - Local channel numbers given by the client (created) are >= 0x80000000
- * - Global channel numbers are < 0x80000000
- */
-typedef uint32_t CADET_ChannelNumber;
-
/**
* Message for a client to create channels.
/**
* ID of a channel controlled by this client.
*/
- CADET_ChannelNumber channel_id GNUNET_PACKED;
+ struct GNUNET_CADET_ClientChannelNumber channel_id;
/**
* Channel's peer
* Size: sizeof(struct GNUNET_CADET_ChannelDestroyMessage)
*/
struct GNUNET_MessageHeader header;
-
+
/**
* ID of a channel controlled by this client.
*/
- CADET_ChannelNumber channel_id GNUNET_PACKED;
+ struct GNUNET_CADET_ClientChannelNumber channel_id;
};
/**
* ID of the channel
*/
- uint32_t id GNUNET_PACKED;
+ struct GNUNET_CADET_ClientChannelNumber id;
/**
* Payload follows
/**
* ID of the channel allowed to send more data.
*/
- CADET_ChannelNumber channel_id GNUNET_PACKED;
+ struct GNUNET_CADET_ClientChannelNumber channel_id;
};
/**
* ID of the channel allowed to send more data.
*/
- CADET_ChannelNumber channel_id GNUNET_PACKED;
+ struct GNUNET_CADET_ClientChannelNumber channel_id;
/**
* ID of the owner of the channel (can be local peer).
* (each path ends in destination) */
};
+
/**
* Message to inform the client about one of the tunnels in the service.
*/
*/
uint16_t cstate GNUNET_PACKED;
- /* If TUNNEL (no 'S'): GNUNET_PeerIdentity connection_ids[connections] */
+ /* If TUNNEL (no 'S'): struct GNUNET_CADET_ConnectionTunnelIdentifier connection_ids[connections] */
/* If TUNNEL (no 'S'): uint32_t channel_ids[channels] */
};
const struct GNUNET_HashCode *
GC_h2hc (const struct GNUNET_CADET_Hash *id);
+
/**
* Get a string from a Cadet Hash (256 bits).
* WARNING: Not reentrant (based on GNUNET_h2s).
/*
This file is part of GNUnet.
- Copyright (C) 2011 GNUnet e.V.
+ Copyright (C) 2011, 2017 GNUnet e.V.
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
*/
/**
* @file cadet/cadet_api.c
- * @brief cadet api: client implementation of new cadet service
+ * @brief cadet api: client implementation of cadet service
* @author Bartlomiej Polot
*/
*/
struct GNUNET_CADET_TransmitHandle
{
- /**
- * Double Linked list
- */
+ /**
+ * Double Linked list
+ */
struct GNUNET_CADET_TransmitHandle *next;
- /**
- * Double Linked list
- */
+ /**
+ * Double Linked list
+ */
struct GNUNET_CADET_TransmitHandle *prev;
- /**
- * Channel this message is sent on / for (may be NULL for control messages).
- */
+ /**
+ * Channel this message is sent on / for (may be NULL for control messages).
+ */
struct GNUNET_CADET_Channel *channel;
- /**
- * Request data task.
- */
+ /**
+ * Request data task.
+ */
struct GNUNET_SCHEDULER_Task *request_data_task;
- /**
- * Callback to obtain the message to transmit, or NULL if we
- * got the message in 'data'. Notice that messages built
- * by 'notify' need to be encapsulated with information about
- * the 'target'.
- */
+ /**
+ * Callback to obtain the message to transmit, or NULL if we
+ * got the message in 'data'. Notice that messages built
+ * by 'notify' need to be encapsulated with information about
+ * the 'target'.
+ */
GNUNET_CONNECTION_TransmitReadyNotify notify;
- /**
- * Closure for 'notify'
- */
+ /**
+ * Closure for 'notify'
+ */
void *notify_cls;
- /**
- * Size of the payload.
- */
+ /**
+ * Size of the payload.
+ */
size_t size;
};
-union CadetInfoCB {
+
+union CadetInfoCB
+{
/**
* Channel callback.
*/
struct GNUNET_CADET_Handle
{
- /**
- * Message queue (if available).
- */
+ /**
+ * Message queue (if available).
+ */
struct GNUNET_MQ_Handle *mq;
- /**
- * Set of handlers used for processing incoming messages in the channels
- */
+ /**
+ * Set of handlers used for processing incoming messages in the channels
+ */
const struct GNUNET_CADET_MessageHandler *message_handlers;
/**
*/
struct GNUNET_CONTAINER_MultiHashMap *ports;
- /**
- * Double linked list of the channels this client is connected to, head.
- */
+ /**
+ * Double linked list of the channels this client is connected to, head.
+ */
struct GNUNET_CADET_Channel *channels_head;
- /**
- * Double linked list of the channels this client is connected to, tail.
- */
+ /**
+ * Double linked list of the channels this client is connected to, tail.
+ */
struct GNUNET_CADET_Channel *channels_tail;
- /**
- * Callback for inbound channel disconnection
- */
+ /**
+ * Callback for inbound channel disconnection
+ */
GNUNET_CADET_ChannelEndHandler *cleaner;
- /**
- * Closure for all the handlers given by the client
- */
+ /**
+ * Closure for all the handlers given by the client
+ */
void *cls;
- /**
- * Messages to send to the service, head.
- */
+ /**
+ * Messages to send to the service, head.
+ */
struct GNUNET_CADET_TransmitHandle *th_head;
- /**
- * Messages to send to the service, tail.
- */
+ /**
+ * Messages to send to the service, tail.
+ */
struct GNUNET_CADET_TransmitHandle *th_tail;
- /**
- * chid of the next channel to create (to avoid reusing IDs often)
- */
- CADET_ChannelNumber next_chid;
+ /**
+ * child of the next channel to create (to avoid reusing IDs often)
+ */
+ struct GNUNET_CADET_ClientChannelNumber next_chid;
/**
* Configuration given by the client, in case of reconnection
*/
struct GNUNET_CADET_Peer
{
- /**
- * ID of the peer in short form
- */
+ /**
+ * ID of the peer in short form
+ */
GNUNET_PEER_Id id;
/**
*/
struct GNUNET_CADET_Channel
{
- /**
- * DLL next
- */
+ /**
+ * DLL next
+ */
struct GNUNET_CADET_Channel *next;
- /**
- * DLL prev
- */
+ /**
+ * DLL prev
+ */
struct GNUNET_CADET_Channel *prev;
- /**
- * Handle to the cadet this channel belongs to
- */
+ /**
+ * Handle to the cadet this channel belongs to
+ */
struct GNUNET_CADET_Handle *cadet;
- /**
- * Local ID of the channel
- */
- CADET_ChannelNumber chid;
+ /**
+ * Local ID of the channel
+ */
+ struct GNUNET_CADET_ClientChannelNumber chid;
- /**
- * Channel's port, if any.
- */
+ /**
+ * Channel's port, if any.
+ */
struct GNUNET_CADET_Port *port;
- /**
- * Other end of the channel.
- */
+ /**
+ * Other end of the channel.
+ */
GNUNET_PEER_Id peer;
/**
*/
void *ctx;
- /**
- * Size of packet queued in this channel
- */
+ /**
+ * Size of packet queued in this channel
+ */
unsigned int packet_size;
- /**
- * Channel options: reliability, etc.
- */
+ /**
+ * Channel options: reliability, etc.
+ */
enum GNUNET_CADET_ChannelOption options;
- /**
- * Are we allowed to send to the service?
- */
+ /**
+ * Are we allowed to send to the service?
+ */
int allow_send;
};
+
/**
* Opaque handle to a port.
*/
struct GNUNET_CADET_Port
{
- /**
- * Handle to the CADET session this port belongs to.
- */
+ /**
+ * Handle to the CADET session this port belongs to.
+ */
struct GNUNET_CADET_Handle *cadet;
- /**
- * Port ID.
- */
+ /**
+ * Port ID.
+ */
struct GNUNET_HashCode *hash;
- /**
- * Callback handler for incoming channels on this port.
- */
+ /**
+ * Callback handler for incoming channels on this port.
+ */
GNUNET_CADET_InboundChannelNotificationHandler *handler;
- /**
- * Closure for @a handler.
- */
+ /**
+ * Closure for @a handler.
+ */
void *cls;
};
/**
* Get the channel handler for the channel specified by id from the given handle
+ *
* @param h Cadet handle
* @param chid ID of the wanted channel
* @return handle to the required channel or NULL if not found
*/
static struct GNUNET_CADET_Channel *
-retrieve_channel (struct GNUNET_CADET_Handle *h, CADET_ChannelNumber chid)
+retrieve_channel (struct GNUNET_CADET_Handle *h,
+ struct GNUNET_CADET_ClientChannelNumber chid)
{
struct GNUNET_CADET_Channel *ch;
- ch = h->channels_head;
- while (ch != NULL)
- {
- if (ch->chid == chid)
+ for (ch = h->channels_head; NULL != ch; ch = ch->next)
+ if (ch->chid.channel_of_client == chid.channel_of_client)
return ch;
- ch = ch->next;
- }
return NULL;
}
* @return Handle to the created channel.
*/
static struct GNUNET_CADET_Channel *
-create_channel (struct GNUNET_CADET_Handle *h, CADET_ChannelNumber chid)
+create_channel (struct GNUNET_CADET_Handle *h,
+ struct GNUNET_CADET_ClientChannelNumber chid)
{
struct GNUNET_CADET_Channel *ch;
ch = GNUNET_new (struct GNUNET_CADET_Channel);
- GNUNET_CONTAINER_DLL_insert (h->channels_head, h->channels_tail, ch);
+ GNUNET_CONTAINER_DLL_insert (h->channels_head,
+ h->channels_tail,
+ ch);
ch->cadet = h;
- if (0 == chid)
+ if (0 == chid.channel_of_client)
{
ch->chid = h->next_chid;
- while (NULL != retrieve_channel (h, h->next_chid))
+ while (NULL != retrieve_channel (h,
+ h->next_chid))
{
- h->next_chid++;
- h->next_chid &= ~GNUNET_CADET_LOCAL_CHANNEL_ID_SERV;
- h->next_chid |= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI;
+ h->next_chid.channel_of_client
+ = htonl (1 + ntohl (h->next_chid.channel_of_client));
+ if (0 == ntohl (h->next_chid.channel_of_client))
+ h->next_chid.channel_of_client
+ = htonl (GNUNET_CADET_LOCAL_CHANNEL_ID_CLI);
}
}
else
}
h = ch->cadet;
- GNUNET_CONTAINER_DLL_remove (h->channels_head, h->channels_tail, ch);
+ GNUNET_CONTAINER_DLL_remove (h->channels_head,
+ h->channels_tail,
+ ch);
/* signal channel destruction */
if ( (NULL != h->cleaner) && (0 != ch->peer) && (GNUNET_YES == call_cleaner) )
if (0 != ch->peer)
GNUNET_PEER_change_rc (ch->peer, -1);
GNUNET_free (ch);
- return;
+
}
struct GNUNET_CADET_LocalAck *msg;
struct GNUNET_MQ_Envelope *env;
- env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK);
-
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Sending ACK on channel %X\n", ch->chid);
- msg->channel_id = htonl (ch->chid);
- GNUNET_MQ_send (ch->cadet->mq, env);
+ env = GNUNET_MQ_msg (msg,
+ GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK);
- return;
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Sending ACK on channel %X\n",
+ ch->chid.channel_of_client);
+ msg->channel_id = ch->chid;
+ GNUNET_MQ_send (ch->cadet->mq,
+ env);
}
th->channel->packet_size = 0;
remove_from_queue (th);
- env = GNUNET_MQ_msg_extra (msg, th->size,
+ env = GNUNET_MQ_msg_extra (msg,
+ th->size,
GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA);
- msg->id = htonl (th->channel->chid);
- osize = th->notify (th->notify_cls, th->size, &msg[1]);
+ msg->id = th->channel->chid;
+ osize = th->notify (th->notify_cls,
+ th->size,
+ &msg[1]);
GNUNET_assert (osize == th->size);
- GNUNET_MQ_send (th->channel->cadet->mq, env);
-
+ GNUNET_MQ_send (th->channel->cadet->mq,
+ env);
GNUNET_free (th);
}
struct GNUNET_CADET_Channel *ch;
struct GNUNET_CADET_Port *port;
const struct GNUNET_HashCode *port_number;
- CADET_ChannelNumber chid;
+ struct GNUNET_CADET_ClientChannelNumber chid;
- chid = ntohl (msg->channel_id);
+ chid = msg->channel_id;
port_number = &msg->port;
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Creating incoming channel %X [%s]\n",
- chid, GNUNET_h2s (port_number));
- if (chid < GNUNET_CADET_LOCAL_CHANNEL_ID_SERV)
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Creating incoming channel %X [%s]\n",
+ ntohl (chid.channel_of_client),
+ GNUNET_h2s (port_number));
+ if (ntohl (chid.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
{
GNUNET_break (0);
return;
{
struct GNUNET_CADET_Handle *h = cls;
struct GNUNET_CADET_Channel *ch;
- CADET_ChannelNumber chid;
+ struct GNUNET_CADET_ClientChannelNumber chid;
- chid = ntohl (msg->channel_id);
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Channel %X Destroy from service\n", chid);
- ch = retrieve_channel (h, chid);
+ chid = msg->channel_id;
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Channel %X Destroy from service\n",
+ ntohl (chid.channel_of_client));
+ ch = retrieve_channel (h,
+ chid);
if (NULL == ch)
{
- LOG (GNUNET_ERROR_TYPE_DEBUG, "channel %X unknown\n", chid);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "channel %X unknown\n",
+ ntohl (chid.channel_of_client));
return;
}
- destroy_channel (ch, GNUNET_YES);
+ destroy_channel (ch,
+ GNUNET_YES);
}
return GNUNET_SYSERR;
}
- ch = retrieve_channel (h, ntohl (message->id));
+ ch = retrieve_channel (h,
+ message->id);
if (NULL == ch)
{
GNUNET_break_op (0);
unsigned int i;
uint16_t type;
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Got a data message!\n");
- ch = retrieve_channel (h, ntohl (message->id));
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Got a data message!\n");
+ ch = retrieve_channel (h, message->id);
GNUNET_assert (NULL != ch);
payload = (struct GNUNET_MessageHeader *) &message[1];
LOG (GNUNET_ERROR_TYPE_DEBUG, " %s data on channel %s [%X]\n",
- GC_f2s (ch->chid >= GNUNET_CADET_LOCAL_CHANNEL_ID_SERV),
- GNUNET_i2s (GNUNET_PEER_resolve2 (ch->peer)), ntohl (message->id));
+ GC_f2s (ntohl (ch->chid.channel_of_client) >=
+ GNUNET_CADET_LOCAL_CHANNEL_ID_CLI),
+ GNUNET_i2s (GNUNET_PEER_resolve2 (ch->peer)),
+ ntohl (message->id.channel_of_client));
type = ntohs (payload->type);
LOG (GNUNET_ERROR_TYPE_DEBUG, " payload type %s\n", GC_m2s (type));
{
struct GNUNET_CADET_Handle *h = cls;
struct GNUNET_CADET_Channel *ch;
- CADET_ChannelNumber chid;
+ struct GNUNET_CADET_ClientChannelNumber chid;
LOG (GNUNET_ERROR_TYPE_DEBUG, "Got an ACK!\n");
- chid = ntohl (message->channel_id);
+ chid = message->channel_id;
ch = retrieve_channel (h, chid);
if (NULL == ch)
{
- LOG (GNUNET_ERROR_TYPE_DEBUG, "ACK on unknown channel %X\n", chid);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "ACK on unknown channel %X\n",
+ ntohl (chid.channel_of_client));
return;
}
- LOG (GNUNET_ERROR_TYPE_DEBUG, " on channel %X!\n", ch->chid);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ " on channel %X!\n",
+ ntohl (ch->chid.channel_of_client));
ch->allow_send = GNUNET_YES;
if (0 < ch->packet_size)
{
{
struct GNUNET_CADET_Handle *h = cls;
- h->info_cb.tunnels_cb (h->info_cls, &msg->destination,
- ntohl (msg->channels), ntohl (msg->connections),
- ntohs (msg->estate), ntohs (msg->cstate));
+ h->info_cb.tunnels_cb (h->info_cls,
+ &msg->destination,
+ ntohl (msg->channels),
+ ntohl (msg->connections),
+ ntohs (msg->estate),
+ ntohs (msg->cstate));
}
if (esize > msize)
{
GNUNET_break_op (0);
- h->info_cb.tunnel_cb (h->info_cls, NULL, 0, 0, NULL, NULL, 0, 0);
+ h->info_cb.tunnel_cb (h->info_cls,
+ NULL, 0, 0, NULL, NULL, 0, 0);
goto clean_cls;
}
ch_n = ntohl (msg->channels);
c_n = ntohl (msg->connections);
- esize += ch_n * sizeof (CADET_ChannelNumber);
- esize += c_n * sizeof (struct GNUNET_CADET_Hash);
+ esize += ch_n * sizeof (struct GNUNET_CADET_ChannelNumber);
+ esize += c_n * sizeof (struct GNUNET_CADET_ConnectionTunnelIdentifier);
if (msize != esize)
{
GNUNET_break_op (0);
(unsigned int) esize,
ch_n,
c_n);
- h->info_cb.tunnel_cb (h->info_cls, NULL, 0, 0, NULL, NULL, 0, 0);
+ h->info_cb.tunnel_cb (h->info_cls,
+ NULL, 0, 0, NULL, NULL, 0, 0);
goto clean_cls;
}
struct GNUNET_CADET_Handle *h = cls;
unsigned int ch_n;
unsigned int c_n;
- struct GNUNET_CADET_Hash *conns;
- CADET_ChannelNumber *chns;
+ const struct GNUNET_CADET_ConnectionTunnelIdentifier *conns;
+ const struct GNUNET_CADET_ChannelNumber *chns;
ch_n = ntohl (msg->channels);
c_n = ntohl (msg->connections);
/* Call Callback with tunnel info. */
- conns = (struct GNUNET_CADET_Hash *) &msg[1];
- chns = (CADET_ChannelNumber *) &conns[c_n];
- h->info_cb.tunnel_cb (h->info_cls, &msg->destination,
- ch_n, c_n, chns, conns,
- ntohs (msg->estate), ntohs (msg->cstate));
+ conns = (const struct GNUNET_CADET_ConnectionTunnelIdentifier *) &msg[1];
+ chns = (const struct GNUNET_CADET_ChannelNumber *) &conns[c_n];
+ h->info_cb.tunnel_cb (h->info_cls,
+ &msg->destination,
+ ch_n,
+ c_n,
+ chns,
+ conns,
+ ntohs (msg->estate),
+ ntohs (msg->cstate));
}
/******************************************************************************/
struct GNUNET_CADET_Handle *
-GNUNET_CADET_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, void *cls,
- GNUNET_CADET_ChannelEndHandler cleaner,
- const struct GNUNET_CADET_MessageHandler *handlers)
+GNUNET_CADET_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ void *cls,
+ GNUNET_CADET_ChannelEndHandler cleaner,
+ const struct GNUNET_CADET_MessageHandler *handlers)
{
struct GNUNET_CADET_Handle *h;
}
h->cls = cls;
h->message_handlers = handlers;
- h->next_chid = GNUNET_CADET_LOCAL_CHANNEL_ID_CLI;
+ h->next_chid.channel_of_client = htonl (GNUNET_CADET_LOCAL_CHANNEL_ID_CLI);
h->reconnect_time = GNUNET_TIME_UNIT_MILLISECONDS;
h->reconnect_task = NULL;
struct GNUNET_CADET_Channel *aux;
struct GNUNET_CADET_TransmitHandle *th;
- LOG (GNUNET_ERROR_TYPE_DEBUG, "CADET DISCONNECT\n");
-
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "CADET DISCONNECT\n");
ch = handle->channels_head;
while (NULL != ch)
{
aux = ch->next;
- if (ch->chid < GNUNET_CADET_LOCAL_CHANNEL_ID_SERV)
+ if (ntohl (ch->chid.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
{
GNUNET_break (0);
- LOG (GNUNET_ERROR_TYPE_DEBUG, "channel %X not destroyed\n", ch->chid);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "channel %X not destroyed\n",
+ ntohl (ch->chid.channel_of_client));
}
- destroy_channel (ch, GNUNET_YES);
+ destroy_channel (ch,
+ GNUNET_YES);
ch = aux;
}
- while ( (th = handle->th_head) != NULL)
+ while (NULL != (th = handle->th_head))
{
struct GNUNET_MessageHeader *msg;
struct GNUNET_CADET_ChannelCreateMessage *msg;
struct GNUNET_MQ_Envelope *env;
struct GNUNET_CADET_Channel *ch;
+ struct GNUNET_CADET_ClientChannelNumber chid;
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Creating new channel to %s:%u\n",
GNUNET_i2s (peer), port);
- ch = create_channel (h, 0);
+ chid.channel_of_client = htonl (0);
+ ch = create_channel (h, chid);
LOG (GNUNET_ERROR_TYPE_DEBUG, " at %p\n", ch);
- LOG (GNUNET_ERROR_TYPE_DEBUG, " number %X\n", ch->chid);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " number %X\n",
+ ntohl (ch->chid.channel_of_client));
ch->ctx = channel_ctx;
ch->peer = GNUNET_PEER_intern (peer);
env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_CHANNEL_CREATE);
- msg->channel_id = htonl (ch->chid);
+ msg->channel_id = ch->chid;
msg->port = *port;
msg->peer = *peer;
msg->opt = htonl (options);
ch->allow_send = GNUNET_NO;
- GNUNET_MQ_send (h->mq, env);
-
+ GNUNET_MQ_send (h->mq,
+ env);
return ch;
}
}
env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY);
- msg->channel_id = htonl (channel->chid);
+ msg->channel_id = channel->chid;
GNUNET_MQ_send (h->mq, env);
destroy_channel (channel, GNUNET_YES);
{
case GNUNET_CADET_OPTION_NOBUFFER:
case GNUNET_CADET_OPTION_RELIABLE:
- case GNUNET_CADET_OPTION_OOORDER:
+ case GNUNET_CADET_OPTION_OUT_OF_ORDER:
if (0 != (option & channel->options))
bool_flag = GNUNET_YES;
else
LOG (GNUNET_ERROR_TYPE_DEBUG, "CADET NOTIFY TRANSMIT READY\n");
LOG (GNUNET_ERROR_TYPE_DEBUG, " on channel %X\n", channel->chid);
LOG (GNUNET_ERROR_TYPE_DEBUG, " allow_send %d\n", channel->allow_send);
- if (channel->chid >= GNUNET_CADET_LOCAL_CHANNEL_ID_SERV)
+ if (ntohl (channel->chid.channel_of_client) >=
+ GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
LOG (GNUNET_ERROR_TYPE_DEBUG, " to origin\n");
else
LOG (GNUNET_ERROR_TYPE_DEBUG, " to destination\n");
env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNEL);
msg->peer = *initiator;
- msg->channel_id = htonl (channel_number);
+ msg->channel_id.channel_of_client = htonl (channel_number);
GNUNET_MQ_send (h->mq, env);
h->info_cb.channel_cb = callback;
* For alignment.
*/
uint32_t reserved GNUNET_PACKED;
-
+
/**
* ID of the connection
*/
/******************************* CHANNEL ***********************************/
/******************************************************************************/
+
/**
* Message to create a Channel.
*/
/**
* ID of the channel
*/
- CADET_ChannelNumber chid GNUNET_PACKED;
+ struct GNUNET_CADET_ChannelNumber chid;
};
/**
* ID of the channel
*/
- CADET_ChannelNumber chid GNUNET_PACKED;
+ struct GNUNET_CADET_ChannelNumber chid;
};
/**
* ID of the channel
*/
- CADET_ChannelNumber chid GNUNET_PACKED;
+ struct GNUNET_CADET_ChannelNumber chid;
/**
* Payload follows
/**
* ID of the channel
*/
- CADET_ChannelNumber chid GNUNET_PACKED;
+ struct GNUNET_CADET_ChannelNumber chid;
/**
* Bitfield of already-received newer messages
const struct GNUNET_PeerIdentity *peer,
unsigned int n_channels,
unsigned int n_connections,
- uint32_t *channels,
- struct GNUNET_CADET_Hash *connections,
+ const struct GNUNET_CADET_ChannelNumber *channels,
+ const struct GNUNET_CADET_ConnectionTunnelIdentifier *connections,
unsigned int estate,
unsigned int cstate)
{
FPRINTF (stdout, "Tunnel %s\n", GNUNET_i2s_full (peer));
FPRINTF (stdout, "\t%u channels\n", n_channels);
for (i = 0; i < n_channels; i++)
- FPRINTF (stdout, "\t\t%X\n", ntohl (channels[i]));
+ FPRINTF (stdout, "\t\t%X\n", ntohl (channels[i].cn));
FPRINTF (stdout, "\t%u connections\n", n_connections);
for (i = 0; i < n_connections; i++)
- FPRINTF (stdout, "\t\t%s\n", GC_h2s (&connections[i]));
+ FPRINTF (stdout, "\t\t%s\n", GC_h2s (&connections[i].connection_of_tunnel));
FPRINTF (stdout, "\tencryption state: %s\n", enc_2s (estate));
FPRINTF (stdout, "\tconnection state: %s\n", conn_2s (cstate));
}
GNUNET_SCHEDULER_shutdown ();
return;
}
- GNUNET_CADET_get_tunnel (mh, &pid, tunnel_callback, NULL);
+ GNUNET_CADET_get_tunnel (mh,
+ &pid,
+ &tunnel_callback,
+ NULL);
}
/**
* Connection confirmed, ready to carry traffic.
*/
- CADET_CHANNEL_READY,
+ CADET_CHANNEL_READY
};
/**
* Global channel number ( < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
*/
- CADET_ChannelNumber gid;
+ struct GNUNET_CADET_ChannelNumber gid;
/**
* Local tunnel number for root (owner) client.
* ( >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI or 0 )
*/
- CADET_ChannelNumber lid_root;
-
+ struct GNUNET_CADET_ClientChannelNumber lid_root;
+
/**
* Local tunnel number for local destination clients (incoming number)
* ( >= GNUNET_CADET_LOCAL_CHANNEL_ID_SERV or 0).
*/
- CADET_ChannelNumber lid_dest;
+ struct GNUNET_CADET_ClientChannelNumber lid_dest;
/**
* Channel state.
msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY);
msg.header.size = htons (sizeof (msg));
- msg.chid = htonl (ch->gid);
+ msg.chid = ch->gid;
/* If root is not NULL, notify.
* If it's NULL, check lid_root. When a local destroy comes in, root
*/
if (NULL != ch->root)
GML_send_channel_destroy (ch->root, ch->lid_root);
- else if (0 == ch->lid_root && GNUNET_NO == local_only)
+ else if (0 == ch->lid_root.channel_of_client && GNUNET_NO == local_only)
GCCH_send_prebuilt_message (&msg.header, ch, GNUNET_NO, NULL);
if (NULL != ch->dest)
GML_send_channel_destroy (ch->dest, ch->lid_dest);
- else if (0 == ch->lid_dest && GNUNET_NO == local_only)
+ else if (0 == ch->lid_dest.channel_of_client && GNUNET_NO == local_only)
GCCH_send_prebuilt_message (&msg.header, ch, GNUNET_YES, NULL);
}
opt = 0;
opt |= GNUNET_YES == ch->reliable ? GNUNET_CADET_OPTION_RELIABLE : 0;
opt |= GNUNET_YES == ch->nobuffer ? GNUNET_CADET_OPTION_NOBUFFER : 0;
- GML_send_channel_create (ch->dest, ch->lid_dest, &ch->port, opt,
+ GML_send_channel_create (ch->dest,
+ ch->lid_dest,
+ &ch->port,
+ opt,
GCT_get_destination (ch->t));
}
msgcc.header.size = htons (sizeof (msgcc));
msgcc.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_CREATE);
- msgcc.chid = htonl (ch->gid);
+ msgcc.chid = ch->gid;
msgcc.port = ch->port;
msgcc.opt = htonl (channel_get_options (ch));
msg.header.size = htons (sizeof (msg));
msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_ACK);
- LOG (GNUNET_ERROR_TYPE_DEBUG, " sending channel %s ack for channel %s\n",
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ " sending channel %s ack for channel %s\n",
GC_f2s (fwd), GCCH_2s (ch));
- msg.chid = htonl (ch->gid);
+ msg.chid =ch->gid;
GCCH_send_prebuilt_message (&msg.header, ch, !fwd, NULL);
}
struct CadetChannel *ch,
int force)
{
- GNUNET_break (NULL == GCT_send_prebuilt_message (msg, ch->t, NULL,
- force, NULL, NULL));
+ GNUNET_break (NULL ==
+ GCT_send_prebuilt_message (msg, ch->t, NULL,
+ force, NULL, NULL));
}
" sending channel NACK for channel %s\n",
GCCH_2s (ch));
- msg.chid = htonl (ch->gid);
+ msg.chid = ch->gid;
GCCH_send_prebuilt_message (&msg.header, ch, GNUNET_NO, NULL);
}
static struct CadetChannel *
channel_new (struct CadetTunnel *t,
struct CadetClient *owner,
- CADET_ChannelNumber lid_root)
+ struct GNUNET_CADET_ClientChannelNumber lid_root)
{
struct CadetChannel *ch;
*
* @return ID used to identify the channel with the remote peer.
*/
-CADET_ChannelNumber
+struct GNUNET_CADET_ChannelNumber
GCCH_get_id (const struct CadetChannel *ch)
{
return ch->gid;
msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_DATA_ACK);
msg.header.size = htons (sizeof (msg));
- msg.chid = htonl (ch->gid);
+ msg.chid = ch->gid;
msg.mid = htonl (ack);
msg.futures = 0LL;
{
LOG2 (level, "CHN cli %s\n", GML_2s (ch->root));
LOG2 (level, "CHN ready %s\n", ch->root_rel->client_ready ? "YES" : "NO");
- LOG2 (level, "CHN id %X\n", ch->lid_root);
+ LOG2 (level, "CHN id %X\n", ch->lid_root.channel_of_client);
LOG2 (level, "CHN recv %d\n", ch->root_rel->n_recv);
LOG2 (level, "CHN MID r: %d, s: %d\n",
ch->root_rel->mid_recv, ch->root_rel->mid_send);
* @param message Data message.
* @param size Size of data.
*
- * @return GNUNET_OK if everything goes well, GNUNET_SYSERR in case of en error.
+ * @return #GNUNET_OK if everything goes well, #GNUNET_SYSERR in case of en error.
*/
int
GCCH_handle_local_data (struct CadetChannel *ch,
- struct CadetClient *c, int fwd,
+ struct CadetClient *c,
+ int fwd,
const struct GNUNET_MessageHeader *message,
size_t size)
{
GNUNET_memcpy (&payload[1], message, size);
payload->header.size = htons (p2p_size);
payload->header.type = htons (GNUNET_MESSAGE_TYPE_CADET_DATA);
- payload->chid = htonl (ch->gid);
+ payload->chid = ch->gid;
LOG (GNUNET_ERROR_TYPE_DEBUG, " sending on channel...\n");
GCCH_send_prebuilt_message (&payload->header, ch, fwd, NULL);
struct CadetChannel *ch;
struct CadetTunnel *t;
struct CadetPeer *peer;
- CADET_ChannelNumber chid;
+ struct GNUNET_CADET_ClientChannelNumber chid;
LOG (GNUNET_ERROR_TYPE_DEBUG, " towards %s:%u\n",
GNUNET_i2s (&msg->peer), GNUNET_h2s (&msg->port));
- chid = ntohl (msg->channel_id);
+ chid = msg->channel_id;
/* Sanity check for duplicate channel IDs */
if (NULL != GML_channel_get (c, chid))
GCCH_handle_create (struct CadetTunnel *t,
const struct GNUNET_CADET_ChannelCreate *msg)
{
- CADET_ChannelNumber chid;
+ struct GNUNET_CADET_ClientChannelNumber chid;
+ struct GNUNET_CADET_ChannelNumber gid;
struct CadetChannel *ch;
struct CadetClient *c;
int new_channel;
const struct GNUNET_HashCode *port;
- chid = ntohl (msg->chid);
-
- ch = GCT_get_channel (t, chid);
+ gid = msg->chid;
+ ch = GCT_get_channel (t, gid);
if (NULL == ch)
{
/* Create channel */
- ch = channel_new (t, NULL, 0);
- ch->gid = chid;
+ chid.channel_of_client = htonl (0);
+ ch = channel_new (t, NULL, chid);
+ ch->gid = gid;
channel_set_options (ch, ntohl (msg->opt));
new_channel = GNUNET_YES;
}
{
struct GNUNET_CADET_ChannelCreate *cc_msg;
cc_msg = (struct GNUNET_CADET_ChannelCreate *) message;
- SPRINTF (info, " 0x%08X", ntohl (cc_msg->chid));
+ SPRINTF (info, " 0x%08X", ntohl (cc_msg->chid.cn));
break;
}
case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_ACK:
{
struct GNUNET_CADET_ChannelManage *m_msg;
m_msg = (struct GNUNET_CADET_ChannelManage *) message;
- SPRINTF (info, " 0x%08X", ntohl (m_msg->chid));
+ SPRINTF (info, " 0x%08X", ntohl (m_msg->chid.cn));
break;
}
default:
if (NULL == ch)
return "(NULL Channel)";
- SPRINTF (buf, "%s:%s gid:%X (%X / %X)",
- GCT_2s (ch->t), GNUNET_h2s (&ch->port),
- ch->gid, ch->lid_root, ch->lid_dest);
+ SPRINTF (buf,
+ "%s:%s gid:%X (%X / %X)",
+ GCT_2s (ch->t),
+ GNUNET_h2s (&ch->port),
+ ntohl (ch->gid.cn),
+ ntohl (ch->lid_root.channel_of_client),
+ ntohl (ch->lid_dest.channel_of_client));
return buf;
}
*
* @return ID used to identify the channel with the remote peer.
*/
-CADET_ChannelNumber
+struct GNUNET_CADET_ChannelNumber
GCCH_get_id (const struct CadetChannel *ch);
/**
GCCH_2s (const struct CadetChannel *ch);
+
+
#if 0 /* keep Emacsens' auto-indent happy */
{
#endif
if (GNUNET_MESSAGE_TYPE_CADET_ENCRYPTED == type)
{
fc = fwd ? &c->bck_fc : &c->fwd_fc;
- LOG (GNUNET_ERROR_TYPE_DEBUG, " PID %u (expected %u - %u)\n",
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " PID %u (expected in interval [%u,%u])\n",
pid,
fc->last_pid_recv + 1,
fc->last_ack_sent);
*/
struct GCD_search_handle
{
- /** DHT_GET handle. */
+ /**
+ * DHT_GET handle.
+ */
struct GNUNET_DHT_GetHandle *dhtget;
- /** Provided callback to call when a path is found. */
+ /**
+ * Provided callback to call when a path is found.
+ */
GCD_search_callback callback;
- /** Provided closure. */
+ /**
+ * Provided closure.
+ */
void *cls;
- /** Peer ID searched for */
+ /**
+ * Peer ID searched for
+ */
GNUNET_PEER_Id peer_id;
};
void
GCH_init (const struct GNUNET_CONFIGURATION_Handle *c);
+
/**
* Shut down the hello subsystem.
*/
void
-GCH_shutdown ();
+GCH_shutdown (void);
+
/**
* Get own hello message.
const struct GNUNET_HELLO_Message *
GCH_get_mine (void);
+
#if 0 /* keep Emacsens' auto-indent happy */
{
#endif
* Tunnels that belong to this client, indexed by local id
*/
struct GNUNET_CONTAINER_MultiHashMap32 *own_channels;
-
+
/**
* Tunnels this client has accepted, indexed by incoming local id
*/
/**
* Channel ID for the next incoming channel.
*/
- CADET_ChannelNumber next_chid;
+ struct GNUNET_CADET_ClientChannelNumber next_chid;
/**
* Handle to communicate with the client
" Channel %s destroy, due to client %s shutdown.\n",
GCCH_2s (ch), GML_2s (c));
- GCCH_handle_local_destroy (ch, c, key < GNUNET_CADET_LOCAL_CHANNEL_ID_SERV);
+ GCCH_handle_local_destroy (ch,
+ c,
+ key < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI);
return GNUNET_OK;
}
c = GNUNET_new (struct CadetClient);
c->handle = client;
c->id = next_client_id++; /* overflow not important: just for debug */
- c->next_chid = GNUNET_CADET_LOCAL_CHANNEL_ID_SERV;
c->own_channels = GNUNET_CONTAINER_multihashmap32_create (32);
c->incoming_channels = GNUNET_CONTAINER_multihashmap32_create (32);
struct GNUNET_CADET_ChannelDestroyMessage *msg;
struct CadetClient *c;
struct CadetChannel *ch;
- CADET_ChannelNumber chid;
+ struct GNUNET_CADET_ClientChannelNumber chid;
LOG (GNUNET_ERROR_TYPE_DEBUG, "Got a DESTROY CHANNEL from client!\n");
msg = (struct GNUNET_CADET_ChannelDestroyMessage *) message;
/* Retrieve tunnel */
- chid = ntohl (msg->channel_id);
+ chid = msg->channel_id;
ch = GML_channel_get (c, chid);
LOG (GNUNET_ERROR_TYPE_INFO, "Client %u is destroying channel %X\n",
return;
}
- GCCH_handle_local_destroy (ch, c, chid < GNUNET_CADET_LOCAL_CHANNEL_ID_SERV);
+ GCCH_handle_local_destroy (ch,
+ c,
+ ntohl (chid.channel_of_client) < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
return;
struct GNUNET_CADET_LocalData *msg;
struct CadetClient *c;
struct CadetChannel *ch;
- CADET_ChannelNumber chid;
+ struct GNUNET_CADET_ClientChannelNumber chid;
size_t message_size;
size_t payload_size;
size_t payload_claimed_size;
return;
}
- chid = ntohl (msg->id);
+ chid = msg->id;
LOG (GNUNET_ERROR_TYPE_DEBUG, " %u bytes (%u payload) by client %u\n",
payload_size, payload_claimed_size, c->id);
/* Channel exists? */
- fwd = chid < GNUNET_CADET_LOCAL_CHANNEL_ID_SERV;
+ fwd = ntohl (chid.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI;
ch = GML_channel_get (c, chid);
if (NULL == ch)
{
struct GNUNET_CADET_LocalAck *msg;
struct CadetChannel *ch;
struct CadetClient *c;
- CADET_ChannelNumber chid;
+ struct GNUNET_CADET_ClientChannelNumber chid;
int fwd;
LOG (GNUNET_ERROR_TYPE_DEBUG, "\n");
msg = (struct GNUNET_CADET_LocalAck *) message;
/* Channel exists? */
- chid = ntohl (msg->channel_id);
- LOG (GNUNET_ERROR_TYPE_DEBUG, " on channel %X\n", chid);
+ chid = msg->channel_id;
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " on channel %X\n",
+ ntohl (chid.channel_of_client));
ch = GML_channel_get (c, chid);
LOG (GNUNET_ERROR_TYPE_DEBUG, " -- ch %p\n", ch);
if (NULL == ch)
{
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Channel %X unknown.\n", chid);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Channel %X unknown.\n",
+ ntohl (chid.channel_of_client));
LOG (GNUNET_ERROR_TYPE_DEBUG, " for client %u.\n", c->id);
GNUNET_STATISTICS_update (stats,
"# client ack messages on unknown channel",
/* If client is root, the ACK is going FWD, therefore this is "BCK ACK". */
/* If client is dest, the ACK is going BCK, therefore this is "FWD ACK" */
- fwd = chid >= GNUNET_CADET_LOCAL_CHANNEL_ID_SERV;
+ fwd = ntohl (chid.channel_of_client) < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI;
GCCH_handle_local_ack (ch, fwd);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
-
- return;
}
{
struct GNUNET_CADET_LocalInfoTunnel *msg = cls;
struct GNUNET_CADET_Hash *h = (struct GNUNET_CADET_Hash *) &msg[1];
- CADET_ChannelNumber *chn = (CADET_ChannelNumber *) &h[msg->connections];
+ struct GNUNET_CADET_ChannelNumber *chn = (struct GNUNET_CADET_ChannelNumber *) &h[msg->connections];
- chn[msg->channels] = htonl (GCCH_get_id (ch));
+ chn[msg->channels] = GCCH_get_id (ch);
msg->channels++;
}
size = sizeof (struct GNUNET_CADET_LocalInfoTunnel);
size += c_n * sizeof (struct GNUNET_CADET_Hash);
- size += ch_n * sizeof (CADET_ChannelNumber);
+ size += ch_n * sizeof (struct GNUNET_CADET_ChannelNumber);
resp = GNUNET_malloc (size);
resp->header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL);
* @return non-NULL if channel exists in the clients lists
*/
struct CadetChannel *
-GML_channel_get (struct CadetClient *c, CADET_ChannelNumber chid)
+GML_channel_get (struct CadetClient *c,
+ struct GNUNET_CADET_ClientChannelNumber chid)
{
struct GNUNET_CONTAINER_MultiHashMap32 *map;
- if (0 == (chid & GNUNET_CADET_LOCAL_CHANNEL_ID_CLI))
- {
- GNUNET_break_op (0);
- LOG (GNUNET_ERROR_TYPE_DEBUG, "CHID %X not a local chid\n", chid);
- return NULL;
- }
-
- if (chid >= GNUNET_CADET_LOCAL_CHANNEL_ID_SERV)
- map = c->incoming_channels;
- else if (chid >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
+ if (ntohl (chid.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
map = c->own_channels;
else
- {
- GNUNET_break (0);
- map = NULL;
- }
+ map = c->incoming_channels;
+
if (NULL == map)
{
GNUNET_break (0);
GML_2s (c), chid);
return NULL;
}
- return GNUNET_CONTAINER_multihashmap32_get (map, chid);
+ return GNUNET_CONTAINER_multihashmap32_get (map,
+ chid.channel_of_client);
}
*/
void
GML_channel_add (struct CadetClient *client,
- uint32_t chid,
+ struct GNUNET_CADET_ClientChannelNumber chid,
struct CadetChannel *ch)
{
- if (chid >= GNUNET_CADET_LOCAL_CHANNEL_ID_SERV)
- GNUNET_CONTAINER_multihashmap32_put (client->incoming_channels, chid, ch,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
- else if (chid >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
- GNUNET_CONTAINER_multihashmap32_put (client->own_channels, chid, ch,
+ if (ntohl (chid.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
+ GNUNET_CONTAINER_multihashmap32_put (client->own_channels,
+ chid.channel_of_client,
+ ch,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
else
- GNUNET_break (0);
+ GNUNET_CONTAINER_multihashmap32_put (client->incoming_channels,
+ chid.channel_of_client,
+ ch,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
}
*/
void
GML_channel_remove (struct CadetClient *client,
- uint32_t chid,
+ struct GNUNET_CADET_ClientChannelNumber chid,
struct CadetChannel *ch)
{
- if (GNUNET_CADET_LOCAL_CHANNEL_ID_SERV <= chid)
- GNUNET_break (GNUNET_YES ==
- GNUNET_CONTAINER_multihashmap32_remove (client->incoming_channels,
- chid, ch));
- else if (GNUNET_CADET_LOCAL_CHANNEL_ID_CLI <= chid)
- GNUNET_break (GNUNET_YES ==
- GNUNET_CONTAINER_multihashmap32_remove (client->own_channels,
- chid, ch));
+ if (ntohl (chid.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
+ GNUNET_CONTAINER_multihashmap32_remove (client->own_channels,
+ chid.channel_of_client,
+ ch);
else
- GNUNET_break (0);
+ GNUNET_CONTAINER_multihashmap32_remove (client->incoming_channels,
+ chid.channel_of_client,
+ ch);
}
*
* @return LID of a channel free to use.
*/
-CADET_ChannelNumber
+struct GNUNET_CADET_ClientChannelNumber
GML_get_next_chid (struct CadetClient *c)
{
- CADET_ChannelNumber chid;
+ struct GNUNET_CADET_ClientChannelNumber chid;
- while (NULL != GML_channel_get (c, c->next_chid))
+ while (NULL != GML_channel_get (c,
+ c->next_chid))
{
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Channel %u exists...\n", c->next_chid);
- c->next_chid = (c->next_chid + 1) | GNUNET_CADET_LOCAL_CHANNEL_ID_SERV;
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Channel %u exists...\n",
+ c->next_chid);
+ c->next_chid.channel_of_client
+ = htonl (1 + (ntohl (c->next_chid.channel_of_client)));
+ if (ntohl (c->next_chid.channel_of_client) >=
+ GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
+ c->next_chid.channel_of_client = htonl (0);
}
chid = c->next_chid;
- c->next_chid = (c->next_chid + 1) | GNUNET_CADET_LOCAL_CHANNEL_ID_SERV;
+ c->next_chid.channel_of_client
+ = htonl (1 + (ntohl (c->next_chid.channel_of_client)));
return chid;
}
{
if (NULL == client)
return NULL;
- return GNUNET_SERVER_client_get_user_context (client, struct CadetClient);
+ return GNUNET_SERVER_client_get_user_context (client,
+ struct CadetClient);
}
+
/**
* Find a client that has opened a port
*
void
GML_client_delete_channel (struct CadetClient *c,
struct CadetChannel *ch,
- CADET_ChannelNumber id)
+ struct GNUNET_CADET_ClientChannelNumber id)
{
int res;
- if (GNUNET_CADET_LOCAL_CHANNEL_ID_SERV <= id)
- {
- res = GNUNET_CONTAINER_multihashmap32_remove (c->incoming_channels,
- id, ch);
- if (GNUNET_YES != res)
- LOG (GNUNET_ERROR_TYPE_DEBUG, "client_delete_channel dest KO\n");
- }
- else if (GNUNET_CADET_LOCAL_CHANNEL_ID_CLI <= id)
+ if (ntohl (id.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
{
res = GNUNET_CONTAINER_multihashmap32_remove (c->own_channels,
- id, ch);
+ id.channel_of_client,
+ ch);
if (GNUNET_YES != res)
LOG (GNUNET_ERROR_TYPE_DEBUG, "client_delete_tunnel root KO\n");
}
else
{
- GNUNET_break (0);
+ res = GNUNET_CONTAINER_multihashmap32_remove (c->incoming_channels,
+ id.channel_of_client,
+ ch);
+ if (GNUNET_YES != res)
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "client_delete_channel dest KO\n");
}
}
* @param id Channel ID to use
*/
void
-GML_send_ack (struct CadetClient *c, CADET_ChannelNumber id)
+GML_send_ack (struct CadetClient *c,
+ struct GNUNET_CADET_ClientChannelNumber id)
{
struct GNUNET_CADET_LocalAck msg;
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "send local %s ack on %X towards %p\n",
- id < GNUNET_CADET_LOCAL_CHANNEL_ID_SERV ? "FWD" : "BCK", id, c);
+ "send local %s ack on %X towards %p\n",
+ ntohl (id.channel_of_client) < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI
+ ? "FWD" : "BCK",
+ ntohl (id.channel_of_client),
+ c);
msg.header.size = htons (sizeof (msg));
msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK);
- msg.channel_id = htonl (id);
+ msg.channel_id = id;
GNUNET_SERVER_notification_context_unicast (nc,
c->handle,
&msg.header,
*/
void
GML_send_channel_create (struct CadetClient *c,
- uint32_t id, struct GNUNET_HashCode *port,
- uint32_t opt, const struct GNUNET_PeerIdentity *peer)
+ struct GNUNET_CADET_ClientChannelNumber id,
+ const struct GNUNET_HashCode *port,
+ uint32_t opt,
+ const struct GNUNET_PeerIdentity *peer)
{
struct GNUNET_CADET_ChannelCreateMessage msg;
msg.header.size = htons (sizeof (msg));
msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_CREATE);
- msg.channel_id = htonl (id);
+ msg.channel_id = id;
msg.port = *port;
msg.opt = htonl (opt);
msg.peer = *peer;
* @param id Channel ID to use
*/
void
-GML_send_channel_nack (struct CadetClient *c, CADET_ChannelNumber id)
+GML_send_channel_nack (struct CadetClient *c,
+ struct GNUNET_CADET_ClientChannelNumber id)
{
struct GNUNET_CADET_LocalAck msg;
LOG (GNUNET_ERROR_TYPE_DEBUG,
"send local nack on %X towards %p\n",
- id, c);
+ ntohl (id.channel_of_client),
+ c);
msg.header.size = htons (sizeof (msg));
msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_NACK);
- msg.channel_id = htonl (id);
+ msg.channel_id = id;
GNUNET_SERVER_notification_context_unicast (nc,
c->handle,
&msg.header,
* @param id ID of the channel that is destroyed.
*/
void
-GML_send_channel_destroy (struct CadetClient *c, uint32_t id)
+GML_send_channel_destroy (struct CadetClient *c,
+ struct GNUNET_CADET_ClientChannelNumber id)
{
struct GNUNET_CADET_ChannelDestroyMessage msg;
return;
msg.header.size = htons (sizeof (msg));
msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY);
- msg.channel_id = htonl (id);
+ msg.channel_id = id;
GNUNET_SERVER_notification_context_unicast (nc, c->handle,
&msg.header, GNUNET_NO);
}
void
GML_send_data (struct CadetClient *c,
const struct GNUNET_CADET_Data *msg,
- CADET_ChannelNumber id)
+ struct GNUNET_CADET_ClientChannelNumber id)
{
struct GNUNET_CADET_LocalData *copy;
uint16_t size = ntohs (msg->header.size) - sizeof (struct GNUNET_CADET_Data);
GNUNET_memcpy (©[1], &msg[1], size);
copy->header.size = htons (sizeof (struct GNUNET_CADET_LocalData) + size);
copy->header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA);
- copy->id = htonl (id);
+ copy->id = id;
GNUNET_SERVER_notification_context_unicast (nc, c->handle,
©->header, GNUNET_NO);
}
* @return non-NULL if channel exists in the clients lists
*/
struct CadetChannel *
-GML_channel_get (struct CadetClient *c, uint32_t chid);
+GML_channel_get (struct CadetClient *c,
+ struct GNUNET_CADET_ClientChannelNumber chid);
/**
* Add a channel to a client
*/
void
GML_channel_add (struct CadetClient *client,
- uint32_t chid,
+ struct GNUNET_CADET_ClientChannelNumber chid,
struct CadetChannel *ch);
/**
*/
void
GML_channel_remove (struct CadetClient *client,
- uint32_t chid,
+ struct GNUNET_CADET_ClientChannelNumber chid,
struct CadetChannel *ch);
/**
*
* @return LID of a channel free to use.
*/
-CADET_ChannelNumber
+struct GNUNET_CADET_ClientChannelNumber
GML_get_next_chid (struct CadetClient *c);
/**
void
GML_client_delete_channel (struct CadetClient *c,
struct CadetChannel *ch,
- CADET_ChannelNumber id);
+ struct GNUNET_CADET_ClientChannelNumber id);
/**
* Build a local ACK message and send it to a local client, if needed.
* @param id Channel ID to use
*/
void
-GML_send_ack (struct CadetClient *c, CADET_ChannelNumber id);
+GML_send_ack (struct CadetClient *c,
+ struct GNUNET_CADET_ClientChannelNumber id);
/**
* Notify the appropriate client that a new incoming channel was created.
*/
void
GML_send_channel_create (struct CadetClient *c,
- uint32_t id, struct GNUNET_HashCode *port,
- uint32_t opt, const struct GNUNET_PeerIdentity *peer);
+ struct GNUNET_CADET_ClientChannelNumber id,
+ const struct GNUNET_HashCode *port,
+ uint32_t opt,
+ const struct GNUNET_PeerIdentity *peer);
/**
* Build a local channel NACK message and send it to a local client.
* @param id Channel ID to use
*/
void
-GML_send_channel_nack (struct CadetClient *c, CADET_ChannelNumber id);
+GML_send_channel_nack (struct CadetClient *c,
+ struct GNUNET_CADET_ClientChannelNumber id);
+
/**
* Notify a client that a channel is no longer valid.
* @param id ID of the channel that is destroyed.
*/
void
-GML_send_channel_destroy (struct CadetClient *c, uint32_t id);
+GML_send_channel_destroy (struct CadetClient *c,
+ struct GNUNET_CADET_ClientChannelNumber id);
+
/**
* Modify the cadet message ID from global to local and send to client.
void
GML_send_data (struct CadetClient *c,
const struct GNUNET_CADET_Data *msg,
- CADET_ChannelNumber id);
+ struct GNUNET_CADET_ClientChannelNumber id);
/**
* Get the static string to represent a client.
* Task to asynchronously run the drop continuation.
*/
struct GNUNET_SCHEDULER_Task *drop_task;
-
+
/**
* Time when message was queued for sending.
*/
drop_cb (void *cls)
{
struct CadetPeerQueue *q = cls;
-
+
GNUNET_MQ_discard (q->env);
call_peer_cont (q, GNUNET_YES);
GNUNET_free (q);
struct CadetPeer *
GCP_get (const struct GNUNET_PeerIdentity *peer_id, int create);
+
/**
* Retrieve the CadetPeer stucture associated with the peer. Optionally create
* one and insert it in the appropriate structures if the peer is not known yet.
struct CadetPeer *
GCP_get_short (const GNUNET_PEER_Id peer, int create);
+
/**
* Try to establish a new connection to this peer (in its tunnel).
* If the peer doesn't have any path to it yet, try to get one.
* @param cls Closure for @c iter.
*/
void
-GCP_iterate_all (GNUNET_CONTAINER_PeerMapIterator iter, void *cls);
+GCP_iterate_all (GNUNET_CONTAINER_PeerMapIterator iter,
+ void *cls);
/**
/**
- * Connection list and metadata.
+ * Entry in list of connections used by tunnel, with metadata.
*/
struct CadetTConnection
{
struct GNUNET_TIME_Absolute ratchet_expiration;
};
+
/**
* Struct containing all information regarding a tunnel to a peer.
*/
/**
* Channel ID for the next created channel.
*/
- CADET_ChannelNumber next_chid;
+ struct GNUNET_CADET_ChannelNumber next_chid;
/**
* Destroy flag: if true, destroy on last message.
GNUNET_break (0);
LOG (GNUNET_ERROR_TYPE_ERROR, "type %s not valid\n", GC_m2s (type));
}
- LOG (GNUNET_ERROR_TYPE_DEBUG, "type %s\n", GC_m2s (type));
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Sending message of type %s with PID %u and CID %s\n",
+ GC_m2s (type),
+ htonl (ax_msg->pid),
+ GC_h2s (&ax_msg->cid));
if (NULL == cont)
{
* @param gid ID of the channel.
*/
static void
-send_channel_destroy (struct CadetTunnel *t, unsigned int gid)
+send_channel_destroy (struct CadetTunnel *t,
+ struct GNUNET_CADET_ChannelNumber gid)
{
struct GNUNET_CADET_ChannelManage msg;
msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY);
msg.header.size = htons (sizeof (msg));
- msg.chid = htonl (gid);
+ msg.chid = gid;
LOG (GNUNET_ERROR_TYPE_DEBUG,
"WARNING destroying unknown channel %u on tunnel %s\n",
- gid, GCT_2s (t));
+ ntohl (gid.cn),
+ GCT_2s (t));
send_prebuilt_message (&msg.header, t, NULL, GNUNET_YES, NULL, NULL, NULL);
}
/* Check channel */
- ch = GCT_get_channel (t, ntohl (msg->chid));
+ ch = GCT_get_channel (t, msg->chid);
if (NULL == ch)
{
- GNUNET_STATISTICS_update (stats, "# data on unknown channel",
- 1, GNUNET_NO);
- LOG (GNUNET_ERROR_TYPE_DEBUG, "channel 0x%X unknown\n", ntohl (msg->chid));
- send_channel_destroy (t, ntohl (msg->chid));
+ GNUNET_STATISTICS_update (stats,
+ "# data on unknown channel",
+ 1,
+ GNUNET_NO);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "channel 0x%X unknown\n",
+ ntohl (msg->chid.cn));
+ send_channel_destroy (t, msg->chid);
return;
}
}
/* Check channel */
- ch = GCT_get_channel (t, ntohl (msg->chid));
+ ch = GCT_get_channel (t, msg->chid);
if (NULL == ch)
{
GNUNET_STATISTICS_update (stats, "# data ack on unknown channel",
1, GNUNET_NO);
LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel %u unknown\n",
- ntohl (msg->chid));
+ ntohl (msg->chid.cn));
return;
}
}
/* Check channel */
- ch = GCT_get_channel (t, ntohl (msg->chid));
+ ch = GCT_get_channel (t, msg->chid);
if (NULL != ch && ! GCT_is_loopback (t))
{
/* Probably a retransmission, safe to ignore */
}
/* Check channel */
- ch = GCT_get_channel (t, ntohl (msg->chid));
+ ch = GCT_get_channel (t, msg->chid);
if (NULL == ch)
{
GNUNET_STATISTICS_update (stats, "# channel NACK on unknown channel",
1, GNUNET_NO);
- LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel %u unknown\n",
- ntohl (msg->chid));
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "WARNING channel %u unknown\n",
+ ntohl (msg->chid.cn));
return;
}
}
/* Check channel */
- ch = GCT_get_channel (t, ntohl (msg->chid));
+ ch = GCT_get_channel (t, msg->chid);
if (NULL == ch)
{
- GNUNET_STATISTICS_update (stats, "# channel ack on unknown channel",
- 1, GNUNET_NO);
- LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel %u unknown\n",
- ntohl (msg->chid));
+ GNUNET_STATISTICS_update (stats,
+ "# channel ack on unknown channel",
+ 1,
+ GNUNET_NO);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "WARNING channel %u unknown\n",
+ ntohl (msg->chid.cn));
return;
}
}
/* Check channel */
- ch = GCT_get_channel (t, ntohl (msg->chid));
+ ch = GCT_get_channel (t, msg->chid);
if (NULL == ch)
{
/* Probably a retransmission, safe to ignore */
struct CadetTunnel *t;
t = GNUNET_new (struct CadetTunnel);
- t->next_chid = 0;
+ t->next_chid.cn = 0;
t->peer = destination;
if (GNUNET_OK !=
* @param ch Channel.
*/
void
-GCT_add_channel (struct CadetTunnel *t, struct CadetChannel *ch)
+GCT_add_channel (struct CadetTunnel *t,
+ struct CadetChannel *ch)
{
struct CadetTChannel *aux;
* @return channel handler, NULL if doesn't exist
*/
struct CadetChannel *
-GCT_get_channel (struct CadetTunnel *t, CADET_ChannelNumber chid)
+GCT_get_channel (struct CadetTunnel *t,
+ struct GNUNET_CADET_ChannelNumber chid)
{
struct CadetTChannel *iter;
for (iter = t->channel_head; NULL != iter; iter = iter->next)
{
- if (GCCH_get_id (iter->ch) == chid)
+ if (GCCH_get_id (iter->ch).cn == chid.cn)
break;
}
*
* @return GID of a channel free to use.
*/
-CADET_ChannelNumber
+struct GNUNET_CADET_ChannelNumber
GCT_get_next_chid (struct CadetTunnel *t)
{
- CADET_ChannelNumber chid;
- CADET_ChannelNumber mask;
+ struct GNUNET_CADET_ChannelNumber chid;
+ struct GNUNET_CADET_ChannelNumber mask;
int result;
/* Set bit 30 depending on the ID relationship. Bit 31 is always 0 for GID.
*/
result = GNUNET_CRYPTO_cmp_peer_identity (&my_full_id, GCP_get_id (t->peer));
if (0 > result)
- mask = 0x40000000;
+ mask.cn = htonl (0x40000000);
else
- mask = 0x0;
- t->next_chid |= mask;
+ mask.cn = 0x0;
+ t->next_chid.cn |= mask.cn;
while (NULL != GCT_get_channel (t, t->next_chid))
{
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Channel %u exists...\n", t->next_chid);
- t->next_chid = (t->next_chid + 1) & ~GNUNET_CADET_LOCAL_CHANNEL_ID_CLI;
- t->next_chid |= mask;
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Channel %u exists...\n",
+ t->next_chid.cn);
+ t->next_chid.cn = htonl ((ntohl (t->next_chid.cn) + 1) & ~GNUNET_CADET_LOCAL_CHANNEL_ID_CLI);
+ t->next_chid.cn |= mask.cn;
}
chid = t->next_chid;
- t->next_chid = (t->next_chid + 1) & ~GNUNET_CADET_LOCAL_CHANNEL_ID_CLI;
- t->next_chid |= mask;
+ t->next_chid.cn = (t->next_chid.cn + 1) & ~GNUNET_CADET_LOCAL_CHANNEL_ID_CLI;
+ t->next_chid.cn |= mask.cn;
return chid;
}
for (cht = t->channel_head; NULL != cht; cht = cht->next)
iter (cls, cht->ch);
}
-
* @return channel handler, NULL if doesn't exist
*/
struct CadetChannel *
-GCT_get_channel (struct CadetTunnel *t, CADET_ChannelNumber chid);
+GCT_get_channel (struct CadetTunnel *t, struct GNUNET_CADET_ChannelNumber chid);
/**
*
* @return ID of a channel free to use.
*/
-CADET_ChannelNumber
+struct GNUNET_CADET_ChannelNumber
GCT_get_next_chid (struct CadetTunnel *t);
* with the channel is stored
*/
static void
-channel_end (void *cls, const struct GNUNET_CADET_Channel *channel,
+channel_end (void *cls,
+ const struct GNUNET_CADET_Channel *channel,
void *channel_ctx)
{
long id = (long) cls;
GNUNET_CADET_notify_transmit_ready_cancel (mth);
mth = NULL;
}
+ if (channel == ch)
+ ch = NULL;
if (GNUNET_NO == got_data)
{
GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (
/**
* Enable out of order delivery of messages.
- * Yes/No.
+ * Set bit for out-of-order delivery.
*/
- GNUNET_CADET_OPTION_OOORDER = 0x4,
+ GNUNET_CADET_OPTION_OUT_OF_ORDER = 0x4,
/**
* Who is the peer at the other end of the channel.
*/
const union GNUNET_CADET_ChannelInfo *
GNUNET_CADET_channel_get_info (struct GNUNET_CADET_Channel *channel,
- enum GNUNET_CADET_ChannelOption option, ...);
+ enum GNUNET_CADET_ChannelOption option,
+ ...);
/**
uint16_t cstate);
+/**
+ * Hash uniquely identifying a connection below a tunnel.
+ */
+struct GNUNET_CADET_ConnectionTunnelIdentifier
+{
+ struct GNUNET_CADET_Hash connection_of_tunnel;
+};
+
+
+/**
+ * Number identifying a CADET channel.
+ */
+struct GNUNET_CADET_ChannelNumber
+{
+ uint32_t cn GNUNET_PACKED;
+};
+
+
/**
* Method called to retrieve information about a specific tunnel the cadet peer
* has established, o`r is trying to establish.
const struct GNUNET_PeerIdentity *peer,
unsigned int n_channels,
unsigned int n_connections,
- uint32_t *channels,
- struct GNUNET_CADET_Hash *connections,
+ const struct GNUNET_CADET_ChannelNumber *channels,
+ const struct GNUNET_CADET_ConnectionTunnelIdentifier *connections,
unsigned int estate,
unsigned int cstate);
*/
#define GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_DUMP 1038
+/**
+ * End of local information about all peers known to the service.
+ */
+#define GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER_END 1039
+
/******************************** Application *******************************/
/**