diff options
author | Bertrand Marc <beberking@gmail.com> | 2012-05-02 21:43:37 +0200 |
---|---|---|
committer | Bertrand Marc <beberking@gmail.com> | 2012-05-02 21:43:37 +0200 |
commit | 2b81464a43485fcc8ce079fafdee7b7a171835f4 (patch) | |
tree | 394774c0f735199b57d51a2d3840356317853fe1 /src/transport/transport_api_blacklist.c |
Imported Upstream version 0.9.2upstream/0.9.2
Diffstat (limited to 'src/transport/transport_api_blacklist.c')
-rw-r--r-- | src/transport/transport_api_blacklist.c | 296 |
1 files changed, 296 insertions, 0 deletions
diff --git a/src/transport/transport_api_blacklist.c b/src/transport/transport_api_blacklist.c new file mode 100644 index 0000000..be52623 --- /dev/null +++ b/src/transport/transport_api_blacklist.c @@ -0,0 +1,296 @@ +/* + This file is part of GNUnet. + (C) 2010 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/** + * @file transport/transport_api_blacklist.c + * @brief library to access the blacklisting functions of the transport service + * @author Christian Grothoff + */ +#include "platform.h" +#include "gnunet_client_lib.h" +#include "gnunet_arm_service.h" +#include "gnunet_hello_lib.h" +#include "gnunet_protocols.h" +#include "gnunet_server_lib.h" +#include "gnunet_time_lib.h" +#include "gnunet_transport_service.h" +#include "transport.h" + +/** + * Handle for blacklisting requests. + */ +struct GNUNET_TRANSPORT_Blacklist +{ + + /** + * Connection to transport service. + */ + struct GNUNET_CLIENT_Connection *client; + + /** + * Configuration to use. + */ + const struct GNUNET_CONFIGURATION_Handle *cfg; + + /** + * Pending handle for the current request. + */ + struct GNUNET_CLIENT_TransmitHandle *th; + + /** + * Function to call for determining if a peer is allowed + * to communicate with us. + */ + GNUNET_TRANSPORT_BlacklistCallback cb; + + /** + * Closure for 'cb'. + */ + void *cb_cls; + + /** + * Peer currently under consideration. + */ + struct GNUNET_PeerIdentity peer; + +}; + + +/** + * Establish blacklist connection to transport service. + * + * @param br overall handle + */ +static void +reconnect (struct GNUNET_TRANSPORT_Blacklist *br); + + +/** + * Send our reply to a blacklisting request. + * + * @param br our overall context + */ +static void +reply (struct GNUNET_TRANSPORT_Blacklist *br); + + +/** + * Handle blacklist queries. + * + * @param cls our overall handle + * @param msg query + */ +static void +query_handler (void *cls, const struct GNUNET_MessageHeader *msg) +{ + struct GNUNET_TRANSPORT_Blacklist *br = cls; + const struct BlacklistMessage *bm; + + GNUNET_assert (br != NULL); + if ((NULL == msg) || + (ntohs (msg->size) != sizeof (struct BlacklistMessage)) || + (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_QUERY)) + { + reconnect (br); + return; + } + bm = (const struct BlacklistMessage *) msg; + GNUNET_break (0 == ntohl (bm->is_allowed)); + br->peer = bm->peer; + reply (br); +} + + +/** + * Receive blacklist queries from transport service. + * + * @param br overall handle + */ +static void +receive (struct GNUNET_TRANSPORT_Blacklist *br) +{ + GNUNET_CLIENT_receive (br->client, &query_handler, br, + GNUNET_TIME_UNIT_FOREVER_REL); +} + + +/** + * Transmit the blacklist initialization request to the service. + * + * @param cls closure (struct GNUNET_TRANSPORT_Blacklist*) + * @param size number of bytes available in buf + * @param buf where the callee should write the message + * @return number of bytes written to buf + */ +static size_t +transmit_blacklist_init (void *cls, size_t size, void *buf) +{ + struct GNUNET_TRANSPORT_Blacklist *br = cls; + struct GNUNET_MessageHeader req; + + br->th = NULL; + if (buf == NULL) + { + reconnect (br); + return 0; + } + req.size = htons (sizeof (struct GNUNET_MessageHeader)); + req.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_INIT); + memcpy (buf, &req, sizeof (req)); + receive (br); + return sizeof (req); +} + + +/** + * Establish blacklist connection to transport service. + * + * @param br overall handle + */ +static void +reconnect (struct GNUNET_TRANSPORT_Blacklist *br) +{ + if (br->client != NULL) + GNUNET_CLIENT_disconnect (br->client, GNUNET_NO); + br->client = GNUNET_CLIENT_connect ("transport", br->cfg); + GNUNET_assert (br->client != NULL); + br->th = + GNUNET_CLIENT_notify_transmit_ready (br->client, + sizeof (struct GNUNET_MessageHeader), + GNUNET_TIME_UNIT_FOREVER_REL, + GNUNET_YES, &transmit_blacklist_init, + br); +} + + +/** + * Transmit the blacklist response to the service. + * + * @param cls closure (struct GNUNET_TRANSPORT_Blacklist*) + * @param size number of bytes available in buf + * @param buf where the callee should write the message + * @return number of bytes written to buf + */ +static size_t +transmit_blacklist_reply (void *cls, size_t size, void *buf) +{ + struct GNUNET_TRANSPORT_Blacklist *br = cls; + struct BlacklistMessage req; + + br->th = NULL; + if (buf == NULL) + { + reconnect (br); + return 0; + } + req.header.size = htons (sizeof (req)); + req.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_REPLY); + req.is_allowed = htonl (br->cb (br->cb_cls, &br->peer)); + req.peer = br->peer; + memcpy (buf, &req, sizeof (req)); + br->th = NULL; + receive (br); + return sizeof (req); +} + + +/** + * Send our reply to a blacklisting request. + * + * @param br our overall context + */ +static void +reply (struct GNUNET_TRANSPORT_Blacklist *br) +{ + GNUNET_assert (br->th == NULL); + br->th = + GNUNET_CLIENT_notify_transmit_ready (br->client, + sizeof (struct BlacklistMessage), + GNUNET_TIME_UNIT_FOREVER_REL, + GNUNET_NO, &transmit_blacklist_reply, + br); + if (br->th == NULL) + { + reconnect (br); + return; + } +} + + +/** + * Install a blacklist callback. The service will be queried for all + * existing connections as well as any fresh connections to check if + * they are permitted. If the blacklisting callback is unregistered, + * all hosts that were denied in the past will automatically be + * whitelisted again. Cancelling the blacklist handle is also the + * only way to re-enable connections from peers that were previously + * blacklisted. + * + * @param cfg configuration to use + * @param cb callback to invoke to check if connections are allowed + * @param cb_cls closure for cb + * @return NULL on error, otherwise handle for cancellation + */ +struct GNUNET_TRANSPORT_Blacklist * +GNUNET_TRANSPORT_blacklist (const struct GNUNET_CONFIGURATION_Handle *cfg, + GNUNET_TRANSPORT_BlacklistCallback cb, void *cb_cls) +{ + struct GNUNET_CLIENT_Connection *client; + struct GNUNET_TRANSPORT_Blacklist *ret; + + client = GNUNET_CLIENT_connect ("transport", cfg); + if (NULL == client) + return NULL; + ret = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_Blacklist)); + ret->client = client; + ret->cfg = cfg; + ret->cb = cb; + ret->cb_cls = cb_cls; + GNUNET_assert (ret->th == NULL); + ret->th = + GNUNET_CLIENT_notify_transmit_ready (client, + sizeof (struct GNUNET_MessageHeader), + GNUNET_TIME_UNIT_FOREVER_REL, + GNUNET_YES, &transmit_blacklist_init, + ret); + return ret; +} + + +/** + * Abort the blacklist. Note that this function is the only way for + * removing a peer from the blacklist. + * + * @param br handle of the request that is to be cancelled + */ +void +GNUNET_TRANSPORT_blacklist_cancel (struct GNUNET_TRANSPORT_Blacklist *br) +{ + if (br->th != NULL) + { + GNUNET_CLIENT_notify_transmit_ready_cancel (br->th); + br->th = NULL; + } + GNUNET_CLIENT_disconnect (br->client, GNUNET_NO); + GNUNET_free (br); +} + + +/* end of transport_api_blacklist.c */ |