diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-05-31 17:16:02 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-05-31 17:16:02 +0000 |
commit | ca8893f5a65b9f0750aaeb247f415fe3a9334689 (patch) | |
tree | c2432a050fed328816c029393be0d58748492c3c /src/regex/gnunet-service-regex.c | |
parent | f8a7961e146ef505721bd7ba78abc7adea6a174b (diff) | |
download | gnunet-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.c | 267 |
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 | */ | ||
35 | struct 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 | */ | ||
79 | static struct GNUNET_DHT_Handle *dht; | ||
80 | |||
81 | /** | ||
82 | * Handle for doing statistics. | ||
83 | */ | ||
84 | static struct GNUNET_STATISTICS_Handle *stats; | ||
85 | |||
86 | /** | ||
87 | * Head of list of clients. | ||
88 | */ | ||
89 | static struct ClientEntry *client_head; | ||
90 | |||
91 | /** | ||
92 | * End of list of clients. | ||
93 | */ | ||
94 | static struct ClientEntry *client_tail; | ||
95 | |||
96 | |||
31 | /** | 97 | /** |
32 | * Task run during shutdown. | 98 | * Task run during shutdown. |
33 | * | 99 | * |
@@ -37,7 +103,192 @@ | |||
37 | static void | 103 | static void |
38 | cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 104 | cleanup_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 | */ | ||
119 | static void | ||
120 | handle_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 | */ | ||
160 | static void | ||
161 | reannounce (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 | */ | ||
180 | static void | ||
181 | handle_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 | */ | ||
235 | static void | ||
236 | handle_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 | */ | ||
254 | static void | ||
255 | handle_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 | ||