aboutsummaryrefslogtreecommitdiff
path: root/src/dv
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-03-13 14:23:23 +0000
committerChristian Grothoff <christian@grothoff.org>2013-03-13 14:23:23 +0000
commitd7fde87aac5d2d9842f167a40f793ca798cf06e0 (patch)
tree833b55186d2ec0cf4a65a339c77a06dde19139d6 /src/dv
parent7e036f66817a92099eef2414847c87eb8816cf1e (diff)
downloadgnunet-d7fde87aac5d2d9842f167a40f793ca798cf06e0.tar.gz
gnunet-d7fde87aac5d2d9842f167a40f793ca798cf06e0.zip
-finishing DV API
Diffstat (limited to 'src/dv')
-rw-r--r--src/dv/dv_api.c95
1 files changed, 79 insertions, 16 deletions
diff --git a/src/dv/dv_api.c b/src/dv/dv_api.c
index 3f9f11423..4b6cc1a5c 100644
--- a/src/dv/dv_api.c
+++ b/src/dv/dv_api.c
@@ -164,6 +164,8 @@ static size_t
164transmit_pending (void *cls, size_t size, void *buf) 164transmit_pending (void *cls, size_t size, void *buf)
165{ 165{
166 struct GNUNET_DV_ServiceHandle *sh = cls; 166 struct GNUNET_DV_ServiceHandle *sh = cls;
167 char *cbuf = buf;
168 struct GNUNET_DV_TransmitHandle *th;
167 size_t ret; 169 size_t ret;
168 size_t tsize; 170 size_t tsize;
169 171
@@ -174,15 +176,18 @@ transmit_pending (void *cls, size_t size, void *buf)
174 return 0; 176 return 0;
175 } 177 }
176 ret = 0; 178 ret = 0;
177 // FIXME: yuck! -- copy multiple, remove from DLL, and add to hash map! 179 while ( (NULL != (th = sh->th_head)) &&
178 if (NULL != sh->th_head) 180 (size - ret >= (tsize = ntohs (th->msg->size)) ))
179 { 181 {
180 tsize = ntohs (sh->th_head->msg->size); 182 GNUNET_CONTAINER_DLL_remove (sh->th_head,
181 if (size >= tsize) 183 sh->th_tail,
182 { 184 th);
183 memcpy (buf, sh->th_head->msg, tsize); 185 memcpy (&cbuf[ret], th->msg, tsize);
184 return tsize; 186 ret += tsize;
185 } 187 (void) GNUNET_CONTAINER_multihashmap_put (sh->send_callbacks,
188 &th->target.hashPubKey,
189 th,
190 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
186 } 191 }
187 return ret; 192 return ret;
188} 193}
@@ -224,6 +229,7 @@ handle_message_receipt (void *cls,
224 const struct GNUNET_DV_ConnectMessage *cm; 229 const struct GNUNET_DV_ConnectMessage *cm;
225 const struct GNUNET_DV_DisconnectMessage *dm; 230 const struct GNUNET_DV_DisconnectMessage *dm;
226 const struct GNUNET_DV_ReceivedMessage *rm; 231 const struct GNUNET_DV_ReceivedMessage *rm;
232 const struct GNUNET_MessageHeader *payload;
227 233
228 if (NULL == msg) 234 if (NULL == msg)
229 { 235 {
@@ -241,7 +247,9 @@ handle_message_receipt (void *cls,
241 return; 247 return;
242 } 248 }
243 cm = (const struct GNUNET_DV_ConnectMessage *) msg; 249 cm = (const struct GNUNET_DV_ConnectMessage *) msg;
244 // FIXME 250 sh->connect_cb (sh->cls,
251 &cm->peer,
252 ntohl (cm->distance));
245 break; 253 break;
246 case GNUNET_MESSAGE_TYPE_DV_DISCONNECT: 254 case GNUNET_MESSAGE_TYPE_DV_DISCONNECT:
247 if (ntohs (msg->size) != sizeof (struct GNUNET_DV_DisconnectMessage)) 255 if (ntohs (msg->size) != sizeof (struct GNUNET_DV_DisconnectMessage))
@@ -251,17 +259,28 @@ handle_message_receipt (void *cls,
251 return; 259 return;
252 } 260 }
253 dm = (const struct GNUNET_DV_DisconnectMessage *) msg; 261 dm = (const struct GNUNET_DV_DisconnectMessage *) msg;
254 // FIXME 262 sh->disconnect_cb (sh->cls,
263 &dm->peer);
255 break; 264 break;
256 case GNUNET_MESSAGE_TYPE_DV_RECV: 265 case GNUNET_MESSAGE_TYPE_DV_RECV:
257 if (ntohs (msg->size) < sizeof (struct GNUNET_DV_ReceivedMessage)) 266 if (ntohs (msg->size) < sizeof (struct GNUNET_DV_ReceivedMessage) + sizeof (struct GNUNET_MessageHeader))
258 { 267 {
259 GNUNET_break (0); 268 GNUNET_break (0);
260 reconnect (sh); 269 reconnect (sh);
261 return; 270 return;
262 } 271 }
263 rm = (const struct GNUNET_DV_ReceivedMessage *) msg; 272 rm = (const struct GNUNET_DV_ReceivedMessage *) msg;
264 // FIXME 273 payload = (const struct GNUNET_MessageHeader *) &rm[1];
274 if (ntohs (msg->size) != sizeof (struct GNUNET_DV_ReceivedMessage) + ntohs (payload->size))
275 {
276 GNUNET_break (0);
277 reconnect (sh);
278 return;
279 }
280 sh->message_cb (sh->cls,
281 &rm->sender,
282 ntohl (rm->distance),
283 payload);
265 break; 284 break;
266 default: 285 default:
267 reconnect (sh); 286 reconnect (sh);
@@ -309,13 +328,40 @@ transmit_start (void *cls,
309 328
310 329
311/** 330/**
331 * We got disconnected from the service and thus all of the
332 * pending send callbacks will never be confirmed. Clean up.
333 *
334 * @param cls the 'struct GNUNET_DV_ServiceHandle'
335 * @param key a peer identity
336 * @param value a 'struct GNUNET_DV_TransmitHandle' to clean up
337 * @return GNUNET_OK (continue to iterate)
338 */
339static int
340cleanup_send_cb (void *cls,
341 const struct GNUNET_HashCode *key,
342 void *value)
343{
344 struct GNUNET_DV_ServiceHandle *sh = cls;
345 struct GNUNET_DV_TransmitHandle *th = value;
346
347 GNUNET_assert (GNUNET_YES ==
348 GNUNET_CONTAINER_multihashmap_remove (sh->send_callbacks,
349 key,
350 th));
351 th->cb (th->cb_cls, GNUNET_SYSERR);
352 GNUNET_free (th);
353 return GNUNET_OK;
354}
355
356
357/**
312 * Disconnect and then reconnect to the DV service. 358 * Disconnect and then reconnect to the DV service.
313 * 359 *
314 * @param sh service handle 360 * @param sh service handle
315 */ 361 */
316static void 362static void
317reconnect (struct GNUNET_DV_ServiceHandle *sh) 363reconnect (struct GNUNET_DV_ServiceHandle *sh)
318{ 364{
319 if (NULL != sh->th) 365 if (NULL != sh->th)
320 { 366 {
321 GNUNET_CLIENT_notify_transmit_ready_cancel (sh->th); 367 GNUNET_CLIENT_notify_transmit_ready_cancel (sh->th);
@@ -326,6 +372,9 @@ reconnect (struct GNUNET_DV_ServiceHandle *sh)
326 GNUNET_CLIENT_disconnect (sh->client); 372 GNUNET_CLIENT_disconnect (sh->client);
327 sh->client = NULL; 373 sh->client = NULL;
328 } 374 }
375 GNUNET_CONTAINER_multihashmap_iterate (sh->send_callbacks,
376 &cleanup_send_cb,
377 sh);
329 sh->client = GNUNET_CLIENT_connect ("dv", sh->cfg); 378 sh->client = GNUNET_CLIENT_connect ("dv", sh->cfg);
330 if (NULL == sh->client) 379 if (NULL == sh->client)
331 { 380 {
@@ -401,7 +450,9 @@ GNUNET_DV_service_disconnect (struct GNUNET_DV_ServiceHandle *sh)
401 GNUNET_CLIENT_disconnect (sh->client); 450 GNUNET_CLIENT_disconnect (sh->client);
402 sh->client = NULL; 451 sh->client = NULL;
403 } 452 }
404 // FIXME: handle and/or free entries in 'send_callbacks'! 453 GNUNET_CONTAINER_multihashmap_iterate (sh->send_callbacks,
454 &cleanup_send_cb,
455 sh);
405 GNUNET_CONTAINER_multihashmap_destroy (sh->send_callbacks); 456 GNUNET_CONTAINER_multihashmap_destroy (sh->send_callbacks);
406 GNUNET_free (sh); 457 GNUNET_free (sh);
407} 458}
@@ -425,16 +476,28 @@ GNUNET_DV_send (struct GNUNET_DV_ServiceHandle *sh,
425 void *cb_cls) 476 void *cb_cls)
426{ 477{
427 struct GNUNET_DV_TransmitHandle *th; 478 struct GNUNET_DV_TransmitHandle *th;
479 struct GNUNET_DV_SendMessage *sm;
428 480
481 if (ntohs (msg->size) + sizeof (struct GNUNET_DV_SendMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
482 {
483 GNUNET_break (0);
484 return NULL;
485 }
429 th = GNUNET_malloc (sizeof (struct GNUNET_DV_TransmitHandle) + 486 th = GNUNET_malloc (sizeof (struct GNUNET_DV_TransmitHandle) +
487 sizeof (struct GNUNET_DV_SendMessage) +
430 ntohs (msg->size)); 488 ntohs (msg->size));
431 th->sh = sh; 489 th->sh = sh;
432 th->target = *target; 490 th->target = *target;
433 th->cb = cb; 491 th->cb = cb;
434 th->cb_cls = cb_cls; 492 th->cb_cls = cb_cls;
435 // FIXME: wrong, need to box 'msg' AND generate UID!
436 th->msg = (const struct GNUNET_MessageHeader *) &th[1]; 493 th->msg = (const struct GNUNET_MessageHeader *) &th[1];
437 memcpy (&th[1], msg, ntohs (msg->size)); 494 sm = (struct GNUNET_DV_SendMessage *) &th[1];
495 sm->header.type = htons (GNUNET_MESSAGE_TYPE_DV_SEND);
496 sm->header.size = htons (sizeof (struct GNUNET_DV_SendMessage) +
497 ntohs (msg->size));
498 /* use memcpy here as 'target' may not be sufficiently aligned */
499 memcpy (&sm->target, target, sizeof (struct GNUNET_PeerIdentity));
500 memcpy (&sm[1], msg, ntohs (msg->size));
438 GNUNET_CONTAINER_DLL_insert (sh->th_head, 501 GNUNET_CONTAINER_DLL_insert (sh->th_head,
439 sh->th_tail, 502 sh->th_tail,
440 th); 503 th);