make more use of testing lib
[oweals/gnunet.git] / src / transport / transport_api_blacklist.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2010-2014, 2016 GNUnet e.V.
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18      Boston, MA 02110-1301, USA.
19 */
20
21 /**
22  * @file transport/transport_api_blacklist.c
23  * @brief library to access the blacklisting functions of the transport service
24  * @author Christian Grothoff
25  */
26 #include "platform.h"
27 #include "gnunet_util_lib.h"
28 #include "gnunet_arm_service.h"
29 #include "gnunet_hello_lib.h"
30 #include "gnunet_protocols.h"
31 #include "gnunet_transport_service.h"
32 #include "transport.h"
33
34 /**
35  * Handle for blacklisting requests.
36  */
37 struct GNUNET_TRANSPORT_Blacklist
38 {
39
40   /**
41    * Connection to transport service.
42    */
43   struct GNUNET_MQ_Handle *mq;
44
45   /**
46    * Configuration to use.
47    */
48   const struct GNUNET_CONFIGURATION_Handle *cfg;
49
50   /**
51    * Function to call for determining if a peer is allowed
52    * to communicate with us.
53    */
54   GNUNET_TRANSPORT_BlacklistCallback cb;
55
56   /**
57    * Closure for @e cb.
58    */
59   void *cb_cls;
60
61 };
62
63
64 /**
65  * Establish blacklist connection to transport service.
66  *
67  * @param br overall handle
68  */
69 static void
70 reconnect (struct GNUNET_TRANSPORT_Blacklist *br);
71
72
73 /**
74  * Handle blacklist queries.
75  *
76  * @param cls our overall handle
77  * @param bm query
78  */
79 static void
80 handle_query (void *cls,
81               const struct BlacklistMessage *bm)
82 {
83   struct GNUNET_TRANSPORT_Blacklist *br = cls;
84   struct GNUNET_MQ_Envelope *env;
85   struct BlacklistMessage *res;
86
87   GNUNET_break (0 == ntohl (bm->is_allowed));
88   env = GNUNET_MQ_msg (res,
89                        GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_REPLY);
90   res->is_allowed = htonl (br->cb (br->cb_cls,
91                                    &bm->peer));
92   res->peer = bm->peer;
93   GNUNET_MQ_send (br->mq,
94                   env);
95 }
96
97 /**
98  * Generic error handler, called with the appropriate error code and
99  * the same closure specified at the creation of the message queue.
100  * Not every message queue implementation supports an error handler.
101  *
102  * @param cls closure with the `struct GNUNET_TRANSPORT_Blacklist *`
103  * @param error error code
104  */
105 static void
106 mq_error_handler (void *cls,
107                   enum GNUNET_MQ_Error error)
108 {
109   struct GNUNET_TRANSPORT_Blacklist *br = cls;
110
111   reconnect (br);
112 }
113
114
115 /**
116  * Establish blacklist connection to transport service.
117  *
118  * @param br overall handle
119  */
120 static void
121 reconnect (struct GNUNET_TRANSPORT_Blacklist *br)
122 {
123   GNUNET_MQ_hd_fixed_size (query,
124                            GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_QUERY,
125                            struct BlacklistMessage);
126   struct GNUNET_MQ_MessageHandler handlers[] = {
127     make_query_handler (br),
128     GNUNET_MQ_handler_end ()
129   };
130   struct GNUNET_MQ_Envelope *env;
131   struct GNUNET_MessageHeader *req;
132
133   if (NULL != br->mq)
134     GNUNET_MQ_destroy (br->mq);
135   br->mq = GNUNET_CLIENT_connecT (br->cfg,
136                                   "transport",
137                                   handlers,
138                                   &mq_error_handler,
139                                   br);
140   if (NULL == br->mq)
141     return;
142   env = GNUNET_MQ_msg (req,
143                        GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_INIT);
144   GNUNET_MQ_send (br->mq,
145                   env);
146 }
147
148
149 /**
150  * Install a blacklist callback.  The service will be queried for all
151  * existing connections as well as any fresh connections to check if
152  * they are permitted.  If the blacklisting callback is unregistered,
153  * all hosts that were denied in the past will automatically be
154  * whitelisted again.  Cancelling the blacklist handle is also the
155  * only way to re-enable connections from peers that were previously
156  * blacklisted.
157  *
158  * @param cfg configuration to use
159  * @param cb callback to invoke to check if connections are allowed
160  * @param cb_cls closure for @a cb
161  * @return NULL on error, otherwise handle for cancellation
162  */
163 struct GNUNET_TRANSPORT_Blacklist *
164 GNUNET_TRANSPORT_blacklist (const struct GNUNET_CONFIGURATION_Handle *cfg,
165                             GNUNET_TRANSPORT_BlacklistCallback cb,
166                             void *cb_cls)
167 {
168   struct GNUNET_TRANSPORT_Blacklist *br;
169
170   br = GNUNET_new (struct GNUNET_TRANSPORT_Blacklist);
171   br->cfg = cfg;
172   br->cb = cb;
173   br->cb_cls = cb_cls;
174   reconnect (br);
175   if (NULL == br->mq)
176   {
177     GNUNET_free (br);
178     return NULL;
179   }
180   return br;
181 }
182
183
184 /**
185  * Abort the blacklist.  Note that this function is the only way for
186  * removing a peer from the blacklist.
187  *
188  * @param br handle of the request that is to be cancelled
189  */
190 void
191 GNUNET_TRANSPORT_blacklist_cancel (struct GNUNET_TRANSPORT_Blacklist *br)
192 {
193   GNUNET_MQ_destroy (br->mq);
194   GNUNET_free (br);
195 }
196
197
198 /* end of transport_api_blacklist.c */