diff options
author | Christian Grothoff <christian@grothoff.org> | 2010-04-18 20:23:40 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2010-04-18 20:23:40 +0000 |
commit | 541caf3dec54aaee621fed935e667f9ee423ef31 (patch) | |
tree | 6f80958e68541ce071bc557bbfc168644963c473 /src/transport/transport_api_blacklist.c | |
parent | e8bc962b2ed43e194ba124537573da236786e82c (diff) | |
download | gnunet-541caf3dec54aaee621fed935e667f9ee423ef31.tar.gz gnunet-541caf3dec54aaee621fed935e667f9ee423ef31.zip |
towards fixing blacklisting APIs and implementation
Diffstat (limited to 'src/transport/transport_api_blacklist.c')
-rw-r--r-- | src/transport/transport_api_blacklist.c | 385 |
1 files changed, 149 insertions, 236 deletions
diff --git a/src/transport/transport_api_blacklist.c b/src/transport/transport_api_blacklist.c index c8838f1b6..5d2d616e8 100644 --- a/src/transport/transport_api_blacklist.c +++ b/src/transport/transport_api_blacklist.c | |||
@@ -36,7 +36,7 @@ | |||
36 | /** | 36 | /** |
37 | * Handle for blacklisting requests. | 37 | * Handle for blacklisting requests. |
38 | */ | 38 | */ |
39 | struct GNUNET_TRANSPORT_BlacklistRequest | 39 | struct GNUNET_TRANSPORT_Blacklist |
40 | { | 40 | { |
41 | 41 | ||
42 | /** | 42 | /** |
@@ -45,342 +45,255 @@ struct GNUNET_TRANSPORT_BlacklistRequest | |||
45 | struct GNUNET_CLIENT_Connection * client; | 45 | struct GNUNET_CLIENT_Connection * client; |
46 | 46 | ||
47 | /** | 47 | /** |
48 | * Function to call when done. | 48 | * Scheduler to use. |
49 | */ | ||
50 | GNUNET_SCHEDULER_Task cont; | ||
51 | |||
52 | /** | ||
53 | * Clsoure for 'cont'. | ||
54 | */ | 49 | */ |
55 | void *cont_cls; | 50 | struct GNUNET_SCHEDULER_Handle *sched; |
56 | 51 | ||
57 | /** | 52 | /** |
58 | * Scheduler to use. | 53 | * Configuration to use. |
59 | */ | 54 | */ |
60 | struct GNUNET_SCHEDULER_Handle *sched; | 55 | const struct GNUNET_CONFIGURATION_Handle *cfg; |
61 | 56 | ||
62 | /** | 57 | /** |
63 | * Pending handle for the blacklisting request. | 58 | * Pending handle for the current request. |
64 | */ | 59 | */ |
65 | struct GNUNET_CLIENT_TransmitHandle *th; | 60 | struct GNUNET_CLIENT_TransmitHandle *th; |
66 | 61 | ||
67 | /** | 62 | /** |
68 | * How long should 'peer' be blacklisted? | 63 | * Function to call for determining if a peer is allowed |
64 | * to communicate with us. | ||
69 | */ | 65 | */ |
70 | struct GNUNET_TIME_Absolute duration; | 66 | GNUNET_TRANSPORT_BlacklistCallback cb; |
71 | 67 | ||
72 | /** | 68 | /** |
73 | * Which peer is being blacklisted? | 69 | * Closure for 'cb'. |
70 | */ | ||
71 | void *cb_cls; | ||
72 | |||
73 | /** | ||
74 | * Peer currently under consideration. | ||
74 | */ | 75 | */ |
75 | struct GNUNET_PeerIdentity peer; | 76 | struct GNUNET_PeerIdentity peer; |
76 | 77 | ||
77 | }; | 78 | }; |
78 | 79 | ||
79 | 80 | ||
80 | /** | 81 | /** |
81 | * Function called to notify a client about the socket | 82 | * Establish blacklist connection to transport service. |
82 | * begin ready to queue more data. "buf" will be | ||
83 | * NULL and "size" zero if the socket was closed for | ||
84 | * writing in the meantime. | ||
85 | * | 83 | * |
86 | * @param cls closure | 84 | * @param br overall handle |
87 | * @param size number of bytes available in buf | ||
88 | * @param buf where the callee should write the message | ||
89 | * @return number of bytes written to buf | ||
90 | */ | 85 | */ |
91 | static size_t | 86 | static void |
92 | transmit_blacklist_request (void *cls, | 87 | reconnect (struct GNUNET_TRANSPORT_Blacklist *br); |
93 | size_t size, void *buf) | ||
94 | { | ||
95 | struct GNUNET_TRANSPORT_BlacklistRequest *br = cls; | ||
96 | struct BlacklistMessage req; | ||
97 | |||
98 | if (buf == NULL) | ||
99 | { | ||
100 | GNUNET_SCHEDULER_add_continuation (br->sched, | ||
101 | br->cont, | ||
102 | br->cont_cls, | ||
103 | GNUNET_SCHEDULER_REASON_TIMEOUT); | ||
104 | GNUNET_free (br); | ||
105 | return 0; | ||
106 | } | ||
107 | req.header.size = htons (sizeof (req)); | ||
108 | req.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST); | ||
109 | req.reserved = htonl (0); | ||
110 | req.peer = br->peer; | ||
111 | req.until = GNUNET_TIME_absolute_hton (br->duration); | ||
112 | memcpy (buf, &req, sizeof (req)); | ||
113 | GNUNET_SCHEDULER_add_continuation (br->sched, | ||
114 | br->cont, | ||
115 | br->cont_cls, | ||
116 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); | ||
117 | GNUNET_free (br); | ||
118 | return sizeof (req); | ||
119 | } | ||
120 | 88 | ||
121 | 89 | ||
122 | /** | 90 | /** |
123 | * Blacklist a peer for a given period of time. All connections | 91 | * Send our reply to a blacklisting request. |
124 | * (inbound and outbound) to a peer that is blacklisted will be | ||
125 | * dropped (as soon as we learn who the connection is for). A second | ||
126 | * call to this function for the same peer overrides previous | ||
127 | * blacklisting requests. | ||
128 | * | 92 | * |
129 | * @param sched scheduler to use | 93 | * @param br our overall context |
130 | * @param cfg configuration to use | ||
131 | * @param peer identity of peer to blacklist | ||
132 | * @param duration how long to blacklist, use GNUNET_TIME_UNIT_ZERO to | ||
133 | * re-enable connections | ||
134 | * @param timeout when should this operation (trying to establish the | ||
135 | * blacklisting time out) | ||
136 | * @param cont continuation to call once the request has been processed | ||
137 | * @param cont_cls closure for cont | ||
138 | * @return NULL on error, otherwise handle for cancellation | ||
139 | */ | 94 | */ |
140 | struct GNUNET_TRANSPORT_BlacklistRequest * | 95 | static void |
141 | GNUNET_TRANSPORT_blacklist (struct GNUNET_SCHEDULER_Handle *sched, | 96 | reply (struct GNUNET_TRANSPORT_Blacklist *br); |
142 | const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
143 | const struct GNUNET_PeerIdentity *peer, | ||
144 | struct GNUNET_TIME_Relative duration, | ||
145 | struct GNUNET_TIME_Relative timeout, | ||
146 | GNUNET_SCHEDULER_Task cont, | ||
147 | void *cont_cls) | ||
148 | { | ||
149 | struct GNUNET_CLIENT_Connection * client; | ||
150 | struct GNUNET_TRANSPORT_BlacklistRequest *ret; | ||
151 | |||
152 | client = GNUNET_CLIENT_connect (sched, "transport", cfg); | ||
153 | if (NULL == client) | ||
154 | return NULL; | ||
155 | ret = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_BlacklistRequest)); | ||
156 | ret->client = client; | ||
157 | ret->peer = *peer; | ||
158 | ret->duration = GNUNET_TIME_relative_to_absolute (duration); | ||
159 | ret->sched = sched; | ||
160 | ret->cont = cont; | ||
161 | ret->cont_cls = cont_cls; | ||
162 | ret->th = GNUNET_CLIENT_notify_transmit_ready (client, | ||
163 | sizeof (struct BlacklistMessage), | ||
164 | timeout, | ||
165 | GNUNET_YES, | ||
166 | &transmit_blacklist_request, | ||
167 | ret); | ||
168 | GNUNET_assert (NULL != ret->th); | ||
169 | return ret; | ||
170 | } | ||
171 | 97 | ||
172 | 98 | ||
173 | /** | 99 | /** |
174 | * Abort transmitting the blacklist request. Note that this function | 100 | * Handle blacklist queries. |
175 | * is NOT for removing a peer from the blacklist (for that, call | ||
176 | * GNUNET_TRANSPORT_blacklist with a duration of zero). This function | ||
177 | * is only for aborting the transmission of a blacklist request | ||
178 | * (i.e. because of shutdown). | ||
179 | * | 101 | * |
180 | * @param br handle of the request that is to be cancelled | 102 | * @param cls our overall handle |
103 | * @param msg query | ||
181 | */ | 104 | */ |
182 | void | 105 | static void |
183 | GNUNET_TRANSPORT_blacklist_cancel (struct GNUNET_TRANSPORT_BlacklistRequest * br) | 106 | query_handler (void *cls, |
184 | { | 107 | const struct GNUNET_MessageHeader *msg) |
185 | GNUNET_CLIENT_notify_transmit_ready_cancel (br->th); | ||
186 | GNUNET_free (br); | ||
187 | } | ||
188 | |||
189 | |||
190 | /** | ||
191 | * Handle for blacklist notifications. | ||
192 | */ | ||
193 | struct GNUNET_TRANSPORT_BlacklistNotification | ||
194 | { | 108 | { |
195 | 109 | struct GNUNET_TRANSPORT_Blacklist *br = cls; | |
196 | /** | 110 | const struct BlacklistMessage *bm; |
197 | * Function to call whenever there is a change. | ||
198 | */ | ||
199 | GNUNET_TRANSPORT_BlacklistCallback notify; | ||
200 | |||
201 | /** | ||
202 | * Closure for notify. | ||
203 | */ | ||
204 | void *notify_cls; | ||
205 | |||
206 | /** | ||
207 | * Scheduler to use. | ||
208 | */ | ||
209 | struct GNUNET_SCHEDULER_Handle *sched; | ||
210 | |||
211 | /** | ||
212 | * Configuration to use. | ||
213 | */ | ||
214 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
215 | 111 | ||
216 | /** | 112 | if ( (ntohs(msg->size) != sizeof (struct BlacklistMessage)) || |
217 | * Connection to transport service. | 113 | (ntohs(msg->type) != GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_QUERY) ) |
218 | */ | 114 | { |
219 | struct GNUNET_CLIENT_Connection * client; | 115 | reconnect (br); |
220 | 116 | return; | |
221 | /** | 117 | } |
222 | * Pending handle for the notification request. | 118 | bm = (const struct BlacklistMessage *)msg; |
223 | */ | 119 | GNUNET_break (0 == ntohl (bm->is_allowed)); |
224 | struct GNUNET_CLIENT_TransmitHandle *th; | 120 | br->peer = bm->peer; |
225 | }; | 121 | reply (br); |
122 | } | ||
226 | 123 | ||
227 | 124 | ||
228 | /** | 125 | /** |
229 | * Send a request to receive blacklisting notifications | 126 | * Receive blacklist queries from transport service. |
230 | * | 127 | * |
231 | * @param bn context to initialize | 128 | * @param br overall handle |
232 | */ | 129 | */ |
233 | static void | 130 | static void |
234 | request_notifications (struct GNUNET_TRANSPORT_BlacklistNotification *bn); | 131 | receive (struct GNUNET_TRANSPORT_Blacklist *br) |
132 | { | ||
133 | GNUNET_CLIENT_receive (br->client, | ||
134 | &query_handler, | ||
135 | br, | ||
136 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
137 | } | ||
235 | 138 | ||
236 | 139 | ||
237 | /** | 140 | /** |
238 | * Destroy the existing connection to the transport service and | 141 | * Transmit the blacklist initialization request to the service. |
239 | * setup a new one (the existing one had serious problems). | 142 | * |
240 | * | 143 | * @param cls closure (struct GNUNET_TRANSPORT_Blacklist*) |
241 | * @param bn context to re-initialize | 144 | * @param size number of bytes available in buf |
145 | * @param buf where the callee should write the message | ||
146 | * @return number of bytes written to buf | ||
242 | */ | 147 | */ |
243 | static void | 148 | static size_t |
244 | retry_get_notifications (struct GNUNET_TRANSPORT_BlacklistNotification *bn) | 149 | transmit_blacklist_init (void *cls, |
150 | size_t size, void *buf) | ||
245 | { | 151 | { |
246 | GNUNET_CLIENT_disconnect (bn->client, GNUNET_NO); | 152 | struct GNUNET_TRANSPORT_Blacklist *br = cls; |
247 | bn->client = GNUNET_CLIENT_connect (bn->sched, "transport", bn->cfg); | 153 | struct GNUNET_MessageHeader req; |
248 | request_notifications (bn); | 154 | |
155 | if (buf == NULL) | ||
156 | { | ||
157 | reconnect (br); | ||
158 | return 0; | ||
159 | } | ||
160 | req.size = htons (sizeof (struct GNUNET_MessageHeader)); | ||
161 | req.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_INIT); | ||
162 | memcpy (buf, &req, sizeof (req)); | ||
163 | receive (br); | ||
164 | return sizeof (req); | ||
249 | } | 165 | } |
250 | 166 | ||
251 | 167 | ||
252 | /** | 168 | /** |
253 | * Function called whenever we get a blacklisting notification. | 169 | * Establish blacklist connection to transport service. |
254 | * Pass it on to the callback and wait for more. | ||
255 | * | 170 | * |
256 | * @param cls our 'struct GNUNET_TRANSPORT_BlacklistNotification *' | 171 | * @param br overall handle |
257 | * @param msg the blacklisting notification, NULL on error | ||
258 | */ | 172 | */ |
259 | static void | 173 | static void |
260 | recv_blacklist_info (void *cls, | 174 | reconnect (struct GNUNET_TRANSPORT_Blacklist *br) |
261 | const struct GNUNET_MessageHeader *msg) | ||
262 | { | 175 | { |
263 | struct GNUNET_TRANSPORT_BlacklistNotification *bn = cls; | 176 | if (br->client != NULL) |
264 | const struct BlacklistMessage *req; | 177 | GNUNET_CLIENT_disconnect (br->client, GNUNET_NO); |
265 | 178 | br->client = GNUNET_CLIENT_connect (br->sched, | |
266 | if ( (msg == NULL) || | 179 | "transport", |
267 | (sizeof(struct BlacklistMessage) != ntohs(msg->size)) || | 180 | br->cfg); |
268 | (GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST != ntohs(msg->type)) ) | 181 | br->th = GNUNET_CLIENT_notify_transmit_ready (br->client, |
269 | { | 182 | sizeof (struct GNUNET_MessageHeader), |
270 | retry_get_notifications (bn); | 183 | GNUNET_TIME_UNIT_FOREVER_REL, |
271 | return; | 184 | GNUNET_YES, |
272 | } | 185 | &transmit_blacklist_init, |
273 | req = (const struct BlacklistMessage*) msg; | 186 | br); |
274 | bn->notify (bn->notify_cls, | ||
275 | &req->peer, | ||
276 | GNUNET_TIME_absolute_ntoh (req->until)); | ||
277 | GNUNET_CLIENT_receive (bn->client, | ||
278 | &recv_blacklist_info, | ||
279 | bn, | ||
280 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
281 | } | 187 | } |
282 | 188 | ||
283 | 189 | ||
284 | /** | 190 | /** |
285 | * Function called to notify a client about the socket | 191 | * Transmit the blacklist response to the service. |
286 | * begin ready to queue more data. "buf" will be | ||
287 | * NULL and "size" zero if the socket was closed for | ||
288 | * writing in the meantime. | ||
289 | * | 192 | * |
290 | * @param cls closure | 193 | * @param cls closure (struct GNUNET_TRANSPORT_Blacklist*) |
291 | * @param size number of bytes available in buf | 194 | * @param size number of bytes available in buf |
292 | * @param buf where the callee should write the message | 195 | * @param buf where the callee should write the message |
293 | * @return number of bytes written to buf | 196 | * @return number of bytes written to buf |
294 | */ | 197 | */ |
295 | static size_t | 198 | static size_t |
296 | transmit_notify_request (void *cls, | 199 | transmit_blacklist_reply (void *cls, |
297 | size_t size, void *buf) | 200 | size_t size, void *buf) |
298 | { | 201 | { |
299 | struct GNUNET_TRANSPORT_BlacklistNotification *bn = cls; | 202 | struct GNUNET_TRANSPORT_Blacklist *br = cls; |
300 | struct GNUNET_MessageHeader hdr; | 203 | struct BlacklistMessage req; |
301 | 204 | ||
302 | bn->th = NULL; | ||
303 | if (buf == NULL) | 205 | if (buf == NULL) |
304 | { | 206 | { |
305 | retry_get_notifications (bn); | 207 | reconnect (br); |
306 | return 0; | 208 | return 0; |
307 | } | 209 | } |
308 | GNUNET_assert (size >= sizeof(hdr)); | 210 | req.header.size = htons (sizeof (req)); |
309 | hdr.size = htons (sizeof (hdr)); | 211 | req.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_REPLY); |
310 | hdr.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_NOTIFY); | 212 | req.is_allowed = htonl (br->cb (br->cb_cls, &br->peer)); |
311 | memcpy (buf, &hdr, sizeof(hdr)); | 213 | req.peer = br->peer; |
312 | return sizeof(hdr); | 214 | memcpy (buf, &req, sizeof (req)); |
215 | receive (br); | ||
216 | return sizeof (req); | ||
313 | } | 217 | } |
314 | 218 | ||
315 | 219 | ||
316 | /** | 220 | /** |
317 | * Send a request to receive blacklisting notifications | 221 | * Send our reply to a blacklisting request. |
318 | * | 222 | * |
319 | * @param bn context to initialize | 223 | * @param br our overall context |
320 | */ | 224 | */ |
321 | static void | 225 | static void |
322 | request_notifications (struct GNUNET_TRANSPORT_BlacklistNotification *bn) | 226 | reply (struct GNUNET_TRANSPORT_Blacklist *br) |
323 | { | 227 | { |
324 | GNUNET_assert (bn->client != NULL); | 228 | br->th = GNUNET_CLIENT_notify_transmit_ready (br->client, |
325 | bn->th = GNUNET_CLIENT_notify_transmit_ready (bn->client, | 229 | sizeof (struct BlacklistMessage), |
326 | sizeof (struct GNUNET_MessageHeader), | ||
327 | GNUNET_TIME_UNIT_FOREVER_REL, | 230 | GNUNET_TIME_UNIT_FOREVER_REL, |
328 | GNUNET_YES, | 231 | GNUNET_NO, |
329 | &transmit_notify_request, | 232 | &transmit_blacklist_reply, |
330 | bn); | 233 | br); |
331 | GNUNET_assert (bn->th != NULL); | 234 | if (br->th == NULL) |
332 | GNUNET_CLIENT_receive (bn->client, | 235 | { |
333 | &recv_blacklist_info, | 236 | reconnect (br); |
334 | bn, | 237 | return; |
335 | GNUNET_TIME_UNIT_FOREVER_REL); | 238 | } |
336 | } | 239 | } |
337 | 240 | ||
338 | 241 | ||
339 | /** | 242 | /** |
340 | * Call a function whenever a peer's blacklisting status changes. | 243 | * Install a blacklist callback. The service will be queried for all |
244 | * existing connections as well as any fresh connections to check if | ||
245 | * they are permitted. If the blacklisting callback is unregistered, | ||
246 | * all hosts that were denied in the past will automatically be | ||
247 | * whitelisted again. Cancelling the blacklist handle is also the | ||
248 | * only way to re-enable connections from peers that were previously | ||
249 | * blacklisted. | ||
341 | * | 250 | * |
342 | * @param sched scheduler to use | 251 | * @param sched scheduler to use |
343 | * @param cfg configuration to use | 252 | * @param cfg configuration to use |
344 | * @param bc function to call on status changes | 253 | * @param cb callback to invoke to check if connections are allowed |
345 | * @param bc_cls closure for bc | 254 | * @param cb_cls closure for cb |
346 | * @return NULL on error, otherwise handle for cancellation | 255 | * @return NULL on error, otherwise handle for cancellation |
347 | */ | 256 | */ |
348 | struct GNUNET_TRANSPORT_BlacklistNotification * | 257 | struct GNUNET_TRANSPORT_Blacklist * |
349 | GNUNET_TRANSPORT_blacklist_notify (struct GNUNET_SCHEDULER_Handle *sched, | 258 | GNUNET_TRANSPORT_blacklist (struct GNUNET_SCHEDULER_Handle *sched, |
350 | const struct GNUNET_CONFIGURATION_Handle *cfg, | 259 | const struct GNUNET_CONFIGURATION_Handle *cfg, |
351 | GNUNET_TRANSPORT_BlacklistCallback bc, | 260 | GNUNET_TRANSPORT_BlacklistCallback cb, |
352 | void *bc_cls) | 261 | void *cb_cls) |
353 | { | 262 | { |
354 | struct GNUNET_TRANSPORT_BlacklistNotification *ret; | ||
355 | struct GNUNET_CLIENT_Connection * client; | 263 | struct GNUNET_CLIENT_Connection * client; |
264 | struct GNUNET_TRANSPORT_Blacklist *ret; | ||
356 | 265 | ||
357 | client = GNUNET_CLIENT_connect (sched, "transport", cfg); | 266 | client = GNUNET_CLIENT_connect (sched, "transport", cfg); |
358 | if (NULL == client) | 267 | if (NULL == client) |
359 | return NULL; | 268 | return NULL; |
360 | ret = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_BlacklistNotification)); | 269 | ret = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_Blacklist)); |
361 | ret->client = client; | 270 | ret->client = client; |
362 | ret->sched = sched; | 271 | ret->sched = sched; |
363 | ret->cfg = cfg; | 272 | ret->cfg = cfg; |
364 | ret->notify = bc; | 273 | ret->th = GNUNET_CLIENT_notify_transmit_ready (client, |
365 | ret->notify_cls = bc_cls; | 274 | sizeof (struct GNUNET_MessageHeader), |
366 | request_notifications (ret); | 275 | GNUNET_TIME_UNIT_FOREVER_REL, |
276 | GNUNET_YES, | ||
277 | &transmit_blacklist_init, | ||
278 | ret); | ||
367 | return ret; | 279 | return ret; |
368 | } | 280 | } |
369 | 281 | ||
370 | 282 | ||
371 | /** | 283 | /** |
372 | * Stop calling the notification callback associated with | 284 | * Abort the blacklist. Note that this function is the only way for |
373 | * the given blacklist notification. | 285 | * removing a peer from the blacklist. |
374 | * | 286 | * |
375 | * @param bn handle of the request that is to be cancelled | 287 | * @param br handle of the request that is to be cancelled |
376 | */ | 288 | */ |
377 | void | 289 | void |
378 | GNUNET_TRANSPORT_blacklist_notify_cancel (struct GNUNET_TRANSPORT_BlacklistNotification * bn) | 290 | GNUNET_TRANSPORT_blacklist_cancel (struct GNUNET_TRANSPORT_Blacklist *br) |
379 | { | 291 | { |
380 | if (bn->th != NULL) | 292 | if (br->th != NULL) |
381 | GNUNET_CLIENT_notify_transmit_ready_cancel (bn->th); | 293 | GNUNET_CLIENT_notify_transmit_ready_cancel (br->th); |
382 | GNUNET_CLIENT_disconnect (bn->client, GNUNET_NO); | 294 | GNUNET_CLIENT_disconnect (br->client, GNUNET_NO); |
383 | GNUNET_free (bn); | 295 | GNUNET_free (br); |
384 | } | 296 | } |
385 | 297 | ||
298 | |||
386 | /* end of transport_api_blacklist.c */ | 299 | /* end of transport_api_blacklist.c */ |