diff options
author | Sree Harsha Totakura <totakura@in.tum.de> | 2012-05-13 17:21:18 +0000 |
---|---|---|
committer | Sree Harsha Totakura <totakura@in.tum.de> | 2012-05-13 17:21:18 +0000 |
commit | fc73a3da5ded1ff8488d7e13ab4ae4a1d0680f96 (patch) | |
tree | 61d50f96a1f1f0c329d22727bfe80d77d8ab874d /src/lockmanager/lockmanager_api.c | |
parent | 761e32ca4ffae07d145081c8273eb68fb505194b (diff) | |
download | gnunet-fc73a3da5ded1ff8488d7e13ab4ae4a1d0680f96.tar.gz gnunet-fc73a3da5ded1ff8488d7e13ab4ae4a1d0680f96.zip |
clean shutdown in lockmanager, test case for lock release and message format checks for incoming msg in lockmanager API
Diffstat (limited to 'src/lockmanager/lockmanager_api.c')
-rw-r--r-- | src/lockmanager/lockmanager_api.c | 282 |
1 files changed, 127 insertions, 155 deletions
diff --git a/src/lockmanager/lockmanager_api.c b/src/lockmanager/lockmanager_api.c index 18f5d0a71..1545717ee 100644 --- a/src/lockmanager/lockmanager_api.c +++ b/src/lockmanager/lockmanager_api.c | |||
@@ -98,44 +98,28 @@ struct GNUNET_LOCKMANAGER_LockingRequest | |||
98 | * The status of the lock | 98 | * The status of the lock |
99 | */ | 99 | */ |
100 | enum GNUNET_LOCKMANAGER_Status status; | 100 | enum GNUNET_LOCKMANAGER_Status status; |
101 | |||
102 | /** | ||
103 | * The length of the locking domain string including the trailing NULL | ||
104 | */ | ||
105 | uint16_t domain_name_length; | ||
106 | }; | 101 | }; |
107 | 102 | ||
108 | 103 | ||
109 | /** | 104 | /** |
110 | * Generate hash with domain name and the lock | 105 | * Get the key for the given lock in the 'lock_map'. |
111 | * | 106 | * |
112 | * @param domain NULL terminated domain name | 107 | * @param domain_name |
113 | * | 108 | * @param lock_number |
114 | * @param domain_length the length of the domain name including the terminating | 109 | * @param key set to the key |
115 | * NULL if already known; 0 to calculate | ||
116 | * | ||
117 | * @param lock the lock number | ||
118 | * @param ret where to write the generated hash | ||
119 | */ | 110 | */ |
120 | static void | 111 | static void |
121 | hash_domain_and_lock (const char *domain, | 112 | get_key (const char *domain_name, |
122 | uint16_t domain_length, | 113 | uint32_t lock_number, |
123 | uint32_t lock, | 114 | struct GNUNET_HashCode *key) |
124 | GNUNET_HashCode *ret) | ||
125 | { | 115 | { |
126 | unsigned int str_len; | 116 | uint32_t *last_32; |
127 | uint32_t *block; | 117 | |
128 | size_t block_size; | 118 | GNUNET_CRYPTO_hash (domain_name, |
129 | 119 | strlen (domain_name), | |
130 | str_len = (0 == domain_length) ? strlen (domain) : domain_length - 1; | 120 | key); |
131 | block_size = sizeof (uint32_t) + str_len; | 121 | last_32 = (uint32_t *) key; |
132 | block = GNUNET_malloc (block_size); | 122 | *last_32 ^= lock_number; |
133 | /* Copy data */ | ||
134 | *block = lock; | ||
135 | memcpy (&block[1], domain, str_len); | ||
136 | |||
137 | GNUNET_CRYPTO_hash (block, block_size, ret); | ||
138 | GNUNET_free (block); | ||
139 | } | 123 | } |
140 | 124 | ||
141 | 125 | ||
@@ -151,15 +135,15 @@ call_status_cb_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
151 | const struct GNUNET_LOCKMANAGER_LockingRequest *r = cls; | 135 | const struct GNUNET_LOCKMANAGER_LockingRequest *r = cls; |
152 | 136 | ||
153 | if (NULL != r->status_cb) | 137 | if (NULL != r->status_cb) |
154 | { | 138 | { |
155 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 139 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
156 | "Calling status change callback for lock: %d in domain: %s\n", | 140 | "Calling status change callback for lock: %d in domain: %s\n", |
157 | r->lock, r->domain); | 141 | r->lock, r->domain); |
158 | r->status_cb (r->status_cb_cls, | 142 | r->status_cb (r->status_cb_cls, |
159 | r->domain, | 143 | r->domain, |
160 | r->lock, | 144 | r->lock, |
161 | r->status); | 145 | r->status); |
162 | } | 146 | } |
163 | } | 147 | } |
164 | 148 | ||
165 | 149 | ||
@@ -174,67 +158,70 @@ handle_replies (void *cls, | |||
174 | const struct GNUNET_MessageHeader *msg) | 158 | const struct GNUNET_MessageHeader *msg) |
175 | { | 159 | { |
176 | struct GNUNET_LOCKMANAGER_Handle *handle = cls; | 160 | struct GNUNET_LOCKMANAGER_Handle *handle = cls; |
177 | 161 | const struct GNUNET_LOCKMANAGER_Message *m; | |
162 | const char *domain; | ||
163 | struct GNUNET_HashCode hash; | ||
164 | int match_found; | ||
165 | uint32_t lock; | ||
166 | uint16_t msize; | ||
167 | |||
178 | if (NULL == msg) | 168 | if (NULL == msg) |
169 | { | ||
170 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
171 | "Lockmanager service not available or went down\n"); | ||
172 | return; | ||
173 | } | ||
174 | if (GNUNET_MESSAGE_TYPE_LOCKMANAGER_SUCCESS != ntohs(msg->type)) | ||
175 | { | ||
176 | GNUNET_break (0); | ||
177 | return; | ||
178 | } | ||
179 | msize = ntohs (msg->size); | ||
180 | if (msize <= sizeof (struct GNUNET_LOCKMANAGER_Message)) | ||
181 | { | ||
182 | GNUNET_break (0); | ||
183 | return; | ||
184 | } | ||
185 | m = (const struct GNUNET_LOCKMANAGER_Message *) msg; | ||
186 | domain = (const char *) &m[1]; | ||
187 | msize -= sizeof (struct GNUNET_LOCKMANAGER_Message); | ||
188 | if ('\0' != domain[msize-1]) | ||
189 | { | ||
190 | GNUNET_break (0); | ||
191 | return; | ||
192 | } | ||
193 | |||
194 | lock = ntohl (m->lock); | ||
195 | get_key (domain, lock, &hash); | ||
196 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
197 | "Received SUCCESS message for lock: %d, domain %s\n", | ||
198 | lock, domain); | ||
199 | int match_iterator(void *cls, const GNUNET_HashCode *key, void *value) | ||
200 | { | ||
201 | struct GNUNET_LOCKMANAGER_LockingRequest *r = value; | ||
202 | |||
203 | if ( !((0 == strcmp (domain, r->domain)) | ||
204 | && (lock == r->lock))) | ||
205 | return GNUNET_YES; | ||
206 | match_found = GNUNET_YES; | ||
207 | if (GNUNET_LOCKMANAGER_SUCCESS != r->status) | ||
179 | { | 208 | { |
180 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 209 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
181 | "Lockmanager service not available or went down\n"); | 210 | "Changing status for lock: %d in domain: %s to SUCCESS\n", |
182 | return; | 211 | r->lock, r->domain); |
183 | } | 212 | r->status = GNUNET_LOCKMANAGER_SUCCESS; |
184 | 213 | GNUNET_SCHEDULER_add_continuation (&call_status_cb_task, | |
185 | switch (ntohs (msg->type)) | 214 | r, |
186 | { | 215 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); |
187 | case GNUNET_MESSAGE_TYPE_LOCKMANAGER_SUCCESS: | ||
188 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
189 | "Received SUCCESS message\n"); | ||
190 | |||
191 | const struct GNUNET_LOCKMANAGER_Message *m; | ||
192 | const char *domain; | ||
193 | struct GNUNET_HashCode hash; | ||
194 | uint32_t lock; | ||
195 | int match_found; | ||
196 | |||
197 | m = (struct GNUNET_LOCKMANAGER_Message *) msg; | ||
198 | domain = (char *) &m[1]; | ||
199 | lock = ntohl (m->lock); | ||
200 | hash_domain_and_lock (domain, 0, lock, &hash); | ||
201 | |||
202 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
203 | "\t on lock: %d in domain %s\n", | ||
204 | lock, domain); | ||
205 | |||
206 | int match_iterator(void *cls, const GNUNET_HashCode *key, void *value) | ||
207 | { | ||
208 | struct GNUNET_LOCKMANAGER_LockingRequest *r = value; | ||
209 | |||
210 | if ( !((0 == strcmp (domain, r->domain)) | ||
211 | && (lock == r->lock))) | ||
212 | return GNUNET_YES; | ||
213 | |||
214 | match_found = GNUNET_YES; | ||
215 | if (GNUNET_LOCKMANAGER_SUCCESS != r->status) | ||
216 | { | ||
217 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
218 | "Changing status for lock: %d in domain: %s to SUCCESS\n", | ||
219 | r->lock, r->domain); | ||
220 | r->status = GNUNET_LOCKMANAGER_SUCCESS; | ||
221 | GNUNET_SCHEDULER_add_continuation (&call_status_cb_task, | ||
222 | r, | ||
223 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); | ||
224 | } | ||
225 | return GNUNET_NO; | ||
226 | } | ||
227 | |||
228 | match_found = GNUNET_NO; | ||
229 | GNUNET_CONTAINER_multihashmap_get_multiple (handle->hashmap, | ||
230 | &hash, | ||
231 | &match_iterator, | ||
232 | NULL); | ||
233 | GNUNET_assert (GNUNET_YES == match_found); | ||
234 | break; | ||
235 | default: | ||
236 | GNUNET_break(0); | ||
237 | } | 216 | } |
217 | return GNUNET_NO; | ||
218 | } | ||
219 | match_found = GNUNET_NO; | ||
220 | GNUNET_CONTAINER_multihashmap_get_multiple (handle->hashmap, | ||
221 | &hash, | ||
222 | &match_iterator, | ||
223 | NULL); | ||
224 | GNUNET_break (GNUNET_YES == match_found); | ||
238 | } | 225 | } |
239 | 226 | ||
240 | 227 | ||
@@ -253,10 +240,10 @@ transmit_notify (void *cls, size_t size, void *buf) | |||
253 | uint16_t msg_size; | 240 | uint16_t msg_size; |
254 | 241 | ||
255 | if ((0 == size) || (NULL == buf)) | 242 | if ((0 == size) || (NULL == buf)) |
256 | { | 243 | { |
257 | /* FIXME: Timed out -- requeue? */ | 244 | /* FIXME: Timed out -- requeue? */ |
258 | return 0; | 245 | return 0; |
259 | } | 246 | } |
260 | msg_size = ntohs (msg->header.size); | 247 | msg_size = ntohs (msg->header.size); |
261 | GNUNET_assert (size >= msg_size); | 248 | GNUNET_assert (size >= msg_size); |
262 | memcpy (buf, msg, msg_size); | 249 | memcpy (buf, msg, msg_size); |
@@ -313,15 +300,13 @@ GNUNET_LOCKMANAGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
313 | h = GNUNET_malloc (sizeof (struct GNUNET_LOCKMANAGER_Handle)); | 300 | h = GNUNET_malloc (sizeof (struct GNUNET_LOCKMANAGER_Handle)); |
314 | h->conn = GNUNET_CLIENT_connect ("lockmanager", cfg); | 301 | h->conn = GNUNET_CLIENT_connect ("lockmanager", cfg); |
315 | if (NULL == h->conn) | 302 | if (NULL == h->conn) |
316 | { | 303 | { |
317 | GNUNET_free (h); | 304 | GNUNET_free (h); |
318 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); | 305 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); |
319 | return NULL; | 306 | return NULL; |
320 | } | 307 | } |
321 | |||
322 | h->hashmap = GNUNET_CONTAINER_multihashmap_create (15); | 308 | h->hashmap = GNUNET_CONTAINER_multihashmap_create (15); |
323 | GNUNET_assert (NULL != h->hashmap); | 309 | GNUNET_assert (NULL != h->hashmap); |
324 | |||
325 | GNUNET_CLIENT_receive (h->conn, | 310 | GNUNET_CLIENT_receive (h->conn, |
326 | &handle_replies, | 311 | &handle_replies, |
327 | h, | 312 | h, |
@@ -342,18 +327,16 @@ GNUNET_LOCKMANAGER_disconnect (struct GNUNET_LOCKMANAGER_Handle *handle) | |||
342 | { | 327 | { |
343 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__); | 328 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__); |
344 | GNUNET_CLIENT_disconnect (handle->conn); | 329 | GNUNET_CLIENT_disconnect (handle->conn); |
345 | |||
346 | if (0 != GNUNET_CONTAINER_multihashmap_size (handle->hashmap)) | 330 | if (0 != GNUNET_CONTAINER_multihashmap_size (handle->hashmap)) |
347 | { | 331 | { |
348 | LOG (GNUNET_ERROR_TYPE_WARNING, | 332 | LOG (GNUNET_ERROR_TYPE_WARNING, |
349 | "Some locking requests are still present. Cancel them before " | 333 | "Some locking requests are still present. Cancel them before " |
350 | "calling %s\n", __func__); | 334 | "calling %s\n", __func__); |
351 | GNUNET_CONTAINER_multihashmap_iterate (handle->hashmap, | 335 | GNUNET_CONTAINER_multihashmap_iterate (handle->hashmap, |
352 | &free_iterator, | 336 | &free_iterator, |
353 | NULL); | 337 | NULL); |
354 | } | 338 | } |
355 | GNUNET_CONTAINER_multihashmap_destroy (handle->hashmap); | 339 | GNUNET_CONTAINER_multihashmap_destroy (handle->hashmap); |
356 | |||
357 | GNUNET_free (handle); | 340 | GNUNET_free (handle); |
358 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); | 341 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); |
359 | } | 342 | } |
@@ -395,25 +378,24 @@ GNUNET_LOCKMANAGER_acquire_lock (struct GNUNET_LOCKMANAGER_Handle *handle, | |||
395 | struct GNUNET_LOCKMANAGER_Message *msg; | 378 | struct GNUNET_LOCKMANAGER_Message *msg; |
396 | struct GNUNET_HashCode hash; | 379 | struct GNUNET_HashCode hash; |
397 | uint16_t msg_size; | 380 | uint16_t msg_size; |
381 | size_t domain_name_length; | ||
398 | 382 | ||
399 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__); | 383 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__); |
400 | r = GNUNET_malloc (sizeof (struct GNUNET_LOCKMANAGER_LockingRequest)); | 384 | r = GNUNET_malloc (sizeof (struct GNUNET_LOCKMANAGER_LockingRequest)); |
401 | r->domain_name_length = strlen (domain_name) + 1; | 385 | domain_name_length = strlen (domain_name) + 1; |
402 | r->handle = handle; | 386 | r->handle = handle; |
403 | r->lock = lock; | 387 | r->lock = lock; |
404 | r->domain = GNUNET_malloc (r->domain_name_length); | 388 | r->domain = GNUNET_malloc (domain_name_length); |
405 | r->status = GNUNET_LOCKMANAGER_RELEASE; | 389 | r->status = GNUNET_LOCKMANAGER_RELEASE; |
406 | r->status_cb = status_cb; | 390 | r->status_cb = status_cb; |
407 | r->status_cb_cls = status_cb_cls; | 391 | r->status_cb_cls = status_cb_cls; |
408 | memcpy (r->domain, domain_name, r->domain_name_length); | 392 | memcpy (r->domain, domain_name, domain_name_length); |
409 | 393 | msg_size = sizeof (struct GNUNET_LOCKMANAGER_Message) + domain_name_length; | |
410 | msg_size = sizeof (struct GNUNET_LOCKMANAGER_Message) + r->domain_name_length; | ||
411 | msg = GNUNET_malloc (msg_size); | 394 | msg = GNUNET_malloc (msg_size); |
412 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_LOCKMANAGER_ACQUIRE); | 395 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_LOCKMANAGER_ACQUIRE); |
413 | msg->header.size = htons (msg_size); | 396 | msg->header.size = htons (msg_size); |
414 | msg->lock = htonl (lock); | 397 | msg->lock = htonl (lock); |
415 | memcpy (&msg[1], r->domain, r->domain_name_length); | 398 | memcpy (&msg[1], r->domain, domain_name_length); |
416 | |||
417 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Queueing ACQUIRE message\n"); | 399 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Queueing ACQUIRE message\n"); |
418 | r->transmit_handle = | 400 | r->transmit_handle = |
419 | GNUNET_CLIENT_notify_transmit_ready (r->handle->conn, | 401 | GNUNET_CLIENT_notify_transmit_ready (r->handle->conn, |
@@ -422,15 +404,11 @@ GNUNET_LOCKMANAGER_acquire_lock (struct GNUNET_LOCKMANAGER_Handle *handle, | |||
422 | GNUNET_YES, | 404 | GNUNET_YES, |
423 | &transmit_notify, | 405 | &transmit_notify, |
424 | msg); | 406 | msg); |
425 | hash_domain_and_lock (r->domain, | 407 | get_key (r->domain, r->lock, &hash); |
426 | r->domain_name_length, | ||
427 | r->lock, | ||
428 | &hash); | ||
429 | GNUNET_CONTAINER_multihashmap_put (r->handle->hashmap, | 408 | GNUNET_CONTAINER_multihashmap_put (r->handle->hashmap, |
430 | &hash, | 409 | &hash, |
431 | r, | 410 | r, |
432 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | 411 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); |
433 | |||
434 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); | 412 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); |
435 | return r; | 413 | return r; |
436 | } | 414 | } |
@@ -449,40 +427,34 @@ void | |||
449 | GNUNET_LOCKMANAGER_cancel_request (struct GNUNET_LOCKMANAGER_LockingRequest | 427 | GNUNET_LOCKMANAGER_cancel_request (struct GNUNET_LOCKMANAGER_LockingRequest |
450 | *request) | 428 | *request) |
451 | { | 429 | { |
430 | struct GNUNET_LOCKMANAGER_Message *msg; | ||
452 | struct GNUNET_HashCode hash; | 431 | struct GNUNET_HashCode hash; |
432 | uint16_t msg_size; | ||
433 | size_t domain_name_length; | ||
453 | 434 | ||
454 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__); | 435 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__); |
455 | /* FIXME: Stop ACQUIRE retransmissions */ | 436 | /* FIXME: Stop ACQUIRE retransmissions */ |
456 | if (GNUNET_LOCKMANAGER_SUCCESS == request->status) | 437 | if (GNUNET_LOCKMANAGER_SUCCESS == request->status) |
457 | { | 438 | { |
458 | struct GNUNET_LOCKMANAGER_Message *msg; | 439 | domain_name_length = strlen (request->domain) + 1; |
459 | uint16_t msg_size; | 440 | msg_size = sizeof (struct GNUNET_LOCKMANAGER_Message) |
460 | 441 | + domain_name_length; | |
461 | msg_size = sizeof (struct GNUNET_LOCKMANAGER_Message) | 442 | msg = GNUNET_malloc (msg_size); |
462 | + request->domain_name_length; | 443 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_LOCKMANAGER_RELEASE); |
463 | msg = GNUNET_malloc (msg_size); | 444 | msg->header.size = htons (msg_size); |
464 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_LOCKMANAGER_RELEASE); | 445 | msg->lock = htonl (request->lock); |
465 | msg->header.size = htons (msg_size); | 446 | memcpy (&msg[1], request->domain, domain_name_length); |
466 | msg->lock = htonl (request->lock); | 447 | GNUNET_CLIENT_notify_transmit_ready (request->handle->conn, |
467 | memcpy (&msg[1], request->domain, request->domain_name_length); | 448 | msg_size, |
468 | 449 | TIMEOUT, /* What if this fails */ | |
469 | GNUNET_CLIENT_notify_transmit_ready (request->handle->conn, | 450 | GNUNET_NO, |
470 | msg_size, | 451 | &transmit_notify, |
471 | TIMEOUT, /* What if this fails */ | 452 | msg); |
472 | GNUNET_NO, | 453 | } |
473 | &transmit_notify, | 454 | get_key (request->domain, request->lock, &hash); |
474 | msg); | ||
475 | } | ||
476 | |||
477 | hash_domain_and_lock (request->domain, | ||
478 | request->domain_name_length, | ||
479 | request->lock, | ||
480 | &hash); | ||
481 | |||
482 | GNUNET_assert (GNUNET_YES == | 455 | GNUNET_assert (GNUNET_YES == |
483 | GNUNET_CONTAINER_multihashmap_remove | 456 | GNUNET_CONTAINER_multihashmap_remove |
484 | (request->handle->hashmap, &hash, request)); | 457 | (request->handle->hashmap, &hash, request)); |
485 | |||
486 | GNUNET_free (request->domain); | 458 | GNUNET_free (request->domain); |
487 | GNUNET_free (request); | 459 | GNUNET_free (request); |
488 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); | 460 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); |