* Channel this peer belongs to
*/
struct GNUNET_MESH_Channel *t;
-
- /**
- * Flag indicating whether service has informed about its connection
- * FIXME-BART: is this flag used? Seems dead right now...
- */
- int connected;
-
};
unsigned int packet_size;
/**
- * Is the channel allowed to buffer?
- */
- int nobuffer;
-
- /**
- * Is the channel realiable?
+ * Channel options: reliability, etc.
*/
- int reliable;
-
- /**
- * If reliable, is the channel out of order?
- */
- int ooorder;
+ enum GNUNET_MESH_ChannelOption options;
/**
* Are we allowed to send to the service?
ch->chid = chid;
}
ch->allow_send = GNUNET_NO;
- ch->nobuffer = GNUNET_NO;
return ch;
}
struct GNUNET_MESH_TransmitHandle *th;
struct GNUNET_MESH_TransmitHandle *next;
- LOG (GNUNET_ERROR_TYPE_DEBUG, "destroy_channel %X\n", ch->chid);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " destroy_channel %X\n", ch->chid);
if (NULL == ch)
{
/* signal channel destruction */
if ( (NULL != h->cleaner) && (0 != ch->peer) && (GNUNET_YES == call_cleaner) )
+ {
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " calling cleaner\n");
h->cleaner (h->cls, ch, ch->ctx);
+ }
/* check that clients did not leave messages behind in the queue */
for (th = h->th_head; NULL != th; th = next)
if (th->channel != ch)
continue;
/* Clients should have aborted their requests already.
- * Management traffic should be ok, as clients can't cancel that */
- GNUNET_break (GNUNET_NO == th_is_payload (th));
+ * Management traffic should be ok, as clients can't cancel that.
+ * If the service crashed and we are reconnecting, it's ok.
+ */
+ GNUNET_break (GNUNET_NO == th_is_payload (th)
+ || GNUNET_NO == h->in_receive);
GNUNET_CONTAINER_DLL_remove (h->th_head, h->th_tail, th);
/* clean up request */
static int
do_reconnect (struct GNUNET_MESH_Handle *h)
{
- struct GNUNET_MESH_Channel *ch;
-
LOG (GNUNET_ERROR_TYPE_DEBUG, "*****************************\n");
LOG (GNUNET_ERROR_TYPE_DEBUG, "******* RECONNECT *******\n");
LOG (GNUNET_ERROR_TYPE_DEBUG, "*****************************\n");
h->reconnect_time = GNUNET_TIME_UNIT_MILLISECONDS;
}
send_connect (h);
- /* Rebuild all channels */
- for (ch = h->channels_head; NULL != ch; ch = ch->next)
- {
- struct GNUNET_MESH_ChannelMessage tmsg;
- uint32_t options;
-
- if (ch->chid >= GNUNET_MESH_LOCAL_CHANNEL_ID_SERV)
- {
- /* Channel was created by service (incoming channel) */
- /* TODO: Notify service of missing channel, to request
- * creator to recreate path (find a path to him via DHT?)
- */
- continue;
- }
- ch->allow_send = GNUNET_NO;
- tmsg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE);
- tmsg.header.size = htons (sizeof (struct GNUNET_MESH_ChannelMessage));
- tmsg.channel_id = htonl (ch->chid);
- tmsg.port = htonl (ch->port);
- GNUNET_PEER_resolve (ch->peer, &tmsg.peer);
-
- options = 0;
- if (GNUNET_YES == ch->nobuffer)
- options |= GNUNET_MESH_OPTION_NOBUFFER;
-
- if (GNUNET_YES == ch->reliable)
- options |= GNUNET_MESH_OPTION_RELIABLE;
-
- tmsg.opt = htonl (options);
- send_packet (h, &tmsg.header, ch);
- }
return GNUNET_YES;
}
static void
reconnect (struct GNUNET_MESH_Handle *h)
{
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Requested RECONNECT\n");
+ struct GNUNET_MESH_Channel *ch;
+ struct GNUNET_MESH_Channel *next;
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Requested RECONNECT, destroying all channels\n");
h->in_receive = GNUNET_NO;
+ for (ch = h->channels_head; NULL != ch; ch = next)
+ {
+ next = ch->next;
+ destroy_channel (ch, GNUNET_YES);
+ }
if (GNUNET_SCHEDULER_NO_TASK == h->reconnect_task)
h->reconnect_task = GNUNET_SCHEDULER_add_delayed (h->reconnect_time,
&reconnect_cbk, h);
}
if (NULL != h->new_channel)
{
+ void *ctx;
+
ch = create_channel (h, chid);
ch->allow_send = GNUNET_NO;
ch->peer = GNUNET_PEER_intern (&msg->peer);
ch->mesh = h;
ch->chid = chid;
ch->port = port;
- if (0 != (msg->opt & GNUNET_MESH_OPTION_NOBUFFER))
- ch->nobuffer = GNUNET_YES;
- else
- ch->nobuffer = GNUNET_NO;
-
- if (0 != (msg->opt & GNUNET_MESH_OPTION_RELIABLE))
- ch->reliable = GNUNET_YES;
- else
- ch->reliable = GNUNET_NO;
-
- if (GNUNET_YES == ch->reliable &&
- 0 != (msg->opt & GNUNET_MESH_OPTION_OOORDER))
- ch->ooorder = GNUNET_YES;
- else
- ch->ooorder = GNUNET_NO;
+ ch->options = ntohl (msg->opt);
LOG (GNUNET_ERROR_TYPE_DEBUG, " created channel %p\n", ch);
- ch->ctx = h->new_channel (h->cls, ch, &msg->peer, ch->port);
+ ctx = h->new_channel (h->cls, ch, &msg->peer, ch->port, ch->options);
+ if (NULL != ctx)
+ ch->ctx = ctx;
LOG (GNUNET_ERROR_TYPE_DEBUG, "User notified\n");
}
else
struct GNUNET_MESH_Channel *ch;
MESH_ChannelNumber chid;
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroying channel from service\n");
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Channel Destroy received from service\n");
chid = ntohl (msg->channel_id);
ch = retrieve_channel (h, chid);
LOG (GNUNET_ERROR_TYPE_DEBUG, "channel %X unknown\n", chid);
return;
}
- LOG (GNUNET_ERROR_TYPE_DEBUG, "channel %X destroyed\n", ch->chid);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " destroying channel %X\n", ch->chid);
destroy_channel (ch, GNUNET_YES);
}
unsigned int i;
uint16_t type;
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Got a data message!\n");
-
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Got a data message!\n");
dmsg = (struct GNUNET_MESH_LocalData *) message;
-
ch = retrieve_channel (h, ntohl (dmsg->id));
payload = (struct GNUNET_MessageHeader *) &dmsg[1];
- LOG (GNUNET_ERROR_TYPE_DEBUG, " %s data on channel %s [%X]\n",
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ " %s data on channel %s [%X]\n",
ch->chid >= GNUNET_MESH_LOCAL_CHANNEL_ID_SERV ? "fwd" : "bck",
GNUNET_i2s (GNUNET_PEER_resolve2 (ch->peer)), ntohl (dmsg->id));
if (NULL == ch)
{
LOG (GNUNET_ERROR_TYPE_DEBUG,
"callback completed successfully\n");
+ return;
}
}
}
// const struct GNUNET_MessageHeader *message)
// {
// struct GNUNET_MESH_LocalMonitor *msg;
-//
+//
// GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Get Channels messasge received\n");
-//
+//
// if (NULL == h->channels_cb)
// {
// GNUNET_log (GNUNET_ERROR_TYPE_ERROR, " ignored\n");
// return;
// }
-//
+//
// msg = (struct GNUNET_MESH_LocalMonitor *) message;
// if (ntohs (message->size) !=
// (sizeof (struct GNUNET_MESH_LocalMonitor) +
// {
// struct GNUNET_MESH_LocalMonitor *msg;
// size_t esize;
-//
+//
// GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Show Channel messasge received\n");
-//
+//
// if (NULL == h->channel_cb)
// {
// GNUNET_log (GNUNET_ERROR_TYPE_ERROR, " ignored\n");
// return;
// }
-//
+//
// /* Verify message sanity */
// msg = (struct GNUNET_MESH_LocalMonitor *) message;
// esize = sizeof (struct GNUNET_MESH_LocalMonitor);
// "Show channel message: size %hu - expected %u\n",
// ntohs (message->size),
// esize);
-//
+//
// h->channel_cb (h->channel_cls, NULL, NULL);
// h->channel_cb = NULL;
// h->channel_cls = NULL;
-//
+//
// return;
// }
-//
+//
// h->channel_cb (h->channel_cls,
// &msg->destination,
// &msg->owner);
type = ntohs (msg->type);
LOG (GNUNET_ERROR_TYPE_DEBUG, "\n");
LOG (GNUNET_ERROR_TYPE_DEBUG, "Received a message: %s\n",
- GNUNET_MESH_DEBUG_M2S (type));
+ GM_m2s (type));
switch (type)
{
/* Notify of a new incoming channel */
process_channel_created (h, (struct GNUNET_MESH_ChannelMessage *) msg);
break;
/* Notify of a channel disconnection */
- case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY:
+ case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY: /* TODO separate(gid problem)*/
case GNUNET_MESSAGE_TYPE_MESH_LOCAL_NACK:
process_channel_destroy (h, (struct GNUNET_MESH_ChannelMessage *) msg);
break;
/* We shouldn't get any other packages, log and ignore */
LOG (GNUNET_ERROR_TYPE_WARNING,
"unsolicited message form service (type %s)\n",
- GNUNET_MESH_DEBUG_M2S (ntohs (msg->type)));
+ GM_m2s (ntohs (msg->type)));
}
LOG (GNUNET_ERROR_TYPE_DEBUG, "message processed\n");
if (GNUNET_YES == h->in_receive)
dmsg->id = htonl (ch->chid);
dmsg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_DATA);
LOG (GNUNET_ERROR_TYPE_DEBUG, "# payload type %s\n",
- GNUNET_MESH_DEBUG_M2S (ntohs (mh->type)));
+ GM_m2s (ntohs (mh->type)));
ch->allow_send = GNUNET_NO;
}
else
struct GNUNET_MessageHeader *mh = (struct GNUNET_MessageHeader *) &th[1];
LOG (GNUNET_ERROR_TYPE_DEBUG, "# mesh internal traffic, type %s\n",
- GNUNET_MESH_DEBUG_M2S (ntohs (mh->type)));
+ GM_m2s (ntohs (mh->type)));
memcpy (cbuf, &th[1], th->size);
psize = th->size;
}
size_t msize;
LOG (GNUNET_ERROR_TYPE_DEBUG, " Sending message to service: %s\n",
- GNUNET_MESH_DEBUG_M2S(ntohs(msg->type)));
+ GM_m2s(ntohs(msg->type)));
msize = ntohs (msg->size);
th = GNUNET_malloc (sizeof (struct GNUNET_MESH_TransmitHandle) + msize);
th->timeout = GNUNET_TIME_UNIT_FOREVER_ABS;
* @param channel_ctx client's channel context to associate with the channel
* @param peer peer identity the channel should go to
* @param port Port number.
- * @param nobuffer Flag for disabling buffering on relay nodes.
- * @param reliable Flag for end-to-end reliability.
+ * @param options MeshOption flag field, with all desired option bits set to 1.
*
* @return handle to the channel
*/
struct GNUNET_MESH_Channel *
GNUNET_MESH_channel_create (struct GNUNET_MESH_Handle *h,
- void *channel_ctx,
- const struct GNUNET_PeerIdentity *peer,
- uint32_t port,
- int nobuffer,
- int reliable)
+ void *channel_ctx,
+ const struct GNUNET_PeerIdentity *peer,
+ uint32_t port,
+ enum GNUNET_MESH_ChannelOption options)
{
struct GNUNET_MESH_Channel *ch;
struct GNUNET_MESH_ChannelMessage msg;
msg.channel_id = htonl (ch->chid);
msg.port = htonl (port);
msg.peer = *peer;
- msg.opt = 0;
- if (GNUNET_YES == reliable)
- msg.opt |= GNUNET_MESH_OPTION_RELIABLE;
- if (GNUNET_YES == nobuffer)
- msg.opt |= GNUNET_MESH_OPTION_NOBUFFER;
- msg.opt = htonl (msg.opt);
+ msg.opt = htonl (options);
ch->allow_send = 0;
send_packet (h, &msg.header, ch);
return ch;
*/
const union GNUNET_MESH_ChannelInfo *
GNUNET_MESH_channel_get_info (struct GNUNET_MESH_Channel *channel,
- enum MeshOption option, ...)
+ enum GNUNET_MESH_ChannelOption option, ...)
{
+ static int bool_flag;
const union GNUNET_MESH_ChannelInfo *ret;
switch (option)
{
case GNUNET_MESH_OPTION_NOBUFFER:
- ret = (const union GNUNET_MESH_ChannelInfo *) &channel->nobuffer;
- break;
case GNUNET_MESH_OPTION_RELIABLE:
- ret = (const union GNUNET_MESH_ChannelInfo *) &channel->reliable;
- break;
case GNUNET_MESH_OPTION_OOORDER:
- ret = (const union GNUNET_MESH_ChannelInfo *) &channel->ooorder;
+ if (0 != (option & channel->options))
+ bool_flag = GNUNET_YES;
+ else
+ bool_flag = GNUNET_NO;
+ ret = (const union GNUNET_MESH_ChannelInfo *) &bool_flag;
break;
case GNUNET_MESH_OPTION_PEER:
- ret = (const union GNUNET_MESH_ChannelInfo *) &channel->peer;
+ ret = (const union GNUNET_MESH_ChannelInfo *) GNUNET_PEER_resolve2 (channel->peer);
break;
default:
GNUNET_break (0);
}
}
+
void
GNUNET_MESH_receive_done (struct GNUNET_MESH_Channel *channel)
{
send_packet (h, &msg, NULL);
h->channels_cb = callback;
h->channels_cls = callback_cls;
-
- return;
}
send_packet (h, &msg.header, NULL);
h->channel_cb = callback;
h->channel_cls = callback_cls;
-
- return;
}
struct MeshMQState *state = impl_state;
GNUNET_assert (NULL == state->th);
- GNUNET_MQ_impl_send_commit (mq);
state->th =
GNUNET_MESH_notify_transmit_ready (state->channel,
/* FIXME: add option for corking */