From: Christian Grothoff Date: Fri, 22 Jan 2010 14:47:45 +0000 (+0000) Subject: finishing blacklist implementation X-Git-Tag: initial-import-from-subversion-38251~22876 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=3f3d51ef20ae4ef5017ca92ed1f6e153322f3a95;p=oweals%2Fgnunet.git finishing blacklist implementation --- diff --git a/src/transport/gnunet-service-transport_blacklist.c b/src/transport/gnunet-service-transport_blacklist.c index b51f51442..5ddf9c1bf 100644 --- a/src/transport/gnunet-service-transport_blacklist.c +++ b/src/transport/gnunet-service-transport_blacklist.c @@ -37,63 +37,20 @@ struct BlacklistEntry { /** - * How long until this entry times out? - */ - struct GNUNET_TIME_Absolute until; - - /** - * Task scheduled to run the moment the time does run out. - */ - GNUNET_SCHEDULER_TaskIdentifier timeout_task; -}; - - -/** - * Entry in list of notifications still to transmit to - * a client. - */ -struct PendingNotificationList -{ - - /** - * This is a linked list. - */ - struct PendingNotificationList *next; - - /** - * Identity of the peer to send notification about. + * Identity of the peer being blacklisted by this entry. + * (also equivalent to the key) */ struct GNUNET_PeerIdentity peer; -}; - - -/** - * List of clients to notify whenever the blacklist changes. - */ -struct BlacklistNotificationList -{ - /** - * This is a linked list. - */ - struct BlacklistNotificationList *next; - - /** - * Client to notify. + * How long until this entry times out? */ - struct GNUNET_SERVER_Client *client; - - /** - * Pending request for transmission to client, or NULL. - */ - struct GNUNET_CONNECTION_TransmitHandle *req; + struct GNUNET_TIME_Absolute until; /** - * Blacklist entries that still need to be submitted. + * Task scheduled to run the moment the time does run out. */ - struct PendingNotificationList *pending; - + GNUNET_SCHEDULER_TaskIdentifier timeout_task; }; @@ -104,9 +61,9 @@ struct BlacklistNotificationList static struct GNUNET_CONTAINER_MultiHashMap *blacklist; /** - * Linked list of clients to notify whenever the blacklist changes. + * Notifications for blacklisting. */ -static struct BlacklistNotificationList *blacklist_notifiers; +static struct GNUNET_SERVER_NotificationContext *blacklist_notifiers; /** * Our scheduler. @@ -120,9 +77,7 @@ static struct GNUNET_SCHEDULER_Handle *sched; * @param cls closure, unused * @param key current key code * @param value value in the hash map - * @return GNUNET_YES if we should continue to - * iterate, - * GNUNET_NO if not. + * @return GNUNET_YES (continue to iterate) */ static int free_blacklist_entry (void *cls, @@ -152,6 +107,38 @@ shutdown_task (void *cls, &free_blacklist_entry, 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. + * + * @param cls closure (the 'struct BlacklistEntry*') + * @param tc scheduler context (unused) + */ +static void +timeout_task (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + 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); } @@ -167,11 +154,67 @@ GNUNET_TRANSPORT_handle_blacklist (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { - /* FIXME */ + struct BlacklistEntry *be; + const struct BlacklistMessage *msg = (const struct BlacklistMessage*) message; + + be = GNUNET_CONTAINER_multihashmap_get (blacklist, + &be->peer.hashPubKey); + if (be != NULL) + { + GNUNET_SCHEDULER_cancel (sched, + be->timeout_task); + } + else + { + be = GNUNET_malloc (sizeof (struct BlacklistEntry)); + be->peer = msg->peer; + GNUNET_CONTAINER_multihashmap_put (blacklist, + &be->peer.hashPubKey, + be, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); + } + 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); } +/** + * Notify the given client about all entries in the blacklist. + * + * @param cls closure, refers to the 'struct GNUNET_SERVER_Client' to notify + * @param key current key code (peer identity, not used) + * @param value value in the hash map, the 'struct BlacklistEntry*' + * @return GNUNET_YES (continue to iterate) + */ +static int +notify_blacklist_entry (void *cls, + const GNUNET_HashCode *key, + void *value) +{ + struct GNUNET_SERVER_Client *client = cls; + struct BlacklistEntry *be = value; + struct BlacklistMessage msg; + + 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 (be->until); + GNUNET_SERVER_notification_context_unicast (blacklist_notifiers, + client, + &msg.header, + GNUNET_NO); + return GNUNET_YES; +} + + /** * Handle a request for notification of blacklist changes. * @@ -184,13 +227,10 @@ GNUNET_TRANSPORT_handle_blacklist_notify (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { - struct BlacklistNotificationList *bnl; - - bnl = GNUNET_malloc (sizeof (struct BlacklistNotificationList)); - bnl->next = blacklist_notifiers; - blacklist_notifiers = bnl; - /* FIXME */ - GNUNET_SERVER_receive_done (client, GNUNET_OK); + GNUNET_SERVER_notification_context_add (blacklist_notifiers, client); + GNUNET_CONTAINER_multihashmap_iterate (blacklist, + ¬ify_blacklist_entry, + client); } @@ -213,7 +253,8 @@ GNUNET_TRANSPORT_blacklist_check (const struct GNUNET_PeerIdentity *id) * @param s scheduler to use */ void -GNUNET_TRANSPORT_blacklist_init (struct GNUNET_SCHEDULER_Handle *s) +GNUNET_TRANSPORT_blacklist_init (struct GNUNET_SERVER_Handle *server, + struct GNUNET_SCHEDULER_Handle *s) { sched = s; blacklist = GNUNET_CONTAINER_multihashmap_create (4); @@ -221,6 +262,8 @@ GNUNET_TRANSPORT_blacklist_init (struct GNUNET_SCHEDULER_Handle *s) GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, NULL); + blacklist_notifiers = GNUNET_SERVER_notification_context_create (server, 0); } + /* end of gnunet-service-transport_blacklist.c */ diff --git a/src/transport/gnunet-service-transport_blacklist.h b/src/transport/gnunet-service-transport_blacklist.h index 46a65cb61..92f81a2e9 100644 --- a/src/transport/gnunet-service-transport_blacklist.h +++ b/src/transport/gnunet-service-transport_blacklist.h @@ -69,10 +69,12 @@ 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_SCHEDULER_Handle *s); +GNUNET_TRANSPORT_blacklist_init (struct GNUNET_SERVER_Handle *server, + struct GNUNET_SCHEDULER_Handle *s); #endif