diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2012-01-27 15:51:30 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2012-01-27 15:51:30 +0000 |
commit | 3716d50b290b939ff856196806951c134eff88ff (patch) | |
tree | dcc99d98186ea4ca9f1c8404c942730921fb9a57 /src/transport/plugin_transport_unix.c | |
parent | 240e3109cde69be3752a44b8ed7799599171fc80 (diff) | |
download | gnunet-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.c | 162 |
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 | |||
250 | static int | ||
251 | get_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 | |||
260 | void | 277 | void |
261 | unix_disconnect (void *cls, const struct GNUNET_PeerIdentity *target) | 278 | unix_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 | ||
462 | struct gsi_ctx | 482 | struct 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); |