* PEERINFO: [CG]
- trust: need *fast* way to check/update trust in peers
(async peerinfo would not be right; certainly not with the current API)
+* TRANSPORT: [CG]
+ - need to implement and test new blacklisting code (server-side only, client API exists)
* TOPOLOGY: [CG]
- - If the topology daemon crashes, peers that were put on the
- blacklist with transport will never be removed from it (until
- transport service dies); we should use the blacklist notification
- API to learn about the exact set of blacklisted peers at all times
- (FIXME: the transport_api implementation of blacklisting
- also does not work nicely for this since it won't let us know about
- disconnect-reconnect events and the implicit whitelisting
- that might happen here; that's not so bad since we will
- re-blacklist on pre-connect attempts anyway, so this is
- a minor issue; OTOH, we might want to be more explicit about
- allowing/forbidding connects on pre-connect to avoid
- entering connect attempts to just be blacklisted shortly afterwards).
- - needs more testing (especially F2F topology)
+ - needs more testing (especially F2F topology) -- need transport blacklisting to be implemented first!
* FS: [CG]
- support recursive download even if filename is NULL and we hence
do not generate files on disk (use temp_filename)
* transmitted to the client.
*/
#define GNUNET_CORE_OPTION_NOTHING 0
-#define GNUNET_CORE_OPTION_SEND_PRE_CONNECT 1
-#define GNUNET_CORE_OPTION_SEND_CONNECT 2
-#define GNUNET_CORE_OPTION_SEND_DISCONNECT 4
-#define GNUNET_CORE_OPTION_SEND_FULL_INBOUND 8
-#define GNUNET_CORE_OPTION_SEND_HDR_INBOUND 16
-#define GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND 32
-#define GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND 64
+#define GNUNET_CORE_OPTION_SEND_CONNECT 1
+#define GNUNET_CORE_OPTION_SEND_DISCONNECT 2
+#define GNUNET_CORE_OPTION_SEND_FULL_INBOUND 4
+#define GNUNET_CORE_OPTION_SEND_HDR_INBOUND 8
+#define GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND 16
+#define GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND 32
/**
*/
GNUNET_CORE_StartupCallback init;
- /**
- * Function to call whenever we're notified about a peer connecting
- * (pre-connects, no session key exchange yet).
- */
- GNUNET_CORE_ConnectEventHandler pre_connects;
-
/**
* Function to call whenever we're notified about a peer connecting.
*/
#endif
switch (ntohs (msg->type))
{
- case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_PRE_CONNECT:
- if (NULL == h->pre_connects)
- {
- GNUNET_break (0);
- break;
- }
- if (msize != sizeof (struct ConnectNotifyMessage))
- {
- GNUNET_break (0);
- break;
- }
- cnm = (const struct ConnectNotifyMessage *) msg;
- h->pre_connects (h->cls,
- &cnm->peer,
- GNUNET_TIME_relative_ntoh (cnm->latency),
- ntohl (cnm->distance));
- break;
case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT:
if (NULL == h->connects)
{
init->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_INIT);
init->header.size = htons (msize);
opt = GNUNET_CORE_OPTION_NOTHING;
- if (h->pre_connects != NULL)
- opt |= GNUNET_CORE_OPTION_SEND_PRE_CONNECT;
if (h->connects != NULL)
opt |= GNUNET_CORE_OPTION_SEND_CONNECT;
if (h->disconnects != NULL)
* @param cls closure for the various callbacks that follow (including handlers in the handlers array)
* @param init callback to call on timeout or once we have successfully
* connected to the core service; note that timeout is only meaningful if init is not NULL
- * @param pre_connects function to call on peer pre-connect (no session key yet), can be NULL
* @param connects function to call on peer connect, can be NULL
* @param disconnects function to call on peer disconnect / timeout, can be NULL
* @param inbound_notify function to call for all inbound messages, can be NULL
struct GNUNET_TIME_Relative timeout,
void *cls,
GNUNET_CORE_StartupCallback init,
- GNUNET_CORE_ConnectEventHandler pre_connects,
GNUNET_CORE_ConnectEventHandler connects,
GNUNET_CORE_DisconnectEventHandler disconnects,
GNUNET_CORE_MessageCallback inbound_notify,
h->cfg = cfg;
h->cls = cls;
h->init = init;
- h->pre_connects = pre_connects;
h->connects = connects;
h->disconnects = disconnects;
h->inbound_notify = inbound_notify;
(n->status != PEER_STATE_KEY_CONFIRMED))
{
GNUNET_break_op (0);
- /* blacklist briefly (?); might help recover (?) */
- GNUNET_TRANSPORT_blacklist (sched, cfg,
- &n->peer,
- GNUNET_TIME_UNIT_SECONDS,
- GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS,
- 5),
- NULL, NULL);
return;
}
handle_encrypted_message (n, (const struct EncryptedMessage *) message);
unsigned int distance)
{
struct Neighbour *n;
- struct ConnectNotifyMessage cnm;
if (0 == memcmp (peer, &my_identity, sizeof (struct GNUNET_PeerIdentity)))
{
"Received connection from `%4s'.\n",
GNUNET_i2s (&n->peer));
#endif
- cnm.header.size = htons (sizeof (struct ConnectNotifyMessage));
- cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_PRE_CONNECT);
- cnm.distance = htonl (n->last_distance);
- cnm.latency = GNUNET_TIME_relative_hton (n->last_latency);
- cnm.peer = *peer;
- send_to_all_clients (&cnm.header, GNUNET_YES, GNUNET_CORE_OPTION_SEND_PRE_CONNECT);
GNUNET_TRANSPORT_set_quota (transport,
&n->peer,
n->bw_in,
p2.cfg,
TIMEOUT,
&p2,
- &init_notify,
- NULL,
+ &init_notify,
&connect_notify,
&disconnect_notify,
&inbound_notify,
TIMEOUT,
&p1,
&init_notify,
- NULL,
- &connect_notify,
+ &connect_notify,
&disconnect_notify,
&inbound_notify,
GNUNET_YES, &outbound_notify, GNUNET_YES, handlers);
p2.cfg,
TIMEOUT,
&p2,
- &init_notify,
- NULL,
+ &init_notify,
&connect_notify,
&disconnect_notify,
&inbound_notify,
TIMEOUT,
&p1,
&init_notify,
- NULL,
- &connect_notify,
+ &connect_notify,
&disconnect_notify,
&inbound_notify,
GNUNET_YES, &outbound_notify, GNUNET_YES, handlers);
GNUNET_TIME_UNIT_FOREVER_REL,
NULL,
NULL,
- NULL,
&peer_connect_handler,
&peer_disconnect_handler,
NULL, GNUNET_NO,
GNUNET_TIME_UNIT_FOREVER_REL,
NULL,
&core_init,
- NULL, &connect_handler, &disconnect_handler,
+ &connect_handler, &disconnect_handler,
NULL, GNUNET_NO,
NULL, GNUNET_NO,
learning? learn_handlers : no_learn_handlers);
/**
- * Method called whenever a given peer either connects.
+ * Method called whenever a given peer connects.
*
* @param cls closure
* @param peer peer identity this notification is about
* @param cls closure for the various callbacks that follow (including handlers in the handlers array)
* @param init callback to call on timeout or once we have successfully
* connected to the core service; note that timeout is only meaningful if init is not NULL
- * @param pre_connects function to call on peer pre-connect (no session key yet), can be NULL
* @param connects function to call on peer connect, can be NULL
* @param disconnects function to call on peer disconnect / timeout, can be NULL
* @param inbound_notify function to call for all inbound messages, can be NULL
struct GNUNET_TIME_Relative timeout,
void *cls,
GNUNET_CORE_StartupCallback init,
- GNUNET_CORE_ConnectEventHandler pre_connects,
GNUNET_CORE_ConnectEventHandler connects,
GNUNET_CORE_DisconnectEventHandler disconnects,
GNUNET_CORE_MessageCallback inbound_notify,
#define GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_REPLY 28
/**
- * Change in blacklisting status of a peer.
+ * Register a client that wants to do blacklisting.
*/
-#define GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST 29
+#define GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_INIT 29
/**
- * Request to transport to notify us about any blacklisting status
- * changes on this connection (and to immediately send all
- * active blacklist entries).
+ * Query to a blacklisting client (is this peer blacklisted)?
*/
-#define GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_NOTIFY 30
+#define GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_QUERY 30
+
+/**
+ * Reply from blacklisting client (answer to blacklist query).
+ */
+#define GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_REPLY 31
/**
* Transport PING message
/**
- * Handle for blacklisting requests.
+ * Handle for blacklisting peers.
*/
-struct GNUNET_TRANSPORT_BlacklistRequest;
+struct GNUNET_TRANSPORT_Blacklist;
/**
- * Blacklist a peer for a given period of time. All connections
- * (inbound and outbound) to a peer that is blacklisted will be
- * dropped (as soon as we learn who the connection is for). A second
- * call to this function for the same peer overrides previous
- * blacklisting requests.
- *
- * @param sched scheduler to use
- * @param cfg configuration to use
- * @param peer identity of peer to blacklist
- * @param duration how long to blacklist, use GNUNET_TIME_UNIT_ZERO to
- * re-enable connections
- * @param timeout when should this operation (trying to establish the
- * blacklisting time out)
- * @param cont continuation to call once the request has been processed
- * @param cont_cls closure for cont
- * @return NULL on error, otherwise handle for cancellation
- */
-struct GNUNET_TRANSPORT_BlacklistRequest *
-GNUNET_TRANSPORT_blacklist (struct GNUNET_SCHEDULER_Handle *sched,
- const struct GNUNET_CONFIGURATION_Handle *cfg,
- const struct GNUNET_PeerIdentity *peer,
- struct GNUNET_TIME_Relative duration,
- struct GNUNET_TIME_Relative timeout,
- GNUNET_SCHEDULER_Task cont,
- void *cont_cls);
-
-
-/**
- * Abort transmitting the blacklist request. Note that this function
- * is NOT for removing a peer from the blacklist (for that, call
- * GNUNET_TRANSPORT_blacklist with a duration of zero). This function
- * is only for aborting the transmission of a blacklist request
- * (i.e. because of shutdown).
- *
- * @param br handle of the request that is to be cancelled
- */
-void
-GNUNET_TRANSPORT_blacklist_cancel (struct GNUNET_TRANSPORT_BlacklistRequest * br);
-
-
-/**
- * Handle for blacklist notifications.
- */
-struct GNUNET_TRANSPORT_BlacklistNotification;
-
-
-/**
- * Signature of function called whenever the blacklist status of
- * a peer changes. This includes changes to the duration of the
- * blacklist status as well as the expiration of an existing
- * blacklist status.
+ * Function that decides if a connection is acceptable or not.
*
* @param cls closure
- * @param peer identity of peer with the change
- * @param until GNUNET_TIME_UNIT_ZERO_ABS if the peer is no
- * longer blacklisted, otherwise the time at
- * which the current blacklisting will expire
+ * @param pid peer to approve or disapproave
+ * @return GNUNET_OK if the connection is allowed
*/
-typedef void (*GNUNET_TRANSPORT_BlacklistCallback)(void *cls,
- const struct GNUNET_PeerIdentity *peer,
- struct GNUNET_TIME_Absolute until);
+typedef int (*GNUNET_TRANSPORT_BlacklistCallback)(void *cls,
+ const struct GNUNET_PeerIdentity *pid);
/**
- * Call a function whenever a peer's blacklisting status changes.
+ * 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 sched scheduler to use
* @param cfg configuration to use
- * @param bc function to call on status changes
- * @param bc_cls closure for bc
+ * @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_BlacklistNotification *
-GNUNET_TRANSPORT_blacklist_notify (struct GNUNET_SCHEDULER_Handle *sched,
- const struct GNUNET_CONFIGURATION_Handle *cfg,
- GNUNET_TRANSPORT_BlacklistCallback bc,
- void *bc_cls);
+struct GNUNET_TRANSPORT_Blacklist *
+GNUNET_TRANSPORT_blacklist (struct GNUNET_SCHEDULER_Handle *sched,
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ GNUNET_TRANSPORT_BlacklistCallback cb,
+ void *cb_cls);
/**
- * Stop calling the notification callback associated with
- * the given blacklist notification.
+ * Abort the blacklist. Note that this function is the only way for
+ * removing a peer from the blacklist.
*
- * @param bn handle of the request that is to be cancelled
+ * @param br handle of the request that is to be cancelled
*/
void
-GNUNET_TRANSPORT_blacklist_notify_cancel (struct GNUNET_TRANSPORT_BlacklistNotification * bn);
+GNUNET_TRANSPORT_blacklist_cancel (struct GNUNET_TRANSPORT_Blacklist *br);
temp_daemon->cfg,
TIMEOUT,
new_connection,
- &init_notify,
- NULL,
+ &init_notify,
NULL,
NULL,
NULL,
ARM_START_WAIT,
d,
&testing_init,
- NULL, NULL, NULL,
+ NULL, NULL,
NULL, GNUNET_NO,
NULL, GNUNET_NO, no_handlers);
break;
timeout,
ctx,
NULL,
- NULL, &connect_notify, NULL,
+ &connect_notify, NULL,
NULL, GNUNET_NO,
NULL, GNUNET_NO, no_handlers);
if (ctx->d1core == NULL)
*/
struct GNUNET_CONTAINER_BloomFilter *filter;
- /**
- * Our request handle for *whitelisting* this peer (NULL if
- * no whitelisting request is pending).
- */
- struct GNUNET_TRANSPORT_BlacklistRequest *wh;
-
/**
* Until what time should we not try to connect again
* to this peer?
*/
int is_connected;
- /**
- * Are we currently blocking this peer (via blacklist)?
- */
- int is_blocked;
-
-};
-
-
-/**
- * Entry in linked list of active 'disconnect' requests that we have issued.
- */
-struct DisconnectList
-{
- /**
- * This is a doubly-linked list.
- */
- struct DisconnectList *next;
-
- /**
- * This is a doubly-linked list.
- */
- struct DisconnectList *prev;
-
- /**
- * Our request handle.
- */
- struct GNUNET_TRANSPORT_BlacklistRequest *rh;
-
- /**
- * Peer we tried to disconnect.
- */
- struct GNUNET_PeerIdentity peer;
-
};
*/
static struct GNUNET_STATISTICS_Handle *stats;
+/**
+ * Blacklist (NULL if we have none).
+ */
+static struct GNUNET_TRANSPORT_Blacklist *blacklist;
+
/**
* Flag to disallow non-friend connections (pure F2F mode).
*/
*/
static int autoconnect;
-/**
- * Head of doubly-linked list of active 'disconnect' requests that we have issued.
- */
-static struct DisconnectList *disconnect_head;
-
-/**
- * Head of doubly-linked list of active 'disconnect' requests that we have issued.
- */
-static struct DisconnectList *disconnect_tail;
-
/**
- * Function called once our request to 'disconnect' a peer
- * has completed.
+ * Function that decides if a connection is acceptable or not.
+ * If we have a blacklist, only friends are allowed, so the check
+ * is rather simple.
*
- * @param cls our 'struct DisconnectList'
- * @param tc unused
+ * @param cls closure
+ * @param pid peer to approve or disapproave
+ * @return GNUNET_OK if the connection is allowed
*/
-static void
-disconnect_done (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc)
+static int
+blacklist_check (void *cls,
+ const struct GNUNET_PeerIdentity *pid)
{
- struct DisconnectList *dl = cls;
+ struct Peer *pos;
+ pos = GNUNET_CONTAINER_multihashmap_get (peers, &pid->hashPubKey);
+ if ( (pos != NULL) &&
+ (pos->is_friend == GNUNET_YES) )
+ return GNUNET_OK;
GNUNET_STATISTICS_update (stats,
gettext_noop ("# peers blacklisted"),
1,
GNUNET_NO);
- GNUNET_CONTAINER_DLL_remove (disconnect_head,
- disconnect_tail,
- dl);
- GNUNET_free (dl);
-}
-
-
-/**
- * Force a disconnect from the specified peer.
- *
- * @param pl peer to disconnect
- */
-static void
-force_disconnect (struct Peer *pl)
-{
- const struct GNUNET_PeerIdentity *peer = &pl->pid;
- struct DisconnectList *dl;
-
- if (NULL != pl->wh)
- {
- GNUNET_TRANSPORT_blacklist_cancel (pl->wh);
- pl->wh = NULL;
- }
- pl->is_blocked = GNUNET_YES;
- dl = GNUNET_malloc (sizeof (struct DisconnectList));
- dl->peer = *peer;
- GNUNET_CONTAINER_DLL_insert (disconnect_head,
- disconnect_tail,
- dl);
- dl->rh = GNUNET_TRANSPORT_blacklist (sched, cfg,
- peer,
- GNUNET_TIME_UNIT_FOREVER_REL,
- GNUNET_TIME_UNIT_FOREVER_REL,
- &disconnect_done,
- dl);
-}
-
-
-
-/**
- * Function called once our request to 'whitelist' a peer
- * has completed.
- *
- * @param cls our 'struct Peer'
- * @param tc unused
- */
-static void
-whitelist_done (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- struct Peer *pl = cls;
-
- pl->wh = NULL;
- GNUNET_STATISTICS_update (stats,
- gettext_noop ("# peers blacklisted"),
- -1,
- GNUNET_NO);
-}
-
-
-/**
- * Whitelist the given peer (if it was blacklisted before).
- *
- * @param cls closure (not used)
- * @param pid identity of the peer
- * @param value peer to free
- * @return GNUNET_YES (always: continue to iterate)
- */
-static int
-whitelist_peer (void *cls,
- const GNUNET_HashCode *pid,
- void *value)
-{
- struct Peer *pl = value;
-
- if (! pl->is_blocked)
- return GNUNET_YES;
- pl->wh = GNUNET_TRANSPORT_blacklist (sched, cfg,
- &pl->pid,
- GNUNET_TIME_UNIT_ZERO,
- GNUNET_TIME_UNIT_FOREVER_REL,
- &whitelist_done,
- pl);
- pl->is_blocked = GNUNET_NO;
- return GNUNET_YES;
+ return GNUNET_SYSERR;
}
static void
whitelist_peers ()
{
- struct DisconnectList *dl;
-
- /* first, cancel all blacklisting requests */
- while (NULL != (dl = disconnect_head))
+ if (blacklist != NULL)
{
- GNUNET_CONTAINER_DLL_remove (disconnect_head,
- disconnect_tail,
- dl);
- GNUNET_TRANSPORT_blacklist_cancel (dl->rh);
- GNUNET_free (dl);
+ GNUNET_TRANSPORT_blacklist_cancel (blacklist);
+ blacklist = NULL;
}
- /* then, specifically whitelist all peers that we
- know to have blacklisted */
- GNUNET_CONTAINER_multihashmap_iterate (peers,
- &whitelist_peer,
- NULL);
}
pos));
if (pos->hello_req != NULL)
GNUNET_CORE_notify_transmit_ready_cancel (pos->hello_req);
- if (pos->wh != NULL)
- GNUNET_TRANSPORT_blacklist_cancel (pos->wh);
if (pos->connect_req != NULL)
GNUNET_CORE_peer_request_connect_cancel (pos->connect_req);
if (pos->hello_delay_task != GNUNET_SCHEDULER_NO_TASK)
return;
if (GNUNET_OK != is_connection_allowed (pos))
return;
- if (GNUNET_YES == pos->is_blocked)
- return;
if (GNUNET_TIME_absolute_get_remaining (pos->greylisted_until).value > 0)
return;
if (GNUNET_YES == pos->is_friend)
pos);
}
if ( (GNUNET_NO == pos->is_friend) &&
- (GNUNET_NO == pos->is_blocked) &&
(GNUNET_NO == pos->is_connected) )
{
free_peer (NULL, &pos->pid.hashPubKey, pos);
if (pos == NULL)
{
pos = make_peer (peer, NULL, GNUNET_NO);
- if (GNUNET_OK != is_connection_allowed (pos))
- {
- GNUNET_assert (pos->is_friend == GNUNET_NO);
- pos->is_connected = GNUNET_YES;
-#if DEBUG_TOPOLOGY
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Connection to `%s' is forbidden, forcing disconnect!\n",
- GNUNET_i2s (peer));
-#endif
- force_disconnect (pos);
- return;
- }
+ GNUNET_break (GNUNET_OK == is_connection_allowed (pos));
}
else
{
}
-/**
- * Disconnect from all non-friends (we're below quota).
- *
- * @param cls closure, not used
- * @param pid identity of a peer
- * @param value 'struct Peer*' for the peer
- * @return GNUNET_YES (continue to iterate)
- */
-static int
-drop_non_friends (void *cls,
- const GNUNET_HashCode *pid,
- void *value)
-{
- struct Peer *pos = value;
-
- if ( (GNUNET_NO == pos->is_friend) &&
- (GNUNET_YES == pos->is_connected) )
- {
-#if DEBUG_TOPOLOGY
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Connection to `%s' is not from a friend, forcing disconnect!\n",
- GNUNET_i2s (&pos->pid));
-#endif
- force_disconnect (pos);
- }
- return GNUNET_YES;
-}
-
-
/**
* Try to add more peers to our connection set.
*
GNUNET_CONTAINER_multihashmap_iterate (peers,
&try_add_peers,
NULL);
- if (friend_count < minimum_friend_count)
- {
- /* disconnect from all non-friends */
-#if DEBUG_TOPOLOGY
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Not enough friendly connections, dropping all non-friend connections\n");
-#endif
- GNUNET_CONTAINER_multihashmap_iterate (peers,
- &drop_non_friends,
- NULL);
- }
+ if ( (friend_count < minimum_friend_count) &&
+ (blacklist == NULL) )
+ blacklist = GNUNET_TRANSPORT_blacklist (sched, cfg,
+ &blacklist_check, NULL);
}
GNUNET_NO);
peer = GNUNET_CONTAINER_multihashmap_get (peers,
&pid.hashPubKey);
- if ( (peer != NULL) &&
- (peer->is_blocked) )
- return GNUNET_OK; /* ignore: currently blocked */
- if ( (GNUNET_YES == friends_only) &&
- ( (peer == NULL) ||
- (GNUNET_YES != peer->is_friend) ) )
- return GNUNET_OK; /* ignore: not a friend */
+ if (peer == NULL)
+ {
+ if ( (GNUNET_YES == friends_only) ||
+ (friend_count < minimum_friend_count) )
+ return GNUNET_OK;
+ }
+ else
+ {
+ if ( (GNUNET_YES != peer->is_friend) &&
+ (GNUNET_YES == friends_only) )
+ return GNUNET_OK;
+ if ( (GNUNET_YES != peer->is_friend) &&
+ (friend_count < minimum_friend_count) )
+ return GNUNET_OK;
+ }
if (transport != NULL)
GNUNET_TRANSPORT_offer_hello (transport,
message);
cleaning_task (void *cls,
const struct GNUNET_SCHEDULER_TaskContext *tc)
{
- struct DisconnectList *dl;
-
if (NULL != peerinfo_notify)
{
GNUNET_PEERINFO_notify_cancel (peerinfo_notify);
GNUNET_CORE_disconnect (handle);
handle = NULL;
}
- while (NULL != (dl = disconnect_head))
- {
- GNUNET_CONTAINER_DLL_remove (disconnect_head,
- disconnect_tail,
- dl);
- GNUNET_TRANSPORT_blacklist_cancel (dl->rh);
- GNUNET_free (dl);
- }
+ whitelist_peers ();
if (stats != NULL)
{
GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
minimum_friend_count,
autoconnect ? "autoconnect enabled" : "autoconnect disabled");
#endif
+ if (friend_count < minimum_friend_count)
+ blacklist = GNUNET_TRANSPORT_blacklist (sched, cfg,
+ &blacklist_check, NULL);
transport = GNUNET_TRANSPORT_connect (sched,
cfg,
NULL,
GNUNET_TIME_UNIT_FOREVER_REL,
NULL,
&core_init,
- NULL,
&connect_notify,
&disconnect_notify,
NULL, GNUNET_NO,
$(GN_LIBINTL)
gnunet_service_transport_SOURCES = \
- gnunet-service-transport.c plugin_transport.h \
- gnunet-service-transport_blacklist.c gnunet-service-transport_blacklist.h
+ gnunet-service-transport.c plugin_transport.h
gnunet_service_transport_LDADD = \
$(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \
$(top_builddir)/src/statistics/libgnunetstatistics.la \
struct GNUNET_PeerIdentity peer;
/**
- * How long until this entry times out?
+ * Client responsible for this entry.
*/
- struct GNUNET_TIME_Absolute until;
+ struct GNUNET_SERVER_Client *client;
+
+};
+
+
+/**
+ * Information kept for each client registered to perform
+ * blacklisting.
+ */
+struct Blacklisters
+{
+ /**
+ * This is a linked list.
+ */
+ struct Blacklisters *next;
+
+ /**
+ * This is a linked list.
+ */
+ struct Blacklisters *prev;
/**
- * Task scheduled to run the moment the time does run out.
+ * Client responsible for this entry.
*/
- GNUNET_SCHEDULER_TaskIdentifier timeout_task;
+ struct GNUNET_SERVER_Client *client;
+
};
+/**
+ * State of blacklist check to be performed for each
+ * connecting peer.
+ */
+struct BlacklistCheck
+{
+
+
+
+ /**
+ * Identity of the peer being checked.
+ */
+ struct GNUNET_PeerIdentity peer;
+
+ /**
+ * Clients we still need to ask.
+ */
+ struct GNUNET_SERVER_Client *pending;
+
+};
+
+
+
/**
* Map of blacklisted peers (maps from peer identities
* to 'struct BlacklistEntry*' values).
static struct GNUNET_CONTAINER_MultiHashMap *blacklist;
/**
- * Notifications for blacklisting.
+ * Head of DLL of blacklisting clients.
*/
-static struct GNUNET_SERVER_NotificationContext *blacklist_notifiers;
+static struct Blacklisters *bl_head;
/**
- * Our scheduler.
+ * Tail of DLL of blacklisting clients.
*/
-static struct GNUNET_SCHEDULER_Handle *sched;
+static struct Blacklisters *bl_tail;
/**
{
struct BlacklistEntry *be = value;
- GNUNET_SCHEDULER_cancel (sched,
- be->timeout_task);
GNUNET_free (be);
return GNUNET_YES;
}
NULL);
GNUNET_CONTAINER_multihashmap_destroy (blacklist);
blacklist = NULL;
- GNUNET_SERVER_notification_context_destroy (blacklist_notifiers);
- blacklist_notifiers = NULL;
}
/**
- * Task run when a blacklist entry times out.
+ * Handle a request to start a blacklist.
*
- * @param cls closure (the 'struct BlacklistEntry*')
- * @param tc scheduler context (unused)
+ * @param cls closure (always NULL)
+ * @param client identification of the client
+ * @param message the actual message
*/
-static void
-timeout_task (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc)
+void
+GNUNET_TRANSPORT_handle_blacklist_init (void *cls,
+ struct GNUNET_SERVER_Client *client,
+ const struct GNUNET_MessageHeader *message)
{
- struct BlacklistEntry *be = cls;
- struct BlacklistMessage msg;
-
- be->timeout_task = GNUNET_SCHEDULER_NO_TASK;
- msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST);
- msg.header.size = htons (sizeof (struct BlacklistMessage));
- msg.reserved = htonl (0);
- msg.peer = be->peer;
- msg.until = GNUNET_TIME_absolute_hton (GNUNET_TIME_UNIT_ZERO_ABS);
- GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (blacklist,
- &be->peer.hashPubKey,
- be));
- GNUNET_free (be);
- GNUNET_SERVER_notification_context_broadcast (blacklist_notifiers,
- &msg.header,
- GNUNET_NO);
+ struct Blacklisters *bl;
+
+ bl = GNUNET_malloc (sizeof (struct Blacklisters));
+ bl->client = client;
+ GNUNET_SERVER_client_keep (client);
+ GNUNET_CONTAINER_DLL_insert (bl_head, bl_tail, bl);
+ /* FIXME: confirm that all existing connections are OK! */
}
* @param message the actual message
*/
void
-GNUNET_TRANSPORT_handle_blacklist (void *cls,
- struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
+GNUNET_TRANSPORT_handle_blacklist_reply (void *cls,
+ struct GNUNET_SERVER_Client *client,
+ const struct GNUNET_MessageHeader *message)
{
- struct BlacklistEntry *be;
+ struct Blacklisters *bl;
const struct BlacklistMessage *msg = (const struct BlacklistMessage*) message;
- be = GNUNET_CONTAINER_multihashmap_get (blacklist,
- &msg->peer.hashPubKey);
- if (be != NULL)
+ bl = bl_head;
+ while ( (bl != NULL) &&
+ (bl->client != client) )
+ bl = bl->next;
+ if (bl == NULL)
{
- GNUNET_SCHEDULER_cancel (sched,
- be->timeout_task);
+ GNUNET_SERVER_client_done (client, GNUNET_SYSERR);
+ return;
}
- else
- {
+ if (ntohl (msg->is_allowed) == GNUNET_SYSERR)
+ {
be = GNUNET_malloc (sizeof (struct BlacklistEntry));
be->peer = msg->peer;
+ be->client = client;
GNUNET_CONTAINER_multihashmap_put (blacklist,
&msg->peer.hashPubKey,
be,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
}
- be->until = GNUNET_TIME_absolute_ntoh (msg->until);
- be->timeout_task = GNUNET_SCHEDULER_add_delayed (sched,
- GNUNET_TIME_absolute_get_remaining (be->until),
- &timeout_task,
- be);
- GNUNET_SERVER_notification_context_broadcast (blacklist_notifiers,
- &msg->header,
- GNUNET_NO);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ /* FIXME: trigger continuation... */
}
int
GNUNET_TRANSPORT_blacklist_check (const struct GNUNET_PeerIdentity *id)
{
- return GNUNET_CONTAINER_multihashmap_contains (blacklist, &id->hashPubKey);
+ if (GNUNET_CONTAINER_multihashmap_contains (blacklist, &id->hashPubKey))
+ return GNUNET_YES;
+
}
GNUNET_TIME_UNIT_FOREVER_REL,
&shutdown_task,
NULL);
- blacklist_notifiers = GNUNET_SERVER_notification_context_create (server, 0);
}
#include "transport.h"
/**
- * Handle a request to blacklist a peer.
+ * Handle a request to start a blacklist.
*
* @param cls closure (always NULL)
* @param client identification of the client
* @param message the actual message
*/
void
-GNUNET_TRANSPORT_handle_blacklist (void *cls,
- struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message);
+GNUNET_TRANSPORT_handle_blacklist_init (void *cls,
+ struct GNUNET_SERVER_Client *client,
+ const struct GNUNET_MessageHeader *message);
/**
* @param message the actual message
*/
void
-GNUNET_TRANSPORT_handle_blacklist_notify (void *cls,
- struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message);
-
-
-/**
- * Is the given peer currently blacklisted?
- *
- * @param id identity of the peer
- * @return GNUNET_YES if the peer is blacklisted, GNUNET_NO if not
- */
-int
-GNUNET_TRANSPORT_blacklist_check (const struct GNUNET_PeerIdentity *id);
-
-
-/**
- * Initialize the blacklisting subsystem.
- *
- * @param server server we handle requests from (transport service server)
- * @param s scheduler to use
- */
-void
-GNUNET_TRANSPORT_blacklist_init (struct GNUNET_SERVER_Handle *server,
- struct GNUNET_SCHEDULER_Handle *s);
+GNUNET_TRANSPORT_handle_blacklist_reply (void *cls,
+ struct GNUNET_SERVER_Client *client,
+ const struct GNUNET_MessageHeader *message);
#endif
{
/**
- * Type will be GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST
+ * Type will be GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_QUERY or
+ * GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_REPLY.
*/
struct GNUNET_MessageHeader header;
/**
- * Reserved (for alignment).
+ * 0 for the query, GNUNET_OK (allowed) or GNUNET_SYSERR (disallowed)
+ * for the response.
*/
- uint32_t reserved GNUNET_PACKED;
+ uint32_t is_allowed GNUNET_PACKED;
/**
- * Which peer is being blacklisted (or has seen its
- * blacklisting expire)?
+ * Which peer is being blacklisted or queried?
*/
struct GNUNET_PeerIdentity peer;
- /**
- * Until what time is this peer blacklisted (zero for
- * no longer blacklisted).
- */
- struct GNUNET_TIME_AbsoluteNBO until;
-
};
/**
* Handle for blacklisting requests.
*/
-struct GNUNET_TRANSPORT_BlacklistRequest
+struct GNUNET_TRANSPORT_Blacklist
{
/**
struct GNUNET_CLIENT_Connection * client;
/**
- * Function to call when done.
- */
- GNUNET_SCHEDULER_Task cont;
-
- /**
- * Clsoure for 'cont'.
+ * Scheduler to use.
*/
- void *cont_cls;
+ struct GNUNET_SCHEDULER_Handle *sched;
/**
- * Scheduler to use.
+ * Configuration to use.
*/
- struct GNUNET_SCHEDULER_Handle *sched;
+ const struct GNUNET_CONFIGURATION_Handle *cfg;
/**
- * Pending handle for the blacklisting request.
+ * Pending handle for the current request.
*/
struct GNUNET_CLIENT_TransmitHandle *th;
-
+
/**
- * How long should 'peer' be blacklisted?
+ * Function to call for determining if a peer is allowed
+ * to communicate with us.
*/
- struct GNUNET_TIME_Absolute duration;
-
+ GNUNET_TRANSPORT_BlacklistCallback cb;
+
/**
- * Which peer is being blacklisted?
+ * Closure for 'cb'.
+ */
+ void *cb_cls;
+
+ /**
+ * Peer currently under consideration.
*/
struct GNUNET_PeerIdentity peer;
-
+
};
/**
- * Function called to notify a client about the socket
- * begin ready to queue more data. "buf" will be
- * NULL and "size" zero if the socket was closed for
- * writing in the meantime.
+ * Establish blacklist connection to transport service.
*
- * @param cls closure
- * @param size number of bytes available in buf
- * @param buf where the callee should write the message
- * @return number of bytes written to buf
+ * @param br overall handle
*/
-static size_t
-transmit_blacklist_request (void *cls,
- size_t size, void *buf)
-{
- struct GNUNET_TRANSPORT_BlacklistRequest *br = cls;
- struct BlacklistMessage req;
-
- if (buf == NULL)
- {
- GNUNET_SCHEDULER_add_continuation (br->sched,
- br->cont,
- br->cont_cls,
- GNUNET_SCHEDULER_REASON_TIMEOUT);
- GNUNET_free (br);
- return 0;
- }
- req.header.size = htons (sizeof (req));
- req.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST);
- req.reserved = htonl (0);
- req.peer = br->peer;
- req.until = GNUNET_TIME_absolute_hton (br->duration);
- memcpy (buf, &req, sizeof (req));
- GNUNET_SCHEDULER_add_continuation (br->sched,
- br->cont,
- br->cont_cls,
- GNUNET_SCHEDULER_REASON_PREREQ_DONE);
- GNUNET_free (br);
- return sizeof (req);
-}
+static void
+reconnect (struct GNUNET_TRANSPORT_Blacklist *br);
/**
- * Blacklist a peer for a given period of time. All connections
- * (inbound and outbound) to a peer that is blacklisted will be
- * dropped (as soon as we learn who the connection is for). A second
- * call to this function for the same peer overrides previous
- * blacklisting requests.
+ * Send our reply to a blacklisting request.
*
- * @param sched scheduler to use
- * @param cfg configuration to use
- * @param peer identity of peer to blacklist
- * @param duration how long to blacklist, use GNUNET_TIME_UNIT_ZERO to
- * re-enable connections
- * @param timeout when should this operation (trying to establish the
- * blacklisting time out)
- * @param cont continuation to call once the request has been processed
- * @param cont_cls closure for cont
- * @return NULL on error, otherwise handle for cancellation
+ * @param br our overall context
*/
-struct GNUNET_TRANSPORT_BlacklistRequest *
-GNUNET_TRANSPORT_blacklist (struct GNUNET_SCHEDULER_Handle *sched,
- const struct GNUNET_CONFIGURATION_Handle *cfg,
- const struct GNUNET_PeerIdentity *peer,
- struct GNUNET_TIME_Relative duration,
- struct GNUNET_TIME_Relative timeout,
- GNUNET_SCHEDULER_Task cont,
- void *cont_cls)
-{
- struct GNUNET_CLIENT_Connection * client;
- struct GNUNET_TRANSPORT_BlacklistRequest *ret;
-
- client = GNUNET_CLIENT_connect (sched, "transport", cfg);
- if (NULL == client)
- return NULL;
- ret = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_BlacklistRequest));
- ret->client = client;
- ret->peer = *peer;
- ret->duration = GNUNET_TIME_relative_to_absolute (duration);
- ret->sched = sched;
- ret->cont = cont;
- ret->cont_cls = cont_cls;
- ret->th = GNUNET_CLIENT_notify_transmit_ready (client,
- sizeof (struct BlacklistMessage),
- timeout,
- GNUNET_YES,
- &transmit_blacklist_request,
- ret);
- GNUNET_assert (NULL != ret->th);
- return ret;
-}
+static void
+reply (struct GNUNET_TRANSPORT_Blacklist *br);
/**
- * Abort transmitting the blacklist request. Note that this function
- * is NOT for removing a peer from the blacklist (for that, call
- * GNUNET_TRANSPORT_blacklist with a duration of zero). This function
- * is only for aborting the transmission of a blacklist request
- * (i.e. because of shutdown).
+ * Handle blacklist queries.
*
- * @param br handle of the request that is to be cancelled
+ * @param cls our overall handle
+ * @param msg query
*/
-void
-GNUNET_TRANSPORT_blacklist_cancel (struct GNUNET_TRANSPORT_BlacklistRequest * br)
-{
- GNUNET_CLIENT_notify_transmit_ready_cancel (br->th);
- GNUNET_free (br);
-}
-
-
-/**
- * Handle for blacklist notifications.
- */
-struct GNUNET_TRANSPORT_BlacklistNotification
+static void
+query_handler (void *cls,
+ const struct GNUNET_MessageHeader *msg)
{
-
- /**
- * Function to call whenever there is a change.
- */
- GNUNET_TRANSPORT_BlacklistCallback notify;
-
- /**
- * Closure for notify.
- */
- void *notify_cls;
-
- /**
- * Scheduler to use.
- */
- struct GNUNET_SCHEDULER_Handle *sched;
-
- /**
- * Configuration to use.
- */
- const struct GNUNET_CONFIGURATION_Handle *cfg;
+ struct GNUNET_TRANSPORT_Blacklist *br = cls;
+ const struct BlacklistMessage *bm;
- /**
- * Connection to transport service.
- */
- struct GNUNET_CLIENT_Connection * client;
-
- /**
- * Pending handle for the notification request.
- */
- struct GNUNET_CLIENT_TransmitHandle *th;
-};
+ if ( (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);
+}
/**
- * Send a request to receive blacklisting notifications
+ * Receive blacklist queries from transport service.
*
- * @param bn context to initialize
+ * @param br overall handle
*/
static void
-request_notifications (struct GNUNET_TRANSPORT_BlacklistNotification *bn);
+receive (struct GNUNET_TRANSPORT_Blacklist *br)
+{
+ GNUNET_CLIENT_receive (br->client,
+ &query_handler,
+ br,
+ GNUNET_TIME_UNIT_FOREVER_REL);
+}
/**
- * Destroy the existing connection to the transport service and
- * setup a new one (the existing one had serious problems).
- *
- * @param bn context to re-initialize
+ * 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 void
-retry_get_notifications (struct GNUNET_TRANSPORT_BlacklistNotification *bn)
+static size_t
+transmit_blacklist_init (void *cls,
+ size_t size, void *buf)
{
- GNUNET_CLIENT_disconnect (bn->client, GNUNET_NO);
- bn->client = GNUNET_CLIENT_connect (bn->sched, "transport", bn->cfg);
- request_notifications (bn);
+ struct GNUNET_TRANSPORT_Blacklist *br = cls;
+ struct GNUNET_MessageHeader req;
+
+ 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);
}
/**
- * Function called whenever we get a blacklisting notification.
- * Pass it on to the callback and wait for more.
+ * Establish blacklist connection to transport service.
*
- * @param cls our 'struct GNUNET_TRANSPORT_BlacklistNotification *'
- * @param msg the blacklisting notification, NULL on error
+ * @param br overall handle
*/
static void
-recv_blacklist_info (void *cls,
- const struct GNUNET_MessageHeader *msg)
+reconnect (struct GNUNET_TRANSPORT_Blacklist *br)
{
- struct GNUNET_TRANSPORT_BlacklistNotification *bn = cls;
- const struct BlacklistMessage *req;
-
- if ( (msg == NULL) ||
- (sizeof(struct BlacklistMessage) != ntohs(msg->size)) ||
- (GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST != ntohs(msg->type)) )
- {
- retry_get_notifications (bn);
- return;
- }
- req = (const struct BlacklistMessage*) msg;
- bn->notify (bn->notify_cls,
- &req->peer,
- GNUNET_TIME_absolute_ntoh (req->until));
- GNUNET_CLIENT_receive (bn->client,
- &recv_blacklist_info,
- bn,
- GNUNET_TIME_UNIT_FOREVER_REL);
+ if (br->client != NULL)
+ GNUNET_CLIENT_disconnect (br->client, GNUNET_NO);
+ br->client = GNUNET_CLIENT_connect (br->sched,
+ "transport",
+ br->cfg);
+ br->th = GNUNET_CLIENT_notify_transmit_ready (br->client,
+ sizeof (struct GNUNET_MessageHeader),
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ GNUNET_YES,
+ &transmit_blacklist_init,
+ br);
}
/**
- * Function called to notify a client about the socket
- * begin ready to queue more data. "buf" will be
- * NULL and "size" zero if the socket was closed for
- * writing in the meantime.
+ * Transmit the blacklist response to the service.
*
- * @param cls closure
+ * @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_notify_request (void *cls,
- size_t size, void *buf)
+static size_t
+transmit_blacklist_reply (void *cls,
+ size_t size, void *buf)
{
- struct GNUNET_TRANSPORT_BlacklistNotification *bn = cls;
- struct GNUNET_MessageHeader hdr;
+ struct GNUNET_TRANSPORT_Blacklist *br = cls;
+ struct BlacklistMessage req;
- bn->th = NULL;
if (buf == NULL)
{
- retry_get_notifications (bn);
+ reconnect (br);
return 0;
}
- GNUNET_assert (size >= sizeof(hdr));
- hdr.size = htons (sizeof (hdr));
- hdr.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_NOTIFY);
- memcpy (buf, &hdr, sizeof(hdr));
- return sizeof(hdr);
+ 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));
+ receive (br);
+ return sizeof (req);
}
/**
- * Send a request to receive blacklisting notifications
+ * Send our reply to a blacklisting request.
*
- * @param bn context to initialize
+ * @param br our overall context
*/
static void
-request_notifications (struct GNUNET_TRANSPORT_BlacklistNotification *bn)
+reply (struct GNUNET_TRANSPORT_Blacklist *br)
{
- GNUNET_assert (bn->client != NULL);
- bn->th = GNUNET_CLIENT_notify_transmit_ready (bn->client,
- sizeof (struct GNUNET_MessageHeader),
+ br->th = GNUNET_CLIENT_notify_transmit_ready (br->client,
+ sizeof (struct BlacklistMessage),
GNUNET_TIME_UNIT_FOREVER_REL,
- GNUNET_YES,
- &transmit_notify_request,
- bn);
- GNUNET_assert (bn->th != NULL);
- GNUNET_CLIENT_receive (bn->client,
- &recv_blacklist_info,
- bn,
- GNUNET_TIME_UNIT_FOREVER_REL);
+ GNUNET_NO,
+ &transmit_blacklist_reply,
+ br);
+ if (br->th == NULL)
+ {
+ reconnect (br);
+ return;
+ }
}
/**
- * Call a function whenever a peer's blacklisting status changes.
+ * 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 sched scheduler to use
* @param cfg configuration to use
- * @param bc function to call on status changes
- * @param bc_cls closure for bc
+ * @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_BlacklistNotification *
-GNUNET_TRANSPORT_blacklist_notify (struct GNUNET_SCHEDULER_Handle *sched,
- const struct GNUNET_CONFIGURATION_Handle *cfg,
- GNUNET_TRANSPORT_BlacklistCallback bc,
- void *bc_cls)
+struct GNUNET_TRANSPORT_Blacklist *
+GNUNET_TRANSPORT_blacklist (struct GNUNET_SCHEDULER_Handle *sched,
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ GNUNET_TRANSPORT_BlacklistCallback cb,
+ void *cb_cls)
{
- struct GNUNET_TRANSPORT_BlacklistNotification *ret;
struct GNUNET_CLIENT_Connection * client;
+ struct GNUNET_TRANSPORT_Blacklist *ret;
client = GNUNET_CLIENT_connect (sched, "transport", cfg);
if (NULL == client)
return NULL;
- ret = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_BlacklistNotification));
+ ret = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_Blacklist));
ret->client = client;
ret->sched = sched;
ret->cfg = cfg;
- ret->notify = bc;
- ret->notify_cls = bc_cls;
- request_notifications (ret);
+ 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;
}
/**
- * Stop calling the notification callback associated with
- * the given blacklist notification.
+ * Abort the blacklist. Note that this function is the only way for
+ * removing a peer from the blacklist.
*
- * @param bn handle of the request that is to be cancelled
+ * @param br handle of the request that is to be cancelled
*/
void
-GNUNET_TRANSPORT_blacklist_notify_cancel (struct GNUNET_TRANSPORT_BlacklistNotification * bn)
+GNUNET_TRANSPORT_blacklist_cancel (struct GNUNET_TRANSPORT_Blacklist *br)
{
- if (bn->th != NULL)
- GNUNET_CLIENT_notify_transmit_ready_cancel (bn->th);
- GNUNET_CLIENT_disconnect (bn->client, GNUNET_NO);
- GNUNET_free (bn);
+ if (br->th != NULL)
+ GNUNET_CLIENT_notify_transmit_ready_cancel (br->th);
+ GNUNET_CLIENT_disconnect (br->client, GNUNET_NO);
+ GNUNET_free (br);
}
+
/* end of transport_api_blacklist.c */