diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2011-10-26 09:21:18 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2011-10-26 09:21:18 +0000 |
commit | 2b500f19f324c22cbedbaecaa2763bc781711730 (patch) | |
tree | 64635111e3aeabe91c4952ff67111052f0ca8a27 /src | |
parent | 70eaa3dda652deed20a9ec5ff228a5620db0016e (diff) | |
download | gnunet-2b500f19f324c22cbedbaecaa2763bc781711730.tar.gz gnunet-2b500f19f324c22cbedbaecaa2763bc781711730.zip |
Diffstat (limited to 'src')
-rw-r--r-- | src/transport/gnunet-service-transport_neighbours_fsm.c | 289 |
1 files changed, 185 insertions, 104 deletions
diff --git a/src/transport/gnunet-service-transport_neighbours_fsm.c b/src/transport/gnunet-service-transport_neighbours_fsm.c index 015a25062..ca5eb959d 100644 --- a/src/transport/gnunet-service-transport_neighbours_fsm.c +++ b/src/transport/gnunet-service-transport_neighbours_fsm.c | |||
@@ -189,7 +189,8 @@ enum State | |||
189 | S_CONNECT_RECV_ACK_SENT = 8, | 189 | S_CONNECT_RECV_ACK_SENT = 8, |
190 | /* received ACK or payload */ | 190 | /* received ACK or payload */ |
191 | S_CONNECTED = 16, | 191 | S_CONNECTED = 16, |
192 | S_DISCONNECTED = 32 | 192 | /* Disconnect in progress */ |
193 | S_DISCONNECT = 32 | ||
193 | }; | 194 | }; |
194 | 195 | ||
195 | /** | 196 | /** |
@@ -293,7 +294,7 @@ struct NeighbourMapEntry | |||
293 | * Do we currently consider this neighbour connected? (as far as | 294 | * Do we currently consider this neighbour connected? (as far as |
294 | * the connect/disconnect callbacks are concerned)? | 295 | * the connect/disconnect callbacks are concerned)? |
295 | */ | 296 | */ |
296 | int is_connected; | 297 | //int is_connected; |
297 | 298 | ||
298 | int state; | 299 | int state; |
299 | 300 | ||
@@ -340,6 +341,30 @@ lookup_neighbour (const struct GNUNET_PeerIdentity *pid) | |||
340 | #define change_state(n, state, ...) change (n, state, __LINE__) | 341 | #define change_state(n, state, ...) change (n, state, __LINE__) |
341 | 342 | ||
342 | static int | 343 | static int |
344 | is_connecting (struct NeighbourMapEntry * n) | ||
345 | { | ||
346 | if ((n->state > S_NOT_CONNECTED) && (n->state < S_CONNECTED)) | ||
347 | return GNUNET_YES; | ||
348 | return GNUNET_NO; | ||
349 | } | ||
350 | |||
351 | static int | ||
352 | is_connected (struct NeighbourMapEntry * n) | ||
353 | { | ||
354 | if (n->state == S_CONNECTED) | ||
355 | return GNUNET_YES; | ||
356 | return GNUNET_NO; | ||
357 | } | ||
358 | |||
359 | static int | ||
360 | is_disconnecting (struct NeighbourMapEntry * n) | ||
361 | { | ||
362 | if (n->state == S_DISCONNECT) | ||
363 | return GNUNET_YES; | ||
364 | return GNUNET_NO; | ||
365 | } | ||
366 | |||
367 | static int | ||
343 | change (struct NeighbourMapEntry * n, int state, int line) | 368 | change (struct NeighbourMapEntry * n, int state, int line) |
344 | { | 369 | { |
345 | char * old = NULL; | 370 | char * old = NULL; |
@@ -358,7 +383,7 @@ change (struct NeighbourMapEntry * n, int state, int line) | |||
358 | case S_CONNECT_SENT: | 383 | case S_CONNECT_SENT: |
359 | old = "S_CONNECT_SENT"; | 384 | old = "S_CONNECT_SENT"; |
360 | break; | 385 | break; |
361 | case S_DISCONNECTED: | 386 | case S_DISCONNECT: |
362 | old = "S_DISCONNECTED"; | 387 | old = "S_DISCONNECTED"; |
363 | break; | 388 | break; |
364 | case S_NOT_CONNECTED: | 389 | case S_NOT_CONNECTED: |
@@ -382,7 +407,7 @@ change (struct NeighbourMapEntry * n, int state, int line) | |||
382 | case S_CONNECT_SENT: | 407 | case S_CONNECT_SENT: |
383 | new = "S_CONNECT_SENT"; | 408 | new = "S_CONNECT_SENT"; |
384 | break; | 409 | break; |
385 | case S_DISCONNECTED: | 410 | case S_DISCONNECT: |
386 | new = "S_DISCONNECTED"; | 411 | new = "S_DISCONNECTED"; |
387 | break; | 412 | break; |
388 | case S_NOT_CONNECTED: | 413 | case S_NOT_CONNECTED: |
@@ -424,7 +449,7 @@ change (struct NeighbourMapEntry * n, int state, int line) | |||
424 | break; | 449 | break; |
425 | } | 450 | } |
426 | break; | 451 | break; |
427 | case S_DISCONNECTED: | 452 | case S_DISCONNECT: |
428 | break; | 453 | break; |
429 | default: | 454 | default: |
430 | GNUNET_break (0); | 455 | GNUNET_break (0); |
@@ -447,6 +472,49 @@ change (struct NeighbourMapEntry * n, int state, int line) | |||
447 | return GNUNET_OK; | 472 | return GNUNET_OK; |
448 | } | 473 | } |
449 | 474 | ||
475 | static ssize_t | ||
476 | send_with_plugin (void *cls, | ||
477 | const struct GNUNET_PeerIdentity * target, | ||
478 | const char *msgbuf, | ||
479 | size_t msgbuf_size, | ||
480 | uint32_t priority, | ||
481 | struct GNUNET_TIME_Relative timeout, | ||
482 | struct Session * session, | ||
483 | const char * plugin_name, | ||
484 | const void *addr, | ||
485 | size_t addrlen, | ||
486 | int force_address, | ||
487 | GNUNET_TRANSPORT_TransmitContinuation cont, | ||
488 | void *cont_cls) | ||
489 | |||
490 | { | ||
491 | struct GNUNET_TRANSPORT_PluginFunctions *papi; | ||
492 | size_t ret = GNUNET_SYSERR; | ||
493 | |||
494 | papi = GST_plugins_find (plugin_name); | ||
495 | GNUNET_assert (papi != NULL); | ||
496 | |||
497 | ret = papi->send (papi->cls, | ||
498 | target, | ||
499 | msgbuf, msgbuf_size, | ||
500 | 0, | ||
501 | timeout, | ||
502 | session, | ||
503 | addr, addrlen, | ||
504 | GNUNET_YES, | ||
505 | cont, cont_cls); | ||
506 | |||
507 | if (ret == -1) | ||
508 | { | ||
509 | cont (cont_cls, target, GNUNET_SYSERR); | ||
510 | } | ||
511 | else | ||
512 | { | ||
513 | cont (cont_cls, target, GNUNET_OK); | ||
514 | } | ||
515 | return ret; | ||
516 | } | ||
517 | |||
450 | /** | 518 | /** |
451 | * Task invoked to start a transmission to another peer. | 519 | * Task invoked to start a transmission to another peer. |
452 | * | 520 | * |
@@ -612,6 +680,15 @@ disconnect_neighbour (struct NeighbourMapEntry *n) | |||
612 | { | 680 | { |
613 | struct MessageQueue *mq; | 681 | struct MessageQueue *mq; |
614 | 682 | ||
683 | if (is_disconnecting(n) == GNUNET_YES) | ||
684 | return; | ||
685 | |||
686 | /* send DISCONNECT MESSAGE */ | ||
687 | if (is_connected(n) || is_connecting(n)) | ||
688 | { | ||
689 | change_state (n, S_DISCONNECT); | ||
690 | } | ||
691 | |||
615 | if (GNUNET_YES == n->in_disconnect) | 692 | if (GNUNET_YES == n->in_disconnect) |
616 | return; | 693 | return; |
617 | n->in_disconnect = GNUNET_YES; | 694 | n->in_disconnect = GNUNET_YES; |
@@ -627,7 +704,7 @@ disconnect_neighbour (struct NeighbourMapEntry *n) | |||
627 | n->is_active->n = NULL; | 704 | n->is_active->n = NULL; |
628 | n->is_active = NULL; | 705 | n->is_active = NULL; |
629 | } | 706 | } |
630 | if (n->state == S_CONNECTED) | 707 | if (is_connected (n)) |
631 | { | 708 | { |
632 | change_state (n, S_NOT_CONNECTED); | 709 | change_state (n, S_NOT_CONNECTED); |
633 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != n->keepalive_task); | 710 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != n->keepalive_task); |
@@ -683,8 +760,8 @@ neighbour_timeout_task (void *cls, | |||
683 | struct NeighbourMapEntry *n = cls; | 760 | struct NeighbourMapEntry *n = cls; |
684 | 761 | ||
685 | n->timeout_task = GNUNET_SCHEDULER_NO_TASK; | 762 | n->timeout_task = GNUNET_SCHEDULER_NO_TASK; |
686 | if (GNUNET_YES == n->is_connected) | 763 | |
687 | GNUNET_STATISTICS_update (GST_stats, | 764 | GNUNET_STATISTICS_update (GST_stats, |
688 | gettext_noop ("# peers disconnected due to timeout"), 1, | 765 | gettext_noop ("# peers disconnected due to timeout"), 1, |
689 | GNUNET_NO); | 766 | GNUNET_NO); |
690 | disconnect_neighbour (n); | 767 | disconnect_neighbour (n); |
@@ -703,25 +780,23 @@ neighbour_keepalive_task (void *cls, | |||
703 | { | 780 | { |
704 | struct NeighbourMapEntry *n = cls; | 781 | struct NeighbourMapEntry *n = cls; |
705 | struct GNUNET_MessageHeader m; | 782 | struct GNUNET_MessageHeader m; |
706 | struct GNUNET_TRANSPORT_PluginFunctions *papi; | ||
707 | 783 | ||
708 | n->keepalive_task = GNUNET_SCHEDULER_add_delayed (KEEPALIVE_FREQUENCY, | 784 | n->keepalive_task = GNUNET_SCHEDULER_add_delayed (KEEPALIVE_FREQUENCY, |
709 | &neighbour_keepalive_task, | 785 | &neighbour_keepalive_task, |
710 | n); | 786 | n); |
711 | GNUNET_assert (GNUNET_YES == n->is_connected); | 787 | GNUNET_assert (is_connected(n)); |
712 | GNUNET_STATISTICS_update (GST_stats, | 788 | GNUNET_STATISTICS_update (GST_stats, |
713 | gettext_noop ("# keepalives sent"), 1, | 789 | gettext_noop ("# keepalives sent"), 1, |
714 | GNUNET_NO); | 790 | GNUNET_NO); |
715 | m.size = htons (sizeof (struct GNUNET_MessageHeader)); | 791 | m.size = htons (sizeof (struct GNUNET_MessageHeader)); |
716 | m.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE); | 792 | m.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE); |
717 | papi = GST_plugins_find (n->plugin_name); | 793 | |
718 | if (papi != NULL) | 794 | send_with_plugin(NULL, &n->id, (const void *) &m, |
719 | papi->send (papi->cls, | 795 | sizeof (m), |
720 | &n->id, (const void *) &m, | 796 | UINT32_MAX /* priority */ , |
721 | sizeof (m), | 797 | GNUNET_TIME_UNIT_FOREVER_REL, |
722 | UINT32_MAX /* priority */ , | 798 | n->session, n->plugin_name, n->addr, n->addrlen, |
723 | GNUNET_TIME_UNIT_FOREVER_REL, n->session, n->addr, n->addrlen, | 799 | GNUNET_YES, NULL, NULL); |
724 | GNUNET_YES, NULL, NULL); | ||
725 | } | 800 | } |
726 | 801 | ||
727 | 802 | ||
@@ -741,7 +816,7 @@ disconnect_all_neighbours (void *cls, const GNUNET_HashCode * key, void *value) | |||
741 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting peer `%4s', %s\n", | 816 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting peer `%4s', %s\n", |
742 | GNUNET_i2s (&n->id), "SHUTDOWN_TASK"); | 817 | GNUNET_i2s (&n->id), "SHUTDOWN_TASK"); |
743 | #endif | 818 | #endif |
744 | if (GNUNET_YES == n->is_connected) | 819 | if (n->state == S_CONNECTED) |
745 | GNUNET_STATISTICS_update (GST_stats, | 820 | GNUNET_STATISTICS_update (GST_stats, |
746 | gettext_noop ("# peers disconnected due to global disconnect"), 1, | 821 | gettext_noop ("# peers disconnected due to global disconnect"), 1, |
747 | GNUNET_NO); | 822 | GNUNET_NO); |
@@ -771,7 +846,7 @@ GST_neighbours_stop () | |||
771 | 846 | ||
772 | /** | 847 | /** |
773 | * We tried to send a SESSION_CONNECT message to another peer. If this | 848 | * We tried to send a SESSION_CONNECT message to another peer. If this |
774 | * succeeded, we should mark the peer up. If it failed, we should tell | 849 | * succeeded, we change the state. If it failed, we should tell |
775 | * ATS to not use this address anymore (until it is re-validated). | 850 | * ATS to not use this address anymore (until it is re-validated). |
776 | * | 851 | * |
777 | * @param cls the 'struct NeighbourMapEntry' | 852 | * @param cls the 'struct NeighbourMapEntry' |
@@ -779,7 +854,9 @@ GST_neighbours_stop () | |||
779 | */ | 854 | */ |
780 | static void | 855 | static void |
781 | send_connect_continuation (void *cls, | 856 | send_connect_continuation (void *cls, |
782 | int success) | 857 | const struct GNUNET_PeerIdentity * target, |
858 | int success) | ||
859 | |||
783 | { | 860 | { |
784 | struct NeighbourMapEntry *n = cls; | 861 | struct NeighbourMapEntry *n = cls; |
785 | 862 | ||
@@ -788,14 +865,25 @@ send_connect_continuation (void *cls, | |||
788 | return; /* neighbour is going away */ | 865 | return; /* neighbour is going away */ |
789 | if (GNUNET_YES != success) | 866 | if (GNUNET_YES != success) |
790 | { | 867 | { |
868 | #if DEBUG_TRANSPORT | ||
869 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
870 | "Failed to send CONNECT_MSG to peer `%4s' with plugin `%s' address '%s' session %X, asking ATS for new address \n", | ||
871 | GNUNET_i2s (&n->id), n->plugin_name, | ||
872 | (n->addrlen == 0) ? "<inbound>" : GST_plugins_a2s (n->plugin_name, | ||
873 | n->addr, | ||
874 | n->addrlen), | ||
875 | n->session); | ||
876 | #endif | ||
791 | change_state(n, S_NOT_CONNECTED); | 877 | change_state(n, S_NOT_CONNECTED); |
878 | |||
792 | GNUNET_ATS_address_destroyed (GST_ats, | 879 | GNUNET_ATS_address_destroyed (GST_ats, |
793 | &n->id, | 880 | &n->id, |
794 | n->plugin_name, | 881 | n->plugin_name, |
795 | n->addr, | 882 | n->addr, |
796 | n->addrlen, | 883 | n->addrlen, |
797 | NULL); | 884 | NULL); |
798 | disconnect_neighbour (n); | 885 | |
886 | GNUNET_ATS_suggest_address(GST_ats, &n->id); | ||
799 | return; | 887 | return; |
800 | } | 888 | } |
801 | } | 889 | } |
@@ -825,7 +913,8 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer, | |||
825 | { | 913 | { |
826 | struct NeighbourMapEntry *n; | 914 | struct NeighbourMapEntry *n; |
827 | struct SessionConnectMessage connect_msg; | 915 | struct SessionConnectMessage connect_msg; |
828 | //int was_connected; | 916 | size_t len; |
917 | size_t ret; | ||
829 | 918 | ||
830 | GNUNET_assert (neighbours != NULL); | 919 | GNUNET_assert (neighbours != NULL); |
831 | n = lookup_neighbour (peer); | 920 | n = lookup_neighbour (peer); |
@@ -838,13 +927,6 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer, | |||
838 | address_len, NULL); | 927 | address_len, NULL); |
839 | return GNUNET_NO; | 928 | return GNUNET_NO; |
840 | } | 929 | } |
841 | /* | ||
842 | was_connected = n->is_connected; | ||
843 | n->is_connected = GNUNET_YES; | ||
844 | if (GNUNET_YES != was_connected) | ||
845 | n->keepalive_task = GNUNET_SCHEDULER_add_delayed (KEEPALIVE_FREQUENCY, | ||
846 | &neighbour_keepalive_task, | ||
847 | n);*/ | ||
848 | 930 | ||
849 | change_state (n, S_CONNECT_SENT); | 931 | change_state (n, S_CONNECT_SENT); |
850 | 932 | ||
@@ -868,26 +950,26 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer, | |||
868 | n->timeout_task = | 950 | n->timeout_task = |
869 | GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, | 951 | GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, |
870 | &neighbour_timeout_task, n); | 952 | &neighbour_timeout_task, n); |
871 | connect_msg.header.size = htons (sizeof (struct SessionConnectMessage)); | 953 | |
954 | len = sizeof (struct SessionConnectMessage); | ||
955 | connect_msg.header.size = htons (len); | ||
872 | connect_msg.header.type = | 956 | connect_msg.header.type = |
873 | htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_CONNECT); | 957 | htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_CONNECT); |
874 | connect_msg.reserved = htonl (0); | 958 | connect_msg.reserved = htonl (0); |
875 | connect_msg.timestamp = | 959 | connect_msg.timestamp = |
876 | GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ()); | 960 | GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ()); |
877 | GST_neighbours_send (peer, &connect_msg, sizeof (connect_msg), | 961 | |
878 | GNUNET_TIME_UNIT_FOREVER_REL, | 962 | ret =send_with_plugin (NULL, peer, (const char *) &connect_msg, len, 0, GNUNET_TIME_UNIT_FOREVER_REL, session, plugin_name, address, address_len, GNUNET_YES, &send_connect_continuation, n); |
879 | &send_connect_continuation, | 963 | if (ret == GNUNET_SYSERR) |
880 | n); | 964 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
881 | /* | 965 | "Failed to send CONNECT_MESSAGE to `%4s' using plugin `%s' address '%s' session %X\n", |
882 | if (GNUNET_YES == was_connected) | 966 | GNUNET_i2s (peer), plugin_name, |
883 | return GNUNET_YES; | 967 | (address_len == 0) ? "<inbound>" : GST_plugins_a2s (plugin_name, |
884 | // First tell clients about connected neighbours... | 968 | address, |
885 | neighbours_connected++; | 969 | address_len), |
886 | GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# peers connected"), 1, | 970 | session); |
887 | GNUNET_NO); | 971 | |
888 | connect_notify_cb (callback_cls, peer, ats, ats_count); | 972 | |
889 | return GNUNET_YES;*/ | ||
890 | /* connection not yet up */ | ||
891 | return GNUNET_NO; | 973 | return GNUNET_NO; |
892 | } | 974 | } |
893 | 975 | ||
@@ -946,7 +1028,7 @@ GST_neighbours_try_connect (const struct GNUNET_PeerIdentity *target) | |||
946 | memcmp (target, &GST_my_identity, | 1028 | memcmp (target, &GST_my_identity, |
947 | sizeof (struct GNUNET_PeerIdentity))); | 1029 | sizeof (struct GNUNET_PeerIdentity))); |
948 | n = lookup_neighbour (target); | 1030 | n = lookup_neighbour (target); |
949 | if ((NULL != n) && (GNUNET_YES == n->is_connected)) | 1031 | if ((NULL != n) && (n->state > S_CONNECTED)) |
950 | return; /* already connected */ | 1032 | return; /* already connected */ |
951 | 1033 | ||
952 | if ((NULL != n) && (n->state > S_NOT_CONNECTED)) | 1034 | if ((NULL != n) && (n->state > S_NOT_CONNECTED)) |
@@ -1015,7 +1097,7 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer, | |||
1015 | n->addrlen = 0; | 1097 | n->addrlen = 0; |
1016 | 1098 | ||
1017 | 1099 | ||
1018 | if (GNUNET_YES != n->is_connected) | 1100 | if (!is_connected(n)) |
1019 | return; /* not connected anymore anyway, shouldn't matter */ | 1101 | return; /* not connected anymore anyway, shouldn't matter */ |
1020 | /* fast disconnect unless ATS suggests a new address */ | 1102 | /* fast disconnect unless ATS suggests a new address */ |
1021 | GNUNET_SCHEDULER_cancel (n->timeout_task); | 1103 | GNUNET_SCHEDULER_cancel (n->timeout_task); |
@@ -1048,8 +1130,7 @@ GST_neighbours_send (const struct GNUNET_PeerIdentity *target, const void *msg, | |||
1048 | GNUNET_assert (neighbours != NULL); | 1130 | GNUNET_assert (neighbours != NULL); |
1049 | 1131 | ||
1050 | n = lookup_neighbour (target); | 1132 | n = lookup_neighbour (target); |
1051 | /* FIXME */ | 1133 | if ((n == NULL) || (n->state != S_CONNECTED)) |
1052 | if ((n == NULL) /* || (GNUNET_YES != n->is_connected)*/) | ||
1053 | { | 1134 | { |
1054 | GNUNET_STATISTICS_update (GST_stats, | 1135 | GNUNET_STATISTICS_update (GST_stats, |
1055 | gettext_noop | 1136 | gettext_noop |
@@ -1060,7 +1141,7 @@ GST_neighbours_send (const struct GNUNET_PeerIdentity *target, const void *msg, | |||
1060 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1141 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1061 | "Could not send message to peer `%s': unknown neighbor", | 1142 | "Could not send message to peer `%s': unknown neighbor", |
1062 | GNUNET_i2s (target)); | 1143 | GNUNET_i2s (target)); |
1063 | else if (GNUNET_YES != n->is_connected) | 1144 | else if (n->state != S_CONNECTED) |
1064 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1145 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1065 | "Could not send message to peer `%s': not connected\n", | 1146 | "Could not send message to peer `%s': not connected\n", |
1066 | GNUNET_i2s (target)); | 1147 | GNUNET_i2s (target)); |
@@ -1069,7 +1150,7 @@ GST_neighbours_send (const struct GNUNET_PeerIdentity *target, const void *msg, | |||
1069 | cont (cont_cls, GNUNET_SYSERR); | 1150 | cont (cont_cls, GNUNET_SYSERR); |
1070 | return; | 1151 | return; |
1071 | } | 1152 | } |
1072 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "GST_neighbours_send %u\n", __LINE__); | 1153 | |
1073 | if ((n->session == NULL) && (n->addr == NULL) && (n->addrlen ==0)) | 1154 | if ((n->session == NULL) && (n->addr == NULL) && (n->addrlen ==0)) |
1074 | { | 1155 | { |
1075 | GNUNET_STATISTICS_update (GST_stats, | 1156 | GNUNET_STATISTICS_update (GST_stats, |
@@ -1086,7 +1167,6 @@ GST_neighbours_send (const struct GNUNET_PeerIdentity *target, const void *msg, | |||
1086 | cont (cont_cls, GNUNET_SYSERR); | 1167 | cont (cont_cls, GNUNET_SYSERR); |
1087 | return; | 1168 | return; |
1088 | } | 1169 | } |
1089 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "GST_neighbours_send %u\n", __LINE__); | ||
1090 | GNUNET_assert (msg_size >= sizeof (struct GNUNET_MessageHeader)); | 1170 | GNUNET_assert (msg_size >= sizeof (struct GNUNET_MessageHeader)); |
1091 | GNUNET_STATISTICS_update (GST_stats, | 1171 | GNUNET_STATISTICS_update (GST_stats, |
1092 | gettext_noop | 1172 | gettext_noop |
@@ -1146,7 +1226,7 @@ GST_neighbours_calculate_receive_delay (const struct GNUNET_PeerIdentity | |||
1146 | return GNUNET_TIME_UNIT_ZERO; | 1226 | return GNUNET_TIME_UNIT_ZERO; |
1147 | } | 1227 | } |
1148 | } | 1228 | } |
1149 | if (GNUNET_YES != n->is_connected) | 1229 | if (!is_connected(n)) |
1150 | { | 1230 | { |
1151 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1231 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
1152 | _("Plugin gave us %d bytes of data but somehow the session is not marked as UP yet!\n"), | 1232 | _("Plugin gave us %d bytes of data but somehow the session is not marked as UP yet!\n"), |
@@ -1263,7 +1343,7 @@ GST_neighbours_set_incoming_quota (const struct GNUNET_PeerIdentity *neighbour, | |||
1263 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting peer `%4s' due to `%s'\n", | 1343 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting peer `%4s' due to `%s'\n", |
1264 | GNUNET_i2s (&n->id), "SET_QUOTA"); | 1344 | GNUNET_i2s (&n->id), "SET_QUOTA"); |
1265 | #endif | 1345 | #endif |
1266 | if (GNUNET_YES == n->is_connected) | 1346 | if (is_connected(n)) |
1267 | GNUNET_STATISTICS_update (GST_stats, | 1347 | GNUNET_STATISTICS_update (GST_stats, |
1268 | gettext_noop ("# disconnects due to quota of 0"), 1, | 1348 | gettext_noop ("# disconnects due to quota of 0"), 1, |
1269 | GNUNET_NO); | 1349 | GNUNET_NO); |
@@ -1302,7 +1382,7 @@ neighbours_iterate (void *cls, const GNUNET_HashCode * key, void *value) | |||
1302 | struct IteratorContext *ic = cls; | 1382 | struct IteratorContext *ic = cls; |
1303 | struct NeighbourMapEntry *n = value; | 1383 | struct NeighbourMapEntry *n = value; |
1304 | 1384 | ||
1305 | if (GNUNET_YES != n->is_connected) | 1385 | if (is_connected(n)) |
1306 | return GNUNET_OK; | 1386 | return GNUNET_OK; |
1307 | 1387 | ||
1308 | ic->cb (ic->cb_cls, &n->id, NULL, 0, n->plugin_name, n->addr, n->addrlen); | 1388 | ic->cb (ic->cb_cls, &n->id, NULL, 0, n->plugin_name, n->addr, n->addrlen); |
@@ -1328,6 +1408,38 @@ GST_neighbours_iterate (GST_NeighbourIterator cb, void *cb_cls) | |||
1328 | GNUNET_CONTAINER_multihashmap_iterate (neighbours, &neighbours_iterate, &ic); | 1408 | GNUNET_CONTAINER_multihashmap_iterate (neighbours, &neighbours_iterate, &ic); |
1329 | } | 1409 | } |
1330 | 1410 | ||
1411 | static void | ||
1412 | send_disconnect (struct NeighbourMapEntry *n) | ||
1413 | { | ||
1414 | size_t ret; | ||
1415 | struct SessionDisconnectMessage disconnect_msg; | ||
1416 | |||
1417 | disconnect_msg.header.size = htons (sizeof (struct SessionDisconnectMessage)); | ||
1418 | disconnect_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DISCONNECT); | ||
1419 | disconnect_msg.reserved = htonl (0); | ||
1420 | disconnect_msg.purpose.size = htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + | ||
1421 | sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) + | ||
1422 | sizeof (struct GNUNET_TIME_AbsoluteNBO) ); | ||
1423 | disconnect_msg.purpose.purpose = htonl (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_DISCONNECT); | ||
1424 | disconnect_msg.timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ()); | ||
1425 | disconnect_msg.public_key = GST_my_public_key; | ||
1426 | GNUNET_assert (GNUNET_OK == | ||
1427 | GNUNET_CRYPTO_rsa_sign (GST_my_private_key, | ||
1428 | &disconnect_msg.purpose, | ||
1429 | &disconnect_msg.signature)); | ||
1430 | |||
1431 | ret = send_with_plugin(NULL, &n->id, | ||
1432 | (const char *) &disconnect_msg, sizeof (disconnect_msg), | ||
1433 | UINT32_MAX, GNUNET_TIME_UNIT_FOREVER_REL, n->session, n->plugin_name, n->addr, n->addrlen, | ||
1434 | GNUNET_YES, NULL, NULL); | ||
1435 | |||
1436 | GNUNET_STATISTICS_update (GST_stats, | ||
1437 | gettext_noop ("# peers disconnected due to external request"), 1, | ||
1438 | GNUNET_NO); | ||
1439 | |||
1440 | if (n->state != S_DISCONNECT) | ||
1441 | change_state (n, S_DISCONNECT); | ||
1442 | } | ||
1331 | 1443 | ||
1332 | /** | 1444 | /** |
1333 | * If we have an active connection to the given target, it must be shutdown. | 1445 | * If we have an active connection to the given target, it must be shutdown. |
@@ -1338,9 +1450,6 @@ void | |||
1338 | GST_neighbours_force_disconnect (const struct GNUNET_PeerIdentity *target) | 1450 | GST_neighbours_force_disconnect (const struct GNUNET_PeerIdentity *target) |
1339 | { | 1451 | { |
1340 | struct NeighbourMapEntry *n; | 1452 | struct NeighbourMapEntry *n; |
1341 | struct GNUNET_TRANSPORT_PluginFunctions *papi; | ||
1342 | struct SessionDisconnectMessage disconnect_msg; | ||
1343 | int ret; | ||
1344 | 1453 | ||
1345 | GNUNET_assert (neighbours != NULL); | 1454 | GNUNET_assert (neighbours != NULL); |
1346 | 1455 | ||
@@ -1349,37 +1458,8 @@ GST_neighbours_force_disconnect (const struct GNUNET_PeerIdentity *target) | |||
1349 | return; /* not active */ | 1458 | return; /* not active */ |
1350 | if (n->state == S_CONNECTED) | 1459 | if (n->state == S_CONNECTED) |
1351 | { | 1460 | { |
1352 | /* we're actually connected, send DISCONNECT message */ | 1461 | send_disconnect(n); |
1353 | disconnect_msg.header.size = htons (sizeof (struct SessionDisconnectMessage)); | 1462 | |
1354 | disconnect_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DISCONNECT); | ||
1355 | disconnect_msg.reserved = htonl (0); | ||
1356 | disconnect_msg.purpose.size = htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + | ||
1357 | sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) + | ||
1358 | sizeof (struct GNUNET_TIME_AbsoluteNBO) ); | ||
1359 | disconnect_msg.purpose.purpose = htonl (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_DISCONNECT); | ||
1360 | disconnect_msg.timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ()); | ||
1361 | disconnect_msg.public_key = GST_my_public_key; | ||
1362 | GNUNET_assert (GNUNET_OK == | ||
1363 | GNUNET_CRYPTO_rsa_sign (GST_my_private_key, | ||
1364 | &disconnect_msg.purpose, | ||
1365 | &disconnect_msg.signature)); | ||
1366 | |||
1367 | papi = GST_plugins_find (n->plugin_name); | ||
1368 | if (papi != NULL) | ||
1369 | { | ||
1370 | ret = papi->send (papi->cls, target, (const void *) &disconnect_msg, | ||
1371 | sizeof (disconnect_msg), | ||
1372 | UINT32_MAX /* priority */ , | ||
1373 | GNUNET_TIME_UNIT_FOREVER_REL, n->session, n->addr, n->addrlen, | ||
1374 | GNUNET_YES, NULL, NULL); | ||
1375 | GNUNET_STATISTICS_update (GST_stats, | ||
1376 | gettext_noop ("# peers disconnected due to external request"), 1, | ||
1377 | GNUNET_NO); | ||
1378 | if (ret == GNUNET_SYSERR) | ||
1379 | change_state (n, S_NOT_CONNECTED); | ||
1380 | else | ||
1381 | change_state (n, S_DISCONNECTED); | ||
1382 | } | ||
1383 | n = lookup_neighbour (target); | 1463 | n = lookup_neighbour (target); |
1384 | if (NULL == n) | 1464 | if (NULL == n) |
1385 | return; /* gone already */ | 1465 | return; /* gone already */ |
@@ -1457,12 +1537,13 @@ static void neighbour_connected (struct NeighbourMapEntry *n, | |||
1457 | const struct GNUNET_ATS_Information *ats, | 1537 | const struct GNUNET_ATS_Information *ats, |
1458 | uint32_t ats_count) | 1538 | uint32_t ats_count) |
1459 | { | 1539 | { |
1460 | struct GNUNET_TRANSPORT_PluginFunctions *papi; | 1540 | struct GNUNET_MessageHeader msg; |
1461 | struct SessionConnectMessage scm; | 1541 | size_t msg_len; |
1462 | int ret; | 1542 | int ret; |
1463 | 1543 | ||
1464 | if (n->state == S_CONNECTED) | 1544 | if (n->state == S_CONNECTED) |
1465 | return; | 1545 | return; |
1546 | |||
1466 | change_state (n, S_CONNECTED); | 1547 | change_state (n, S_CONNECTED); |
1467 | 1548 | ||
1468 | n->keepalive_task = GNUNET_SCHEDULER_add_delayed (KEEPALIVE_FREQUENCY, | 1549 | n->keepalive_task = GNUNET_SCHEDULER_add_delayed (KEEPALIVE_FREQUENCY, |
@@ -1470,20 +1551,20 @@ static void neighbour_connected (struct NeighbourMapEntry *n, | |||
1470 | n); | 1551 | n); |
1471 | 1552 | ||
1472 | /* send CONNECT_ACK (SYN_ACK)*/ | 1553 | /* send CONNECT_ACK (SYN_ACK)*/ |
1473 | scm.header.size = htons (sizeof (struct SessionConnectMessage)); | 1554 | msg_len = sizeof (msg); |
1474 | scm.header.type = | 1555 | msg.size = htons (msg_len); |
1475 | htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_ACK); | 1556 | msg.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_ACK); |
1476 | scm.reserved = htonl (0); | ||
1477 | scm.timestamp = | ||
1478 | GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ()); | ||
1479 | 1557 | ||
1480 | papi = GST_plugins_find (n->plugin_name); | 1558 | ret = send_with_plugin (NULL, &n->id, (const char *) &msg, msg_len, 0, |
1481 | ret = papi->send (papi->cls, &n->id, (const char *) &scm, sizeof (struct SessionConnectMessage), | 1559 | GNUNET_TIME_UNIT_FOREVER_REL, n->session, n->plugin_name, n->addr, n->addrlen, GNUNET_YES, NULL, NULL); |
1482 | 0, | 1560 | if (ret == GNUNET_SYSERR) |
1483 | GNUNET_TIME_UNIT_FOREVER_REL, NULL, n->addr, n->addrlen, GNUNET_YES, | 1561 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1484 | NULL, NULL); | 1562 | "Failed to send CONNECT_MESSAGE to `%4s' using plugin `%s' address '%s' session %X\n", |
1485 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 1563 | GNUNET_i2s (&n->id), n->plugin_name, |
1486 | "neighbour_connected %i\n", ret); | 1564 | (n->addrlen == 0) ? "<inbound>" : GST_plugins_a2s (n->plugin_name, |
1565 | n->addr, | ||
1566 | n->addrlen), | ||
1567 | n->session); | ||
1487 | 1568 | ||
1488 | neighbours_connected++; | 1569 | neighbours_connected++; |
1489 | GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# peers connected"), 1, | 1570 | GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# peers connected"), 1, |