aboutsummaryrefslogtreecommitdiff
path: root/src/transport/plugin_transport_unix.c
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2012-01-27 15:51:30 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2012-01-27 15:51:30 +0000
commit3716d50b290b939ff856196806951c134eff88ff (patch)
treedcc99d98186ea4ca9f1c8404c942730921fb9a57 /src/transport/plugin_transport_unix.c
parent240e3109cde69be3752a44b8ed7799599171fc80 (diff)
downloadgnunet-3716d50b290b939ff856196806951c134eff88ff.tar.gz
gnunet-3716d50b290b939ff856196806951c134eff88ff.zip
implemented sessions
Diffstat (limited to 'src/transport/plugin_transport_unix.c')
-rw-r--r--src/transport/plugin_transport_unix.c162
1 files changed, 134 insertions, 28 deletions
diff --git a/src/transport/plugin_transport_unix.c b/src/transport/plugin_transport_unix.c
index 0c8722eab..e4d756408 100644
--- a/src/transport/plugin_transport_unix.c
+++ b/src/transport/plugin_transport_unix.c
@@ -102,13 +102,9 @@ struct UNIXMessageWrapper
102 102
103 int retry_counter; 103 int retry_counter;
104 104
105 struct GNUNET_PeerIdentity target;
106
107 struct GNUNET_TIME_Relative timeout; 105 struct GNUNET_TIME_Relative timeout;
108 unsigned int priority; 106 unsigned int priority;
109 107
110 void *addr;
111 size_t addrlen;
112 struct Session *session; 108 struct Session *session;
113 GNUNET_TRANSPORT_TransmitContinuation cont; 109 GNUNET_TRANSPORT_TransmitContinuation cont;
114 void *cont_cls; 110 void *cont_cls;
@@ -250,6 +246,27 @@ struct Plugin
250 struct GNUNET_ATS_Information ats_network; 246 struct GNUNET_ATS_Information ats_network;
251}; 247};
252 248
249
250static int
251get_session_delete_it (void *cls, const GNUNET_HashCode * key, void *value)
252{
253 struct Session *s = value;
254 struct Plugin *plugin = cls;
255 GNUNET_assert (plugin != NULL);
256
257#if DEBUG_UNIX
258 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleting session for peer `%s' `%s' \n", GNUNET_i2s (&s->target), s->addr);
259#endif
260
261 plugin->env->session_end (plugin->env->cls, &s->target, s);
262
263 GNUNET_CONTAINER_multihashmap_remove(plugin->session_map, &s->target.hashPubKey, s);
264
265 GNUNET_free (s);
266
267 return GNUNET_YES;
268}
269
253/** 270/**
254 * Disconnect from a remote node. Clean up session if we have one for this peer 271 * Disconnect from a remote node. Clean up session if we have one for this peer
255 * 272 *
@@ -260,7 +277,10 @@ struct Plugin
260void 277void
261unix_disconnect (void *cls, const struct GNUNET_PeerIdentity *target) 278unix_disconnect (void *cls, const struct GNUNET_PeerIdentity *target)
262{ 279{
263 /** TODO: Implement! */ 280 struct Plugin *plugin = cls;
281 GNUNET_assert (plugin != NULL);
282
283 GNUNET_CONTAINER_multihashmap_get_multiple (plugin->session_map, &target->hashPubKey, &get_session_delete_it, plugin);
264 return; 284 return;
265} 285}
266 286
@@ -284,7 +304,7 @@ unix_transport_server_stop (void *cls)
284 { 304 {
285 GNUNET_CONTAINER_DLL_remove (plugin->msg_head, plugin->msg_tail, msgw); 305 GNUNET_CONTAINER_DLL_remove (plugin->msg_head, plugin->msg_tail, msgw);
286 if (msgw->cont != NULL) 306 if (msgw->cont != NULL)
287 msgw->cont (msgw->cont_cls, &msgw->target, GNUNET_SYSERR); 307 msgw->cont (msgw->cont_cls, &msgw->session->target, GNUNET_SYSERR);
288 GNUNET_free (msgw->msg); 308 GNUNET_free (msgw->msg);
289 GNUNET_free (msgw); 309 GNUNET_free (msgw);
290 } 310 }
@@ -432,7 +452,7 @@ unix_real_send (void *cls,
432 } 452 }
433 453
434#if DEBUG_UNIX 454#if DEBUG_UNIX
435 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 455 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
436 "UNIX transmit %u-byte message to %s (%d: %s)\n", 456 "UNIX transmit %u-byte message to %s (%d: %s)\n",
437 (unsigned int) msgbuf_size, GNUNET_a2s (sb, sbs), (int) sent, 457 (unsigned int) msgbuf_size, GNUNET_a2s (sb, sbs), (int) sent,
438 (sent < 0) ? STRERROR (errno) : "ok"); 458 (sent < 0) ? STRERROR (errno) : "ok");
@@ -461,7 +481,8 @@ unix_real_send (void *cls,
461 481
462struct gsi_ctx 482struct gsi_ctx
463{ 483{
464 const struct GNUNET_HELLO_Address *address; 484 char *address;
485 size_t addrlen;
465 struct Session *res; 486 struct Session *res;
466}; 487};
467 488
@@ -471,8 +492,11 @@ get_session_it (void *cls, const GNUNET_HashCode * key, void *value)
471 struct gsi_ctx *gsi = cls; 492 struct gsi_ctx *gsi = cls;
472 struct Session *s = value; 493 struct Session *s = value;
473 494
474 if ((gsi->address->address_length == s->addrlen) && 495#if DEBUG_UNIX
475 (0 == memcmp (gsi->address->address, s->addr, s->addrlen))) 496 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Comparing session %s %s\n", gsi->address, s->addr);
497#endif
498 if ((gsi->addrlen == s->addrlen) &&
499 (0 == memcmp (gsi->address, s->addr, s->addrlen)))
476 { 500 {
477 gsi->res = s; 501 gsi->res = s;
478 return GNUNET_NO; 502 return GNUNET_NO;
@@ -501,14 +525,33 @@ unix_plugin_get_session (void *cls,
501 GNUNET_assert (address != NULL); 525 GNUNET_assert (address != NULL);
502 526
503 /* Check if already existing */ 527 /* Check if already existing */
504 gsi.address = address; 528 gsi.address = (char *) address->address;
529 gsi.addrlen = address->address_length;
505 gsi.res = NULL; 530 gsi.res = NULL;
506 GNUNET_CONTAINER_multihashmap_get_multiple (plugin->session_map, &address->peer.hashPubKey, &get_session_it, &gsi); 531 GNUNET_CONTAINER_multihashmap_get_multiple (plugin->session_map, &address->peer.hashPubKey, &get_session_it, &gsi);
532 if (gsi.res != NULL)
533 {
534#if DEBUG_UNIX
535 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found existing session\n");
536#endif
537 return gsi.res;
538 }
507 539
508 /* Create a new session */ 540 /* Create a new session */
509 541
510 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "To be implemented\n"); 542 s = GNUNET_malloc (sizeof (struct Session) + address->address_length);
511 GNUNET_break (0); 543 s->addr = &s[1];
544 s->addrlen = address->address_length;
545 memcpy(s->addr, address->address, s->addrlen);
546 memcpy(&s->target, &address->peer, sizeof (struct GNUNET_PeerIdentity));
547
548 GNUNET_CONTAINER_multihashmap_put (plugin->session_map,
549 &address->peer.hashPubKey, s,
550 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
551#if DEBUG_UNIX
552 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating new session\n");
553#endif
554
512 return s; 555 return s;
513} 556}
514 557
@@ -547,10 +590,47 @@ unix_plugin_send (void *cls,
547 struct GNUNET_TIME_Relative to, 590 struct GNUNET_TIME_Relative to,
548 GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls) 591 GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls)
549{ 592{
550 ssize_t sent = -1; 593 struct Plugin *plugin = cls;
551 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "To be implemented\n"); 594 struct UNIXMessageWrapper *wrapper;
552 GNUNET_break (0); 595 struct UNIXMessage *message;
553 return sent; 596 int ssize;
597
598 GNUNET_assert (plugin != NULL);
599 GNUNET_assert (session != NULL);
600
601 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_contains_value(plugin->session_map,
602 &session->target.hashPubKey, session))
603 {
604 GNUNET_break (0);
605 return GNUNET_SYSERR;
606 }
607
608 ssize = sizeof (struct UNIXMessage) + msgbuf_size;
609 message = GNUNET_malloc (sizeof (struct UNIXMessage) + msgbuf_size);
610 message->header.size = htons (ssize);
611 message->header.type = htons (0);
612 memcpy (&message->sender, plugin->env->my_identity,
613 sizeof (struct GNUNET_PeerIdentity));
614 memcpy (&message[1], msgbuf, msgbuf_size);
615
616 wrapper = GNUNET_malloc (sizeof (struct UNIXMessageWrapper));
617 wrapper->msg = message;
618 wrapper->msgsize = ssize;
619 wrapper->priority = priority;
620 wrapper->timeout = to;
621 wrapper->cont = cont;
622 wrapper->cont_cls = cont_cls;
623 wrapper->retry_counter = 0;
624 wrapper->session = session;
625
626 GNUNET_CONTAINER_DLL_insert(plugin->msg_head, plugin->msg_tail, wrapper);
627
628#if DEBUG_UNIX
629 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sent %d bytes to `%s'\n", sent,
630 (char *) session->addr);
631#endif
632
633 return ssize;
554} 634}
555 635
556 636
@@ -589,8 +669,7 @@ unix_plugin_send_old (void *cls, const struct GNUNET_PeerIdentity *target,
589 struct UNIXMessage *message; 669 struct UNIXMessage *message;
590 struct UNIXMessageWrapper *wrapper; 670 struct UNIXMessageWrapper *wrapper;
591 int ssize; 671 int ssize;
592 672 struct gsi_ctx gsi;
593 GNUNET_assert (NULL == session);
594 673
595 /* Build the message to be sent */ 674 /* Build the message to be sent */
596 wrapper = GNUNET_malloc (sizeof (struct UNIXMessageWrapper) + addrlen); 675 wrapper = GNUNET_malloc (sizeof (struct UNIXMessageWrapper) + addrlen);
@@ -608,18 +687,41 @@ unix_plugin_send_old (void *cls, const struct GNUNET_PeerIdentity *target,
608 sizeof (struct GNUNET_PeerIdentity)); 687 sizeof (struct GNUNET_PeerIdentity));
609 memcpy (&message[1], msgbuf, msgbuf_size); 688 memcpy (&message[1], msgbuf, msgbuf_size);
610 689
690 if (session == NULL)
691 {
692 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking for existing session\n");
693 gsi.address = (char *) addr;
694 gsi.addrlen = addrlen;
695 gsi.res = NULL;
696 GNUNET_CONTAINER_multihashmap_get_multiple (plugin->session_map, &target->hashPubKey, &get_session_it, &gsi);
697 wrapper->session = gsi.res;
698 if (gsi.res == NULL)
699 {
700 wrapper->session = GNUNET_malloc (sizeof (struct Session) + addrlen);
701 wrapper->session->addr = &wrapper->session[1];
702 wrapper->session->addrlen = addrlen;
703 memcpy(wrapper->session->addr, addr, wrapper->session->addrlen);
704 memcpy(&wrapper->session->target, target, sizeof (struct GNUNET_PeerIdentity));
705 GNUNET_CONTAINER_multihashmap_put (plugin->session_map,
706 &target->hashPubKey, wrapper->session,
707 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
708
709 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created new session for `%s'\n", addr);
710 }
711 else
712 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found existing session\n");
713
714 }
715 else
716 wrapper->session = session;
717
611 wrapper->msg = message; 718 wrapper->msg = message;
612 wrapper->msgsize = ssize; 719 wrapper->msgsize = ssize;
613 wrapper->priority = priority; 720 wrapper->priority = priority;
614 wrapper->timeout = timeout; 721 wrapper->timeout = timeout;
615 wrapper->cont = cont; 722 wrapper->cont = cont;
616 wrapper->cont_cls = cont_cls; 723 wrapper->cont_cls = cont_cls;
617 wrapper->addr = &wrapper[1];
618 wrapper->addrlen = addrlen;
619 wrapper->retry_counter = 0; 724 wrapper->retry_counter = 0;
620 memcpy (&wrapper->target, target, sizeof (struct GNUNET_PeerIdentity));
621 memcpy (&wrapper[1], addr, addrlen);
622
623 GNUNET_CONTAINER_DLL_insert(plugin->msg_head, plugin->msg_tail, wrapper); 725 GNUNET_CONTAINER_DLL_insert(plugin->msg_head, plugin->msg_tail, wrapper);
624 726
625#if DEBUG_UNIX 727#if DEBUG_UNIX
@@ -737,19 +839,20 @@ unix_plugin_select_write (struct Plugin * plugin)
737 839
738 sent = unix_real_send (plugin, 840 sent = unix_real_send (plugin,
739 plugin->unix_sock.desc, 841 plugin->unix_sock.desc,
740 &msgw->target, 842 &msgw->session->target,
741 (const char *) msgw->msg, 843 (const char *) msgw->msg,
742 msgw->msgsize, 844 msgw->msgsize,
743 msgw->priority, 845 msgw->priority,
744 msgw->timeout, 846 msgw->timeout,
745 msgw->addr, 847 msgw->session->addr,
746 msgw->addrlen, 848 msgw->session->addrlen,
747 msgw->cont, msgw->cont_cls); 849 msgw->cont, msgw->cont_cls);
748 850
749 /* successfully sent bytes */ 851 /* successfully sent bytes */
750 if (sent > 0) 852 if (sent > 0)
751 { 853 {
752 GNUNET_CONTAINER_DLL_remove(plugin->msg_head, plugin->msg_tail, msgw); 854 GNUNET_CONTAINER_DLL_remove(plugin->msg_head, plugin->msg_tail, msgw);
855 GNUNET_free (msgw->msg);
753 GNUNET_free (msgw); 856 GNUNET_free (msgw);
754 return; 857 return;
755 } 858 }
@@ -757,9 +860,10 @@ unix_plugin_select_write (struct Plugin * plugin)
757 /* max retries */ 860 /* max retries */
758 if (msgw->retry_counter > MAX_RETRIES) 861 if (msgw->retry_counter > MAX_RETRIES)
759 { 862 {
760 msgw->cont (msgw->cont_cls, &msgw->target, GNUNET_SYSERR); 863 msgw->cont (msgw->cont_cls, &msgw->session->target, GNUNET_SYSERR);
761 GNUNET_CONTAINER_DLL_remove(plugin->msg_head, plugin->msg_tail, msgw); 864 GNUNET_CONTAINER_DLL_remove(plugin->msg_head, plugin->msg_tail, msgw);
762 GNUNET_break (0); 865 GNUNET_break (0);
866 GNUNET_free (msgw->msg);
763 GNUNET_free (msgw); 867 GNUNET_free (msgw);
764 return; 868 return;
765 } 869 }
@@ -768,6 +872,7 @@ unix_plugin_select_write (struct Plugin * plugin)
768 if (sent == -1) 872 if (sent == -1)
769 { 873 {
770 GNUNET_CONTAINER_DLL_remove(plugin->msg_head, plugin->msg_tail, msgw); 874 GNUNET_CONTAINER_DLL_remove(plugin->msg_head, plugin->msg_tail, msgw);
875 GNUNET_free (msgw->msg);
771 GNUNET_free (msgw); 876 GNUNET_free (msgw);
772 return; 877 return;
773 } 878 }
@@ -1039,6 +1144,7 @@ libgnunet_plugin_transport_unix_done (void *cls)
1039 1144
1040 unix_transport_server_stop (plugin); 1145 unix_transport_server_stop (plugin);
1041 1146
1147 GNUNET_CONTAINER_multihashmap_iterate (plugin->session_map, &get_session_delete_it, plugin);
1042 GNUNET_CONTAINER_multihashmap_destroy (plugin->session_map); 1148 GNUNET_CONTAINER_multihashmap_destroy (plugin->session_map);
1043 1149
1044 GNUNET_NETWORK_fdset_destroy (plugin->rs); 1150 GNUNET_NETWORK_fdset_destroy (plugin->rs);