* TODO: add regex to reconnect
*/
#include "platform.h"
-#include "gnunet_common.h"
-#include "gnunet_client_lib.h"
#include "gnunet_util_lib.h"
-#include "gnunet_peer_lib.h"
#include "gnunet_mesh_service.h"
#include "mesh.h"
#include "mesh_protocol.h"
* Time to the next reconnect in case one reconnect fails
*/
struct GNUNET_TIME_Relative reconnect_time;
-
+
/**
* Task for trying to reconnect.
*/
*/
struct GNUNET_MESH_Peer
{
- /**
- * ID of the peer in short form
- */
+ /**
+ * ID of the peer in short form
+ */
GNUNET_PEER_Id id;
/**
/**
* Flag indicating whether service has informed about its connection
+ * FIXME-BART: is this flag used? Seems dead right now...
*/
int connected;
*/
GNUNET_PEER_Id peer;
+ struct GNUNET_PeerIdentity pid;
+
/**
* Any data the caller wants to put in here
*/
/**
* Is the tunnel allowed to buffer?
*/
- int buffering;
+ int nobuffer;
/**
- * Is the tunnel allowed to buffer?
+ * Is the tunnel realiable?
*/
int reliable;
/**
- * Maximum allowed PID to send (last ACK recevied).
+ * If reliable, is the tunnel out of order?
*/
- uint32_t last_ack_recv;
+ int ooorder;
/**
- * Last PID received from the service.
+ * Are we allowed to send to the service?
*/
- uint32_t last_pid_recv;
+ int allow_send;
- /**
- * Last packet ID sent to the service.
- */
- uint32_t last_pid_sent;
-
- /**
- * Last ACK value sent to the service: how much are we willing to accept?
- */
- uint32_t last_ack_sent;
};
/**
* Check whether there is any message ready in the queue and find the size.
- *
+ *
* @param h Mesh handle.
- *
+ *
* @return The size of the first ready message in the queue,
* 0 if there is none.
*/
LOG (GNUNET_ERROR_TYPE_DEBUG, "# message internal\n");
return th->size;
}
- if (GNUNET_YES == GMC_is_pid_bigger(t->last_ack_recv, t->last_pid_sent))
+ if (GNUNET_YES == t->allow_send)
{
- LOG (GNUNET_ERROR_TYPE_DEBUG, "# message payload ok (%u =< %u)\n",
- t->last_pid_sent + 1, t->last_ack_recv);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "# message payload ok\n");
return th->size;
}
}
{
t->tid = tid;
}
- t->last_ack_recv = (uint32_t) -1;
- t->last_pid_recv = (uint32_t) -1;
- t->last_ack_sent = (uint32_t) -1;
- t->last_pid_sent = (uint32_t) -1;
- t->buffering = GNUNET_YES;
+ t->allow_send = GNUNET_NO;
+ t->nobuffer = GNUNET_NO;
return t;
}
struct GNUNET_MESH_TransmitHandle *th;
struct GNUNET_MESH_TransmitHandle *next;
- LOG (GNUNET_ERROR_TYPE_DEBUG, "destroy_tunnel %X\n", t->tid);
-
if (NULL == t)
{
GNUNET_break (0);
return;
}
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "destroy_tunnel %X\n",
+ t->tid);
h = t->mesh;
GNUNET_CONTAINER_DLL_remove (h->tunnels_head, h->tunnels_tail, t);
/* clean up request */
if (GNUNET_SCHEDULER_NO_TASK != th->timeout_task)
GNUNET_SCHEDULER_cancel (th->timeout_task);
- GNUNET_free (th);
+ GNUNET_free (th);
}
/* if there are no more pending requests with mesh service, cancel active request */
/**
* Notify client that the transmission has timed out
- *
+ *
* @param cls closure
* @param tc task context
*/
struct GNUNET_MESH_TransmitHandle *th)
{
GNUNET_CONTAINER_DLL_insert_tail (h->th_head, h->th_tail, th);
- if (GNUNET_TIME_UNIT_FOREVER_ABS.abs_value == th->timeout.abs_value)
+ if (GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us == th->timeout.abs_value_us)
return;
th->timeout_task =
GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining
/**
* Send an ack on the tunnel to confirm the processing of a message.
- *
+ *
* @param t Tunnel on which to send the ACK.
*/
static void
{
struct GNUNET_MESH_LocalAck msg;
- t->last_ack_sent = t->last_pid_recv + 1;
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Sending ACK on tunnel %X: %u\n",
- t->tid, t->last_ack_sent);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Sending ACK on tunnel %X\n", t->tid);
msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK);
msg.header.size = htons (sizeof (msg));
msg.tunnel_id = htonl (t->tid);
- msg.ack = htonl (t->last_ack_sent);
#if DEBUG_ACK
t->mesh->acks_sent++;
GNUNET_TIME_relative_min (GNUNET_TIME_UNIT_SECONDS,
GNUNET_TIME_relative_multiply
(h->reconnect_time, 2));
- LOG (GNUNET_ERROR_TYPE_DEBUG,
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
"Next retry in %s\n",
GNUNET_STRINGS_relative_time_to_string (h->reconnect_time,
GNUNET_NO));
for (t = h->tunnels_head; NULL != t; t = t->next)
{
struct GNUNET_MESH_TunnelMessage tmsg;
+ uint32_t options;
if (t->tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
{
*/
continue;
}
- t->last_ack_sent = (uint32_t) -1;
- t->last_pid_sent = (uint32_t) -1;
- t->last_ack_recv = (uint32_t) -1;
- t->last_pid_recv = (uint32_t) -1;
+ t->allow_send = GNUNET_NO;
tmsg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE);
tmsg.header.size = htons (sizeof (struct GNUNET_MESH_TunnelMessage));
tmsg.tunnel_id = htonl (t->tid);
+ tmsg.port = htonl (t->port);
+ t->pid = tmsg.peer;
GNUNET_PEER_resolve (t->peer, &tmsg.peer);
- send_packet (h, &tmsg.header, t);
- if (GNUNET_NO == t->buffering)
- GNUNET_MESH_tunnel_buffer (t, GNUNET_NO);
+ options = 0;
+ if (GNUNET_YES == t->nobuffer)
+ options |= GNUNET_MESH_OPTION_NOBUFFER;
if (GNUNET_YES == t->reliable)
- GNUNET_MESH_tunnel_reliable (t, GNUNET_YES);
+ options |= GNUNET_MESH_OPTION_RELIABLE;
+
+ tmsg.opt = htonl (options);
+ send_packet (h, &tmsg.header, t);
}
return GNUNET_YES;
}
*/
static void
process_tunnel_created (struct GNUNET_MESH_Handle *h,
- const struct GNUNET_MESH_TunnelNotification *msg)
+ const struct GNUNET_MESH_TunnelMessage *msg)
{
struct GNUNET_MESH_Tunnel *t;
MESH_TunnelNumber tid;
+ uint32_t port;
tid = ntohl (msg->tunnel_id);
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Creating incoming tunnel %X\n", tid);
+ port = ntohl (msg->port);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Creating incoming tunnel %X:%u\n", tid, port);
if (tid < GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
{
GNUNET_break (0);
if (NULL != h->new_tunnel)
{
t = create_tunnel (h, tid);
- t->last_ack_sent = 0;
+ t->allow_send = GNUNET_NO;
t->peer = GNUNET_PEER_intern (&msg->peer);
+ t->pid = msg->peer;
t->mesh = h;
t->tid = tid;
- t->port = ntohl (msg->port);
- if (0 != (msg->opt & MESH_TUNNEL_OPT_NOBUFFER))
- t->buffering = GNUNET_NO;
+ t->port = port;
+ if (0 != (msg->opt & GNUNET_MESH_OPTION_NOBUFFER))
+ t->nobuffer = GNUNET_YES;
+ else
+ t->nobuffer = GNUNET_NO;
+ if (0 != (msg->opt & GNUNET_MESH_OPTION_RELIABLE))
+ t->reliable = GNUNET_YES;
+ else
+ t->reliable = GNUNET_NO;
+ if (GNUNET_YES == t->reliable &&
+ 0 != (msg->opt & GNUNET_MESH_OPTION_OOORDER))
+ t->ooorder = GNUNET_YES;
else
- t->buffering = GNUNET_YES;
+ t->ooorder = GNUNET_NO;
LOG (GNUNET_ERROR_TYPE_DEBUG, " created tunnel %p\n", t);
t->ctx = h->new_tunnel (h->cls, t, &msg->peer, t->port);
LOG (GNUNET_ERROR_TYPE_DEBUG, "User notified\n");
d_msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY);
d_msg.header.size = htons (sizeof (struct GNUNET_MESH_TunnelMessage));
d_msg.tunnel_id = msg->tunnel_id;
+ memset (&d_msg.peer, 0, sizeof (struct GNUNET_PeerIdentity));
+ d_msg.port = 0;
+ d_msg.opt = 0;
send_packet (h, &d_msg.header, NULL);
}
struct GNUNET_MESH_Tunnel *t;
MESH_TunnelNumber tid;
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroying tunnel from service\n");
tid = ntohl (msg->tunnel_id);
t = retrieve_tunnel (h, tid);
if (NULL == t)
{
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "tunnel %X unknown\n", tid);
return;
}
LOG (GNUNET_ERROR_TYPE_DEBUG, "tunnel %X destroyed\n", t->tid);
destroy_tunnel (t, GNUNET_YES);
- return;
}
{
const struct GNUNET_MessageHeader *payload;
const struct GNUNET_MESH_MessageHandler *handler;
- const struct GNUNET_PeerIdentity *peer;
- struct GNUNET_PeerIdentity id;
- struct GNUNET_MESH_Data *dmsg;
+ struct GNUNET_MESH_LocalData *dmsg;
struct GNUNET_MESH_Tunnel *t;
unsigned int i;
- uint32_t pid;
uint16_t type;
LOG (GNUNET_ERROR_TYPE_DEBUG, "Got a data message!\n");
- type = ntohs (message->type);
- switch (type)
- {
- case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
- case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
- dmsg = (struct GNUNET_MESH_Data *) message;
-
- t = retrieve_tunnel (h, ntohl (dmsg->tid));
- payload = (struct GNUNET_MessageHeader *) &dmsg[1];
- GNUNET_PEER_resolve (t->peer, &id);
- peer = &id;
- pid = ntohl (dmsg->pid);
- LOG (GNUNET_ERROR_TYPE_DEBUG, " %s data on tunnel %s [%X]\n",
- type == GNUNET_MESSAGE_TYPE_MESH_UNICAST ? "fwd" : "bck",
- GNUNET_i2s (peer), ntohl (dmsg->tid));
- break;
- default:
- GNUNET_break (0);
- return;
- }
- LOG (GNUNET_ERROR_TYPE_DEBUG, " pid %u\n", pid);
+
+ dmsg = (struct GNUNET_MESH_LocalData *) message;
+
+ t = retrieve_tunnel (h, ntohl (dmsg->tid));
+ payload = (struct GNUNET_MessageHeader *) &dmsg[1];
if (NULL == t)
{
/* Tunnel was ignored/destroyed, probably service didn't get it yet */
LOG (GNUNET_ERROR_TYPE_DEBUG, " ignored!\n");
return;
}
- if (GNUNET_YES ==
- GMC_is_pid_bigger(pid, t->last_ack_sent))
- {
- GNUNET_break (0);
- LOG (GNUNET_ERROR_TYPE_WARNING,
- " unauthorized message! (%u, ACK %u)\n",
- pid, t->last_ack_sent);
- // FIXME fc what now? accept? reject?
- return;
- }
- t->last_pid_recv = pid;
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ " %s data on tunnel %s [%X]\n",
+ t->tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV ? "fwd" : "bck",
+ GNUNET_i2s (GNUNET_PEER_resolve2(t->peer)),
+ ntohl (dmsg->tid));
type = ntohs (payload->type);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " payload type %u\n", type);
for (i = 0; i < h->n_handlers; i++)
{
handler = &h->message_handlers[i];
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ " checking handler for type %u\n",
+ handler->type);
if (handler->type == type)
{
if (GNUNET_OK !=
/**
* Process a local ACK message, enabling the client to send
* more data to the service.
- *
+ *
* @param h Mesh handle.
* @param message Message itself.
*/
{
struct GNUNET_MESH_LocalAck *msg;
struct GNUNET_MESH_Tunnel *t;
- uint32_t ack;
+ MESH_TunnelNumber tid;
LOG (GNUNET_ERROR_TYPE_DEBUG, "Got an ACK!\n");
h->acks_recv++;
msg = (struct GNUNET_MESH_LocalAck *) message;
-
- t = retrieve_tunnel (h, ntohl (msg->tunnel_id));
-
+ tid = ntohl (msg->tunnel_id);
+ t = retrieve_tunnel (h, tid);
if (NULL == t)
{
- LOG (GNUNET_ERROR_TYPE_WARNING,
- "ACK on unknown tunnel %X\n",
- ntohl (msg->tunnel_id));
+ LOG (GNUNET_ERROR_TYPE_WARNING, "ACK on unknown tunnel %X\n", tid);
return;
}
- ack = ntohl (msg->ack);
- LOG (GNUNET_ERROR_TYPE_DEBUG, " on tunnel %X, ack %u!\n", t->tid, ack);
- if (GNUNET_YES == GMC_is_pid_bigger(ack, t->last_ack_recv))
- t->last_ack_recv = ack;
- else
- return;
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " on tunnel %X!\n", t->tid);
+ t->allow_send = GNUNET_YES;
if (NULL == h->th && 0 < t->packet_size)
{
- LOG (GNUNET_ERROR_TYPE_DEBUG, " tmt rdy was NULL, requesting!\n", t->tid, ack);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " tmt rdy was NULL, requesting!\n");
h->th =
GNUNET_CLIENT_notify_transmit_ready (h->client, t->packet_size,
GNUNET_TIME_UNIT_FOREVER_REL,
msg_received (void *cls, const struct GNUNET_MessageHeader *msg)
{
struct GNUNET_MESH_Handle *h = cls;
+ uint16_t type;
if (msg == NULL)
{
- LOG (GNUNET_ERROR_TYPE_DEBUG,
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
"Mesh service disconnected, reconnecting\n", h);
reconnect (h);
return;
}
- LOG (GNUNET_ERROR_TYPE_DEBUG, "\n",
- GNUNET_MESH_DEBUG_M2S (ntohs (msg->type)));
+ type = ntohs (msg->type);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "\n");
LOG (GNUNET_ERROR_TYPE_DEBUG, "Received a message: %s\n",
- GNUNET_MESH_DEBUG_M2S (ntohs (msg->type)));
- switch (ntohs (msg->type))
+ GNUNET_MESH_DEBUG_M2S (type));
+ switch (type)
{
/* Notify of a new incoming tunnel */
case GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE:
- process_tunnel_created (h, (struct GNUNET_MESH_TunnelNotification *) msg);
+ process_tunnel_created (h, (struct GNUNET_MESH_TunnelMessage *) msg);
break;
/* Notify of a tunnel disconnection */
case GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY:
process_tunnel_destroy (h, (struct GNUNET_MESH_TunnelMessage *) msg);
break;
/* Notify of a new data packet in the tunnel */
- case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
- case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
+ case GNUNET_MESSAGE_TYPE_MESH_LOCAL_DATA:
process_incoming_data (h, msg);
break;
case GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK:
process_ack (h, msg);
break;
case GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNELS:
- process_get_tunnels (h, msg);
+ process_get_tunnels (h, msg);
break;
case GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNEL:
- process_show_tunnel (h, msg);
+ process_show_tunnel (h, msg);
break;
default:
/* We shouldn't get any other packages, log and ignore */
t = th->tunnel;
if (GNUNET_YES == th_is_payload (th))
{
- struct GNUNET_MESH_Data *dmsg;
+ struct GNUNET_MESH_LocalData *dmsg;
struct GNUNET_MessageHeader *mh;
LOG (GNUNET_ERROR_TYPE_DEBUG, "# payload\n");
- if (GNUNET_NO == GMC_is_pid_bigger (t->last_ack_recv, t->last_pid_sent))
+ if (GNUNET_NO == t->allow_send)
{
/* This tunnel is not ready to transmit yet, try next message */
next = th->next;
}
t->packet_size = 0;
GNUNET_assert (size >= th->size);
- dmsg = (struct GNUNET_MESH_Data *) cbuf;
+ dmsg = (struct GNUNET_MESH_LocalData *) cbuf;
mh = (struct GNUNET_MessageHeader *) &dmsg[1];
psize = th->notify (th->notify_cls,
- size - sizeof (struct GNUNET_MESH_Data),
+ size - sizeof (struct GNUNET_MESH_LocalData),
mh);
if (psize > 0)
{
- psize += sizeof (struct GNUNET_MESH_Data);
+ psize += sizeof (struct GNUNET_MESH_LocalData);
GNUNET_assert (size >= psize);
dmsg->header.size = htons (psize);
dmsg->tid = htonl (t->tid);
- dmsg->pid = htonl (t->last_pid_sent + 1);
- dmsg->ttl = 0;
- memset (&dmsg->oid, 0, sizeof (struct GNUNET_PeerIdentity));
- t->last_pid_sent++;
- }
- if (t->tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
- {
- dmsg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN);
- LOG (GNUNET_ERROR_TYPE_DEBUG, "# to origin, type %s\n",
+ 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)));
+ t->allow_send = GNUNET_NO;
}
else
{
- dmsg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_UNICAST);
- LOG (GNUNET_ERROR_TYPE_DEBUG, "# unicast, type %s\n",
- GNUNET_MESH_DEBUG_M2S (ntohs (mh->type)));
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "# callback returned size 0, "
+ "application canceled transmission\n");
}
}
else
{
struct GNUNET_MessageHeader *mh = (struct GNUNET_MessageHeader *) &th[1];
- LOG (GNUNET_ERROR_TYPE_DEBUG, "# mesh traffic, type %s\n",
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "# mesh internal traffic, type %s\n",
GNUNET_MESH_DEBUG_M2S (ntohs (mh->type)));
memcpy (cbuf, &th[1], th->size);
psize = th->size;
* Auxiliary function to send an already constructed packet to the service.
* Takes care of creating a new queue element, copying the message and
* calling the tmt_rdy function if necessary.
- *
+ *
* @param h mesh handle
* @param msg message to transmit
* @param tunnel tunnel this send is related to (NULL if N/A)
h->reconnect_time = GNUNET_TIME_UNIT_MILLISECONDS;
h->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
+ if (NULL != ports && ports[0] != 0 && NULL == new_tunnel)
+ {
+ GNUNET_break (0);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "no new tunnel handler given, ports parameter is useless!!\n");
+ }
+ if ((NULL == ports || ports[0] == 0) && NULL != new_tunnel)
+ {
+ GNUNET_break (0);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "no ports given, new tunnel handler will never be called!!\n");
+ }
/* count handlers */
for (h->n_handlers = 0;
handlers && handlers[h->n_handlers].type;
}
+/**
+ * Create a new tunnel (we're initiator and will be allowed to add/remove peers
+ * and to broadcast).
+ *
+ * @param h mesh handle
+ * @param tunnel_ctx client's tunnel context to associate with the tunnel
+ * @param peer peer identity the tunnel should go to
+ * @param port Port number.
+ * @param nobuffer Flag for disabling buffering on relay nodes.
+ * @param reliable Flag for end-to-end reliability.
+ *
+ * @return handle to the tunnel
+ */
struct GNUNET_MESH_Tunnel *
-GNUNET_MESH_tunnel_create (struct GNUNET_MESH_Handle *h,
+GNUNET_MESH_tunnel_create (struct GNUNET_MESH_Handle *h,
void *tunnel_ctx,
const struct GNUNET_PeerIdentity *peer,
- uint32_t port)
+ uint32_t port,
+ int nobuffer,
+ int reliable)
{
struct GNUNET_MESH_Tunnel *t;
struct GNUNET_MESH_TunnelMessage msg;
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Creating new tunnel\n");
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Creating new tunnel to %s:%u\n",
+ GNUNET_i2s (peer), port);
t = create_tunnel (h, 0);
LOG (GNUNET_ERROR_TYPE_DEBUG, " at %p\n", t);
LOG (GNUNET_ERROR_TYPE_DEBUG, " number %X\n", t->tid);
t->ctx = tunnel_ctx;
t->peer = GNUNET_PEER_intern (peer);
+ t->pid = *peer;
msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE);
msg.header.size = htons (sizeof (struct GNUNET_MESH_TunnelMessage));
msg.tunnel_id = htonl (t->tid);
msg.port = htonl (port);
msg.peer = *peer;
- t->last_ack_sent = 0;
+ 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);
+ t->allow_send = 0;
send_packet (h, &msg.header, t);
return t;
}
msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY);
msg.header.size = htons (sizeof (struct GNUNET_MESH_TunnelMessage));
msg.tunnel_id = htonl (tunnel->tid);
+ memset (&msg.peer, 0, sizeof (struct GNUNET_PeerIdentity));
+ msg.port = 0;
+ msg.opt = 0;
th = h->th_head;
while (th != NULL)
{
}
-void
-GNUNET_MESH_tunnel_buffer (struct GNUNET_MESH_Tunnel *tunnel, int buffer)
-{
- struct GNUNET_MESH_TunnelMessage msg;
- struct GNUNET_MESH_Handle *h;
-
- h = tunnel->mesh;
- tunnel->buffering = buffer;
-
- if (GNUNET_YES == buffer)
- msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_BUFFER);
- else
- msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_NOBUFFER);
- msg.header.size = htons (sizeof (struct GNUNET_MESH_TunnelMessage));
- msg.tunnel_id = htonl (tunnel->tid);
-
- send_packet (h, &msg.header, NULL);
-}
-
-
/**
- * Turn on/off the reliability of the tunnel.
- *
- * If reliability is on, mesh will resend lost messages, similar to TCP.
- * If reliability is off, mesh just do best effort, similar to UDP.
- *
- * @param tunnel Tunnel affected.
- * @param reliable GNUNET_YES to turn reliability on,
- * GNUNET_NO to have a best effort tunnel (default).
+ * Get information about a tunnel.
+ *
+ * @param tunnel Tunnel handle.
+ * @param option Query (GNUNET_MESH_OPTION_*).
+ * @param ... dependant on option, currently not used
+ *
+ * @return Union with an answer to the query.
*/
-void
-GNUNET_MESH_tunnel_reliable (struct GNUNET_MESH_Tunnel *tunnel, int reliable)
+const union GNUNET_MESH_TunnelInfo *
+GNUNET_MESH_tunnel_get_info (struct GNUNET_MESH_Tunnel *tunnel,
+ enum MeshTunnelOption option, ...)
{
- struct GNUNET_MESH_TunnelMessage msg;
- struct GNUNET_MESH_Handle *h;
+ const union GNUNET_MESH_TunnelInfo *ret;
- h = tunnel->mesh;
- tunnel->reliable = reliable;
-
- if (GNUNET_YES == reliable)
- msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_RELIABLE);
- else
- msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_UNRELIABLE);
- msg.header.size = htons (sizeof (struct GNUNET_MESH_TunnelMessage));
- msg.tunnel_id = htonl (tunnel->tid);
+ switch (option)
+ {
+ case GNUNET_MESH_OPTION_NOBUFFER:
+ ret = (const union GNUNET_MESH_TunnelInfo *) &tunnel->nobuffer;
+ break;
+ case GNUNET_MESH_OPTION_RELIABLE:
+ ret = (const union GNUNET_MESH_TunnelInfo *) &tunnel->reliable;
+ break;
+ case GNUNET_MESH_OPTION_OOORDER:
+ ret = (const union GNUNET_MESH_TunnelInfo *) &tunnel->ooorder;
+ break;
+ case GNUNET_MESH_OPTION_PEER:
+ ret = (const union GNUNET_MESH_TunnelInfo *) &tunnel->pid;
+ break;
+ default:
+ GNUNET_break (0);
+ return NULL;
+ }
- send_packet (h, &msg.header, NULL);
+ return ret;
}
-
struct GNUNET_MESH_TransmitHandle *
GNUNET_MESH_notify_transmit_ready (struct GNUNET_MESH_Tunnel *tunnel, int cork,
struct GNUNET_TIME_Relative maxdelay,
GNUNET_assert (NULL != tunnel);
LOG (GNUNET_ERROR_TYPE_DEBUG, "MESH NOTIFY TRANSMIT READY\n");
LOG (GNUNET_ERROR_TYPE_DEBUG, " on tunnel %X\n", tunnel->tid);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " allow_send %d\n", tunnel->allow_send);
if (tunnel->tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
LOG (GNUNET_ERROR_TYPE_DEBUG, " to origin\n");
else
th = GNUNET_malloc (sizeof (struct GNUNET_MESH_TransmitHandle));
th->tunnel = tunnel;
th->timeout = GNUNET_TIME_relative_to_absolute (maxdelay);
- th->size = notify_size + sizeof (struct GNUNET_MESH_Data);
+ th->size = notify_size + sizeof (struct GNUNET_MESH_LocalData);
tunnel->packet_size = th->size;
LOG (GNUNET_ERROR_TYPE_DEBUG, " total size %u\n", th->size);
th->notify = notify;
add_to_queue (tunnel->mesh, th);
if (NULL != tunnel->mesh->th)
return th;
- if (!GMC_is_pid_bigger (tunnel->last_ack_recv, tunnel->last_pid_sent))
+ if (GNUNET_NO == tunnel->allow_send)
return th;
LOG (GNUNET_ERROR_TYPE_DEBUG, " call client notify tmt rdy\n");
tunnel->mesh->th =
mesh_mq_ntr (void *cls, size_t size,
void *buf)
{
- struct GNUNET_MQ_Handle *mq = cls;
+ struct GNUNET_MQ_Handle *mq = cls;
struct MeshMQState *state = GNUNET_MQ_impl_state (mq);
const struct GNUNET_MessageHeader *msg = GNUNET_MQ_impl_current (mq);
uint16_t msize;
+ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "mesh-mq",
+ "writing message (t: %u, s: %u) to buffer\n",
+ ntohs (msg->type), ntohs (msg->size));
+
state->th = NULL;
if (NULL == buf)
{
GNUNET_assert (NULL == state->th);
GNUNET_MQ_impl_send_commit (mq);
+ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "mesh-mq",
+ "calling ntr for message (t: %u, s: %u)\n",
+ ntohs (msg->type), ntohs (msg->size));
state->th =
GNUNET_MESH_notify_transmit_ready (state->tunnel,
/* FIXME: add option for corking */
GNUNET_NO,
- GNUNET_TIME_UNIT_FOREVER_REL,
+ GNUNET_TIME_UNIT_FOREVER_REL,
ntohs (msg->size),
mesh_mq_ntr, mq);
* destruction of a message queue.
* Implementations must not free 'mq', but should
* take care of 'impl_state'.
- *
+ *
* @param mq the message queue to destroy
* @param impl_state state of the implementation
*/