aboutsummaryrefslogtreecommitdiff
path: root/src/regex/gnunet-service-regex.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-05-31 17:16:02 +0000
committerChristian Grothoff <christian@grothoff.org>2013-05-31 17:16:02 +0000
commitca8893f5a65b9f0750aaeb247f415fe3a9334689 (patch)
treec2432a050fed328816c029393be0d58748492c3c /src/regex/gnunet-service-regex.c
parentf8a7961e146ef505721bd7ba78abc7adea6a174b (diff)
downloadgnunet-ca8893f5a65b9f0750aaeb247f415fe3a9334689.tar.gz
gnunet-ca8893f5a65b9f0750aaeb247f415fe3a9334689.zip
-towards implementing regex service
Diffstat (limited to 'src/regex/gnunet-service-regex.c')
-rw-r--r--src/regex/gnunet-service-regex.c267
1 files changed, 263 insertions, 4 deletions
diff --git a/src/regex/gnunet-service-regex.c b/src/regex/gnunet-service-regex.c
index e88d8c336..4bddb5042 100644
--- a/src/regex/gnunet-service-regex.c
+++ b/src/regex/gnunet-service-regex.c
@@ -28,6 +28,72 @@
28#include "gnunet_regex_lib.h" 28#include "gnunet_regex_lib.h"
29#include "regex_ipc.h" 29#include "regex_ipc.h"
30 30
31
32/**
33 * Information about one of our clients.
34 */
35struct ClientEntry
36{
37
38 /**
39 * Kept in DLL.
40 */
41 struct ClientEntry *next;
42
43 /**
44 * Kept in DLL.
45 */
46 struct ClientEntry *prev;
47
48 /**
49 * Handle identifying the client.
50 */
51 struct GNUNET_SERVER_Client *client;
52
53 /**
54 * Search handle (if this client is searching).
55 */
56 struct GNUNET_REGEX_search_handle *sh;
57
58 /**
59 * Announcement handle (if this client is announcing).
60 */
61 struct GNUNET_REGEX_announce_handle *ah;
62
63 /**
64 * Refresh frequency for announcements.
65 */
66 struct GNUNET_TIME_Relative frequency;
67
68 /**
69 * Task for re-announcing.
70 */
71 GNUNET_SCHEDULER_TaskIdentifier refresh_task;
72
73};
74
75
76/**
77 * Connection to the DHT.
78 */
79static struct GNUNET_DHT_Handle *dht;
80
81/**
82 * Handle for doing statistics.
83 */
84static struct GNUNET_STATISTICS_Handle *stats;
85
86/**
87 * Head of list of clients.
88 */
89static struct ClientEntry *client_head;
90
91/**
92 * End of list of clients.
93 */
94static struct ClientEntry *client_tail;
95
96
31/** 97/**
32 * Task run during shutdown. 98 * Task run during shutdown.
33 * 99 *
@@ -37,7 +103,192 @@
37static void 103static void
38cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 104cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
39{ 105{
40 /* FIXME: do clean up here */ 106 GNUNET_DHT_disconnect (dht);
107 dht = NULL;
108 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
109 stats = NULL;
110}
111
112
113/**
114 * A client disconnected. Remove all of its data structure entries.
115 *
116 * @param cls closure, NULL
117 * @param client identification of the client
118 */
119static void
120handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
121{
122 struct ClientEntry *ce;
123 struct ClientEntry *nx;
124
125 nx = client_head;
126 for (ce = nx; NULL != ce; ce = nx)
127 {
128 nx = ce->next;
129 if (ce->client == client)
130 {
131 if (GNUNET_SCHEDULER_NO_TASK != ce->refresh_task)
132 {
133 GNUNET_SCHEDULER_cancel (ce->refresh_task);
134 ce->refresh_task = GNUNET_SCHEDULER_NO_TASK;
135 }
136 if (NULL != ce->ah)
137 {
138 GNUNET_REGEX_announce_cancel (ce->ah);
139 ce->ah = NULL;
140 }
141 if (NULL != ce->sh)
142 {
143 GNUNET_REGEX_search_cancel (ce->sh);
144 ce->sh = NULL;
145 }
146 GNUNET_CONTAINER_DLL_remove (client_head, client_tail, ce);
147 GNUNET_free (ce);
148 }
149 }
150}
151
152
153/**
154 * Periodic task to refresh our announcement of the regex.
155 *
156 * @param cls the 'struct ClientEntry' of the client that triggered the
157 * announcement
158 * @param tc scheduler context
159 */
160static void
161reannounce (void *cls,
162 const struct GNUNET_SCHEDULER_TaskContext *tc)
163{
164 struct ClientEntry *ce = cls;
165
166 GNUNET_REGEX_reannounce (ce->ah);
167 ce->refresh_task = GNUNET_SCHEDULER_add_delayed (ce->frequency,
168 &reannounce,
169 ce);
170}
171
172
173/**
174 * Handle ANNOUNCE message.
175 *
176 * @param cls closure
177 * @param client identification of the client
178 * @param message the actual message
179 */
180static void
181handle_announce (void *cls,
182 struct GNUNET_SERVER_Client *client,
183 const struct GNUNET_MessageHeader *message)
184{
185 const struct AnnounceMessage *am;
186 const char *regex;
187 struct ClientEntry *ce;
188 uint16_t size;
189
190 size = ntohs (message->size);
191 am = (const struct AnnounceMessage *) message;
192 regex = (const char *) &am[1];
193 if ( (size <= sizeof (struct AnnounceMessage)) ||
194 ('\0' != regex[size - sizeof (struct AnnounceMessage) - 1]) )
195 {
196 GNUNET_break (0);
197 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
198 return;
199 }
200 ce = GNUNET_new (struct ClientEntry);
201 ce->client = client;
202 ce->ah = GNUNET_REGEX_announce (dht,
203 &am->pid,
204 regex,
205 ntohs (am->compression),
206 stats);
207 if (NULL == ce->ah)
208 {
209 GNUNET_break (0);
210 GNUNET_free (ce);
211 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
212 return;
213 }
214 ce->frequency = GNUNET_TIME_relative_ntoh (am->refresh_delay);
215 ce->refresh_task = GNUNET_SCHEDULER_add_delayed (ce->frequency,
216 &reannounce,
217 ce);
218 GNUNET_CONTAINER_DLL_insert (client_head,
219 client_tail,
220 ce);
221 GNUNET_SERVER_receive_done (client, GNUNET_OK);
222}
223
224
225/**
226 * Handle result, pass it back to the client.
227 *
228 * @param cls the struct ClientEntry of the client searching
229 * @param id Peer providing a regex that matches the string.
230 * @param get_path Path of the get request.
231 * @param get_path_length Lenght of get_path.
232 * @param put_path Path of the put request.
233 * @param put_path_length Length of the put_path.
234 */
235static void
236handle_search_result (void *cls,
237 const struct GNUNET_PeerIdentity *id,
238 const struct GNUNET_PeerIdentity *get_path,
239 unsigned int get_path_length,
240 const struct GNUNET_PeerIdentity *put_path,
241 unsigned int put_path_length)
242{
243
244}
245
246
247/**
248 * Handle SEARCH message.
249 *
250 * @param cls closure
251 * @param client identification of the client
252 * @param message the actual message
253 */
254static void
255handle_search (void *cls,
256 struct GNUNET_SERVER_Client *client,
257 const struct GNUNET_MessageHeader *message)
258{
259 const struct SearchMessage *sm;
260 const char *string;
261 struct ClientEntry *ce;
262 uint16_t size;
263
264 size = ntohs (message->size);
265 sm = (const struct SearchMessage *) message;
266 string = (const char *) &sm[1];
267 if ( (size <= sizeof (struct SearchMessage)) ||
268 ('\0' != string[size - sizeof (struct SearchMessage) - 1]) )
269 {
270 GNUNET_break (0);
271 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
272 return;
273 }
274 ce = GNUNET_new (struct ClientEntry);
275 ce->client = client;
276 ce->sh = GNUNET_REGEX_search (dht,
277 string,
278 &handle_search_result,
279 ce,
280 stats);
281 if (NULL == ce->sh)
282 {
283 GNUNET_break (0);
284 GNUNET_free (ce);
285 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
286 return;
287 }
288 GNUNET_CONTAINER_DLL_insert (client_head,
289 client_tail,
290 ce);
291 GNUNET_SERVER_receive_done (client, GNUNET_OK);
41} 292}
42 293
43 294
@@ -53,13 +304,21 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
53 const struct GNUNET_CONFIGURATION_Handle *cfg) 304 const struct GNUNET_CONFIGURATION_Handle *cfg)
54{ 305{
55 static const struct GNUNET_SERVER_MessageHandler handlers[] = { 306 static const struct GNUNET_SERVER_MessageHandler handlers[] = {
56 /* FIXME: add handlers here! */ 307 {&handle_announce, NULL, GNUNET_MESSAGE_TYPE_REGEX_ANNOUNCE, 0},
308 {&handle_search, NULL, GNUNET_MESSAGE_TYPE_REGEX_SEARCH, 0},
57 {NULL, NULL, 0, 0} 309 {NULL, NULL, 0, 0}
58 }; 310 };
59 /* FIXME: do setup here */ 311 dht = GNUNET_DHT_connect (cfg, 1024);
60 GNUNET_SERVER_add_handlers (server, handlers); 312 if (NULL == dht)
313 {
314 GNUNET_SCHEDULER_shutdown ();
315 return;
316 }
61 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup_task, 317 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup_task,
62 NULL); 318 NULL);
319 stats = GNUNET_STATISTICS_create ("regex", cfg);
320 GNUNET_SERVER_add_handlers (server, handlers);
321 GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL);
63} 322}
64 323
65 324