aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-service-transport_blacklist.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/gnunet-service-transport_blacklist.c')
-rw-r--r--src/transport/gnunet-service-transport_blacklist.c142
1 files changed, 85 insertions, 57 deletions
diff --git a/src/transport/gnunet-service-transport_blacklist.c b/src/transport/gnunet-service-transport_blacklist.c
index 8f78f498f..08ed2c9d2 100644
--- a/src/transport/gnunet-service-transport_blacklist.c
+++ b/src/transport/gnunet-service-transport_blacklist.c
@@ -43,32 +43,75 @@ struct BlacklistEntry
43 struct GNUNET_PeerIdentity peer; 43 struct GNUNET_PeerIdentity peer;
44 44
45 /** 45 /**
46 * How long until this entry times out? 46 * Client responsible for this entry.
47 */ 47 */
48 struct GNUNET_TIME_Absolute until; 48 struct GNUNET_SERVER_Client *client;
49
50};
51
52
53/**
54 * Information kept for each client registered to perform
55 * blacklisting.
56 */
57struct Blacklisters
58{
59 /**
60 * This is a linked list.
61 */
62 struct Blacklisters *next;
63
64 /**
65 * This is a linked list.
66 */
67 struct Blacklisters *prev;
49 68
50 /** 69 /**
51 * Task scheduled to run the moment the time does run out. 70 * Client responsible for this entry.
52 */ 71 */
53 GNUNET_SCHEDULER_TaskIdentifier timeout_task; 72 struct GNUNET_SERVER_Client *client;
73
54}; 74};
55 75
56 76
57/** 77/**
78 * State of blacklist check to be performed for each
79 * connecting peer.
80 */
81struct BlacklistCheck
82{
83
84
85
86 /**
87 * Identity of the peer being checked.
88 */
89 struct GNUNET_PeerIdentity peer;
90
91 /**
92 * Clients we still need to ask.
93 */
94 struct GNUNET_SERVER_Client *pending;
95
96};
97
98
99
100/**
58 * Map of blacklisted peers (maps from peer identities 101 * Map of blacklisted peers (maps from peer identities
59 * to 'struct BlacklistEntry*' values). 102 * to 'struct BlacklistEntry*' values).
60 */ 103 */
61static struct GNUNET_CONTAINER_MultiHashMap *blacklist; 104static struct GNUNET_CONTAINER_MultiHashMap *blacklist;
62 105
63/** 106/**
64 * Notifications for blacklisting. 107 * Head of DLL of blacklisting clients.
65 */ 108 */
66static struct GNUNET_SERVER_NotificationContext *blacklist_notifiers; 109static struct Blacklisters *bl_head;
67 110
68/** 111/**
69 * Our scheduler. 112 * Tail of DLL of blacklisting clients.
70 */ 113 */
71static struct GNUNET_SCHEDULER_Handle *sched; 114static struct Blacklisters *bl_tail;
72 115
73 116
74/** 117/**
@@ -86,8 +129,6 @@ free_blacklist_entry (void *cls,
86{ 129{
87 struct BlacklistEntry *be = value; 130 struct BlacklistEntry *be = value;
88 131
89 GNUNET_SCHEDULER_cancel (sched,
90 be->timeout_task);
91 GNUNET_free (be); 132 GNUNET_free (be);
92 return GNUNET_YES; 133 return GNUNET_YES;
93} 134}
@@ -108,37 +149,28 @@ shutdown_task (void *cls,
108 NULL); 149 NULL);
109 GNUNET_CONTAINER_multihashmap_destroy (blacklist); 150 GNUNET_CONTAINER_multihashmap_destroy (blacklist);
110 blacklist = NULL; 151 blacklist = NULL;
111 GNUNET_SERVER_notification_context_destroy (blacklist_notifiers);
112 blacklist_notifiers = NULL;
113} 152}
114 153
115 154
116/** 155/**
117 * Task run when a blacklist entry times out. 156 * Handle a request to start a blacklist.
118 * 157 *
119 * @param cls closure (the 'struct BlacklistEntry*') 158 * @param cls closure (always NULL)
120 * @param tc scheduler context (unused) 159 * @param client identification of the client
160 * @param message the actual message
121 */ 161 */
122static void 162void
123timeout_task (void *cls, 163GNUNET_TRANSPORT_handle_blacklist_init (void *cls,
124 const struct GNUNET_SCHEDULER_TaskContext *tc) 164 struct GNUNET_SERVER_Client *client,
165 const struct GNUNET_MessageHeader *message)
125{ 166{
126 struct BlacklistEntry *be = cls; 167 struct Blacklisters *bl;
127 struct BlacklistMessage msg; 168
128 169 bl = GNUNET_malloc (sizeof (struct Blacklisters));
129 be->timeout_task = GNUNET_SCHEDULER_NO_TASK; 170 bl->client = client;
130 msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST); 171 GNUNET_SERVER_client_keep (client);
131 msg.header.size = htons (sizeof (struct BlacklistMessage)); 172 GNUNET_CONTAINER_DLL_insert (bl_head, bl_tail, bl);
132 msg.reserved = htonl (0); 173 /* FIXME: confirm that all existing connections are OK! */
133 msg.peer = be->peer;
134 msg.until = GNUNET_TIME_absolute_hton (GNUNET_TIME_UNIT_ZERO_ABS);
135 GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (blacklist,
136 &be->peer.hashPubKey,
137 be));
138 GNUNET_free (be);
139 GNUNET_SERVER_notification_context_broadcast (blacklist_notifiers,
140 &msg.header,
141 GNUNET_NO);
142} 174}
143 175
144 176
@@ -150,38 +182,33 @@ timeout_task (void *cls,
150 * @param message the actual message 182 * @param message the actual message
151 */ 183 */
152void 184void
153GNUNET_TRANSPORT_handle_blacklist (void *cls, 185GNUNET_TRANSPORT_handle_blacklist_reply (void *cls,
154 struct GNUNET_SERVER_Client *client, 186 struct GNUNET_SERVER_Client *client,
155 const struct GNUNET_MessageHeader *message) 187 const struct GNUNET_MessageHeader *message)
156{ 188{
157 struct BlacklistEntry *be; 189 struct Blacklisters *bl;
158 const struct BlacklistMessage *msg = (const struct BlacklistMessage*) message; 190 const struct BlacklistMessage *msg = (const struct BlacklistMessage*) message;
159 191
160 be = GNUNET_CONTAINER_multihashmap_get (blacklist, 192 bl = bl_head;
161 &msg->peer.hashPubKey); 193 while ( (bl != NULL) &&
162 if (be != NULL) 194 (bl->client != client) )
195 bl = bl->next;
196 if (bl == NULL)
163 { 197 {
164 GNUNET_SCHEDULER_cancel (sched, 198 GNUNET_SERVER_client_done (client, GNUNET_SYSERR);
165 be->timeout_task); 199 return;
166 } 200 }
167 else 201 if (ntohl (msg->is_allowed) == GNUNET_SYSERR)
168 { 202 {
169 be = GNUNET_malloc (sizeof (struct BlacklistEntry)); 203 be = GNUNET_malloc (sizeof (struct BlacklistEntry));
170 be->peer = msg->peer; 204 be->peer = msg->peer;
205 be->client = client;
171 GNUNET_CONTAINER_multihashmap_put (blacklist, 206 GNUNET_CONTAINER_multihashmap_put (blacklist,
172 &msg->peer.hashPubKey, 207 &msg->peer.hashPubKey,
173 be, 208 be,
174 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); 209 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
175 } 210 }
176 be->until = GNUNET_TIME_absolute_ntoh (msg->until); 211 /* FIXME: trigger continuation... */
177 be->timeout_task = GNUNET_SCHEDULER_add_delayed (sched,
178 GNUNET_TIME_absolute_get_remaining (be->until),
179 &timeout_task,
180 be);
181 GNUNET_SERVER_notification_context_broadcast (blacklist_notifiers,
182 &msg->header,
183 GNUNET_NO);
184 GNUNET_SERVER_receive_done (client, GNUNET_OK);
185} 212}
186 213
187 214
@@ -243,7 +270,9 @@ GNUNET_TRANSPORT_handle_blacklist_notify (void *cls,
243int 270int
244GNUNET_TRANSPORT_blacklist_check (const struct GNUNET_PeerIdentity *id) 271GNUNET_TRANSPORT_blacklist_check (const struct GNUNET_PeerIdentity *id)
245{ 272{
246 return GNUNET_CONTAINER_multihashmap_contains (blacklist, &id->hashPubKey); 273 if (GNUNET_CONTAINER_multihashmap_contains (blacklist, &id->hashPubKey))
274 return GNUNET_YES;
275
247} 276}
248 277
249 278
@@ -263,7 +292,6 @@ GNUNET_TRANSPORT_blacklist_init (struct GNUNET_SERVER_Handle *server,
263 GNUNET_TIME_UNIT_FOREVER_REL, 292 GNUNET_TIME_UNIT_FOREVER_REL,
264 &shutdown_task, 293 &shutdown_task,
265 NULL); 294 NULL);
266 blacklist_notifiers = GNUNET_SERVER_notification_context_create (server, 0);
267} 295}
268 296
269 297