From 9d10ae765c3e83a2cac780a02cd5aed9a81466f8 Mon Sep 17 00:00:00 2001 From: Bart Polot Date: Thu, 7 Nov 2013 16:24:46 +0000 Subject: [PATCH] - fix #3091 --- src/mesh/gnunet-service-mesh-enc.c | 34 ------ src/mesh/gnunet-service-mesh_channel.c | 67 ++++++++++- src/mesh/gnunet-service-mesh_channel.h | 10 ++ src/mesh/gnunet-service-mesh_local.c | 26 +++++ src/mesh/gnunet-service-mesh_local.h | 9 ++ src/mesh/gnunet-service-mesh_tunnel.c | 52 ++++++++- src/mesh/mesh_api_enc.c | 152 ++++++++++++------------- src/mesh/mesh_protocol_enc.h | 2 +- 8 files changed, 235 insertions(+), 117 deletions(-) diff --git a/src/mesh/gnunet-service-mesh-enc.c b/src/mesh/gnunet-service-mesh-enc.c index 3d1238a36..f5e365e1c 100644 --- a/src/mesh/gnunet-service-mesh-enc.c +++ b/src/mesh/gnunet-service-mesh-enc.c @@ -56,17 +56,6 @@ #include "gnunet-service-mesh_peer.h" -/******************************************************************************/ -/************************ DATA STRUCTURES ****************************/ -/******************************************************************************/ - - - -/******************************************************************************/ -/************************ DEBUG FUNCTIONS ****************************/ -/******************************************************************************/ - - /******************************************************************************/ /*********************** GLOBAL VARIABLES ****************************/ /******************************************************************************/ @@ -96,33 +85,10 @@ struct GNUNET_PeerIdentity my_full_id; static struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key; -/******************************************************************************/ -/*********************** DECLARATIONS **************************/ -/******************************************************************************/ - - -/******************************************************************************/ -/****************** GENERAL HELPER FUNCTIONS ************************/ -/******************************************************************************/ - - - -/******************************************************************************/ -/**************** MESH NETWORK HANDLER HELPERS ***********************/ -/******************************************************************************/ - - - -/******************************************************************************/ -/******************** MESH NETWORK HANDLERS **************************/ -/******************************************************************************/ - - /******************************************************************************/ /************************ MAIN FUNCTIONS ****************************/ /******************************************************************************/ - /** * Task run during shutdown. * diff --git a/src/mesh/gnunet-service-mesh_channel.c b/src/mesh/gnunet-service-mesh_channel.c index 4b5baa528..e7fc0323b 100644 --- a/src/mesh/gnunet-service-mesh_channel.c +++ b/src/mesh/gnunet-service-mesh_channel.c @@ -481,6 +481,23 @@ send_client_ack (struct MeshChannel *ch, int fwd) } +/** + * Notify the root that the destination rejected the channel. + * + * @param ch Rejected channel. + */ +static void +send_client_nack (struct MeshChannel *ch) +{ + if (NULL == ch->root) + { + GNUNET_break (0); + return; + } + GML_send_nack (ch->root, ch->lid_root); +} + + /** * Destroy all reliable messages queued for a channel, * during a channel destruction. @@ -714,6 +731,27 @@ channel_send_ack (struct MeshChannel *ch, int fwd) } +/** + * Notify that a channel create didn't succeed. + * + * @param ch The channel to reject. + */ +static void +channel_send_nack (struct MeshChannel *ch) +{ + struct GNUNET_MESH_ChannelManage msg; + + msg.header.size = htons (sizeof (msg)); + msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CHANNEL_NACK); + LOG (GNUNET_ERROR_TYPE_DEBUG, + " sending channel NACK for channel %s\n", + GMCH_2s (ch)); + + msg.chid = htonl (ch->gid); + GMCH_send_prebuilt_message (&msg.header, ch, GNUNET_NO); +} + + /** * Channel was ACK'd by remote peer, mark as ready and cancel retransmission. * @@ -941,6 +979,10 @@ handle_loopback (struct MeshChannel *ch, fwd); break; + case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_NACK: + GMCH_handle_nack (ch); + break; + case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY: GMCH_handle_destroy (ch, (struct GNUNET_MESH_ChannelManage *) msgh, @@ -1692,7 +1734,15 @@ GMCH_handle_create (struct MeshTunnel3 *t, { /* TODO send reject */ LOG (GNUNET_ERROR_TYPE_DEBUG, " no client has port registered\n"); - channel_destroy (ch); + if (is_loopback (ch)) + { + channel_send_nack (ch); + } + else + { + channel_send_nack (ch); + channel_destroy (ch); + } return NULL; } else @@ -1713,6 +1763,21 @@ GMCH_handle_create (struct MeshTunnel3 *t, } +/** + * Handler for channel NACK messages. + * + * NACK messages always go dest -> root, no need for 'fwd' or 'msg' parameter. + * + * @param ch Channel. + */ +void +GMCH_handle_nack (struct MeshChannel *ch) +{ + send_client_nack (ch); + channel_destroy (ch); +} + + /** * Handler for channel ack messages. * diff --git a/src/mesh/gnunet-service-mesh_channel.h b/src/mesh/gnunet-service-mesh_channel.h index 66fe33340..e718b315c 100644 --- a/src/mesh/gnunet-service-mesh_channel.h +++ b/src/mesh/gnunet-service-mesh_channel.h @@ -277,6 +277,16 @@ struct MeshChannel * GMCH_handle_create (struct MeshTunnel3 *t, const struct GNUNET_MESH_ChannelCreate *msg); +/** + * Handler for channel NACK messages. + * + * NACK messages always go dest -> root, no need for 'fwd' or 'msg' parameter. + * + * @param ch Channel. + */ +void +GMCH_handle_nack (struct MeshChannel *ch); + /** * Handler for channel ack messages. * diff --git a/src/mesh/gnunet-service-mesh_local.c b/src/mesh/gnunet-service-mesh_local.c index 78a63956f..9430fbefa 100644 --- a/src/mesh/gnunet-service-mesh_local.c +++ b/src/mesh/gnunet-service-mesh_local.c @@ -946,6 +946,32 @@ GML_send_ack (struct MeshClient *c, MESH_ChannelNumber id) } +/** + * Build a local channel NACK message and send it to a local client. + * + * @param c Client to whom send the NACK. + * @param id Channel ID to use + */ +void +GML_send_nack (struct MeshClient *c, MESH_ChannelNumber id) +{ + struct GNUNET_MESH_LocalAck msg; + + LOG (GNUNET_ERROR_TYPE_DEBUG, + "send local nack on %X towards %p\n", + id, c); + + msg.header.size = htons (sizeof (msg)); + msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_NACK); + msg.channel_id = htonl (id); + GNUNET_SERVER_notification_context_unicast (nc, + c->handle, + &msg.header, + GNUNET_NO); + +} + + /** * Notify the client that a new incoming channel was created. * diff --git a/src/mesh/gnunet-service-mesh_local.h b/src/mesh/gnunet-service-mesh_local.h index 0c07fedfe..a78ef7af2 100644 --- a/src/mesh/gnunet-service-mesh_local.h +++ b/src/mesh/gnunet-service-mesh_local.h @@ -159,6 +159,15 @@ GML_client_delete_channel (struct MeshClient *c, void GML_send_ack (struct MeshClient *c, MESH_ChannelNumber id); +/** + * Build a local channel NACK message and send it to a local client. + * + * @param c Client to whom send the NACK. + * @param id Channel ID to use + */ +void +GML_send_nack (struct MeshClient *c, MESH_ChannelNumber id); + /** * Notify the appropriate client that a new incoming channel was created. * diff --git a/src/mesh/gnunet-service-mesh_tunnel.c b/src/mesh/gnunet-service-mesh_tunnel.c index 977908f35..07c907c6c 100644 --- a/src/mesh/gnunet-service-mesh_tunnel.c +++ b/src/mesh/gnunet-service-mesh_tunnel.c @@ -838,7 +838,7 @@ rekey (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) * #GNUNET_NO if message is BCK on the respective channel (loopback) * #GNUNET_SYSERR if message on a one-ended channel (remote) */ -void +static void handle_data (struct MeshTunnel3 *t, const struct GNUNET_MESH_Data *msg, int fwd) @@ -888,7 +888,7 @@ handle_data (struct MeshTunnel3 *t, * #GNUNET_NO if message is BCK on the respective channel (loopback) * #GNUNET_SYSERR if message on a one-ended channel (remote) */ -void +static void handle_data_ack (struct MeshTunnel3 *t, const struct GNUNET_MESH_DataACK *msg, int fwd) @@ -925,7 +925,7 @@ handle_data_ack (struct MeshTunnel3 *t, * @param t Tunnel on which the data came. * @param msg Data message. */ -void +static void handle_ch_create (struct MeshTunnel3 *t, const struct GNUNET_MESH_ChannelCreate *msg) { @@ -955,6 +955,43 @@ handle_ch_create (struct MeshTunnel3 *t, } + +/** + * Handle channel NACK. + * + * @param t Tunnel on which the data came. + * @param msg Data message. + */ +static void +handle_ch_nack (struct MeshTunnel3 *t, + const struct GNUNET_MESH_ChannelManage *msg) +{ + struct MeshChannel *ch; + size_t size; + + /* Check size */ + size = ntohs (msg->header.size); + if (size != sizeof (struct GNUNET_MESH_ChannelManage)) + { + GNUNET_break (0); + return; + } + + /* Check channel */ + ch = GMT_get_channel (t, ntohl (msg->chid)); + if (NULL != ch && ! GMT_is_loopback (t)) + { + 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)); + return; + } + + GMCH_handle_nack (ch); +} + + /** * Handle a CHANNEL ACK (SYNACK/ACK). * @@ -965,7 +1002,7 @@ handle_ch_create (struct MeshTunnel3 *t, * #GNUNET_NO if message is BCK on the respective channel (loopback) * #GNUNET_SYSERR if message on a one-ended channel (remote) */ -void +static void handle_ch_ack (struct MeshTunnel3 *t, const struct GNUNET_MESH_ChannelManage *msg, int fwd) @@ -1007,7 +1044,7 @@ handle_ch_ack (struct MeshTunnel3 *t, * #GNUNET_NO if message is BCK on the respective channel (loopback) * #GNUNET_SYSERR if message on a one-ended channel (remote) */ -void +static void handle_ch_destroy (struct MeshTunnel3 *t, const struct GNUNET_MESH_ChannelManage *msg, int fwd) @@ -1169,6 +1206,11 @@ handle_decrypted (struct MeshTunnel3 *t, (struct GNUNET_MESH_ChannelCreate *) msgh); break; + case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_NACK: + handle_ch_nack (t, + (struct GNUNET_MESH_ChannelManage *) msgh); + break; + case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK: handle_ch_ack (t, (struct GNUNET_MESH_ChannelManage *) msgh, diff --git a/src/mesh/mesh_api_enc.c b/src/mesh/mesh_api_enc.c index 8f4d42fd3..e1eb69740 100644 --- a/src/mesh/mesh_api_enc.c +++ b/src/mesh/mesh_api_enc.c @@ -486,7 +486,7 @@ destroy_channel (struct GNUNET_MESH_Channel *ch, int call_cleaner) 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)); + GNUNET_break (GNUNET_NO == th_is_payload (th)); GNUNET_CONTAINER_DLL_remove (h->th_head, h->th_tail, th); /* clean up request */ @@ -966,37 +966,37 @@ process_ack (struct GNUNET_MESH_Handle *h, * @param h Mesh handle. * @param message Message itself. */ -static void -process_get_channels (struct GNUNET_MESH_Handle *h, - 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) + - sizeof (struct GNUNET_PeerIdentity))) - { - GNUNET_break_op (0); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Get channels message: size %hu - expected %u\n", - ntohs (message->size), - sizeof (struct GNUNET_MESH_LocalMonitor)); - return; - } - h->channels_cb (h->channels_cls, - ntohl (msg->channel_id), - &msg->owner, - &msg->destination); -} +// static void +// process_get_channels (struct GNUNET_MESH_Handle *h, +// 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) + +// sizeof (struct GNUNET_PeerIdentity))) +// { +// GNUNET_break_op (0); +// GNUNET_log (GNUNET_ERROR_TYPE_ERROR, +// "Get channels message: size %hu - expected %u\n", +// ntohs (message->size), +// sizeof (struct GNUNET_MESH_LocalMonitor)); +// return; +// } +// h->channels_cb (h->channels_cls, +// ntohl (msg->channel_id), +// &msg->owner, +// &msg->destination); +// } @@ -1006,43 +1006,43 @@ process_get_channels (struct GNUNET_MESH_Handle *h, * @param h Mesh handle. * @param message Message itself. */ -static void -process_show_channel (struct GNUNET_MESH_Handle *h, - const struct GNUNET_MessageHeader *message) -{ - 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); - if (ntohs (message->size) != esize) - { - GNUNET_break_op (0); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "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); -} +// static void +// process_show_channel (struct GNUNET_MESH_Handle *h, +// const struct GNUNET_MessageHeader *message) +// { +// 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); +// if (ntohs (message->size) != esize) +// { +// GNUNET_break_op (0); +// GNUNET_log (GNUNET_ERROR_TYPE_ERROR, +// "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); +// } /** @@ -1076,21 +1076,21 @@ msg_received (void *cls, const struct GNUNET_MessageHeader *msg) break; /* Notify of a channel disconnection */ case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY: + case GNUNET_MESSAGE_TYPE_MESH_LOCAL_NACK: process_channel_destroy (h, (struct GNUNET_MESH_ChannelMessage *) msg); break; - /* Notify of a new data packet in the channel */ 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_CHANNELS: - process_get_channels (h, msg); - break; - case GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_CHANNEL: - process_show_channel (h, msg); - break; +// case GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_CHANNELS: DEPRECATED +// process_get_channels (h, msg); +// break; +// case GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_CHANNEL: DEPRECATED +// process_show_channel (h, msg); +// break; default: /* We shouldn't get any other packages, log and ignore */ LOG (GNUNET_ERROR_TYPE_WARNING, diff --git a/src/mesh/mesh_protocol_enc.h b/src/mesh/mesh_protocol_enc.h index 2f834642c..aa26a6237 100644 --- a/src/mesh/mesh_protocol_enc.h +++ b/src/mesh/mesh_protocol_enc.h @@ -287,7 +287,7 @@ struct GNUNET_MESH_ChannelCreate struct GNUNET_MESH_ChannelManage { /** - * Type: GNUNET_MESSAGE_TYPE_MESH_CHANNEL_{ACK|DESTROY} + * Type: GNUNET_MESSAGE_TYPE_MESH_CHANNEL_{ACK|NACK|DESTROY} */ struct GNUNET_MessageHeader header; -- 2.25.1